koffi 2.1.5 → 2.2.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 (65) hide show
  1. package/ChangeLog.md +21 -1
  2. package/doc/Makefile +1 -1
  3. package/doc/callbacks.md +175 -0
  4. package/doc/changes.md +2 -3
  5. package/doc/conf.py +29 -6
  6. package/doc/functions.md +39 -124
  7. package/doc/index.rst +1 -0
  8. package/doc/make.bat +1 -1
  9. package/doc/types.md +36 -9
  10. package/package.json +2 -2
  11. package/src/core/libcc/libcc.cc +89 -27
  12. package/src/core/libcc/libcc.hh +74 -39
  13. package/src/koffi/build/2.2.1/koffi_darwin_arm64.tar.gz +0 -0
  14. package/src/koffi/build/2.2.1/koffi_darwin_x64.tar.gz +0 -0
  15. package/src/koffi/build/2.2.1/koffi_freebsd_arm64.tar.gz +0 -0
  16. package/src/koffi/build/2.2.1/koffi_freebsd_ia32.tar.gz +0 -0
  17. package/src/koffi/build/2.2.1/koffi_freebsd_x64.tar.gz +0 -0
  18. package/src/koffi/build/2.2.1/koffi_linux_arm32hf.tar.gz +0 -0
  19. package/src/koffi/build/2.2.1/koffi_linux_arm64.tar.gz +0 -0
  20. package/src/koffi/build/2.2.1/koffi_linux_ia32.tar.gz +0 -0
  21. package/src/koffi/build/2.2.1/koffi_linux_riscv64hf64.tar.gz +0 -0
  22. package/src/koffi/build/2.2.1/koffi_linux_x64.tar.gz +0 -0
  23. package/src/koffi/build/2.2.1/koffi_openbsd_ia32.tar.gz +0 -0
  24. package/src/koffi/build/2.2.1/koffi_openbsd_x64.tar.gz +0 -0
  25. package/src/koffi/build/2.2.1/koffi_win32_arm64.tar.gz +0 -0
  26. package/src/koffi/build/2.2.1/koffi_win32_ia32.tar.gz +0 -0
  27. package/src/koffi/build/2.2.1/koffi_win32_x64.tar.gz +0 -0
  28. package/src/koffi/qemu/qemu.js +3 -1
  29. package/src/koffi/src/abi_arm32.cc +26 -23
  30. package/src/koffi/src/abi_arm64.cc +25 -22
  31. package/src/koffi/src/abi_riscv64.cc +21 -18
  32. package/src/koffi/src/abi_x64_sysv.cc +20 -17
  33. package/src/koffi/src/abi_x64_win.cc +19 -16
  34. package/src/koffi/src/abi_x86.cc +23 -20
  35. package/src/koffi/src/call.cc +222 -607
  36. package/src/koffi/src/call.hh +7 -11
  37. package/src/koffi/src/ffi.cc +229 -29
  38. package/src/koffi/src/ffi.hh +6 -2
  39. package/src/koffi/src/parser.cc +3 -9
  40. package/src/koffi/src/util.cc +546 -8
  41. package/src/koffi/src/util.hh +8 -2
  42. package/src/koffi/test/CMakeLists.txt +3 -3
  43. package/src/koffi/test/callbacks.js +89 -0
  44. package/src/koffi/test/misc.c +78 -0
  45. package/src/koffi/test/raylib.js +2 -2
  46. package/src/koffi/test/sqlite.js +1 -1
  47. package/src/koffi/test/sync.js +28 -6
  48. package/vendor/brotli/c/common/platform.h +2 -0
  49. package/vendor/sqlite3mc/sqlite3.c +243532 -0
  50. package/vendor/sqlite3mc/sqlite3.h +12887 -0
  51. package/src/koffi/build/2.1.5/koffi_darwin_arm64.tar.gz +0 -0
  52. package/src/koffi/build/2.1.5/koffi_darwin_x64.tar.gz +0 -0
  53. package/src/koffi/build/2.1.5/koffi_freebsd_arm64.tar.gz +0 -0
  54. package/src/koffi/build/2.1.5/koffi_freebsd_ia32.tar.gz +0 -0
  55. package/src/koffi/build/2.1.5/koffi_freebsd_x64.tar.gz +0 -0
  56. package/src/koffi/build/2.1.5/koffi_linux_arm32hf.tar.gz +0 -0
  57. package/src/koffi/build/2.1.5/koffi_linux_arm64.tar.gz +0 -0
  58. package/src/koffi/build/2.1.5/koffi_linux_ia32.tar.gz +0 -0
  59. package/src/koffi/build/2.1.5/koffi_linux_riscv64hf64.tar.gz +0 -0
  60. package/src/koffi/build/2.1.5/koffi_linux_x64.tar.gz +0 -0
  61. package/src/koffi/build/2.1.5/koffi_openbsd_ia32.tar.gz +0 -0
  62. package/src/koffi/build/2.1.5/koffi_openbsd_x64.tar.gz +0 -0
  63. package/src/koffi/build/2.1.5/koffi_win32_arm64.tar.gz +0 -0
  64. package/src/koffi/build/2.1.5/koffi_win32_ia32.tar.gz +0 -0
  65. package/src/koffi/build/2.1.5/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;
