koffi 2.1.4 → 2.2.0

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 (89) hide show
  1. package/{src/koffi/ChangeLog.md → ChangeLog.md} +21 -1
  2. package/{src/koffi/LICENSE.txt → LICENSE.txt} +0 -0
  3. package/{src/koffi/README.md → README.md} +0 -0
  4. package/{src/koffi/doc → doc}/Makefile +1 -1
  5. package/{src/koffi/doc → doc}/benchmarks.md +0 -0
  6. package/{src/koffi/doc → doc}/benchmarks.xlsx +0 -0
  7. package/doc/callbacks.md +175 -0
  8. package/{src/koffi/doc → doc}/changes.md +2 -3
  9. package/{src/koffi/doc → doc}/conf.py +29 -6
  10. package/{src/koffi/doc → doc}/contribute.md +0 -0
  11. package/{src/koffi/doc → doc}/functions.md +39 -124
  12. package/{src/koffi/doc → doc}/index.rst +1 -0
  13. package/{src/koffi/doc → doc}/make.bat +1 -1
  14. package/{src/koffi/doc → doc}/memory.md +0 -0
  15. package/{src/koffi/doc → doc}/platforms.md +0 -0
  16. package/{src/koffi/doc → doc}/poetry.lock +0 -0
  17. package/{src/koffi/doc → doc}/pyproject.toml +0 -0
  18. package/{src/koffi/doc → doc}/start.md +0 -0
  19. package/{src/koffi/doc → doc}/static/bench_linux.png +0 -0
  20. package/{src/koffi/doc → doc}/static/bench_windows.png +0 -0
  21. package/{src/koffi/doc → doc}/static/custom.css +0 -0
  22. package/{src/koffi/doc → doc}/static/perf_linux_20220623.png +0 -0
  23. package/{src/koffi/doc → doc}/static/perf_linux_20220623_2.png +0 -0
  24. package/{src/koffi/doc → doc}/static/perf_linux_20220627.png +0 -0
  25. package/{src/koffi/doc → doc}/static/perf_linux_20220628.png +0 -0
  26. package/{src/koffi/doc → doc}/static/perf_linux_20220812.png +0 -0
  27. package/{src/koffi/doc → doc}/static/perf_windows_20220623.png +0 -0
  28. package/{src/koffi/doc → doc}/static/perf_windows_20220623_2.png +0 -0
  29. package/{src/koffi/doc → doc}/static/perf_windows_20220627.png +0 -0
  30. package/{src/koffi/doc → doc}/static/perf_windows_20220628.png +0 -0
  31. package/{src/koffi/doc → doc}/static/perf_windows_20220812.png +0 -0
  32. package/{src/koffi/doc → doc}/templates/badges.html +0 -0
  33. package/{src/koffi/doc → doc}/types.md +36 -9
  34. package/package.json +2 -2
  35. package/src/core/libcc/libcc.cc +89 -27
  36. package/src/core/libcc/libcc.hh +74 -39
  37. package/src/koffi/build/2.2.0/koffi_darwin_arm64.tar.gz +0 -0
  38. package/src/koffi/build/2.2.0/koffi_darwin_x64.tar.gz +0 -0
  39. package/src/koffi/build/2.2.0/koffi_freebsd_arm64.tar.gz +0 -0
  40. package/src/koffi/build/2.2.0/koffi_freebsd_ia32.tar.gz +0 -0
  41. package/src/koffi/build/2.2.0/koffi_freebsd_x64.tar.gz +0 -0
  42. package/src/koffi/build/2.2.0/koffi_linux_arm32hf.tar.gz +0 -0
  43. package/src/koffi/build/2.2.0/koffi_linux_arm64.tar.gz +0 -0
  44. package/src/koffi/build/2.2.0/koffi_linux_ia32.tar.gz +0 -0
  45. package/src/koffi/build/2.2.0/koffi_linux_riscv64hf64.tar.gz +0 -0
  46. package/src/koffi/build/2.2.0/koffi_linux_x64.tar.gz +0 -0
  47. package/src/koffi/build/2.2.0/koffi_openbsd_ia32.tar.gz +0 -0
  48. package/src/koffi/build/2.2.0/koffi_openbsd_x64.tar.gz +0 -0
  49. package/src/koffi/build/2.2.0/koffi_win32_arm64.tar.gz +0 -0
  50. package/src/koffi/build/2.2.0/koffi_win32_ia32.tar.gz +0 -0
  51. package/src/koffi/build/2.2.0/koffi_win32_x64.tar.gz +0 -0
  52. package/src/koffi/qemu/qemu.js +17 -7
  53. package/src/koffi/src/abi_arm32.cc +25 -23
  54. package/src/koffi/src/abi_arm64.cc +24 -22
  55. package/src/koffi/src/abi_riscv64.cc +20 -18
  56. package/src/koffi/src/abi_x64_sysv.cc +19 -17
  57. package/src/koffi/src/abi_x64_win.cc +18 -16
  58. package/src/koffi/src/abi_x86.cc +22 -20
  59. package/src/koffi/src/call.cc +220 -607
  60. package/src/koffi/src/call.hh +7 -11
  61. package/src/koffi/src/ffi.cc +229 -29
  62. package/src/koffi/src/ffi.hh +6 -2
  63. package/src/koffi/src/parser.cc +3 -9
  64. package/src/koffi/src/util.cc +546 -8
  65. package/src/koffi/src/util.hh +8 -2
  66. package/src/koffi/test/CMakeLists.txt +3 -3
  67. package/src/koffi/test/callbacks.js +70 -0
  68. package/src/koffi/test/misc.c +67 -0
  69. package/src/koffi/test/raylib.js +2 -2
  70. package/src/koffi/test/sqlite.js +1 -1
  71. package/src/koffi/test/sync.js +28 -6
  72. package/vendor/brotli/c/common/platform.h +2 -0
  73. package/vendor/sqlite3mc/sqlite3.c +243532 -0
  74. package/vendor/sqlite3mc/sqlite3.h +12887 -0
  75. package/src/koffi/build/2.1.4/koffi_darwin_arm64.tar.gz +0 -0
  76. package/src/koffi/build/2.1.4/koffi_darwin_x64.tar.gz +0 -0
  77. package/src/koffi/build/2.1.4/koffi_freebsd_arm64.tar.gz +0 -0
  78. package/src/koffi/build/2.1.4/koffi_freebsd_ia32.tar.gz +0 -0
  79. package/src/koffi/build/2.1.4/koffi_freebsd_x64.tar.gz +0 -0
  80. package/src/koffi/build/2.1.4/koffi_linux_arm32hf.tar.gz +0 -0
  81. package/src/koffi/build/2.1.4/koffi_linux_arm64.tar.gz +0 -0
  82. package/src/koffi/build/2.1.4/koffi_linux_ia32.tar.gz +0 -0
  83. package/src/koffi/build/2.1.4/koffi_linux_riscv64hf64.tar.gz +0 -0
  84. package/src/koffi/build/2.1.4/koffi_linux_x64.tar.gz +0 -0
  85. package/src/koffi/build/2.1.4/koffi_openbsd_ia32.tar.gz +0 -0
  86. package/src/koffi/build/2.1.4/koffi_openbsd_x64.tar.gz +0 -0
  87. package/src/koffi/build/2.1.4/koffi_win32_arm64.tar.gz +0 -0
  88. package/src/koffi/build/2.1.4/koffi_win32_ia32.tar.gz +0 -0
  89. package/src/koffi/build/2.1.4/koffi_win32_x64.tar.gz +0 -0
