koffi 1.3.12 → 2.1.0-beta.1

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 (104) hide show
  1. package/CMakeLists.txt +8 -10
  2. package/ChangeLog.md +48 -16
  3. package/README.md +6 -0
  4. package/benchmark/atoi_koffi.js +12 -8
  5. package/benchmark/atoi_napi.js +12 -8
  6. package/benchmark/atoi_node_ffi.js +11 -10
  7. package/benchmark/raylib_cc.cc +12 -9
  8. package/benchmark/raylib_koffi.js +15 -13
  9. package/benchmark/raylib_node_ffi.js +15 -13
  10. package/benchmark/raylib_node_raylib.js +14 -11
  11. package/build/qemu/2.1.0-beta.1/koffi_darwin_arm64.tar.gz +0 -0
  12. package/build/qemu/2.1.0-beta.1/koffi_darwin_x64.tar.gz +0 -0
  13. package/build/qemu/2.1.0-beta.1/koffi_freebsd_arm64.tar.gz +0 -0
  14. package/build/qemu/2.1.0-beta.1/koffi_freebsd_ia32.tar.gz +0 -0
  15. package/build/qemu/2.1.0-beta.1/koffi_freebsd_x64.tar.gz +0 -0
  16. package/build/qemu/2.1.0-beta.1/koffi_linux_arm32hf.tar.gz +0 -0
  17. package/build/qemu/2.1.0-beta.1/koffi_linux_arm64.tar.gz +0 -0
  18. package/build/qemu/2.1.0-beta.1/koffi_linux_ia32.tar.gz +0 -0
  19. package/build/qemu/2.1.0-beta.1/koffi_linux_riscv64hf64.tar.gz +0 -0
  20. package/build/qemu/2.1.0-beta.1/koffi_linux_x64.tar.gz +0 -0
  21. package/build/qemu/2.1.0-beta.1/koffi_openbsd_ia32.tar.gz +0 -0
  22. package/build/qemu/2.1.0-beta.1/koffi_openbsd_x64.tar.gz +0 -0
  23. package/build/qemu/2.1.0-beta.1/koffi_win32_arm64.tar.gz +0 -0
  24. package/build/qemu/2.1.0-beta.1/koffi_win32_ia32.tar.gz +0 -0
  25. package/build/qemu/2.1.0-beta.1/koffi_win32_x64.tar.gz +0 -0
  26. package/doc/changes.md +160 -1
  27. package/doc/conf.py +14 -1
  28. package/doc/contribute.md +0 -1
  29. package/doc/dist/doctrees/benchmarks.doctree +0 -0
  30. package/doc/dist/doctrees/changes.doctree +0 -0
  31. package/doc/dist/doctrees/environment.pickle +0 -0
  32. package/doc/dist/doctrees/functions.doctree +0 -0
  33. package/doc/dist/doctrees/index.doctree +0 -0
  34. package/doc/dist/doctrees/types.doctree +0 -0
  35. package/doc/dist/html/.buildinfo +1 -1
  36. package/doc/dist/html/_sources/benchmarks.md.txt +2 -2
  37. package/doc/dist/html/_sources/changes.md.txt +160 -1
  38. package/doc/dist/html/_sources/functions.md.txt +17 -13
  39. package/doc/dist/html/_sources/types.md.txt +87 -35
  40. package/doc/dist/html/benchmarks.html +7 -3
  41. package/doc/dist/html/changes.html +241 -14
  42. package/doc/dist/html/contribute.html +5 -1
  43. package/doc/dist/html/functions.html +30 -23
  44. package/doc/dist/html/genindex.html +5 -1
  45. package/doc/dist/html/index.html +13 -19
  46. package/doc/dist/html/memory.html +7 -3
  47. package/doc/dist/html/objects.inv +0 -0
  48. package/doc/dist/html/platforms.html +6 -2
  49. package/doc/dist/html/search.html +5 -1
  50. package/doc/dist/html/searchindex.js +1 -1
  51. package/doc/dist/html/start.html +5 -1
  52. package/doc/dist/html/types.html +104 -43
  53. package/doc/functions.md +139 -15
  54. package/doc/templates/badges.html +5 -0
  55. package/doc/types.md +108 -40
  56. package/package.json +2 -2
  57. package/qemu/qemu.js +1 -1
  58. package/qemu/registry/machines.json +5 -5
  59. package/qemu/registry/sha256sum.txt +16 -16
  60. package/src/abi_arm32.cc +91 -19
  61. package/src/abi_arm32_fwd.S +121 -57
  62. package/src/abi_arm64.cc +91 -19
  63. package/src/abi_arm64_fwd.S +96 -0
  64. package/src/abi_arm64_fwd.asm +128 -0
  65. package/src/abi_riscv64.cc +89 -19
  66. package/src/abi_riscv64_fwd.S +96 -0
  67. package/src/abi_x64_sysv.cc +94 -22
  68. package/src/abi_x64_sysv_fwd.S +96 -0
  69. package/src/abi_x64_win.cc +89 -19
  70. package/src/abi_x64_win_fwd.asm +128 -0
  71. package/src/abi_x86.cc +94 -19
  72. package/src/abi_x86_fwd.S +96 -0
  73. package/src/abi_x86_fwd.asm +128 -0
  74. package/src/call.cc +128 -78
  75. package/src/call.hh +17 -4
  76. package/src/ffi.cc +514 -145
  77. package/src/ffi.hh +30 -9
  78. package/src/index.js +4 -2
  79. package/src/parser.cc +19 -44
  80. package/src/util.cc +160 -27
  81. package/src/util.hh +7 -2
  82. package/test/async.js +1 -2
  83. package/test/callbacks.js +56 -11
  84. package/test/misc.c +50 -15
  85. package/test/raylib.js +2 -2
  86. package/test/sqlite.js +27 -19
  87. package/test/sync.js +71 -35
  88. package/vendor/libcc/libcc.cc +18 -5
  89. package/vendor/libcc/libcc.hh +70 -23
  90. package/build/qemu/1.3.12/koffi_darwin_arm64.tar.gz +0 -0
  91. package/build/qemu/1.3.12/koffi_darwin_x64.tar.gz +0 -0
  92. package/build/qemu/1.3.12/koffi_freebsd_arm64.tar.gz +0 -0
  93. package/build/qemu/1.3.12/koffi_freebsd_ia32.tar.gz +0 -0
  94. package/build/qemu/1.3.12/koffi_freebsd_x64.tar.gz +0 -0
  95. package/build/qemu/1.3.12/koffi_linux_arm32hf.tar.gz +0 -0
  96. package/build/qemu/1.3.12/koffi_linux_arm64.tar.gz +0 -0
  97. package/build/qemu/1.3.12/koffi_linux_ia32.tar.gz +0 -0
  98. package/build/qemu/1.3.12/koffi_linux_riscv64hf64.tar.gz +0 -0
  99. package/build/qemu/1.3.12/koffi_linux_x64.tar.gz +0 -0
  100. package/build/qemu/1.3.12/koffi_openbsd_ia32.tar.gz +0 -0
  101. package/build/qemu/1.3.12/koffi_openbsd_x64.tar.gz +0 -0
  102. package/build/qemu/1.3.12/koffi_win32_arm64.tar.gz +0 -0
  103. package/build/qemu/1.3.12/koffi_win32_ia32.tar.gz +0 -0
  104. package/build/qemu/1.3.12/koffi_win32_x64.tar.gz +0 -0
