koffi 1.3.10 → 2.0.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/CMakeLists.txt +7 -2
  2. package/ChangeLog.md +52 -14
  3. package/README.md +6 -0
  4. package/build/qemu/2.0.0/koffi_darwin_arm64.tar.gz +0 -0
  5. package/build/qemu/2.0.0/koffi_darwin_x64.tar.gz +0 -0
  6. package/build/qemu/2.0.0/koffi_freebsd_arm64.tar.gz +0 -0
  7. package/build/qemu/2.0.0/koffi_freebsd_ia32.tar.gz +0 -0
  8. package/build/qemu/2.0.0/koffi_freebsd_x64.tar.gz +0 -0
  9. package/build/qemu/2.0.0/koffi_linux_arm32hf.tar.gz +0 -0
  10. package/build/qemu/2.0.0/koffi_linux_arm64.tar.gz +0 -0
  11. package/build/qemu/2.0.0/koffi_linux_ia32.tar.gz +0 -0
  12. package/build/qemu/2.0.0/koffi_linux_riscv64hf64.tar.gz +0 -0
  13. package/build/qemu/2.0.0/koffi_linux_x64.tar.gz +0 -0
  14. package/build/qemu/2.0.0/koffi_openbsd_ia32.tar.gz +0 -0
  15. package/build/qemu/2.0.0/koffi_openbsd_x64.tar.gz +0 -0
  16. package/build/qemu/2.0.0/koffi_win32_arm64.tar.gz +0 -0
  17. package/build/qemu/2.0.0/koffi_win32_ia32.tar.gz +0 -0
  18. package/build/qemu/2.0.0/koffi_win32_x64.tar.gz +0 -0
  19. package/doc/benchmarks.md +2 -2
  20. package/doc/changes.md +156 -1
  21. package/doc/contribute.md +0 -1
  22. package/doc/dist/doctrees/changes.doctree +0 -0
  23. package/doc/dist/doctrees/environment.pickle +0 -0
  24. package/doc/dist/doctrees/functions.doctree +0 -0
  25. package/doc/dist/doctrees/types.doctree +0 -0
  26. package/doc/dist/html/_sources/changes.md.txt +156 -1
  27. package/doc/dist/html/_sources/functions.md.txt +8 -4
  28. package/doc/dist/html/_sources/types.md.txt +9 -0
  29. package/doc/dist/html/benchmarks.html +1 -1
  30. package/doc/dist/html/changes.html +226 -14
  31. package/doc/dist/html/contribute.html +1 -1
  32. package/doc/dist/html/functions.html +15 -12
  33. package/doc/dist/html/genindex.html +1 -1
  34. package/doc/dist/html/index.html +6 -16
  35. package/doc/dist/html/memory.html +3 -3
  36. package/doc/dist/html/objects.inv +0 -0
  37. package/doc/dist/html/platforms.html +1 -1
  38. package/doc/dist/html/search.html +1 -1
  39. package/doc/dist/html/searchindex.js +1 -1
  40. package/doc/dist/html/start.html +1 -1
  41. package/doc/dist/html/types.html +11 -3
  42. package/doc/functions.md +137 -13
  43. package/doc/types.md +35 -10
  44. package/package.json +9 -7
  45. package/qemu/registry/machines.json +5 -5
  46. package/qemu/registry/sha256sum.txt +16 -16
  47. package/src/abi_arm32.cc +90 -18
  48. package/src/abi_arm32_fwd.S +121 -57
  49. package/src/abi_arm64.cc +90 -18
  50. package/src/abi_arm64_fwd.S +96 -0
  51. package/src/abi_arm64_fwd.asm +128 -0
  52. package/src/abi_riscv64.cc +88 -18
  53. package/src/abi_riscv64_fwd.S +96 -0
  54. package/src/abi_x64_sysv.cc +93 -21
  55. package/src/abi_x64_sysv_fwd.S +96 -0
  56. package/src/abi_x64_win.cc +88 -18
  57. package/src/abi_x64_win_fwd.asm +128 -0
  58. package/src/abi_x86.cc +93 -18
  59. package/src/abi_x86_fwd.S +96 -0
  60. package/src/abi_x86_fwd.asm +128 -0
  61. package/src/call.cc +97 -63
  62. package/src/call.hh +2 -1
  63. package/src/ffi.cc +452 -140
  64. package/src/ffi.hh +23 -9
  65. package/src/parser.cc +20 -42
  66. package/src/util.cc +117 -27
  67. package/src/util.hh +3 -2
  68. package/test/callbacks.js +54 -8
  69. package/test/misc.c +30 -15
  70. package/test/raylib.js +1 -1
  71. package/test/sqlite.js +24 -16
  72. package/test/sync.js +43 -33
  73. package/vendor/libcc/libcc.cc +18 -5
  74. package/vendor/libcc/libcc.hh +70 -23
  75. package/build/qemu/1.3.10/koffi_darwin_arm64.tar.gz +0 -0
  76. package/build/qemu/1.3.10/koffi_darwin_x64.tar.gz +0 -0
  77. package/build/qemu/1.3.10/koffi_freebsd_arm64.tar.gz +0 -0
  78. package/build/qemu/1.3.10/koffi_freebsd_ia32.tar.gz +0 -0
  79. package/build/qemu/1.3.10/koffi_freebsd_x64.tar.gz +0 -0
  80. package/build/qemu/1.3.10/koffi_linux_arm32hf.tar.gz +0 -0
  81. package/build/qemu/1.3.10/koffi_linux_arm64.tar.gz +0 -0
  82. package/build/qemu/1.3.10/koffi_linux_ia32.tar.gz +0 -0
  83. package/build/qemu/1.3.10/koffi_linux_riscv64hf64.tar.gz +0 -0
  84. package/build/qemu/1.3.10/koffi_linux_x64.tar.gz +0 -0
  85. package/build/qemu/1.3.10/koffi_openbsd_ia32.tar.gz +0 -0
  86. package/build/qemu/1.3.10/koffi_openbsd_x64.tar.gz +0 -0
  87. package/build/qemu/1.3.10/koffi_win32_arm64.tar.gz +0 -0
  88. package/build/qemu/1.3.10/koffi_win32_ia32.tar.gz +0 -0
  89. package/build/qemu/1.3.10/koffi_win32_x64.tar.gz +0 -0