@@ -282,7 +282,7 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
282
282
  return false; \
283
283
  } \
284
284
  \
285
- CType v = CopyNumber<CType>(value); \
285
+ CType v = GetNumber<CType>(value); \
286
286
  *((param.gpr_count ? gpr_ptr : args_ptr)++) = (uint32_t)v; \
287
287
  } while (false)
288
288
  #define PUSH_INTEGER_32_SWAP(CType) \
@@ -292,7 +292,7 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
292
292
  return false; \
293
293
  } \
294
294
  \
295
- CType v = CopyNumber<CType>(value); \
295
+ CType v = GetNumber<CType>(value); \
296
296
  *((param.gpr_count ? gpr_ptr : args_ptr)++) = (uint32_t)ReverseBytes(v); \
297
297
  } while (false)
298
298
  #define PUSH_INTEGER_64(CType) \
@@ -302,7 +302,7 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
302
302
  return false; \
303
303
  } \
304
304
  \
305
- CType v = CopyNumber<CType>(value); \
305
+ CType v = GetNumber<CType>(value); \
306
306
  \
307
307
  if (RG_LIKELY(param.gpr_count)) { \
308
308
  gpr_ptr = AlignUp(gpr_ptr, 8); \
@@ -321,7 +321,7 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
321
321
  return false; \
322
322
  } \
