ffi 1.17.2 → 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.
Files changed (90) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +25 -0
  4. data/Gemfile +7 -4
  5. data/README.md +1 -0
  6. data/Rakefile +7 -4
  7. data/Steepfile +8 -0
  8. data/ext/ffi_c/DynamicLibrary.c +1 -1
  9. data/ext/ffi_c/Function.c +2 -0
  10. data/ext/ffi_c/MethodHandle.c +4 -2
  11. data/ext/ffi_c/libffi/.ci/Containerfile.ppc64le +12 -0
  12. data/ext/ffi_c/libffi/.ci/build.sh +38 -33
  13. data/ext/ffi_c/libffi/.ci/install.sh +46 -50
  14. data/ext/ffi_c/libffi/.ci/site.exp +6 -0
  15. data/ext/ffi_c/libffi/.gail-labels +44 -0
  16. data/ext/ffi_c/libffi/.github/workflows/build.yml +212 -333
  17. data/ext/ffi_c/libffi/.github/workflows/emscripten.yml +58 -3
  18. data/ext/ffi_c/libffi/.github/workflows/label-new-issue.yaml +15 -0
  19. data/ext/ffi_c/libffi/.github/workflows/tarball.yml +55 -0
  20. data/ext/ffi_c/libffi/LICENSE +1 -1
  21. data/ext/ffi_c/libffi/Makefile.am +17 -13
  22. data/ext/ffi_c/libffi/Makefile.in +37 -30
  23. data/ext/ffi_c/libffi/README.md +22 -3
  24. data/ext/ffi_c/libffi/configure +105 -121
  25. data/ext/ffi_c/libffi/configure.ac +21 -8
  26. data/ext/ffi_c/libffi/configure.host +6 -1
  27. data/ext/ffi_c/libffi/doc/Makefile.in +3 -0
  28. data/ext/ffi_c/libffi/doc/libffi.texi +24 -1
  29. data/ext/ffi_c/libffi/doc/version.texi +4 -4
  30. data/ext/ffi_c/libffi/generate-darwin-source-and-headers.py +1 -28
  31. data/ext/ffi_c/libffi/include/Makefile.in +3 -0
  32. data/ext/ffi_c/libffi/include/ffi.h.in +19 -1
  33. data/ext/ffi_c/libffi/libffi.map.in +13 -1
  34. data/ext/ffi_c/libffi/libtool-version +1 -1
  35. data/ext/ffi_c/libffi/m4/asmcfi.m4 +28 -11
  36. data/ext/ffi_c/libffi/m4/ax_check_compile_flag.m4 +13 -3
  37. data/ext/ffi_c/libffi/man/Makefile.in +3 -0
  38. data/ext/ffi_c/libffi/src/aarch64/sysv.S +7 -1
  39. data/ext/ffi_c/libffi/src/arm/sysv.S +1 -1
  40. data/ext/ffi_c/libffi/src/pa/linux.S +4 -0
  41. data/ext/ffi_c/libffi/src/powerpc/ffi.c +6 -0
  42. data/ext/ffi_c/libffi/src/riscv/ffi.c +39 -16
  43. data/ext/ffi_c/libffi/src/riscv/internal.h +7 -0
  44. data/ext/ffi_c/libffi/src/riscv/sysv.S +24 -0
  45. data/ext/ffi_c/libffi/src/tramp.c +6 -1
  46. data/ext/ffi_c/libffi/src/types.c +23 -1
  47. data/ext/ffi_c/libffi/src/{wasm32 → wasm}/ffi.c +157 -54
  48. data/ext/ffi_c/libffi/src/{wasm32 → wasm}/ffitarget.h +17 -0
  49. data/ext/ffi_c/libffi/src/x86/ffitarget.h +0 -3
  50. data/ext/ffi_c/libffi/src/x86/sysv.S +1 -3
  51. data/ext/ffi_c/libffi/src/x86/sysv_intel.S +1 -3
  52. data/ext/ffi_c/libffi/testsuite/Makefile.am +3 -2
  53. data/ext/ffi_c/libffi/testsuite/Makefile.in +6 -2
  54. data/ext/ffi_c/libffi/testsuite/emscripten/build.sh +2 -2
  55. data/ext/ffi_c/libffi/testsuite/emscripten/node-tests.sh +4 -4
  56. data/ext/ffi_c/libffi/testsuite/lib/libffi.exp +269 -256
  57. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/testcases.c +1 -1
  58. data/ext/ffi_c/libffi/testsuite/libffi.call/ffitest.h +3 -0
  59. data/ext/ffi_c/libffi/testsuite/libffi.call/longjmp.c +60 -0
  60. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_dbls_struct.c +1 -1
  61. data/ext/ffi_c/libffi/testsuite/libffi.closures/huge_struct.c +1 -2
  62. data/ext/ffi_c/libffi/testsuite/libffi.closures/unwindtest.cc +2 -0
  63. data/ext/ffi_c/libffi/testsuite/libffi.closures/unwindtest_ffi_call.cc +2 -0
  64. data/ext/ffi_c/libffi/testsuite/libffi.threads/ffitest.h +1 -0
  65. data/ext/ffi_c/libffi/testsuite/libffi.threads/threads.exp +50 -0
  66. data/ext/ffi_c/libffi/testsuite/libffi.threads/tsan.c +74 -0
  67. data/ext/ffi_c/libffi.mk +5 -0
  68. data/ffi.gemspec +4 -5
  69. data/lib/ffi/autopointer.rb +6 -0
  70. data/lib/ffi/compat.rb +11 -0
  71. data/lib/ffi/function.rb +23 -0
  72. data/lib/ffi/library.rb +19 -3
  73. data/lib/ffi/struct_by_reference.rb +1 -1
  74. data/lib/ffi/version.rb +1 -1
  75. data/samples/hello_ractor.rb +9 -1
  76. data/samples/qsort_ractor.rb +9 -1
  77. data/sig/ffi/auto_pointer.rbs +1 -1
  78. data/sig/ffi/errno.rbs +8 -0
  79. data/sig/ffi/platform.rbs +49 -0
  80. data/sig/ffi/struct.rbs +2 -2
  81. data/sig/ffi/struct_by_reference.rbs +1 -1
  82. data/sig/ffi.rbs +4 -1
  83. data.tar.gz.sig +0 -0
  84. metadata +33 -79
  85. metadata.gz.sig +0 -0
  86. data/ext/ffi_c/libffi/.appveyor/site.exp +0 -16
  87. data/ext/ffi_c/libffi/.appveyor.yml +0 -84
  88. data/lib/ffi/tools/types_generator.rb +0 -137
  89. data/rakelib/ffi_gem_helper.rb +0 -65
  90. /data/ext/ffi_c/libffi/{.appveyor → .ci}/unix-noexec.exp +0 -0
