koffi 1.1.0 → 1.1.3

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 (43) hide show
  1. package/CMakeLists.txt +10 -7
  2. package/README.md +29 -28
  3. package/build/qemu/1.1.3/koffi_darwin_x64.tar.gz +0 -0
  4. package/build/qemu/1.1.3/koffi_freebsd_arm64.tar.gz +0 -0
  5. package/build/qemu/1.1.3/koffi_freebsd_ia32.tar.gz +0 -0
  6. package/build/qemu/1.1.3/koffi_freebsd_x64.tar.gz +0 -0
  7. package/build/qemu/1.1.3/koffi_linux_arm.tar.gz +0 -0
  8. package/build/qemu/1.1.3/koffi_linux_arm64.tar.gz +0 -0
  9. package/build/qemu/1.1.3/koffi_linux_ia32.tar.gz +0 -0
  10. package/build/qemu/1.1.3/koffi_linux_x64.tar.gz +0 -0
  11. package/build/qemu/1.1.3/koffi_openbsd_x64.tar.gz +0 -0
  12. package/build/qemu/1.1.3/koffi_win32_ia32.tar.gz +0 -0
  13. package/build/qemu/1.1.3/koffi_win32_x64.tar.gz +0 -0
  14. package/package.json +2 -2
  15. package/qemu/qemu.js +1 -1
  16. package/qemu/registry/machines.json +47 -3
  17. package/qemu/registry/sha256sum.txt +16 -12
  18. package/src/abi_arm32.cc +43 -4
  19. package/src/abi_arm64.cc +22 -5
  20. package/src/abi_x64_sysv.cc +1 -1
  21. package/src/abi_x64_win.cc +1 -1
  22. package/src/abi_x86.cc +10 -4
  23. package/src/call.cc +213 -44
  24. package/src/call.hh +2 -2
  25. package/src/ffi.cc +63 -36
  26. package/src/ffi.hh +10 -4
  27. package/src/parser.cc +46 -24
  28. package/src/parser.hh +3 -1
  29. package/src/util.hh +1 -1
  30. package/test/CMakeLists.txt +3 -0
  31. package/test/misc.c +17 -0
  32. package/vendor/libcc/libcc.cc +7 -7
  33. package/vendor/libcc/libcc.hh +4 -1
  34. package/build/qemu/1.1.0/koffi_darwin_x64.tar.gz +0 -0
  35. package/build/qemu/1.1.0/koffi_freebsd_arm64.tar.gz +0 -0
  36. package/build/qemu/1.1.0/koffi_freebsd_ia32.tar.gz +0 -0
  37. package/build/qemu/1.1.0/koffi_freebsd_x64.tar.gz +0 -0
  38. package/build/qemu/1.1.0/koffi_linux_arm.tar.gz +0 -0
  39. package/build/qemu/1.1.0/koffi_linux_arm64.tar.gz +0 -0
  40. package/build/qemu/1.1.0/koffi_linux_ia32.tar.gz +0 -0
  41. package/build/qemu/1.1.0/koffi_linux_x64.tar.gz +0 -0
  42. package/build/qemu/1.1.0/koffi_win32_ia32.tar.gz +0 -0
  43. package/build/qemu/1.1.0/koffi_win32_x64.tar.gz +0 -0
package/CMakeLists.txt CHANGED
@@ -23,6 +23,9 @@ if(MSVC)
23
23
  else()
24
24
  add_compile_options(-Wall -Wextra -Wno-missing-field-initializers
25
25
  -Wno-unused-parameter -Wno-class-memaccess)
26
+ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
27
+ add_compile_options(-Wno-unknown-warning-option)
28
+ endif()
26
29
  endif()
27
30
 
28
31
  # ---- Koffi ----
@@ -40,20 +43,20 @@ set(KOFFI_SRC
40
43
  vendor/libcc/libcc.cc
41
44
  )
42
45
  if(CMAKE_SIZEOF_VOID_P EQUAL 8)
43
- if(WIN32)
44
- list(APPEND KOFFI_SRC src/abi_x64_win_fwd.asm)
45
- elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|arm64")
46
+ if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch|arm")
46
47
  list(APPEND KOFFI_SRC src/abi_arm64_fwd.S)