@@ -495,6 +495,7 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
495
495
 
496
496
  void CallData::Execute()
497
497
  {
498
+ RG_DEFER_C(prev_call = exec_call) { exec_call = prev_call; };
498
499
  exec_call = this;
499
500
 
500
501
  #define PERFORM_CALL(Suffix) \
@@ -588,7 +589,7 @@ Napi::Value CallData::Complete()
588
589
  const uint8_t *ptr = return_ptr ? (const uint8_t *)return_ptr
589
590
  : (const uint8_t *)&result.buf;
590
591
 
591
- Napi::Object obj = PopObject(ptr, func->ret.type);
592
+ Napi::Object obj = DecodeObject(env, ptr, func->ret.type);
592
593
  return obj;
593
594
  } break;
594
595
  case PrimitiveKind::Array: { RG_UNREACHABLE(); } break;
@@ -625,7 +626,9 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
625
626
  return;
626
627
  }
627
628
 
628
- LocalArray<napi_value, MaxParameters> arguments;
629
+ LocalArray<napi_value, MaxParameters + 1> arguments;
630
+
631
+ arguments.Append(!trampoline.recv.IsEmpty() ? trampoline.recv.Value() : env.Undefined());
629
632
 
630
633
  // Convert to JS arguments
631
634
  for (Size i = 0; i < proto->parameters.len; i++) {
@@ -780,7 +783,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
780
783
  } break;
781
784
  case PrimitiveKind::Record: {
782
785
  if (param.vec_count) {
783
- Napi::Object obj = PopObject((const uint8_t *)vec_ptr, param.type);
786
+ Napi::Object obj = DecodeObject(env, (const uint8_t *)vec_ptr, param.type);
784
787
  arguments.Append(obj);
785
788
 
786
789
  vec_ptr += param.vec_count;
@@ -799,13 +802,13 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
799
802
  memcpy(ptr, gpr_ptr, gpr_size);
800
803
  memcpy(ptr + gpr_size, args_ptr, param.type->size - gpr_size);
801
804
 
802
- Napi::Object obj = PopObject(ptr, param.type);
805
+ Napi::Object obj = DecodeObject(env, ptr, param.type);
803
806
  arguments.Append(obj);
804
807
 
805
808
  gpr_ptr += param.gpr_count;
806
809
  args_ptr += (param.type->size - gpr_size + 3) / 4;
807
810
  } else {
808
- Napi::Object obj = PopObject((const uint8_t *)gpr_ptr, param.type);
811
+ Napi::Object obj = DecodeObject(env, (const uint8_t *)gpr_ptr, param.type);
809
812
  arguments.Append(obj);
810
813
 
811
814
  gpr_ptr += param.gpr_count;
@@ -814,7 +817,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
814
817
  int16_t align = (param.type->align <= 4) ? 4 : 8;
815
818
  args_ptr = AlignUp(args_ptr, align);
816
819
 
817
- Napi::Object obj = PopObject((const uint8_t *)args_ptr, param.type);
820
+ Napi::Object obj = DecodeObject(env, (const uint8_t *)args_ptr, param.type);
818
821
  arguments.Append(obj);
819
822
 
820
823
  args_ptr += (param.type->size + 3) / 4;
@@ -861,7 +864,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
861
864
 
862
865
  // Make the call
863
866
  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); });
