koffi 2.16.0 → 2.16.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/CHANGELOG.md +8 -1
- package/build/koffi/darwin_arm64/koffi.node +0 -0
- package/build/koffi/darwin_x64/koffi.node +0 -0
- package/build/koffi/freebsd_arm64/koffi.node +0 -0
- package/build/koffi/freebsd_ia32/koffi.node +0 -0
- package/build/koffi/freebsd_x64/koffi.node +0 -0
- package/build/koffi/linux_arm64/koffi.node +0 -0
- package/build/koffi/linux_armhf/koffi.node +0 -0
- package/build/koffi/linux_ia32/koffi.node +0 -0
- package/build/koffi/linux_loong64/koffi.node +0 -0
- package/build/koffi/linux_riscv64d/koffi.node +0 -0
- package/build/koffi/linux_x64/koffi.node +0 -0
- package/build/koffi/musl_arm64/koffi.node +0 -0
- package/build/koffi/musl_x64/koffi.node +0 -0
- package/build/koffi/openbsd_ia32/koffi.node +0 -0
- package/build/koffi/openbsd_x64/koffi.node +0 -0
- package/build/koffi/win32_arm64/koffi.node +0 -0
- package/build/koffi/win32_ia32/koffi.node +0 -0
- package/build/koffi/win32_x64/koffi.node +0 -0
- package/index.js +1 -1
- package/indirect.js +1 -1
- package/package.json +1 -1
- package/src/koffi/src/abi_arm32.cc +2 -10
- package/src/koffi/src/abi_arm64.cc +2 -28
- package/src/koffi/src/abi_loong64_asm.S +2 -2
- package/src/koffi/src/abi_riscv64.cc +2 -10
- package/src/koffi/src/abi_riscv64_asm.S +2 -2
- package/src/koffi/src/abi_x64_sysv.cc +2 -10
- package/src/koffi/src/abi_x64_win.cc +2 -26
- package/src/koffi/src/abi_x64_win_asm.S +2 -2
- package/src/koffi/src/abi_x86.cc +2 -28
- package/src/koffi/src/abi_x86_asm.S +4 -2
- package/src/koffi/src/abi_x86_asm.asm +2 -0
- package/src/koffi/src/call.cc +2 -3
- package/src/koffi/src/ffi.cc +32 -5
- package/src/koffi/src/ffi.hh +1 -3
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,13 @@
|
|
|
7
7
|
|
|
8
8
|
### Koffi 2.16
|
|
9
9
|
|
|
10
|
+
#### Koffi 2.16.1
|
|
11
|
+
|
|
12
|
+
*Released on 2026-04-17*
|
|
13
|
+
|
|
14
|
+
- Fix possible stack check crash when relaying callbacks on Windows
|
|
15
|
+
- Improve exception handling inside callbacks
|
|
16
|
+
|
|
10
17
|
#### Koffi 2.16.0
|
|
11
18
|
|
|
12
19
|
*Released on 2026-04-14*
|
|
@@ -14,7 +21,7 @@
|
|
|
14
21
|
- Support buffers and typed arrays in `koffi.address()`
|
|
15
22
|
- Put x86 SEH record at the top of stack frame
|
|
16
23
|
- Optimize Koffi binaries produced by GCC (with `-fno-semantic-interposition`)
|
|
17
|
-
- Fix nonsensical addresses in Koffi call dumps (when using DUMP_CALLS=1
|
|
24
|
+
- Fix nonsensical addresses in Koffi call dumps (when using DUMP_CALLS=1 environment variable)
|
|
18
25
|
|
|
19
26
|
- Reduce Koffi package size even more:
|
|
20
27
|
* Replace table of callback trampoline pointers with simple offset computation
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/index.js
CHANGED
|
@@ -398,7 +398,7 @@ var require_package = __commonJS({
|
|
|
398
398
|
"../../bin/Koffi/package/src/koffi/package.json"(exports2, module2) {
|
|
399
399
|
module2.exports = {
|
|
400
400
|
name: "koffi",
|
|
401
|
-
version: "2.16.
|
|
401
|
+
version: "2.16.1",
|
|
402
402
|
description: "Fast and simple C FFI (foreign function interface) for Node.js",
|
|
403
403
|
keywords: [
|
|
404
404
|
"foreign",
|
package/indirect.js
CHANGED
|
@@ -398,7 +398,7 @@ var require_package = __commonJS({
|
|
|
398
398
|
"../../bin/Koffi/package/src/koffi/package.json"(exports2, module2) {
|
|
399
399
|
module2.exports = {
|
|
400
400
|
name: "koffi",
|
|
401
|
-
version: "2.16.
|
|
401
|
+
version: "2.16.1",
|
|
402
402
|
description: "Fast and simple C FFI (foreign function interface) for Node.js",
|
|
403
403
|
keywords: [
|
|
404
404
|
"foreign",
|
package/package.json
CHANGED
|
@@ -544,15 +544,12 @@ Napi::Value CallData::Complete(const FunctionInfo *func)
|
|
|
544
544
|
|
|
545
545
|
void CallData::Relay(Size idx, uint8_t *sp)
|
|
546
546
|
{
|
|
547
|
+
const TrampolineInfo &trampoline = shared.trampolines[idx];
|
|
548
|
+
|
|
547
549
|
uint8_t *own_sp = sp;
|
|
548
550
|
uint8_t *caller_sp = sp + 128;
|
|
549
551
|
BackRegisters *out_reg = (BackRegisters *)(sp + 80);
|
|
550
552
|
|
|
551
|
-
if (env.IsExceptionPending()) [[unlikely]]
|
|
552
|
-
return;
|
|
553
|
-
|
|
554
|
-
const TrampolineInfo &trampoline = shared.trampolines[idx];
|
|
555
|
-
|
|
556
553
|
const FunctionInfo *proto = trampoline.proto;
|
|
557
554
|
Napi::Function func = trampoline.func.Value();
|
|
558
555
|
|
|
@@ -565,11 +562,6 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
565
562
|
|
|
566
563
|
K_DEFER_N(err_guard) { memset(out_reg, 0, K_SIZE(*out_reg)); };
|
|
567
564
|
|
|
568
|
-
if (trampoline.generation >= 0 && trampoline.generation != (int32_t)mem->generation) [[unlikely]] {
|
|
569
|
-
ThrowError<Napi::Error>(env, "Cannot use non-registered callback beyond FFI call");
|
|
570
|
-
return;
|
|
571
|
-
}
|
|
572
|
-
|
|
573
565
|
LocalArray<napi_value, MaxParameters + 1> arguments;
|
|
574
566
|
|
|
575
567
|
arguments.Append(!trampoline.recv.IsEmpty() ? trampoline.recv.Value() : env.Undefined());
|
|
@@ -693,33 +693,12 @@ Napi::Value CallData::Complete(const FunctionInfo *func)
|
|
|
693
693
|
|
|
694
694
|
void CallData::Relay(Size idx, uint8_t *sp)
|
|
695
695
|
{
|
|
696
|
+
const TrampolineInfo &trampoline = shared.trampolines[idx];
|
|
697
|
+
|
|
696
698
|
uint8_t *own_sp = sp;
|
|
697
699
|
uint8_t *caller_sp = sp + 208;
|
|
698
700
|
BackRegisters *out_reg = (BackRegisters *)(sp + 136);
|
|
699
701
|
|
|
700
|
-
if (env.IsExceptionPending()) [[unlikely]]
|
|
701
|
-
return;
|
|
702
|
-
|
|
703
|
-
#if defined(_WIN32)
|
|
704
|
-
TEB *teb = GetTEB();
|
|
705
|
-
|
|
706
|
-
// Restore previous stack limits at the end
|
|
707
|
-
K_DEFER_C(base = teb->StackBase,
|
|
708
|
-
limit = teb->StackLimit,
|
|
709
|
-
dealloc = teb->DeallocationStack) {
|
|
710
|
-
teb->StackBase = base;
|
|
711
|
-
teb->StackLimit = limit;
|
|
712
|
-
teb->DeallocationStack = dealloc;
|
|
713
|
-
};
|
|
714
|
-
|
|
715
|
-
// Adjust stack limits so SEH works correctly
|
|
716
|
-
teb->StackBase = instance->main_stack_max;
|
|
717
|
-
teb->StackLimit = instance->main_stack_min;
|
|
718
|
-
teb->DeallocationStack = instance->main_stack_min;
|
|
719
|
-
#endif
|
|
720
|
-
|
|
721
|
-
const TrampolineInfo &trampoline = shared.trampolines[idx];
|
|
722
|
-
|
|
723
702
|
const FunctionInfo *proto = trampoline.proto;
|
|
724
703
|
Napi::Function func = trampoline.func.Value();
|
|
725
704
|
|
|
@@ -731,11 +710,6 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
731
710
|
|
|
732
711
|
K_DEFER_N(err_guard) { memset(out_reg, 0, K_SIZE(*out_reg)); };
|
|
733
712
|
|
|
734
|
-
if (trampoline.generation >= 0 && trampoline.generation != (int32_t)mem->generation) [[unlikely]] {
|
|
735
|
-
ThrowError<Napi::Error>(env, "Cannot use non-registered callback beyond FFI call");
|
|
736
|
-
return;
|
|
737
|
-
}
|
|
738
|
-
|
|
739
713
|
LocalArray<napi_value, MaxParameters + 1> arguments;
|
|
740
714
|
|
|
741
715
|
arguments.Append(!trampoline.recv.IsEmpty() ? trampoline.recv.Value() : env.Undefined());
|
|
@@ -141,7 +141,7 @@ ForwardCallXDD:
|
|
|
141
141
|
.macro trampoline id
|
|
142
142
|
li.d $t0, \id
|
|
143
143
|
b RelayTrampoline
|
|
144
|
-
.
|
|
144
|
+
.balign 16
|
|
145
145
|
.endm
|
|
146
146
|
|
|
147
147
|
RelayTrampoline:
|
|
@@ -197,7 +197,7 @@ SwitchAndRelay:
|
|
|
197
197
|
addi.d $sp, $sp, 16
|
|
198
198
|
jr $ra
|
|
199
199
|
|
|
200
|
-
.
|
|
200
|
+
.balign 16
|
|
201
201
|
#include "gnu.inc"
|
|
202
202
|
|
|
203
203
|
TrampolineEnd:
|
|
@@ -485,15 +485,12 @@ Napi::Value CallData::Complete(const FunctionInfo *func)
|
|
|
485
485
|
|
|
486
486
|
void CallData::Relay(Size idx, uint8_t *sp)
|
|
487
487
|
{
|
|
488
|
+
const TrampolineInfo &trampoline = shared.trampolines[idx];
|
|
489
|
+
|
|
488
490
|
uint8_t *own_sp = sp;
|
|
489
491
|
uint8_t *caller_sp = sp + 168;
|
|
490
492
|
BackRegisters *out_reg = (BackRegisters *)(sp + 128);
|
|
491
493
|
|
|
492
|
-
if (env.IsExceptionPending()) [[unlikely]]
|
|
493
|
-
return;
|
|
494
|
-
|
|
495
|
-
const TrampolineInfo &trampoline = shared.trampolines[idx];
|
|
496
|
-
|
|
497
494
|
const FunctionInfo *proto = trampoline.proto;
|
|
498
495
|
Napi::Function func = trampoline.func.Value();
|
|
499
496
|
|
|
@@ -506,11 +503,6 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
506
503
|
|
|
507
504
|
K_DEFER_N(err_guard) { memset(out_reg, 0, K_SIZE(*out_reg)); };
|
|
508
505
|
|
|
509
|
-
if (trampoline.generation >= 0 && trampoline.generation != (int32_t)mem->generation) [[unlikely]] {
|
|
510
|
-
ThrowError<Napi::Error>(env, "Cannot use non-registered callback beyond FFI call");
|
|
511
|
-
return;
|
|
512
|
-
}
|
|
513
|
-
|
|
514
506
|
LocalArray<napi_value, MaxParameters + 1> arguments;
|
|
515
507
|
|
|
516
508
|
arguments.Append(!trampoline.recv.IsEmpty() ? trampoline.recv.Value() : env.Undefined());
|
|
@@ -141,7 +141,7 @@ ForwardCallXDD:
|
|
|
141
141
|
.macro trampoline id
|
|
142
142
|
li t0, \id
|
|
143
143
|
j RelayTrampoline
|
|
144
|
-
.
|
|
144
|
+
.balign 16
|
|
145
145
|
.endm
|
|
146
146
|
|
|
147
147
|
RelayTrampoline:
|
|
@@ -196,7 +196,7 @@ SwitchAndRelay:
|
|
|
196
196
|
addi sp, sp, 16
|
|
197
197
|
ret
|
|
198
198
|
|
|
199
|
-
.
|
|
199
|
+
.balign 16
|
|
200
200
|
#include "gnu.inc"
|
|
201
201
|
|
|
202
202
|
TrampolineEnd:
|
|
@@ -521,15 +521,12 @@ Napi::Value CallData::Complete(const FunctionInfo *func)
|
|
|
521
521
|
|
|
522
522
|
void CallData::Relay(Size idx, uint8_t *sp)
|
|
523
523
|
{
|
|
524
|
+
const TrampolineInfo &trampoline = shared.trampolines[idx];
|
|
525
|
+
|
|
524
526
|
uint8_t *own_sp = sp;
|
|
525
527
|
uint8_t *caller_sp = sp + 160;
|
|
526
528
|
BackRegisters *out_reg = (BackRegisters *)(sp + 112);
|
|
527
529
|
|
|
528
|
-
if (env.IsExceptionPending()) [[unlikely]]
|
|
529
|
-
return;
|
|
530
|
-
|
|
531
|
-
const TrampolineInfo &trampoline = shared.trampolines[idx];
|
|
532
|
-
|
|
533
530
|
const FunctionInfo *proto = trampoline.proto;
|
|
534
531
|
Napi::Function func = trampoline.func.Value();
|
|
535
532
|
|
|
@@ -542,11 +539,6 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
542
539
|
|
|
543
540
|
K_DEFER_N(err_guard) { memset(out_reg, 0, K_SIZE(*out_reg)); };
|
|
544
541
|
|
|
545
|
-
if (trampoline.generation >= 0 && trampoline.generation != (int32_t)mem->generation) [[unlikely]] {
|
|
546
|
-
ThrowError<Napi::Error>(env, "Cannot use non-registered callback beyond FFI call");
|
|
547
|
-
return;
|
|
548
|
-
}
|
|
549
|
-
|
|
550
542
|
LocalArray<napi_value, MaxParameters + 1> arguments;
|
|
551
543
|
|
|
552
544
|
arguments.Append(!trampoline.recv.IsEmpty() ? trampoline.recv.Value() : env.Undefined());
|
|
@@ -327,31 +327,12 @@ Napi::Value CallData::Complete(const FunctionInfo *func)
|
|
|
327
327
|
|
|
328
328
|
void CallData::Relay(Size idx, uint8_t *sp)
|
|
329
329
|
{
|
|
330
|
+
const TrampolineInfo &trampoline = shared.trampolines[idx];
|
|
331
|
+
|
|
330
332
|
uint8_t *own_sp = sp;
|
|
331
333
|
uint8_t *caller_sp = sp + 128;
|
|
332
334
|
BackRegisters *out_reg = (BackRegisters *)(sp + 64);
|
|
333
335
|
|
|
334
|
-
if (env.IsExceptionPending()) [[unlikely]]
|
|
335
|
-
return;
|
|
336
|
-
|
|
337
|
-
TEB *teb = GetTEB();
|
|
338
|
-
|
|
339
|
-
// Restore previous stack limits at the end
|
|
340
|
-
K_DEFER_C(base = teb->StackBase,
|
|
341
|
-
limit = teb->StackLimit,
|
|
342
|
-
dealloc = teb->DeallocationStack) {
|
|
343
|
-
teb->StackBase = base;
|
|
344
|
-
teb->StackLimit = limit;
|
|
345
|
-
teb->DeallocationStack = dealloc;
|
|
346
|
-
};
|
|
347
|
-
|
|
348
|
-
// Adjust stack limits so SEH works correctly
|
|
349
|
-
teb->StackBase = instance->main_stack_max;
|
|
350
|
-
teb->StackLimit = instance->main_stack_min;
|
|
351
|
-
teb->DeallocationStack = instance->main_stack_min;
|
|
352
|
-
|
|
353
|
-
const TrampolineInfo &trampoline = shared.trampolines[idx];
|
|
354
|
-
|
|
355
336
|
const FunctionInfo *proto = trampoline.proto;
|
|
356
337
|
Napi::Function func = trampoline.func.Value();
|
|
357
338
|
|
|
@@ -363,11 +344,6 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
363
344
|
|
|
364
345
|
K_DEFER_N(err_guard) { memset(out_reg, 0, K_SIZE(*out_reg)); };
|
|
365
346
|
|
|
366
|
-
if (trampoline.generation >= 0 && trampoline.generation != (int32_t)mem->generation) [[unlikely]] {
|
|
367
|
-
ThrowError<Napi::Error>(env, "Cannot use non-registered callback beyond FFI call");
|
|
368
|
-
return;
|
|
369
|
-
}
|
|
370
|
-
|
|
371
347
|
LocalArray<napi_value, MaxParameters + 1> arguments;
|
|
372
348
|
|
|
373
349
|
arguments.Append(!trampoline.recv.IsEmpty() ? trampoline.recv.Value() : env.Undefined());
|
package/src/koffi/src/abi_x86.cc
CHANGED
|
@@ -441,32 +441,11 @@ Napi::Value CallData::Complete(const FunctionInfo *func)
|
|
|
441
441
|
|
|
442
442
|
void CallData::Relay(Size idx, uint8_t *sp)
|
|
443
443
|
{
|
|
444
|
+
const TrampolineInfo &trampoline = shared.trampolines[idx];
|
|
445
|
+
|
|
444
446
|
uint8_t *caller_sp = sp + 48;
|
|
445
447
|
BackRegisters *out_reg = (BackRegisters *)(sp + 16);
|
|
446
448
|
|
|
447
|
-
if (env.IsExceptionPending()) [[unlikely]]
|
|
448
|
-
return;
|
|
449
|
-
|
|
450
|
-
#if defined(_WIN32)
|
|
451
|
-
TEB *teb = GetTEB();
|
|
452
|
-
|
|
453
|
-
// Restore previous stack limits at the end
|
|
454
|
-
K_DEFER_C(base = teb->StackBase,
|
|
455
|
-
limit = teb->StackLimit,
|
|
456
|
-
dealloc = teb->DeallocationStack) {
|
|
457
|
-
teb->StackBase = base;
|
|
458
|
-
teb->StackLimit = limit;
|
|
459
|
-
teb->DeallocationStack = dealloc;
|
|
460
|
-
};
|
|
461
|
-
|
|
462
|
-
// Adjust stack limits so SEH works correctly
|
|
463
|
-
teb->StackBase = instance->main_stack_max;
|
|
464
|
-
teb->StackLimit = instance->main_stack_min;
|
|
465
|
-
teb->DeallocationStack = instance->main_stack_min;
|
|
466
|
-
#endif
|
|
467
|
-
|
|
468
|
-
const TrampolineInfo &trampoline = shared.trampolines[idx];
|
|
469
|
-
|
|
470
449
|
const FunctionInfo *proto = trampoline.proto;
|
|
471
450
|
Napi::Function func = trampoline.func.Value();
|
|
472
451
|
|
|
@@ -492,11 +471,6 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
492
471
|
out_reg->ret_pop = pop;
|
|
493
472
|
};
|
|
494
473
|
|
|
495
|
-
if (trampoline.generation >= 0 && trampoline.generation != (int32_t)mem->generation) [[unlikely]] {
|
|
496
|
-
ThrowError<Napi::Error>(env, "Cannot use non-registered callback beyond FFI call");
|
|
497
|
-
return;
|
|
498
|
-
}
|
|
499
|
-
|
|
500
474
|
LocalArray<napi_value, MaxParameters + 1> arguments;
|
|
501
475
|
|
|
502
476
|
arguments.Append(!trampoline.recv.IsEmpty() ? trampoline.recv.Value() : env.Undefined());
|
|
@@ -109,6 +109,8 @@ RelayTrampoline:
|
|
|
109
109
|
.cfi_def_cfa esp, 48
|
|
110
110
|
movl %eax, 0(%esp)
|
|
111
111
|
movl %esp, 4(%esp)
|
|
112
|
+
movl $0, 32(%esp)
|
|
113
|
+
movl $0, 36(%esp)
|
|
112
114
|
call GetEIP
|
|
113
115
|
addl $_GLOBAL_OFFSET_TABLE_, %eax
|
|
114
116
|
call *RelayCallback@GOT(%eax)
|
|
@@ -172,13 +174,13 @@ SwitchAndRelay:
|
|
|
172
174
|
ret
|
|
173
175
|
.cfi_endproc
|
|
174
176
|
|
|
175
|
-
.
|
|
177
|
+
.balign 16
|
|
176
178
|
FindTrampolineStart:
|
|
177
179
|
call GetEIP
|
|
178
180
|
addl $16, %eax
|
|
179
181
|
andl $0xFFFFFFF0, %eax
|
|
180
182
|
ret
|
|
181
|
-
.
|
|
183
|
+
.balign 16
|
|
182
184
|
|
|
183
185
|
#include "gnu.inc"
|
|
184
186
|
|
package/src/koffi/src/call.cc
CHANGED
|
@@ -31,7 +31,6 @@ CallData::CallData(Napi::Env env, InstanceData *instance, InstanceMemory *mem)
|
|
|
31
31
|
: env(env), instance(instance),
|
|
32
32
|
mem(mem), old_stack_mem(mem->stack), old_heap_mem(mem->heap)
|
|
33
33
|
{
|
|
34
|
-
mem->generation += !mem->depth;
|
|
35
34
|
mem->depth++;
|
|
36
35
|
|
|
37
36
|
K_ASSERT(AlignUp(mem->stack.ptr, 16) == mem->stack.ptr);
|
|
@@ -64,9 +63,9 @@ void CallData::Dispose()
|
|
|
64
63
|
K_ASSERT(trampoline->instance == instance);
|
|
65
64
|
K_ASSERT(!trampoline->func.IsEmpty());
|
|
66
65
|
|
|
67
|
-
trampoline->instance = nullptr;
|
|
68
66
|
trampoline->func.Reset();
|
|
69
67
|
trampoline->recv.Reset();
|
|
68
|
+
trampoline->used = false;
|
|
70
69
|
|
|
71
70
|
shared.available.Append(idx);
|
|
72
71
|
}
|
|
@@ -1142,7 +1141,7 @@ void *CallData::ReserveTrampoline(const FunctionInfo *proto, Napi::Function func
|
|
|
1142
1141
|
trampoline->proto = proto;
|
|
1143
1142
|
trampoline->func.Reset(func, 1);
|
|
1144
1143
|
trampoline->recv.Reset();
|
|
1145
|
-
trampoline->
|
|
1144
|
+
trampoline->used = true;
|
|
1146
1145
|
|
|
1147
1146
|
void *ptr = GetTrampoline(idx);
|
|
1148
1147
|
|
package/src/koffi/src/ffi.cc
CHANGED
|
@@ -1728,10 +1728,6 @@ extern "C" void RelayCallback(Size idx, uint8_t *sp)
|
|
|
1728
1728
|
return;
|
|
1729
1729
|
}
|
|
1730
1730
|
|
|
1731
|
-
// Avoid triggering the "use callback beyond FFI" check
|
|
1732
|
-
K_DEFER_C(generation = trampoline->generation) { trampoline->generation = generation; };
|
|
1733
|
-
trampoline->generation = -1;
|
|
1734
|
-
|
|
1735
1731
|
if (std::this_thread::get_id() == instance->main_thread_id) {
|
|
1736
1732
|
CallData call(env, instance, mem);
|
|
1737
1733
|
|
|
@@ -1745,6 +1741,35 @@ extern "C" void RelayCallback(Size idx, uint8_t *sp)
|
|
|
1745
1741
|
|
|
1746
1742
|
extern "C" void RelayDirect(CallData *call, Size idx, uint8_t *sp)
|
|
1747
1743
|
{
|
|
1744
|
+
TrampolineInfo *trampoline = &shared.trampolines[idx];
|
|
1745
|
+
Napi::Env env = trampoline->func.Env();
|
|
1746
|
+
|
|
1747
|
+
#if defined(_WIN32)
|
|
1748
|
+
TEB *teb = GetTEB();
|
|
1749
|
+
InstanceData *instance = trampoline->instance;
|
|
1750
|
+
|
|
1751
|
+
// Restore previous stack limits at the end
|
|
1752
|
+
K_DEFER_C(base = teb->StackBase,
|
|
1753
|
+
limit = teb->StackLimit,
|
|
1754
|
+
dealloc = teb->DeallocationStack) {
|
|
1755
|
+
teb->StackBase = base;
|
|
1756
|
+
teb->StackLimit = limit;
|
|
1757
|
+
teb->DeallocationStack = dealloc;
|
|
1758
|
+
};
|
|
1759
|
+
|
|
1760
|
+
// Adjust stack limits so SEH works correctly
|
|
1761
|
+
teb->StackBase = instance->main_stack_max;
|
|
1762
|
+
teb->StackLimit = instance->main_stack_min;
|
|
1763
|
+
teb->DeallocationStack = instance->main_stack_min;
|
|
1764
|
+
#endif
|
|
1765
|
+
|
|
1766
|
+
if (env.IsExceptionPending()) [[unlikely]]
|
|
1767
|
+
return;
|
|
1768
|
+
if (!trampoline->used) [[unlikely]] {
|
|
1769
|
+
ThrowError<Napi::Error>(env, "Cannot use non-registered callback beyond FFI call");
|
|
1770
|
+
return;
|
|
1771
|
+
}
|
|
1772
|
+
|
|
1748
1773
|
Napi::HandleScope scope(call->env);
|
|
1749
1774
|
call->Relay(idx, sp);
|
|
1750
1775
|
}
|
|
@@ -2020,7 +2045,7 @@ static Napi::Value RegisterCallback(const Napi::CallbackInfo &info)
|
|
|
2020
2045
|
} else {
|
|
2021
2046
|
trampoline->recv.Reset();
|
|
2022
2047
|
}
|
|
2023
|
-
trampoline->
|
|
2048
|
+
trampoline->used = true;
|
|
2024
2049
|
|
|
2025
2050
|
void *ptr = GetTrampoline(idx);
|
|
2026
2051
|
|
|
@@ -2072,6 +2097,7 @@ static Napi::Value UnregisterCallback(const Napi::CallbackInfo &info)
|
|
|
2072
2097
|
|
|
2073
2098
|
trampoline->func.Reset();
|
|
2074
2099
|
trampoline->recv.Reset();
|
|
2100
|
+
trampoline->used = false;
|
|
2075
2101
|
|
|
2076
2102
|
shared.available.Append(idx);
|
|
2077
2103
|
}
|
|
@@ -2665,6 +2691,7 @@ InstanceData::~InstanceData()
|
|
|
2665
2691
|
trampoline->instance = nullptr;
|
|
2666
2692
|
trampoline->func.Reset();
|
|
2667
2693
|
trampoline->recv.Reset();
|
|
2694
|
+
trampoline->used = false;
|
|
2668
2695
|
}
|
|
2669
2696
|
}
|
|
2670
2697
|
}
|
package/src/koffi/src/ffi.hh
CHANGED
|
@@ -249,8 +249,6 @@ struct InstanceMemory {
|
|
|
249
249
|
Span<uint8_t> stack0;
|
|
250
250
|
Span<uint8_t> heap;
|
|
251
251
|
|
|
252
|
-
uint16_t generation; // Can wrap without risk
|
|
253
|
-
|
|
254
252
|
bool busy;
|
|
255
253
|
bool temporary;
|
|
256
254
|
int depth;
|
|
@@ -322,7 +320,7 @@ struct TrampolineInfo {
|
|
|
322
320
|
Napi::FunctionReference func;
|
|
323
321
|
Napi::Reference<Napi::Value> recv;
|
|
324
322
|
|
|
325
|
-
|
|
323
|
+
bool used;
|
|
326
324
|
};
|
|
327
325
|
|
|
328
326
|
struct SharedData {
|