@@ -56,57 +56,40 @@
56
56
  .cfi_endproc
57
57
  .endm
58
58
 
59
- # Prepare general purpose argument registers from array passed by caller.
60
- .macro forward_gpr
61
- ldr r3, [r1, 76]
62
- ldr r2, [r1, 72]
63
- ldr r0, [r1, 64]
64
- ldr r1, [r1, 68]
65
- .endm
66
-
67
- # Prepare vector argument registers from array passed by caller.
68
- .macro forward_vec
69
- vldr d7, [r1, 56]
70
- vldr d6, [r1, 48]
71
- vldr d5, [r1, 40]
72
- vldr d4, [r1, 32]
73
- vldr d3, [r1, 24]
74
- vldr d2, [r1, 16]
75
- vldr d1, [r1, 8]
76
- vldr d0, [r1, 0]
77
- .endm
78
-
79
59
  ForwardCallGG:
80
60
  prologue
81
- forward_gpr
61
+ add r1, r1, #64
62
+ ldmia r1, {r0-r3}
82
63
  epilogue
83
64
 
84
65
  ForwardCallF:
85
66
  prologue
86
- forward_gpr
67
+ add r1, r1, #64
68
+ ldmia r1, {r0-r3}
87
69
  epilogue
88
70
 
89
71
  ForwardCallDDDD:
90
72
  prologue
91
- forward_gpr
73
+ add r1, r1, #64
74
+ ldmia r1, {r0-r3}
92
75
  epilogue
93
76
 