867
+ [](Napi::Function *func, size_t argc, napi_value *argv) { return (napi_value)func->Call(argv[0], argc - 1, argv + 1); });
865
868
  Napi::Value value(env, ret);
866
869
 
867
870
  if (RG_UNLIKELY(env.IsExceptionPending()))
@@ -874,7 +877,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
874
877
  return; \
875
878
  } \
876
879
  \
877
- CType v = CopyNumber<CType>(value); \
880
+ CType v = GetNumber<CType>(value); \
878
881
  out_reg->r0 = (uint32_t)v; \
879
882
  } while (false)
880
883
  #define RETURN_INTEGER_32_SWAP(CType) \
@@ -884,7 +887,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
884
887
  return; \
885
888
  } \
886
889
  \
887
- CType v = CopyNumber<CType>(value); \
890
+ CType v = GetNumber<CType>(value); \
888
891
  out_reg->r0 = (uint32_t)ReverseBytes(v); \
889
892
  } while (false)
890
893
  #define RETURN_INTEGER_64(CType) \
@@ -894,7 +897,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
894
897
  return; \
895
898
  } \
896
899
  \
897
- CType v = CopyNumber<CType>(value); \
900
+ CType v = GetNumber<CType>(value); \
898
901
  \
899
902
  out_reg->r0 = (uint32_t)((uint64_t)v >> 32); \
900
903
  out_reg->r1 = (uint32_t)((uint64_t)v & 0xFFFFFFFFu); \
@@ -906,7 +909,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
906
909
  return; \
907
910
  } \
908
911
  \
909
- CType v = ReverseBytes(CopyNumber<CType>(value)); \
912
+ CType v = ReverseBytes(GetNumber<CType>(value)); \
910
913
  \
911
914
  out_reg->r0 = (uint32_t)((uint64_t)v >> 32); \
912
915
  out_reg->r1 = (uint32_t)((uint64_t)v & 0xFFFFFFFFu); \
@@ -940,14 +943,14 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
940
943
  case PrimitiveKind::UInt64S: { RETURN_INTEGER_64_SWAP(uint64_t); } break;
941
944
  case PrimitiveKind::String: {
942
945
  const char *str;
943
- if (RG_UNLIKELY(!PushString(value, &str)))
946
+ if (RG_UNLIKELY(!PushString(value, 1, &str)))
944
947
  return;
945
948
 
946
949
  out_reg->r0 = (uint32_t)str;
947
950
  } break;
948
951
  case PrimitiveKind::String16: {
949
952
  const char16_t *str16;
950
- if (RG_UNLIKELY(!PushString16(value, &str16)))
953
+ if (RG_UNLIKELY(!PushString16(value, 1, &str16)))
951
954
  return;
952
955
 
953
956
  out_reg->r0 = (uint32_t)str16;
@@ -998,7 +1001,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
998
1001
  return;
999
1002
  }
1000
1003
 
1001
- float f = CopyNumber<float>(value);
1004
+ float f = GetNumber<float>(value);
1002
1005
  #ifdef __ARM_PCS_VFP
1003
1006
  memcpy(&out_reg->d0, &f, 4);
1004
1007
  #else
@@ -1011,7 +1014,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
1011
1014
  return;
1012
1015
  }
1013
1016
 