323
323
  \
324
- CType v = CopyNumber<CType>(value); \
324
+ CType v = GetNumber<CType>(value); \
325
325
  \
326
326
  if (RG_LIKELY(param.gpr_count)) { \
327
327
  gpr_ptr = AlignUp(gpr_ptr, 8); \
@@ -369,14 +369,14 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
369
369
  case PrimitiveKind::UInt64S: { PUSH_INTEGER_64_SWAP(uint64_t); } break;
370
370
  case PrimitiveKind::String: {
371
371
  const char *str;
372
- if (RG_UNLIKELY(!PushString(value, &str)))
372
+ if (RG_UNLIKELY(!PushString(value, param.directions, &str)))
373
373
  return false;
374
374
 
375
375
  *(const char **)((param.gpr_count ? gpr_ptr : args_ptr)++) = str;
376
376
  } break;
377
377
  case PrimitiveKind::String16: {
378
378
  const char16_t *str16;
379
- if (RG_UNLIKELY(!PushString16(value, &str16)))
379
+ if (RG_UNLIKELY(!PushString16(value, param.directions, &str16)))
380
380
  return false;
381
381
 
382
382
  *(const char16_t **)((param.gpr_count ? gpr_ptr : args_ptr)++) = str16;
@@ -427,7 +427,7 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
427
427
  return false;
428
428
  }
429
429
 
430
- float f = CopyNumber<float>(value);
430
+ float f = GetNumber<float>(value);
431
431
 
432
432
  if (RG_LIKELY(param.vec_count)) {
433
433
  *(float *)(vec_ptr++) = f;
@@ -443,7 +443,7 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
443
443
  return false;
444
444
  }
445
445
 
446
- double d = CopyNumber<double>(value);
446
+ double d = GetNumber<double>(value);
447
447
 
448
448
  if (RG_LIKELY(param.vec_count)) {
449
449
  *(double *)vec_ptr = d;
@@ -588,7 +588,7 @@ Napi::Value CallData::Complete()
588
588
  const uint8_t *ptr = return_ptr ? (const uint8_t *)return_ptr
589
589
  : (const uint8_t *)&result.buf;
590
590
 
591
- Napi::Object obj = PopObject(ptr, func->ret.type);
591
+ Napi::Object obj = DecodeObject(env, ptr, func->ret.type);
592
592
  return obj;
593
593
  } break;
594
594
  case PrimitiveKind::Array: { RG_UNREACHABLE(); } break;
@@ -625,7 +625,9 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
625
625
  return;
626
626
  }
627
627
 
628
- LocalArray<napi_value, MaxParameters> arguments;
628
+ LocalArray<napi_value, MaxParameters + 1> arguments;
629
+
630
+ arguments.Append(!trampoline.recv.IsEmpty() ? trampoline.recv.Value() : env.Undefined());
629
631
 
630
632
  // Convert to JS arguments
631
633
  for (Size i = 0; i < proto->parameters.len; i++) {
@@ -780,7 +782,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
780
782
  } break;