48
+ elseif(WIN32)
49
+ list(APPEND KOFFI_SRC src/abi_x64_win_fwd.asm)
47
50
  else()
48
51
  list(APPEND KOFFI_SRC src/abi_x64_sysv_fwd.S)
49
52
  endif()
50
53
  elseif(CMAKE_SIZEOF_VOID_P EQUAL 4)
51
- if(WIN32)
54
+ if(CMAKE_SYSTEM_PROCESSOR MATCHES "arm")
55
+ list(APPEND KOFFI_SRC src/abi_arm32_fwd.S)
56
+ elseif(WIN32)
52
57
  list(APPEND KOFFI_SRC src/abi_x86_fwd.asm)
53
- elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "i[3456]86|x86|AMD64")
58
+ else()
54
59
  list(APPEND KOFFI_SRC src/abi_x86_fwd.S)
55
- elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "armv[678]l")
56
- list(APPEND KOFFI_SRC src/abi_arm32_fwd.S)
57
60
  endif()
58
61
  endif()
59
62
 
package/README.md CHANGED
@@ -13,7 +13,7 @@
13
13
  * [Raylib results](#raylib-results)
14
14
  - [Tests](#tests)
15
15
  - [Compilation](#compilation)
16
- * [Windows](#windows)
16
+ * [Windows](#windows-1)
17
17
  * [Other platforms](#other-platforms)
18
18
 
19
19
  # Introduction
@@ -23,33 +23,23 @@ 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: Type parser
27
-
28
- The following platforms __are officially supported and tested__ at the moment:
29
-
30
- Platform | Architecture | Sync calls | Async calls | Callbacks | Pre-built binary
31
- --------- | -------------------------------- | ---------- | ----------- | --------- | ----------------
32
- Windows | x86 (cdecl, stdcall, fastcall) | 🟩 Yes | 🟩 Yes | 🟥 No | 🟩 Yes
33
- Windows | x86_64 | 🟩 Yes | 🟩 Yes | 🟥 No | 🟩 Yes
34
- Linux | x86 | 🟩 Yes | 🟩 Yes | 🟥 No | 🟩 Yes
35
- Linux | x86_64 | 🟩 Yes | 🟩 Yes | 🟥 No | 🟩 Yes
36
- Linux | ARM32+VFP Little Endian | 🟩 Yes | 🟩 Yes | 🟥 No | 🟩 Yes
37
- Linux | ARM64 Little Endian | 🟩 Yes | 🟩 Yes | 🟥 No | 🟩 Yes
38
- FreeBSD | x86 | 🟩 Yes | 🟩 Yes | 🟥 No | 🟩 Yes
39
- FreeBSD | x86_64 | 🟩 Yes | 🟩 Yes | 🟥 No | 🟩 Yes
40
- FreeBSD | ARM64 Little Endian | 🟩 Yes | 🟩 Yes | 🟥 No | 🟩 Yes
41
- macOS | x86_64 | 🟩 Yes | 🟩 Yes | 🟥 No | 🟩 Yes
42
- macOS | ARM64 (M1) Little Endian | 🟩 Yes | 🟩 Yes | 🟥 No | 🟥 No
43
- OpenBSD | x86_64 | 🟧 Maybe | 🟧 Maybe | 🟥 No | 🟥 No
44
- OpenBSD | x86 | 🟧 Maybe | 🟧 Maybe | 🟥 No | 🟥 No
45
- OpenBSD | ARM64 Little Endian | 🟧 Maybe | 🟧 Maybe | 🟥 No | 🟥 No
46
- NetBSD | x86_64 | 🟧 Maybe | 🟧 Maybe | 🟥 No | 🟥 No
47
- NetBSD | x86 | 🟧 Maybe | 🟧 Maybe | 🟥 No | 🟥 No
48
- NetBSD | ARM64 Little Endian | 🟧 Maybe | 🟧 Maybe | 🟥 No | 🟥 No
49
-
50
- 🟩 Tested, fully operational
51
- 🟧 May work, but not actively tested
52
- 🟥 Does not work yet
26
+ * 1.3: RISC-V support (32 and 64 bit)
27
+ * 1.4: Type parser
28
+
29
+ The following combinations of OS and architectures __are officially supported and tested__ at the moment:
30
+
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
53
43
 
54
44
  This is still in development, bugs are to be expected. More tests will come in the near future.
55
45
 
@@ -231,6 +221,8 @@ Koffi exposes three functions to explore type information:
231
221
  Fixed-size arrays are declared with `koffi.array(type, length)`. Just like in C, they cannot be passed
232
222
  as functions parameters (they degenerate to pointers), or returned by value. You can however embed them in struct types.
233
223
 
224
+ ### JS typed arrays
225
+
234
226
  Special rules apply for arrays of primitive integer and float types (uint32_t, double, etc...):
235
227
  - When converting from JS to C, Koffi can take a normal Array (e.g. `[1, 2]`) or a TypedArray of the correct type (e.g. `Uint8Array` for an array of `uint8_t` numbers)
236
228
  - When converting from C to JS (for return value or output parameters), Koffi will by default use a TypedArray. But you can change this behavior when you create the array type with the optional hint argument: `koffi.array('uint8_t', 64, 'array')`
@@ -258,6 +250,14 @@ console.log(ReturnFoo1({ i: 5, a16: [6, 8] })) // Prints { i: 5, a16: Int16Array
258
250
  console.log(ReturnFoo2({ i: 5, a16: [6, 8] })) // Prints { i: 5, a16: [6, 8] }
259
251
  ```
260
252
 
253
+ ### C strings
254
+
255
+ Koffi can also convert JS strings to fixed-sized arrays in the following cases:
256
+ - char (or int8_t) arrays are filled with the UTF-8 encoded string, truncated if needed. The buffer is always NUL-terminated.
257
+ - char16 (or int16_t) arrays are filled with the UTF-16 encoded string, truncated if needed. The buffer is always NUL-terminated.
258
+
259
+ The reverse case is also true, Koffi can convert a C fixed-size buffer to a JS string. Use the `string` array hint to do this (e.g. `koffi.array('char', 8, 'string')`).
260
+
261
261
  ## Variadic functions
262
262
 
263
263
  Variadic functions are declared with an ellipsis as the last argument.
@@ -267,6 +267,7 @@ In order to call a variadic function, you must provide two Javascript arguments
267
267
  ```js
268
268
  const printf = lib.func('printf', 'int', ['string', '...']);
269
269
 
270
+ // The variadic arguments are: 6 (int), 8.5 (double), 'THE END' (const char *)
270
271
  printf('Integer %d, double %g, string %s', 'int', 6, 'double', 8.5, 'string', 'THE END');
271
272
  ```
272
273
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "koffi",
3
- "version": "1.1.0",
3
+ "version": "1.1.3",
4
4
  "description": "Fast and simple FFI (foreign function interface) for Node.js",
5
5
  "keywords": [
6
6
  "foreign",
@@ -24,7 +24,7 @@
24
24
  },
25
25
  "license": "AGPL-3.0",
26
26
  "dependencies": {
27
- "cnoke": "^1.0.7"
27
+ "cnoke": "^1.0.9"
28
28
  },
29
29
  "devDependencies": {
30
30
  "chalk": "^4.1.2",
package/qemu/qemu.js CHANGED
@@ -395,7 +395,7 @@ async function pack() {
395
395
  }));
396
396
 
397
397
  let status = copied ? chalk.bold.green('[ok]') : chalk.bold.red('[error]');
398
- log(machine, 'Download', status);
398
+ log(machine, 'Pack', status);
399
399
  }));
400
400
  }
401
401
 
@@ -253,7 +253,7 @@
253
253
  },
254
254
 
255
255
  "info": {
256
- "version": 1,
256
+ "version": 2,
257
257
  "platform": "freebsd",
258
258
  "arch": "x64",
259
259
 
@@ -298,7 +298,7 @@
298
298
  },
299
299
 
300
300
  "info": {
301
- "version": 1,
301
+ "version": 2,
302
302
  "platform": "freebsd",
303
303
  "arch": "ia32",
304
304
 
@@ -343,7 +343,7 @@
343
343
  },
344
344
 
345
345
  "info": {
346
- "version": 1,
346
+ "version": 2,
347
347
  "platform": "freebsd",
348
348
  "arch": "arm64",
349
349
 
@@ -421,5 +421,49 @@
421
421
  }
422
422
  }
423
423
  }
424
+ },
425
+
426
+ "openbsd_x64": {
427
+ "name": "OpenBSD x64",
428
+
429
+ "qemu": {
430
+ "binary": "qemu-system-x86_64",
431
+ "arguments": ["-m", "1G", "-smp", 2, "-hda", "disk.qcow2", "-netdev", "user,id=mynet,hostfwd=tcp::22210-:22", "-device", "e1000,netdev=mynet", "-vnc", "127.0.0.1:20"]
432
+ },
433
+
434
+ "info": {
435
+ "version": 1,
436
+ "platform": "openbsd",
437
+ "arch": "x64",
438
+
439
+ "ssh_port": 22210,
440
+ "vnc_port": 5920,
441
+
442
+ "username": "openbsd",
443
+ "password": "openbsd",
444
+
445
+ "shutdown": "sudo shutdown -p now"
446
+ },
447
+
448
+ "builds": {
449
+ "OpenBSD x64": {
450
+ "directory": "/home/openbsd/luigi",
451
+ "build": "node ../cnoke/cnoke.js"
452
+ }
453
+ },
454
+
455
+ "tests": {
456
+ "OpenBSD x64": {
457
+ "directory": "/home/openbsd/luigi",
458
+ "build": {
459
+ "Build": "node ../cnoke/cnoke.js -C test"
460
+ },
461
+ "commands": {
462
+ "Test Sync": "node test/sync.js",
463
+ "Test Async": "node test/async.js",
464
+ "Test SQLite": "node test/sqlite.js"
465
+ }
466
+ }
467
+ }
424
468
  }
425
469
  }
@@ -22,20 +22,20 @@ ed05b84b7759ec945bb5422305a3a3c5b61d89e231844656ea31e07d89451a20 *qemu/debian_i3
22
22
  292a61c415a99a9c63a9337f1e074bea6c5df594e16bc40ded76141963c67ea4 *qemu/debian_i386/install.sh
23
23
  8dc1360e1c23ea21931f5eb94461d15fac6bcec00cf42bf1e590b7fb937e80c1 *qemu/debian_i386/initrd.img-5.10.0-12-686-pae
24
24
  338602d969f953cd88c2df736b9f8f7ee53029d233c83c7398258ae5bcb4e286 *qemu/debian_i386/disk.qcow2
25
- 6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b *qemu/freebsd_arm64/VERSION
26
- 5daea533330eb8d2f8df946561680e09f8dacc467fbf03d28caa2115d94386b5 *qemu/freebsd_arm64/QEMU_EFI.img
27
- a083e4e1f58f477e4a9e8ae30f75660e82275b88f77b5e2c7f5d6ee1deb43b41 *qemu/freebsd_arm64/varstore.img
25
+ e5d9d3e1e4a5c980fce4ef3aab5e29b9607b8e5da6e9fe58c3f396009e283cff *qemu/freebsd_arm64/disk.qcow2
28
26
  53a4dc48317e1c9de4a088cd45ba39a1810f0bafad75c7f810e18d4e3eb340e3 *qemu/freebsd_arm64/install.sh
29
- a19ad06aec7972f3b95a56fb9bb8ac8a6afcd61b586f398691d58c704e8c466e *qemu/freebsd_arm64/disk.qcow2
30
- 10f2bc603b171368cacda43485f8f72567af0a9a490b7e0fa0c14c983ae66f16 *qemu/freebsd_arm64/xvfb-run.sh
31
- 6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b *qemu/freebsd_x64/VERSION
32
- 06eef544fe9c61d3905b0e588c306d1dedac7ee7d4c01df154ff6ed64e25ef77 *qemu/freebsd_x64/install.sh
33
- 060b66901313ddfcd434c20a7b13052b3e5126e43c4e44884b85191560bd99eb *qemu/freebsd_x64/disk.qcow2
34
- 10f2bc603b171368cacda43485f8f72567af0a9a490b7e0fa0c14c983ae66f16 *qemu/freebsd_x64/xvfb-run.sh
35
- 6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b *qemu/freebsd_i386/VERSION
27
+ 5daea533330eb8d2f8df946561680e09f8dacc467fbf03d28caa2115d94386b5 *qemu/freebsd_arm64/QEMU_EFI.img
28
+ 8ac20d46117a5a15761bf3070e365141b96ee3283250824f113029e106c62a50 *qemu/freebsd_arm64/varstore.img
29
+ d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35 *qemu/freebsd_arm64/VERSION
30
+ 73837b3991eae13f6c346955ea4aa419c8c168cadf70e0a38446db60cf47b0e9 *qemu/freebsd_arm64/xvfb-run.sh
31
+ fd0e51c43d7848564a81ddcb3eecf49103251bffcf25315ef87db01350ad4ac5 *qemu/freebsd_i386/disk.qcow2
36
32
  bdeac2cca1d22d70c2d388a50709d5cba3069bbd4bd1bcb102955b0ee12ca3e9 *qemu/freebsd_i386/install.sh
37
- 8191cea63d738cdca6df0b2d2d6953675e1dd33cac4d98fff88ba4367b182b64 *qemu/freebsd_i386/disk.qcow2
38
- 10f2bc603b171368cacda43485f8f72567af0a9a490b7e0fa0c14c983ae66f16 *qemu/freebsd_i386/xvfb-run.sh
33
+ d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35 *qemu/freebsd_i386/VERSION
34
+ 73837b3991eae13f6c346955ea4aa419c8c168cadf70e0a38446db60cf47b0e9 *qemu/freebsd_i386/xvfb-run.sh
35
+ 41649d2f5959388e1c5d8ee89bb084795470a8b9e68d87861b4e95e4102b62cf *qemu/freebsd_x64/disk.qcow2
36
+ 06eef544fe9c61d3905b0e588c306d1dedac7ee7d4c01df154ff6ed64e25ef77 *qemu/freebsd_x64/install.sh
37
+ d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35 *qemu/freebsd_x64/VERSION
38
+ 73837b3991eae13f6c346955ea4aa419c8c168cadf70e0a38446db60cf47b0e9 *qemu/freebsd_x64/xvfb-run.sh
39
39
  16a4f09b3e70b97f5cfb1cf9b913d67d0ec45c4342d202cc9a2b2cfee852a8de *qemu/macos_x64/ESP.qcow2
40
40
  5d2ac383371b408398accee7ec27c8c09ea5b74a0de0ceea6513388b15be5d1e *qemu/macos_x64/OVMF_VARS.fd
41
41
  d79538ac489f1948b04b65f12c5618c28e4a5de0be062f5cf1d73e422a091a37 *qemu/macos_x64/install.txt
@@ -43,3 +43,7 @@ d79538ac489f1948b04b65f12c5618c28e4a5de0be062f5cf1d73e422a091a37 *qemu/macos_x64
43
43
  5cc2d42949c7e4e763db0abeb88299972bafef991d87dbf744a5108ef9190f6f *qemu/macos_x64/OVMF_VARS-1024x768.fd
44
44
  53c234e5e8472b6ac51c1ae1cab3fe06fad053beb8ebfd8977b010655bfdd3c3 *qemu/macos_x64/VERSION
45
45
  2a247500e8ad9aa479994097ba5976bd881fde4de1516abd14491f3dba9fe060 *qemu/macos_x64/OVMF_CODE.fd
46
+ 3a3395f70240d8e3137dfe06ef7dd76255dc597626e087d33abdcc65710f3dff *qemu/openbsd_x64/disk.qcow2
47
+ 9dcdabfc12ad2ba2da1b9c3d95dc46311a12d6e3190f1bfd0c9b184ac1577c94 *qemu/openbsd_x64/install.sh
48
+ 6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b *qemu/openbsd_x64/VERSION
49
+ 7b66bdf8b77fd1c6256ffdab623e37ce099797ad657dcd25af5df0486fadce37 *qemu/openbsd_x64/xvfb-run.sh
package/src/abi_arm32.cc CHANGED
@@ -11,7 +11,7 @@
11
11
  // You should have received a copy of the GNU Affero General Public License
12
12
  // along with this program. If not, see https://www.gnu.org/licenses/.
13
13
 
14
- #if defined(__arm__)
14
+ #if defined(__arm__) || (defined(__M_ARM) && !defined(_M_ARM64))
15
15
 
16
16
  #include "vendor/libcc/libcc.hh"
17
17
  #include "ffi.hh"
@@ -19,6 +19,8 @@
19
19
  #include "util.hh"
20
20
 
21
21
  #include <napi.h>
22
+ #include <signal.h>
23
+ #include <setjmp.h>
22
24
 
23
25
  namespace RG {
24
26
 
@@ -37,9 +39,46 @@ extern "C" uint64_t ForwardCallXGG(const void *func, uint8_t *sp);
37
39
  extern "C" float ForwardCallXF(const void *func, uint8_t *sp);
38
40
  extern "C" HfaRet ForwardCallXDDDD(const void *func, uint8_t *sp);
39
41
 
42
+ static bool DetectVFP()
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);
77
+ }
78
+
40
79
  bool AnalyseFunction(InstanceData *, FunctionInfo *func)
41
80
  {
42
- if (IsHFA(func->ret.type, 1, 4)) {
81
+ if (IsHFA(func->ret.type)) {
43
82
  func->ret.vec_count = func->ret.type->members.len *
44
83
  (func->ret.type->members[0].type->size / 4);
45
84
  } else if (func->ret.type->primitive != PrimitiveKind::Record ||
@@ -84,7 +123,7 @@ bool AnalyseFunction(InstanceData *, FunctionInfo *func)
84
123
  }
85
124
  } break;
86
125
  case PrimitiveKind::Record: {
87
- if (IsHFA(param.type, 1, 4)) {
126
+ if (IsHFA(param.type)) {
88
127
  int vec_count = (int)(param.type->members.len *
89
128
  param.type->members[0].type->size / 4);
90
129
 
@@ -112,8 +151,8 @@ bool AnalyseFunction(InstanceData *, FunctionInfo *func)
112
151
  case PrimitiveKind::Array: { RG_UNREACHABLE(); } break;
113
152
  case PrimitiveKind::Float32:
114
153
  case PrimitiveKind::Float64: {
154
+ bool vfp = HasVFP() && !param.variadic;
115
155
  Size need = param.type->size / 4;
116
- bool vfp = !param.variadic;
117
156
 
118
157
  if (vfp) {
119
158
  if (need <= vec_avail) {
package/src/abi_arm64.cc CHANGED
@@ -11,7 +11,7 @@
11
11
  // You should have received a copy of the GNU Affero General Public License
12
12
  // along with this program. If not, see https://www.gnu.org/licenses/.
13
13
 
14
- #if defined(__aarch64__)
14
+ #if defined(__aarch64__) || defined(_M_ARM64)
15
15
 
16
16
  #include "vendor/libcc/libcc.hh"
17
17
  #include "ffi.hh"
@@ -41,9 +41,14 @@ 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)
45
+ {
46
+ return IsHFA(type, 1, 4);
47
+ }
48
+
44
49
  bool AnalyseFunction(InstanceData *, FunctionInfo *func)
45
50
  {
46
- if (IsHFA(func->ret.type, 1, 4)) {
51
+ if (IsHFA(func->ret.type)) {
47
52
  func->ret.vec_count = func->ret.type->members.len;
48
53
  } else if (func->ret.type->size <= 16) {
49
54
  func->ret.gpr_count = (func->ret.type->size + 7) / 8;
@@ -81,14 +86,18 @@ bool AnalyseFunction(InstanceData *, FunctionInfo *func)
81
86
  }
82
87
  } break;
83
88
  case PrimitiveKind::Record: {
84
- #ifdef __APPLE__
89
+ bool hfa = IsHFA(param.type);
90
+
91
+ #if defined(_WIN32)
92
+ hfa &= !param.variadic;
93
+ #elif defined(__APPLE__)
85
94
  if (param.variadic) {
86
95
  param.use_memory = (param.type->size > 16);
87
96
  break;
88
97
  }
89
98
  #endif
90
99
 
91
- if (IsHFA(param.type, 1, 4)) {
100
+ if (hfa) {
92
101
  int vec_count = (int)param.type->members.len;
93
102
 
94
103
  if (vec_count <= vec_avail) {
@@ -118,7 +127,15 @@ bool AnalyseFunction(InstanceData *, FunctionInfo *func)
118
127
  case PrimitiveKind::Array: { RG_UNREACHABLE(); } break;
119
128
  case PrimitiveKind::Float32:
120
129
  case PrimitiveKind::Float64: {
121
- #ifdef __APPLE__
130
+ #if defined(_WIN32)
131
+ if (param.variadic) {
132
+ if (gpr_avail) {
133
+ param.gpr_count = 1;
134
+ gpr_avail--;
135
+ }
136
+ break;
137
+ }
138
+ #elif defined(__APPLE__)
122
139
  if (param.variadic)
123
140
  break;
124
141
  #endif
@@ -11,7 +11,7 @@
11
11
  // You should have received a copy of the GNU Affero General Public License
12
12
  // along with this program. If not, see https://www.gnu.org/licenses/.
13
13
 
14
- #if defined(__x86_64__) && !defined(_WIN64)
14
+ #if defined(__x86_64__) && !defined(_WIN32)
15
15
 
16
16
  #include "vendor/libcc/libcc.hh"
17
17
  #include "ffi.hh"
@@ -11,7 +11,7 @@
11
11
  // You should have received a copy of the GNU Affero General Public License
12
12
  // along with this program. If not, see https://www.gnu.org/licenses/.
13
13
 
14
- #ifdef _WIN64
14
+ #if defined(_WIN32) && (defined(__x86_64__) || defined(_M_AMD64))
15
15
 
16
16
  #include "vendor/libcc/libcc.hh"
17
17
  #include "ffi.hh"
package/src/abi_x86.cc CHANGED
@@ -37,7 +37,9 @@ static inline bool IsRegular(Size size)
37
37
 
38
38
  bool AnalyseFunction(InstanceData *instance, FunctionInfo *func)
39
39
  {
40
- int fast = (func->convention == CallConvention::Fastcall) ? 2 : 0;
40
+ int fast = (func->convention == CallConvention::Fastcall) ? 2 :
41
+ (func->convention == CallConvention::Thiscall) ? 1 : 0;
42
+ func->fast = fast;
41
43
 
42
44
  if (func->ret.type->primitive != PrimitiveKind::Record) {
43
45
  func->ret.trivial = true;
@@ -77,6 +79,10 @@ bool AnalyseFunction(InstanceData *instance, FunctionInfo *func)
77
79
  func->decorated_name = Fmt(&instance->str_alloc, "@%1@%2", func->name, params_size).ptr;
78
80
  func->args_size += 16;
79
81
  } break;
82
+ case CallConvention::Thiscall: {
83
+ RG_ASSERT(!func->variadic);
84
+ func->args_size += 16;
85
+ } break;
80
86
  }
81
87
 
82
88
  return true;
@@ -90,7 +96,7 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
90
96
  // Pass return value in register or through memory
91
97
  if (RG_UNLIKELY(!AllocStack(func->args_size, 16, &args_ptr)))
92
98
  return false;
93
- if (func->convention == CallConvention::Fastcall) {
99
+ if (func->fast) {
94
100
  fast_ptr = args_ptr;
95
101
  args_ptr += 4;
96
102
  }
@@ -259,8 +265,8 @@ void CallData::Execute()
259
265
  {
260
266
  #define PERFORM_CALL(Suffix) \
261
267
  ([&]() { \
262
- auto ret = (func->convention == CallConvention::Fastcall ? ForwardCallR ## Suffix(func->func, stack.ptr) \
263
- : ForwardCall ## Suffix(func->func, stack.ptr)); \
268
+ auto ret = (func->fast ? ForwardCallR ## Suffix(func->func, stack.ptr) \
269
+ : ForwardCall ## Suffix(func->func, stack.ptr)); \
264
270
  return ret; \
265
271
  })()
266
272