1014
- double d = CopyNumber<double>(value);
1017
+ double d = GetNumber<double>(value);
1015
1018
  #ifdef __ARM_PCS_VFP
1016
1019
  out_reg->d0 = d;
1017
1020
  #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;
@@ -563,6 +563,7 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
563
563
 
564
564
  void CallData::Execute()
565
565
  {
566
+ RG_DEFER_C(prev_call = exec_call) { exec_call = prev_call; };
566
567
  exec_call = this;
567
568
 
568
569
  #define PERFORM_CALL(Suffix) \
@@ -657,13 +658,13 @@ Napi::Value CallData::Complete()
657
658
  } break;
658
659
  case PrimitiveKind::Record: {
659
660
  if (func->ret.vec_count) { // HFA
660
- Napi::Object obj = PopObject((const uint8_t *)&result.buf, func->ret.type, 8);
661
+ Napi::Object obj = DecodeObject(env, (const uint8_t *)&result.buf, func->ret.type, 8);
661
662
  return obj;
662
663
  } else {
663
664
  const uint8_t *ptr = return_ptr ? (const uint8_t *)return_ptr
664
665
  : (const uint8_t *)&result.buf;
665
666
 
666
- Napi::Object obj = PopObject(ptr, func->ret.type);
667
+ Napi::Object obj = DecodeObject(env, ptr, func->ret.type);
667
668
  return obj;
668
669
  }
669
670
  } break;
@@ -700,7 +701,9 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
700
701
  return;
701
702
  }
702
703
 
703
- LocalArray<napi_value, MaxParameters> arguments;
704
+ LocalArray<napi_value, MaxParameters + 1> arguments;
705
+
706
+ arguments.Append(!trampoline.recv.IsEmpty() ? trampoline.recv.Value() : env.Undefined());
704
707
 
705
708
  // Convert to JS arguments
706
709
  for (Size i = 0; i < proto->parameters.len; i++) {
@@ -1005,7 +1008,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
1005
1008
  } break;
1006
1009
  case PrimitiveKind::Record: {
1007
1010
  if (param.vec_count) { // HFA
1008
- Napi::Object obj = PopObject((uint8_t *)vec_ptr, param.type, 8);
1011
+ Napi::Object obj = DecodeObject(env, (uint8_t *)vec_ptr, param.type, 8);
1009
1012
  arguments.Append(obj);
1010
1013
 
1011
1014
  vec_ptr += param.vec_count;
@@ -1013,14 +1016,14 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
1013
1016
  if (param.gpr_count) {
1014
1017
  RG_ASSERT(param.type->align <= 8);
1015
1018
 
1016
- Napi::Object obj = PopObject((uint8_t *)gpr_ptr, param.type);
1019
+ Napi::Object obj = DecodeObject(env, (uint8_t *)gpr_ptr, param.type);
1017
1020
  arguments.Append(obj);
1018
1021
 
1019
1022
  gpr_ptr += param.gpr_count;
1020
1023
  } else if (param.type->size) {
1021
1024
  args_ptr = AlignUp(args_ptr, param.type->align);
1022
1025
 
1023
- Napi::Object obj = PopObject((uint8_t *)args_ptr, param.type);
1026
+ Napi::Object obj = DecodeObject(env, (uint8_t *)args_ptr, param.type);
1024
1027
  arguments.Append(obj);
1025
1028
 
1026
1029
  args_ptr += (param.type->size + 7) / 8;
@@ -1032,7 +1035,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
1032
1035
 
1033
1036
  void *ptr2 = *(void **)((param.gpr_count ? gpr_ptr : args_ptr)++);
1034
1037
 
1035
- Napi::Object obj = PopObject((uint8_t *)ptr2, param.type);
1038
+ Napi::Object obj = DecodeObject(env, (uint8_t *)ptr2, param.type);
1036
1039
  arguments.Append(obj);
1037
1040
  }
1038
1041
  } break;
@@ -1086,7 +1089,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
1086
1089
 
1087
1090
  // Make the call
1088
1091
  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); });
