koffi 1.3.12 → 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.
- package/CMakeLists.txt +7 -2
- package/ChangeLog.md +42 -16
- package/README.md +6 -0
- package/build/qemu/2.0.0/koffi_darwin_arm64.tar.gz +0 -0
- package/build/qemu/2.0.0/koffi_darwin_x64.tar.gz +0 -0
- package/build/qemu/2.0.0/koffi_freebsd_arm64.tar.gz +0 -0
- package/build/qemu/2.0.0/koffi_freebsd_ia32.tar.gz +0 -0
- package/build/qemu/2.0.0/koffi_freebsd_x64.tar.gz +0 -0
- package/build/qemu/2.0.0/koffi_linux_arm32hf.tar.gz +0 -0
- package/build/qemu/2.0.0/koffi_linux_arm64.tar.gz +0 -0
- package/build/qemu/2.0.0/koffi_linux_ia32.tar.gz +0 -0
- package/build/qemu/2.0.0/koffi_linux_riscv64hf64.tar.gz +0 -0
- package/build/qemu/2.0.0/koffi_linux_x64.tar.gz +0 -0
- package/build/qemu/2.0.0/koffi_openbsd_ia32.tar.gz +0 -0
- package/build/qemu/2.0.0/koffi_openbsd_x64.tar.gz +0 -0
- package/build/qemu/2.0.0/koffi_win32_arm64.tar.gz +0 -0
- package/build/qemu/2.0.0/koffi_win32_ia32.tar.gz +0 -0
- package/build/qemu/2.0.0/koffi_win32_x64.tar.gz +0 -0
- package/doc/benchmarks.md +2 -2
- package/doc/changes.md +156 -1
- package/doc/contribute.md +0 -1
- package/doc/dist/doctrees/changes.doctree +0 -0
- package/doc/dist/doctrees/environment.pickle +0 -0
- package/doc/dist/doctrees/functions.doctree +0 -0
- package/doc/dist/doctrees/types.doctree +0 -0
- package/doc/dist/html/_sources/changes.md.txt +156 -1
- package/doc/dist/html/_sources/functions.md.txt +8 -4
- package/doc/dist/html/_sources/types.md.txt +9 -0
- package/doc/dist/html/benchmarks.html +1 -1
- package/doc/dist/html/changes.html +226 -14
- package/doc/dist/html/contribute.html +1 -1
- package/doc/dist/html/functions.html +15 -12
- package/doc/dist/html/genindex.html +1 -1
- package/doc/dist/html/index.html +6 -16
- package/doc/dist/html/memory.html +3 -3
- package/doc/dist/html/objects.inv +0 -0
- package/doc/dist/html/platforms.html +1 -1
- package/doc/dist/html/search.html +1 -1
- package/doc/dist/html/searchindex.js +1 -1
- package/doc/dist/html/start.html +1 -1
- package/doc/dist/html/types.html +11 -3
- package/doc/functions.md +137 -13
- package/doc/types.md +35 -10
- package/package.json +1 -1
- package/qemu/registry/machines.json +5 -5
- package/qemu/registry/sha256sum.txt +16 -16
- package/src/abi_arm32.cc +90 -18
- package/src/abi_arm32_fwd.S +121 -57
- package/src/abi_arm64.cc +90 -18
- package/src/abi_arm64_fwd.S +96 -0
- package/src/abi_arm64_fwd.asm +128 -0
- package/src/abi_riscv64.cc +88 -18
- package/src/abi_riscv64_fwd.S +96 -0
- package/src/abi_x64_sysv.cc +93 -21
- package/src/abi_x64_sysv_fwd.S +96 -0
- package/src/abi_x64_win.cc +88 -18
- package/src/abi_x64_win_fwd.asm +128 -0
- package/src/abi_x86.cc +93 -18
- package/src/abi_x86_fwd.S +96 -0
- package/src/abi_x86_fwd.asm +128 -0
- package/src/call.cc +97 -63
- package/src/call.hh +2 -1
- package/src/ffi.cc +452 -140
- package/src/ffi.hh +23 -9
- package/src/parser.cc +18 -41
- package/src/util.cc +117 -27
- package/src/util.hh +3 -2
- package/test/callbacks.js +54 -8
- package/test/misc.c +29 -14
- package/test/raylib.js +1 -1
- package/test/sqlite.js +24 -16
- package/test/sync.js +41 -31
- package/vendor/libcc/libcc.cc +18 -5
- package/vendor/libcc/libcc.hh +70 -23
- package/build/qemu/1.3.12/koffi_darwin_arm64.tar.gz +0 -0
- package/build/qemu/1.3.12/koffi_darwin_x64.tar.gz +0 -0
- package/build/qemu/1.3.12/koffi_freebsd_arm64.tar.gz +0 -0
- package/build/qemu/1.3.12/koffi_freebsd_ia32.tar.gz +0 -0
- package/build/qemu/1.3.12/koffi_freebsd_x64.tar.gz +0 -0
- package/build/qemu/1.3.12/koffi_linux_arm32hf.tar.gz +0 -0
- package/build/qemu/1.3.12/koffi_linux_arm64.tar.gz +0 -0
- package/build/qemu/1.3.12/koffi_linux_ia32.tar.gz +0 -0
- package/build/qemu/1.3.12/koffi_linux_riscv64hf64.tar.gz +0 -0
- package/build/qemu/1.3.12/koffi_linux_x64.tar.gz +0 -0
- package/build/qemu/1.3.12/koffi_openbsd_ia32.tar.gz +0 -0
- package/build/qemu/1.3.12/koffi_openbsd_x64.tar.gz +0 -0
- package/build/qemu/1.3.12/koffi_win32_arm64.tar.gz +0 -0
- package/build/qemu/1.3.12/koffi_win32_ia32.tar.gz +0 -0
- package/build/qemu/1.3.12/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->
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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 ¶m, void *
|
|
|
634
633
|
} break;
|
|
635
634
|
|
|
636
635
|
case napi_external: {
|
|
637
|
-
|
|
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 ¶m, 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 ¶m, 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 ¶m, 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
|
-
|
|
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
|
-
|
|
757
|
-
|
|
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
|
-
|
|
760
|
-
|
|
761
|
-
|
|
767
|
+
trampoline->proto = proto;
|
|
768
|
+
trampoline->func.Reset(func, 1);
|
|
769
|
+
trampoline->generation = (int32_t)mem->generation;
|
|
762
770
|
|
|
763
|
-
void *
|
|
764
|
-
return
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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)
|