koffi 2.16.1 → 3.0.0-alpha.2

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 (84) hide show
  1. package/CHANGELOG.md +2 -2
  2. package/README.md +8 -8
  3. package/build/koffi/darwin_arm64/koffi.node +0 -0
  4. package/build/koffi/darwin_x64/koffi.node +0 -0
  5. package/build/koffi/freebsd_arm64/koffi.node +0 -0
  6. package/build/koffi/freebsd_ia32/koffi.node +0 -0
  7. package/build/koffi/freebsd_x64/koffi.node +0 -0
  8. package/build/koffi/linux_arm64/koffi.node +0 -0
  9. package/build/koffi/linux_ia32/koffi.node +0 -0
  10. package/build/koffi/linux_x64/koffi.node +0 -0
  11. package/build/koffi/musl_arm64/koffi.node +0 -0
  12. package/build/koffi/musl_x64/koffi.node +0 -0
  13. package/build/koffi/openbsd_ia32/koffi.node +0 -0
  14. package/build/koffi/openbsd_x64/koffi.node +0 -0
  15. package/build/koffi/win32_ia32/koffi.node +0 -0
  16. package/build/koffi/win32_x64/koffi.node +0 -0
  17. package/doc/benchmarks.md +33 -33
  18. package/doc/benchmarks.xlsx +0 -0
  19. package/doc/contribute.md +37 -25
  20. package/doc/index.md +8 -8
  21. package/doc/variables.md +1 -1
  22. package/index.d.ts +11 -9
  23. package/index.js +1 -634
  24. package/indirect.js +1 -533
  25. package/lib/native/base/base.cc +63 -85
  26. package/lib/native/base/base.hh +178 -151
  27. package/package.json +3 -4
  28. package/src/build.js +1178 -0
  29. package/src/koffi/CMakeLists.txt +97 -34
  30. package/src/koffi/index.js +359 -0
  31. package/src/koffi/indirect.js +216 -0
  32. package/src/koffi/src/{abi_arm32.cc → abi/arm32.cc} +279 -275
  33. package/src/koffi/src/{abi_arm32_asm.S → abi/arm32_asm.S} +2 -5
  34. package/src/koffi/src/abi/arm64.cc +1511 -0
  35. package/src/koffi/src/{abi_arm64_asm.S → abi/arm64_asm.S} +44 -23
  36. package/src/koffi/src/{abi_arm64_asm.asm → abi/arm64_asm.asm} +32 -25
  37. package/src/koffi/src/{abi_loong64_asm.S → abi/loong64_asm.S} +1 -5
  38. package/src/koffi/src/{abi_riscv64.cc → abi/riscv64.cc} +279 -273
  39. package/src/koffi/src/{abi_riscv64_asm.S → abi/riscv64_asm.S} +1 -4
  40. package/src/koffi/src/abi/x64sysv.cc +1456 -0
  41. package/src/koffi/src/{abi_x64_sysv_asm.S → abi/x64sysv_asm.S} +30 -33
  42. package/src/koffi/src/abi/x64win.cc +1121 -0
  43. package/src/koffi/src/{abi_x64_win_asm.S → abi/x64win_asm.S} +8 -12
  44. package/src/koffi/src/{abi_x64_win_asm.asm → abi/x64win_asm.asm} +11 -14
  45. package/src/koffi/src/abi/x86.cc +1233 -0
  46. package/src/koffi/src/{abi_x86_asm.S → abi/x86_asm.S} +49 -25
  47. package/src/koffi/src/{abi_x86_asm.asm → abi/x86_asm.asm} +11 -14
  48. package/src/koffi/src/call.cc +458 -598
  49. package/src/koffi/src/call.hh +61 -82
  50. package/src/koffi/src/ffi.cc +595 -309
  51. package/src/koffi/src/ffi.hh +103 -89
  52. package/src/koffi/src/parser.cc +0 -4
  53. package/src/koffi/src/primitives.inc +39 -0
  54. package/src/koffi/{tools/write_trampolines.js → src/trampolines.js} +1 -1
  55. package/src/koffi/src/util.cc +503 -446
  56. package/src/koffi/src/util.hh +269 -57
  57. package/src/koffi/src/uv.cc +2 -2
  58. package/src/koffi/src/uv.def +3 -0
  59. package/src/koffi/src/win32.hh +30 -1
  60. package/vendor/node-addon-api/napi-inl.h +4 -0
  61. package/vendor/node-addon-api/napi.h +1 -0
  62. package/build/koffi/linux_armhf/koffi.node +0 -0
  63. package/build/koffi/linux_loong64/koffi.node +0 -0
  64. package/build/koffi/linux_riscv64d/koffi.node +0 -0
  65. package/build/koffi/win32_arm64/koffi.exp +0 -0
  66. package/build/koffi/win32_arm64/koffi.lib +0 -0
  67. package/build/koffi/win32_arm64/koffi.node +0 -0
  68. package/doc/platforms.md +0 -36
  69. package/src/cnoke/LICENSE.txt +0 -22
  70. package/src/cnoke/README.md +0 -99
  71. package/src/cnoke/assets/FindCNoke.cmake +0 -127
  72. package/src/cnoke/assets/toolchains.json +0 -126
  73. package/src/cnoke/assets/win_delay_hook.c +0 -36
  74. package/src/cnoke/cnoke.js +0 -170
  75. package/src/cnoke/package.json +0 -24
  76. package/src/cnoke/src/builder.js +0 -511
  77. package/src/cnoke/src/index.js +0 -10
  78. package/src/cnoke/src/tools.js +0 -407
  79. package/src/koffi/src/abi_arm64.cc +0 -1295
  80. package/src/koffi/src/abi_x64_sysv.cc +0 -939
  81. package/src/koffi/src/abi_x64_win.cc +0 -715
  82. package/src/koffi/src/abi_x86.cc +0 -860
  83. package/src/koffi/src/init.js +0 -105
  84. /package/src/koffi/src/{abi_loong64.cc → abi/loong64.cc} +0 -0
@@ -4,9 +4,9 @@
4
4
  #if defined(__arm__) || (defined(__M_ARM) && !defined(_M_ARM64))
5
5
 
6
6
  #include "lib/native/base/base.hh"