1092
+ [](Napi::Function *func, size_t argc, napi_value *argv) { return (napi_value)func->Call(argv[0], argc - 1, argv + 1); });
1090
1093
  Napi::Value value(env, ret);
1091
1094
 
1092
1095
  if (RG_UNLIKELY(env.IsExceptionPending()))
@@ -1099,7 +1102,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
1099
1102
  return; \
1100
1103
  } \
1101
1104
  \
1102
- CType v = CopyNumber<CType>(value); \
1105
+ CType v = GetNumber<CType>(value); \
1103
1106
  out_reg->x0 = (uint64_t)v; \
1104
1107
  } while (false)
1105
1108
  #define RETURN_INTEGER_SWAP(CType) \
@@ -1109,7 +1112,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
1109
1112
  return; \
1110
1113
  } \
1111
1114
  \
1112
- CType v = CopyNumber<CType>(value); \
1115
+ CType v = GetNumber<CType>(value); \
1113
1116
  out_reg->x0 = (uint64_t)ReverseBytes(v); \
1114
1117
  } while (false)
1115
1118
 
@@ -1141,14 +1144,14 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
1141
1144
  case PrimitiveKind::UInt64S: { RETURN_INTEGER_SWAP(uint64_t); } break;
1142
1145
  case PrimitiveKind::String: {
1143
1146
  const char *str;
1144
- if (RG_UNLIKELY(!PushString(value, &str)))
1147
+ if (RG_UNLIKELY(!PushString(value, 1, &str)))
1145
1148
  return;
1146
1149
 
1147
1150
  out_reg->x0 = (uint64_t)str;
1148
1151
  } break;
1149
1152
  case PrimitiveKind::String16: {
1150
1153
  const char16_t *str16;
1151
- if (RG_UNLIKELY(!PushString16(value, &str16)))
1154
+ if (RG_UNLIKELY(!PushString16(value, 1, &str16)))
1152
1155
  return;
1153
1156
 
1154
1157
  out_reg->x0 = (uint64_t)str16;
@@ -1199,7 +1202,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
1199
1202
  return;
1200
1203
  }
1201
1204
 
1202
- float f = CopyNumber<float>(value);
1205
+ float f = GetNumber<float>(value);
1203
1206
 
1204
1207
  memset((uint8_t *)&out_reg->d0 + 4, 0, 4);
1205
1208
  memcpy(&out_reg->d0, &f, 4);
@@ -1210,7 +1213,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
1210
1213
  return;
1211
1214
  }
1212
1215
 
1213
- double d = CopyNumber<double>(value);
1216
+ double d = GetNumber<double>(value);
1214
1217
  out_reg->d0 = d;
1215
1218
  } break;
1216
1219
  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;
@@ -410,6 +410,7 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
410
410
 
411
411
  void CallData::Execute()
412
412
  {
413
+ RG_DEFER_C(prev_call = exec_call) { exec_call = prev_call; };
413
414
  exec_call = this;
414
415
 
415
416
  #define PERFORM_CALL(Suffix) \
@@ -508,13 +509,13 @@ Napi::Value CallData::Complete()
508
509
  } break;
509
510
  case PrimitiveKind::Record: {
510
511
  if (func->ret.vec_count) { // HFA
511
- Napi::Object obj = PopObject((const uint8_t *)&result.buf, func->ret.type, 8);
512
+ Napi::Object obj = DecodeObject(env, (const uint8_t *)&result.buf, func->ret.type, 8);
512
513
  return obj;
513
514
  } else {
514
515
  const uint8_t *ptr = return_ptr ? (const uint8_t *)return_ptr
515
516
  : (const uint8_t *)&result.buf;
516
517
 
517
- Napi::Object obj = PopObject(ptr, func->ret.type);
518
+ Napi::Object obj = DecodeObject(env, ptr, func->ret.type);
518
519
  return obj;
519
520
  }
520
521
  } break;