@@ -59,16 +59,29 @@ EM_JS_DEPS(libffi, "$getWasmTableEntry,$setWasmTableEntry,$getEmptyTableSlot,$co
59
59
  offsetof(struct, field) == offset, \
60
60
  "Memory layout of '" #struct "' has changed: '" #field "' is in an unexpected location");
61
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
+
62
73
  CHECK_FIELD_OFFSET(ffi_cif, abi, 4*0);
63
74
  CHECK_FIELD_OFFSET(ffi_cif, nargs, 4*1);
64
75
  CHECK_FIELD_OFFSET(ffi_cif, arg_types, 4*2);
65
76
  CHECK_FIELD_OFFSET(ffi_cif, rtype, 4*3);
77
+ CHECK_FIELD_OFFSET(ffi_cif, flags, 4*5);
66
78
  CHECK_FIELD_OFFSET(ffi_cif, nfixedargs, 4*6);
67
79
 
68
80
  #define CIF__ABI(addr) DEREF_U32(addr, 0)
69
81
  #define CIF__NARGS(addr) DEREF_U32(addr, 1)
70
82
  #define CIF__ARGTYPES(addr) DEREF_U32(addr, 2)
71
83
  #define CIF__RTYPE(addr) DEREF_U32(addr, 3)
84
+ #define CIF__FLAGS(addr) DEREF_U32(addr, 5)
72
85
  #define CIF__NFIXEDARGS(addr) DEREF_U32(addr, 6)
73
86
 
74
87
  CHECK_FIELD_OFFSET(ffi_type, size, 0);
@@ -81,6 +94,49 @@ CHECK_FIELD_OFFSET(ffi_type, elements, 8);
81
94
  #define FFI_TYPE__TYPEID(addr) DEREF_U16(addr + 6, 0)
82
95
  #define FFI_TYPE__ELEMENTS(addr) DEREF_U32(addr + 8, 0)
83
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
+
84
140
  #define ALIGN_ADDRESS(addr, align) (addr &= (~((align) - 1)))
85
141
  #define STACK_ALLOC(stack, size, align) ((stack -= (size)), ALIGN_ADDRESS(stack, align))
86
142
 
@@ -100,7 +156,7 @@ _Static_assert(FFI_BAD_TYPEDEF_MACRO == FFI_BAD_TYPEDEF, "FFI_BAD_TYPEDEF must b
100
156
  ffi_status FFI_HIDDEN
101
157
  ffi_prep_cif_machdep(ffi_cif *cif)
102
158
  {
103
- if (cif->abi != FFI_WASM32_EMSCRIPTEN)
159
+ if (cif->abi != FFI_EMSCRIPTEN_ABI)
104
160
  return FFI_BAD_ABI;
105
161
  // This is called after ffi_prep_cif_machdep_var so we need to avoid
106
162
  // overwriting cif->nfixedargs.
@@ -144,6 +200,7 @@ ffi_prep_cif_machdep_var(ffi_cif *cif, unsigned nfixedargs, unsigned ntotalargs)
144
200
  EM_JS_MACROS(
145
201
  void,
146
202
  unbox_small_structs, (ffi_type type_ptr), {
203
+ type_ptr = DEC_PTR(type_ptr);
147
204
  var type_id = FFI_TYPE__TYPEID(type_ptr);
148
205
  while (type_id === FFI_TYPE_STRUCT) {
149
206
  // Don't unbox single element structs if they are bigger than 16 bytes. This
@@ -156,15 +213,15 @@ unbox_small_structs, (ffi_type type_ptr), {
156
213
  //
157
214
  // See the Python comment here:
158
215
  // https://github.com/python/cpython/blob/a16a9f978f42b8a09297c1efbf33877f6388c403/Modules/_ctypes/stgdict.c#L718-L779
159
- if (FFI_TYPE__SIZE(type_ptr) > 16) {
216
+ if (DEC_PTR(FFI_TYPE__SIZE(type_ptr)) > 16) {
160
217
  break;
161
218
  }
162
- var elements = FFI_TYPE__ELEMENTS(type_ptr);
163
- var first_element = DEREF_U32(elements, 0);
219
+ var elements = DEC_PTR(FFI_TYPE__ELEMENTS(type_ptr));
220
+ var first_element = DEREF_PTR_NUMBER(elements, 0);
164
221
  if (first_element === 0) {
165
222
  type_id = FFI_TYPE_VOID;
166
223
  break;
167
- } else if (DEREF_U32(elements, 1) === 0) {
224
+ } else if (DEREF_PTR_NUMBER(elements, 1) === 0) {
168
225
  type_ptr = first_element;
169
226
  type_id = FFI_TYPE__TYPEID(first_element);
170
227
  } else {
@@ -178,10 +235,15 @@ EM_JS_MACROS(
178
235
  void,
179
236
  ffi_call_js, (ffi_cif *cif, ffi_fp fn, void *rvalue, void **avalue),
180
237
  {
238
+ cif = DEC_PTR(cif);
239
+ fn = DEC_PTR(fn);
240
+ rvalue = DEC_PTR(rvalue);
241
+ avalue = DEC_PTR(avalue);
181
242
  var abi = CIF__ABI(cif);
182
243
  var nargs = CIF__NARGS(cif);
183
244
  var nfixedargs = CIF__NFIXEDARGS(cif);
184
- var arg_types_ptr = CIF__ARGTYPES(cif);
245
+ var arg_types_ptr = DEC_PTR(CIF__ARGTYPES(cif));
246
+ var flags = CIF__FLAGS(cif);
185
247
  var rtype_unboxed = unbox_small_structs(CIF__RTYPE(cif));
186
248
  var rtype_ptr = rtype_unboxed[0];
187
249
  var rtype_id = rtype_unboxed[1];
@@ -205,7 +267,7 @@ ffi_call_js, (ffi_cif *cif, ffi_fp fn, void *rvalue, void **avalue),
205
267
  // just use this. We also mark a flag that we don't need to convert the return
206
268
  // value of the dynamic call back to C.
207
269
  if (rtype_id === FFI_TYPE_LONGDOUBLE || rtype_id === FFI_TYPE_STRUCT) {
208
- args.push(rvalue);
270
+ args.push(ENC_PTR(rvalue));
209
271
  ret_by_arg = true;
210
272
  }
211
273
 
@@ -214,8 +276,8 @@ ffi_call_js, (ffi_cif *cif, ffi_fp fn, void *rvalue, void **avalue),
214
276
  // Javascript to C automatically, here we manually do the inverse conversion
215
277
  // from C to Javascript.
216
278
  for (var i = 0; i < nfixedargs; i++) {
217
- var arg_ptr = DEREF_U32(avalue, i);
218
- var arg_unboxed = unbox_small_structs(DEREF_U32(arg_types_ptr, i));
279
+ var arg_ptr = DEREF_PTR_NUMBER(avalue, i);
280
+ var arg_unboxed = unbox_small_structs(DEREF_PTR(arg_types_ptr, i));
219
281
  var arg_type_ptr = arg_unboxed[0];
220
282
  var arg_type_id = arg_unboxed[1];
221
283
 
@@ -226,7 +288,6 @@ ffi_call_js, (ffi_cif *cif, ffi_fp fn, void *rvalue, void **avalue),
226
288
  case FFI_TYPE_INT:
227
289
  case FFI_TYPE_SINT32:
228
290
  case FFI_TYPE_UINT32:
229
- case FFI_TYPE_POINTER:
230
291
  args.push(DEREF_U32(arg_ptr, 0));
231
292
  break;
232
293
  case FFI_TYPE_FLOAT:
@@ -260,11 +321,14 @@ ffi_call_js, (ffi_cif *cif, ffi_fp fn, void *rvalue, void **avalue),
260
321
  // Nontrivial structs are passed by pointer.
261
322
  // Have to copy the struct onto the stack though because C ABI says it's
262
323
  // call by value.
263
- var size = FFI_TYPE__SIZE(arg_type_ptr);
324
+ var size = DEC_PTR(FFI_TYPE__SIZE(arg_type_ptr));
264
325
  var align = FFI_TYPE__ALIGN(arg_type_ptr);
265
326
  STACK_ALLOC(cur_stack_ptr, size, align);
266
327
  HEAP8.subarray(cur_stack_ptr, cur_stack_ptr+size).set(HEAP8.subarray(arg_ptr, arg_ptr + size));
267
- args.push(cur_stack_ptr);
328
+ args.push(ENC_PTR(cur_stack_ptr));
329
+ break;
330
+ case FFI_TYPE_POINTER:
331
+ args.push(DEREF_PTR(arg_ptr, 0));
268
332
  break;
269
333
  case FFI_TYPE_COMPLEX:
270
334
  throw new Error('complex marshalling nyi');
@@ -282,11 +346,11 @@ ffi_call_js, (ffi_cif *cif, ffi_fp fn, void *rvalue, void **avalue),
282
346
  // We don't have any way of knowing how many args were actually passed, so we
283
347
  // just always copy extra nonsense past the end. The ownwards call will know
284
348
  // not to look at it.
285
- if (nfixedargs != nargs) {
349
+ if (flags & VARARGS_FLAG) {
286
350
  var struct_arg_info = [];
287
351
  for (var i = nargs - 1; i >= nfixedargs; i--) {
288
- var arg_ptr = DEREF_U32(avalue, i);
289
- var arg_unboxed = unbox_small_structs(DEREF_U32(arg_types_ptr, i));
352
+ var arg_ptr = DEREF_PTR_NUMBER(avalue, i);
353
+ var arg_unboxed = unbox_small_structs(DEREF_PTR(arg_types_ptr, i));
290
354
  var arg_type_ptr = arg_unboxed[0];
291
355
  var arg_type_id = arg_unboxed[1];
292
356
  switch (arg_type_id) {
@@ -303,7 +367,6 @@ ffi_call_js, (ffi_cif *cif, ffi_fp fn, void *rvalue, void **avalue),
303
367
  case FFI_TYPE_INT:
304
368
  case FFI_TYPE_UINT32:
305
369
  case FFI_TYPE_SINT32:
306
- case FFI_TYPE_POINTER:
307
370
  case FFI_TYPE_FLOAT:
308
371
  STACK_ALLOC(cur_stack_ptr, 4, 4);
309
372
  DEREF_U32(cur_stack_ptr, 0) = DEREF_U32(arg_ptr, 0);
@@ -326,8 +389,12 @@ ffi_call_js, (ffi_cif *cif, ffi_fp fn, void *rvalue, void **avalue),
326
389
  // Again, struct must be passed by pointer.
327
390
  // But ABI is by value, so have to copy struct onto stack.
328
391
  // Currently arguments are going onto stack so we can't put it there now. Come back for this.
329
- STACK_ALLOC(cur_stack_ptr, 4, 4);
330
- 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);
331
398
  break;
332
399
  case FFI_TYPE_COMPLEX:
333
400
  throw new Error('complex arg marshalling nyi');
@@ -336,7 +403,7 @@ ffi_call_js, (ffi_cif *cif, ffi_fp fn, void *rvalue, void **avalue),
336
403
  }
337
404
  }
338
405
  // extra normal argument which is the pointer to the varargs.
339
- args.push(cur_stack_ptr);
406
+ args.push(ENC_PTR(cur_stack_ptr));
340
407
  // Now allocate variable struct args on stack too.
341
408
  for (var i = 0; i < struct_arg_info.length; i++) {
342
409
  var struct_info = struct_arg_info[i];
@@ -346,7 +413,7 @@ ffi_call_js, (ffi_cif *cif, ffi_fp fn, void *rvalue, void **avalue),
346
413
  var align = struct_info[3];
347
414
  STACK_ALLOC(cur_stack_ptr, size, align);
348
415
  HEAP8.subarray(cur_stack_ptr, cur_stack_ptr+size).set(HEAP8.subarray(arg_ptr, arg_ptr + size));
349
- DEREF_U32(arg_target, 0) = cur_stack_ptr;
416
+ DEREF_PTR(arg_target, 0) = ENC_PTR(cur_stack_ptr);
350
417
  }
351
418
  }
352
419
  stackRestore(cur_stack_ptr);
@@ -371,7 +438,6 @@ ffi_call_js, (ffi_cif *cif, ffi_fp fn, void *rvalue, void **avalue),
371
438
  case FFI_TYPE_INT:
372
439
  case FFI_TYPE_UINT32:
373
440
  case FFI_TYPE_SINT32:
374
- case FFI_TYPE_POINTER:
375
441
  DEREF_U32(rvalue, 0) = result;
376
442
  break;
377
443
  case FFI_TYPE_FLOAT:
@@ -392,6 +458,9 @@ ffi_call_js, (ffi_cif *cif, ffi_fp fn, void *rvalue, void **avalue),
392
458
  case FFI_TYPE_SINT64:
393
459
  DEREF_U64(rvalue, 0) = result;
394
460
  break;
461
+ case FFI_TYPE_POINTER:
462
+ DEREF_PTR(rvalue, 0) = result;
463
+ break;
395
464
  case FFI_TYPE_COMPLEX:
396
465
  throw new Error('complex ret marshalling nyi');
397
466
  default:
@@ -403,6 +472,8 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) {
403
472
  ffi_call_js(cif, fn, rvalue, avalue);
404
473
  }
405
474
 
475
+ #if __SIZEOF_POINTER__ == 4
476
+
406
477
  CHECK_FIELD_OFFSET(ffi_closure, ftramp, 4*0);
407
478
  CHECK_FIELD_OFFSET(ffi_closure, cif, 4*1);
408
479
  CHECK_FIELD_OFFSET(ffi_closure, fun, 4*2);
@@ -413,12 +484,30 @@ CHECK_FIELD_OFFSET(ffi_closure, user_data, 4*3);
413
484
  #define CLOSURE__fun(addr) DEREF_U32(addr, 2)
414
485
  #define CLOSURE__user_data(addr) DEREF_U32(addr, 3)
415
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
+
416
503
  EM_JS_MACROS(void *, ffi_closure_alloc_js, (size_t size, void **code), {
504
+ size = DEC_PTR(size);
505
+ code = DEC_PTR(code);
417
506
  var closure = _malloc(size);
418
507
  var index = getEmptyTableSlot();
419
- DEREF_U32(code, 0) = index;
420
- CLOSURE__wrapper(closure) = index;
421
- return closure;
508
+ DEREF_PTR(code, 0) = ENC_PTR(index);
509
+ CLOSURE__wrapper(closure) = ENC_PTR(index);
510
+ return ENC_PTR(closure);
422
511
  })
423
512
 
424
513
  void * __attribute__ ((visibility ("default")))
@@ -427,7 +516,8 @@ ffi_closure_alloc(size_t size, void **code) {
427
516
  }
428
517
 
429
518
  EM_JS_MACROS(void, ffi_closure_free_js, (void *closure), {
430
- var index = CLOSURE__wrapper(closure);
519
+ closure = DEC_PTR(closure);
520
+ var index = DEC_PTR(CLOSURE__wrapper(closure));
431
521
  freeTableIndexes.push(index);
432
522
  _free(closure);
433
523
  })
@@ -442,10 +532,15 @@ ffi_status,
442
532
  ffi_prep_closure_loc_js,
443
533
  (ffi_closure *closure, ffi_cif *cif, void *fun, void *user_data, void *codeloc),
444
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);
445
540
  var abi = CIF__ABI(cif);
446
541
  var nargs = CIF__NARGS(cif);
447
542
  var nfixedargs = CIF__NFIXEDARGS(cif);
448
- var arg_types_ptr = CIF__ARGTYPES(cif);
543
+ var arg_types_ptr = DEC_PTR(CIF__ARGTYPES(cif));
449
544
  var rtype_unboxed = unbox_small_structs(CIF__RTYPE(cif));
450
545
  var rtype_ptr = rtype_unboxed[0];
451
546
  var rtype_id = rtype_unboxed[1];
@@ -461,7 +556,7 @@ ffi_prep_closure_loc_js,
461
556
  case FFI_TYPE_STRUCT:
462
557
  case FFI_TYPE_LONGDOUBLE:
463
558
  // Return via a first pointer argument.
464
- sig = 'vi';
559
+ sig = 'v' + PTR_SIG;
465
560
  ret_by_arg = true;
466
561
  break;
467
562
  case FFI_TYPE_INT:
@@ -471,7 +566,6 @@ ffi_prep_closure_loc_js,
471
566
  case FFI_TYPE_SINT16:
472
567
  case FFI_TYPE_UINT32:
473
568
  case FFI_TYPE_SINT32:
474
- case FFI_TYPE_POINTER:
475
569
  sig = 'i';
476
570
  break;
477
571
  case FFI_TYPE_FLOAT:
@@ -484,6 +578,9 @@ ffi_prep_closure_loc_js,
484
578
  case FFI_TYPE_SINT64:
485
579
  sig = 'j';
486
580
  break;
581
+ case FFI_TYPE_POINTER:
582
+ sig = PTR_SIG;
583
+ break;
487
584
  case FFI_TYPE_COMPLEX:
488
585
  throw new Error('complex ret marshalling nyi');
489
586
  default:
@@ -492,11 +589,11 @@ ffi_prep_closure_loc_js,
492
589
  var unboxed_arg_type_id_list = [];
493
590
  var unboxed_arg_type_info_list = [];
494
591
  for (var i = 0; i < nargs; i++) {
495
- var arg_unboxed = unbox_small_structs(DEREF_U32(arg_types_ptr, i));
592
+ var arg_unboxed = unbox_small_structs(DEREF_PTR(arg_types_ptr, i));
496
593
  var arg_type_ptr = arg_unboxed[0];
497
594
  var arg_type_id = arg_unboxed[1];
498
595
  unboxed_arg_type_id_list.push(arg_type_id);
499
- 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)]);
500
597
  }
501
598
  for (var i = 0; i < nfixedargs; i++) {
502
599
  switch (unboxed_arg_type_id_list[i]) {
@@ -507,8 +604,6 @@ ffi_prep_closure_loc_js,
507
604
  case FFI_TYPE_SINT16:
508
605
  case FFI_TYPE_UINT32:
509
606
  case FFI_TYPE_SINT32:
510
- case FFI_TYPE_POINTER:
511
- case FFI_TYPE_STRUCT:
512
607
  sig += 'i';
513
608
  break;
514
609
  case FFI_TYPE_FLOAT:
@@ -524,6 +619,10 @@ ffi_prep_closure_loc_js,
524
619
  case FFI_TYPE_SINT64:
525
620
  sig += 'j';
526
621
  break;
622
+ case FFI_TYPE_STRUCT:
623
+ case FFI_TYPE_POINTER:
624
+ sig += PTR_SIG;
625
+ break;
527
626
  case FFI_TYPE_COMPLEX:
528
627
  throw new Error('complex marshalling nyi');
529
628
  default:
@@ -532,7 +631,7 @@ ffi_prep_closure_loc_js,
532
631
  }
533
632
  if (nfixedargs < nargs) {
534
633
  // extra pointer to varargs stack
535
- sig += 'i';
634
+ sig += PTR_SIG;
536
635
  }
537
636
  LOG_DEBUG("CREATE_CLOSURE", "sig:", sig);
538
637
  function trampoline() {
@@ -551,7 +650,7 @@ ffi_prep_closure_loc_js,
551
650
  STACK_ALLOC(cur_ptr, 8, 8);
552
651
  ret_ptr = cur_ptr;
553
652
  }
554
- cur_ptr -= 4 * nargs;
653
+ cur_ptr -= __SIZEOF_POINTER__ * nargs;
555
654
  var args_ptr = cur_ptr;
556
655
  var carg_idx = 0;
557
656
  // Here we either have the actual argument, or a pair of BigInts for long
@@ -572,58 +671,62 @@ ffi_prep_closure_loc_js,
572
671
  case FFI_TYPE_SINT8:
573
672
  // Bad things happen if we don't align to 4 here
574
673
  STACK_ALLOC(cur_ptr, 1, 4);
575
- DEREF_U32(args_ptr, carg_idx) = cur_ptr;
674
+ DEREF_PTR(args_ptr, carg_idx) = ENC_PTR(cur_ptr);
576
675
  DEREF_U8(cur_ptr, 0) = cur_arg;
577
676
  break;
578
677
  case FFI_TYPE_UINT16:
579
678
  case FFI_TYPE_SINT16:
580
679
  // Bad things happen if we don't align to 4 here
581
680
  STACK_ALLOC(cur_ptr, 2, 4);
582
- DEREF_U32(args_ptr, carg_idx) = cur_ptr;
681
+ DEREF_PTR(args_ptr, carg_idx) = ENC_PTR(cur_ptr);
583
682
  DEREF_U16(cur_ptr, 0) = cur_arg;
584
683
  break;
585
684
  case FFI_TYPE_INT:
586
685
  case FFI_TYPE_UINT32:
587
686
  case FFI_TYPE_SINT32:
588
- case FFI_TYPE_POINTER:
589
687
  STACK_ALLOC(cur_ptr, 4, 4);
590
- DEREF_U32(args_ptr, carg_idx) = cur_ptr;
688
+ DEREF_PTR(args_ptr, carg_idx) = ENC_PTR(cur_ptr);
591
689
  DEREF_U32(cur_ptr, 0) = cur_arg;
592
690
  break;
593
691
  case FFI_TYPE_STRUCT:
594
692
  // cur_arg is already a pointer to struct
595
693
  // copy it onto stack to pass by value
596
694
  STACK_ALLOC(cur_ptr, arg_size, arg_align);
597
- HEAP8.subarray(cur_ptr, cur_ptr + arg_size).set(HEAP8.subarray(cur_arg, cur_arg + arg_size));
598
- DEREF_U32(args_ptr, carg_idx) = cur_ptr;
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);
599
697
  break;
600
698
  case FFI_TYPE_FLOAT:
601
699
  STACK_ALLOC(cur_ptr, 4, 4);
602
- DEREF_U32(args_ptr, carg_idx) = cur_ptr;
700
+ DEREF_PTR(args_ptr, carg_idx) = ENC_PTR(cur_ptr);
603
701
  DEREF_F32(cur_ptr, 0) = cur_arg;
604
702
  break;
605
703
  case FFI_TYPE_DOUBLE:
606
704
  STACK_ALLOC(cur_ptr, 8, 8);
607
- DEREF_U32(args_ptr, carg_idx) = cur_ptr;
705
+ DEREF_PTR(args_ptr, carg_idx) = ENC_PTR(cur_ptr);
608
706
  DEREF_F64(cur_ptr, 0) = cur_arg;
609
707
  break;
610
708
  case FFI_TYPE_UINT64:
611
709
  case FFI_TYPE_SINT64:
612
710
  STACK_ALLOC(cur_ptr, 8, 8);
613
- DEREF_U32(args_ptr, carg_idx) = cur_ptr;
711
+ DEREF_PTR(args_ptr, carg_idx) = ENC_PTR(cur_ptr);
614
712
  DEREF_U64(cur_ptr, 0) = cur_arg;
615
713
  break;
616
714
  case FFI_TYPE_LONGDOUBLE:
617
715
  STACK_ALLOC(cur_ptr, 16, 8);
618
- DEREF_U32(args_ptr, carg_idx) = cur_ptr;
716
+ DEREF_PTR(args_ptr, carg_idx) = ENC_PTR(cur_ptr);
619
717
  DEREF_U64(cur_ptr, 0) = cur_arg;
620
718
  cur_arg = args[jsarg_idx++];
621
719
  DEREF_U64(cur_ptr, 1) = cur_arg;
622
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;
725
+ break;
623
726
  }
624
727
  }
625
728
  // If its a varargs call, last js argument is a pointer to the varargs.
626
- var varargs = args[args.length - 1];
729
+ var varargs = DEC_PTR(args[args.length - 1]);
627
730
  // We have no way of knowing how many varargs were actually provided, this
628
731
  // fills the rest of the stack space allocated with nonsense. The onward
629
732
  // call will know to ignore the nonsense.
@@ -639,20 +742,20 @@ ffi_prep_closure_loc_js,
639
742
  if (arg_type_id === FFI_TYPE_STRUCT) {
640
743
  // In this case varargs is a pointer to pointer to struct so we need to
641
744
  // deref once
642
- var struct_ptr = DEREF_U32(varargs, 0);
745
+ var struct_ptr = DEREF_PTR_NUMBER(varargs, 0);
643
746
  STACK_ALLOC(cur_ptr, arg_size, arg_align);
644
747
  HEAP8.subarray(cur_ptr, cur_ptr + arg_size).set(HEAP8.subarray(struct_ptr, struct_ptr + arg_size));
645
- DEREF_U32(args_ptr, carg_idx) = cur_ptr;
748
+ DEREF_PTR(args_ptr, carg_idx) = ENC_PTR(cur_ptr);
646
749
  } else {
647
- DEREF_U32(args_ptr, carg_idx) = varargs;
750
+ DEREF_PTR(args_ptr, carg_idx) = ENC_PTR(varargs);
648
751
  }
649
- varargs += 4;
752
+ varargs += __SIZEOF_POINTER__;
650
753
  }
651
754
  stackRestore(cur_ptr);
652
755
  stackAlloc(0); // stackAlloc enforces alignment invariants on the stack pointer
653
756
  LOG_DEBUG("CALL_CLOSURE", "closure:", closure, "fptr", CLOSURE__fun(closure), "cif", CLOSURE__cif(closure));
654
757
  getWasmTableEntry(CLOSURE__fun(closure))(
655
- CLOSURE__cif(closure), ret_ptr, args_ptr,
758
+ CLOSURE__cif(closure), ENC_PTR(ret_ptr), ENC_PTR(args_ptr),
656
759
  CLOSURE__user_data(closure)
657
760
  );
658
761
  stackRestore(orig_stack_ptr);
@@ -677,9 +780,9 @@ ffi_prep_closure_loc_js,
677
780
  return FFI_BAD_TYPEDEF_MACRO;
678
781
  }
679
782
  setWasmTableEntry(codeloc, wasm_trampoline);
680
- CLOSURE__cif(closure) = cif;
681
- CLOSURE__fun(closure) = fun;
682
- 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);
683
786
  return FFI_OK_MACRO;
684
787
  })