7
- #include "ffi.hh"
8
- #include "call.hh"
9
- #include "util.hh"
7
+ #include "../ffi.hh"
8
+ #include "../call.hh"
9
+ #include "../util.hh"
10
10
 
11
11
  #include <napi.h>
12
12
  #include <signal.h>
@@ -38,10 +38,11 @@ extern "C" uint64_t ForwardCallXGG(const void *func, uint8_t *sp, uint8_t **out_
38
38
  extern "C" float ForwardCallXF(const void *func, uint8_t *sp, uint8_t **out_old_sp);
39
39
  extern "C" HfaRet ForwardCallXDDDD(const void *func, uint8_t *sp, uint8_t **out_old_sp);
40
40
 
41
- extern "C" uint8_t Trampoline0;
42
- extern "C" uint8_t TrampolineEnd;
43
- extern "C" void *FindTrampolineStart();
44
- extern "C" void *FindTrampolineEnd();
41
+ enum class AbiOpcode : int8_t {
42
+ #define PRIMITIVE(Name) Name,
43
+ #include "../primitives.inc"
44
+ End
45
+ };
45
46
 
46
47
  static int IsHFA(const TypeInfo *type)
47
48
  {
@@ -190,9 +191,11 @@ bool AnalyseFunction(Napi::Env, InstanceData *, FunctionInfo *func)
190
191
  case PrimitiveKind::Prototype: { K_UNREACHABLE(); } break;
191
192
  }
192
193
 
194
+ func->instructions.Append((AbiOpcode)param.type->primitive);
193
195
  func->args_size += AlignLen(param.type->size, 16);
194
196
  }
195
197
 
198
+ func->instructions.Append(AbiOpcode::End);
196
199
  func->forward_fp = (vec_avail < 16);
197
200
 
198
201
  return true;
@@ -200,54 +203,74 @@ bool AnalyseFunction(Napi::Env, InstanceData *, FunctionInfo *func)
200
203
 
201
204
  bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
202
205
  {
203
- uint32_t *args_ptr = nullptr;
204
- uint32_t *gpr_ptr = nullptr;
205
- uint32_t *vec_ptr = nullptr;
206
-
207
- // Unlike other call conventions, here we put the general-purpose
208
- // registers just before the stack (so behind the vector ones).
209
- // In the armv7hf calling convention, some arguments can end up
210
- // partially in GPR, partially in the stack.
211
- if (!AllocStack(func->args_size, 16, &args_ptr)) [[unlikely]]
212
- return false;
213
- if (!AllocStack(4 * 4, 8, &gpr_ptr)) [[unlikely]]
214
- return false;
215
- if (!AllocStack(8 * 8, 8, &vec_ptr)) [[unlikely]]
206
+ // Unlike other call conventions, here we put the general-purpose registers before the stack, behind the vector ones).
207
+ // In the armv7hf calling convention, some arguments can end up partially in GPR, partially in the stack.
208
+ uint32_t *vec_ptr = AllocStack<uint32_t>(20 * 4 + func->args_size);
209
+ uint32_t *gpr_ptr = vec_ptr + 16;
210
+ uint32_t *args_ptr = vec_ptr + 20;
211
+
212
+ if (!vec_ptr) [[unlikely]]
216
213
  return false;
217
214
  if (func->ret.use_memory) {
218
- return_ptr = AllocHeap(func->ret.type->size, 16);
215
+ return_ptr = AllocHeap(func->ret.type->size);
219
216
  *(uint8_t **)(gpr_ptr++) = return_ptr;
220
217
  }
221
218
 
219
+ Size i = -1;
220
+
221
+ static const void *const DispatchTable[] = {
222
+ #define PRIMITIVE(Name) && Name,
223
+ #include "../primitives.inc"
224
+ && End
225
+ };
226
+
227
+ #define LOOP
228
+ #define CASE(Primitive) \
229
+ do { \
230
+ AbiOpcode next = func->instructions[++i]; \
231
+ goto *DispatchTable[(int)next]; \
232
+ } while (false); \
233
+ Primitive:
234
+ #define OR(Primitive) \
235
+ Primitive:
236
+
222
237
  #define PUSH_INTEGER_32(CType) \
223
238
  do { \
224
- if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] { \
239
+ const ParameterInfo &param = func->parameters[i]; \
240
+ Napi::Value value = info[param.offset]; \
241
+ \
242
+ CType v; \
243
+ if (!TryNumber(value, &v)) [[unlikely]] { \
225
244
  ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value)); \
226
245
  return false; \
227
246
  } \
228
247
  \
229
- CType v = GetNumber<CType>(value); \
230
248
  *((param.gpr_count ? gpr_ptr : args_ptr)++) = (uint32_t)v; \
231
249
  } while (false)
232
250
  #define PUSH_INTEGER_32_SWAP(CType) \
233
251
  do { \
234
- if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] { \
252
+ const ParameterInfo &param = func->parameters[i]; \
253
+ Napi::Value value = info[param.offset]; \
254
+ \
255
+ CType v; \
256
+ if (!TryNumber(value, &v)) [[unlikely]] { \
235
257
  ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value)); \
236
258
  return false; \
237
259
  } \
238
260
  \
239
- CType v = GetNumber<CType>(value); \
240
261
  *((param.gpr_count ? gpr_ptr : args_ptr)++) = (uint32_t)ReverseBytes(v); \
241
262
  } while (false)
242
263
  #define PUSH_INTEGER_64(CType) \
243
264
  do { \
244
- if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] { \
265
+ const ParameterInfo &param = func->parameters[i]; \
266
+ Napi::Value value = info[param.offset]; \
267
+ \
268
+ CType v; \
269
+ if (!TryNumber(value, &v)) [[unlikely]] { \
245
270
  ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value)); \
246
271
  return false; \
247
272
  } \
248
273
  \
249
- CType v = GetNumber<CType>(value); \
250
- \
251
274
  if (param.gpr_count) [[likely]] { \
252
275
  gpr_ptr = AlignUp(gpr_ptr, 8); \
253
276
  *(uint64_t *)gpr_ptr = (uint64_t)v; \
@@ -260,13 +283,15 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
260
283
  } while (false)
