koffi 2.15.2 → 2.15.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/build/koffi/darwin_arm64/koffi.node +0 -0
  3. package/build/koffi/darwin_x64/koffi.node +0 -0
  4. package/build/koffi/freebsd_arm64/koffi.node +0 -0
  5. package/build/koffi/freebsd_ia32/koffi.node +0 -0
  6. package/build/koffi/freebsd_x64/koffi.node +0 -0
  7. package/build/koffi/linux_arm64/koffi.node +0 -0
  8. package/build/koffi/linux_armhf/koffi.node +0 -0
  9. package/build/koffi/linux_ia32/koffi.node +0 -0
  10. package/build/koffi/linux_loong64/koffi.node +0 -0
  11. package/build/koffi/linux_riscv64d/koffi.node +0 -0
  12. package/build/koffi/linux_x64/koffi.node +0 -0
  13. package/build/koffi/musl_arm64/koffi.node +0 -0
  14. package/build/koffi/musl_x64/koffi.node +0 -0
  15. package/build/koffi/openbsd_ia32/koffi.node +0 -0
  16. package/build/koffi/openbsd_x64/koffi.node +0 -0
  17. package/build/koffi/win32_arm64/koffi.node +0 -0
  18. package/build/koffi/win32_ia32/koffi.node +0 -0
  19. package/build/koffi/win32_x64/koffi.node +0 -0
  20. package/index.js +8 -8
  21. package/indirect.js +8 -8
  22. package/package.json +1 -1
  23. package/src/koffi/src/abi_arm32.cc +7 -14
  24. package/src/koffi/src/abi_arm32_asm.S +6 -10
  25. package/src/koffi/src/abi_arm64.cc +11 -17
  26. package/src/koffi/src/abi_arm64_asm.S +4 -7
  27. package/src/koffi/src/abi_arm64_asm.asm +5 -7
  28. package/src/koffi/src/abi_loong64_asm.S +4 -7
  29. package/src/koffi/src/abi_riscv64.cc +7 -14
  30. package/src/koffi/src/abi_riscv64_asm.S +4 -7
  31. package/src/koffi/src/abi_x64_sysv.cc +7 -14
  32. package/src/koffi/src/abi_x64_sysv_asm.S +4 -7
  33. package/src/koffi/src/abi_x64_win.cc +7 -14
  34. package/src/koffi/src/abi_x64_win_asm.S +29 -24
  35. package/src/koffi/src/abi_x64_win_asm.asm +28 -25
  36. package/src/koffi/src/abi_x86.cc +17 -15
  37. package/src/koffi/src/abi_x86_asm.S +11 -17
  38. package/src/koffi/src/abi_x86_asm.asm +6 -14
  39. package/src/koffi/src/call.cc +37 -47
  40. package/src/koffi/src/call.hh +7 -9
  41. package/src/koffi/src/ffi.cc +41 -20
  42. package/src/koffi/src/ffi.hh +1 -1
  43. package/src/koffi/src/util.cc +7 -11
  44. package/src/koffi/src/win32.cc +13 -0
  45. package/src/koffi/src/win32.hh +2 -0
package/CHANGELOG.md CHANGED
@@ -7,6 +7,21 @@
7
7
 
8
8
  ### Koffi 2.15
9
9
 