781
783
  case PrimitiveKind::Record: {
782
784
  if (param.vec_count) {
783
- Napi::Object obj = PopObject((const uint8_t *)vec_ptr, param.type);
785
+ Napi::Object obj = DecodeObject(env, (const uint8_t *)vec_ptr, param.type);
784
786
  arguments.Append(obj);
785
787
 
786
788
  vec_ptr += param.vec_count;
@@ -799,13 +801,13 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
799
801
  memcpy(ptr, gpr_ptr, gpr_size);
800
802
  memcpy(ptr + gpr_size, args_ptr, param.type->size - gpr_size);
801
803
 
802
- Napi::Object obj = PopObject(ptr, param.type);
804
+ Napi::Object obj = DecodeObject(env, ptr, param.type);
803
805
  arguments.Append(obj);
804
806
 
805
807
  gpr_ptr += param.gpr_count;
806
808
  args_ptr += (param.type->size - gpr_size + 3) / 4;
807
809
  } else {
808
- Napi::Object obj = PopObject((const uint8_t *)gpr_ptr, param.type);
810
+ Napi::Object obj = DecodeObject(env, (const uint8_t *)gpr_ptr, param.type);
809
811
  arguments.Append(obj);
810
812
 
811
813
  gpr_ptr += param.gpr_count;
@@ -814,7 +816,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
814
816
  int16_t align = (param.type->align <= 4) ? 4 : 8;
815
817
  args_ptr = AlignUp(args_ptr, align);
816
818
 
817
- Napi::Object obj = PopObject((const uint8_t *)args_ptr, param.type);
819
+ Napi::Object obj = DecodeObject(env, (const uint8_t *)args_ptr, param.type);
818
820
  arguments.Append(obj);
819
821
 
820
822
  args_ptr += (param.type->size + 3) / 4;
@@ -861,7 +863,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
861
863
 
862
864
  // Make the call
863
865
  napi_value ret = CallSwitchStack(&func, (size_t)arguments.len, arguments.data, old_sp, &mem->stack,
864
- [](Napi::Function *func, size_t argc, napi_value *argv) { return (napi_value)func->Call(argc, argv); });
866
+ [](Napi::Function *func, size_t argc, napi_value *argv) { return (napi_value)func->Call(argv[0], argc - 1, argv + 1); });
865
867
  Napi::Value value(env, ret);
866
868
 
867
869
  if (RG_UNLIKELY(env.IsExceptionPending()))
@@ -874,7 +876,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
874
876
  return; \
875
877
  } \
876
878
  \
877
- CType v = CopyNumber<CType>(value); \
879
+ CType v = GetNumber<CType>(value); \
878
880
  out_reg->r0 = (uint32_t)v; \
879
881
  } while (false)
880
882
  #define RETURN_INTEGER_32_SWAP(CType) \
@@ -884,7 +886,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
884
886
  return; \
885
887
  } \
886
888
  \
887
- CType v = CopyNumber<CType>(value); \
889
+ CType v = GetNumber<CType>(value); \
888
890
  out_reg->r0 = (uint32_t)ReverseBytes(v); \
889
891
  } while (false)
890
892
  #define RETURN_INTEGER_64(CType) \
@@ -894,7 +896,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
894
896
  return; \
895
897
  } \
896
898
  \
897
- CType v = CopyNumber<CType>(value); \
899
+ CType v = GetNumber<CType>(value); \
898
900
  \
899
901
  out_reg->r0 = (uint32_t)((uint64_t)v >> 32); \
900
902
  out_reg->r1 = (uint32_t)((uint64_t)v & 0xFFFFFFFFu); \
@@ -906,7 +908,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
906
908
  return; \
907
909
  } \
908
910
  \
909
- CType v = ReverseBytes(CopyNumber<CType>(value)); \
911
+ CType v = ReverseBytes(GetNumber<CType>(value)); \
910
912
  \
911
913
  out_reg->r0 = (uint32_t)((uint64_t)v >> 32); \
912
914
  out_reg->r1 = (uint32_t)((uint64_t)v & 0xFFFFFFFFu); \
@@ -940,14 +942,14 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
940
942
  case PrimitiveKind::UInt64S: { RETURN_INTEGER_64_SWAP(uint64_t); } break;
941
943
  case PrimitiveKind::String: {
942
944
  const char *str;
943
- if (RG_UNLIKELY(!PushString(value, &str)))
945
+ if (RG_UNLIKELY(!PushString(value, 1, &str)))
944
946
  return;
945
947
 
946
948
  out_reg->r0 = (uint32_t)str;
947
949
  } break;
948
950
  case PrimitiveKind::String16: {
949
951
  const char16_t *str16;
950
- if (RG_UNLIKELY(!PushString16(value, &str16)))
952
+ if (RG_UNLIKELY(!PushString16(value, 1, &str16)))
951
953
  return;
952
954
 
953
955
  out_reg->r0 = (uint32_t)str16;
@@ -998,7 +1000,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
998
1000
  return;
999
1001
  }
1000
1002
 
1001
- float f = CopyNumber<float>(value);
1003
+ float f = GetNumber<float>(value);
1002
1004
  #ifdef __ARM_PCS_VFP
1003
1005
  memcpy(&out_reg->d0, &f, 4);
1004
1006
  #else
@@ -1011,7 +1013,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
1011
1013
  return;