261
284
  #define PUSH_INTEGER_64_SWAP(CType) \
262
285
  do { \
263
- if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] { \
286
+ const ParameterInfo &param = func->parameters[i]; \
287
+ Napi::Value value = info[param.offset]; \
288
+ \
289
+ CType v; \
290
+ if (!TryNumber(value, &v)) [[unlikely]] { \
264
291
  ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value)); \
265
292
  return false; \
266
293
  } \
267
294
  \
268
- CType v = GetNumber<CType>(value); \
269
- \
270
295
  if (param.gpr_count) [[likely]] { \
271
296
  gpr_ptr = AlignUp(gpr_ptr, 8); \
272
297
  *(uint64_t *)gpr_ptr = (uint64_t)ReverseBytes(v); \
@@ -278,148 +303,172 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
278
303
  } \
279
304
  } while (false)
280
305
 
281
- // Push arguments
282
- for (Size i = 0; i < func->parameters.len; i++) {
283
- const ParameterInfo &param = func->parameters[i];
284
- K_ASSERT(param.directions >= 1 && param.directions <= 3);
306
+ LOOP {
307
+ CASE(Void) { K_UNREACHABLE(); };
285
308
 
286
- Napi::Value value = info[param.offset];
309
+ CASE(Bool) {
310
+ const ParameterInfo &param = func->parameters[i];
311
+ Napi::Value value = info[param.offset];
287
312
 
288
- switch (param.type->primitive) {
289
- case PrimitiveKind::Void: { K_UNREACHABLE(); } break;
313
+ bool b;
314
+ if (napi_get_value_bool(env, value, &b) != napi_ok) [[unlikely]] {
315
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected boolean", GetValueType(instance, value));
316
+ return false;
317
+ }
290
318
 
291
- case PrimitiveKind::Bool: {
292
- if (!value.IsBoolean()) [[unlikely]] {
293
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected boolean", GetValueType(instance, value));
294
- return false;
295
- }
319
+ *((param.gpr_count ? gpr_ptr : args_ptr)++) = (uint32_t)b;
320
+ };
321
+
322
+ CASE(Int8) { PUSH_INTEGER_32(int8_t); };
323
+ CASE(UInt8) { PUSH_INTEGER_32(uint8_t); };
324
+ CASE(Int16) { PUSH_INTEGER_32(int16_t); };
325
+ CASE(Int16S) { PUSH_INTEGER_32_SWAP(int16_t); };
326
+ CASE(UInt16) { PUSH_INTEGER_32(uint16_t); };
327
+ CASE(UInt16S) { PUSH_INTEGER_32_SWAP(uint16_t); };
328
+ CASE(Int32) { PUSH_INTEGER_32(int32_t); };
329
+ CASE(Int32S) { PUSH_INTEGER_32_SWAP(int32_t); };
330
+ CASE(UInt32) { PUSH_INTEGER_32(uint32_t); };
331
+ CASE(UInt32S) { PUSH_INTEGER_32_SWAP(uint32_t); };
332
+ CASE(Int64) { PUSH_INTEGER_64(int64_t); };
333
+ CASE(Int64S) { PUSH_INTEGER_64_SWAP(int64_t); };
334
+ CASE(UInt64) { PUSH_INTEGER_64(uint64_t); };
335
+ CASE(UInt64S) { PUSH_INTEGER_64_SWAP(uint64_t); };
336
+
337
+ CASE(String) {
338
+ const ParameterInfo &param = func->parameters[i];
339
+ Napi::Value value = info[param.offset];
296
340
 
297
- bool b = value.As<Napi::Boolean>();
298
- *((param.gpr_count ? gpr_ptr : args_ptr)++) = (uint32_t)b;
299
- } break;
300
- case PrimitiveKind::Int8: { PUSH_INTEGER_32(int8_t); } break;
301
- case PrimitiveKind::UInt8: { PUSH_INTEGER_32(uint8_t); } break;
302
- case PrimitiveKind::Int16: { PUSH_INTEGER_32(int16_t); } break;
303
- case PrimitiveKind::Int16S: { PUSH_INTEGER_32_SWAP(int16_t); } break;
304
- case PrimitiveKind::UInt16: { PUSH_INTEGER_32(uint16_t); } break;
305
- case PrimitiveKind::UInt16S: { PUSH_INTEGER_32_SWAP(uint16_t); } break;
306
- case PrimitiveKind::Int32: { PUSH_INTEGER_32(int32_t); } break;
307
- case PrimitiveKind::Int32S: { PUSH_INTEGER_32_SWAP(int32_t); } break;
308
- case PrimitiveKind::UInt32: { PUSH_INTEGER_32(uint32_t); } break;
309
- case PrimitiveKind::UInt32S: { PUSH_INTEGER_32_SWAP(uint32_t); } break;
310
- case PrimitiveKind::Int64: { PUSH_INTEGER_64(int64_t); } break;
311
- case PrimitiveKind::Int64S: { PUSH_INTEGER_64_SWAP(int64_t); } break;
312
- case PrimitiveKind::UInt64: { PUSH_INTEGER_64(uint64_t); } break;
313
- case PrimitiveKind::UInt64S: { PUSH_INTEGER_64_SWAP(uint64_t); } break;
314
- case PrimitiveKind::String: {
315
- const char *str;
316
- if (!PushString(value, param.directions, &str)) [[unlikely]]
317
- return false;
341
+ const char *str;
342
+ if (!PushString(value, param.directions, &str)) [[unlikely]]
343
+ return false;
318
344
 
319
- *(const char **)((param.gpr_count ? gpr_ptr : args_ptr)++) = str;
320
- } break;
321
- case PrimitiveKind::String16: {
322
- const char16_t *str16;
323
- if (!PushString16(value, param.directions, &str16)) [[unlikely]]
324
- return false;
345
+ *(const char **)((param.gpr_count ? gpr_ptr : args_ptr)++) = str;
346
+ };
347
+ CASE(String16) {
348
+ const ParameterInfo &param = func->parameters[i];
349
+ Napi::Value value = info[param.offset];
325
350
 
326
- *(const char16_t **)((param.gpr_count ? gpr_ptr : args_ptr)++) = str16;
327
- } break;
328
- case PrimitiveKind::String32: {
329
- const char32_t *str32;
330
- if (!PushString32(value, param.directions, &str32)) [[unlikely]]
331
- return false;
351
+ const char16_t *str16;
352
+ if (!PushString16(value, param.directions, &str16)) [[unlikely]]
353
+ return false;
332
354
 
333
- *(const char32_t **)((param.gpr_count ? gpr_ptr : args_ptr)++) = str32;
334
- } break;
335
- case PrimitiveKind::Pointer: {
336
- void *ptr;
337
- if (!PushPointer(value, param.type, param.directions, &ptr)) [[unlikely]]
338
- return false;
355
+ *(const char16_t **)((param.gpr_count ? gpr_ptr : args_ptr)++) = str16;
356
+ };
357
+ CASE(String32) {
358
+ const ParameterInfo &param = func->parameters[i];
359
+ Napi::Value value = info[param.offset];
339
360
 
340
- *(void **)((param.gpr_count ? gpr_ptr : args_ptr)++) = ptr;
341
- } break;
342
- case PrimitiveKind::Record:
343
- case PrimitiveKind::Union: {
344
- if (!IsObject(value)) [[unlikely]] {
345
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected object", GetValueType(instance, value));
346
- return false;
347
- }
361
+ const char32_t *str32;
362
+ if (!PushString32(value, param.directions, &str32)) [[unlikely]]
363
+ return false;
348
364
 
349
- Napi::Object obj = value.As<Napi::Object>();
365
+ *(const char32_t **)((param.gpr_count ? gpr_ptr : args_ptr)++) = str32;
366
+ };
350
367
 
351
- if (param.vec_count) {
352
- if (!PushObject(obj, param.type, (uint8_t *)vec_ptr))
353
- return false;
354
- vec_ptr += param.vec_count;
355
- } else if (param.gpr_count) {
356
- K_ASSERT(param.type->align <= 8);
368
+ CASE(Pointer) {
369
+ const ParameterInfo &param = func->parameters[i];
370
+ Napi::Value value = info[param.offset];
357
371
 
358
- int16_t align = (param.type->align <= 4) ? 4 : 8;
359
- gpr_ptr = AlignUp(gpr_ptr, align);
372
+ void *ptr;
373
+ if (!PushPointer(value, param.type, param.directions, &ptr)) [[unlikely]]
374
+ return false;
360
375
 
361
- if (!PushObject(obj, param.type, (uint8_t *)gpr_ptr))
362
- return false;
376
+ *(void **)((param.gpr_count ? gpr_ptr : args_ptr)++) = ptr;
377
+ };
363
378
 
364
- gpr_ptr += param.gpr_count;
365
- args_ptr += (param.type->size - param.gpr_count * 4 + 3) / 4;
366
- } else if (param.type->size) {
367
- int16_t align = (param.type->align <= 4) ? 4 : 8;
368
- args_ptr = AlignUp(args_ptr, align);
379
+ CASE(Record) OR(Union) {
380
+ const ParameterInfo &param = func->parameters[i];
381
+ Napi::Value value = info[param.offset];
369
382
 
370
- if (!PushObject(obj, param.type, (uint8_t *)args_ptr))
371
- return false;
372
- args_ptr += (param.type->size + 3) / 4;
373
- }
374
- } break;
375
- case PrimitiveKind::Array: { K_UNREACHABLE(); } break;
376
- case PrimitiveKind::Float32: {
377
- if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] {
378
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value));
383
+ if (!IsObject(value)) [[unlikely]] {
384
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected object", GetValueType(instance, value));
385
+ return false;
386
+ }
387
+
388
+ Napi::Object obj = value.As<Napi::Object>();
389
+
390
+ if (param.vec_count) {
391
+ if (!PushObject(obj, param.type, (uint8_t *)vec_ptr))
379
392
  return false;
380
- }
393
+ vec_ptr += param.vec_count;
394
+ } else if (param.gpr_count) {
395
+ K_ASSERT(param.type->align <= 8);
381
396
 
382
- float f = GetNumber<float>(value);
397
+ int16_t align = (param.type->align <= 4) ? 4 : 8;
398
+ gpr_ptr = AlignUp(gpr_ptr, align);
383
399
 
384
- if (param.vec_count) [[likely]] {
385
- *(float *)(vec_ptr++) = f;
386
- } else if (param.gpr_count) {
387
- *(float *)(gpr_ptr++) = f;
388
- } else {
389
- *(float *)(args_ptr++) = f;
390
- }
391
- } break;
392
- case PrimitiveKind::Float64: {
393
- if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] {
394
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value));
400
+ if (!PushObject(obj, param.type, (uint8_t *)gpr_ptr))
395
401
  return false;
396
- }
397
402
 