package/src/call.cc CHANGED
@@ -40,7 +40,7 @@ CallData::~CallData()
40
40
  mem->stack = old_stack_mem;
41
41
  mem->heap = old_heap_mem;
42
42
 
43
- instance->free_trampolines |= used_trampolines;
43
+ instance->temp_trampolines -= used_trampolines;
44
44
  instance->temporaries -= mem->temporary;
45
45
 
46
46
  if (!--mem->depth && mem->temporary) {
@@ -127,9 +127,8 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
127
127
  RG_ASSERT(IsObject(obj));
128
128
  RG_ASSERT(type->primitive == PrimitiveKind::Record);
129
129
 
130
- Size offset = 0;
131
-
132
- for (const RecordMember &member: type->members) {
130
+ for (Size i = 0; i < type->members.len; i++) {
131
+ const RecordMember &member = type->members[i];
133
132
  Napi::Value value = obj.Get(member.name);
134
133
 
135
134
  if (RG_UNLIKELY(value.IsUndefined())) {
@@ -137,9 +136,7 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
137
136
  return false;
138
137
  }
139
138
 
140
- int16_t align = std::max(member.align, realign);
141
- offset = AlignLen(offset, align);
142
-
139
+ Size offset = realign ? (i * realign) : member.offset;
143
140
  uint8_t *dest = origin + offset;
144
141
 
145
142
  switch (member.type->primitive) {
@@ -257,7 +254,7 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
257
254
  *(const char16_t **)dest = str16;
258
255
  } break;
259
256
  case PrimitiveKind::Pointer: {
260
- if (CheckValueTag(instance, value, member.type)) {
257
+ if (CheckValueTag(instance, value, member.type->ref.marker)) {
261
258
  Napi::External<void> external = value.As<Napi::External<void>>();
262
259
  void *ptr = external.Data();
263
260
  *(void **)dest = ptr;
@@ -281,15 +278,15 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
281
278
  case PrimitiveKind::Array: {
282
279
  if (value.IsArray()) {
283
280
  Napi::Array array = value.As<Napi::Array>();
284
- Size len = (Size)member.type->size / member.type->ref->size;
281
+ Size len = (Size)member.type->size / member.type->ref.type->size;
285
282
 
286
- if (!PushNormalArray(array, len, member.type->ref, dest, realign))
283
+ if (!PushNormalArray(array, len, member.type->ref.type, dest, realign))
287
284
  return false;
288
285
  } else if (value.IsTypedArray()) {
289
286
  Napi::TypedArray array = value.As<Napi::TypedArray>();
290
- Size len = (Size)member.type->size / member.type->ref->size;
287
+ Size len = (Size)member.type->size / member.type->ref.type->size;
291
288
 
292
- if (!PushTypedArray(array, len, member.type->ref, dest, realign))
289
+ if (!PushTypedArray(array, len, member.type->ref.type, dest, realign))
293
290
  return false;
294
291
  } else if (value.IsString() && !realign) {
295
292
  if (!PushStringArray(value, member.type, dest))
@@ -323,10 +320,10 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
323
320
  if (value.IsFunction()) {
324
321
  Napi::Function func = value.As<Napi::Function>();
325
322
 
326
- ptr = ReserveTrampoline(member.type->proto, func);
323
+ ptr = ReserveTrampoline(member.type->ref.proto, func);
327
324
  if (RG_UNLIKELY(!ptr))
328
325
  return false;
329
- } else if (CheckValueTag(instance, value, member.type)) {
326
+ } else if (CheckValueTag(instance, value, member.type->ref.marker)) {
330
327
  Napi::External<void> external = value.As<Napi::External<void>>();
331
328
  ptr = external.Data();
332
329
  } else if (IsNullOrUndefined(value)) {
@@ -338,9 +335,9 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
338
335
 
339
336
  *(void **)dest = ptr;
340
337
  } break;
341
- }
342
338
 
343
- offset += member.type->size;
339
+ case PrimitiveKind::Prototype: { RG_UNREACHABLE(); } break;
340
+ }
344
341
  }
345
342
 
346
343
  return true;
@@ -460,7 +457,7 @@ bool CallData::PushNormalArray(Napi::Array array, Size len, const TypeInfo *ref,
460
457
  });
461
458
  } break;
462
459
  case PrimitiveKind::Pointer: {
463
- PUSH_ARRAY(CheckValueTag(instance, value, ref) || IsNullOrUndefined(value), ref->name, {
460
+ PUSH_ARRAY(CheckValueTag(instance, value, ref->ref.marker) || IsNullOrUndefined(value), ref->name, {
464
461
  if (!IsNullOrUndefined(value)) {
465
462
  Napi::External<void> external = value.As<Napi::External<void>>();
466
463
  *(void **)dest = external.Data();
@@ -487,15 +484,15 @@ bool CallData::PushNormalArray(Napi::Array array, Size len, const TypeInfo *ref,
487
484
 
488
485
  if (value.IsArray()) {
489
486
  Napi::Array array2 = value.As<Napi::Array>();
490
- Size len2 = (Size)ref->size / ref->ref->size;
487
+ Size len2 = (Size)ref->size / ref->ref.type->size;
491
488
 
492
- if (!PushNormalArray(array2, len2, ref->ref, dest, realign))
489
+ if (!PushNormalArray(array2, len2, ref->ref.type, dest, realign))
493
490
  return false;
494
491
  } else if (value.IsTypedArray()) {
495
492
  Napi::TypedArray array2 = value.As<Napi::TypedArray>();
496
- Size len2 = (Size)ref->size / ref->ref->size;
493
+ Size len2 = (Size)ref->size / ref->ref.type->size;
497
494
 
498
- if (!PushTypedArray(array2, len2, ref->ref, dest, realign))
495
+ if (!PushTypedArray(array2, len2, ref->ref.type, dest, realign))
499
496
  return false;
500
497
  } else if (value.IsString() && !realign) {
501
498
  if (!PushStringArray(value, ref, dest))
@@ -534,10 +531,10 @@ bool CallData::PushNormalArray(Napi::Array array, Size len, const TypeInfo *ref,
534
531
  if (value.IsFunction()) {
535
532
  Napi::Function func = value.As<Napi::Function>();
536
533
 
537
- ptr = ReserveTrampoline(ref->proto, func);
534
+ ptr = ReserveTrampoline(ref->ref.proto, func);
538
535
  if (RG_UNLIKELY(!ptr))
539
536
  return false;
540
- } else if (CheckValueTag(instance, value, ref)) {
537
+ } else if (CheckValueTag(instance, value, ref->ref.marker)) {
541
538
  Napi::External<void> external = value.As<Napi::External<void>>();
542
539
  ptr = external.Data();
543
540
  } else if (IsNullOrUndefined(value)) {
@@ -552,6 +549,8 @@ bool CallData::PushNormalArray(Napi::Array array, Size len, const TypeInfo *ref,
552
549
  offset += ref->size;
553
550
  }
554
551
  } break;
552
+
553
+ case PrimitiveKind::Prototype: { RG_UNREACHABLE(); } break;
555
554
  }
556
555
 
557
556
  #undef PUSH_ARRAY
@@ -601,7 +600,7 @@ bool CallData::PushStringArray(Napi::Value obj, const TypeInfo *type, uint8_t *o
601
600
 
602
601
  size_t encoded = 0;
603
602
 
604
- switch (type->ref->primitive) {
603
+ switch (type->ref.type->primitive) {
605
604
  case PrimitiveKind::Int8: {
606
605
  napi_status status = napi_get_value_string_utf8(env, obj, (char *)origin, type->size, &encoded);
607
606
  RG_ASSERT(status == napi_ok);
@@ -614,7 +613,7 @@ bool CallData::PushStringArray(Napi::Value obj, const TypeInfo *type, uint8_t *o
614
613
  } break;
615
614
 
616
615
  default: {
617
- ThrowError<Napi::TypeError>(env, "Strings cannot be converted to %1 array", type->ref->name);
616
+ ThrowError<Napi::TypeError>(env, "Strings cannot be converted to %1 array", type->ref.type->name);
618
617
  return false;
619
618
  } break;
620
619
  }
@@ -634,7 +633,9 @@ bool CallData::PushPointer(Napi::Value value, const ParameterInfo &param, void *
634
633
  } break;
635
634
 
636
635
  case napi_external: {
637
- if (RG_UNLIKELY(!CheckValueTag(instance, value, param.type)))
636
+ RG_ASSERT(param.type->primitive == PrimitiveKind::Pointer);
637
+
638
+ if (RG_UNLIKELY(!CheckValueTag(instance, value, param.type->ref.marker)))
638
639
  goto unexpected;
639
640
 
640
641
  *out_ptr = value.As<Napi::External<uint8_t>>().Data();
@@ -648,12 +649,12 @@ bool CallData::PushPointer(Napi::Value value, const ParameterInfo &param, void *
648
649
  Napi::Array array = value.As<Napi::Array>();
649
650
 
650
651
  Size len = (Size)array.Length();
651
- Size size = len * param.type->ref->size;
652
+ Size size = len * param.type->ref.type->size;
652
653
 
653
654
  ptr = AllocHeap(size, 16);
654
655
 
655
656
  if (param.directions & 1) {
656
- if (!PushNormalArray(array, len, param.type->ref, ptr))
657
+ if (!PushNormalArray(array, len, param.type->ref.type, ptr))
657
658
  return false;
658
659
  } else {
659
660
  memset(ptr, 0, size);
@@ -667,24 +668,24 @@ bool CallData::PushPointer(Napi::Value value, const ParameterInfo &param, void *
667
668
  ptr = AllocHeap(size, 16);
668
669
 
669
670
  if (param.directions & 1) {
670
- if (!PushTypedArray(array, len, param.type->ref, ptr))
671
+ if (!PushTypedArray(array, len, param.type->ref.type, ptr))
671
672
  return false;
672
673
  } else {
673
- if (RG_UNLIKELY(array.TypedArrayType() != GetTypedArrayType(param.type->ref))) {
674
- ThrowError<Napi::TypeError>(env, "Cannot use %1 value for %2 array", GetValueType(instance, array), param.type->ref->name);
674
+ if (RG_UNLIKELY(array.TypedArrayType() != GetTypedArrayType(param.type->ref.type))) {
675
+ ThrowError<Napi::TypeError>(env, "Cannot use %1 value for %2 array", GetValueType(instance, array), param.type->ref.type->name);
675
676
  return false;
676
677
  }
677
678
 
678
679
  memset(ptr, 0, size);
679
680
  }
680
- } else if (RG_LIKELY(param.type->ref->primitive == PrimitiveKind::Record)) {
681
+ } else if (RG_LIKELY(param.type->ref.type->primitive == PrimitiveKind::Record)) {
681
682
  Napi::Object obj = value.As<Napi::Object>();
682
683
  RG_ASSERT(IsObject(value));
683
684
 
684
- ptr = AllocHeap(param.type->ref->size, 16);
685
+ ptr = AllocHeap(param.type->ref.type->size, 16);
685
686
 
686
687
  if (param.directions & 1) {
687
- if (!PushObject(obj, param.type->ref, ptr))
688
+ if (!PushObject(obj, param.type->ref.type, ptr))
688
689
  return false;
689
690
  } else {
690
691
  memset(ptr, 0, param.type->size);
@@ -700,7 +701,7 @@ bool CallData::PushPointer(Napi::Value value, const ParameterInfo &param, void *
700
701
  RG_ASSERT(status == napi_ok);
701
702
 
702
703
  out->ptr = ptr;
703
- out->type = param.type->ref;
704
+ out->type = param.type->ref.type;
704
705
  }
705
706
 
706
707
  *out_ptr = ptr;
@@ -741,27 +742,34 @@ void CallData::PopOutArguments()
741
742
  Napi::Object obj(env, value);
742
743
  PopObject(obj, out.ptr, out.type);
743
744
  }
745
+
746
+ if (out.type->dispose) {
747
+ out.type->dispose(env, out.type, out.ptr);
748
+ }
744
749
  }
745
750
  }
746
751
 
747
752
  void *CallData::ReserveTrampoline(const FunctionInfo *proto, Napi::Function func)
748
753
  {
749
- uint32_t idx = CountTrailingZeros(instance->free_trampolines);
750
-
751
- if (RG_UNLIKELY(idx >= MaxTrampolines)) {
752
- ThrowError<Napi::Error>(env, "Too many callbacks are in use (max = %1)", MaxTrampolines);
754
+ if (RG_UNLIKELY(instance->temp_trampolines >= MaxTrampolines)) {
755
+ ThrowError<Napi::Error>(env, "Too many temporary callbacks are in use (max = %1)", MaxTrampolines);
753
756
  return nullptr;
754
757
  }
755
758
 
756
- instance->free_trampolines &= ~(1u << idx);
757
- used_trampolines |= 1u << idx;
759
+ int idx = instance->next_trampoline;
760
+
761
+ instance->next_trampoline = (int16_t)((instance->next_trampoline + 1) % MaxTrampolines);
762
+ instance->temp_trampolines++;
763
+ used_trampolines++;
764
+
765
+ TrampolineInfo *trampoline = &instance->trampolines[idx];
758
766
 
759
- instance->trampolines[idx].proto = proto;
760
- instance->trampolines[idx].func.Reset(func, 1);
761
- instance->trampolines[idx].generation = mem->generation;
767
+ trampoline->proto = proto;
768
+ trampoline->func.Reset(func, 1);
769
+ trampoline->generation = (int32_t)mem->generation;
762
770
 
763
- void *trampoline = GetTrampoline(idx, proto);
764
- return trampoline;
771
+ void *ptr = GetTrampoline(idx, proto);
772
+ return ptr;
765
773
  }
766
774
 
767
775
  void CallData::PopObject(Napi::Object obj, const uint8_t *origin, const TypeInfo *type, int16_t realign)
@@ -771,12 +779,10 @@ void CallData::PopObject(Napi::Object obj, const uint8_t *origin, const TypeInfo
771
779
 
772
780
  RG_ASSERT(type->primitive == PrimitiveKind::Record);
773
781
 
774
- Size offset = 0;
775
-
776
- for (const RecordMember &member: type->members) {
777
- int16_t align = std::max(realign, member.align);
778
- offset = AlignLen(offset, align);
782
+ for (Size i = 0; i < type->members.len; i++) {
783
+ const RecordMember &member = type->members[i];
779
784
 
785
+ Size offset = realign ? (i * realign) : member.offset;
780
786
  const uint8_t *src = origin + offset;
781
787
 
782
788
  switch (member.type->primitive) {
@@ -821,10 +827,18 @@ void CallData::PopObject(Napi::Object obj, const uint8_t *origin, const TypeInfo
821
827
  case PrimitiveKind::String: {
822
828
  const char *str = *(const char **)src;
823
829
  obj.Set(member.name, str ? Napi::String::New(env, str) : env.Null());
830
+
831
+ if (member.type->dispose) {
832
+ member.type->dispose(env, member.type, str);
833
+ }
824
834
  } break;
825
835
  case PrimitiveKind::String16: {
826
836
  const char16_t *str16 = *(const char16_t **)src;
827
837
  obj.Set(member.name, str16 ? Napi::String::New(env, str16) : env.Null());
838
+
839
+ if (member.type->dispose) {
840
+ member.type->dispose(env, member.type, str16);
841
+ }
828
842
  } break;
829
843
  case PrimitiveKind::Pointer:
830
844
  case PrimitiveKind::Callback: {
@@ -832,12 +846,16 @@ void CallData::PopObject(Napi::Object obj, const uint8_t *origin, const TypeInfo
832
846
 
833
847
  if (ptr2) {
834
848
  Napi::External<void> external = Napi::External<void>::New(env, ptr2);
835
- SetValueTag(instance, external, member.type);
849
+ SetValueTag(instance, external, member.type->ref.marker);
836
850
 
837
851
  obj.Set(member.name, external);
838
852
  } else {
839
853
  obj.Set(member.name, env.Null());
840
854
  }
855
+
856
+ if (member.type->dispose) {
857
+ member.type->dispose(env, member.type, ptr2);
858
+ }
841
859
  } break;
842
860
  case PrimitiveKind::Record: {
843
861
  Napi::Object obj2 = PopObject(src, member.type, realign);
@@ -855,9 +873,9 @@ void CallData::PopObject(Napi::Object obj, const uint8_t *origin, const TypeInfo
855
873
  double d = *(double *)src;
856
874
  obj.Set(member.name, Napi::Number::New(env, d));
857
875
  } break;
858
- }
859
876
 
860
- offset += member.type->size;
877
+ case PrimitiveKind::Prototype: { RG_UNREACHABLE(); } break;
878
+ }
861
879
  }
862
880
  }
863
881
 
@@ -938,12 +956,20 @@ void CallData::PopNormalArray(Napi::Array array, const uint8_t *origin, const Ty
938
956
  POP_ARRAY({
939
957
  const char *str = *(const char **)src;
940
958
  array.Set(i, str ? Napi::String::New(env, str) : env.Null());
959
+
960
+ if (ref->dispose) {
961
+ ref->dispose(env, ref, str);
962
+ }
941
963
  });
942
964
  } break;
943
965
  case PrimitiveKind::String16: {
944
966
  POP_ARRAY({
945
967
  const char16_t *str16 = *(const char16_t **)src;
946
968
  array.Set(i, str16 ? Napi::String::New(env, str16) : env.Null());
969
+
970
+ if (ref->dispose) {
971
+ ref->dispose(env, ref, str16);
972
+ }
947
973
  });
948
974
  } break;
949
975
  case PrimitiveKind::Pointer:
@@ -953,12 +979,16 @@ void CallData::PopNormalArray(Napi::Array array, const uint8_t *origin, const Ty
953
979
 
954
980
  if (ptr2) {
955
981
  Napi::External<void> external = Napi::External<void>::New(env, ptr2);
956
- SetValueTag(instance, external, ref);
982
+ SetValueTag(instance, external, ref->ref.marker);
957
983
 
958
984
  array.Set(i, external);
959
985
  } else {
960
986
  array.Set(i, env.Null());
961
987
  }
988
+
989
+ if (ref->dispose) {
990
+ ref->dispose(env, ref, ptr2);
991
+ }
962
992
  });
963
993
  } break;
964
994
  case PrimitiveKind::Record: {
@@ -975,6 +1005,8 @@ void CallData::PopNormalArray(Napi::Array array, const uint8_t *origin, const Ty
975
1005
  } break;
976
1006
  case PrimitiveKind::Float32: { POP_NUMBER_ARRAY(float); } break;
977
1007
  case PrimitiveKind::Float64: { POP_NUMBER_ARRAY(double); } break;
1008
+
1009
+ case PrimitiveKind::Prototype: { RG_UNREACHABLE(); } break;
978
1010
  }
979
1011
 
980
1012
  #undef POP_NUMBER_ARRAY
@@ -1012,7 +1044,7 @@ Napi::Value CallData::PopArray(const uint8_t *origin, const TypeInfo *type, int1
1012
1044
  {
1013
1045
  RG_ASSERT(type->primitive == PrimitiveKind::Array);
1014
1046
 
1015
- uint32_t len = type->size / type->ref->size;
1047
+ uint32_t len = type->size / type->ref.type->size;
1016
1048
  Size offset = 0;
1017
1049
 
1018
1050
  #define POP_ARRAY(SetCode) \
@@ -1020,14 +1052,14 @@ Napi::Value CallData::PopArray(const uint8_t *origin, const TypeInfo *type, int1
1020
1052
  Napi::Array array = Napi::Array::New(env); \
1021
1053
  \
1022
1054
  for (uint32_t i = 0; i < len; i++) { \
1023
- int16_t align = std::max(realign, type->ref->align); \
1055
+ int16_t align = std::max(realign, type->ref.type->align); \
1024
1056
  offset = AlignLen(offset, align); \
1025
1057
  \
1026
1058
  const uint8_t *src = origin + offset; \
1027
1059
  \
1028
1060
  SetCode \
1029
1061
  \
1030
- offset += type->ref->size; \
1062
+ offset += type->ref.type->size; \
1031
1063
  } \
1032
1064
  \
1033
1065
  return array; \
@@ -1041,13 +1073,13 @@ Napi::Value CallData::PopArray(const uint8_t *origin, const TypeInfo *type, int1
1041
1073
  }); \
1042
1074
  } else { \
1043
1075
  Napi::TypedArrayType array = Napi::TypedArrayType::New(env, len); \
1044
- PopTypedArray(array, origin, type->ref, realign); \
1076
+ PopTypedArray(array, origin, type->ref.type, realign); \
1045
1077
  \
1046
1078
  return array; \
1047
1079
  } \
1048
1080
  } while (false)
1049
1081
 
1050
- switch (type->ref->primitive) {
1082
+ switch (type->ref.type->primitive) {
1051
1083
  case PrimitiveKind::Void: { RG_UNREACHABLE(); } break;
1052
1084
 
1053
1085
  case PrimitiveKind::Bool: {
@@ -1117,7 +1149,7 @@ Napi::Value CallData::PopArray(const uint8_t *origin, const TypeInfo *type, int1
1117
1149
 
1118
1150
  if (ptr2) {
1119
1151
  Napi::External<void> external = Napi::External<void>::New(env, ptr2);
1120
- SetValueTag(instance, external, type->ref);
1152
+ SetValueTag(instance, external, type->ref.type->ref.marker);
1121
1153
 
1122
1154
  array.Set(i, external);
1123
1155
  } else {
@@ -1127,18 +1159,20 @@ Napi::Value CallData::PopArray(const uint8_t *origin, const TypeInfo *type, int1
1127
1159
  } break;
1128
1160
  case PrimitiveKind::Record: {
1129
1161
  POP_ARRAY({
1130
- Napi::Object obj = PopObject(src, type->ref, realign);
1162
+ Napi::Object obj = PopObject(src, type->ref.type, realign);
1131
1163
  array.Set(i, obj);
1132
1164
  });
1133
1165
  } break;
1134
1166
  case PrimitiveKind::Array: {
1135
1167
  POP_ARRAY({
1136
- Napi::Value value = PopArray(src, type->ref, realign);
1168
+ Napi::Value value = PopArray(src, type->ref.type, realign);
1137
1169
  array.Set(i, value);
1138
1170
  });
1139
1171
  } break;
1140
1172
  case PrimitiveKind::Float32: { POP_NUMBER_ARRAY(Float32Array, float); } break;
1141
1173
  case PrimitiveKind::Float64: { POP_NUMBER_ARRAY(Float64Array, double); } break;
1174
+
1175
+ case PrimitiveKind::Prototype: { RG_UNREACHABLE(); } break;
1142
1176
  }
1143
1177
 
1144
1178
  #undef POP_NUMBER_ARRAY
package/src/call.hh CHANGED
@@ -42,7 +42,7 @@ class alignas(8) CallData {
42
42
  Span<uint8_t> old_stack_mem;
43
43
  Span<uint8_t> old_heap_mem;
44
44
 
45
- uint32_t used_trampolines = 0;
45
+ int16_t used_trampolines = 0;
46
46
 
47
47
  LocalArray<OutArgument, MaxOutParameters> out_arguments;
48
48
 
@@ -103,6 +103,7 @@ private:
103
103
 
104
104
  void *ReserveTrampoline(const FunctionInfo *proto, Napi::Function func);
105
105
  };
106
+ RG_STATIC_ASSERT(MaxTrampolines <= 32);
106
107
 
107
108
  template <typename T>
108
109
  inline bool CallData::AllocStack(Size size, Size align, T **out_ptr)