1012
1014
  }
1013
1015
 
1014
- double d = CopyNumber<double>(value);
1016
+ double d = GetNumber<double>(value);
1015
1017
  #ifdef __ARM_PCS_VFP
1016
1018
  out_reg->d0 = d;
1017
1019
  #else
@@ -307,7 +307,7 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
307
307
  return false; \
308
308
  } \
309
309
  \
310
- CType v = CopyNumber<CType>(value); \
310
+ CType v = GetNumber<CType>(value); \
311
311
  \
312
312
  if (RG_LIKELY(param.gpr_count)) { \
313
313
  *(gpr_ptr++) = (uint64_t)v; \
@@ -324,7 +324,7 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
324
324
  return false; \
325
325
  } \
326
326
  \
327
- CType v = CopyNumber<CType>(value); \
327
+ CType v = GetNumber<CType>(value); \
328
328
  \
329
329
  if (RG_LIKELY(param.gpr_count)) { \
330
330
  *(gpr_ptr++) = (uint64_t)ReverseBytes(v); \
@@ -342,7 +342,7 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
342
342
  return false; \
343
343
  } \
344
344
  \
345
- CType v = CopyNumber<CType>(value); \
345
+ CType v = GetNumber<CType>(value); \
346
346
  *((param.gpr_count ? gpr_ptr : args_ptr)++) = (uint64_t)v; \
347
347
  } while (false)
348
348
  #define PUSH_INTEGER_SWAP(CType) \
@@ -352,7 +352,7 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
352
352
  return false; \
353
353
  } \
354
354
  \
355
- CType v = CopyNumber<CType>(value); \
355
+ CType v = GetNumber<CType>(value); \
356
356
  *((param.gpr_count ? gpr_ptr : args_ptr)++) = (uint64_t)ReverseBytes(v); \
357
357
  } while (false)
358
358
  #endif
@@ -402,7 +402,7 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
402
402
  case PrimitiveKind::UInt64S: { PUSH_INTEGER_SWAP(uint64_t); } break;
403
403
  case PrimitiveKind::String: {
404
404
  const char *str;
405
- if (RG_UNLIKELY(!PushString(value, &str)))
405
+ if (RG_UNLIKELY(!PushString(value, param.directions, &str)))
406
406
  return false;
407
407
 
408
408
  #ifdef __APPLE__
@@ -412,7 +412,7 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
412
412
  } break;
413
413
  case PrimitiveKind::String16: {
414
414
  const char16_t *str16;
415
- if (RG_UNLIKELY(!PushString16(value, &str16)))
415
+ if (RG_UNLIKELY(!PushString16(value, param.directions, &str16)))
416
416
  return false;
417
417
 
418
418
  #ifdef __APPLE__
@@ -483,7 +483,7 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
483
483
  return false;
484
484
  }
485
485
 
486
- float f = CopyNumber<float>(value);
486
+ float f = GetNumber<float>(value);
487
487
 
488
488
  if (RG_LIKELY(param.vec_count)) {
489
489
  memset((uint8_t *)vec_ptr + 4, 0, 4);
@@ -510,7 +510,7 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
510
510
  return false;
511
511
  }
512
512
 
513
- double d = CopyNumber<double>(value);
513
+ double d = GetNumber<double>(value);
514
514
 
515
515
  if (RG_LIKELY(param.vec_count)) {
516
516
  *(double *)(vec_ptr++) = d;
@@ -657,13 +657,13 @@ Napi::Value CallData::Complete()
657
657
  } break;
658
658
  case PrimitiveKind::Record: {
659
659
  if (func->ret.vec_count) { // HFA
660
- Napi::Object obj = PopObject((const uint8_t *)&result.buf, func->ret.type, 8);
660
+ Napi::Object obj = DecodeObject(env, (const uint8_t *)&result.buf, func->ret.type, 8);
661
661
  return obj;
662
662
  } else {
663
663
  const uint8_t *ptr = return_ptr ? (const uint8_t *)return_ptr
664
664
  : (const uint8_t *)&result.buf;
665
665
 
666
- Napi::Object obj = PopObject(ptr, func->ret.type);
666
+ Napi::Object obj = DecodeObject(env, ptr, func->ret.type);
667
667
  return obj;
668
668
  }
669
669
  } break;
@@ -700,7 +700,9 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
700
700
  return;
701
701
  }
