koffi 1.1.3 → 1.1.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 (51) hide show
  1. package/CMakeLists.txt +3 -0
  2. package/README.md +13 -14
  3. package/build/qemu/1.1.4/koffi_darwin_x64.tar.gz +0 -0
  4. package/build/qemu/1.1.4/koffi_freebsd_arm64.tar.gz +0 -0
  5. package/build/qemu/1.1.4/koffi_freebsd_ia32.tar.gz +0 -0
  6. package/build/qemu/1.1.4/koffi_freebsd_x64.tar.gz +0 -0
  7. package/build/qemu/1.1.4/koffi_linux_arm.tar.gz +0 -0
  8. package/build/qemu/1.1.4/koffi_linux_arm64.tar.gz +0 -0
  9. package/build/qemu/1.1.4/koffi_linux_ia32.tar.gz +0 -0
  10. package/build/qemu/1.1.4/koffi_linux_riscv64.tar.gz +0 -0
  11. package/build/qemu/1.1.4/koffi_linux_x64.tar.gz +0 -0
  12. package/build/qemu/1.1.4/koffi_openbsd_ia32.tar.gz +0 -0
  13. package/build/qemu/1.1.4/koffi_openbsd_x64.tar.gz +0 -0
  14. package/build/qemu/1.1.4/koffi_win32_ia32.tar.gz +0 -0
  15. package/build/qemu/1.1.4/koffi_win32_x64.tar.gz +0 -0
  16. package/package.json +1 -1
  17. package/qemu/qemu.js +13 -10
  18. package/qemu/registry/machines.json +91 -0
  19. package/qemu/registry/sha256sum.txt +11 -0
  20. package/src/abi_arm32.cc +23 -49
  21. package/src/abi_arm64.cc +15 -16
  22. package/src/abi_riscv64.cc +468 -0
  23. package/src/abi_riscv64_fwd.S +129 -0
  24. package/src/abi_x64_sysv.cc +8 -9
  25. package/src/abi_x64_win.cc +4 -7
  26. package/src/abi_x86.cc +3 -4
  27. package/src/call.cc +6 -18
  28. package/src/call.hh +13 -23
  29. package/src/ffi.cc +24 -3
  30. package/src/ffi.hh +6 -3
  31. package/src/parser.cc +2 -2
  32. package/src/util.cc +26 -57
  33. package/src/util.hh +17 -1
  34. package/test/misc.c +34 -0
  35. package/vendor/_patches/glfw_001_fix_openbsd_xlib_soname.patch +145 -0
  36. package/vendor/libcc/libcc.hh +4 -1
  37. package/vendor/raylib/src/external/glfw/src/egl_context.c +6 -0
  38. package/vendor/raylib/src/external/glfw/src/osmesa_context.c +2 -0
  39. package/vendor/raylib/src/external/glfw/src/vulkan.c +2 -0
  40. package/vendor/raylib/src/external/glfw/src/x11_init.c +20 -0
  41. package/build/qemu/1.1.3/koffi_darwin_x64.tar.gz +0 -0
  42. package/build/qemu/1.1.3/koffi_freebsd_arm64.tar.gz +0 -0
  43. package/build/qemu/1.1.3/koffi_freebsd_ia32.tar.gz +0 -0
  44. package/build/qemu/1.1.3/koffi_freebsd_x64.tar.gz +0 -0
  45. package/build/qemu/1.1.3/koffi_linux_arm.tar.gz +0 -0
  46. package/build/qemu/1.1.3/koffi_linux_arm64.tar.gz +0 -0
  47. package/build/qemu/1.1.3/koffi_linux_ia32.tar.gz +0 -0
  48. package/build/qemu/1.1.3/koffi_linux_x64.tar.gz +0 -0
  49. package/build/qemu/1.1.3/koffi_openbsd_x64.tar.gz +0 -0
  50. package/build/qemu/1.1.3/koffi_win32_ia32.tar.gz +0 -0
  51. package/build/qemu/1.1.3/koffi_win32_x64.tar.gz +0 -0