@@ -552,7 +553,9 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
552
553
  return;
553
554
  }
554
555
 
555
- LocalArray<napi_value, MaxParameters> arguments;
556
+ LocalArray<napi_value, MaxParameters + 1> arguments;
557
+
558
+ arguments.Append(!trampoline.recv.IsEmpty() ? trampoline.recv.Value() : env.Undefined());
556
559
 
557
560
  // Convert to JS arguments
558
561
  for (Size i = 0; i < proto->parameters.len; i++) {
@@ -715,12 +718,12 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
715
718
  // Reassemble float or mixed int-float structs from registers
716
719
  int realign = param.vec_count ? 8 : 0;
717
720
 
718
- Napi::Object obj = PopObject((const uint8_t *)buf, param.type, realign);
721
+ Napi::Object obj = DecodeObject(env, (const uint8_t *)buf, param.type, realign);
719
722
  arguments.Append(obj);
720
723
  } else {
721
724
  uint8_t *ptr = *(uint8_t **)((param.gpr_count ? gpr_ptr : args_ptr)++);
722
725
 
723
- Napi::Object obj = PopObject(ptr, param.type);
726
+ Napi::Object obj = DecodeObject(env, ptr, param.type);
724
727
  arguments.Append(obj);
725
728
  }
726
729
  } break;
@@ -760,7 +763,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
760
763
 
761
764
  // Make the call
762
765
  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); });
766
+ [](Napi::Function *func, size_t argc, napi_value *argv) { return (napi_value)func->Call(argv[0], argc - 1, argv + 1); });
764
767
  Napi::Value value(env, ret);
765
768
 
766
769
  if (RG_UNLIKELY(env.IsExceptionPending()))
@@ -773,7 +776,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
773
776
  return; \
774
777
  } \
775
778
  \
776
- CType v = CopyNumber<CType>(value); \
779
+ CType v = GetNumber<CType>(value); \
777
780
  out_reg->a0 = (uint64_t)v; \
778
781
  } while (false)
779
782
  #define RETURN_INTEGER_SWAP(CType) \
@@ -783,7 +786,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
783
786
  return; \
784
787
  } \
785
788
  \
786
- CType v = CopyNumber<CType>(value); \
789
+ CType v = GetNumber<CType>(value); \
787
790
  out_reg->a0 = (uint64_t)ReverseBytes(v); \
788
791
  } while (false)
789
792
 
@@ -815,14 +818,14 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
815
818
  case PrimitiveKind::UInt64S: { RETURN_INTEGER_SWAP(uint64_t); } break;
816
819
  case PrimitiveKind::String: {
817
820
  const char *str;
818
- if (RG_UNLIKELY(!PushString(value, &str)))
821
+ if (RG_UNLIKELY(!PushString(value, 1, &str)))
819
822
  return;
820
823
 
821
824
  out_reg->a0 = (uint64_t)str;
822
825
  } break;
823
826
  case PrimitiveKind::String16: {
824
827
  const char16_t *str16;
825
- if (RG_UNLIKELY(!PushString16(value, &str16)))
828
+ if (RG_UNLIKELY(!PushString16(value, 1, &str16)))
826
829
  return;
827
830
 
828
831
  out_reg->a0 = (uint64_t)str16;
@@ -873,7 +876,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
873
876
  return;
874
877
  }
875
878
 
876
- float f = CopyNumber<float>(value);
879
+ float f = GetNumber<float>(value);
877
880
  memset((uint8_t *)&out_reg->fa0 + 4, 0xFF, 4);
878
881
  memcpy(&out_reg->fa0, &f, 4);
879
882
  } break;
@@ -883,7 +886,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
883
886
  return;
884
887
  }
885
888
 
886
- double d = CopyNumber<double>(value);
889
+ double d = GetNumber<double>(value);
887
890
  out_reg->fa0 = d;
888
891
  } break;
889
892
  case PrimitiveKind::Callback: {