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.
- package/CMakeLists.txt +7 -2
- package/ChangeLog.md +52 -14
- 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 +9 -7
- 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 +20 -42
- package/src/util.cc +117 -27
- package/src/util.hh +3 -2
- package/test/callbacks.js +54 -8
- package/test/misc.c +30 -15
- package/test/raylib.js +1 -1
- package/test/sqlite.js +24 -16
- package/test/sync.js +43 -33
- package/vendor/libcc/libcc.cc +18 -5
- package/vendor/libcc/libcc.hh +70 -23
- package/build/qemu/1.3.10/koffi_darwin_arm64.tar.gz +0 -0
- package/build/qemu/1.3.10/koffi_darwin_x64.tar.gz +0 -0
- package/build/qemu/1.3.10/koffi_freebsd_arm64.tar.gz +0 -0
- package/build/qemu/1.3.10/koffi_freebsd_ia32.tar.gz +0 -0
- package/build/qemu/1.3.10/koffi_freebsd_x64.tar.gz +0 -0
- package/build/qemu/1.3.10/koffi_linux_arm32hf.tar.gz +0 -0
- package/build/qemu/1.3.10/koffi_linux_arm64.tar.gz +0 -0
- package/build/qemu/1.3.10/koffi_linux_ia32.tar.gz +0 -0
- package/build/qemu/1.3.10/koffi_linux_riscv64hf64.tar.gz +0 -0
- package/build/qemu/1.3.10/koffi_linux_x64.tar.gz +0 -0
- package/build/qemu/1.3.10/koffi_openbsd_ia32.tar.gz +0 -0
- package/build/qemu/1.3.10/koffi_openbsd_x64.tar.gz +0 -0
- package/build/qemu/1.3.10/koffi_win32_arm64.tar.gz +0 -0
- package/build/qemu/1.3.10/koffi_win32_ia32.tar.gz +0 -0
- package/build/qemu/1.3.10/koffi_win32_x64.tar.gz +0 -0
package/src/abi_riscv64.cc
CHANGED
|
@@ -74,6 +74,22 @@ extern "C" int Trampoline12; extern "C" int TrampolineX12;
|
|
|
74
74
|
extern "C" int Trampoline13; extern "C" int TrampolineX13;
|
|
75
75
|
extern "C" int Trampoline14; extern "C" int TrampolineX14;
|
|
76
76
|
extern "C" int Trampoline15; extern "C" int TrampolineX15;
|
|
77
|
+
extern "C" int Trampoline16; extern "C" int TrampolineX16;
|
|
78
|
+
extern "C" int Trampoline17; extern "C" int TrampolineX17;
|
|
79
|
+
extern "C" int Trampoline18; extern "C" int TrampolineX18;
|
|
80
|
+
extern "C" int Trampoline19; extern "C" int TrampolineX19;
|
|
81
|
+
extern "C" int Trampoline20; extern "C" int TrampolineX20;
|
|
82
|
+
extern "C" int Trampoline21; extern "C" int TrampolineX21;
|
|
83
|
+
extern "C" int Trampoline22; extern "C" int TrampolineX22;
|
|
84
|
+
extern "C" int Trampoline23; extern "C" int TrampolineX23;
|
|
85
|
+
extern "C" int Trampoline24; extern "C" int TrampolineX24;
|
|
86
|
+
extern "C" int Trampoline25; extern "C" int TrampolineX25;
|
|
87
|
+
extern "C" int Trampoline26; extern "C" int TrampolineX26;
|
|
88
|
+
extern "C" int Trampoline27; extern "C" int TrampolineX27;
|
|
89
|
+
extern "C" int Trampoline28; extern "C" int TrampolineX28;
|
|
90
|
+
extern "C" int Trampoline29; extern "C" int TrampolineX29;
|
|
91
|
+
extern "C" int Trampoline30; extern "C" int TrampolineX30;
|
|
92
|
+
extern "C" int Trampoline31; extern "C" int TrampolineX31;
|
|
77
93
|
|
|
78
94
|
extern "C" napi_value CallSwitchStack(Napi::Function *func, size_t argc, napi_value *argv,
|
|
79
95
|
uint8_t *old_sp, Span<uint8_t> *new_stack,
|
|
@@ -95,9 +111,25 @@ static void *const Trampolines[][2] = {
|
|
|
95
111
|
{ &Trampoline12, &TrampolineX12 },
|
|
96
112
|
{ &Trampoline13, &TrampolineX13 },
|
|
97
113
|
{ &Trampoline14, &TrampolineX14 },
|
|
98
|
-
{ &Trampoline15, &TrampolineX15 }
|
|
114
|
+
{ &Trampoline15, &TrampolineX15 },
|
|
115
|
+
{ &Trampoline16, &TrampolineX16 },
|
|
116
|
+
{ &Trampoline17, &TrampolineX17 },
|
|
117
|
+
{ &Trampoline18, &TrampolineX18 },
|
|
118
|
+
{ &Trampoline19, &TrampolineX19 },
|
|
119
|
+
{ &Trampoline20, &TrampolineX20 },
|
|
120
|
+
{ &Trampoline21, &TrampolineX21 },
|
|
121
|
+
{ &Trampoline22, &TrampolineX22 },
|
|
122
|
+
{ &Trampoline23, &TrampolineX23 },
|
|
123
|
+
{ &Trampoline24, &TrampolineX24 },
|
|
124
|
+
{ &Trampoline25, &TrampolineX25 },
|
|
125
|
+
{ &Trampoline26, &TrampolineX26 },
|
|
126
|
+
{ &Trampoline27, &TrampolineX27 },
|
|
127
|
+
{ &Trampoline28, &TrampolineX28 },
|
|
128
|
+
{ &Trampoline29, &TrampolineX29 },
|
|
129
|
+
{ &Trampoline30, &TrampolineX30 },
|
|
130
|
+
{ &Trampoline31, &TrampolineX31 }
|
|
99
131
|
};
|
|
100
|
-
RG_STATIC_ASSERT(RG_LEN(Trampolines) == MaxTrampolines);
|
|
132
|
+
RG_STATIC_ASSERT(RG_LEN(Trampolines) == MaxTrampolines * 2);
|
|
101
133
|
|
|
102
134
|
static RG_THREAD_LOCAL CallData *exec_call;
|
|
103
135
|
|
|
@@ -354,10 +386,10 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
|
|
|
354
386
|
if (value.IsFunction()) {
|
|
355
387
|
Napi::Function func = value.As<Napi::Function>();
|
|
356
388
|
|
|
357
|
-
ptr = ReserveTrampoline(param.type->proto, func);
|
|
389
|
+
ptr = ReserveTrampoline(param.type->ref.proto, func);
|
|
358
390
|
if (RG_UNLIKELY(!ptr))
|
|
359
391
|
return false;
|
|
360
|
-
} else if (CheckValueTag(instance, value, param.type)) {
|
|
392
|
+
} else if (CheckValueTag(instance, value, param.type->ref.marker)) {
|
|
361
393
|
ptr = value.As<Napi::External<void>>().Data();
|
|
362
394
|
} else if (IsNullOrUndefined(value)) {
|
|
363
395
|
ptr = nullptr;
|
|
@@ -368,6 +400,8 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
|
|
|
368
400
|
|
|
369
401
|
*(void **)((param.gpr_count ? gpr_ptr : args_ptr)++) = ptr;
|
|
370
402
|
} break;
|
|
403
|
+
|
|
404
|
+
case PrimitiveKind::Prototype: { RG_UNREACHABLE(); } break;
|
|
371
405
|
}
|
|
372
406
|
}
|
|
373
407
|
|
|
@@ -421,6 +455,8 @@ void CallData::Execute()
|
|
|
421
455
|
case PrimitiveKind::Array: { RG_UNREACHABLE(); } break;
|
|
422
456
|
case PrimitiveKind::Float32: { result.f = PERFORM_CALL(F); } break;
|
|
423
457
|
case PrimitiveKind::Float64: { result.d = PERFORM_CALL(DD).fa0; } break;
|
|
458
|
+
|
|
459
|
+
case PrimitiveKind::Prototype: { RG_UNREACHABLE(); } break;
|
|
424
460
|
}
|
|
425
461
|
|
|
426
462
|
#undef PERFORM_CALL
|
|
@@ -428,7 +464,13 @@ void CallData::Execute()
|
|
|
428
464
|
|
|
429
465
|
Napi::Value CallData::Complete()
|
|
430
466
|
{
|
|
431
|
-
|
|
467
|
+
RG_DEFER {
|
|
468
|
+
PopOutArguments();
|
|
469
|
+
|
|
470
|
+
if (func->ret.type->dispose) {
|
|
471
|
+
func->ret.type->dispose(env, func->ret.type, result.ptr);
|
|
472
|
+
}
|
|
473
|
+
};
|
|
432
474
|
|
|
433
475
|
switch (func->ret.type->primitive) {
|
|
434
476
|
case PrimitiveKind::Void: return env.Null();
|
|
@@ -447,7 +489,7 @@ Napi::Value CallData::Complete()
|
|
|
447
489
|
case PrimitiveKind::Callback: {
|
|
448
490
|
if (result.ptr) {
|
|
449
491
|
Napi::External<void> external = Napi::External<void>::New(env, result.ptr);
|
|
450
|
-
SetValueTag(instance, external, func->ret.type);
|
|
492
|
+
SetValueTag(instance, external, func->ret.type->ref.marker);
|
|
451
493
|
|
|
452
494
|
return external;
|
|
453
495
|
} else {
|
|
@@ -469,6 +511,8 @@ Napi::Value CallData::Complete()
|
|
|
469
511
|
case PrimitiveKind::Array: { RG_UNREACHABLE(); } break;
|
|
470
512
|
case PrimitiveKind::Float32: return Napi::Number::New(env, (double)result.f);
|
|
471
513
|
case PrimitiveKind::Float64: return Napi::Number::New(env, result.d);
|
|
514
|
+
|
|
515
|
+
case PrimitiveKind::Prototype: { RG_UNREACHABLE(); } break;
|
|
472
516
|
}
|
|
473
517
|
|
|
474
518
|
RG_UNREACHABLE();
|
|
@@ -476,12 +520,10 @@ Napi::Value CallData::Complete()
|
|
|
476
520
|
|
|
477
521
|
void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegisters *out_reg)
|
|
478
522
|
{
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
if (RG_UNLIKELY(trampoline.generation != mem->generation)) {
|
|
482
|
-
ThrowError<Napi::Error>(env, "Cannot use non-persistent callback beyond FFI call");
|
|
523
|
+
if (RG_UNLIKELY(env.IsExceptionPending()))
|
|
483
524
|
return;
|
|
484
|
-
|
|
525
|
+
|
|
526
|
+
const TrampolineInfo &trampoline = instance->trampolines[idx];
|
|
485
527
|
|
|
486
528
|
const FunctionInfo *proto = trampoline.proto;
|
|
487
529
|
Napi::Function func = trampoline.func.Value();
|
|
@@ -493,6 +535,13 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
|
|
|
493
535
|
uint8_t *return_ptr = proto->ret.use_memory ? (uint8_t *)gpr_ptr[0] : nullptr;
|
|
494
536
|
gpr_ptr += proto->ret.use_memory;
|
|
495
537
|
|
|
538
|
+
RG_DEFER_N(err_guard) { memset(out_reg, 0, RG_SIZE(*out_reg)); };
|
|
539
|
+
|
|
540
|
+
if (RG_UNLIKELY(trampoline.generation >= 0 && trampoline.generation != (int32_t)mem->generation)) {
|
|
541
|
+
ThrowError<Napi::Error>(env, "Cannot use non-registered callback beyond FFI call");
|
|
542
|
+
return;
|
|
543
|
+
}
|
|
544
|
+
|
|
496
545
|
LocalArray<napi_value, MaxParameters> arguments;
|
|
497
546
|
|
|
498
547
|
// Convert to JS arguments
|
|
@@ -562,12 +611,20 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
|
|
|
562
611
|
|
|
563
612
|
Napi::Value arg = str ? Napi::String::New(env, str) : env.Null();
|
|
564
613
|
arguments.Append(arg);
|
|
614
|
+
|
|
615
|
+
if (param.type->dispose) {
|
|
616
|
+
param.type->dispose(env, param.type, str);
|
|
617
|
+
}
|
|
565
618
|
} break;
|
|
566
619
|
case PrimitiveKind::String16: {
|
|
567
620
|
const char16_t *str16 = *(const char16_t **)((param.gpr_count ? gpr_ptr : args_ptr)++);
|
|
568
621
|
|
|
569
622
|
Napi::Value arg = str16 ? Napi::String::New(env, str16) : env.Null();
|
|
570
623
|
arguments.Append(arg);
|
|
624
|
+
|
|
625
|
+
if (param.type->dispose) {
|
|
626
|
+
param.type->dispose(env, param.type, str16);
|
|
627
|
+
}
|
|
571
628
|
} break;
|
|
572
629
|
case PrimitiveKind::Pointer:
|
|
573
630
|
case PrimitiveKind::Callback: {
|
|
@@ -575,12 +632,16 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
|
|
|
575
632
|
|
|
576
633
|
if (ptr2) {
|
|
577
634
|
Napi::External<void> external = Napi::External<void>::New(env, ptr2);
|
|
578
|
-
SetValueTag(instance, external, param.type);
|
|
635
|
+
SetValueTag(instance, external, param.type->ref.marker);
|
|
579
636
|
|
|
580
637
|
arguments.Append(external);
|
|
581
638
|
} else {
|
|
582
639
|
arguments.Append(env.Null());
|
|
583
640
|
}
|
|
641
|
+
|
|
642
|
+
if (param.type->dispose) {
|
|
643
|
+
param.type->dispose(env, param.type, ptr2);
|
|
644
|
+
}
|
|
584
645
|
} break;
|
|
585
646
|
case PrimitiveKind::Record: {
|
|
586
647
|
if (!param.use_memory) {
|
|
@@ -640,6 +701,8 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
|
|
|
640
701
|
Napi::Value arg = Napi::Number::New(env, d);
|
|
641
702
|
arguments.Append(arg);
|
|
642
703
|
} break;
|
|
704
|
+
|
|
705
|
+
case PrimitiveKind::Prototype: { RG_UNREACHABLE(); } break;
|
|
643
706
|
}
|
|
644
707
|
}
|
|
645
708
|
|
|
@@ -650,6 +713,9 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
|
|
|
650
713
|
[](Napi::Function *func, size_t argc, napi_value *argv) { return (napi_value)func->Call(argc, argv); });
|
|
651
714
|
Napi::Value value(env, ret);
|
|
652
715
|
|
|
716
|
+
if (RG_UNLIKELY(env.IsExceptionPending()))
|
|
717
|
+
return;
|
|
718
|
+
|
|
653
719
|
// Convert the result
|
|
654
720
|
switch (type->primitive) {
|
|
655
721
|
case PrimitiveKind::Void: {} break;
|
|
@@ -711,14 +777,14 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
|
|
|
711
777
|
case PrimitiveKind::Pointer: {
|
|
712
778
|
uint8_t *ptr;
|
|
713
779
|
|
|
714
|
-
if (CheckValueTag(instance, value, type)) {
|
|
780
|
+
if (CheckValueTag(instance, value, type->ref.marker)) {
|
|
715
781
|
ptr = value.As<Napi::External<uint8_t>>().Data();
|
|
716
|
-
} else if (IsObject(value) && type->ref->primitive == PrimitiveKind::Record) {
|
|
782
|
+
} else if (IsObject(value) && type->ref.type->primitive == PrimitiveKind::Record) {
|
|
717
783
|
Napi::Object obj = value.As<Napi::Object>();
|
|
718
784
|
|
|
719
|
-
ptr = AllocHeap(type->ref->size, 16);
|
|
785
|
+
ptr = AllocHeap(type->ref.type->size, 16);
|
|
720
786
|
|
|
721
|
-
if (!PushObject(obj, type->ref, ptr))
|
|
787
|
+
if (!PushObject(obj, type->ref.type, ptr))
|
|
722
788
|
return;
|
|
723
789
|
} else if (IsNullOrUndefined(value)) {
|
|
724
790
|
ptr = nullptr;
|
|
@@ -773,10 +839,10 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
|
|
|
773
839
|
if (value.IsFunction()) {
|
|
774
840
|
Napi::Function func2 = value.As<Napi::Function>();
|
|
775
841
|
|
|
776
|
-
ptr = ReserveTrampoline(type->proto, func2);
|
|
842
|
+
ptr = ReserveTrampoline(type->ref.proto, func2);
|
|
777
843
|
if (RG_UNLIKELY(!ptr))
|
|
778
844
|
return;
|
|
779
|
-
} else if (CheckValueTag(instance, value, type)) {
|
|
845
|
+
} else if (CheckValueTag(instance, value, type->ref.marker)) {
|
|
780
846
|
ptr = value.As<Napi::External<uint8_t>>().Data();
|
|
781
847
|
} else if (IsNullOrUndefined(value)) {
|
|
782
848
|
ptr = nullptr;
|
|
@@ -787,7 +853,11 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
|
|
|
787
853
|
|
|
788
854
|
out_reg->a0 = (uint64_t)ptr;
|
|
789
855
|
} break;
|
|
856
|
+
|
|
857
|
+
case PrimitiveKind::Prototype: { RG_UNREACHABLE(); } break;
|
|
790
858
|
}
|
|
859
|
+
|
|
860
|
+
err_guard.Disable();
|
|
791
861
|
}
|
|
792
862
|
|
|
793
863
|
void *GetTrampoline(Size idx, const FunctionInfo *proto)
|
package/src/abi_riscv64_fwd.S
CHANGED
|
@@ -152,6 +152,22 @@ ForwardCallXDD:
|
|
|
152
152
|
.global Trampoline13
|
|
153
153
|
.global Trampoline14
|
|
154
154
|
.global Trampoline15
|
|
155
|
+
.global Trampoline16
|
|
156
|
+
.global Trampoline17
|
|
157
|
+
.global Trampoline18
|
|
158
|
+
.global Trampoline19
|
|
159
|
+
.global Trampoline20
|
|
160
|
+
.global Trampoline21
|
|
161
|
+
.global Trampoline22
|
|
162
|
+
.global Trampoline23
|
|
163
|
+
.global Trampoline24
|
|
164
|
+
.global Trampoline25
|
|
165
|
+
.global Trampoline26
|
|
166
|
+
.global Trampoline27
|
|
167
|
+
.global Trampoline28
|
|
168
|
+
.global Trampoline29
|
|
169
|
+
.global Trampoline30
|
|
170
|
+
.global Trampoline31
|
|
155
171
|
.global TrampolineX0
|
|
156
172
|
.global TrampolineX1
|
|
157
173
|
.global TrampolineX2
|
|
@@ -168,6 +184,22 @@ ForwardCallXDD:
|
|
|
168
184
|
.global TrampolineX13
|
|
169
185
|
.global TrampolineX14
|
|
170
186
|
.global TrampolineX15
|
|
187
|
+
.global TrampolineX16
|
|
188
|
+
.global TrampolineX17
|
|
189
|
+
.global TrampolineX18
|
|
190
|
+
.global TrampolineX19
|
|
191
|
+
.global TrampolineX20
|
|
192
|
+
.global TrampolineX21
|
|
193
|
+
.global TrampolineX22
|
|
194
|
+
.global TrampolineX23
|
|
195
|
+
.global TrampolineX24
|
|
196
|
+
.global TrampolineX25
|
|
197
|
+
.global TrampolineX26
|
|
198
|
+
.global TrampolineX27
|
|
199
|
+
.global TrampolineX28
|
|
200
|
+
.global TrampolineX29
|
|
201
|
+
.global TrampolineX30
|
|
202
|
+
.global TrampolineX31
|
|
171
203
|
.global RelayCallback
|
|
172
204
|
.global CallSwitchStack
|
|
173
205
|
|
|
@@ -265,6 +297,38 @@ Trampoline14:
|
|
|
265
297
|
trampoline 14
|
|
266
298
|
Trampoline15:
|
|
267
299
|
trampoline 15
|
|
300
|
+
Trampoline16:
|
|
301
|
+
trampoline 16
|
|
302
|
+
Trampoline17:
|
|
303
|
+
trampoline 17
|
|
304
|
+
Trampoline18:
|
|
305
|
+
trampoline 18
|
|
306
|
+
Trampoline19:
|
|
307
|
+
trampoline 19
|
|
308
|
+
Trampoline20:
|
|
309
|
+
trampoline 20
|
|
310
|
+
Trampoline21:
|
|
311
|
+
trampoline 21
|
|
312
|
+
Trampoline22:
|
|
313
|
+
trampoline 22
|
|
314
|
+
Trampoline23:
|
|
315
|
+
trampoline 23
|
|
316
|
+
Trampoline24:
|
|
317
|
+
trampoline 24
|
|
318
|
+
Trampoline25:
|
|
319
|
+
trampoline 25
|
|
320
|
+
Trampoline26:
|
|
321
|
+
trampoline 26
|
|
322
|
+
Trampoline27:
|
|
323
|
+
trampoline 27
|
|
324
|
+
Trampoline28:
|
|
325
|
+
trampoline 28
|
|
326
|
+
Trampoline29:
|
|
327
|
+
trampoline 29
|
|
328
|
+
Trampoline30:
|
|
329
|
+
trampoline 30
|
|
330
|
+
Trampoline31:
|
|
331
|
+
trampoline 31
|
|
268
332
|
|
|
269
333
|
TrampolineX0:
|
|
270
334
|
trampoline_vec 0
|
|
@@ -298,6 +362,38 @@ TrampolineX14:
|
|
|
298
362
|
trampoline_vec 14
|
|
299
363
|
TrampolineX15:
|
|
300
364
|
trampoline_vec 15
|
|
365
|
+
TrampolineX16:
|
|
366
|
+
trampoline_vec 16
|
|
367
|
+
TrampolineX17:
|
|
368
|
+
trampoline_vec 17
|
|
369
|
+
TrampolineX18:
|
|
370
|
+
trampoline_vec 18
|
|
371
|
+
TrampolineX19:
|
|
372
|
+
trampoline_vec 19
|
|
373
|
+
TrampolineX20:
|
|
374
|
+
trampoline_vec 20
|
|
375
|
+
TrampolineX21:
|
|
376
|
+
trampoline_vec 21
|
|
377
|
+
TrampolineX22:
|
|
378
|
+
trampoline_vec 22
|
|
379
|
+
TrampolineX23:
|
|
380
|
+
trampoline_vec 23
|
|
381
|
+
TrampolineX24:
|
|
382
|
+
trampoline_vec 24
|
|
383
|
+
TrampolineX25:
|
|
384
|
+
trampoline_vec 25
|
|
385
|
+
TrampolineX26:
|
|
386
|
+
trampoline_vec 26
|
|
387
|
+
TrampolineX27:
|
|
388
|
+
trampoline_vec 27
|
|
389
|
+
TrampolineX28:
|
|
390
|
+
trampoline_vec 28
|
|
391
|
+
TrampolineX29:
|
|
392
|
+
trampoline_vec 29
|
|
393
|
+
TrampolineX30:
|
|
394
|
+
trampoline_vec 30
|
|
395
|
+
TrampolineX31:
|
|
396
|
+
trampoline_vec 31
|
|
301
397
|
|
|
302
398
|
# When a callback is relayed, Koffi will call into Node.js and V8 to execute Javascript.
|
|
303
399
|
# The problem is that we're still running on the separate Koffi stack, and V8 will
|
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,7 +522,13 @@ 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
534
|
case PrimitiveKind::Void: return env.Null();
|
|
@@ -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)
|