package/CMakeLists.txt CHANGED
@@ -34,6 +34,7 @@ set(KOFFI_SRC
34
34
  src/call.cc
35
35
  src/abi_arm32.cc
36
36
  src/abi_arm64.cc
37
+ src/abi_riscv64.cc
37
38
  src/abi_x64_sysv.cc
38
39
  src/abi_x64_win.cc
39
40
  src/abi_x86.cc
@@ -45,6 +46,8 @@ set(KOFFI_SRC
45
46
  if(CMAKE_SIZEOF_VOID_P EQUAL 8)
46
47
  if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch|arm")
47
48
  list(APPEND KOFFI_SRC src/abi_arm64_fwd.S)
49
+ elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "riscv")
50
+ list(APPEND KOFFI_SRC src/abi_riscv64_fwd.S)
48
51
  elseif(WIN32)
49
52
  list(APPEND KOFFI_SRC src/abi_x64_win_fwd.asm)
50
53
  else()
package/README.md CHANGED
@@ -23,23 +23,22 @@ Koffi is a fast and easy-to-use FFI module for Node.js, with support for primiti
23
23
  The following features are planned in the near future:
24
24
 
25
25
  * 1.2: C to JS callbacks
26
- * 1.3: RISC-V support (32 and 64 bit)
27
- * 1.4: Type parser
26
+ * 1.3: Type parser
28
27
 
29
28
  The following combinations of OS and architectures __are officially supported and tested__ at the moment:
30
29
 
31
- ISA / OS | Windows | Linux | macOS | FreeBSD | OpenBSD
32
- ------------------ | -------- | -------- | ----------- | -------- | --------
33
- x86 (IA32) [^1] | 🟩 Yes | 🟩 Yes | ⬜️ N/A | 🟩 Yes | 🟧 Maybe
34
- x86_64 (AMD64) | 🟩 Yes | 🟩 Yes | 🟩 Yes | 🟩 Yes | 🟩 Yes
35
- ARM32 VFP LE | ⬜️ N/A | 🟩 Yes | ⬜️ N/A | 🟧 Maybe | 🟧 Maybe
36
- ARM32 (no VFP) LE | ⬜️ N/A | 🟧 Maybe | ⬜️ N/A | 🟧 Maybe | 🟧 Maybe
37
- ARM64 (AArch64) LE | 🟧 Maybe | 🟩 Yes | 🟩 Yes [^2] | 🟩 Yes | 🟧 Maybe
38
- RISC-V 32 | ⬜️ N/A | 🟥 No | ⬜️ N/A | 🟥 No | 🟥 No
39
- RISC-V 64 | ⬜️ N/A | 🟥 No | ⬜️ N/A | 🟥 No | 🟥 No
40
-
41
- [^1]: The following call conventions are supported: cdecl, stdcall, MS fastcall, thiscall
42
- [^2]: However, we don't provide prebuilt binaries for macOS on Apple M1
30
+ ISA / OS | Windows | Linux | macOS | FreeBSD | OpenBSD
31
+ ------------------ | ----------- | -------- | ----------- | ----------- | --------
32
+ x86 (IA32) [^1] | 🟩 Yes | 🟩 Yes | ⬜️ *N/A* | 🟩 Yes | 🟩 Yes
33
+ x86_64 (AMD64) | 🟩 Yes | 🟩 Yes | 🟩 Yes | 🟩 Yes | 🟩 Yes
34
+ ARM32 LE [^2] | ⬜️ *N/A* | 🟩 Yes | ⬜️ *N/A* | 🟨 Probably | 🟨 Probably
35
+ ARM64 (AArch64) LE | 🟧 Maybe | 🟩 Yes | 🟩 Yes [^3] | 🟩 Yes | 🟨 Probably
36
+ RISC-V 64 [^4] | ⬜️ *N/A* | 🟩 Yes | ⬜️ *N/A* | 🟨 Probably | 🟨 Probably
37
+
38
+ [^1]: The following call conventions are supported: cdecl, stdcall, MS fastcall, thiscall.
39
+ [^2]: The prebuilt binary uses the hard float ABI and expects a VFP coprocessor. Build from source to use Koffi with a different ABI (softfp, soft).
40
+ [^3]: However, we don't provide prebuilt binaries for macOS on Apple M1.
41
+ [^4]: Only the LP64D (double-precision float) gets tested. The LP64 ABI is supported in theory (untested), the LP64F ABI is not supported.
43
42
 
44
43
  This is still in development, bugs are to be expected. More tests will come in the near future.
45
44
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "koffi",
3
- "version": "1.1.3",
3
+ "version": "1.1.4",
4
4
  "description": "Fast and simple FFI (foreign function interface) for Node.js",
5
5
  "keywords": [
6
6
  "foreign",
package/qemu/qemu.js CHANGED
@@ -124,13 +124,12 @@ async function main() {
124
124
  machine.started = false;
125
125
 
126
126
  machine.qemu.accelerate = null;
127
- if (accelerate) {
127
+ if (accelerate && (machine.qemu.binary == 'qemu-system-x86_64' ||
128
+ machine.qemu.binary == 'qemu-system-i386')) {
128
129
  if (process.platform == 'linux') {
129
- if (process.arch == 'x64' && (machine.info.arch == 'x64' || machine.info.arch == 'ia32'))
130
- machine.qemu.accelerate = 'kvm';
130
+ machine.qemu.accelerate = 'kvm';
131
131
  } else if (process.platform == 'win32') {
132
- if (process.arch == 'x64' && machine.info.arch == 'x64')
133
- machine.qemu.accelerate = 'whpx';
132
+ machine.qemu.accelerate = 'whpx';
134
133
  }
135
134
  }
136
135
  }
@@ -141,19 +140,23 @@ async function main() {
141
140
 
142
141
  for (let pattern of patterns) {
143
142
  let re = minimatch.makeRe(pattern);
143
+ let match = false;
144
144
 
145
145
  for (let name in machines_map) {
146
146
  let machine = machines_map[name];
147
147
 
148
- if (name.match(re) || machine.name.match(re))
148
+ if (name.match(re) || machine.name.match(re)) {
149
149
  machines.add(name);
150
+ match = true;
151
+ }
150
152
  }
151
- }
152
153
 
153
- if (!machines.size) {
154
- console.log('Could not match any machine');
155
- process.exit(1);
154
+ if (!match) {
155
+ console.log(`Pattern '${pattern}' does not match any machine`);
156
+ process.exit(1);
157
+ }
156
158
  }
159
+
157
160
  } else {
158
161
  machines = new Set(Object.keys(machines_map));
159
162
 
@@ -461,6 +461,97 @@
461
461
  "commands": {
462
462
  "Test Sync": "node test/sync.js",
463
463
  "Test Async": "node test/async.js",
464
+ "Test Raylib": "xvfb-run node test/raylib.js",
465
+ "Test SQLite": "node test/sqlite.js"
466
+ }
467
+ }
468
+ }
469
+ },
470
+
471
+ "openbsd_i386": {
472
+ "name": "OpenBSD i386",
473
+
474
+ "qemu": {
475
+ "binary": "qemu-system-x86_64",
476
+ "arguments": ["-m", "1G", "-smp", 2, "-hda", "disk.qcow2", "-netdev", "user,id=mynet,hostfwd=tcp::22211-:22", "-device", "e1000,netdev=mynet", "-vnc", "127.0.0.1:21"]
477
+ },
478
+
479
+ "info": {
480
+ "version": 1,
481
+ "platform": "openbsd",
482
+ "arch": "ia32",
483
+
484
+ "ssh_port": 22211,
485
+ "vnc_port": 5921,
486
+
487
+ "username": "openbsd",
488
+ "password": "openbsd",
489
+
490
+ "shutdown": "sudo shutdown -p now"
491
+ },
492
+
493
+ "builds": {
494
+ "OpenBSD i386": {
495
+ "directory": "/home/openbsd/luigi",
496
+ "build": "node ../cnoke/cnoke.js"
497
+ }
498
+ },
499
+
500
+ "tests": {
501
+ "OpenBSD i386": {
502
+ "directory": "/home/openbsd/luigi",
503
+ "build": {
504
+ "Build": "node ../cnoke/cnoke.js -C test"
505
+ },
506
+ "commands": {
507
+ "Test Sync": "node test/sync.js",
508
+ "Test Async": "node test/async.js",
509
+ "Test Raylib": "xvfb-run node test/raylib.js",
510
+ "Test SQLite": "node test/sqlite.js"
511
+ }
512
+ }
513
+ }
514
+ },
515
+
516
+ "debian_riscv64": {
517
+ "name": "Debian RISC-V 64",
518
+
519
+ "qemu": {
520
+ "binary": "qemu-system-riscv64",
521
+ "arguments": ["-machine", "virt", "-cpu", "rv64", "-m", "1G", "-smp", 2, "-device", "virtio-blk-device,drive=hd", "-drive", "file=disk.qcow2,if=none,id=hd", "-device", "virtio-net-device,netdev=net", "-netdev", "user,id=net,hostfwd=tcp::22212-:22", "-bios", "fw_jump.elf", "-kernel", "uboot.elf", "-append", "root=LABEL=rootfs console=ttyS0", "-vnc", "127.0.0.1:22"]
522
+ },
523
+
524
+ "info": {
525
+ "version": 1,
526
+ "platform": "linux",
527
+ "arch": "riscv64",
528
+
529
+ "ssh_port": 22212,
530
+ "vnc_port": 5912,
531
+
532
+ "username": "debian",
533
+ "password": "debian",
534
+
535
+ "shutdown": "sudo poweroff"
536
+ },
537
+
538
+ "builds": {
539
+ "Linux RISC-V 64": {
540
+ "directory": "/home/debian/luigi",
541
+ "build": "node ../cnoke/cnoke.js"
542
+ }
543
+ },
544
+
545
+ "tests": {
546
+ "Linux RISC-V 64": {
547
+ "directory": "/home/debian/luigi",
548
+ "build": {
549
+ "Build": "node ../cnoke/cnoke.js -C test"
550
+ },
551
+ "commands": {
552
+ "Test Sync": "node test/sync.js",
553
+ "Test Async": "node test/async.js",
554
+ "Test Raylib": "xvfb-run node test/raylib.js",
464
555
  "Test SQLite": "node test/sqlite.js"
465
556
  }
466
557
  }
@@ -47,3 +47,14 @@ d79538ac489f1948b04b65f12c5618c28e4a5de0be062f5cf1d73e422a091a37 *qemu/macos_x64
47
47
  9dcdabfc12ad2ba2da1b9c3d95dc46311a12d6e3190f1bfd0c9b184ac1577c94 *qemu/openbsd_x64/install.sh
48
48
  6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b *qemu/openbsd_x64/VERSION
49
49
  7b66bdf8b77fd1c6256ffdab623e37ce099797ad657dcd25af5df0486fadce37 *qemu/openbsd_x64/xvfb-run.sh
50
+ 570bc6da16ca3b2b068963e7960e76fd23df3ada54398dfc6b6ddf97348ef5d7 *qemu/openbsd_i386/disk.qcow2
51
+ b82c940781ee678499851e1d2aa4868b7154a16ecc4f01c6c56940276c02748f *qemu/openbsd_i386/install.sh
52
+ 6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b *qemu/openbsd_i386/VERSION
53
+ 7b66bdf8b77fd1c6256ffdab623e37ce099797ad657dcd25af5df0486fadce37 *qemu/openbsd_i386/xvfb-run.sh
54
+ 64048432020bda960f397b5a138ea98aa6bbd42db02e8bb34ff3b9320763e36d *qemu/debian_riscv64/uboot.elf
55
+ 0bdd93879f87c338d62422a65fdcba4d8c834848f2305f31b916539cb523e9e8 *qemu/debian_riscv64/readme.txt
56
+ 76a5819cdacc8fe284370f441820620e911877122068a3b391fa064b7e9eb180 *qemu/debian_riscv64/initrd
57
+ 6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b *qemu/debian_riscv64/VERSION
58
+ 7b6a36b0c2cdd85f3bbee4156de6c65a6f9b01b6bdf95eeb327b6182807ef111 *qemu/debian_riscv64/disk.qcow2
59
+ 45755dd1fec10b7d5d67156bf806d3069a9285d18c5b16f06050e5115cc93f18 *qemu/debian_riscv64/kernel
60
+ 16a1077672903239e2e4451e6898f9d813b369f9ceede30da8937a1361a050d7 *qemu/debian_riscv64/fw_jump.elf
package/src/abi_arm32.cc CHANGED
@@ -39,48 +39,19 @@ extern "C" uint64_t ForwardCallXGG(const void *func, uint8_t *sp);
39
39
  extern "C" float ForwardCallXF(const void *func, uint8_t *sp);
40
40
  extern "C" HfaRet ForwardCallXDDDD(const void *func, uint8_t *sp);
41
41
 
42
- static bool DetectVFP()
42
+ static inline int IsHFA(const TypeInfo *type)
43
43
  {
44
- // If anything fails, assume VFP is available (true for most Linux platforms)
45
- static volatile bool vfp = true;
46
- static jmp_buf env;
47
-
48
- struct sigaction prev;
49
- SetSignalHandler(SIGILL, [](int) {
50
- vfp = false;
51
- longjmp(env, 1);
52
- }, &prev);
53
-
54
- if (!setjmp(env)) {
55
- __asm__ volatile("vmov.f64 d0, #1.0" ::: "d0");
56
- }
57
-
58
- return vfp;
59
- }
60
-
61
- static inline bool HasVFP()
62
- {
63
- static bool init = false;
64
- static bool vfp;
65
-
66
- if (!init) {
67
- vfp = DetectVFP();
68
- init = true;
69
- }
70
-
71
- return vfp;
72
- }
73
-
74
- static inline bool IsHFA(const TypeInfo *type)
75
- {
76
- return HasVFP() && IsHFA(type, 1, 4);
44
+ #ifdef __ARM_PCS_VFP
45
+ return IsHFA(type, 1, 4);
46
+ #else
47
+ return false;
48
+ #endif
77
49
  }
78
50
 
79
51
  bool AnalyseFunction(InstanceData *, FunctionInfo *func)
80
52
  {
81
- if (IsHFA(func->ret.type)) {
82
- func->ret.vec_count = func->ret.type->members.len *
83
- (func->ret.type->members[0].type->size / 4);
53
+ if (int hfa = IsHFA(func->ret.type); hfa) {
54
+ func->ret.vec_count = hfa;
84
55
  } else if (func->ret.type->primitive != PrimitiveKind::Record ||
85
56
  func->ret.type->size <= 4) {
86
57
  func->ret.gpr_count = (func->ret.type->size > 4) ? 2 : 1;
@@ -123,13 +94,12 @@ bool AnalyseFunction(InstanceData *, FunctionInfo *func)
123
94
  }
124
95
  } break;
125
96
  case PrimitiveKind::Record: {
126
- if (IsHFA(param.type)) {
127
- int vec_count = (int)(param.type->members.len *
128
- param.type->members[0].type->size / 4);
97
+ int hfa = IsHFA(param.type);
129
98
 
130
- if (vec_count <= vec_avail) {
131
- param.vec_count = vec_count;
132
- vec_avail -= vec_count;
99
+ if (hfa) {
100
+ if (hfa <= vec_avail) {
101
+ param.vec_count = hfa;
102
+ vec_avail -= hfa;
133
103
  } else {
134
104
  vec_avail = 0;
135
105
  started_stack = true;
@@ -151,7 +121,12 @@ bool AnalyseFunction(InstanceData *, FunctionInfo *func)
151
121
  case PrimitiveKind::Array: { RG_UNREACHABLE(); } break;
152
122
  case PrimitiveKind::Float32:
153
123
  case PrimitiveKind::Float64: {
154
- bool vfp = HasVFP() && !param.variadic;
124
+ #ifdef __ARM_PCS_VFP
125
+ bool vfp = !param.variadic;
126
+ #else
127
+ bool vfp = false;
128
+ #endif
129
+
155
130
  Size need = param.type->size / 4;
156
131
 
157
132
  if (vfp) {
@@ -413,8 +388,7 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
413
388
  }
414
389
  }
415
390
 
416
- stack = MakeSpan(mem->stack.end(), old_stack_mem.end() - mem->stack.end());
417
- heap = MakeSpan(old_heap_mem.ptr, mem->heap.ptr - old_heap_mem.ptr);
391
+ sp = mem->stack.end();
418
392
 
419
393
  return true;
420
394
  }
@@ -423,8 +397,8 @@ void CallData::Execute()
423
397
  {
424
398
  #define PERFORM_CALL(Suffix) \
425
399
  ([&]() { \
426
- auto ret = (func->forward_fp ? ForwardCallX ## Suffix(func->func, stack.ptr) \
427
- : ForwardCall ## Suffix(func->func, stack.ptr)); \
400
+ auto ret = (func->forward_fp ? ForwardCallX ## Suffix(func->func, sp) \
401
+ : ForwardCall ## Suffix(func->func, sp)); \
428
402
  return ret; \
429
403
  })()
430
404
 
@@ -446,7 +420,7 @@ void CallData::Execute()
446
420
  case PrimitiveKind::Record: {
447
421
  if (func->ret.vec_count) {
448
422
  HfaRet ret = PERFORM_CALL(DDDD);
449
- memcpy_safe(&result.buf, &ret, RG_SIZE(ret));
423
+ memcpy(&result.buf, &ret, RG_SIZE(ret));
450
424
  } else {
451
425
  result.u64 = PERFORM_CALL(GG);
452
426
  }
package/src/abi_arm64.cc CHANGED
@@ -41,15 +41,15 @@ extern "C" X0X1Ret ForwardCallXGG(const void *func, uint8_t *sp);
41
41
  extern "C" float ForwardCallXF(const void *func, uint8_t *sp);
42
42
  extern "C" HfaRet ForwardCallXDDDD(const void *func, uint8_t *sp);
43
43
 
44
- static inline bool IsHFA(const TypeInfo *type)
44
+ static inline int IsHFA(const TypeInfo *type)
45
45
  {
46
46
  return IsHFA(type, 1, 4);
47
47
  }
48
48
 
49
49
  bool AnalyseFunction(InstanceData *, FunctionInfo *func)
50
50
  {
51
- if (IsHFA(func->ret.type)) {
52
- func->ret.vec_count = func->ret.type->members.len;
51
+ if (int hfa = IsHFA(func->ret.type); hfa) {
52
+ func->ret.vec_count = hfa;
53
53
  } else if (func->ret.type->size <= 16) {
54
54
  func->ret.gpr_count = (func->ret.type->size + 7) / 8;
55
55
  } else {
@@ -86,10 +86,12 @@ bool AnalyseFunction(InstanceData *, FunctionInfo *func)
86
86
  }
87
87
  } break;
88
88
  case PrimitiveKind::Record: {
89
- bool hfa = IsHFA(param.type);
89
+ int hfa = IsHFA(param.type);
90
90
 
91
91
  #if defined(_WIN32)
92
- hfa &= !param.variadic;
92
+ if (!param.variadic) {
93
+ hfa = 0;
94
+ }
93
95
  #elif defined(__APPLE__)
94
96
  if (param.variadic) {
95
97
  param.use_memory = (param.type->size > 16);
@@ -98,11 +100,9 @@ bool AnalyseFunction(InstanceData *, FunctionInfo *func)
98
100
  #endif
99
101
 
100
102
  if (hfa) {
101
- int vec_count = (int)param.type->members.len;
102
-
103
- if (vec_count <= vec_avail) {
104
- param.vec_count = vec_count;
105
- vec_avail -= vec_count;
103
+ if (hfa <= vec_avail) {
104
+ param.vec_count = hfa;
105
+ vec_avail -= hfa;
106
106
  } else {
107
107
  vec_avail = 0;
108
108
  }
@@ -395,8 +395,7 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
395
395
  }
396
396
  }
397
397
 
398
- stack = MakeSpan(mem->stack.end(), old_stack_mem.end() - mem->stack.end());
399
- heap = MakeSpan(old_heap_mem.ptr, mem->heap.ptr - old_heap_mem.ptr);
398
+ sp = mem->stack.end();
400
399
 
401
400
  return true;
402
401
  }
@@ -405,8 +404,8 @@ void CallData::Execute()
405
404
  {
406
405
  #define PERFORM_CALL(Suffix) \
407
406
  ([&]() { \
408
- auto ret = (func->forward_fp ? ForwardCallX ## Suffix(func->func, stack.ptr) \
409
- : ForwardCall ## Suffix(func->func, stack.ptr)); \
407
+ auto ret = (func->forward_fp ? ForwardCallX ## Suffix(func->func, sp) \
408
+ : ForwardCall ## Suffix(func->func, sp)); \
410
409
  return ret; \
411
410
  })()
412
411
 
@@ -428,10 +427,10 @@ void CallData::Execute()
428
427
  case PrimitiveKind::Record: {
429
428
  if (func->ret.gpr_count) {
430
429
  X0X1Ret ret = PERFORM_CALL(GG);
431
- memcpy_safe(&result.buf, &ret, RG_SIZE(ret));
430
+ memcpy(&result.buf, &ret, RG_SIZE(ret));
432
431
  } else if (func->ret.vec_count) {
433
432
  HfaRet ret = PERFORM_CALL(DDDD);
434
- memcpy_safe(&result.buf, &ret, RG_SIZE(ret));
433
+ memcpy(&result.buf, &ret, RG_SIZE(ret));
435
434
  } else {
436
435
  PERFORM_CALL(GG);
437
436
  }