702
702
 
703
- LocalArray<napi_value, MaxParameters> arguments;
703
+ LocalArray<napi_value, MaxParameters + 1> arguments;
704
+
705
+ arguments.Append(!trampoline.recv.IsEmpty() ? trampoline.recv.Value() : env.Undefined());
704
706
 
705
707
  // Convert to JS arguments
706
708
  for (Size i = 0; i < proto->parameters.len; i++) {
@@ -1005,7 +1007,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
1005
1007
  } break;
1006
1008
  case PrimitiveKind::Record: {
1007
1009
  if (param.vec_count) { // HFA
1008
- Napi::Object obj = PopObject((uint8_t *)vec_ptr, param.type, 8);
1010
+ Napi::Object obj = DecodeObject(env, (uint8_t *)vec_ptr, param.type, 8);
1009
1011
  arguments.Append(obj);
1010
1012
 
1011
1013
  vec_ptr += param.vec_count;
@@ -1013,14 +1015,14 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
1013
1015
  if (param.gpr_count) {
1014
1016
  RG_ASSERT(param.type->align <= 8);
1015
1017
 
1016
- Napi::Object obj = PopObject((uint8_t *)gpr_ptr, param.type);
1018
+ Napi::Object obj = DecodeObject(env, (uint8_t *)gpr_ptr, param.type);
1017
1019
  arguments.Append(obj);
1018
1020
 
1019
1021
  gpr_ptr += param.gpr_count;
1020
1022
  } else if (param.type->size) {
1021
1023
  args_ptr = AlignUp(args_ptr, param.type->align);
1022
1024
 
1023
- Napi::Object obj = PopObject((uint8_t *)args_ptr, param.type);
1025
+ Napi::Object obj = DecodeObject(env, (uint8_t *)args_ptr, param.type);
1024
1026
  arguments.Append(obj);
1025
1027
 
1026
1028
  args_ptr += (param.type->size + 7) / 8;
@@ -1032,7 +1034,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
1032
1034
 
1033
1035
  void *ptr2 = *(void **)((param.gpr_count ? gpr_ptr : args_ptr)++);
1034
1036
 
1035
- Napi::Object obj = PopObject((uint8_t *)ptr2, param.type);
1037
+ Napi::Object obj = DecodeObject(env, (uint8_t *)ptr2, param.type);
1036
1038
  arguments.Append(obj);
1037
1039
  }
1038
1040
  } break;
@@ -1086,7 +1088,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
1086
1088
 
1087
1089
  // Make the call
1088
1090
  napi_value ret = CallSwitchStack(&func, (size_t)arguments.len, arguments.data, old_sp, &mem->stack,
1089
- [](Napi::Function *func, size_t argc, napi_value *argv) { return (napi_value)func->Call(argc, argv); });
1091
+ [](Napi::Function *func, size_t argc, napi_value *argv) { return (napi_value)func->Call(argv[0], argc - 1, argv + 1); });
1090
1092
  Napi::Value value(env, ret);
1091
1093
 
1092
1094
  if (RG_UNLIKELY(env.IsExceptionPending()))
@@ -1099,7 +1101,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
1099
1101
  return; \
1100
1102
  } \
1101
1103
  \
1102
- CType v = CopyNumber<CType>(value); \
1104
+ CType v = GetNumber<CType>(value); \
1103
1105
  out_reg->x0 = (uint64_t)v; \
1104
1106
  } while (false)
1105
1107
  #define RETURN_INTEGER_SWAP(CType) \
@@ -1109,7 +1111,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
1109
1111
  return; \
1110
1112
  } \
1111
1113
  \
1112
- CType v = CopyNumber<CType>(value); \
1114
+ CType v = GetNumber<CType>(value); \
1113
1115
  out_reg->x0 = (uint64_t)ReverseBytes(v); \
1114
1116
  } while (false)
1115
1117
 
@@ -1141,14 +1143,14 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
1141
1143
  case PrimitiveKind::UInt64S: { RETURN_INTEGER_SWAP(uint64_t); } break;
1142
1144
  case PrimitiveKind::String: {
1143
1145
  const char *str;
1144
- if (RG_UNLIKELY(!PushString(value, &str)))
1146
+ if (RG_UNLIKELY(!PushString(value, 1, &str)))
1145
1147
  return;
1146
1148
 
1147
1149
  out_reg->x0 = (uint64_t)str;
1148
1150
  } break;