94
77
  ForwardCallXGG:
95
78
  prologue
96
- forward_vec
97
- forward_gpr
79
+ vldmia r1!, {d0-d7}
80
+ ldmia r1, {r0-r3}
98
81
  epilogue
99
82
 
100
83
  ForwardCallXF:
101
84
  prologue
102
- forward_vec
103
- forward_gpr
85
+ vldmia r1!, {d0-d7}
86
+ ldmia r1, {r0-r3}
104
87
  epilogue
105
88
 
106
89
  ForwardCallXDDDD:
107
90
  prologue
108
- forward_vec
109
- forward_gpr
91
+ vldmia r1!, {d0-d7}
92
+ ldmia r1, {r0-r3}
110
93
  epilogue
111
94
 
112
95
  # Callback trampolines
@@ -128,6 +111,22 @@ ForwardCallXDDDD:
128
111
  .global Trampoline13
129
112
  .global Trampoline14
130
113
  .global Trampoline15
114
+ .global Trampoline16
115
+ .global Trampoline17
116
+ .global Trampoline18
117
+ .global Trampoline19
118
+ .global Trampoline20
119
+ .global Trampoline21
120
+ .global Trampoline22
121
+ .global Trampoline23
122
+ .global Trampoline24
123
+ .global Trampoline25
124
+ .global Trampoline26
125
+ .global Trampoline27
126
+ .global Trampoline28
127
+ .global Trampoline29
128
+ .global Trampoline30
129
+ .global Trampoline31
131
130
  .global TrampolineX0
132
131
  .global TrampolineX1
133
132
  .global TrampolineX2
@@ -144,6 +143,22 @@ ForwardCallXDDDD:
144
143
  .global TrampolineX13
145
144
  .global TrampolineX14
146
145
  .global TrampolineX15
146
+ .global TrampolineX16
147
+ .global TrampolineX17
148
+ .global TrampolineX18
149
+ .global TrampolineX19
150
+ .global TrampolineX20
151
+ .global TrampolineX21
152
+ .global TrampolineX22
153
+ .global TrampolineX23
154
+ .global TrampolineX24
155
+ .global TrampolineX25
156
+ .global TrampolineX26
157
+ .global TrampolineX27
158
+ .global TrampolineX28
159
+ .global TrampolineX29
160
+ .global TrampolineX30
161
+ .global TrampolineX31
147
162
  .global RelayCallback
148
163
  .global CallSwitchStack
149
164
 
@@ -160,18 +175,16 @@ ForwardCallXDDDD:
160
175
  .cfi_offset 14, 8
161
176
  sub sp, sp, #120
162
177
  .cfi_def_cfa sp, 128
163
- str r0, [sp, 64]
164
- str r1, [sp, 68]
165
- str r2, [sp, 72]
166
- str r3, [sp, 76]
178
+ add r12, sp, 64
179
+ stmia r12!, {r0-r3}
167
180
  mov r0, \id
168
181
  mov r1, sp
169
182
  add r2, sp, #128
170
- add r3, sp, #80
183
+ mov r3, r12
171
184
  bl RelayCallback
172
- ldr r0, [sp, 80]
173
- ldr r1, [sp, 84]
174
- add sp, sp, #120
185
+ add sp, sp, #80
186
+ ldmia sp!, {r0-r1}
187
+ add sp, sp, #32
175
188
  .cfi_def_cfa sp, 8
176
189
  pop {fp, lr}
177
190
  .cfi_def_cfa sp, 0
@@ -190,30 +203,17 @@ ForwardCallXDDDD:
190
203
  .cfi_offset 14, 8
191
204
  sub sp, sp, #120
192
205
  .cfi_def_cfa sp, 128
193
- str r0, [sp, 64]
194
- str r1, [sp, 68]
195
- str r2, [sp, 72]
196
- str r3, [sp, 76]
197
- vstr d0, [sp, 0]
198
- vstr d1, [sp, 8]
199
- vstr d2, [sp, 16]
200
- vstr d3, [sp, 24]
201
- vstr d4, [sp, 32]
202
- vstr d5, [sp, 40]
203
- vstr d6, [sp, 48]
204
- vstr d7, [sp, 56]
206
+ mov r12, sp
207
+ vstmia r12!, {d0-d7}
208
+ stmia r12!, {r0-r3}
205
209
  mov r0, \id
206
210
  mov r1, sp
207
211
  add r2, sp, #128
208
- add r3, sp, #80
212
+ mov r3, r12
209
213
  bl RelayCallback