398
- double d = GetNumber<double>(value);
403
+ gpr_ptr += param.gpr_count;
404
+ args_ptr += (param.type->size - param.gpr_count * 4 + 3) / 4;
405
+ } else if (param.type->size) {
406
+ int16_t align = (param.type->align <= 4) ? 4 : 8;
407
+ args_ptr = AlignUp(args_ptr, align);
399
408
 
400
- if (param.vec_count) [[likely]] {
401
- *(double *)vec_ptr = d;
402
- vec_ptr += 2;
403
- } else if (param.gpr_count) {
404
- gpr_ptr = AlignUp(gpr_ptr, 8);
405
- *(double *)gpr_ptr = d;
406
- gpr_ptr += 2;
407
- } else {
408
- args_ptr = AlignUp(args_ptr, 8);
409
- *(double *)args_ptr = d;
410
- args_ptr += 2;
411
- }
412
- } break;
413
- case PrimitiveKind::Callback: {
414
- void *ptr;
415
- if (!PushCallback(value, param.type, &ptr)) [[unlikely]]
409
+ if (!PushObject(obj, param.type, (uint8_t *)args_ptr))
416
410
  return false;
411
+ args_ptr += (param.type->size + 3) / 4;
412
+ }
413
+ };
414
+ CASE(Array) { K_UNREACHABLE(); };
417
415
 