1149
1151
  case PrimitiveKind::String16: {
1150
1152
  const char16_t *str16;
1151
- if (RG_UNLIKELY(!PushString16(value, &str16)))
1153
+ if (RG_UNLIKELY(!PushString16(value, 1, &str16)))
1152
1154
  return;
1153
1155
 
1154
1156
  out_reg->x0 = (uint64_t)str16;
@@ -1199,7 +1201,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
1199
1201
  return;
1200
1202
  }
1201
1203
 
1202
- float f = CopyNumber<float>(value);
1204
+ float f = GetNumber<float>(value);
1203
1205
 
1204
1206
  memset((uint8_t *)&out_reg->d0 + 4, 0, 4);
1205
1207
  memcpy(&out_reg->d0, &f, 4);
@@ -1210,7 +1212,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
1210
1212
  return;
1211
1213
  }
1212
1214
 
1213
- double d = CopyNumber<double>(value);
1215
+ double d = GetNumber<double>(value);
1214
1216
  out_reg->d0 = d;
1215
1217
  } break;
1216
1218
  case PrimitiveKind::Callback: {
@@ -223,7 +223,7 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
223
223
  return false; \
224
224
  } \
225
225
  \
226
- CType v = CopyNumber<CType>(value); \
226
+ CType v = GetNumber<CType>(value); \
227
227
  *((param.gpr_count ? gpr_ptr : args_ptr)++) = (uint64_t)v; \
228
228
  } while (false)
229
229
  #define PUSH_INTEGER_SWAP(CType) \
@@ -233,7 +233,7 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
233
233
  return false; \
234
234
  } \
235
235
  \
236
- CType v = CopyNumber<CType>(value); \
236
+ CType v = GetNumber<CType>(value); \
237
237
  *((param.gpr_count ? gpr_ptr : args_ptr)++) = (uint64_t)ReverseBytes(v); \
238
238
  } while (false)
239
239
 
@@ -272,14 +272,14 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
272
272
  case PrimitiveKind::UInt64S: { PUSH_INTEGER_SWAP(uint64_t); } break;
273
273
  case PrimitiveKind::String: {
274
274
  const char *str;
275
- if (RG_UNLIKELY(!PushString(value, &str)))
275
+ if (RG_UNLIKELY(!PushString(value, param.directions, &str)))
276
276
  return false;
277
277
 
278
278
  *(const char **)((param.gpr_count ? gpr_ptr : args_ptr)++) = str;
279
279
  } break;
280
280
  case PrimitiveKind::String16: {
281
281
  const char16_t *str16;
282
- if (RG_UNLIKELY(!PushString16(value, &str16)))
282
+ if (RG_UNLIKELY(!PushString16(value, param.directions, &str16)))
283
283
  return false;
284
284
 
285
285
  *(const char16_t **)((param.gpr_count ? gpr_ptr : args_ptr)++) = str16;
@@ -346,7 +346,7 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
346
346
  return false;
347
347
  }
348
348
 
349
- float f = CopyNumber<float>(value);
349
+ float f = GetNumber<float>(value);
350
350
 
351
351
  if (RG_LIKELY(param.vec_count)) {
352
352
  memset((uint8_t *)vec_ptr + 4, 0xFF, 4);
@@ -365,7 +365,7 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
365
365
  return false;
366
366
  }
367
367
 
368
- double d = CopyNumber<double>(value);
368
+ double d = GetNumber<double>(value);
369
369
 
370
370
  if (RG_LIKELY(param.vec_count)) {
371
371
  *(double *)(vec_ptr++) = d;
@@ -508,13 +508,13 @@ Napi::Value CallData::Complete()
508
508
  } break;
509
509
  case PrimitiveKind::Record: {
510
510
  if (func->ret.vec_count) { // HFA
511
- Napi::Object obj = PopObject((const uint8_t *)&result.buf, func->ret.type, 8);
511
+ Napi::Object obj = DecodeObject(env, (const uint8_t *)&result.buf, func->ret.type, 8);
512
512
  return obj;
513
513
  } else {
514
514
  const uint8_t *ptr = return_ptr ? (const uint8_t *)return_ptr
515
515
  : (const uint8_t *)&result.buf;
516
516
 
517
- Napi::Object obj = PopObject(ptr, func->ret.type);
517
+ Napi::Object obj = DecodeObject(env, ptr, func->ret.type);
518
518
  return obj;
519
519
  }
520
520
  } break;
