ffi 1.17.1 → 1.17.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +33 -0
- data/Gemfile +8 -3
- data/README.md +1 -0
- data/Rakefile +7 -4
- data/Steepfile +8 -0
- data/ext/ffi_c/DynamicLibrary.c +1 -1
- data/ext/ffi_c/Function.c +2 -0
- data/ext/ffi_c/MethodHandle.c +4 -2
- data/ext/ffi_c/libffi/.ci/Containerfile.ppc64le +12 -0
- data/ext/ffi_c/libffi/.ci/build.sh +38 -33
- data/ext/ffi_c/libffi/.ci/install.sh +46 -50
- data/ext/ffi_c/libffi/.ci/site.exp +6 -0
- data/ext/ffi_c/libffi/.gail-labels +44 -0
- data/ext/ffi_c/libffi/.github/workflows/build.yml +212 -333
- data/ext/ffi_c/libffi/.github/workflows/emscripten.yml +101 -58
- data/ext/ffi_c/libffi/.github/workflows/label-new-issue.yaml +15 -0
- data/ext/ffi_c/libffi/.github/workflows/tarball.yml +55 -0
- data/ext/ffi_c/libffi/LICENSE +1 -1
- data/ext/ffi_c/libffi/Makefile.am +20 -15
- data/ext/ffi_c/libffi/Makefile.in +41 -54
- data/ext/ffi_c/libffi/README.md +40 -4
- data/ext/ffi_c/libffi/acinclude.m4 +6 -0
- data/ext/ffi_c/libffi/config.guess +80 -22
- data/ext/ffi_c/libffi/config.sub +161 -80
- data/ext/ffi_c/libffi/configure +1058 -1372
- data/ext/ffi_c/libffi/configure.ac +28 -14
- data/ext/ffi_c/libffi/configure.host +6 -6
- data/ext/ffi_c/libffi/doc/Makefile.in +4 -0
- data/ext/ffi_c/libffi/doc/libffi.texi +27 -4
- data/ext/ffi_c/libffi/doc/version.texi +4 -4
- data/ext/ffi_c/libffi/fficonfig.h.in +9 -9
- data/ext/ffi_c/libffi/generate-darwin-source-and-headers.py +1 -28
- data/ext/ffi_c/libffi/include/Makefile.in +4 -0
- data/ext/ffi_c/libffi/include/ffi.h.in +19 -1
- data/ext/ffi_c/libffi/include/ffi_cfi.h +2 -0
- data/ext/ffi_c/libffi/include/ffi_common.h +17 -0
- data/ext/ffi_c/libffi/libffi.map.in +13 -1
- data/ext/ffi_c/libffi/libtool-version +1 -1
- data/ext/ffi_c/libffi/m4/asmcfi.m4 +28 -11
- data/ext/ffi_c/libffi/m4/ax_check_compile_flag.m4 +13 -3
- data/ext/ffi_c/libffi/man/Makefile.in +4 -0
- data/ext/ffi_c/libffi/src/aarch64/ffi.c +7 -4
- data/ext/ffi_c/libffi/src/aarch64/ffitarget.h +2 -2
- data/ext/ffi_c/libffi/src/aarch64/internal.h +63 -17
- data/ext/ffi_c/libffi/src/aarch64/sysv.S +22 -12
- data/ext/ffi_c/libffi/src/arc/arcompact.S +2 -2
- data/ext/ffi_c/libffi/src/arc/ffi.c +6 -2
- data/ext/ffi_c/libffi/src/arm/sysv.S +1 -1
- data/ext/ffi_c/libffi/src/closures.c +3 -3
- data/ext/ffi_c/libffi/src/dlmalloc.c +1 -0
- data/ext/ffi_c/libffi/src/mips/ffitarget.h +2 -4
- data/ext/ffi_c/libffi/src/mips/n32.S +4 -0
- data/ext/ffi_c/libffi/src/mips/o32.S +4 -0
- data/ext/ffi_c/libffi/src/or1k/ffi.c +2 -2
- data/ext/ffi_c/libffi/src/pa/linux.S +4 -0
- data/ext/ffi_c/libffi/src/powerpc/ffi.c +19 -0
- data/ext/ffi_c/libffi/src/powerpc/ffi_linux64.c +26 -19
- data/ext/ffi_c/libffi/src/powerpc/ffi_sysv.c +26 -16
- data/ext/ffi_c/libffi/src/powerpc/internal.h +10 -0
- data/ext/ffi_c/libffi/src/powerpc/linux64_closure.S +47 -0
- data/ext/ffi_c/libffi/src/powerpc/ppc_closure.S +24 -0
- data/ext/ffi_c/libffi/src/prep_cif.c +1 -4
- data/ext/ffi_c/libffi/src/riscv/ffi.c +39 -16
- data/ext/ffi_c/libffi/src/riscv/internal.h +7 -0
- data/ext/ffi_c/libffi/src/riscv/sysv.S +24 -0
- data/ext/ffi_c/libffi/src/s390/ffi.c +28 -1
- data/ext/ffi_c/libffi/src/s390/internal.h +11 -0
- data/ext/ffi_c/libffi/src/s390/sysv.S +38 -0
- data/ext/ffi_c/libffi/src/sparc/ffi.c +16 -0
- data/ext/ffi_c/libffi/src/tramp.c +6 -1
- data/ext/ffi_c/libffi/src/types.c +23 -1
- data/ext/ffi_c/libffi/src/{wasm32 → wasm}/ffi.c +166 -315
- data/ext/ffi_c/libffi/src/{wasm32 → wasm}/ffitarget.h +17 -0
- data/ext/ffi_c/libffi/src/x86/ffi.c +4 -1
- data/ext/ffi_c/libffi/src/x86/ffi64.c +4 -1
- data/ext/ffi_c/libffi/src/x86/ffitarget.h +0 -3
- data/ext/ffi_c/libffi/src/x86/sysv.S +1 -3
- data/ext/ffi_c/libffi/src/x86/sysv_intel.S +1 -3
- data/ext/ffi_c/libffi/testsuite/Makefile.am +6 -4
- data/ext/ffi_c/libffi/testsuite/Makefile.in +10 -4
- data/ext/ffi_c/libffi/testsuite/emscripten/build-tests.sh +4 -24
- data/ext/ffi_c/libffi/testsuite/emscripten/build.sh +10 -27
- data/ext/ffi_c/libffi/testsuite/emscripten/node-tests.sh +6 -31
- data/ext/ffi_c/libffi/testsuite/lib/libffi.exp +269 -256
- data/ext/ffi_c/libffi/testsuite/libffi.bhaible/testcases.c +1 -1
- data/ext/ffi_c/libffi/testsuite/libffi.call/callback.c +2 -2
- data/ext/ffi_c/libffi/testsuite/libffi.call/callback2.c +2 -2
- data/ext/ffi_c/libffi/testsuite/libffi.call/callback3.c +2 -2
- data/ext/ffi_c/libffi/testsuite/libffi.call/callback4.c +2 -2
- data/ext/ffi_c/libffi/testsuite/libffi.call/ffitest.h +3 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/longjmp.c +60 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/overread.c +54 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct_int_float.c +88 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct2.c +1 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct3.c +1 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/x32.c +31 -0
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_dbls_struct.c +1 -1
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_multi_sshortchar.c +1 -1
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_multi_ushortchar.c +1 -1
- data/ext/ffi_c/libffi/testsuite/libffi.closures/huge_struct.c +1 -2
- data/ext/ffi_c/libffi/testsuite/libffi.closures/unwindtest.cc +2 -0
- data/ext/ffi_c/libffi/testsuite/libffi.closures/unwindtest_ffi_call.cc +2 -0
- data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_int.c +1 -1
- data/ext/ffi_c/libffi/testsuite/libffi.threads/ffitest.h +1 -0
- data/ext/ffi_c/libffi/testsuite/libffi.threads/threads.exp +50 -0
- data/ext/ffi_c/libffi/testsuite/libffi.threads/tsan.c +74 -0
- data/ext/ffi_c/libffi.mk +5 -0
- data/ffi.gemspec +4 -5
- data/lib/ffi/autopointer.rb +6 -0
- data/lib/ffi/compat.rb +11 -0
- data/lib/ffi/function.rb +23 -0
- data/lib/ffi/library.rb +19 -3
- data/lib/ffi/struct_by_reference.rb +1 -1
- data/lib/ffi/version.rb +1 -1
- data/samples/hello_ractor.rb +9 -1
- data/samples/qsort_ractor.rb +9 -1
- data/sig/ffi/auto_pointer.rbs +1 -1
- data/sig/ffi/errno.rbs +8 -0
- data/sig/ffi/platform.rbs +49 -0
- data/sig/ffi/struct.rbs +2 -2
- data/sig/ffi/struct_by_reference.rbs +1 -1
- data/sig/ffi.rbs +4 -1
- data.tar.gz.sig +0 -0
- metadata +37 -83
- metadata.gz.sig +0 -0
- data/ext/ffi_c/libffi/.appveyor/site.exp +0 -16
- data/ext/ffi_c/libffi/.appveyor.yml +0 -84
- data/ext/ffi_c/libffi/.circleci/config.yml +0 -156
- data/ext/ffi_c/libffi/src/nios2/ffi.c +0 -304
- data/ext/ffi_c/libffi/src/nios2/ffitarget.h +0 -52
- data/ext/ffi_c/libffi/src/nios2/sysv.S +0 -136
- data/lib/ffi/tools/types_generator.rb +0 -137
- data/rakelib/ffi_gem_helper.rb +0 -65
- /data/ext/ffi_c/libffi/{.appveyor → .ci}/unix-noexec.exp +0 -0
|
@@ -41,28 +41,7 @@
|
|
|
41
41
|
|
|
42
42
|
#define EM_JS_MACROS(ret, name, args, body...) EM_JS(ret, name, args, body)
|
|
43
43
|
|
|
44
|
-
#if WASM_BIGINT
|
|
45
44
|
EM_JS_DEPS(libffi, "$getWasmTableEntry,$setWasmTableEntry,$getEmptyTableSlot,$convertJsFunctionToWasm");
|
|
46
|
-
#define CALL_FUNCTION_POINTER(ptr, args...) \
|
|
47
|
-
(LOG_DEBUG("CALL_FUNC_PTR", ptr, args), \
|
|
48
|
-
getWasmTableEntry(ptr).apply(null, args))
|
|
49
|
-
|
|
50
|
-
#define JS_FUNCTION_TO_WASM convertJsFunctionToWasm
|
|
51
|
-
#else
|
|
52
|
-
EM_JS_DEPS(libffi, "$getWasmTableEntry,$setWasmTableEntry,$getEmptyTableSlot,$convertJsFunctionToWasm,$dynCall,$generateFuncType,$uleb128Encode");
|
|
53
|
-
#define CALL_FUNCTION_POINTER(ptr, args...) \
|
|
54
|
-
(LOG_DEBUG("CALL_FUNC_PTR", sig, ptr, args), \
|
|
55
|
-
dynCall(sig, ptr, args))
|
|
56
|
-
|
|
57
|
-
#define JS_FUNCTION_TO_WASM createLegalizerWrapper
|
|
58
|
-
#endif
|
|
59
|
-
|
|
60
|
-
// Signature calculations are not needed if WASM_BIGINT is present.
|
|
61
|
-
#if WASM_BIGINT
|
|
62
|
-
#define SIG(sig)
|
|
63
|
-
#else
|
|
64
|
-
#define SIG(sig) sig
|
|
65
|
-
#endif
|
|
66
45
|
|
|
67
46
|
#define DEREF_U8(addr, offset) HEAPU8[addr + offset]
|
|
68
47
|
#define DEREF_S8(addr, offset) HEAP8[addr + offset]
|
|
@@ -73,28 +52,36 @@ EM_JS_DEPS(libffi, "$getWasmTableEntry,$setWasmTableEntry,$getEmptyTableSlot,$co
|
|
|
73
52
|
|
|
74
53
|
#define DEREF_F32(addr, offset) HEAPF32[(addr >> 2) + offset]
|
|
75
54
|
#define DEREF_F64(addr, offset) HEAPF64[(addr >> 3) + offset]
|
|
76
|
-
|
|
77
|
-
#if WASM_BIGINT
|
|
78
|
-
// We have HEAPU64 in this case.
|
|
79
55
|
#define DEREF_U64(addr, offset) HEAPU64[(addr >> 3) + offset]
|
|
80
|
-
#endif
|
|
81
|
-
|
|
82
56
|
|
|
83
57
|
#define CHECK_FIELD_OFFSET(struct, field, offset) \
|
|
84
58
|
_Static_assert( \
|
|
85
59
|
offsetof(struct, field) == offset, \
|
|
86
60
|
"Memory layout of '" #struct "' has changed: '" #field "' is in an unexpected location");
|
|
87
61
|
|
|
62
|
+
#if __SIZEOF_POINTER__ == 4
|
|
63
|
+
|
|
64
|
+
#define FFI_EMSCRIPTEN_ABI FFI_WASM32_EMSCRIPTEN
|
|
65
|
+
#define PTR_SIG 'i'
|
|
66
|
+
|
|
67
|
+
#define DEC_PTR(p) p
|
|
68
|
+
#define ENC_PTR(p) p
|
|
69
|
+
|
|
70
|
+
#define DEREF_PTR(addr, offset) DEREF_U32(addr, offset)
|
|
71
|
+
#define DEREF_PTR_NUMBER(addr, offset) DEREF_PTR(addr, offset)
|
|
72
|
+
|
|
88
73
|
CHECK_FIELD_OFFSET(ffi_cif, abi, 4*0);
|
|
89
74
|
CHECK_FIELD_OFFSET(ffi_cif, nargs, 4*1);
|
|
90
75
|
CHECK_FIELD_OFFSET(ffi_cif, arg_types, 4*2);
|
|
91
76
|
CHECK_FIELD_OFFSET(ffi_cif, rtype, 4*3);
|
|
77
|
+
CHECK_FIELD_OFFSET(ffi_cif, flags, 4*5);
|
|
92
78
|
CHECK_FIELD_OFFSET(ffi_cif, nfixedargs, 4*6);
|
|
93
79
|
|
|
94
80
|
#define CIF__ABI(addr) DEREF_U32(addr, 0)
|
|
95
81
|
#define CIF__NARGS(addr) DEREF_U32(addr, 1)
|
|
96
82
|
#define CIF__ARGTYPES(addr) DEREF_U32(addr, 2)
|
|
97
83
|
#define CIF__RTYPE(addr) DEREF_U32(addr, 3)
|
|
84
|
+
#define CIF__FLAGS(addr) DEREF_U32(addr, 5)
|
|
98
85
|
#define CIF__NFIXEDARGS(addr) DEREF_U32(addr, 6)
|
|
99
86
|
|
|
100
87
|
CHECK_FIELD_OFFSET(ffi_type, size, 0);
|
|
@@ -107,6 +94,49 @@ CHECK_FIELD_OFFSET(ffi_type, elements, 8);
|
|
|
107
94
|
#define FFI_TYPE__TYPEID(addr) DEREF_U16(addr + 6, 0)
|
|
108
95
|
#define FFI_TYPE__ELEMENTS(addr) DEREF_U32(addr + 8, 0)
|
|
109
96
|
|
|
97
|
+
#elif __SIZEOF_POINTER__ == 8
|
|
98
|
+
|
|
99
|
+
#define FFI_EMSCRIPTEN_ABI FFI_WASM64_EMSCRIPTEN
|
|
100
|
+
#define PTR_SIG 'j'
|
|
101
|
+
|
|
102
|
+
// DEC_PTR casts a pointer value (comming from Wasm) represented as BigInt (i64) to Number (i53).
|
|
103
|
+
// This should be used for a pointer that is expected to be within the i53 range. If the pointer
|
|
104
|
+
// value is outside the Number's range, the value will become NaN.
|
|
105
|
+
#define DEC_PTR(p) bigintToI53Checked(p)
|
|
106
|
+
// ENC_PTR casts a pointer value represented as Number to BigInt (i64)
|
|
107
|
+
#define ENC_PTR(p) BigInt(p)
|
|
108
|
+
|
|
109
|
+
#define DEREF_PTR(addr, offset) DEREF_U64(addr, offset)
|
|
110
|
+
#define DEREF_PTR_NUMBER(addr, offset) DEC_PTR(DEREF_PTR(addr, offset))
|
|
111
|
+
|
|
112
|
+
CHECK_FIELD_OFFSET(ffi_cif, abi, 0);
|
|
113
|
+
CHECK_FIELD_OFFSET(ffi_cif, nargs, 4);
|
|
114
|
+
CHECK_FIELD_OFFSET(ffi_cif, arg_types, 8);
|
|
115
|
+
CHECK_FIELD_OFFSET(ffi_cif, rtype, 16);
|
|
116
|
+
CHECK_FIELD_OFFSET(ffi_cif, flags, 28);
|
|
117
|
+
CHECK_FIELD_OFFSET(ffi_cif, nfixedargs, 32);
|
|
118
|
+
|
|
119
|
+
#define CIF__ABI(addr) DEREF_U32(addr, 0)
|
|
120
|
+
#define CIF__NARGS(addr) DEREF_U32(addr + 4, 0)
|
|
121
|
+
#define CIF__ARGTYPES(addr) DEREF_U64(addr + 8, 0)
|
|
122
|
+
#define CIF__RTYPE(addr) DEREF_U64(addr + 16, 0)
|
|
123
|
+
#define CIF__FLAGS(addr) DEREF_U32(addr + 28, 0)
|
|
124
|
+
#define CIF__NFIXEDARGS(addr) DEREF_U32(addr + 32, 0)
|
|
125
|
+
|
|
126
|
+
CHECK_FIELD_OFFSET(ffi_type, size, 0);
|
|
127
|
+
CHECK_FIELD_OFFSET(ffi_type, alignment, 8);
|
|
128
|
+
CHECK_FIELD_OFFSET(ffi_type, type, 10);
|
|
129
|
+
CHECK_FIELD_OFFSET(ffi_type, elements, 16);
|
|
130
|
+
|
|
131
|
+
#define FFI_TYPE__SIZE(addr) DEREF_U64(addr, 0)
|
|
132
|
+
#define FFI_TYPE__ALIGN(addr) DEREF_U16(addr + 8, 0)
|
|
133
|
+
#define FFI_TYPE__TYPEID(addr) DEREF_U16(addr + 10, 0)
|
|
134
|
+
#define FFI_TYPE__ELEMENTS(addr) DEREF_U64(addr + 16, 0)
|
|
135
|
+
|
|
136
|
+
#else
|
|
137
|
+
#error "Unknown pointer size"
|
|
138
|
+
#endif
|
|
139
|
+
|
|
110
140
|
#define ALIGN_ADDRESS(addr, align) (addr &= (~((align) - 1)))
|
|
111
141
|
#define STACK_ALLOC(stack, size, align) ((stack -= (size)), ALIGN_ADDRESS(stack, align))
|
|
112
142
|
|
|
@@ -126,7 +156,7 @@ _Static_assert(FFI_BAD_TYPEDEF_MACRO == FFI_BAD_TYPEDEF, "FFI_BAD_TYPEDEF must b
|
|
|
126
156
|
ffi_status FFI_HIDDEN
|
|
127
157
|
ffi_prep_cif_machdep(ffi_cif *cif)
|
|
128
158
|
{
|
|
129
|
-
if (cif->abi !=
|
|
159
|
+
if (cif->abi != FFI_EMSCRIPTEN_ABI)
|
|
130
160
|
return FFI_BAD_ABI;
|
|
131
161
|
// This is called after ffi_prep_cif_machdep_var so we need to avoid
|
|
132
162
|
// overwriting cif->nfixedargs.
|
|
@@ -170,6 +200,7 @@ ffi_prep_cif_machdep_var(ffi_cif *cif, unsigned nfixedargs, unsigned ntotalargs)
|
|
|
170
200
|
EM_JS_MACROS(
|
|
171
201
|
void,
|
|
172
202
|
unbox_small_structs, (ffi_type type_ptr), {
|
|
203
|
+
type_ptr = DEC_PTR(type_ptr);
|
|
173
204
|
var type_id = FFI_TYPE__TYPEID(type_ptr);
|
|
174
205
|
while (type_id === FFI_TYPE_STRUCT) {
|
|
175
206
|
// Don't unbox single element structs if they are bigger than 16 bytes. This
|
|
@@ -182,15 +213,15 @@ unbox_small_structs, (ffi_type type_ptr), {
|
|
|
182
213
|
//
|
|
183
214
|
// See the Python comment here:
|
|
184
215
|
// https://github.com/python/cpython/blob/a16a9f978f42b8a09297c1efbf33877f6388c403/Modules/_ctypes/stgdict.c#L718-L779
|
|
185
|
-
if (FFI_TYPE__SIZE(type_ptr) > 16) {
|
|
216
|
+
if (DEC_PTR(FFI_TYPE__SIZE(type_ptr)) > 16) {
|
|
186
217
|
break;
|
|
187
218
|
}
|
|
188
|
-
var elements = FFI_TYPE__ELEMENTS(type_ptr);
|
|
189
|
-
var first_element =
|
|
219
|
+
var elements = DEC_PTR(FFI_TYPE__ELEMENTS(type_ptr));
|
|
220
|
+
var first_element = DEREF_PTR_NUMBER(elements, 0);
|
|
190
221
|
if (first_element === 0) {
|
|
191
222
|
type_id = FFI_TYPE_VOID;
|
|
192
223
|
break;
|
|
193
|
-
} else if (
|
|
224
|
+
} else if (DEREF_PTR_NUMBER(elements, 1) === 0) {
|
|
194
225
|
type_ptr = first_element;
|
|
195
226
|
type_id = FFI_TYPE__TYPEID(first_element);
|
|
196
227
|
} else {
|
|
@@ -204,10 +235,15 @@ EM_JS_MACROS(
|
|
|
204
235
|
void,
|
|
205
236
|
ffi_call_js, (ffi_cif *cif, ffi_fp fn, void *rvalue, void **avalue),
|
|
206
237
|
{
|
|
238
|
+
cif = DEC_PTR(cif);
|
|
239
|
+
fn = DEC_PTR(fn);
|
|
240
|
+
rvalue = DEC_PTR(rvalue);
|
|
241
|
+
avalue = DEC_PTR(avalue);
|
|
207
242
|
var abi = CIF__ABI(cif);
|
|
208
243
|
var nargs = CIF__NARGS(cif);
|
|
209
244
|
var nfixedargs = CIF__NFIXEDARGS(cif);
|
|
210
|
-
var arg_types_ptr = CIF__ARGTYPES(cif);
|
|
245
|
+
var arg_types_ptr = DEC_PTR(CIF__ARGTYPES(cif));
|
|
246
|
+
var flags = CIF__FLAGS(cif);
|
|
211
247
|
var rtype_unboxed = unbox_small_structs(CIF__RTYPE(cif));
|
|
212
248
|
var rtype_ptr = rtype_unboxed[0];
|
|
213
249
|
var rtype_id = rtype_unboxed[1];
|
|
@@ -231,51 +267,17 @@ ffi_call_js, (ffi_cif *cif, ffi_fp fn, void *rvalue, void **avalue),
|
|
|
231
267
|
// just use this. We also mark a flag that we don't need to convert the return
|
|
232
268
|
// value of the dynamic call back to C.
|
|
233
269
|
if (rtype_id === FFI_TYPE_LONGDOUBLE || rtype_id === FFI_TYPE_STRUCT) {
|
|
234
|
-
args.push(rvalue);
|
|
270
|
+
args.push(ENC_PTR(rvalue));
|
|
235
271
|
ret_by_arg = true;
|
|
236
272
|
}
|
|
237
273
|
|
|
238
|
-
SIG(var sig = "");
|
|
239
|
-
|
|
240
|
-
#if !WASM_BIGINT
|
|
241
|
-
switch(rtype_id) {
|
|
242
|
-
case FFI_TYPE_VOID:
|
|
243
|
-
SIG(sig = 'v');
|
|
244
|
-
break;
|
|
245
|
-
case FFI_TYPE_STRUCT:
|
|
246
|
-
case FFI_TYPE_LONGDOUBLE:
|
|
247
|
-
SIG(sig = 'vi');
|
|
248
|
-
break;
|
|
249
|
-
case FFI_TYPE_INT:
|
|
250
|
-
case FFI_TYPE_UINT8:
|
|
251
|
-
case FFI_TYPE_SINT8:
|
|
252
|
-
case FFI_TYPE_UINT16:
|
|
253
|
-
case FFI_TYPE_SINT16:
|
|
254
|
-
case FFI_TYPE_UINT32:
|
|
255
|
-
case FFI_TYPE_SINT32:
|
|
256
|
-
case FFI_TYPE_POINTER:
|
|
257
|
-
SIG(sig = 'i');
|
|
258
|
-
break;
|
|
259
|
-
case FFI_TYPE_FLOAT:
|
|
260
|
-
SIG(sig = 'f');
|
|
261
|
-
break;
|
|
262
|
-
case FFI_TYPE_DOUBLE:
|
|
263
|
-
SIG(sig = 'd');
|
|
264
|
-
break;
|
|
265
|
-
case FFI_TYPE_UINT64:
|
|
266
|
-
case FFI_TYPE_SINT64:
|
|
267
|
-
SIG(sig = 'j');
|
|
268
|
-
break;
|
|
269
|
-
}
|
|
270
|
-
#endif
|
|
271
|
-
|
|
272
274
|
// Accumulate a Javascript list of arguments for the Javascript wrapper for
|
|
273
275
|
// the wasm function. The Javascript wrapper does a type conversion from
|
|
274
276
|
// Javascript to C automatically, here we manually do the inverse conversion
|
|
275
277
|
// from C to Javascript.
|
|
276
278
|
for (var i = 0; i < nfixedargs; i++) {
|
|
277
|
-
var arg_ptr =
|
|
278
|
-
var arg_unboxed = unbox_small_structs(
|
|
279
|
+
var arg_ptr = DEREF_PTR_NUMBER(avalue, i);
|
|
280
|
+
var arg_unboxed = unbox_small_structs(DEREF_PTR(arg_types_ptr, i));
|
|
279
281
|
var arg_type_ptr = arg_unboxed[0];
|
|
280
282
|
var arg_type_id = arg_unboxed[1];
|
|
281
283
|
|
|
@@ -286,67 +288,47 @@ ffi_call_js, (ffi_cif *cif, ffi_fp fn, void *rvalue, void **avalue),
|
|
|
286
288
|
case FFI_TYPE_INT:
|
|
287
289
|
case FFI_TYPE_SINT32:
|
|
288
290
|
case FFI_TYPE_UINT32:
|
|
289
|
-
case FFI_TYPE_POINTER:
|
|
290
291
|
args.push(DEREF_U32(arg_ptr, 0));
|
|
291
|
-
SIG(sig += 'i');
|
|
292
292
|
break;
|
|
293
293
|
case FFI_TYPE_FLOAT:
|
|
294
294
|
args.push(DEREF_F32(arg_ptr, 0));
|
|
295
|
-
SIG(sig += 'f');
|
|
296
295
|
break;
|
|
297
296
|
case FFI_TYPE_DOUBLE:
|
|
298
297
|
args.push(DEREF_F64(arg_ptr, 0));
|
|
299
|
-
SIG(sig += 'd');
|
|
300
298
|
break;
|
|
301
299
|
case FFI_TYPE_UINT8:
|
|
302
300
|
args.push(DEREF_U8(arg_ptr, 0));
|
|
303
|
-
SIG(sig += 'i');
|
|
304
301
|
break;
|
|
305
302
|
case FFI_TYPE_SINT8:
|
|
306
303
|
args.push(DEREF_S8(arg_ptr, 0));
|
|
307
|
-
SIG(sig += 'i');
|
|
308
304
|
break;
|
|
309
305
|
case FFI_TYPE_UINT16:
|
|
310
306
|
args.push(DEREF_U16(arg_ptr, 0));
|
|
311
|
-
SIG(sig += 'i');
|
|
312
307
|
break;
|
|
313
308
|
case FFI_TYPE_SINT16:
|
|
314
309
|
args.push(DEREF_S16(arg_ptr, 0));
|
|
315
|
-
SIG(sig += 'i');
|
|
316
310
|
break;
|
|
317
311
|
case FFI_TYPE_UINT64:
|
|
318
312
|
case FFI_TYPE_SINT64:
|
|
319
|
-
#if WASM_BIGINT
|
|
320
313
|
args.push(DEREF_U64(arg_ptr, 0));
|
|
321
|
-
#else
|
|
322
|
-
args.push(DEREF_U32(arg_ptr, 0));
|
|
323
|
-
args.push(DEREF_U32(arg_ptr, 1));
|
|
324
|
-
#endif
|
|
325
|
-
SIG(sig += 'j');
|
|
326
314
|
break;
|
|
327
315
|
case FFI_TYPE_LONGDOUBLE:
|
|
328
316
|
// long double is passed as a pair of BigInts.
|
|
329
|
-
#if WASM_BIGINT
|
|
330
317
|
args.push(DEREF_U64(arg_ptr, 0));
|
|
331
318
|
args.push(DEREF_U64(arg_ptr, 1));
|
|
332
|
-
#else
|
|
333
|
-
args.push(DEREF_U32(arg_ptr, 0));
|
|
334
|
-
args.push(DEREF_U32(arg_ptr, 1));
|
|
335
|
-
args.push(DEREF_U32(arg_ptr, 2));
|
|
336
|
-
args.push(DEREF_U32(arg_ptr, 3));
|
|
337
|
-
#endif
|
|
338
|
-
SIG(sig += "jj");
|
|
339
319
|
break;
|
|
340
320
|
case FFI_TYPE_STRUCT:
|
|
341
321
|
// Nontrivial structs are passed by pointer.
|
|
342
322
|
// Have to copy the struct onto the stack though because C ABI says it's
|
|
343
323
|
// call by value.
|
|
344
|
-
var size = FFI_TYPE__SIZE(arg_type_ptr);
|
|
324
|
+
var size = DEC_PTR(FFI_TYPE__SIZE(arg_type_ptr));
|
|
345
325
|
var align = FFI_TYPE__ALIGN(arg_type_ptr);
|
|
346
326
|
STACK_ALLOC(cur_stack_ptr, size, align);
|
|
347
327
|
HEAP8.subarray(cur_stack_ptr, cur_stack_ptr+size).set(HEAP8.subarray(arg_ptr, arg_ptr + size));
|
|
348
|
-
args.push(cur_stack_ptr);
|
|
349
|
-
|
|
328
|
+
args.push(ENC_PTR(cur_stack_ptr));
|
|
329
|
+
break;
|
|
330
|
+
case FFI_TYPE_POINTER:
|
|
331
|
+
args.push(DEREF_PTR(arg_ptr, 0));
|
|
350
332
|
break;
|
|
351
333
|
case FFI_TYPE_COMPLEX:
|
|
352
334
|
throw new Error('complex marshalling nyi');
|
|
@@ -364,12 +346,11 @@ ffi_call_js, (ffi_cif *cif, ffi_fp fn, void *rvalue, void **avalue),
|
|
|
364
346
|
// We don't have any way of knowing how many args were actually passed, so we
|
|
365
347
|
// just always copy extra nonsense past the end. The ownwards call will know
|
|
366
348
|
// not to look at it.
|
|
367
|
-
if (
|
|
368
|
-
SIG(sig += 'i');
|
|
349
|
+
if (flags & VARARGS_FLAG) {
|
|
369
350
|
var struct_arg_info = [];
|
|
370
351
|
for (var i = nargs - 1; i >= nfixedargs; i--) {
|
|
371
|
-
var arg_ptr =
|
|
372
|
-
var arg_unboxed = unbox_small_structs(
|
|
352
|
+
var arg_ptr = DEREF_PTR_NUMBER(avalue, i);
|
|
353
|
+
var arg_unboxed = unbox_small_structs(DEREF_PTR(arg_types_ptr, i));
|
|
373
354
|
var arg_type_ptr = arg_unboxed[0];
|
|
374
355
|
var arg_type_id = arg_unboxed[1];
|
|
375
356
|
switch (arg_type_id) {
|
|
@@ -386,7 +367,6 @@ ffi_call_js, (ffi_cif *cif, ffi_fp fn, void *rvalue, void **avalue),
|
|
|
386
367
|
case FFI_TYPE_INT:
|
|
387
368
|
case FFI_TYPE_UINT32:
|
|
388
369
|
case FFI_TYPE_SINT32:
|
|
389
|
-
case FFI_TYPE_POINTER:
|
|
390
370
|
case FFI_TYPE_FLOAT:
|
|
391
371
|
STACK_ALLOC(cur_stack_ptr, 4, 4);
|
|
392
372
|
DEREF_U32(cur_stack_ptr, 0) = DEREF_U32(arg_ptr, 0);
|
|
@@ -409,8 +389,12 @@ ffi_call_js, (ffi_cif *cif, ffi_fp fn, void *rvalue, void **avalue),
|
|
|
409
389
|
// Again, struct must be passed by pointer.
|
|
410
390
|
// But ABI is by value, so have to copy struct onto stack.
|
|
411
391
|
// Currently arguments are going onto stack so we can't put it there now. Come back for this.
|
|
412
|
-
STACK_ALLOC(cur_stack_ptr,
|
|
413
|
-
struct_arg_info.push([cur_stack_ptr, arg_ptr, FFI_TYPE__SIZE(arg_type_ptr), FFI_TYPE__ALIGN(arg_type_ptr)]);
|
|
392
|
+
STACK_ALLOC(cur_stack_ptr, __SIZEOF_POINTER__, __SIZEOF_POINTER__);
|
|
393
|
+
struct_arg_info.push([cur_stack_ptr, arg_ptr, DEC_PTR(FFI_TYPE__SIZE(arg_type_ptr)), FFI_TYPE__ALIGN(arg_type_ptr)]);
|
|
394
|
+
break;
|
|
395
|
+
case FFI_TYPE_POINTER:
|
|
396
|
+
STACK_ALLOC(cur_stack_ptr, __SIZEOF_POINTER__, __SIZEOF_POINTER__);
|
|
397
|
+
DEREF_PTR(cur_stack_ptr, 0) = DEREF_PTR(arg_ptr, 0);
|
|
414
398
|
break;
|
|
415
399
|
case FFI_TYPE_COMPLEX:
|
|
416
400
|
throw new Error('complex arg marshalling nyi');
|
|
@@ -419,7 +403,7 @@ ffi_call_js, (ffi_cif *cif, ffi_fp fn, void *rvalue, void **avalue),
|
|
|
419
403
|
}
|
|
420
404
|
}
|
|
421
405
|
// extra normal argument which is the pointer to the varargs.
|
|
422
|
-
args.push(cur_stack_ptr);
|
|
406
|
+
args.push(ENC_PTR(cur_stack_ptr));
|
|
423
407
|
// Now allocate variable struct args on stack too.
|
|
424
408
|
for (var i = 0; i < struct_arg_info.length; i++) {
|
|
425
409
|
var struct_info = struct_arg_info[i];
|
|
@@ -429,12 +413,13 @@ ffi_call_js, (ffi_cif *cif, ffi_fp fn, void *rvalue, void **avalue),
|
|
|
429
413
|
var align = struct_info[3];
|
|
430
414
|
STACK_ALLOC(cur_stack_ptr, size, align);
|
|
431
415
|
HEAP8.subarray(cur_stack_ptr, cur_stack_ptr+size).set(HEAP8.subarray(arg_ptr, arg_ptr + size));
|
|
432
|
-
|
|
416
|
+
DEREF_PTR(arg_target, 0) = ENC_PTR(cur_stack_ptr);
|
|
433
417
|
}
|
|
434
418
|
}
|
|
435
419
|
stackRestore(cur_stack_ptr);
|
|
436
420
|
stackAlloc(0); // stackAlloc enforces alignment invariants on the stack pointer
|
|
437
|
-
|
|
421
|
+
LOG_DEBUG("CALL_FUNC_PTR", "fn:", fn, "args:", args);
|
|
422
|
+
var result = getWasmTableEntry(fn).apply(null, args);
|
|
438
423
|
// Put the stack pointer back (we moved it if there were any struct args or we
|
|
439
424
|
// made a varargs call)
|
|
440
425
|
stackRestore(orig_stack_ptr);
|
|
@@ -453,7 +438,6 @@ ffi_call_js, (ffi_cif *cif, ffi_fp fn, void *rvalue, void **avalue),
|
|
|
453
438
|
case FFI_TYPE_INT:
|
|
454
439
|
case FFI_TYPE_UINT32:
|
|
455
440
|
case FFI_TYPE_SINT32:
|
|
456
|
-
case FFI_TYPE_POINTER:
|
|
457
441
|
DEREF_U32(rvalue, 0) = result;
|
|
458
442
|
break;
|
|
459
443
|
case FFI_TYPE_FLOAT:
|
|
@@ -472,12 +456,10 @@ ffi_call_js, (ffi_cif *cif, ffi_fp fn, void *rvalue, void **avalue),
|
|
|
472
456
|
break;
|
|
473
457
|
case FFI_TYPE_UINT64:
|
|
474
458
|
case FFI_TYPE_SINT64:
|
|
475
|
-
#if WASM_BIGINT
|
|
476
459
|
DEREF_U64(rvalue, 0) = result;
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
#endif
|
|
460
|
+
break;
|
|
461
|
+
case FFI_TYPE_POINTER:
|
|
462
|
+
DEREF_PTR(rvalue, 0) = result;
|
|
481
463
|
break;
|
|
482
464
|
case FFI_TYPE_COMPLEX:
|
|
483
465
|
throw new Error('complex ret marshalling nyi');
|
|
@@ -490,6 +472,8 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) {
|
|
|
490
472
|
ffi_call_js(cif, fn, rvalue, avalue);
|
|
491
473
|
}
|
|
492
474
|
|
|
475
|
+
#if __SIZEOF_POINTER__ == 4
|
|
476
|
+
|
|
493
477
|
CHECK_FIELD_OFFSET(ffi_closure, ftramp, 4*0);
|
|
494
478
|
CHECK_FIELD_OFFSET(ffi_closure, cif, 4*1);
|
|
495
479
|
CHECK_FIELD_OFFSET(ffi_closure, fun, 4*2);
|
|
@@ -500,12 +484,30 @@ CHECK_FIELD_OFFSET(ffi_closure, user_data, 4*3);
|
|
|
500
484
|
#define CLOSURE__fun(addr) DEREF_U32(addr, 2)
|
|
501
485
|
#define CLOSURE__user_data(addr) DEREF_U32(addr, 3)
|
|
502
486
|
|
|
487
|
+
#elif __SIZEOF_POINTER__ == 8
|
|
488
|
+
|
|
489
|
+
CHECK_FIELD_OFFSET(ffi_closure, ftramp, 0);
|
|
490
|
+
CHECK_FIELD_OFFSET(ffi_closure, cif, 8);
|
|
491
|
+
CHECK_FIELD_OFFSET(ffi_closure, fun, 16);
|
|
492
|
+
CHECK_FIELD_OFFSET(ffi_closure, user_data, 24);
|
|
493
|
+
|
|
494
|
+
#define CLOSURE__wrapper(addr) DEREF_U64(addr, 0)
|
|
495
|
+
#define CLOSURE__cif(addr) DEREF_U64(addr, 1)
|
|
496
|
+
#define CLOSURE__fun(addr) DEREF_U64(addr, 2)
|
|
497
|
+
#define CLOSURE__user_data(addr) DEREF_U64(addr, 3)
|
|
498
|
+
|
|
499
|
+
#else
|
|
500
|
+
#error "Unknown pointer size"
|
|
501
|
+
#endif
|
|
502
|
+
|
|
503
503
|
EM_JS_MACROS(void *, ffi_closure_alloc_js, (size_t size, void **code), {
|
|
504
|
+
size = DEC_PTR(size);
|
|
505
|
+
code = DEC_PTR(code);
|
|
504
506
|
var closure = _malloc(size);
|
|
505
507
|
var index = getEmptyTableSlot();
|
|
506
|
-
|
|
507
|
-
CLOSURE__wrapper(closure) = index;
|
|
508
|
-
return closure;
|
|
508
|
+
DEREF_PTR(code, 0) = ENC_PTR(index);
|
|
509
|
+
CLOSURE__wrapper(closure) = ENC_PTR(index);
|
|
510
|
+
return ENC_PTR(closure);
|
|
509
511
|
})
|
|
510
512
|
|
|
511
513
|
void * __attribute__ ((visibility ("default")))
|
|
@@ -514,7 +516,8 @@ ffi_closure_alloc(size_t size, void **code) {
|
|
|
514
516
|
}
|
|
515
517
|
|
|
516
518
|
EM_JS_MACROS(void, ffi_closure_free_js, (void *closure), {
|
|
517
|
-
|
|
519
|
+
closure = DEC_PTR(closure);
|
|
520
|
+
var index = DEC_PTR(CLOSURE__wrapper(closure));
|
|
518
521
|
freeTableIndexes.push(index);
|
|
519
522
|
_free(closure);
|
|
520
523
|
})
|
|
@@ -524,155 +527,20 @@ ffi_closure_free(void *closure) {
|
|
|
524
527
|
return ffi_closure_free_js(closure);
|
|
525
528
|
}
|
|
526
529
|
|
|
527
|
-
#if !WASM_BIGINT
|
|
528
|
-
|
|
529
|
-
// When !WASM_BIGINT, we assume there is no JS bigint integration, so JavaScript
|
|
530
|
-
// functions cannot take 64 bit integer arguments.
|
|
531
|
-
//
|
|
532
|
-
// We need to make our own wasm legalizer adaptor that splits 64 bit integer
|
|
533
|
-
// arguments and then calls the JavaScript trampoline, then the JavaScript
|
|
534
|
-
// trampoline reassembles them, calls the closure, then splits the result (if
|
|
535
|
-
// it's a 64 bit integer) and the adaptor puts it back together.
|
|
536
|
-
//
|
|
537
|
-
// This is basically the reverse of the Emscripten function
|
|
538
|
-
// createDyncallWrapper.
|
|
539
|
-
EM_JS(void, createLegalizerWrapper, (int trampoline, int sig), {
|
|
540
|
-
if(!sig.includes("j")) {
|
|
541
|
-
return convertJsFunctionToWasm(trampoline, sig);
|
|
542
|
-
}
|
|
543
|
-
var sections = [];
|
|
544
|
-
var prelude = [
|
|
545
|
-
0x00, 0x61, 0x73, 0x6d, // magic ("\0asm")
|
|
546
|
-
0x01, 0x00, 0x00, 0x00, // version: 1
|
|
547
|
-
];
|
|
548
|
-
sections.push(prelude);
|
|
549
|
-
var wrappersig = [
|
|
550
|
-
// if return type is j, we will put the upper 32 bits into tempRet0.
|
|
551
|
-
sig[0].replace("j", "i"),
|
|
552
|
-
// in the rest of the argument list, one 64 bit integer is legalized into
|
|
553
|
-
// two 32 bit integers.
|
|
554
|
-
sig.slice(1).replace(/j/g, "ii"),
|
|
555
|
-
].join("");
|
|
556
|
-
|
|
557
|
-
var typeSectionBody = [
|
|
558
|
-
0x03, // number of types = 3
|
|
559
|
-
];
|
|
560
|
-
generateFuncType(wrappersig, typeSectionBody); // The signature of the wrapper we are generating
|
|
561
|
-
generateFuncType(sig, typeSectionBody); // the signature of the function pointer we will call
|
|
562
|
-
generateFuncType("i", typeSectionBody); // the signature of getTempRet0
|
|
563
|
-
|
|
564
|
-
var typeSection = [0x01 /* Type section code */];
|
|
565
|
-
uleb128Encode(typeSectionBody.length, typeSection); // length of section in bytes
|
|
566
|
-
typeSection.push.apply(typeSection, typeSectionBody);
|
|
567
|
-
sections.push(typeSection);
|
|
568
|
-
|
|
569
|
-
var importSection = [
|
|
570
|
-
0x02, // import section code
|
|
571
|
-
0x0d, // length of section in bytes
|
|
572
|
-
0x02, // number of imports = 2
|
|
573
|
-
// Import the getTempRet0 function, which we will call "r"
|
|
574
|
-
0x01, 0x65, // name "e"
|
|
575
|
-
0x01, 0x72, // name "r"
|
|
576
|
-
0x00, // importing a function
|
|
577
|
-
0x02, // type 2 = () -> i32
|
|
578
|
-
// Import the wrapped function, which we will call "f"
|
|
579
|
-
0x01, 0x65, // name "e"
|
|
580
|
-
0x01, 0x66, // name "f"
|
|
581
|
-
0x00, // importing a function
|
|
582
|
-
0x00, // type 0 = wrappersig
|
|
583
|
-
];
|
|
584
|
-
sections.push(importSection);
|
|
585
|
-
|
|
586
|
-
var functionSection = [
|
|
587
|
-
0x03, // function section code
|
|
588
|
-
0x02, // length of section in bytes
|
|
589
|
-
0x01, // number of functions = 1
|
|
590
|
-
0x01, // type 1 = sig
|
|
591
|
-
];
|
|
592
|
-
sections.push(functionSection);
|
|
593
|
-
|
|
594
|
-
var exportSection = [
|
|
595
|
-
0x07, // export section code
|
|
596
|
-
0x05, // length of section in bytes
|
|
597
|
-
0x01, // One export
|
|
598
|
-
0x01, 0x66, // name "f"
|
|
599
|
-
0x00, // type: function
|
|
600
|
-
0x02, // function index 2 = the wrapper function
|
|
601
|
-
];
|
|
602
|
-
sections.push(exportSection);
|
|
603
|
-
|
|
604
|
-
var convert_code = [];
|
|
605
|
-
convert_code.push(0x00); // no local variables (except the arguments)
|
|
606
|
-
|
|
607
|
-
function localGet(j) {
|
|
608
|
-
convert_code.push(0x20); // local.get
|
|
609
|
-
uleb128Encode(j, convert_code);
|
|
610
|
-
}
|
|
611
|
-
|
|
612
|
-
for (var i = 1; i < sig.length; i++) {
|
|
613
|
-
if (sig[i] == "j") {
|
|
614
|
-
localGet(i - 1);
|
|
615
|
-
convert_code.push(
|
|
616
|
-
0xa7 // i32.wrap_i64
|
|
617
|
-
);
|
|
618
|
-
localGet(i - 1);
|
|
619
|
-
convert_code.push(
|
|
620
|
-
0x42, 0x20, // i64.const 32
|
|
621
|
-
0x88, // i64.shr_u
|
|
622
|
-
0xa7 // i32.wrap_i64
|
|
623
|
-
);
|
|
624
|
-
} else {
|
|
625
|
-
localGet(i - 1);
|
|
626
|
-
}
|
|
627
|
-
}
|
|
628
|
-
convert_code.push(
|
|
629
|
-
0x10, 0x01 // call f
|
|
630
|
-
);
|
|
631
|
-
if (sig[0] === "j") {
|
|
632
|
-
// Need to reassemble a 64 bit integer. Lower 32 bits is on stack. Upper 32
|
|
633
|
-
// bits we get from getTempRet0
|
|
634
|
-
convert_code.push(
|
|
635
|
-
0xad, // i64.extend_i32_unsigned
|
|
636
|
-
0x10, 0x00, // Call function 0 (r = getTempRet0)
|
|
637
|
-
// join lower 32 bits and upper 32 bits
|
|
638
|
-
0xac, // i64.extend_i32_signed
|
|
639
|
-
0x42, 0x20, // i64.const 32
|
|
640
|
-
0x86, // i64.shl,
|
|
641
|
-
0x84 // i64.or
|
|
642
|
-
);
|
|
643
|
-
}
|
|
644
|
-
convert_code.push(0x0b); // end
|
|
645
|
-
|
|
646
|
-
var codeBody = [0x01]; // one code
|
|
647
|
-
uleb128Encode(convert_code.length, codeBody);
|
|
648
|
-
codeBody.push.apply(codeBody, convert_code);
|
|
649
|
-
var codeSection = [0x0a /* Code section code */];
|
|
650
|
-
uleb128Encode(codeBody.length, codeSection);
|
|
651
|
-
codeSection.push.apply(codeSection, codeBody);
|
|
652
|
-
sections.push(codeSection);
|
|
653
|
-
|
|
654
|
-
var bytes = new Uint8Array([].concat.apply([], sections));
|
|
655
|
-
// We can compile this wasm module synchronously because it is small.
|
|
656
|
-
var module = new WebAssembly.Module(bytes);
|
|
657
|
-
var instance = new WebAssembly.Instance(module, {
|
|
658
|
-
e: {
|
|
659
|
-
r: getTempRet0,
|
|
660
|
-
f: trampoline,
|
|
661
|
-
},
|
|
662
|
-
});
|
|
663
|
-
return instance.exports.f;
|
|
664
|
-
});
|
|
665
|
-
#endif
|
|
666
|
-
|
|
667
530
|
EM_JS_MACROS(
|
|
668
531
|
ffi_status,
|
|
669
532
|
ffi_prep_closure_loc_js,
|
|
670
533
|
(ffi_closure *closure, ffi_cif *cif, void *fun, void *user_data, void *codeloc),
|
|
671
534
|
{
|
|
535
|
+
closure = DEC_PTR(closure);
|
|
536
|
+
cif = DEC_PTR(cif);
|
|
537
|
+
fun = DEC_PTR(fun);
|
|
538
|
+
user_data = DEC_PTR(user_data);
|
|
539
|
+
codeloc = DEC_PTR(codeloc);
|
|
672
540
|
var abi = CIF__ABI(cif);
|
|
673
541
|
var nargs = CIF__NARGS(cif);
|
|
674
542
|
var nfixedargs = CIF__NFIXEDARGS(cif);
|
|
675
|
-
var arg_types_ptr = CIF__ARGTYPES(cif);
|
|
543
|
+
var arg_types_ptr = DEC_PTR(CIF__ARGTYPES(cif));
|
|
676
544
|
var rtype_unboxed = unbox_small_structs(CIF__RTYPE(cif));
|
|
677
545
|
var rtype_ptr = rtype_unboxed[0];
|
|
678
546
|
var rtype_id = rtype_unboxed[1];
|
|
@@ -688,7 +556,7 @@ ffi_prep_closure_loc_js,
|
|
|
688
556
|
case FFI_TYPE_STRUCT:
|
|
689
557
|
case FFI_TYPE_LONGDOUBLE:
|
|
690
558
|
// Return via a first pointer argument.
|
|
691
|
-
sig = '
|
|
559
|
+
sig = 'v' + PTR_SIG;
|
|
692
560
|
ret_by_arg = true;
|
|
693
561
|
break;
|
|
694
562
|
case FFI_TYPE_INT:
|
|
@@ -698,7 +566,6 @@ ffi_prep_closure_loc_js,
|
|
|
698
566
|
case FFI_TYPE_SINT16:
|
|
699
567
|
case FFI_TYPE_UINT32:
|
|
700
568
|
case FFI_TYPE_SINT32:
|
|
701
|
-
case FFI_TYPE_POINTER:
|
|
702
569
|
sig = 'i';
|
|
703
570
|
break;
|
|
704
571
|
case FFI_TYPE_FLOAT:
|
|
@@ -711,6 +578,9 @@ ffi_prep_closure_loc_js,
|
|
|
711
578
|
case FFI_TYPE_SINT64:
|
|
712
579
|
sig = 'j';
|
|
713
580
|
break;
|
|
581
|
+
case FFI_TYPE_POINTER:
|
|
582
|
+
sig = PTR_SIG;
|
|
583
|
+
break;
|
|
714
584
|
case FFI_TYPE_COMPLEX:
|
|
715
585
|
throw new Error('complex ret marshalling nyi');
|
|
716
586
|
default:
|
|
@@ -719,11 +589,11 @@ ffi_prep_closure_loc_js,
|
|
|
719
589
|
var unboxed_arg_type_id_list = [];
|
|
720
590
|
var unboxed_arg_type_info_list = [];
|
|
721
591
|
for (var i = 0; i < nargs; i++) {
|
|
722
|
-
var arg_unboxed = unbox_small_structs(
|
|
592
|
+
var arg_unboxed = unbox_small_structs(DEREF_PTR(arg_types_ptr, i));
|
|
723
593
|
var arg_type_ptr = arg_unboxed[0];
|
|
724
594
|
var arg_type_id = arg_unboxed[1];
|
|
725
595
|
unboxed_arg_type_id_list.push(arg_type_id);
|
|
726
|
-
unboxed_arg_type_info_list.push([FFI_TYPE__SIZE(arg_type_ptr), FFI_TYPE__ALIGN(arg_type_ptr)]);
|
|
596
|
+
unboxed_arg_type_info_list.push([DEC_PTR(FFI_TYPE__SIZE(arg_type_ptr)), FFI_TYPE__ALIGN(arg_type_ptr)]);
|
|
727
597
|
}
|
|
728
598
|
for (var i = 0; i < nfixedargs; i++) {
|
|
729
599
|
switch (unboxed_arg_type_id_list[i]) {
|
|
@@ -734,8 +604,6 @@ ffi_prep_closure_loc_js,
|
|
|
734
604
|
case FFI_TYPE_SINT16:
|
|
735
605
|
case FFI_TYPE_UINT32:
|
|
736
606
|
case FFI_TYPE_SINT32:
|
|
737
|
-
case FFI_TYPE_POINTER:
|
|
738
|
-
case FFI_TYPE_STRUCT:
|
|
739
607
|
sig += 'i';
|
|
740
608
|
break;
|
|
741
609
|
case FFI_TYPE_FLOAT:
|
|
@@ -751,6 +619,10 @@ ffi_prep_closure_loc_js,
|
|
|
751
619
|
case FFI_TYPE_SINT64:
|
|
752
620
|
sig += 'j';
|
|
753
621
|
break;
|
|
622
|
+
case FFI_TYPE_STRUCT:
|
|
623
|
+
case FFI_TYPE_POINTER:
|
|
624
|
+
sig += PTR_SIG;
|
|
625
|
+
break;
|
|
754
626
|
case FFI_TYPE_COMPLEX:
|
|
755
627
|
throw new Error('complex marshalling nyi');
|
|
756
628
|
default:
|
|
@@ -759,9 +631,9 @@ ffi_prep_closure_loc_js,
|
|
|
759
631
|
}
|
|
760
632
|
if (nfixedargs < nargs) {
|
|
761
633
|
// extra pointer to varargs stack
|
|
762
|
-
sig +=
|
|
634
|
+
sig += PTR_SIG;
|
|
763
635
|
}
|
|
764
|
-
LOG_DEBUG("CREATE_CLOSURE",
|
|
636
|
+
LOG_DEBUG("CREATE_CLOSURE", "sig:", sig);
|
|
765
637
|
function trampoline() {
|
|
766
638
|
var args = Array.prototype.slice.call(arguments);
|
|
767
639
|
var size = 0;
|
|
@@ -778,7 +650,7 @@ ffi_prep_closure_loc_js,
|
|
|
778
650
|
STACK_ALLOC(cur_ptr, 8, 8);
|
|
779
651
|
ret_ptr = cur_ptr;
|
|
780
652
|
}
|
|
781
|
-
cur_ptr -=
|
|
653
|
+
cur_ptr -= __SIZEOF_POINTER__ * nargs;
|
|
782
654
|
var args_ptr = cur_ptr;
|
|
783
655
|
var carg_idx = 0;
|
|
784
656
|
// Here we either have the actual argument, or a pair of BigInts for long
|
|
@@ -799,76 +671,62 @@ ffi_prep_closure_loc_js,
|
|
|
799
671
|
case FFI_TYPE_SINT8:
|
|
800
672
|
// Bad things happen if we don't align to 4 here
|
|
801
673
|
STACK_ALLOC(cur_ptr, 1, 4);
|
|
802
|
-
|
|
674
|
+
DEREF_PTR(args_ptr, carg_idx) = ENC_PTR(cur_ptr);
|
|
803
675
|
DEREF_U8(cur_ptr, 0) = cur_arg;
|
|
804
676
|
break;
|
|
805
677
|
case FFI_TYPE_UINT16:
|
|
806
678
|
case FFI_TYPE_SINT16:
|
|
807
679
|
// Bad things happen if we don't align to 4 here
|
|
808
680
|
STACK_ALLOC(cur_ptr, 2, 4);
|
|
809
|
-
|
|
681
|
+
DEREF_PTR(args_ptr, carg_idx) = ENC_PTR(cur_ptr);
|
|
810
682
|
DEREF_U16(cur_ptr, 0) = cur_arg;
|
|
811
683
|
break;
|
|
812
684
|
case FFI_TYPE_INT:
|
|
813
685
|
case FFI_TYPE_UINT32:
|
|
814
686
|
case FFI_TYPE_SINT32:
|
|
815
|
-
case FFI_TYPE_POINTER:
|
|
816
687
|
STACK_ALLOC(cur_ptr, 4, 4);
|
|
817
|
-
|
|
688
|
+
DEREF_PTR(args_ptr, carg_idx) = ENC_PTR(cur_ptr);
|
|
818
689
|
DEREF_U32(cur_ptr, 0) = cur_arg;
|
|
819
690
|
break;
|
|
820
691
|
case FFI_TYPE_STRUCT:
|
|
821
692
|
// cur_arg is already a pointer to struct
|
|
822
693
|
// copy it onto stack to pass by value
|
|
823
694
|
STACK_ALLOC(cur_ptr, arg_size, arg_align);
|
|
824
|
-
HEAP8.subarray(cur_ptr, cur_ptr + arg_size).set(HEAP8.subarray(cur_arg, cur_arg + arg_size));
|
|
825
|
-
|
|
695
|
+
HEAP8.subarray(cur_ptr, cur_ptr + arg_size).set(HEAP8.subarray(DEC_PTR(cur_arg), DEC_PTR(cur_arg) + arg_size));
|
|
696
|
+
DEREF_PTR(args_ptr, carg_idx) = ENC_PTR(cur_ptr);
|
|
826
697
|
break;
|
|
827
698
|
case FFI_TYPE_FLOAT:
|
|
828
699
|
STACK_ALLOC(cur_ptr, 4, 4);
|
|
829
|
-
|
|
700
|
+
DEREF_PTR(args_ptr, carg_idx) = ENC_PTR(cur_ptr);
|
|
830
701
|
DEREF_F32(cur_ptr, 0) = cur_arg;
|
|
831
702
|
break;
|
|
832
703
|
case FFI_TYPE_DOUBLE:
|
|
833
704
|
STACK_ALLOC(cur_ptr, 8, 8);
|
|
834
|
-
|
|
705
|
+
DEREF_PTR(args_ptr, carg_idx) = ENC_PTR(cur_ptr);
|
|
835
706
|
DEREF_F64(cur_ptr, 0) = cur_arg;
|
|
836
707
|
break;
|
|
837
708
|
case FFI_TYPE_UINT64:
|
|
838
709
|
case FFI_TYPE_SINT64:
|
|
839
710
|
STACK_ALLOC(cur_ptr, 8, 8);
|
|
840
|
-
|
|
841
|
-
#if WASM_BIGINT
|
|
711
|
+
DEREF_PTR(args_ptr, carg_idx) = ENC_PTR(cur_ptr);
|
|
842
712
|
DEREF_U64(cur_ptr, 0) = cur_arg;
|
|
843
|
-
#else
|
|
844
|
-
// Bigint arg was split by legalizer adaptor
|
|
845
|
-
DEREF_U32(cur_ptr, 0) = cur_arg;
|
|
846
|
-
cur_arg = args[jsarg_idx++];
|
|
847
|
-
DEREF_U32(cur_ptr, 1) = cur_arg;
|
|
848
|
-
#endif
|
|
849
713
|
break;
|
|
850
714
|
case FFI_TYPE_LONGDOUBLE:
|
|
851
715
|
STACK_ALLOC(cur_ptr, 16, 8);
|
|
852
|
-
|
|
853
|
-
#if WASM_BIGINT
|
|
716
|
+
DEREF_PTR(args_ptr, carg_idx) = ENC_PTR(cur_ptr);
|
|
854
717
|
DEREF_U64(cur_ptr, 0) = cur_arg;
|
|
855
718
|
cur_arg = args[jsarg_idx++];
|
|
856
719
|
DEREF_U64(cur_ptr, 1) = cur_arg;
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
cur_arg = args[jsarg_idx++];
|
|
863
|
-
DEREF_U32(cur_ptr, 2) = cur_arg;
|
|
864
|
-
cur_arg = args[jsarg_idx++];
|
|
865
|
-
DEREF_U32(cur_ptr, 3) = cur_arg;
|
|
866
|
-
#endif
|
|
720
|
+
break;
|
|
721
|
+
case FFI_TYPE_POINTER:
|
|
722
|
+
STACK_ALLOC(cur_ptr, __SIZEOF_POINTER__, __SIZEOF_POINTER__);
|
|
723
|
+
DEREF_PTR(args_ptr, carg_idx) = ENC_PTR(cur_ptr);
|
|
724
|
+
DEREF_PTR(cur_ptr, 0) = cur_arg;
|
|
867
725
|
break;
|
|
868
726
|
}
|
|
869
727
|
}
|
|
870
728
|
// If its a varargs call, last js argument is a pointer to the varargs.
|
|
871
|
-
var varargs = args[args.length - 1];
|
|
729
|
+
var varargs = DEC_PTR(args[args.length - 1]);
|
|
872
730
|
// We have no way of knowing how many varargs were actually provided, this
|
|
873
731
|
// fills the rest of the stack space allocated with nonsense. The onward
|
|
874
732
|
// call will know to ignore the nonsense.
|
|
@@ -884,20 +742,20 @@ ffi_prep_closure_loc_js,
|
|
|
884
742
|
if (arg_type_id === FFI_TYPE_STRUCT) {
|
|
885
743
|
// In this case varargs is a pointer to pointer to struct so we need to
|
|
886
744
|
// deref once
|
|
887
|
-
var struct_ptr =
|
|
745
|
+
var struct_ptr = DEREF_PTR_NUMBER(varargs, 0);
|
|
888
746
|
STACK_ALLOC(cur_ptr, arg_size, arg_align);
|
|
889
747
|
HEAP8.subarray(cur_ptr, cur_ptr + arg_size).set(HEAP8.subarray(struct_ptr, struct_ptr + arg_size));
|
|
890
|
-
|
|
748
|
+
DEREF_PTR(args_ptr, carg_idx) = ENC_PTR(cur_ptr);
|
|
891
749
|
} else {
|
|
892
|
-
|
|
750
|
+
DEREF_PTR(args_ptr, carg_idx) = ENC_PTR(varargs);
|
|
893
751
|
}
|
|
894
|
-
varargs +=
|
|
752
|
+
varargs += __SIZEOF_POINTER__;
|
|
895
753
|
}
|
|
896
754
|
stackRestore(cur_ptr);
|
|
897
755
|
stackAlloc(0); // stackAlloc enforces alignment invariants on the stack pointer
|
|
898
|
-
LOG_DEBUG("CALL_CLOSURE",
|
|
756
|
+
LOG_DEBUG("CALL_CLOSURE", "closure:", closure, "fptr", CLOSURE__fun(closure), "cif", CLOSURE__cif(closure));
|
|
899
757
|
getWasmTableEntry(CLOSURE__fun(closure))(
|
|
900
|
-
CLOSURE__cif(closure), ret_ptr, args_ptr,
|
|
758
|
+
CLOSURE__cif(closure), ENC_PTR(ret_ptr), ENC_PTR(args_ptr),
|
|
901
759
|
CLOSURE__user_data(closure)
|
|
902
760
|
);
|
|
903
761
|
stackRestore(orig_stack_ptr);
|
|
@@ -905,33 +763,26 @@ ffi_prep_closure_loc_js,
|
|
|
905
763
|
// If we aren't supposed to return by argument, figure out what to return.
|
|
906
764
|
if (!ret_by_arg) {
|
|
907
765
|
switch (sig[0]) {
|
|
908
|
-
case
|
|
766
|
+
case 'i':
|
|
909
767
|
return DEREF_U32(ret_ptr, 0);
|
|
910
|
-
case
|
|
911
|
-
#if WASM_BIGINT
|
|
768
|
+
case 'j':
|
|
912
769
|
return DEREF_U64(ret_ptr, 0);
|
|
913
|
-
|
|
914
|
-
// Split the return i64, set the upper 32 bits into tempRet0 and return
|
|
915
|
-
// the lower 32 bits.
|
|
916
|
-
setTempRet0(DEREF_U32(ret_ptr, 1));
|
|
917
|
-
return DEREF_U32(ret_ptr, 0);
|
|
918
|
-
#endif
|
|
919
|
-
case "d":
|
|
770
|
+
case 'd':
|
|
920
771
|
return DEREF_F64(ret_ptr, 0);
|
|
921
|
-
case
|
|
772
|
+
case 'f':
|
|
922
773
|
return DEREF_F32(ret_ptr, 0);
|
|
923
774
|
}
|
|
924
775
|
}
|
|
925
776
|
}
|
|
926
777
|
try {
|
|
927
|
-
var wasm_trampoline =
|
|
778
|
+
var wasm_trampoline = convertJsFunctionToWasm(trampoline, sig);
|
|
928
779
|
} catch(e) {
|
|
929
780
|
return FFI_BAD_TYPEDEF_MACRO;
|
|
930
781
|
}
|
|
931
782
|
setWasmTableEntry(codeloc, wasm_trampoline);
|
|
932
|
-
CLOSURE__cif(closure) = cif;
|
|
933
|
-
CLOSURE__fun(closure) = fun;
|
|
934
|
-
CLOSURE__user_data(closure) = user_data;
|
|
783
|
+
CLOSURE__cif(closure) = ENC_PTR(cif);
|
|
784
|
+
CLOSURE__fun(closure) = ENC_PTR(fun);
|
|
785
|
+
CLOSURE__user_data(closure) = ENC_PTR(user_data);
|
|
935
786
|
return FFI_OK_MACRO;
|
|
936
787
|
})
|
|
937
788
|
|
|
@@ -940,7 +791,7 @@ ffi_prep_closure_loc_js,
|
|
|
940
791
|
ffi_status ffi_prep_closure_loc(ffi_closure *closure, ffi_cif *cif,
|
|
941
792
|
void (*fun)(ffi_cif *, void *, void **, void *),
|
|
942
793
|
void *user_data, void *codeloc) {
|
|
943
|
-
if (cif->abi !=
|
|
794
|
+
if (cif->abi != FFI_EMSCRIPTEN_ABI)
|
|
944
795
|
return FFI_BAD_ABI;
|
|
945
796
|
return ffi_prep_closure_loc_js(closure, cif, (void *)fun, user_data,
|
|
946
797
|
codeloc);
|