418
- *(void **)((param.gpr_count ? gpr_ptr : args_ptr)++) = ptr;
419
- } break;
416
+ CASE(Float32) {
417
+ const ParameterInfo &param = func->parameters[i];
418
+ Napi::Value value = info[param.offset];
420
419
 
421
- case PrimitiveKind::Prototype: { K_UNREACHABLE(); } break;
422
- }
420
+ float f;
421
+ if (!TryNumber(value, &f)) [[unlikely]] {
422
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value));
423
+ return false;
424
+ }
425
+
426
+ if (param.vec_count) [[likely]] {
427
+ *(float *)(vec_ptr++) = f;
428
+ } else if (param.gpr_count) {
429
+ *(float *)(gpr_ptr++) = f;
430
+ } else {
431
+ *(float *)(args_ptr++) = f;
432
+ }
433
+ };
434
+ CASE(Float64) {
435
+ const ParameterInfo &param = func->parameters[i];
436
+ Napi::Value value = info[param.offset];
437
+
438
+ double d;
439
+ if (!TryNumber(value, &d)) [[unlikely]] {
440
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value));
441
+ return false;
442
+ }
443
+
444
+ if (param.vec_count) [[likely]] {
445
+ *(double *)vec_ptr = d;
446
+ vec_ptr += 2;
447
+ } else if (param.gpr_count) {
448
+ gpr_ptr = AlignUp(gpr_ptr, 8);
449
+ *(double *)gpr_ptr = d;
450
+ gpr_ptr += 2;
451
+ } else {
452
+ args_ptr = AlignUp(args_ptr, 8);
453
+ *(double *)args_ptr = d;
454
+ args_ptr += 2;
455
+ }
456
+ };
457
+
458
+ CASE(Callback) {
459
+ const ParameterInfo &param = func->parameters[i];
460
+ Napi::Value value = info[param.offset];
461
+
462
+ void *ptr;
463
+ if (!PushCallback(value, param.type, &ptr)) [[unlikely]]
464
+ return false;
465
+
466
+ *(void **)((param.gpr_count ? gpr_ptr : args_ptr)++) = ptr;
467
+ };
468
+
469
+ CASE(Prototype) { K_UNREACHABLE(); };
470
+
471
+ CASE(End) { /* End loop */ };
423
472
  }
424
473
 
425
474
  #undef PUSH_INTEGER_64_SWAP
@@ -427,6 +476,10 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
427
476
  #undef PUSH_INTEGER_32_SWAP
428
477
  #undef PUSH_INTEGER_32
429
478
 
479
+ #undef OR
480
+ #undef CASE
481
+ #undef LOOP
482
+
430
483
  new_sp = mem->stack.end();
431
484
 
432
485
  return true;
@@ -486,8 +539,6 @@ void CallData::Execute(const FunctionInfo *func, void *native)
486
539
  Napi::Value CallData::Complete(const FunctionInfo *func)
