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.
- package/CMakeLists.txt +10 -7
- package/README.md +29 -28
- package/build/qemu/1.1.3/koffi_darwin_x64.tar.gz +0 -0
- package/build/qemu/1.1.3/koffi_freebsd_arm64.tar.gz +0 -0
- package/build/qemu/1.1.3/koffi_freebsd_ia32.tar.gz +0 -0
- package/build/qemu/1.1.3/koffi_freebsd_x64.tar.gz +0 -0
- package/build/qemu/1.1.3/koffi_linux_arm.tar.gz +0 -0
- package/build/qemu/1.1.3/koffi_linux_arm64.tar.gz +0 -0
- package/build/qemu/1.1.3/koffi_linux_ia32.tar.gz +0 -0
- package/build/qemu/1.1.3/koffi_linux_x64.tar.gz +0 -0
- package/build/qemu/1.1.3/koffi_openbsd_x64.tar.gz +0 -0
- package/build/qemu/1.1.3/koffi_win32_ia32.tar.gz +0 -0
- package/build/qemu/1.1.3/koffi_win32_x64.tar.gz +0 -0
- package/package.json +2 -2
- package/qemu/qemu.js +1 -1
- package/qemu/registry/machines.json +47 -3
- package/qemu/registry/sha256sum.txt +16 -12
- package/src/abi_arm32.cc +43 -4
- package/src/abi_arm64.cc +22 -5
- package/src/abi_x64_sysv.cc +1 -1
- package/src/abi_x64_win.cc +1 -1
- package/src/abi_x86.cc +10 -4
- package/src/call.cc +213 -44
- package/src/call.hh +2 -2
- package/src/ffi.cc +63 -36
- package/src/ffi.hh +10 -4
- package/src/parser.cc +46 -24
- package/src/parser.hh +3 -1
- package/src/util.hh +1 -1
- package/test/CMakeLists.txt +3 -0
- package/test/misc.c +17 -0
- package/vendor/libcc/libcc.cc +7 -7
- package/vendor/libcc/libcc.hh +4 -1
- package/build/qemu/1.1.0/koffi_darwin_x64.tar.gz +0 -0
- package/build/qemu/1.1.0/koffi_freebsd_arm64.tar.gz +0 -0
- package/build/qemu/1.1.0/koffi_freebsd_ia32.tar.gz +0 -0
- package/build/qemu/1.1.0/koffi_freebsd_x64.tar.gz +0 -0
- package/build/qemu/1.1.0/koffi_linux_arm.tar.gz +0 -0
- package/build/qemu/1.1.0/koffi_linux_arm64.tar.gz +0 -0
- package/build/qemu/1.1.0/koffi_linux_ia32.tar.gz +0 -0
- package/build/qemu/1.1.0/koffi_linux_x64.tar.gz +0 -0
- package/build/qemu/1.1.0/koffi_win32_ia32.tar.gz +0 -0
- 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(
|
|
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(
|
|
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
|
-
|
|
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:
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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
|
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "koffi",
|
|
3
|
-
"version": "1.1.
|
|
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.
|
|
27
|
+
"cnoke": "^1.0.9"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"chalk": "^4.1.2",
|
package/qemu/qemu.js
CHANGED
|
@@ -253,7 +253,7 @@
|
|
|
253
253
|
},
|
|
254
254
|
|
|
255
255
|
"info": {
|
|
256
|
-
"version":
|
|
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":
|
|
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":
|
|
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
|
-
|
|
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
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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
|
-
|
|
38
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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 (
|
|
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
|
-
#
|
|
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
|
package/src/abi_x64_sysv.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(__x86_64__) && !defined(
|
|
14
|
+
#if defined(__x86_64__) && !defined(_WIN32)
|
|
15
15
|
|
|
16
16
|
#include "vendor/libcc/libcc.hh"
|
|
17
17
|
#include "ffi.hh"
|
package/src/abi_x64_win.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
|
-
#
|
|
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 :
|
|
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->
|
|
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->
|
|
263
|
-
|
|
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
|
|