210
- ldr r0, [sp, 80]
211
- ldr r1, [sp, 84]
212
- vldr d0, [sp, 88]
213
- vldr d1, [sp, 96]
214
- vldr d2, [sp, 104]
215
- vldr d3, [sp, 112]
216
- add sp, sp, #120
214
+ add sp, sp, #80
215
+ ldmia sp!, {r0-r1}
216
+ vldmia sp!, {d0-d3}
217
217
  .cfi_def_cfa sp, 8
218
218
  pop {fp, lr}
219
219
  .cfi_def_cfa sp, 0
@@ -255,6 +255,38 @@ Trampoline14:
255
255
  trampoline 14
256
256
  Trampoline15:
257
257
  trampoline 15
258
+ Trampoline16:
259
+ trampoline 16
260
+ Trampoline17:
261
+ trampoline 17
262
+ Trampoline18:
263
+ trampoline 18
264
+ Trampoline19:
265
+ trampoline 19
266
+ Trampoline20:
267
+ trampoline 20
268
+ Trampoline21:
269
+ trampoline 21
270
+ Trampoline22:
271
+ trampoline 22
272
+ Trampoline23:
273
+ trampoline 23
274
+ Trampoline24:
275
+ trampoline 24
276
+ Trampoline25:
277
+ trampoline 25
278
+ Trampoline26:
279
+ trampoline 26
280
+ Trampoline27:
281
+ trampoline 27
282
+ Trampoline28:
283
+ trampoline 28
284
+ Trampoline29:
285
+ trampoline 29
286
+ Trampoline30:
287
+ trampoline 30
288
+ Trampoline31:
289
+ trampoline 31
258
290
 
259
291
  TrampolineX0:
260
292
  trampoline_vec 0
@@ -288,6 +320,38 @@ TrampolineX14:
288
320
  trampoline_vec 14
289
321
  TrampolineX15:
290
322
  trampoline_vec 15
323
+ TrampolineX16:
324
+ trampoline_vec 16
325
+ TrampolineX17:
326
+ trampoline_vec 17
327
+ TrampolineX18:
328
+ trampoline_vec 18
329
+ TrampolineX19:
330
+ trampoline_vec 19
331
+ TrampolineX20:
332
+ trampoline_vec 20
333
+ TrampolineX21:
334
+ trampoline_vec 21
335
+ TrampolineX22:
336
+ trampoline_vec 22
337
+ TrampolineX23:
338
+ trampoline_vec 23
339
+ TrampolineX24:
340
+ trampoline_vec 24
341
+ TrampolineX25:
342
+ trampoline_vec 25
343
+ TrampolineX26:
344
+ trampoline_vec 26
345
+ TrampolineX27:
346
+ trampoline_vec 27
347
+ TrampolineX28:
348
+ trampoline_vec 28
349
+ TrampolineX29:
350
+ trampoline_vec 29
351
+ TrampolineX30:
352
+ trampoline_vec 30
353
+ TrampolineX31:
354
+ trampoline_vec 31
291
355
 
292
356
  # When a callback is relayed, Koffi will call into Node.js and V8 to execute Javascript.
293
357
  # The problem is that we're still running on the separate Koffi stack, and V8 will
package/src/abi_arm64.cc CHANGED
@@ -66,6 +66,22 @@ extern "C" int Trampoline12; extern "C" int TrampolineX12;
66
66
  extern "C" int Trampoline13; extern "C" int TrampolineX13;
67
67
  extern "C" int Trampoline14; extern "C" int TrampolineX14;
68
68
  extern "C" int Trampoline15; extern "C" int TrampolineX15;
69
+ extern "C" int Trampoline16; extern "C" int TrampolineX16;
70
+ extern "C" int Trampoline17; extern "C" int TrampolineX17;
71
+ extern "C" int Trampoline18; extern "C" int TrampolineX18;
72
+ extern "C" int Trampoline19; extern "C" int TrampolineX19;
73
+ extern "C" int Trampoline20; extern "C" int TrampolineX20;
74
+ extern "C" int Trampoline21; extern "C" int TrampolineX21;
75
+ extern "C" int Trampoline22; extern "C" int TrampolineX22;
76
+ extern "C" int Trampoline23; extern "C" int TrampolineX23;
77
+ extern "C" int Trampoline24; extern "C" int TrampolineX24;
78
+ extern "C" int Trampoline25; extern "C" int TrampolineX25;
79
+ extern "C" int Trampoline26; extern "C" int TrampolineX26;
80
+ extern "C" int Trampoline27; extern "C" int TrampolineX27;
81
+ extern "C" int Trampoline28; extern "C" int TrampolineX28;
82
+ extern "C" int Trampoline29; extern "C" int TrampolineX29;
83
+ extern "C" int Trampoline30; extern "C" int TrampolineX30;
84
+ extern "C" int Trampoline31; extern "C" int TrampolineX31;
69
85
 