685
788
 
@@ -688,7 +791,7 @@ ffi_prep_closure_loc_js,
688
791
  ffi_status ffi_prep_closure_loc(ffi_closure *closure, ffi_cif *cif,
689
792
  void (*fun)(ffi_cif *, void *, void **, void *),
690
793
  void *user_data, void *codeloc) {
691
- if (cif->abi != FFI_WASM32_EMSCRIPTEN)
794
+ if (cif->abi != FFI_EMSCRIPTEN_ABI)
692
795
  return FFI_BAD_ABI;
693
796
  return ffi_prep_closure_loc_js(closure, cif, (void *)fun, user_data,
694
797
  codeloc);
@@ -42,14 +42,31 @@ typedef void (*ffi_fp)(void);
42
42
 
43
43
  typedef enum ffi_abi {
44
44
  FFI_FIRST_ABI = 0,
45
+ #if __SIZEOF_POINTER__ == 4
45
46
  FFI_WASM32, // "raw", no structures, varargs, or closures (not implemented!)
46
47
  FFI_WASM32_EMSCRIPTEN, // structures, varargs, and split 64-bit params
48
+ #elif __SIZEOF_POINTER__ == 8
49
+ FFI_WASM64,
50
+ FFI_WASM64_EMSCRIPTEN,
51
+ #else
52
+ #error "Unknown pointer size"
53
+ #endif
47
54
  FFI_LAST_ABI,
55
+ #if __SIZEOF_POINTER__ == 4
48
56
  #ifdef __EMSCRIPTEN__
49
57
  FFI_DEFAULT_ABI = FFI_WASM32_EMSCRIPTEN
50
58
  #else
51
59
  FFI_DEFAULT_ABI = FFI_WASM32
52
60
  #endif
61
+ #elif __SIZEOF_POINTER__ == 8
62
+ #ifdef __EMSCRIPTEN__
63
+ FFI_DEFAULT_ABI = FFI_WASM64_EMSCRIPTEN
64
+ #else
65
+ FFI_DEFAULT_ABI = FFI_WASM64
66
+ #endif
67
+ #else
68
+ #error "Unknown pointer size"
69
+ #endif
53
70
  } ffi_abi;
54
71
 
55
72
  #define FFI_CLOSURES 1
@@ -41,9 +41,6 @@
41
41
 
42
42
  #if defined (X86_64) && defined (__i386__)
43
43
  #undef X86_64
44
- #warning ******************************************************
45
- #warning ********** X86 IS DEFINED ****************************
46
- #warning ******************************************************
47
44
  #define X86
48
45
  #endif
49
46
 
@@ -458,9 +458,7 @@ L(UW24):
458
458
  L(UW25):
459
459
  # cfi_def_cfa_offset(closure_FS + 4)
460
460
  FFI_CLOSURE_SAVE_REGS
461
- movl closure_FS-4(%esp), %ecx /* load retaddr */
462
- movl closure_FS(%esp), %eax /* load closure */
463
- movl %ecx, closure_FS(%esp) /* move retaddr */
461
+ movl closure_FS-4(%esp), %eax /* load closure */
464
462
  jmp L(do_closure_REGISTER)
465
463
  L(UW26):
466
464
  # cfi_endproc
@@ -394,9 +394,7 @@ L(UW24):
394
394
  L(UW25):
395
395
  /* cfi_def_cfa_offset(closure_FS + 4) */
396
396
  FFI_CLOSURE_SAVE_REGS
397
- mov ecx, [esp+closure_FS-4] /* load retaddr */
398
- mov eax, [esp+closure_FS] /* load closure */
399
- mov [esp+closure_FS], ecx /* move retaddr */
397
+ mov eax, [esp+closure_FS-4] /* load closure */
400
398
  jmp L(do_closure_REGISTER)
401
399
  L(UW26):
402
400
  /* cfi_endproc */
@@ -31,7 +31,7 @@ EXTRA_DIST = config/default.exp emscripten/build.sh emscripten/conftest.py \
31
31
  libffi.call/struct9.c libffi.call/struct_by_value_2.c libffi.call/struct_by_value_3.c \
32
32
  libffi.call/struct_by_value_3f.c libffi.call/struct_by_value_4.c libffi.call/struct_by_value_4f.c \
33
33
  libffi.call/struct_by_value_big.c libffi.call/struct_by_value_small.c libffi.call/struct_return_2H.c \
34
- libffi.call/struct_int_float.c \
34
+ libffi.call/struct_int_float.c libffi.call/longjmp.c \
35
35
  libffi.call/struct_return_8H.c libffi.call/uninitialized.c libffi.call/va_1.c \
36
36
  libffi.call/va_2.c libffi.call/va_3.c libffi.call/va_struct1.c \
37
37
  libffi.call/va_struct2.c libffi.call/va_struct3.c libffi.call/callback.c \
@@ -85,4 +85,5 @@ EXTRA_DIST = config/default.exp emscripten/build.sh emscripten/conftest.py \
85
85
  libffi.complex/return_complex2_float.c libffi.complex/return_complex2_longdouble.c libffi.complex/return_complex_double.c \
86
86
  libffi.complex/return_complex_float.c libffi.complex/return_complex_longdouble.c libffi.go/aa-direct.c \
87
87
  libffi.go/closure1.c libffi.go/ffitest.h libffi.go/go.exp \
88
- libffi.go/static-chain.h Makefile.am Makefile.in
88
+ libffi.go/static-chain.h Makefile.am Makefile.in \
89
+ libffi.threads/ffitest.h libffi.threads/threads.exp libffi.threads/tsan.c
@@ -174,6 +174,8 @@ EGREP = @EGREP@
174
174
  ETAGS = @ETAGS@
175
175
  EXEEXT = @EXEEXT@
176
176
  FFI_EXEC_TRAMPOLINE_TABLE = @FFI_EXEC_TRAMPOLINE_TABLE@
177
+ FFI_VERSION_NUMBER = @FFI_VERSION_NUMBER@
178
+ FFI_VERSION_STRING = @FFI_VERSION_STRING@
177
179
  FGREP = @FGREP@
178
180
  FILECMD = @FILECMD@
179
181
  GREP = @GREP@
@@ -224,6 +226,7 @@ TARGET = @TARGET@
224
226
  TARGETDIR = @TARGETDIR@
225
227
  TARGET_OBJ = @TARGET_OBJ@
226
228
  VERSION = @VERSION@
229
+ WASM64_MEMORY64 = @WASM64_MEMORY64@
227
230
  abs_builddir = @abs_builddir@
228
231
  abs_srcdir = @abs_srcdir@
229
232
  abs_top_builddir = @abs_top_builddir@
@@ -316,7 +319,7 @@ EXTRA_DIST = config/default.exp emscripten/build.sh emscripten/conftest.py \
316
319
  libffi.call/struct9.c libffi.call/struct_by_value_2.c libffi.call/struct_by_value_3.c \
317
320
  libffi.call/struct_by_value_3f.c libffi.call/struct_by_value_4.c libffi.call/struct_by_value_4f.c \
318
321
  libffi.call/struct_by_value_big.c libffi.call/struct_by_value_small.c libffi.call/struct_return_2H.c \
319
- libffi.call/struct_int_float.c \
322
+ libffi.call/struct_int_float.c libffi.call/longjmp.c \
320
323
  libffi.call/struct_return_8H.c libffi.call/uninitialized.c libffi.call/va_1.c \
321
324
  libffi.call/va_2.c libffi.call/va_3.c libffi.call/va_struct1.c \
322
325
  libffi.call/va_struct2.c libffi.call/va_struct3.c libffi.call/callback.c \
@@ -370,7 +373,8 @@ EXTRA_DIST = config/default.exp emscripten/build.sh emscripten/conftest.py \
370
373
  libffi.complex/return_complex2_float.c libffi.complex/return_complex2_longdouble.c libffi.complex/return_complex_double.c \
371
374
  libffi.complex/return_complex_float.c libffi.complex/return_complex_longdouble.c libffi.go/aa-direct.c \
372
375
  libffi.go/closure1.c libffi.go/ffitest.h libffi.go/go.exp \
373
- libffi.go/static-chain.h Makefile.am Makefile.in
376
+ libffi.go/static-chain.h Makefile.am Makefile.in \
377
+ libffi.threads/ffitest.h libffi.threads/threads.exp libffi.threads/tsan.c
374
378
 
375
379
  all: all-am
376
380
 
@@ -36,11 +36,11 @@ export PKG_CONFIG_PATH="$TARGET/lib/pkgconfig"
36
36
  export EM_PKG_CONFIG_PATH="$PKG_CONFIG_PATH"
37
37
 
38
38
  # Specific variables for cross-compilation
39
- export CHOST="wasm32-unknown-linux" # wasm32-unknown-emscripten
39
+ export CHOST="${TARGET_HOST}-unknown-linux" # wasm32-unknown-emscripten
40
40
 
41
41
  autoreconf -fiv
42
42
  emconfigure ./configure --host=$CHOST --prefix="$TARGET" --enable-static --disable-shared --disable-dependency-tracking \
43
- --disable-builddir --disable-multi-os-directory --disable-raw-api --disable-docs
43
+ --disable-builddir --disable-multi-os-directory --disable-raw-api --disable-docs ${EXTRA_CONFIGURE_FLAGS}
44
44
  make install
45
45
  cp fficonfig.h target/include/
46
46
  cp include/ffi_common.h target/include/
@@ -8,16 +8,16 @@ fi
8
8
  # Common compiler flags
9
9
  export CFLAGS="-fPIC $EXTRA_CFLAGS"
10
10
  export CXXFLAGS="$CFLAGS -sNO_DISABLE_EXCEPTION_CATCHING $EXTRA_CXXFLAGS"
11
- export LDFLAGS="-sEXPORTED_FUNCTIONS=_main,_malloc,_free -sALLOW_TABLE_GROWTH -sASSERTIONS -sNO_DISABLE_EXCEPTION_CATCHING -sWASM_BIGINT"
11
+ export LDFLAGS="-sEXPORTED_FUNCTIONS=_main,_malloc,_free -sALLOW_TABLE_GROWTH -sASSERTIONS -sNO_DISABLE_EXCEPTION_CATCHING -sWASM_BIGINT -Wno-main"
12
12
 
13
13
  # Specific variables for cross-compilation
14
- export CHOST="wasm32-unknown-linux" # wasm32-unknown-emscripten
14
+ export CHOST="${TARGET_HOST}-unknown-linux" # wasm32-unknown-emscripten
15
15
 
16
16
  autoreconf -fiv
17
17
  emconfigure ./configure --prefix="$(pwd)/target" --host=$CHOST --enable-static --disable-shared \
18
- --disable-builddir --disable-multi-os-directory --disable-raw-api --disable-docs ||
18
+ --disable-builddir --disable-multi-os-directory --disable-raw-api --disable-docs ${EXTRA_CONFIGURE_FLAGS} ||
19
19
  (cat config.log && exit 1)
20
20
  make
21
21
 
22
22
  EMMAKEN_JUST_CONFIGURE=1 emmake make check \
23
- RUNTESTFLAGS="LDFLAGS_FOR_TARGET='$LDFLAGS'" || (cat testsuite/libffi.log && exit 1)
23
+ RUNTESTFLAGS="LDFLAGS_FOR_TARGET='$LDFLAGS $EXTRA_TEST_LDFLAGS'" || (cat testsuite/libffi.log && exit 1)