10
+ #### Koffi 2.15.4
11
+
12
+ *Released on 2026-04-03*
13
+
14
+ - Fix ABI issue with variadic parameters that are passed on the stack on Apple ARM64 platforms
15
+ - Remove erroneous assertion from debug builds
16
+
17
+ #### Koffi 2.15.3
18
+
19
+ *Released on 2026-04-03*
20
+
21
+ - Fix *IsOnCentralStack()* assertion/crash when using callbacks in recent Node versions
22
+ - Support SetUnhandledExceptionFilter on Windows x64 and x86 ([@longhun12346](https://github.com/longhun12346))
23
+ - Fix incorrect stack alignment when relaying callbacks on 32-bit x86 platforms
24
+
10
25
  #### Koffi 2.15.2
11
26
 
12
27
  *Released on 2026-03-11*
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
@@ -4,9 +4,9 @@ var __commonJS = (cb, mod3) => function __require() {
4
4
  return mod3 || (0, cb[__getOwnPropNames(cb)[0]])((mod3 = { exports: {} }).exports, mod3), mod3.exports;
5
5
  };
6
6
 
7
- // package/src/cnoke/src/tools.js
7
+ // ../../bin/Koffi/package/src/cnoke/src/tools.js
8
8
  var require_tools = __commonJS({
9
- "package/src/cnoke/src/tools.js"(exports2, module2) {
9
+ "../../bin/Koffi/package/src/cnoke/src/tools.js"(exports2, module2) {
10
10
  "use strict";
11
11
  var crypto = require("crypto");
12
12
  var fs2 = require("fs");
@@ -393,12 +393,12 @@ var require_tools = __commonJS({
393
393
  }
394
394
  });
395
395
 
396
- // package/src/koffi/package.json
396
+ // ../../bin/Koffi/package/src/koffi/package.json
397
397
  var require_package = __commonJS({
398
- "package/src/koffi/package.json"(exports2, module2) {
398
+ "../../bin/Koffi/package/src/koffi/package.json"(exports2, module2) {
399
399
  module2.exports = {
400
400
  name: "koffi",
401
- version: "2.15.2",
401
+ version: "2.15.4",
402
402
  description: "Fast and simple C FFI (foreign function interface) for Node.js",
403
403
  keywords: [
404
404
  "foreign",
@@ -440,9 +440,9 @@ var require_package = __commonJS({
440
440
  }
441
441
  });
442
442
 
443
- // package/src/koffi/src/init.js
443
+ // ../../bin/Koffi/package/src/koffi/src/init.js
444
444
  var require_init = __commonJS({
445
- "package/src/koffi/src/init.js"(exports, module) {
445
+ "../../bin/Koffi/package/src/koffi/src/init.js"(exports, module) {
446
446
  var fs = require("fs");
447
447
  var path = require("path");
448
448
  var util = require("util");
@@ -526,7 +526,7 @@ var require_init = __commonJS({
526
526
  }
527
527
  });
528
528
 
529
- // package/src/koffi/index.js
529
+ // ../../bin/Koffi/package/src/koffi/index.js
530
530
  var { detect: detect2, init: init2 } = require_init();
531
531
  var triplet2 = detect2();
532
532
  var native2 = null;
package/indirect.js CHANGED
@@ -4,9 +4,9 @@ var __commonJS = (cb, mod3) => function __require() {
4
4
  return mod3 || (0, cb[__getOwnPropNames(cb)[0]])((mod3 = { exports: {} }).exports, mod3), mod3.exports;
5
5
  };
6
6
 
7
- // package/src/cnoke/src/tools.js
7
+ // ../../bin/Koffi/package/src/cnoke/src/tools.js
8
8
  var require_tools = __commonJS({
9
- "package/src/cnoke/src/tools.js"(exports2, module2) {
9
+ "../../bin/Koffi/package/src/cnoke/src/tools.js"(exports2, module2) {
10
10
  "use strict";
11
11
  var crypto = require("crypto");
12
12
  var fs2 = require("fs");
@@ -393,12 +393,12 @@ var require_tools = __commonJS({
393
393
  }
394
394
  });
395
395
 
396
- // package/src/koffi/package.json
396
+ // ../../bin/Koffi/package/src/koffi/package.json
397
397
  var require_package = __commonJS({
398
- "package/src/koffi/package.json"(exports2, module2) {
398
+ "../../bin/Koffi/package/src/koffi/package.json"(exports2, module2) {
399
399
  module2.exports = {
400
400
  name: "koffi",
401
- version: "2.15.2",
401
+ version: "2.15.4",
402
402
  description: "Fast and simple C FFI (foreign function interface) for Node.js",
403
403
  keywords: [
404
404
  "foreign",
@@ -440,9 +440,9 @@ var require_package = __commonJS({
440
440
  }
441
441
  });
442
442
 
443
- // package/src/koffi/src/init.js
443
+ // ../../bin/Koffi/package/src/koffi/src/init.js
444
444
  var require_init = __commonJS({
445
- "package/src/koffi/src/init.js"(exports, module) {
445
+ "../../bin/Koffi/package/src/koffi/src/init.js"(exports, module) {
446
446
  var fs = require("fs");
447
447
  var path = require("path");
448
448
  var util = require("util");
@@ -526,7 +526,7 @@ var require_init = __commonJS({
526
526
  }
527
527
  });
528
528
 
529
- // package/src/koffi/indirect.js
529
+ // ../../bin/Koffi/package/src/koffi/indirect.js
530
530
  var { detect: detect2, init: init2 } = require_init();
531
531
  var triplet2 = detect2();
532
532
  var mod2 = init2(triplet2, null);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "koffi",
3
- "version": "2.15.2",
3
+ "version": "2.15.4",
4
4
  "description": "Fast and simple C FFI (foreign function interface) for Node.js",
5
5
  "keywords": [
6
6
  "foreign",
@@ -38,10 +38,6 @@ extern "C" uint64_t ForwardCallXGG(const void *func, uint8_t *sp, uint8_t **out_
38
38
  extern "C" float ForwardCallXF(const void *func, uint8_t *sp, uint8_t **out_old_sp);
39
39
  extern "C" HfaRet ForwardCallXDDDD(const void *func, uint8_t *sp, uint8_t **out_old_sp);
40
40
 
41
- extern "C" napi_value CallSwitchStack(Napi::Function *func, size_t argc, napi_value *argv,
42
- uint8_t *old_sp, Span<uint8_t> *new_stack,
43
- napi_value (*call)(Napi::Function *func, size_t argc, napi_value *argv));
44
-
45
41
  #include "trampolines/prototypes.inc"
46
42
 
47
43
  static int IsHFA(const TypeInfo *type)
@@ -543,8 +539,12 @@ Napi::Value CallData::Complete(const FunctionInfo *func)
543
539
  K_UNREACHABLE();
544
540
  }
545
541
 
546
- void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_stack, BackRegisters *out_reg)
542
+ void CallData::Relay(Size idx, uint8_t *sp)
547
543
  {
544
+ uint8_t *own_sp = sp;
545
+ uint8_t *caller_sp = sp + 128;
546
+ BackRegisters *out_reg = (BackRegisters *)(sp + 80);
547
+
548
548
  if (env.IsExceptionPending()) [[unlikely]]
549
549
  return;
550
550
 
@@ -810,15 +810,8 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_
810
810
 
811
811
  const TypeInfo *type = proto->ret.type;
812
812
 
813
- // Make the call
814
- napi_value ret;
815
- if (switch_stack) {
816
- ret = CallSwitchStack(&func, (size_t)arguments.len, arguments.data, old_sp, &mem->stack,
817
- [](Napi::Function *func, size_t argc, napi_value *argv) { return (napi_value)func->Call(argv[0], argc - 1, argv + 1); });
818
- } else {
819
- ret = (napi_value)func.Call(arguments[0], arguments.len - 1, arguments.data + 1);
820
- }
821
- Napi::Value value(env, ret);
813
+ // Make the call!
814
+ Napi::Value value = func.Call(arguments[0], arguments.len - 1, arguments.data + 1);
822
815
 
823
816
  if (env.IsExceptionPending()) [[unlikely]]
824
817
  return;
@@ -91,7 +91,8 @@ ForwardCallXDDDD:
91
91
  # ----------------------------
92
92
 
93
93
  .global RelayCallback
94
- .global CallSwitchStack
94
+ .global SwitchAndRelay
95
+ .global RelayDirect
95
96
 
96
97
  # First, make a copy of the GPR argument registers (r0 to r7).
97
98
  # Then call the C function RelayCallback with the following arguments:
@@ -107,11 +108,9 @@ ForwardCallXDDDD:
107
108
  sub sp, sp, #120
108
109
  .cfi_def_cfa sp, 128
109
110
  add r12, sp, 64
110
- stmia r12!, {r0-r3}
111
+ stmia r12, {r0-r3}
111
112
  mov r0, \id
112
113
  mov r1, sp
113
- add r2, sp, #128
114
- mov r3, r12
115
114
  bl RelayCallback
116
115
  add sp, sp, #80
117
116
  ldmia sp!, {r0-r1}
@@ -136,11 +135,9 @@ ForwardCallXDDDD:
136
135
  .cfi_def_cfa sp, 128
137
136
  mov r12, sp
138
137
  vstmia r12!, {d0-d7}
139
- stmia r12!, {r0-r3}
138
+ stmia r12, {r0-r3}
140
139
  mov r0, \id
141
140
  mov r1, sp
142
- add r2, sp, #128
143
- mov r3, r12
144
141
  bl RelayCallback
145
142
  add sp, sp, #80
146
143
  ldmia sp!, {r0-r1}
@@ -159,7 +156,7 @@ ForwardCallXDDDD:
159
156
  # probably misdetect this as a "stack overflow". We have to restore the old
160
157
  # stack pointer, call Node.js/V8 and go back to ours.
161
158
  # The first three parameters (r0, r1, r2) are passed through untouched.
162
- CallSwitchStack:
159
+ SwitchAndRelay:
163
160
  .cfi_startproc
164
161
  push {fp, lr}
165
162
  .cfi_def_cfa sp, 8
@@ -173,9 +170,8 @@ CallSwitchStack:
173
170
  sub r5, sp, r5
174
171
  and r5, r5, #-16
175
172
  str r5, [r4, 4]
176
- ldr r4, [sp, 20]
177
173
  mov sp, r3
178
- blx r4
174
+ bl RelayDirect
179
175
  mov sp, fp
180
176
  .cfi_def_cfa sp, 16
181
177
  pop {r4, r5}
@@ -48,10 +48,6 @@ extern "C" X0X1Ret ForwardCallXGG(const void *func, uint8_t *sp, uint8_t **out_o
48
48
  extern "C" float ForwardCallXF(const void *func, uint8_t *sp, uint8_t **out_old_sp);
49
49
  extern "C" HfaRet ForwardCallXDDDD(const void *func, uint8_t *sp, uint8_t **out_old_sp);
50
50
 
51
- extern "C" napi_value CallSwitchStack(Napi::Function *func, size_t argc, napi_value *argv,
52
- uint8_t *old_sp, Span<uint8_t> *new_stack,
53
- napi_value (*call)(Napi::Function *func, size_t argc, napi_value *argv));
54
-
55
51
  #include "trampolines/prototypes.inc"
56
52
 
57
53
  static HfaInfo IsHFA(const TypeInfo *type)
@@ -290,7 +286,7 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
290
286
  if (param.gpr_count) [[likely]] { \
291
287
  *(gpr_ptr++) = (uint64_t)v; \
292
288
  } else { \
293
- args_ptr = AlignUp(args_ptr, param.type->align); \
289
+ args_ptr = AlignUp(args_ptr, param.variadic ? 8 : param.type->align); \
294
290
  *args_ptr = (uint64_t)v; \
295
291
  args_ptr = (uint64_t *)((uint8_t *)args_ptr + param.type->size); \
296
292
  } \
@@ -307,7 +303,7 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
307
303
  if (param.gpr_count) [[likely]] { \
308
304
  *(gpr_ptr++) = (uint64_t)ReverseBytes(v); \
309
305
  } else { \
310
- args_ptr = AlignUp(args_ptr, param.type->align); \
306
+ args_ptr = AlignUp(args_ptr, param.variadic ? 8 : param.type->align); \
311
307
  *args_ptr = (uint64_t)ReverseBytes(v); \
312
308
  args_ptr = (uint64_t *)((uint8_t *)args_ptr + param.type->size); \
313
309
  } \
@@ -357,6 +353,7 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
357
353
  if (param.gpr_count) [[likely]] {
358
354
  *(gpr_ptr++) = (uint64_t)b;
359
355
  } else {
356
+ args_ptr = AlignUp(args_ptr, param.variadic ? 8 : 1);
360
357
  *(uint8_t *)args_ptr = b;
361
358
  args_ptr = (uint64_t *)((uint8_t *)args_ptr + 1);
362
359
  }
@@ -488,7 +485,7 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
488
485
  #endif
489
486
  } else {
490
487
  #if defined(__APPLE__)
491
- args_ptr = AlignUp(args_ptr, 4);
488
+ args_ptr = AlignUp(args_ptr, param.variadic ? 8 : 4);
492
489
  *(float *)args_ptr = f;
493
490
  args_ptr = (uint64_t *)((uint8_t *)args_ptr + 4);
494
491
  #else
@@ -691,8 +688,12 @@ Napi::Value CallData::Complete(const FunctionInfo *func)
691
688
  K_UNREACHABLE();
692
689
  }
693
690
 
694
- void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_stack, BackRegisters *out_reg)
691
+ void CallData::Relay(Size idx, uint8_t *sp)
695
692
  {
693
+ uint8_t *own_sp = sp;
694
+ uint8_t *caller_sp = sp + 208;
695
+ BackRegisters *out_reg = (BackRegisters *)(sp + 136);
696
+
696
697
  if (env.IsExceptionPending()) [[unlikely]]
697
698
  return;
698
699
 
@@ -1133,15 +1134,8 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_
1133
1134
 
1134
1135
  const TypeInfo *type = proto->ret.type;
1135
1136
 
1136
- // Make the call
1137
- napi_value ret;
1138
- if (switch_stack) {
1139
- ret = CallSwitchStack(&func, (size_t)arguments.len, arguments.data, old_sp, &mem->stack,
1140
- [](Napi::Function *func, size_t argc, napi_value *argv) { return (napi_value)func->Call(argv[0], argc - 1, argv + 1); });
1141
- } else {
1142
- ret = (napi_value)func.Call(arguments[0], arguments.len - 1, arguments.data + 1);
1143
- }
1144
- Napi::Value value(env, ret);
1137
+ // Make the call!
1138
+ Napi::Value value = func.Call(arguments[0], arguments.len - 1, arguments.data + 1);
1145
1139
 
1146
1140
  if (env.IsExceptionPending()) [[unlikely]]
1147
1141
  return;
@@ -112,7 +112,8 @@ SYMBOL(ForwardCallXDDDD):
112
112
  # ----------------------------
113
113
 
114
114
  .global SYMBOL(RelayCallback)
115
- .global SYMBOL(CallSwitchStack)
115
+ .global SYMBOL(SwitchAndRelay)
116
+ .global SYMBOL(RelayDirect)
116
117
 
117
118
  # First, make a copy of the GPR argument registers (x0 to x7).
118
119
  # Then call the C function RelayCallback with the following arguments:
@@ -135,8 +136,6 @@ SYMBOL(ForwardCallXDDDD):
135
136
  str x8, [sp, 64]
136
137
  mov x0, \id
137
138
  mov x1, sp
138
- add x2, sp, #208
139
- add x3, sp, #136
140
139
  bl SYMBOL(RelayCallback)
141
140
  ldp x0, x1, [sp, 136]
142
141
  add sp, sp, #192
@@ -170,8 +169,6 @@ SYMBOL(ForwardCallXDDDD):
170
169
  stp d6, d7, [sp, 120]
171
170
  mov x0, \id
172
171
  mov x1, sp
173
- add x2, sp, #208
174
- add x3, sp, #136
175
172
  bl SYMBOL(RelayCallback)
176
173
  ldp x0, x1, [sp, 136]
177
174
  ldp d0, d1, [sp, 152]
@@ -191,7 +188,7 @@ SYMBOL(ForwardCallXDDDD):
191
188
  # probably misdetect this as a "stack overflow". We have to restore the old
192
189
  # stack pointer, call Node.js/V8 and go back to ours.
193
190
  # The first three parameters (x0, x1, x2) are passed through untouched.
194
- SYMBOL(CallSwitchStack):
191
+ SYMBOL(SwitchAndRelay):
195
192
  .cfi_startproc
196
193
  hint #34
197
194
  stp x29, x30, [sp, -16]!
@@ -204,7 +201,7 @@ SYMBOL(CallSwitchStack):
204
201
  and x9, x9, #-16
205
202
  str x9, [x4, 8]
206
203
  mov sp, x3
207
- blr x5
204
+ bl SYMBOL(RelayDirect)
208
205
  mov sp, x29
209
206
  .cfi_def_cfa sp, 16
210
207
  ldp x29, x30, [sp], 16
@@ -106,7 +106,9 @@ ForwardCallXDDDD PROC
106
106
 
107
107
  EXPORT RelayCallback
108
108
  EXTERN RelayCallback
109
- EXPORT CallSwitchStack
109
+ EXPORT SwitchAndRelay
110
+ EXPORT RelayDirect
111
+ EXTERN RelayDirect
110
112
 
111
113
  ; First, make a copy of the GPR argument registers (x0 to x7).
112
114
  ; Then call the C function RelayCallback with the following arguments:
@@ -125,8 +127,6 @@ ForwardCallXDDDD PROC
125
127
  str x8, [sp, 64]
126
128
  mov x0, $ID
127
129
  mov x1, sp
128
- add x2, sp, #208
129
- add x3, sp, #136
130
130
  bl RelayCallback
131
131
  ldp x0, x1, [sp, 136]
132
132
  add sp, sp, #192
@@ -151,8 +151,6 @@ ForwardCallXDDDD PROC
151
151
  stp d6, d7, [sp, 120]
152
152
  mov x0, $ID
153
153
  mov x1, sp
154
- add x2, sp, #208
155
- add x3, sp, #136
156
154
  bl RelayCallback
157
155
  ldp x0, x1, [sp, 136]
158
156
  ldp d0, d1, [sp, 152]
@@ -167,7 +165,7 @@ ForwardCallXDDDD PROC
167
165
  ; probably misdetect this as a "stack overflow". We have to restore the old
168
166
  ; stack pointer, call Node.js/V8 and go back to ours.
169
167
  ; The first three parameters (x0, x1, x2) are passed through untouched.
170
- CallSwitchStack PROC
168
+ SwitchAndRelay PROC
171
169
  stp x29, x30, [sp, -16]!
172
170
  mov x29, sp
173
171
  ldr x9, [x4, 0]
@@ -175,7 +173,7 @@ CallSwitchStack PROC
175
173
  and x9, x9, #-16
176
174
  str x9, [x4, 8]
177
175
  mov sp, x3
178
- blr x5
176
+ bl RelayDirect
179
177
  mov sp, x29
180
178
  ldp x29, x30, [sp], 16
181
179
  ret
@@ -129,7 +129,8 @@ ForwardCallXDD:
129
129
  # ----------------------------
130
130
 
131
131
  .global RelayCallback
132
- .global CallSwitchStack
132
+ .global SwitchAndRelay
133
+ .global RelayDirect
133
134
 
134
135
  # First, make a copy of the GPR argument registers (a0 to a7).
135
136
  # Then call the C function RelayCallback with the following arguments:
@@ -149,8 +150,6 @@ ForwardCallXDD:
149
150
  st.d $a7, $sp, 64
150
151
  li.d $a0, \id
151
152
  addi.d $a1, $sp, 8
152
- addi.d $a2, $sp, 176
153
- addi.d $a3, $sp, 136
154
153
  bl RelayCallback
155
154
  ld.d $ra, $sp, 0
156
155
  ld.d $a0, $sp, 136
@@ -181,8 +180,6 @@ ForwardCallXDD:
181
180
  fst.d $fa7, $sp, 128
182
181
  li.d $a0, \id
183
182
  addi.d $a1, $sp, 8
184
- addi.d $a2, $sp, 176
185
- addi.d $a3, $sp, 136
186
183
  bl RelayCallback
187
184
  ld.d $ra, $sp, 0
188
185
  ld.d $a0, $sp, 136
@@ -198,7 +195,7 @@ ForwardCallXDD:
198
195
  # probably misdetect this as a "stack overflow". We have to restore the old
199
196
  # stack pointer, call Node.js/V8 and go back to ours.
200
197
  # The first three parameters (a0, a1, a2) are passed through untouched.
201
- CallSwitchStack:
198
+ SwitchAndRelay:
202
199
  addi.d $sp, $sp, -16
203
200
  st.d $ra, $sp, 0
204
201
  st.d $fp, $sp, 8
@@ -209,7 +206,7 @@ CallSwitchStack:
209
206
  and $t0, $t0, $t1
210
207
  st.d $t0, $a4, 8
211
208
  move $sp, $a3
212
- jirl $ra, $a5, 0
209
+ bl RelayDirect
213
210
  move $sp, $fp
214
211
  ld.d $ra, $sp, 0
215
212
  ld.d $fp, $sp, 8
@@ -48,10 +48,6 @@ extern "C" Fa0A0Ret ForwardCallXDG(const void *func, uint8_t *sp, uint8_t **out_
48
48
  extern "C" A0Fa0Ret ForwardCallXGD(const void *func, uint8_t *sp, uint8_t **out_old_sp);
49
49
  extern "C" Fa0Fa1Ret ForwardCallXDD(const void *func, uint8_t *sp, uint8_t **out_old_sp);
50
50
 
51
- extern "C" napi_value CallSwitchStack(Napi::Function *func, size_t argc, napi_value *argv,
52
- uint8_t *old_sp, Span<uint8_t> *new_stack,
53
- napi_value (*call)(Napi::Function *func, size_t argc, napi_value *argv));
54
-
55
51
  #include "trampolines/prototypes.inc"
56
52
 
57
53
  static inline void ExpandPair(const uint8_t raw[16], int size1, int size2, uint64_t out_regs[2])
@@ -484,8 +480,12 @@ Napi::Value CallData::Complete(const FunctionInfo *func)
484
480
  K_UNREACHABLE();
485
481
  }
486
482
 
487
- void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_stack, BackRegisters *out_reg)
483
+ void CallData::Relay(Size idx, uint8_t *sp)
488
484
  {
485
+ uint8_t *own_sp = sp;
486
+ uint8_t *caller_sp = sp + 168;
487
+ BackRegisters *out_reg = (BackRegisters *)(sp + 128);
488
+
489
489
  if (env.IsExceptionPending()) [[unlikely]]
490
490
  return;
491
491
 
@@ -722,15 +722,8 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_
722
722
 
723
723
  const TypeInfo *type = proto->ret.type;
724
724
 
725
- // Make the call
726
- napi_value ret;
727
- if (switch_stack) {
728
- ret = CallSwitchStack(&func, (size_t)arguments.len, arguments.data, old_sp, &mem->stack,
729
- [](Napi::Function *func, size_t argc, napi_value *argv) { return (napi_value)func->Call(argv[0], argc - 1, argv + 1); });
730
- } else {
731
- ret = (napi_value)func.Call(arguments[0], arguments.len - 1, arguments.data + 1);
732
- }
733
- Napi::Value value(env, ret);
725
+ // Make the call!
726
+ Napi::Value value = func.Call(arguments[0], arguments.len - 1, arguments.data + 1);
734
727
 
735
728
  if (env.IsExceptionPending()) [[unlikely]]
736
729
  return;
@@ -129,7 +129,8 @@ ForwardCallXDD:
129
129
  # ----------------------------
130
130
 
131
131
  .global RelayCallback
132
- .global CallSwitchStack
132
+ .global SwitchAndRelay
133
+ .global RelayDirect
133
134
 
134
135
  # First, make a copy of the GPR argument registers (a0 to a7).
135
136
  # Then call the C function RelayCallback with the following arguments:
@@ -149,8 +150,6 @@ ForwardCallXDD:
149
150
  sd a7, 64(sp)
150
151
  li a0, \id
151
152
  addi a1, sp, 8
152
- addi a2, sp, 176
153
- addi a3, sp, 136
154
153
  call RelayCallback
155
154
  ld ra, 0(sp)
156
155
  ld a0, 136(sp)
@@ -181,8 +180,6 @@ ForwardCallXDD:
181
180
  fsd fa7, 128(sp)
182
181
  li a0, \id
183
182
  addi a1, sp, 8
184
- addi a2, sp, 176
185
- addi a3, sp, 136
186
183
  call RelayCallback
187
184
  ld ra, 0(sp)
188
185
  ld a0, 136(sp)
@@ -198,7 +195,7 @@ ForwardCallXDD:
198
195
  # probably misdetect this as a "stack overflow". We have to restore the old
199
196
  # stack pointer, call Node.js/V8 and go back to ours.
200
197
  # The first three parameters (a0, a1, a2) are passed through untouched.
201
- CallSwitchStack:
198
+ SwitchAndRelay:
202
199
  addi sp, sp, -16
203
200
  sd ra, 0(sp)
204
201
  sd s1, 8(sp)
@@ -208,7 +205,7 @@ CallSwitchStack:
208
205
  andi t0, t0, -16
209
206
  sd t0, 8(a4)
210
207
  mv sp, a3
211
- jalr a5
208
+ call RelayDirect
212
209
  mv sp, s1
213
210
  ld ra, 0(sp)
214
211
  ld s1, 8(sp)
@@ -55,10 +55,6 @@ extern "C" Xmm0RaxRet ForwardCallXDG(const void *func, uint8_t *sp, uint8_t **ou
55
55
  extern "C" RaxXmm0Ret ForwardCallXGD(const void *func, uint8_t *sp, uint8_t **out_old_sp);
56
56
  extern "C" Xmm0Xmm1Ret ForwardCallXDD(const void *func, uint8_t *sp, uint8_t **out_old_sp);
57
57
 
58
- extern "C" napi_value CallSwitchStack(Napi::Function *func, size_t argc, napi_value *argv,
59
- uint8_t *old_sp, Span<uint8_t> *new_stack,
60
- napi_value (*call)(Napi::Function *func, size_t argc, napi_value *argv));
61
-
62
58
  #include "trampolines/prototypes.inc"
63
59
 
64
60
  static inline RegisterClass MergeClasses(RegisterClass cls1, RegisterClass cls2)
@@ -520,8 +516,12 @@ Napi::Value CallData::Complete(const FunctionInfo *func)
520
516
  K_UNREACHABLE();
521
517
  }
522
518
 
523
- void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_stack, BackRegisters *out_reg)
519
+ void CallData::Relay(Size idx, uint8_t *sp)
524
520
  {
521
+ uint8_t *own_sp = sp;
522
+ uint8_t *caller_sp = sp + 160;
523
+ BackRegisters *out_reg = (BackRegisters *)(sp + 112);
524
+
525
525
  if (env.IsExceptionPending()) [[unlikely]]
526
526
  return;
527
527
 
@@ -747,15 +747,8 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_
747
747
 
748
748
  const TypeInfo *type = proto->ret.type;
749
749
 
750
- // Make the call
751
- napi_value ret;
752
- if (switch_stack) {
753
- ret = CallSwitchStack(&func, (size_t)arguments.len, arguments.data, old_sp, &mem->stack,
754
- [](Napi::Function *func, size_t argc, napi_value *argv) { return (napi_value)func->Call(argv[0], argc - 1, argv + 1); });
755
- } else {
756
- ret = (napi_value)func.Call(arguments[0], arguments.len - 1, arguments.data + 1);
757
- }
758
- Napi::Value value(env, ret);
750
+ // Make the call!
751
+ Napi::Value value = func.Call(arguments[0], arguments.len - 1, arguments.data + 1);
759
752
 
760
753
  if (env.IsExceptionPending()) [[unlikely]]
761
754
  return;
@@ -146,7 +146,8 @@ SYMBOL(ForwardCallXDD):
146
146
  # ----------------------------
147
147
 
148
148
  .global SYMBOL(RelayCallback)
149
- .global SYMBOL(CallSwitchStack)
149
+ .global SYMBOL(SwitchAndRelay)
150
+ .global SYMBOL(RelayDirect)
150
151
 
151
152
  # First, make a copy of the GPR argument registers (rdi, rsi, rdx, rcx, r8, r9).
152
153
  # Then call the C function RelayCallback with the following arguments:
@@ -167,8 +168,6 @@ SYMBOL(ForwardCallXDD):
167
168
  movq %r9, 40(%rsp)
168
169
  movq $\id, %rdi
169
170
  movq %rsp, %rsi
170
- leaq 160(%rsp), %rdx
171
- leaq 112(%rsp), %rcx
172
171
  #if defined(__linux__)
173
172
  call *RelayCallback@GOTPCREL(%rip)
174
173
  #else
@@ -205,8 +204,6 @@ SYMBOL(ForwardCallXDD):
205
204
  movsd %xmm7, 104(%rsp)
206
205
  movq $\id, %rdi
207
206
  movq %rsp, %rsi
208
- leaq 160(%rsp), %rdx
209
- leaq 112(%rsp), %rcx
210
207
  #if defined(__linux__)
211
208
  call *RelayCallback@GOTPCREL(%rip)
212
209
  #else
@@ -227,7 +224,7 @@ SYMBOL(ForwardCallXDD):
227
224
  # probably misdetect this as a "stack overflow". We have to restore the old
228
225
  # stack pointer, call Node.js/V8 and go back to ours.
229
226
  # The first three parameters (rdi, rsi, rdx) are passed through untouched.
230
- SYMBOL(CallSwitchStack):
227
+ SYMBOL(SwitchAndRelay):
231
228
  .cfi_startproc
232
229
  .cfi_def_cfa rsp, 8
233
230
  ENDBR64
@@ -240,7 +237,7 @@ SYMBOL(CallSwitchStack):
240
237
  movq %r10, 8(%r8)
241
238
  movq %rcx, %rsp
242
239
  .cfi_def_cfa rsp, 16
243
- call *%r9
240
+ call SYMBOL(RelayDirect)
244
241
  mov %rbp, %rsp
245
242
  .cfi_def_cfa rsp, 16
246
243
  pop %rbp