70
86
  extern "C" napi_value CallSwitchStack(Napi::Function *func, size_t argc, napi_value *argv,
71
87
  uint8_t *old_sp, Span<uint8_t> *new_stack,
@@ -87,9 +103,25 @@ static void *const Trampolines[][2] = {
87
103
  { &Trampoline12, &TrampolineX12 },
88
104
  { &Trampoline13, &TrampolineX13 },
89
105
  { &Trampoline14, &TrampolineX14 },
90
- { &Trampoline15, &TrampolineX15 }
106
+ { &Trampoline15, &TrampolineX15 },
107
+ { &Trampoline16, &TrampolineX16 },
108
+ { &Trampoline17, &TrampolineX17 },
109
+ { &Trampoline18, &TrampolineX18 },
110
+ { &Trampoline19, &TrampolineX19 },
111
+ { &Trampoline20, &TrampolineX20 },
112
+ { &Trampoline21, &TrampolineX21 },
113
+ { &Trampoline22, &TrampolineX22 },
114
+ { &Trampoline23, &TrampolineX23 },
115
+ { &Trampoline24, &TrampolineX24 },
116
+ { &Trampoline25, &TrampolineX25 },
117
+ { &Trampoline26, &TrampolineX26 },
118
+ { &Trampoline27, &TrampolineX27 },
119
+ { &Trampoline28, &TrampolineX28 },
120
+ { &Trampoline29, &TrampolineX29 },
121
+ { &Trampoline30, &TrampolineX30 },
122
+ { &Trampoline31, &TrampolineX31 }
91
123
  };
92
- RG_STATIC_ASSERT(RG_LEN(Trampolines) == MaxTrampolines);
124
+ RG_STATIC_ASSERT(RG_LEN(Trampolines) == MaxTrampolines * 2);
93
125
 
94
126
  static RG_THREAD_LOCAL CallData *exec_call;
95
127
 
@@ -198,6 +230,8 @@ bool AnalyseFunction(Napi::Env, InstanceData *, FunctionInfo *func)
198
230
  vec_avail--;
199
231
  }
200
232
  } break;
233
+
234
+ case PrimitiveKind::Prototype: { RG_UNREACHABLE(); } break;
201
235
  }
202
236
  }
203
237
 
@@ -440,10 +474,10 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
440
474
  if (value.IsFunction()) {
441
475
  Napi::Function func = value.As<Napi::Function>();
442
476
 
443
- ptr = ReserveTrampoline(param.type->proto, func);
477
+ ptr = ReserveTrampoline(param.type->ref.proto, func);
444
478
  if (RG_UNLIKELY(!ptr))
445
479
  return false;
446
- } else if (CheckValueTag(instance, value, param.type)) {
480
+ } else if (CheckValueTag(instance, value, param.type->ref.marker)) {
447
481
  ptr = value.As<Napi::External<void>>().Data();
448
482
  } else if (IsNullOrUndefined(value)) {
449
483
  ptr = nullptr;
@@ -457,6 +491,8 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
457
491
  #endif
458
492
  *(void **)((param.gpr_count ? gpr_ptr : args_ptr)++) = ptr;
459
493
  } break;
494
+
495
+ case PrimitiveKind::Prototype: { RG_UNREACHABLE(); } break;
460
496
  }
461
497
  }
462
498
 
@@ -506,6 +542,8 @@ void CallData::Execute()
506
542
  case PrimitiveKind::Array: { RG_UNREACHABLE(); } break;
507
543
  case PrimitiveKind::Float32: { result.f = PERFORM_CALL(F); } break;
508
544
  case PrimitiveKind::Float64: { result.d = PERFORM_CALL(DDDD).d0; } break;
545
+
546
+ case PrimitiveKind::Prototype: { RG_UNREACHABLE(); } break;
509
547
  }
510
548
 
511
549
  #undef PERFORM_CALL
@@ -513,10 +551,16 @@ void CallData::Execute()
513
551
 
514
552
  Napi::Value CallData::Complete()