487
540
  {
488
541
  K_DEFER {
489
- PopOutArguments();
490
-
491
542
  if (func->ret.type->dispose) {
492
543
  func->ret.type->dispose(env, func->ret.type, result.ptr);
493
544
  }
@@ -496,34 +547,25 @@ Napi::Value CallData::Complete(const FunctionInfo *func)
496
547
  switch (func->ret.type->primitive) {
497
548
  case PrimitiveKind::Void: return env.Undefined();
498
549
  case PrimitiveKind::Bool: return Napi::Boolean::New(env, result.u8 & 0x1);
499
- case PrimitiveKind::Int8: return Napi::Number::New(env, (double)result.i8);
500
- case PrimitiveKind::UInt8: return Napi::Number::New(env, (double)result.u8);
501
- case PrimitiveKind::Int16: return Napi::Number::New(env, (double)result.i16);
502
- case PrimitiveKind::Int16S: return Napi::Number::New(env, (double)ReverseBytes(result.i16));
503
- case PrimitiveKind::UInt16: return Napi::Number::New(env, (double)result.u16);
504
- case PrimitiveKind::UInt16S: return Napi::Number::New(env, (double)ReverseBytes(result.u16));
505
- case PrimitiveKind::Int32: return Napi::Number::New(env, (double)result.i32);
506
- case PrimitiveKind::Int32S: return Napi::Number::New(env, (double)ReverseBytes(result.i32));
507
- case PrimitiveKind::UInt32: return Napi::Number::New(env, (double)result.u32);
508
- case PrimitiveKind::UInt32S: return Napi::Number::New(env, (double)ReverseBytes(result.u32));
509
- case PrimitiveKind::Int64: return NewBigInt(env, result.i64);
510
- case PrimitiveKind::Int64S: return NewBigInt(env, ReverseBytes(result.i64));
511
- case PrimitiveKind::UInt64: return NewBigInt(env, result.u64);
512
- case PrimitiveKind::UInt64S: return NewBigInt(env, ReverseBytes(result.u64));
550
+ case PrimitiveKind::Int8: return NewInt(env, result.i8);
551
+ case PrimitiveKind::UInt8: return NewInt(env, result.u8);
552
+ case PrimitiveKind::Int16: return NewInt(env, result.i16);
553
+ case PrimitiveKind::Int16S: return NewInt(env, ReverseBytes(result.i16));
554
+ case PrimitiveKind::UInt16: return NewInt(env, result.u16);
555
+ case PrimitiveKind::UInt16S: return NewInt(env, ReverseBytes(result.u16));
556
+ case PrimitiveKind::Int32: return NewInt(env, result.i32);
557
+ case PrimitiveKind::Int32S: return NewInt(env, ReverseBytes(result.i32));
558
+ case PrimitiveKind::UInt32: return NewInt(env, result.u32);
559
+ case PrimitiveKind::UInt32S: return NewInt(env, ReverseBytes(result.u32));
560
+ case PrimitiveKind::Int64: return NewInt(env, result.i64);
561
+ case PrimitiveKind::Int64S: return NewInt(env, ReverseBytes(result.i64));
562
+ case PrimitiveKind::UInt64: return NewInt(env, result.u64);
563
+ case PrimitiveKind::UInt64S: return NewInt(env, ReverseBytes(result.u64));
513
564
  case PrimitiveKind::String: return result.ptr ? Napi::String::New(env, (const char *)result.ptr) : env.Null();
514
565
  case PrimitiveKind::String16: return result.ptr ? Napi::String::New(env, (const char16_t *)result.ptr) : env.Null();
515
566
  case PrimitiveKind::String32: return result.ptr ? MakeStringFromUTF32(env, (const char32_t *)result.ptr) : env.Null();
516
- case PrimitiveKind::Pointer:
517
- case PrimitiveKind::Callback: {
518
- if (result.ptr) {
519
- Napi::External<void> external = Napi::External<void>::New(env, result.ptr);
520
- SetValueTag(external, func->ret.type->ref.marker);
521
-
522
- return external;
523
- } else {
524
- return env.Null();
525
- }
526
- } break;
567
+ case PrimitiveKind::Pointer: return result.ptr ? WrapPointer(env, func->ret.type->ref.type, result.ptr) : env.Null();
568
+ case PrimitiveKind::Callback: return result.ptr ? WrapCallback(env, func->ret.type->ref.type, result.ptr) : env.Null();
527
569
  case PrimitiveKind::Record:
528
570
  case PrimitiveKind::Union: {
529
571
  const uint8_t *ptr = return_ptr ? (const uint8_t *)return_ptr
@@ -544,14 +586,14 @@ Napi::Value CallData::Complete(const FunctionInfo *func)
544
586
 
545
587
  void CallData::Relay(Size idx, uint8_t *sp)
546
588
  {
547
- const TrampolineInfo &trampoline = shared.trampolines[idx];
589
+ TrampolineInfo *trampoline = &shared.trampolines[idx];
548
590
 
549
591
  uint8_t *own_sp = sp;
550
592
  uint8_t *caller_sp = sp + 128;
551
593
  BackRegisters *out_reg = (BackRegisters *)(sp + 80);
552
594
 
553
- const FunctionInfo *proto = trampoline.proto;
554
- Napi::Function func = trampoline.func.Value();
595
+ const FunctionInfo *proto = trampoline->proto;
596
+ Napi::Function func = trampoline->func.Value();
555
597
 
556
598
  uint32_t *vec_ptr = (uint32_t *)own_sp;
557
599
  uint32_t *gpr_ptr = vec_ptr + 16;
@@ -560,11 +602,14 @@ void CallData::Relay(Size idx, uint8_t *sp)
560
602
  uint8_t *return_ptr = proto->ret.use_memory ? (uint8_t *)gpr_ptr[0] : nullptr;
561
603
  gpr_ptr += proto->ret.use_memory;
562
604
 
563
- K_DEFER_N(err_guard) { memset(out_reg, 0, K_SIZE(*out_reg)); };
605
+ K_DEFER_N(err_guard) {
606
+ trampoline->state = -1;
607
+ memset(out_reg, 0, K_SIZE(*out_reg));
608
+ };
564
609
 
565
610
  LocalArray<napi_value, MaxParameters + 1> arguments;
566
611
 
567
- arguments.Append(!trampoline.recv.IsEmpty() ? trampoline.recv.Value() : env.Undefined());
612
+ arguments.Append(!trampoline->recv.IsEmpty() ? trampoline->recv.Value() : env.Undefined());
568
613
 
569
614
  // Convert to JS arguments
570
615
  for (Size i = 0; i < proto->parameters.len; i++) {
@@ -581,67 +626,63 @@ void CallData::Relay(Size idx, uint8_t *sp)
581
626
  arguments.Append(arg);
582
627
  } break;
583
628
  case PrimitiveKind::Int8: {
584
- double d = (double)*(int8_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
629
+ int8_t v = *(int8_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
585
630
 
586
- Napi::Value arg = Napi::Number::New(env, d);
631
+ Napi::Value arg = NewInt(env, v);
587
632
  arguments.Append(arg);
588
633
  } break;
589
634
  case PrimitiveKind::UInt8: {
590
- double d = (double)*(uint8_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
635
+ uint8_t v = *(uint8_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
591
636
 
592
- Napi::Value arg = Napi::Number::New(env, d);
637
+ Napi::Value arg = NewInt(env, v);
593
638
  arguments.Append(arg);
594
639
  } break;
595
640
  case PrimitiveKind::Int16: {
596
- double d = (double)*(int16_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
641
+ int16_t v = *(int16_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
597
642
 
598
- Napi::Value arg = Napi::Number::New(env, d);
643
+ Napi::Value arg = NewInt(env, v);
599
644
  arguments.Append(arg);
600
645
  } break;
601
646
  case PrimitiveKind::Int16S: {
602
647
  int16_t v = *(int16_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
603
- double d = (double)ReverseBytes(v);
604
648
 
605
- Napi::Value arg = Napi::Number::New(env, d);
649
+ Napi::Value arg = NewInt(env, ReverseBytes(v));
606
650
  arguments.Append(arg);
607
651
  } break;
608
652
  case PrimitiveKind::UInt16: {
609
- double d = (double)*(uint16_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
653
+ uint16_t v = *(uint16_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
610
654
 
611
- Napi::Value arg = Napi::Number::New(env, d);
655
+ Napi::Value arg = NewInt(env, v);
612
656
  arguments.Append(arg);
613
657
  } break;
614
658
  case PrimitiveKind::UInt16S: {
615
659
  uint16_t v = *(uint16_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
616
- double d = (double)ReverseBytes(v);
617
660
 
618
- Napi::Value arg = Napi::Number::New(env, d);
661
+ Napi::Value arg = NewInt(env, ReverseBytes(v));
619
662
  arguments.Append(arg);
620
663
  } break;
621
664
  case PrimitiveKind::Int32: {
622
- double d = (double)*(int32_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
665
+ int32_t v = *(int32_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
623
666
 
624
- Napi::Value arg = Napi::Number::New(env, d);
667
+ Napi::Value arg = NewInt(env, v);
625
668
  arguments.Append(arg);
626
669
  } break;
627
670
  case PrimitiveKind::Int32S: {
628
671
  int32_t v = *(int32_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
629
- double d = (double)ReverseBytes(v);
630
672
 
631
- Napi::Value arg = Napi::Number::New(env, d);
673
+ Napi::Value arg = NewInt(env, ReverseBytes(v));
632
674
  arguments.Append(arg);
633
675
  } break;
634
676
  case PrimitiveKind::UInt32: {
635
- double d = (double)*(uint32_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
677
+ uint32_t v = *(uint32_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
636
678
 
637
- Napi::Value arg = Napi::Number::New(env, d);
679
+ Napi::Value arg = NewInt(env, v);
638
680
  arguments.Append(arg);
639
681
  } break;
640
682
  case PrimitiveKind::UInt32S: {
641
683
  uint32_t v = *(uint32_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
642
- double d = (double)ReverseBytes(v);
643
684
 
644
- Napi::Value arg = Napi::Number::New(env, d);
685
+ Napi::Value arg = NewInt(env, ReverseBytes(v));
645
686
  arguments.Append(arg);
646
687
  } break;
647
688
  case PrimitiveKind::Int64: {
@@ -650,7 +691,7 @@ void CallData::Relay(Size idx, uint8_t *sp)
650
691
  int64_t v = *(int64_t *)(param.gpr_count ? gpr_ptr : args_ptr);
651
692
  (param.gpr_count ? gpr_ptr : args_ptr) += 2;
652
693
 
653
- Napi::Value arg = NewBigInt(env, v);
694
+ Napi::Value arg = NewInt(env, v);
654
695
  arguments.Append(arg);
655
696
  } break;
656
697
  case PrimitiveKind::Int64S: {
@@ -659,7 +700,7 @@ void CallData::Relay(Size idx, uint8_t *sp)
659
700
  int64_t v = *(int64_t *)(param.gpr_count ? gpr_ptr : args_ptr);
660
701
  (param.gpr_count ? gpr_ptr : args_ptr) += 2;
661
702
 
662
- Napi::Value arg = NewBigInt(env, ReverseBytes(v));
703
+ Napi::Value arg = NewInt(env, ReverseBytes(v));
663
704
  arguments.Append(arg);
664
705
  } break;
665
706
  case PrimitiveKind::UInt64: {
@@ -668,7 +709,7 @@ void CallData::Relay(Size idx, uint8_t *sp)
668
709
  uint64_t v = *(uint64_t *)(param.gpr_count ? gpr_ptr : args_ptr);
669
710
  (param.gpr_count ? gpr_ptr : args_ptr) += 2;
670
711
 
671
- Napi::Value arg = NewBigInt(env, v);
712
+ Napi::Value arg = NewInt(env, v);
672
713
  arguments.Append(arg);
673
714
  } break;
674
715
  case PrimitiveKind::UInt64S: {
@@ -677,7 +718,7 @@ void CallData::Relay(Size idx, uint8_t *sp)
677
718
  uint64_t v = *(uint64_t *)(param.gpr_count ? gpr_ptr : args_ptr);
678
719
  (param.gpr_count ? gpr_ptr : args_ptr) += 2;
679
720
 
680
- Napi::Value arg = NewBigInt(env, ReverseBytes(v));
721
+ Napi::Value arg = NewInt(env, ReverseBytes(v));
681
722
  arguments.Append(arg);
682
723
  } break;
683
724
  case PrimitiveKind::String: {
@@ -706,18 +747,21 @@ void CallData::Relay(Size idx, uint8_t *sp)
706
747
  Napi::Value arg = str32 ? MakeStringFromUTF32(env, str32) : env.Null();
707
748
  arguments.Append(arg);
708
749
  } break;
709
- case PrimitiveKind::Pointer:
710
- case PrimitiveKind::Callback: {
750
+ case PrimitiveKind::Pointer: {
711
751
  void *ptr2 = *(void **)((param.gpr_count ? gpr_ptr : args_ptr)++);
712
752
 
713
- if (ptr2) {
714
- Napi::External<void> external = Napi::External<void>::New(env, ptr2);
715
- SetValueTag(external, param.type->ref.marker);
753
+ Napi::Value p = ptr2 ? WrapPointer(env, param.type->ref.type, ptr2) : env.Null();
754
+ arguments.Append(p);
716
755
 
717
- arguments.Append(external);
718
- } else {
719
- arguments.Append(env.Null());
756
+ if (param.type->dispose) {
757
+ param.type->dispose(env, param.type, ptr2);
720
758
  }
759
+ } break;
760
+ case PrimitiveKind::Callback: {
761
+ void *ptr2 = *(void **)((param.gpr_count ? gpr_ptr : args_ptr)++);
762
+
763
+ Napi::Value p = ptr2 ? WrapCallback(env, param.type->ref.type, ptr2) : env.Null();
764
+ arguments.Append(p);
721
765
 
722
766
  if (param.type->dispose) {
723
767
  param.type->dispose(env, param.type, ptr2);
@@ -740,7 +784,7 @@ void CallData::Relay(Size idx, uint8_t *sp)
740
784
  if (param.type->size > gpr_size) {
741
785
  // XXX: Expensive, can we do better?
742
786
  // The problem is that the object is split between the GPRs and the caller stack.
743
- uint8_t *ptr = AllocHeap(param.type->size, 16);
787
+ uint8_t *ptr = AllocHeap(param.type->size);
744
788
 
745
789
  memcpy(ptr, gpr_ptr, gpr_size);
746
790
  memcpy(ptr + gpr_size, args_ptr, param.type->size - gpr_size);
@@ -813,45 +857,43 @@ void CallData::Relay(Size idx, uint8_t *sp)
813
857
 
814
858
  #define RETURN_INTEGER_32(CType) \
815
859
  do { \
816
- if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] { \
860
+ CType v; \
861
+ if (!TryNumber(value, &v)) [[unlikely]] { \
817
862
  ThrowError<Napi::TypeError>(env, "Unexpected %1 value for return value, expected number", GetValueType(instance, value)); \
818
863
  return; \
819
864
  } \
820
865
  \
821
- CType v = GetNumber<CType>(value); \
822
866
  out_reg->r0 = (uint32_t)v; \
823
867
  } while (false)
824
868
  #define RETURN_INTEGER_32_SWAP(CType) \
825
869
  do { \
826
- if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] { \
827
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value)); \
870
+ CType v; \
871
+ if (!TryNumber(value, &v)) [[unlikely]] { \
872
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for return value, expected number", GetValueType(instance, value)); \
828
873
  return; \
829
874
  } \
830
875
  \
831
- CType v = GetNumber<CType>(value); \
832
876
  out_reg->r0 = (uint32_t)ReverseBytes(v); \
833
877
  } while (false)
834
878
  #define RETURN_INTEGER_64(CType) \
835
879
  do { \
836
- if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] { \
837
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value)); \
880
+ CType v; \
881
+ if (!TryNumber(value, &v)) [[unlikely]] { \
882
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for return value, expected number", GetValueType(instance, value)); \
838
883
  return; \
839
884
  } \
840
885
  \
841
- CType v = GetNumber<CType>(value); \
842
- \
843
886
  out_reg->r0 = (uint32_t)((uint64_t)v >> 32); \
844
887
  out_reg->r1 = (uint32_t)((uint64_t)v & 0xFFFFFFFFu); \
845
888
  } while (false)
846
889
  #define RETURN_INTEGER_64_SWAP(CType) \
847
890
  do { \
848
- if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] { \
849
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value)); \
891
+ CType v; \
892
+ if (!TryNumber(value, &v)) [[unlikely]] { \
893
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for return value, expected number", GetValueType(instance, value)); \
850
894
  return; \
851
895
  } \
852
896
  \
853
- CType v = ReverseBytes(GetNumber<CType>(value)); \
854
- \
855
897
  out_reg->r0 = (uint32_t)((uint64_t)v >> 32); \
856
898
  out_reg->r1 = (uint32_t)((uint64_t)v & 0xFFFFFFFFu); \
857
899
  } while (false)
@@ -860,12 +902,12 @@ void CallData::Relay(Size idx, uint8_t *sp)
860
902
  switch (type->primitive) {
861
903
  case PrimitiveKind::Void: {} break;
862
904
  case PrimitiveKind::Bool: {
863
- if (!value.IsBoolean()) [[unlikely]] {
905
+ bool b;
906
+ if (napi_get_value_bool(env, value, &b) != napi_ok) [[unlikely]] {
864
907
  ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected boolean", GetValueType(instance, value));
865
908
  return;
866
909
  }
867
910
 
868
- bool b = value.As<Napi::Boolean>();
869
911
  out_reg->r0 = (uint32_t)b;
870
912
  } break;
871
913
  case PrimitiveKind::Int8: { RETURN_INTEGER_32(int8_t); } break;
@@ -904,24 +946,9 @@ void CallData::Relay(Size idx, uint8_t *sp)
904
946
  out_reg->r0 = (uint32_t)str32;
905
947
  } break;
906
948
  case PrimitiveKind::Pointer: {
907
- uint8_t *ptr;
908
-
909
- if (CheckValueTag(value, type->ref.marker)) {
910
- ptr = value.As<Napi::External<uint8_t>>().Data();
911
- } else if (IsObject(value) && (type->ref.type->primitive == PrimitiveKind::Record ||
912
- type->ref.type->primitive == PrimitiveKind::Union)) {
913
- Napi::Object obj = value.As<Napi::Object>();
914
-
915
- ptr = AllocHeap(type->ref.type->size, 16);
916
-
917
- if (!PushObject(obj, type->ref.type, ptr))
918
- return;
919
- } else if (IsNullOrUndefined(value)) {
920
- ptr = nullptr;
921
- } else {
922
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected %2", GetValueType(instance, value), type->name);
949
+ void *ptr;
950
+ if (!PushPointer(value, type, 1, &ptr)) [[unlikely]]
923
951
  return;
924
- }
925
952
 
926
953
  out_reg->r0 = (uint32_t)ptr;
927
954
  } break;
@@ -946,12 +973,12 @@ void CallData::Relay(Size idx, uint8_t *sp)
946
973
  } break;
947
974
  case PrimitiveKind::Array: { K_UNREACHABLE(); } break;
948
975
  case PrimitiveKind::Float32: {
949
- if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] {
976
+ float f;
977
+ if (!TryNumber(value, &f)) [[unlikely]] {
950
978
  ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value));
951
979
  return;
952
980
  }
953
981
 
954
- float f = GetNumber<float>(value);
955
982
  #if defined(__ARM_PCS_VFP)
956
983
  memcpy(&out_reg->d0, &f, 4);
957
984
  #else
@@ -959,12 +986,12 @@ void CallData::Relay(Size idx, uint8_t *sp)
959
986
  #endif
960
987
  } break;
961
988
  case PrimitiveKind::Float64: {
962
- if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] {
989
+ double d;
990
+ if (!TryNumber(value, &d)) [[unlikely]] {
963
991
  ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected number", GetValueType(instance, value));
964
992
  return;
965
993
  }
966
994
 
967
- double d = GetNumber<double>(value);
968
995
  #if defined(__ARM_PCS_VFP)
969
996
  out_reg->d0 = d;
970
997
  #else
@@ -973,21 +1000,8 @@ void CallData::Relay(Size idx, uint8_t *sp)
973
1000
  } break;
974
1001
  case PrimitiveKind::Callback: {
975
1002
  void *ptr;
976
-
977
- if (value.IsFunction()) {
978
- Napi::Function func2 = value.As<Napi::Function>();
979
-
980
- ptr = ReserveTrampoline(type->ref.proto, func2);
981
- if (!ptr) [[unlikely]]
982
- return;
983
- } else if (CheckValueTag(value, type->ref.marker)) {
984
- ptr = value.As<Napi::External<void>>().Data();
985
- } else if (IsNullOrUndefined(value)) {
986
- ptr = nullptr;
987
- } else {
988
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected %2", GetValueType(instance, value), type->name);
1003
+ if (!PushCallback(value, type, &ptr)) [[unlikely]]
989
1004
  return;
990
- }
991
1005
 
992
1006
  out_reg->r0 = (uint32_t)ptr;
993
1007
  } break;
@@ -1003,16 +1017,6 @@ void CallData::Relay(Size idx, uint8_t *sp)
1003
1017
  err_guard.Disable();
1004
1018
  }
1005
1019
 
1006
- void *FindTrampolineStart()
1007
- {
1008
- return &Trampoline0;
1009
- }
1010
-
1011
- void *FindTrampolineEnd()
1012
- {
1013
- return &TrampolineEnd;
1014
- }
1015
-
1016
1020
  }
1017
1021
 
1018
1022
  #endif