koffi 1.3.12 → 2.1.0-beta.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.
- package/CMakeLists.txt +8 -10
- package/ChangeLog.md +48 -16
- package/README.md +6 -0
- package/benchmark/atoi_koffi.js +12 -8
- package/benchmark/atoi_napi.js +12 -8
- package/benchmark/atoi_node_ffi.js +11 -10
- package/benchmark/raylib_cc.cc +12 -9
- package/benchmark/raylib_koffi.js +15 -13
- package/benchmark/raylib_node_ffi.js +15 -13
- package/benchmark/raylib_node_raylib.js +14 -11
- package/build/qemu/2.1.0-beta.1/koffi_darwin_arm64.tar.gz +0 -0
- package/build/qemu/2.1.0-beta.1/koffi_darwin_x64.tar.gz +0 -0
- package/build/qemu/2.1.0-beta.1/koffi_freebsd_arm64.tar.gz +0 -0
- package/build/qemu/2.1.0-beta.1/koffi_freebsd_ia32.tar.gz +0 -0
- package/build/qemu/2.1.0-beta.1/koffi_freebsd_x64.tar.gz +0 -0
- package/build/qemu/2.1.0-beta.1/koffi_linux_arm32hf.tar.gz +0 -0
- package/build/qemu/2.1.0-beta.1/koffi_linux_arm64.tar.gz +0 -0
- package/build/qemu/2.1.0-beta.1/koffi_linux_ia32.tar.gz +0 -0
- package/build/qemu/2.1.0-beta.1/koffi_linux_riscv64hf64.tar.gz +0 -0
- package/build/qemu/2.1.0-beta.1/koffi_linux_x64.tar.gz +0 -0
- package/build/qemu/2.1.0-beta.1/koffi_openbsd_ia32.tar.gz +0 -0
- package/build/qemu/2.1.0-beta.1/koffi_openbsd_x64.tar.gz +0 -0
- package/build/qemu/2.1.0-beta.1/koffi_win32_arm64.tar.gz +0 -0
- package/build/qemu/2.1.0-beta.1/koffi_win32_ia32.tar.gz +0 -0
- package/build/qemu/2.1.0-beta.1/koffi_win32_x64.tar.gz +0 -0
- package/doc/changes.md +160 -1
- package/doc/conf.py +14 -1
- package/doc/contribute.md +0 -1
- package/doc/dist/doctrees/benchmarks.doctree +0 -0
- 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/index.doctree +0 -0
- package/doc/dist/doctrees/types.doctree +0 -0
- package/doc/dist/html/.buildinfo +1 -1
- package/doc/dist/html/_sources/benchmarks.md.txt +2 -2
- package/doc/dist/html/_sources/changes.md.txt +160 -1
- package/doc/dist/html/_sources/functions.md.txt +17 -13
- package/doc/dist/html/_sources/types.md.txt +87 -35
- package/doc/dist/html/benchmarks.html +7 -3
- package/doc/dist/html/changes.html +241 -14
- package/doc/dist/html/contribute.html +5 -1
- package/doc/dist/html/functions.html +30 -23
- package/doc/dist/html/genindex.html +5 -1
- package/doc/dist/html/index.html +13 -19
- package/doc/dist/html/memory.html +7 -3
- package/doc/dist/html/objects.inv +0 -0
- package/doc/dist/html/platforms.html +6 -2
- package/doc/dist/html/search.html +5 -1
- package/doc/dist/html/searchindex.js +1 -1
- package/doc/dist/html/start.html +5 -1
- package/doc/dist/html/types.html +104 -43
- package/doc/functions.md +139 -15
- package/doc/templates/badges.html +5 -0
- package/doc/types.md +108 -40
- package/package.json +2 -2
- package/qemu/qemu.js +1 -1
- package/qemu/registry/machines.json +5 -5
- package/qemu/registry/sha256sum.txt +16 -16
- package/src/abi_arm32.cc +91 -19
- package/src/abi_arm32_fwd.S +121 -57
- package/src/abi_arm64.cc +91 -19
- package/src/abi_arm64_fwd.S +96 -0
- package/src/abi_arm64_fwd.asm +128 -0
- package/src/abi_riscv64.cc +89 -19
- package/src/abi_riscv64_fwd.S +96 -0
- package/src/abi_x64_sysv.cc +94 -22
- package/src/abi_x64_sysv_fwd.S +96 -0
- package/src/abi_x64_win.cc +89 -19
- package/src/abi_x64_win_fwd.asm +128 -0
- package/src/abi_x86.cc +94 -19
- package/src/abi_x86_fwd.S +96 -0
- package/src/abi_x86_fwd.asm +128 -0
- package/src/call.cc +128 -78
- package/src/call.hh +17 -4
- package/src/ffi.cc +514 -145
- package/src/ffi.hh +30 -9
- package/src/index.js +4 -2
- package/src/parser.cc +19 -44
- package/src/util.cc +160 -27
- package/src/util.hh +7 -2
- package/test/async.js +1 -2
- package/test/callbacks.js +56 -11
- package/test/misc.c +50 -15
- package/test/raylib.js +2 -2
- package/test/sqlite.js +27 -19
- package/test/sync.js +71 -35
- 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/abi_x64_sysv.cc
CHANGED
|
@@ -81,6 +81,22 @@ extern "C" int Trampoline12; extern "C" int TrampolineX12;
|
|
|
81
81
|
extern "C" int Trampoline13; extern "C" int TrampolineX13;
|
|
82
82
|
extern "C" int Trampoline14; extern "C" int TrampolineX14;
|
|
83
83
|
extern "C" int Trampoline15; extern "C" int TrampolineX15;
|
|
84
|
+
extern "C" int Trampoline16; extern "C" int TrampolineX16;
|
|
85
|
+
extern "C" int Trampoline17; extern "C" int TrampolineX17;
|
|
86
|
+
extern "C" int Trampoline18; extern "C" int TrampolineX18;
|
|
87
|
+
extern "C" int Trampoline19; extern "C" int TrampolineX19;
|
|
88
|
+
extern "C" int Trampoline20; extern "C" int TrampolineX20;
|
|
89
|
+
extern "C" int Trampoline21; extern "C" int TrampolineX21;
|
|
90
|
+
extern "C" int Trampoline22; extern "C" int TrampolineX22;
|
|
91
|
+
extern "C" int Trampoline23; extern "C" int TrampolineX23;
|
|
92
|
+
extern "C" int Trampoline24; extern "C" int TrampolineX24;
|
|
93
|
+
extern "C" int Trampoline25; extern "C" int TrampolineX25;
|
|
94
|
+
extern "C" int Trampoline26; extern "C" int TrampolineX26;
|
|
95
|
+
extern "C" int Trampoline27; extern "C" int TrampolineX27;
|
|
96
|
+
extern "C" int Trampoline28; extern "C" int TrampolineX28;
|
|
97
|
+
extern "C" int Trampoline29; extern "C" int TrampolineX29;
|
|
98
|
+
extern "C" int Trampoline30; extern "C" int TrampolineX30;
|
|
99
|
+
extern "C" int Trampoline31; extern "C" int TrampolineX31;
|
|
84
100
|
|
|
85
101
|
extern "C" napi_value CallSwitchStack(Napi::Function *func, size_t argc, napi_value *argv,
|
|
86
102
|
uint8_t *old_sp, Span<uint8_t> *new_stack,
|
|
@@ -102,9 +118,25 @@ static void *const Trampolines[][2] = {
|
|
|
102
118
|
{ &Trampoline12, &TrampolineX12 },
|
|
103
119
|
{ &Trampoline13, &TrampolineX13 },
|
|
104
120
|
{ &Trampoline14, &TrampolineX14 },
|
|
105
|
-
{ &Trampoline15, &TrampolineX15 }
|
|
121
|
+
{ &Trampoline15, &TrampolineX15 },
|
|
122
|
+
{ &Trampoline16, &TrampolineX16 },
|
|
123
|
+
{ &Trampoline17, &TrampolineX17 },
|
|
124
|
+
{ &Trampoline18, &TrampolineX18 },
|
|
125
|
+
{ &Trampoline19, &TrampolineX19 },
|
|
126
|
+
{ &Trampoline20, &TrampolineX20 },
|
|
127
|
+
{ &Trampoline21, &TrampolineX21 },
|
|
128
|
+
{ &Trampoline22, &TrampolineX22 },
|
|
129
|
+
{ &Trampoline23, &TrampolineX23 },
|
|
130
|
+
{ &Trampoline24, &TrampolineX24 },
|
|
131
|
+
{ &Trampoline25, &TrampolineX25 },
|
|
132
|
+
{ &Trampoline26, &TrampolineX26 },
|
|
133
|
+
{ &Trampoline27, &TrampolineX27 },
|
|
134
|
+
{ &Trampoline28, &TrampolineX28 },
|
|
135
|
+
{ &Trampoline29, &TrampolineX29 },
|
|
136
|
+
{ &Trampoline30, &TrampolineX30 },
|
|
137
|
+
{ &Trampoline31, &TrampolineX31 }
|
|
106
138
|
};
|
|
107
|
-
RG_STATIC_ASSERT(RG_LEN(Trampolines) == MaxTrampolines);
|
|
139
|
+
RG_STATIC_ASSERT(RG_LEN(Trampolines) == MaxTrampolines * 2);
|
|
108
140
|
|
|
109
141
|
static RG_THREAD_LOCAL CallData *exec_call;
|
|
110
142
|
|
|
@@ -169,12 +201,12 @@ static Size ClassifyType(const TypeInfo *type, Size offset, Span<RegisterClass>
|
|
|
169
201
|
return 1;
|
|
170
202
|
}
|
|
171
203
|
|
|
172
|
-
Size len = type->size / type->ref->size;
|
|
204
|
+
Size len = type->size / type->ref.type->size;
|
|
173
205
|
|
|
174
206
|
for (Size i = 0; i < len; i++) {
|
|
175
207
|
Size start = offset / 8;
|
|
176
|
-
ClassifyType(type->ref, offset % 8, classes.Take(start, classes.len - start));
|
|
177
|
-
offset += type->ref->size;
|
|
208
|
+
ClassifyType(type->ref.type, offset % 8, classes.Take(start, classes.len - start));
|
|
209
|
+
offset += type->ref.type->size;
|
|
178
210
|
}
|
|
179
211
|
|
|
180
212
|
return (offset + 7) / 8;
|
|
@@ -184,6 +216,8 @@ static Size ClassifyType(const TypeInfo *type, Size offset, Span<RegisterClass>
|
|
|
184
216
|
classes[0] = MergeClasses(classes[0], RegisterClass::SSE);
|
|
185
217
|
return 1;
|
|
186
218
|
} break;
|
|
219
|
+
|
|
220
|
+
case PrimitiveKind::Prototype: { RG_UNREACHABLE(); } break;
|
|
187
221
|
}
|
|
188
222
|
|
|
189
223
|
RG_UNREACHABLE();
|
|
@@ -410,10 +444,10 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
|
|
|
410
444
|
if (value.IsFunction()) {
|
|
411
445
|
Napi::Function func = value.As<Napi::Function>();
|
|
412
446
|
|
|
413
|
-
ptr = ReserveTrampoline(param.type->proto, func);
|
|
447
|
+
ptr = ReserveTrampoline(param.type->ref.proto, func);
|
|
414
448
|
if (RG_UNLIKELY(!ptr))
|
|
415
449
|
return false;
|
|
416
|
-
} else if (CheckValueTag(instance, value, param.type)) {
|
|
450
|
+
} else if (CheckValueTag(instance, value, param.type->ref.marker)) {
|
|
417
451
|
ptr = value.As<Napi::External<void>>().Data();
|
|
418
452
|
} else if (IsNullOrUndefined(value)) {
|
|
419
453
|
ptr = nullptr;
|
|
@@ -424,6 +458,8 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
|
|
|
424
458
|
|
|
425
459
|
*(void **)((param.gpr_count ? gpr_ptr : args_ptr)++) = ptr;
|
|
426
460
|
} break;
|
|
461
|
+
|
|
462
|
+
case PrimitiveKind::Prototype: { RG_UNREACHABLE(); } break;
|
|
427
463
|
}
|
|
428
464
|
}
|
|
429
465
|
|
|
@@ -477,6 +513,8 @@ void CallData::Execute()
|
|
|
477
513
|
case PrimitiveKind::Array: { RG_UNREACHABLE(); } break;
|
|
478
514
|
case PrimitiveKind::Float32: { result.f = PERFORM_CALL(F); } break;
|
|
479
515
|
case PrimitiveKind::Float64: { result.d = PERFORM_CALL(DG).xmm0; } break;
|
|
516
|
+
|
|
517
|
+
case PrimitiveKind::Prototype: { RG_UNREACHABLE(); } break;
|
|
480
518
|
}
|
|
481
519
|
|
|
482
520
|
#undef PERFORM_CALL
|
|
@@ -484,10 +522,16 @@ void CallData::Execute()
|
|
|
484
522
|
|
|
485
523
|
Napi::Value CallData::Complete()
|
|
486
524
|
{
|
|
487
|
-
|
|
525
|
+
RG_DEFER {
|
|
526
|
+
PopOutArguments();
|
|
527
|
+
|
|
528
|
+
if (func->ret.type->dispose) {
|
|
529
|
+
func->ret.type->dispose(env, func->ret.type, result.ptr);
|
|
530
|
+
}
|
|
531
|
+
};
|
|
488
532
|
|
|
489
533
|
switch (func->ret.type->primitive) {
|
|
490
|
-
case PrimitiveKind::Void: return env.
|
|
534
|
+
case PrimitiveKind::Void: return env.Undefined();
|
|
491
535
|
case PrimitiveKind::Bool: return Napi::Boolean::New(env, result.u32);
|
|
492
536
|
case PrimitiveKind::Int8: return Napi::Number::New(env, (double)result.i8);
|
|
493
537
|
case PrimitiveKind::UInt8: return Napi::Number::New(env, (double)result.u8);
|
|
@@ -503,7 +547,7 @@ Napi::Value CallData::Complete()
|
|
|
503
547
|
case PrimitiveKind::Callback: {
|
|
504
548
|
if (result.ptr) {
|
|
505
549
|
Napi::External<void> external = Napi::External<void>::New(env, result.ptr);
|
|
506
|
-
SetValueTag(instance, external, func->ret.type);
|
|
550
|
+
SetValueTag(instance, external, func->ret.type->ref.marker);
|
|
507
551
|
|
|
508
552
|
return external;
|
|
509
553
|
} else {
|
|
@@ -520,6 +564,8 @@ Napi::Value CallData::Complete()
|
|
|
520
564
|
case PrimitiveKind::Array: { RG_UNREACHABLE(); } break;
|
|
521
565
|
case PrimitiveKind::Float32: return Napi::Number::New(env, (double)result.f);
|
|
522
566
|
case PrimitiveKind::Float64: return Napi::Number::New(env, result.d);
|
|
567
|
+
|
|
568
|
+
case PrimitiveKind::Prototype: { RG_UNREACHABLE(); } break;
|
|
523
569
|
}
|
|
524
570
|
|
|
525
571
|
RG_UNREACHABLE();
|
|
@@ -527,12 +573,10 @@ Napi::Value CallData::Complete()
|
|
|
527
573
|
|
|
528
574
|
void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegisters *out_reg)
|
|
529
575
|
{
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
if (RG_UNLIKELY(trampoline.generation != mem->generation)) {
|
|
533
|
-
ThrowError<Napi::Error>(env, "Cannot use non-persistent callback beyond FFI call");
|
|
576
|
+
if (RG_UNLIKELY(env.IsExceptionPending()))
|
|
534
577
|
return;
|
|
535
|
-
|
|
578
|
+
|
|
579
|
+
const TrampolineInfo &trampoline = instance->trampolines[idx];
|
|
536
580
|
|
|
537
581
|
const FunctionInfo *proto = trampoline.proto;
|
|
538
582
|
Napi::Function func = trampoline.func.Value();
|
|
@@ -544,6 +588,13 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
|
|
|
544
588
|
uint8_t *return_ptr = proto->ret.use_memory ? (uint8_t *)gpr_ptr[0] : nullptr;
|
|
545
589
|
gpr_ptr += proto->ret.use_memory;
|
|
546
590
|
|
|
591
|
+
RG_DEFER_N(err_guard) { memset(out_reg, 0, RG_SIZE(*out_reg)); };
|
|
592
|
+
|
|
593
|
+
if (RG_UNLIKELY(trampoline.generation >= 0 && trampoline.generation != (int32_t)mem->generation)) {
|
|
594
|
+
ThrowError<Napi::Error>(env, "Cannot use non-registered callback beyond FFI call");
|
|
595
|
+
return;
|
|
596
|
+
}
|
|
597
|
+
|
|
547
598
|
LocalArray<napi_value, MaxParameters> arguments;
|
|
548
599
|
|
|
549
600
|
// Convert to JS arguments
|
|
@@ -613,12 +664,20 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
|
|
|
613
664
|
|
|
614
665
|
Napi::Value arg = str ? Napi::String::New(env, str) : env.Null();
|
|
615
666
|
arguments.Append(arg);
|
|
667
|
+
|
|
668
|
+
if (param.type->dispose) {
|
|
669
|
+
param.type->dispose(env, param.type, str);
|
|
670
|
+
}
|
|
616
671
|
} break;
|
|
617
672
|
case PrimitiveKind::String16: {
|
|
618
673
|
const char16_t *str16 = *(const char16_t **)((param.gpr_count ? gpr_ptr : args_ptr)++);
|
|
619
674
|
|
|
620
675
|
Napi::Value arg = str16 ? Napi::String::New(env, str16) : env.Null();
|
|
621
676
|
arguments.Append(arg);
|
|
677
|
+
|
|
678
|
+
if (param.type->dispose) {
|
|
679
|
+
param.type->dispose(env, param.type, str16);
|
|
680
|
+
}
|
|
622
681
|
} break;
|
|
623
682
|
case PrimitiveKind::Pointer:
|
|
624
683
|
case PrimitiveKind::Callback: {
|
|
@@ -626,12 +685,16 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
|
|
|
626
685
|
|
|
627
686
|
if (ptr2) {
|
|
628
687
|
Napi::External<void> external = Napi::External<void>::New(env, ptr2);
|
|
629
|
-
SetValueTag(instance, external, param.type);
|
|
688
|
+
SetValueTag(instance, external, param.type->ref.marker);
|
|
630
689
|
|
|
631
690
|
arguments.Append(external);
|
|
632
691
|
} else {
|
|
633
692
|
arguments.Append(env.Null());
|
|
634
693
|
}
|
|
694
|
+
|
|
695
|
+
if (param.type->dispose) {
|
|
696
|
+
param.type->dispose(env, param.type, ptr2);
|
|
697
|
+
}
|
|
635
698
|
} break;
|
|
636
699
|
case PrimitiveKind::Record: {
|
|
637
700
|
if (param.gpr_count || param.xmm_count) {
|
|
@@ -680,6 +743,8 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
|
|
|
680
743
|
Napi::Value arg = Napi::Number::New(env, d);
|
|
681
744
|
arguments.Append(arg);
|
|
682
745
|
} break;
|
|
746
|
+
|
|
747
|
+
case PrimitiveKind::Prototype: { RG_UNREACHABLE(); } break;
|
|
683
748
|
}
|
|
684
749
|
}
|
|
685
750
|
|
|
@@ -690,6 +755,9 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
|
|
|
690
755
|
[](Napi::Function *func, size_t argc, napi_value *argv) { return (napi_value)func->Call(argc, argv); });
|
|
691
756
|
Napi::Value value(env, ret);
|
|
692
757
|
|
|
758
|
+
if (RG_UNLIKELY(env.IsExceptionPending()))
|
|
759
|
+
return;
|
|
760
|
+
|
|
693
761
|
// Convert the result
|
|
694
762
|
switch (type->primitive) {
|
|
695
763
|
case PrimitiveKind::Void: {} break;
|
|
@@ -751,14 +819,14 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
|
|
|
751
819
|
case PrimitiveKind::Pointer: {
|
|
752
820
|
uint8_t *ptr;
|
|
753
821
|
|
|
754
|
-
if (CheckValueTag(instance, value, type)) {
|
|
822
|
+
if (CheckValueTag(instance, value, type->ref.marker)) {
|
|
755
823
|
ptr = value.As<Napi::External<uint8_t>>().Data();
|
|
756
|
-
} else if (IsObject(value) && type->ref->primitive == PrimitiveKind::Record) {
|
|
824
|
+
} else if (IsObject(value) && type->ref.type->primitive == PrimitiveKind::Record) {
|
|
757
825
|
Napi::Object obj = value.As<Napi::Object>();
|
|
758
826
|
|
|
759
|
-
ptr = AllocHeap(type->ref->size, 16);
|
|
827
|
+
ptr = AllocHeap(type->ref.type->size, 16);
|
|
760
828
|
|
|
761
|
-
if (!PushObject(obj, type->ref, ptr))
|
|
829
|
+
if (!PushObject(obj, type->ref.type, ptr))
|
|
762
830
|
return;
|
|
763
831
|
} else if (IsNullOrUndefined(value)) {
|
|
764
832
|
ptr = nullptr;
|
|
@@ -830,10 +898,10 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
|
|
|
830
898
|
if (value.IsFunction()) {
|
|
831
899
|
Napi::Function func2 = value.As<Napi::Function>();
|
|
832
900
|
|
|
833
|
-
ptr = ReserveTrampoline(type->proto, func2);
|
|
901
|
+
ptr = ReserveTrampoline(type->ref.proto, func2);
|
|
834
902
|
if (RG_UNLIKELY(!ptr))
|
|
835
903
|
return;
|
|
836
|
-
} else if (CheckValueTag(instance, value, type)) {
|
|
904
|
+
} else if (CheckValueTag(instance, value, type->ref.marker)) {
|
|
837
905
|
ptr = value.As<Napi::External<uint8_t>>().Data();
|
|
838
906
|
} else if (IsNullOrUndefined(value)) {
|
|
839
907
|
ptr = nullptr;
|
|
@@ -844,7 +912,11 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
|
|
|
844
912
|
|
|
845
913
|
out_reg->rax = (uint64_t)ptr;
|
|
846
914
|
} break;
|
|
915
|
+
|
|
916
|
+
case PrimitiveKind::Prototype: { RG_UNREACHABLE(); } break;
|
|
847
917
|
}
|
|
918
|
+
|
|
919
|
+
err_guard.Disable();
|
|
848
920
|
}
|
|
849
921
|
|
|
850
922
|
void *GetTrampoline(Size idx, const FunctionInfo *proto)
|
package/src/abi_x64_sysv_fwd.S
CHANGED
|
@@ -171,6 +171,22 @@ SYMBOL(ForwardCallXDD):
|
|
|
171
171
|
.global SYMBOL(Trampoline13)
|
|
172
172
|
.global SYMBOL(Trampoline14)
|
|
173
173
|
.global SYMBOL(Trampoline15)
|
|
174
|
+
.global SYMBOL(Trampoline16)
|
|
175
|
+
.global SYMBOL(Trampoline17)
|
|
176
|
+
.global SYMBOL(Trampoline18)
|
|
177
|
+
.global SYMBOL(Trampoline19)
|
|
178
|
+
.global SYMBOL(Trampoline20)
|
|
179
|
+
.global SYMBOL(Trampoline21)
|
|
180
|
+
.global SYMBOL(Trampoline22)
|
|
181
|
+
.global SYMBOL(Trampoline23)
|
|
182
|
+
.global SYMBOL(Trampoline24)
|
|
183
|
+
.global SYMBOL(Trampoline25)
|
|
184
|
+
.global SYMBOL(Trampoline26)
|
|
185
|
+
.global SYMBOL(Trampoline27)
|
|
186
|
+
.global SYMBOL(Trampoline28)
|
|
187
|
+
.global SYMBOL(Trampoline29)
|
|
188
|
+
.global SYMBOL(Trampoline30)
|
|
189
|
+
.global SYMBOL(Trampoline31)
|
|
174
190
|
.global SYMBOL(TrampolineX0)
|
|
175
191
|
.global SYMBOL(TrampolineX1)
|
|
176
192
|
.global SYMBOL(TrampolineX2)
|
|
@@ -187,6 +203,22 @@ SYMBOL(ForwardCallXDD):
|
|
|
187
203
|
.global SYMBOL(TrampolineX13)
|
|
188
204
|
.global SYMBOL(TrampolineX14)
|
|
189
205
|
.global SYMBOL(TrampolineX15)
|
|
206
|
+
.global SYMBOL(TrampolineX16)
|
|
207
|
+
.global SYMBOL(TrampolineX17)
|
|
208
|
+
.global SYMBOL(TrampolineX18)
|
|
209
|
+
.global SYMBOL(TrampolineX19)
|
|
210
|
+
.global SYMBOL(TrampolineX20)
|
|
211
|
+
.global SYMBOL(TrampolineX21)
|
|
212
|
+
.global SYMBOL(TrampolineX22)
|
|
213
|
+
.global SYMBOL(TrampolineX23)
|
|
214
|
+
.global SYMBOL(TrampolineX24)
|
|
215
|
+
.global SYMBOL(TrampolineX25)
|
|
216
|
+
.global SYMBOL(TrampolineX26)
|
|
217
|
+
.global SYMBOL(TrampolineX27)
|
|
218
|
+
.global SYMBOL(TrampolineX28)
|
|
219
|
+
.global SYMBOL(TrampolineX29)
|
|
220
|
+
.global SYMBOL(TrampolineX30)
|
|
221
|
+
.global SYMBOL(TrampolineX31)
|
|
190
222
|
.global SYMBOL(RelayCallback)
|
|
191
223
|
.global SYMBOL(CallSwitchStack)
|
|
192
224
|
|
|
@@ -296,6 +328,38 @@ SYMBOL(Trampoline14):
|
|
|
296
328
|
trampoline 14
|
|
297
329
|
SYMBOL(Trampoline15):
|
|
298
330
|
trampoline 15
|
|
331
|
+
SYMBOL(Trampoline16):
|
|
332
|
+
trampoline 16
|
|
333
|
+
SYMBOL(Trampoline17):
|
|
334
|
+
trampoline 17
|
|
335
|
+
SYMBOL(Trampoline18):
|
|
336
|
+
trampoline 18
|
|
337
|
+
SYMBOL(Trampoline19):
|
|
338
|
+
trampoline 19
|
|
339
|
+
SYMBOL(Trampoline20):
|
|
340
|
+
trampoline 20
|
|
341
|
+
SYMBOL(Trampoline21):
|
|
342
|
+
trampoline 21
|
|
343
|
+
SYMBOL(Trampoline22):
|
|
344
|
+
trampoline 22
|
|
345
|
+
SYMBOL(Trampoline23):
|
|
346
|
+
trampoline 23
|
|
347
|
+
SYMBOL(Trampoline24):
|
|
348
|
+
trampoline 24
|
|
349
|
+
SYMBOL(Trampoline25):
|
|
350
|
+
trampoline 25
|
|
351
|
+
SYMBOL(Trampoline26):
|
|
352
|
+
trampoline 26
|
|
353
|
+
SYMBOL(Trampoline27):
|
|
354
|
+
trampoline 27
|
|
355
|
+
SYMBOL(Trampoline28):
|
|
356
|
+
trampoline 28
|
|
357
|
+
SYMBOL(Trampoline29):
|
|
358
|
+
trampoline 29
|
|
359
|
+
SYMBOL(Trampoline30):
|
|
360
|
+
trampoline 30
|
|
361
|
+
SYMBOL(Trampoline31):
|
|
362
|
+
trampoline 31
|
|
299
363
|
|
|
300
364
|
SYMBOL(TrampolineX0):
|
|
301
365
|
trampoline_xmm 0
|
|
@@ -329,6 +393,38 @@ SYMBOL(TrampolineX14):
|
|
|
329
393
|
trampoline_xmm 14
|
|
330
394
|
SYMBOL(TrampolineX15):
|
|
331
395
|
trampoline_xmm 15
|
|
396
|
+
SYMBOL(TrampolineX16):
|
|
397
|
+
trampoline_xmm 16
|
|
398
|
+
SYMBOL(TrampolineX17):
|
|
399
|
+
trampoline_xmm 17
|
|
400
|
+
SYMBOL(TrampolineX18):
|
|
401
|
+
trampoline_xmm 18
|
|
402
|
+
SYMBOL(TrampolineX19):
|
|
403
|
+
trampoline_xmm 19
|
|
404
|
+
SYMBOL(TrampolineX20):
|
|
405
|
+
trampoline_xmm 20
|
|
406
|
+
SYMBOL(TrampolineX21):
|
|
407
|
+
trampoline_xmm 21
|
|
408
|
+
SYMBOL(TrampolineX22):
|
|
409
|
+
trampoline_xmm 22
|
|
410
|
+
SYMBOL(TrampolineX23):
|
|
411
|
+
trampoline_xmm 23
|
|
412
|
+
SYMBOL(TrampolineX24):
|
|
413
|
+
trampoline_xmm 24
|
|
414
|
+
SYMBOL(TrampolineX25):
|
|
415
|
+
trampoline_xmm 25
|
|
416
|
+
SYMBOL(TrampolineX26):
|
|
417
|
+
trampoline_xmm 26
|
|
418
|
+
SYMBOL(TrampolineX27):
|
|
419
|
+
trampoline_xmm 27
|
|
420
|
+
SYMBOL(TrampolineX28):
|
|
421
|
+
trampoline_xmm 28
|
|
422
|
+
SYMBOL(TrampolineX29):
|
|
423
|
+
trampoline_xmm 29
|
|
424
|
+
SYMBOL(TrampolineX30):
|
|
425
|
+
trampoline_xmm 30
|
|
426
|
+
SYMBOL(TrampolineX31):
|
|
427
|
+
trampoline_xmm 31
|
|
332
428
|
|
|
333
429
|
# When a callback is relayed, Koffi will call into Node.js and V8 to execute Javascript.
|
|
334
430
|
# The problem is that we're still running on the separate Koffi stack, and V8 will
|
package/src/abi_x64_win.cc
CHANGED
|
@@ -50,6 +50,22 @@ extern "C" int Trampoline12; extern "C" int TrampolineX12;
|
|
|
50
50
|
extern "C" int Trampoline13; extern "C" int TrampolineX13;
|
|
51
51
|
extern "C" int Trampoline14; extern "C" int TrampolineX14;
|
|
52
52
|
extern "C" int Trampoline15; extern "C" int TrampolineX15;
|
|
53
|
+
extern "C" int Trampoline16; extern "C" int TrampolineX16;
|
|
54
|
+
extern "C" int Trampoline17; extern "C" int TrampolineX17;
|
|
55
|
+
extern "C" int Trampoline18; extern "C" int TrampolineX18;
|
|
56
|
+
extern "C" int Trampoline19; extern "C" int TrampolineX19;
|
|
57
|
+
extern "C" int Trampoline20; extern "C" int TrampolineX20;
|
|
58
|
+
extern "C" int Trampoline21; extern "C" int TrampolineX21;
|
|
59
|
+
extern "C" int Trampoline22; extern "C" int TrampolineX22;
|
|
60
|
+
extern "C" int Trampoline23; extern "C" int TrampolineX23;
|
|
61
|
+
extern "C" int Trampoline24; extern "C" int TrampolineX24;
|
|
62
|
+
extern "C" int Trampoline25; extern "C" int TrampolineX25;
|
|
63
|
+
extern "C" int Trampoline26; extern "C" int TrampolineX26;
|
|
64
|
+
extern "C" int Trampoline27; extern "C" int TrampolineX27;
|
|
65
|
+
extern "C" int Trampoline28; extern "C" int TrampolineX28;
|
|
66
|
+
extern "C" int Trampoline29; extern "C" int TrampolineX29;
|
|
67
|
+
extern "C" int Trampoline30; extern "C" int TrampolineX30;
|
|
68
|
+
extern "C" int Trampoline31; extern "C" int TrampolineX31;
|
|
53
69
|
|
|
54
70
|
extern "C" napi_value CallSwitchStack(Napi::Function *func, size_t argc, napi_value *argv,
|
|
55
71
|
uint8_t *old_sp, Span<uint8_t> *new_stack,
|
|
@@ -71,9 +87,25 @@ static void *const Trampolines[][2] = {
|
|
|
71
87
|
{ &Trampoline12, &TrampolineX12 },
|
|
72
88
|
{ &Trampoline13, &TrampolineX13 },
|
|
73
89
|
{ &Trampoline14, &TrampolineX14 },
|
|
74
|
-
{ &Trampoline15, &TrampolineX15 }
|
|
90
|
+
{ &Trampoline15, &TrampolineX15 },
|
|
91
|
+
{ &Trampoline16, &TrampolineX16 },
|
|
92
|
+
{ &Trampoline17, &TrampolineX17 },
|
|
93
|
+
{ &Trampoline18, &TrampolineX18 },
|
|
94
|
+
{ &Trampoline19, &TrampolineX19 },
|
|
95
|
+
{ &Trampoline20, &TrampolineX20 },
|
|
96
|
+
{ &Trampoline21, &TrampolineX21 },
|
|
97
|
+
{ &Trampoline22, &TrampolineX22 },
|
|
98
|
+
{ &Trampoline23, &TrampolineX23 },
|
|
99
|
+
{ &Trampoline24, &TrampolineX24 },
|
|
100
|
+
{ &Trampoline25, &TrampolineX25 },
|
|
101
|
+
{ &Trampoline26, &TrampolineX26 },
|
|
102
|
+
{ &Trampoline27, &TrampolineX27 },
|
|
103
|
+
{ &Trampoline28, &TrampolineX28 },
|
|
104
|
+
{ &Trampoline29, &TrampolineX29 },
|
|
105
|
+
{ &Trampoline30, &TrampolineX30 },
|
|
106
|
+
{ &Trampoline31, &TrampolineX31 }
|
|
75
107
|
};
|
|
76
|
-
RG_STATIC_ASSERT(RG_LEN(Trampolines) == MaxTrampolines);
|
|
108
|
+
RG_STATIC_ASSERT(RG_LEN(Trampolines) == MaxTrampolines * 2);
|
|
77
109
|
|
|
78
110
|
static RG_THREAD_LOCAL CallData *exec_call;
|
|
79
111
|
|
|
@@ -235,10 +267,10 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
|
|
|
235
267
|
if (value.IsFunction()) {
|
|
236
268
|
Napi::Function func = value.As<Napi::Function>();
|
|
237
269
|
|
|
238
|
-
ptr = ReserveTrampoline(param.type->proto, func);
|
|
270
|
+
ptr = ReserveTrampoline(param.type->ref.proto, func);
|
|
239
271
|
if (RG_UNLIKELY(!ptr))
|
|
240
272
|
return false;
|
|
241
|
-
} else if (CheckValueTag(instance, value, param.type)) {
|
|
273
|
+
} else if (CheckValueTag(instance, value, param.type->ref.marker)) {
|
|
242
274
|
ptr = value.As<Napi::External<uint8_t>>().Data();
|
|
243
275
|
} else if (IsNullOrUndefined(value)) {
|
|
244
276
|
ptr = nullptr;
|
|
@@ -249,6 +281,8 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
|
|
|
249
281
|
|
|
250
282
|
*(void **)(args_ptr++) = ptr;
|
|
251
283
|
} break;
|
|
284
|
+
|
|
285
|
+
case PrimitiveKind::Prototype: { RG_UNREACHABLE(); } break;
|
|
252
286
|
}
|
|
253
287
|
}
|
|
254
288
|
|
|
@@ -287,6 +321,8 @@ void CallData::Execute()
|
|
|
287
321
|
case PrimitiveKind::Array: { RG_UNREACHABLE(); } break;
|
|
288
322
|
case PrimitiveKind::Float32: { result.f = PERFORM_CALL(F); } break;
|
|
289
323
|
case PrimitiveKind::Float64: { result.d = PERFORM_CALL(D); } break;
|
|
324
|
+
|
|
325
|
+
case PrimitiveKind::Prototype: { RG_UNREACHABLE(); } break;
|
|
290
326
|
}
|
|
291
327
|
|
|
292
328
|
#undef PERFORM_CALL
|
|
@@ -294,10 +330,16 @@ void CallData::Execute()
|
|
|
294
330
|
|
|
295
331
|
Napi::Value CallData::Complete()
|
|
296
332
|
{
|
|
297
|
-
|
|
333
|
+
RG_DEFER {
|
|
334
|
+
PopOutArguments();
|
|
335
|
+
|
|
336
|
+
if (func->ret.type->dispose) {
|
|
337
|
+
func->ret.type->dispose(env, func->ret.type, result.ptr);
|
|
338
|
+
}
|
|
339
|
+
};
|
|
298
340
|
|
|
299
341
|
switch (func->ret.type->primitive) {
|
|
300
|
-
case PrimitiveKind::Void: return env.
|
|
342
|
+
case PrimitiveKind::Void: return env.Undefined();
|
|
301
343
|
case PrimitiveKind::Bool: return Napi::Boolean::New(env, result.u32);
|
|
302
344
|
case PrimitiveKind::Int8: return Napi::Number::New(env, (double)result.i8);
|
|
303
345
|
case PrimitiveKind::UInt8: return Napi::Number::New(env, (double)result.u8);
|
|
@@ -313,7 +355,7 @@ Napi::Value CallData::Complete()
|
|
|
313
355
|
case PrimitiveKind::Callback: {
|
|
314
356
|
if (result.ptr) {
|
|
315
357
|
Napi::External<void> external = Napi::External<void>::New(env, result.ptr);
|
|
316
|
-
SetValueTag(instance, external, func->ret.type);
|
|
358
|
+
SetValueTag(instance, external, func->ret.type->ref.marker);
|
|
317
359
|
|
|
318
360
|
return external;
|
|
319
361
|
} else {
|
|
@@ -330,6 +372,8 @@ Napi::Value CallData::Complete()
|
|
|
330
372
|
case PrimitiveKind::Array: { RG_UNREACHABLE(); } break;
|
|
331
373
|
case PrimitiveKind::Float32: return Napi::Number::New(env, (double)result.f);
|
|
332
374
|
case PrimitiveKind::Float64: return Napi::Number::New(env, result.d);
|
|
375
|
+
|
|
376
|
+
case PrimitiveKind::Prototype: { RG_UNREACHABLE(); } break;
|
|
333
377
|
}
|
|
334
378
|
|
|
335
379
|
RG_UNREACHABLE();
|
|
@@ -337,12 +381,10 @@ Napi::Value CallData::Complete()
|
|
|
337
381
|
|
|
338
382
|
void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegisters *out_reg)
|
|
339
383
|
{
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
if (RG_UNLIKELY(trampoline.generation != mem->generation)) {
|
|
343
|
-
ThrowError<Napi::Error>(env, "Cannot use non-persistent callback beyond FFI call");
|
|
384
|
+
if (RG_UNLIKELY(env.IsExceptionPending()))
|
|
344
385
|
return;
|
|
345
|
-
|
|
386
|
+
|
|
387
|
+
const TrampolineInfo &trampoline = instance->trampolines[idx];
|
|
346
388
|
|
|
347
389
|
const FunctionInfo *proto = trampoline.proto;
|
|
348
390
|
Napi::Function func = trampoline.func.Value();
|
|
@@ -353,6 +395,13 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
|
|
|
353
395
|
|
|
354
396
|
uint8_t *return_ptr = !proto->ret.regular ? (uint8_t *)gpr_ptr[0] : nullptr;
|
|
355
397
|
|
|
398
|
+
RG_DEFER_N(err_guard) { memset(out_reg, 0, RG_SIZE(*out_reg)); };
|
|
399
|
+
|
|
400
|
+
if (RG_UNLIKELY(trampoline.generation >= 0 && trampoline.generation != (int32_t)mem->generation)) {
|
|
401
|
+
ThrowError<Napi::Error>(env, "Cannot use non-registered callback beyond FFI call");
|
|
402
|
+
return;
|
|
403
|
+
}
|
|
404
|
+
|
|
356
405
|
LocalArray<napi_value, MaxParameters> arguments;
|
|
357
406
|
|
|
358
407
|
// Convert to JS arguments
|
|
@@ -432,6 +481,10 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
|
|
|
432
481
|
|
|
433
482
|
Napi::Value arg = str ? Napi::String::New(env, str) : env.Null();
|
|
434
483
|
arguments.Append(arg);
|
|
484
|
+
|
|
485
|
+
if (param.type->dispose) {
|
|
486
|
+
param.type->dispose(env, param.type, str);
|
|
487
|
+
}
|
|
435
488
|
} break;
|
|
436
489
|
case PrimitiveKind::String16: {
|
|
437
490
|
const char16_t *str16 = *(const char16_t **)(j < 4 ? gpr_ptr + j : args_ptr);
|
|
@@ -439,6 +492,10 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
|
|
|
439
492
|
|
|
440
493
|
Napi::Value arg = str16 ? Napi::String::New(env, str16) : env.Null();
|
|
441
494
|
arguments.Append(arg);
|
|
495
|
+
|
|
496
|
+
if (param.type->dispose) {
|
|
497
|
+
param.type->dispose(env, param.type, str16);
|
|
498
|
+
}
|
|
442
499
|
} break;
|
|
443
500
|
case PrimitiveKind::Pointer:
|
|
444
501
|
case PrimitiveKind::Callback: {
|
|
@@ -447,12 +504,16 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
|
|
|
447
504
|
|
|
448
505
|
if (ptr2) {
|
|
449
506
|
Napi::External<void> external = Napi::External<void>::New(env, ptr2);
|
|
450
|
-
SetValueTag(instance, external, param.type);
|
|
507
|
+
SetValueTag(instance, external, param.type->ref.marker);
|
|
451
508
|
|
|
452
509
|
arguments.Append(external);
|
|
453
510
|
} else {
|
|
454
511
|
arguments.Append(env.Null());
|
|
455
512
|
}
|
|
513
|
+
|
|
514
|
+
if (param.type->dispose) {
|
|
515
|
+
param.type->dispose(env, param.type, ptr2);
|
|
516
|
+
}
|
|
456
517
|
} break;
|
|
457
518
|
case PrimitiveKind::Record: {
|
|
458
519
|
uint8_t *ptr;
|
|
@@ -481,6 +542,8 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
|
|
|
481
542
|
Napi::Value arg = Napi::Number::New(env, d);
|
|
482
543
|
arguments.Append(arg);
|
|
483
544
|
} break;
|
|
545
|
+
|
|
546
|
+
case PrimitiveKind::Prototype: { RG_UNREACHABLE(); } break;
|
|
484
547
|
}
|
|
485
548
|
}
|
|
486
549
|
|
|
@@ -491,6 +554,9 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
|
|
|
491
554
|
[](Napi::Function *func, size_t argc, napi_value *argv) { return (napi_value)func->Call(argc, argv); });
|
|
492
555
|
Napi::Value value(env, ret);
|
|
493
556
|
|
|
557
|
+
if (RG_UNLIKELY(env.IsExceptionPending()))
|
|
558
|
+
return;
|
|
559
|
+
|
|
494
560
|
switch (type->primitive) {
|
|
495
561
|
case PrimitiveKind::Void: {} break;
|
|
496
562
|
case PrimitiveKind::Bool: {
|
|
@@ -551,14 +617,14 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
|
|
|
551
617
|
case PrimitiveKind::Pointer: {
|
|
552
618
|
uint8_t *ptr;
|
|
553
619
|
|
|
554
|
-
if (CheckValueTag(instance, value, type)) {
|
|
620
|
+
if (CheckValueTag(instance, value, type->ref.marker)) {
|
|
555
621
|
ptr = value.As<Napi::External<uint8_t>>().Data();
|
|
556
|
-
} else if (IsObject(value) && type->ref->primitive == PrimitiveKind::Record) {
|
|
622
|
+
} else if (IsObject(value) && type->ref.type->primitive == PrimitiveKind::Record) {
|
|
557
623
|
Napi::Object obj = value.As<Napi::Object>();
|
|
558
624
|
|
|
559
|
-
ptr = AllocHeap(type->ref->size, 16);
|
|
625
|
+
ptr = AllocHeap(type->ref.type->size, 16);
|
|
560
626
|
|
|
561
|
-
if (!PushObject(obj, type->ref, ptr))
|
|
627
|
+
if (!PushObject(obj, type->ref.type, ptr))
|
|
562
628
|
return;
|
|
563
629
|
} else if (IsNullOrUndefined(value)) {
|
|
564
630
|
ptr = nullptr;
|
|
@@ -612,10 +678,10 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
|
|
|
612
678
|
if (value.IsFunction()) {
|
|
613
679
|
Napi::Function func2 = value.As<Napi::Function>();
|
|
614
680
|
|
|
615
|
-
ptr = ReserveTrampoline(type->proto, func2);
|
|
681
|
+
ptr = ReserveTrampoline(type->ref.proto, func2);
|
|
616
682
|
if (RG_UNLIKELY(!ptr))
|
|
617
683
|
return;
|
|
618
|
-
} else if (CheckValueTag(instance, value, type)) {
|
|
684
|
+
} else if (CheckValueTag(instance, value, type->ref.marker)) {
|
|
619
685
|
ptr = value.As<Napi::External<uint8_t>>().Data();
|
|
620
686
|
} else if (IsNullOrUndefined(value)) {
|
|
621
687
|
ptr = nullptr;
|
|
@@ -626,7 +692,11 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
|
|
|
626
692
|
|
|
627
693
|
out_reg->rax = (uint64_t)ptr;
|
|
628
694
|
} break;
|
|
695
|
+
|
|
696
|
+
case PrimitiveKind::Prototype: { RG_UNREACHABLE(); } break;
|
|
629
697
|
}
|
|
698
|
+
|
|
699
|
+
err_guard.Disable();
|
|
630
700
|
}
|
|
631
701
|
|
|
632
702
|
void *GetTrampoline(Size idx, const FunctionInfo *proto)
|