515
553
  {
516
- PopOutArguments();
554
+ RG_DEFER {
555
+ PopOutArguments();
556
+
557
+ if (func->ret.type->dispose) {
558
+ func->ret.type->dispose(env, func->ret.type, result.ptr);
559
+ }
560
+ };
517
561
 
518
562
  switch (func->ret.type->primitive) {
519
- case PrimitiveKind::Void: return env.Null();
563
+ case PrimitiveKind::Void: return env.Undefined();
520
564
  case PrimitiveKind::Bool: return Napi::Boolean::New(env, result.u32);
521
565
  case PrimitiveKind::Int8: return Napi::Number::New(env, (double)result.i8);
522
566
  case PrimitiveKind::UInt8: return Napi::Number::New(env, (double)result.u8);
@@ -532,7 +576,7 @@ Napi::Value CallData::Complete()
532
576
  case PrimitiveKind::Callback: {
533
577
  if (result.ptr) {
534
578
  Napi::External<void> external = Napi::External<void>::New(env, result.ptr);
535
- SetValueTag(instance, external, func->ret.type);
579
+ SetValueTag(instance, external, func->ret.type->ref.marker);
536
580
 
537
581
  return external;
538
582
  } else {
@@ -554,6 +598,8 @@ Napi::Value CallData::Complete()
554
598
  case PrimitiveKind::Array: { RG_UNREACHABLE(); } break;
555
599
  case PrimitiveKind::Float32: return Napi::Number::New(env, (double)result.f);
556
600
  case PrimitiveKind::Float64: return Napi::Number::New(env, result.d);
601
+
602
+ case PrimitiveKind::Prototype: { RG_UNREACHABLE(); } break;
557
603
  }
558
604
 
559
605
  RG_UNREACHABLE();
@@ -561,12 +607,10 @@ Napi::Value CallData::Complete()
561
607
 
562
608
  void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegisters *out_reg)
563
609
  {
564
- const TrampolineInfo &trampoline = instance->trampolines[idx];
565
-
566
- if (RG_UNLIKELY(trampoline.generation != mem->generation)) {
567
- ThrowError<Napi::Error>(env, "Cannot use non-persistent callback beyond FFI call");
610
+ if (RG_UNLIKELY(env.IsExceptionPending()))
568
611
  return;
569
- }
612
+
613
+ const TrampolineInfo &trampoline = instance->trampolines[idx];
570
614
 
571
615
  const FunctionInfo *proto = trampoline.proto;
572
616
  Napi::Function func = trampoline.func.Value();
@@ -577,6 +621,13 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
577
621
 
578
622
  uint8_t *return_ptr = proto->ret.use_memory ? (uint8_t *)gpr_ptr[8] : nullptr;
579
623
 
624
+ RG_DEFER_N(err_guard) { memset(out_reg, 0, RG_SIZE(*out_reg)); };
625
+
626
+ if (RG_UNLIKELY(trampoline.generation >= 0 && trampoline.generation != (int32_t)mem->generation)) {
627
+ ThrowError<Napi::Error>(env, "Cannot use non-registered callback beyond FFI call");
628
+ return;
629
+ }
630
+
580
631
  LocalArray<napi_value, MaxParameters> arguments;
581
632
 
582
633
  // Convert to JS arguments
@@ -732,6 +783,10 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
732
783
 
733
784
  Napi::Value arg = str ? Napi::String::New(env, str) : env.Null();
734
785
  arguments.Append(arg);
786
+
787
+ if (param.type->dispose) {
788
+ param.type->dispose(env, param.type, str);
789
+ }
735
790
  } break;
736
791
  case PrimitiveKind::String16: {
737
792
  #ifdef __APPLE__
@@ -742,6 +797,10 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
742
797
 
743
798
  Napi::Value arg = str16 ? Napi::String::New(env, str16) : env.Null();
744
799
  arguments.Append(arg);
800
+
801
+ if (param.type->dispose) {
802
+ param.type->dispose(env, param.type, str16);
803
+ }
745
804
  } break;
746
805
  case PrimitiveKind::Pointer:
747
806
  case PrimitiveKind::Callback: {
@@ -753,12 +812,16 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
753
812
 
754
813
  if (ptr2) {
755
814
  Napi::External<void> external = Napi::External<void>::New(env, ptr2);
756
- SetValueTag(instance, external, param.type);
815
+ SetValueTag(instance, external, param.type->ref.marker);
757
816
 
758
817
  arguments.Append(external);
759
818
  } else {
760
819
  arguments.Append(env.Null());
761
820
  }
821
+
822
+ if (param.type->dispose) {
823
+ param.type->dispose(env, param.type, ptr2);
824
+ }
762
825
  } break;
763
826
  case PrimitiveKind::Record: {
764
827
  if (param.vec_count) { // HFA
@@ -834,6 +897,8 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
834
897
  Napi::Value arg = Napi::Number::New(env, d);
835
898
  arguments.Append(arg);
836
899
  } break;
900
+
901
+ case PrimitiveKind::Prototype: { RG_UNREACHABLE(); } break;
837
902
  }
838
903
  }
839
904
 
@@ -844,6 +909,9 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
844
909
  [](Napi::Function *func, size_t argc, napi_value *argv) { return (napi_value)func->Call(argc, argv); });