@@ -552,7 +552,9 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
552
552
  return;
553
553
  }
554
554
 
555
- LocalArray<napi_value, MaxParameters> arguments;
555
+ LocalArray<napi_value, MaxParameters + 1> arguments;
556
+
557
+ arguments.Append(!trampoline.recv.IsEmpty() ? trampoline.recv.Value() : env.Undefined());
556
558
 
557
559
  // Convert to JS arguments
558
560
  for (Size i = 0; i < proto->parameters.len; i++) {
@@ -715,12 +717,12 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
715
717
  // Reassemble float or mixed int-float structs from registers
716
718
  int realign = param.vec_count ? 8 : 0;
717
719
 
718
- Napi::Object obj = PopObject((const uint8_t *)buf, param.type, realign);
720
+ Napi::Object obj = DecodeObject(env, (const uint8_t *)buf, param.type, realign);
719
721
  arguments.Append(obj);
720
722
  } else {
721
723
  uint8_t *ptr = *(uint8_t **)((param.gpr_count ? gpr_ptr : args_ptr)++);
722
724
 
723
- Napi::Object obj = PopObject(ptr, param.type);
725
+ Napi::Object obj = DecodeObject(env, ptr, param.type);
724
726
  arguments.Append(obj);
725
727
  }
726
728
  } break;
@@ -760,7 +762,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
760
762
 
761
763
  // Make the call
762
764
  napi_value ret = CallSwitchStack(&func, (size_t)arguments.len, arguments.data, old_sp, &mem->stack,
763
- [](Napi::Function *func, size_t argc, napi_value *argv) { return (napi_value)func->Call(argc, argv); });
765
+ [](Napi::Function *func, size_t argc, napi_value *argv) { return (napi_value)func->Call(argv[0], argc - 1, argv + 1); });
764
766
  Napi::Value value(env, ret);
765
767
 
766
768
  if (RG_UNLIKELY(env.IsExceptionPending()))
@@ -773,7 +775,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
773
775
  return; \
774
776
  } \
775
777
  \
776
- CType v = CopyNumber<CType>(value); \
778
+ CType v = GetNumber<CType>(value); \
777
779
  out_reg->a0 = (uint64_t)v; \
778
780
  } while (false)
779
781
  #define RETURN_INTEGER_SWAP(CType) \
@@ -783,7 +785,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
783
785
  return; \
784
786
  } \
785
787
  \
786
- CType v = CopyNumber<CType>(value); \
788
+ CType v = GetNumber<CType>(value); \
787
789
  out_reg->a0 = (uint64_t)ReverseBytes(v); \
788
790
  } while (false)
789
791
 
@@ -815,14 +817,14 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
815
817
  case PrimitiveKind::UInt64S: { RETURN_INTEGER_SWAP(uint64_t); } break;
816
818
  case PrimitiveKind::String: {
817
819
  const char *str;
818
- if (RG_UNLIKELY(!PushString(value, &str)))
820
+ if (RG_UNLIKELY(!PushString(value, 1, &str)))
819
821
  return;
820
822
 
821
823
  out_reg->a0 = (uint64_t)str;
822
824
  } break;
823
825
  case PrimitiveKind::String16: {
824
826
  const char16_t *str16;
825
- if (RG_UNLIKELY(!PushString16(value, &str16)))
827
+ if (RG_UNLIKELY(!PushString16(value, 1, &str16)))
826
828
  return;
827
829
 
828
830
  out_reg->a0 = (uint64_t)str16;
@@ -873,7 +875,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
873
875
  return;
874
876
  }
875
877
 
876
- float f = CopyNumber<float>(value);
878
+ float f = GetNumber<float>(value);
877
879
  memset((uint8_t *)&out_reg->fa0 + 4, 0xFF, 4);
878
880
  memcpy(&out_reg->fa0, &f, 4);
879
881
  } break;
@@ -883,7 +885,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
883
885
  return;
884
886
  }
885
887
 
886
- double d = CopyNumber<double>(value);
888
+ double d = GetNumber<double>(value);
887
889
  out_reg->fa0 = d;
888
890
  } break;
889
891
  case PrimitiveKind::Callback: {