845
910
  Napi::Value value(env, ret);
846
911
 
912
+ if (RG_UNLIKELY(env.IsExceptionPending()))
913
+ return;
914
+
847
915
  // Convert the result
848
916
  switch (type->primitive) {
849
917
  case PrimitiveKind::Void: {} break;
@@ -905,14 +973,14 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
905
973
  case PrimitiveKind::Pointer: {
906
974
  uint8_t *ptr;
907
975
 
908
- if (CheckValueTag(instance, value, type)) {
976
+ if (CheckValueTag(instance, value, type->ref.marker)) {
909
977
  ptr = value.As<Napi::External<uint8_t>>().Data();
910
- } else if (IsObject(value) && type->ref->primitive == PrimitiveKind::Record) {
978
+ } else if (IsObject(value) && type->ref.type->primitive == PrimitiveKind::Record) {
911
979
  Napi::Object obj = value.As<Napi::Object>();
912
980
 
913
- ptr = AllocHeap(type->ref->size, 16);
981
+ ptr = AllocHeap(type->ref.type->size, 16);
914
982
 
915
- if (!PushObject(obj, type->ref, ptr))
983
+ if (!PushObject(obj, type->ref.type, ptr))
916
984
  return;
917
985
  } else if (IsNullOrUndefined(value)) {
918
986
  ptr = nullptr;
@@ -968,10 +1036,10 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
968
1036
  if (value.IsFunction()) {
969
1037
  Napi::Function func2 = value.As<Napi::Function>();
970
1038
 
971
- ptr = ReserveTrampoline(type->proto, func2);
1039
+ ptr = ReserveTrampoline(type->ref.proto, func2);
972
1040
  if (RG_UNLIKELY(!ptr))
973
1041
  return;
974
- } else if (CheckValueTag(instance, value, type)) {
1042
+ } else if (CheckValueTag(instance, value, type->ref.marker)) {
975
1043
  ptr = value.As<Napi::External<uint8_t>>().Data();
976
1044
  } else if (IsNullOrUndefined(value)) {
977
1045
  ptr = nullptr;
@@ -982,7 +1050,11 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
982
1050
 
983
1051
  out_reg->x0 = (uint64_t)ptr;
984
1052
  } break;
1053
+
1054
+ case PrimitiveKind::Prototype: { RG_UNREACHABLE(); } break;
985
1055
  }
1056
+
1057
+ err_guard.Disable();
986
1058
  }
987
1059
 
988
1060
  void *GetTrampoline(Size idx, const FunctionInfo *proto)
@@ -137,6 +137,22 @@ SYMBOL(ForwardCallXDDDD):
137
137
  .global SYMBOL(Trampoline13)
138
138
  .global SYMBOL(Trampoline14)
139
139
  .global SYMBOL(Trampoline15)
140
+ .global SYMBOL(Trampoline16)
141
+ .global SYMBOL(Trampoline17)
142
+ .global SYMBOL(Trampoline18)
143
+ .global SYMBOL(Trampoline19)
144
+ .global SYMBOL(Trampoline20)
145
+ .global SYMBOL(Trampoline21)
146
+ .global SYMBOL(Trampoline22)
147
+ .global SYMBOL(Trampoline23)
148
+ .global SYMBOL(Trampoline24)
149
+ .global SYMBOL(Trampoline25)
150
+ .global SYMBOL(Trampoline26)
151
+ .global SYMBOL(Trampoline27)
152
+ .global SYMBOL(Trampoline28)
153
+ .global SYMBOL(Trampoline29)
154
+ .global SYMBOL(Trampoline30)
155
+ .global SYMBOL(Trampoline31)
140
156
  .global SYMBOL(TrampolineX0)
141
157
  .global SYMBOL(TrampolineX1)
142
158
  .global SYMBOL(TrampolineX2)
@@ -153,6 +169,22 @@ SYMBOL(ForwardCallXDDDD):
153
169
  .global SYMBOL(TrampolineX13)
154
170
  .global SYMBOL(TrampolineX14)
155
171
  .global SYMBOL(TrampolineX15)
172
+ .global SYMBOL(TrampolineX16)
173
+ .global SYMBOL(TrampolineX17)
174
+ .global SYMBOL(TrampolineX18)
175
+ .global SYMBOL(TrampolineX19)
176
+ .global SYMBOL(TrampolineX20)
177
+ .global SYMBOL(TrampolineX21)
178
+ .global SYMBOL(TrampolineX22)
179
+ .global SYMBOL(TrampolineX23)
180
+ .global SYMBOL(TrampolineX24)
181
+ .global SYMBOL(TrampolineX25)
182
+ .global SYMBOL(TrampolineX26)
183
+ .global SYMBOL(TrampolineX27)
184
+ .global SYMBOL(TrampolineX28)
185
+ .global SYMBOL(TrampolineX29)
186
+ .global SYMBOL(TrampolineX30)
187
+ .global SYMBOL(TrampolineX31)
156
188
  .global SYMBOL(RelayCallback)
157
189
  .global SYMBOL(CallSwitchStack)
158
190
 
@@ -260,6 +292,38 @@ SYMBOL(Trampoline14):
260
292
  trampoline 14
261
293
  SYMBOL(Trampoline15):
262
294
  trampoline 15
295
+ SYMBOL(Trampoline16):
296
+ trampoline 16
297
+ SYMBOL(Trampoline17):
298
+ trampoline 17
299
+ SYMBOL(Trampoline18):
300
+ trampoline 18
301
+ SYMBOL(Trampoline19):
302
+ trampoline 19
303
+ SYMBOL(Trampoline20):
304
+ trampoline 20
305
+ SYMBOL(Trampoline21):
306
+ trampoline 21
307
+ SYMBOL(Trampoline22):
308
+ trampoline 22
309
+ SYMBOL(Trampoline23):
310
+ trampoline 23
311
+ SYMBOL(Trampoline24):
312
+ trampoline 24
313
+ SYMBOL(Trampoline25):
314
+ trampoline 25
315
+ SYMBOL(Trampoline26):
316
+ trampoline 26
317
+ SYMBOL(Trampoline27):
318
+ trampoline 27
319
+ SYMBOL(Trampoline28):
320
+ trampoline 28
321
+ SYMBOL(Trampoline29):
322
+ trampoline 29
323
+ SYMBOL(Trampoline30):
324
+ trampoline 30
325
+ SYMBOL(Trampoline31):
326
+ trampoline 31
263
327
 
264
328
  SYMBOL(TrampolineX0):
265
329
  trampoline_vec 0
@@ -293,6 +357,38 @@ SYMBOL(TrampolineX14):
293
357
  trampoline_vec 14
294
358
  SYMBOL(TrampolineX15):
295
359
  trampoline_vec 15
360
+ SYMBOL(TrampolineX16):
361
+ trampoline_vec 16
362
+ SYMBOL(TrampolineX17):
363
+ trampoline_vec 17
364
+ SYMBOL(TrampolineX18):
365
+ trampoline_vec 18
366
+ SYMBOL(TrampolineX19):
367
+ trampoline_vec 19
368
+ SYMBOL(TrampolineX20):
369
+ trampoline_vec 20
370
+ SYMBOL(TrampolineX21):
371
+ trampoline_vec 21
372
+ SYMBOL(TrampolineX22):
373
+ trampoline_vec 22
374
+ SYMBOL(TrampolineX23):
375
+ trampoline_vec 23
376
+ SYMBOL(TrampolineX24):
377
+ trampoline_vec 24
378
+ SYMBOL(TrampolineX25):
379
+ trampoline_vec 25
380
+ SYMBOL(TrampolineX26):
381
+ trampoline_vec 26
382
+ SYMBOL(TrampolineX27):
383
+ trampoline_vec 27
384
+ SYMBOL(TrampolineX28):
385
+ trampoline_vec 28
386
+ SYMBOL(TrampolineX29):
387
+ trampoline_vec 29
388
+ SYMBOL(TrampolineX30):
389
+ trampoline_vec 30
390
+ SYMBOL(TrampolineX31):
391
+ trampoline_vec 31
296
392
 
297
393
  # When a callback is relayed, Koffi will call into Node.js and V8 to execute Javascript.
298
394
  # The problem is that we're still running on the separate Koffi stack, and V8 will