koffi 1.0.5 → 1.1.0-beta.2
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 +4 -0
- package/README.md +54 -24
- package/build/qemu/1.1.0-beta.2/koffi_darwin_x64.tar.gz +0 -0
- package/build/qemu/1.1.0-beta.2/koffi_freebsd_arm64.tar.gz +0 -0
- package/build/qemu/1.1.0-beta.2/koffi_freebsd_ia32.tar.gz +0 -0
- package/build/qemu/1.1.0-beta.2/koffi_freebsd_x64.tar.gz +0 -0
- package/build/qemu/1.1.0-beta.2/koffi_linux_arm.tar.gz +0 -0
- package/build/qemu/1.1.0-beta.2/koffi_linux_arm64.tar.gz +0 -0
- package/build/qemu/1.1.0-beta.2/koffi_linux_ia32.tar.gz +0 -0
- package/build/qemu/1.1.0-beta.2/koffi_linux_x64.tar.gz +0 -0
- package/build/qemu/1.1.0-beta.2/koffi_win32_ia32.tar.gz +0 -0
- package/build/qemu/1.1.0-beta.2/koffi_win32_x64.tar.gz +0 -0
- package/package.json +1 -1
- package/qemu/qemu.js +12 -5
- package/qemu/registry/machines.json +20 -10
- package/src/abi_arm32.cc +40 -51
- package/src/abi_arm64.cc +71 -138
- package/src/abi_x64_sysv.cc +37 -13
- package/src/abi_x64_win.cc +16 -6
- package/src/abi_x86.cc +16 -6
- package/src/call.cc +564 -58
- package/src/call.hh +32 -44
- package/src/ffi.cc +218 -19
- package/src/ffi.hh +27 -11
- package/src/parser.cc +4 -0
- package/src/util.cc +72 -0
- package/src/util.hh +2 -0
- package/test/misc.c +16 -10
- package/build/qemu/1.0.5/koffi_darwin_x64.tar.gz +0 -0
- package/build/qemu/1.0.5/koffi_freebsd_arm64.tar.gz +0 -0
- package/build/qemu/1.0.5/koffi_freebsd_ia32.tar.gz +0 -0
- package/build/qemu/1.0.5/koffi_freebsd_x64.tar.gz +0 -0
- package/build/qemu/1.0.5/koffi_linux_arm.tar.gz +0 -0
- package/build/qemu/1.0.5/koffi_linux_arm64.tar.gz +0 -0
- package/build/qemu/1.0.5/koffi_linux_ia32.tar.gz +0 -0
- package/build/qemu/1.0.5/koffi_linux_x64.tar.gz +0 -0
- package/build/qemu/1.0.5/koffi_win32_ia32.tar.gz +0 -0
- package/build/qemu/1.0.5/koffi_win32_x64.tar.gz +0 -0
- package/test/misc.js +0 -227
package/CMakeLists.txt
CHANGED
|
@@ -18,7 +18,11 @@ find_package(CNoke)
|
|
|
18
18
|
|
|
19
19
|
set(CMAKE_CXX_STANDARD 17)
|
|
20
20
|
if(MSVC)
|
|
21
|
+
add_compile_options(/W4 /wd4200 /wd4458 /wd4706 /wd4100 /wd4127 /wd4702)
|
|
21
22
|
enable_language(ASM_MASM)
|
|
23
|
+
else()
|
|
24
|
+
add_compile_options(-Wall -Wextra -Wno-missing-field-initializers
|
|
25
|
+
-Wno-unused-parameter -Wno-class-memaccess)
|
|
22
26
|
endif()
|
|
23
27
|
|
|
24
28
|
# ---- Koffi ----
|
package/README.md
CHANGED
|
@@ -2,6 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
- [Introduction](#introduction)
|
|
4
4
|
- [Get started](#get-started)
|
|
5
|
+
- [Extra features](#extra-features)
|
|
6
|
+
* [C arrays](#c-arrays)
|
|
7
|
+
* [Variadic functions](#variadic-functions)
|
|
8
|
+
* [Asynchronous calls](#asynchronous-calls)
|
|
9
|
+
* [Callbacks](#callbacks)
|
|
5
10
|
- [Benchmarks](#benchmarks)
|
|
6
11
|
* [atoi results](#atoi-results)
|
|
7
12
|
* [Raylib results](#raylib-results)
|
|
@@ -16,31 +21,30 @@ Koffi is a fast and easy-to-use FFI module for Node.js, with support for primiti
|
|
|
16
21
|
|
|
17
22
|
After the release of version 1.0, the following features are planned:
|
|
18
23
|
|
|
19
|
-
* 1.1: Asynchronous calls
|
|
24
|
+
* 1.1: Asynchronous calls and fixed-size array types
|
|
20
25
|
* 1.2: C to JS callbacks
|
|
21
|
-
* 1.3: Unions and (fixed size) array types
|
|
22
26
|
|
|
23
27
|
The following platforms __are officially supported and tested__ at the moment:
|
|
24
28
|
|
|
25
|
-
Platform | Architecture |
|
|
26
|
-
--------- | -------------------------------- |
|
|
27
|
-
Windows | x86 (cdecl, stdcall, fastcall) | 🟩 Yes
|
|
28
|
-
Windows | x86_64 | 🟩 Yes
|
|
29
|
-
Linux | x86 | 🟩 Yes
|
|
30
|
-
Linux | x86_64 | 🟩 Yes
|
|
31
|
-
Linux | ARM32+VFP Little Endian | 🟩 Yes
|
|
32
|
-
Linux | ARM64 Little Endian | 🟩 Yes
|
|
33
|
-
FreeBSD | x86 | 🟩 Yes
|
|
34
|
-
FreeBSD | x86_64 | 🟩 Yes
|
|
35
|
-
FreeBSD | ARM64 Little Endian | 🟩 Yes
|
|
36
|
-
macOS | x86_64 | 🟩 Yes
|
|
37
|
-
macOS | ARM64 (M1) Little Endian | 🟩 Yes
|
|
38
|
-
OpenBSD | x86_64 | 🟧 Maybe | 🟥 No
|
|
39
|
-
OpenBSD | x86 | 🟧 Maybe | 🟥 No
|
|
40
|
-
OpenBSD | ARM64 Little Endian | 🟧 Maybe | 🟥 No
|
|
41
|
-
NetBSD | x86_64 | 🟧 Maybe | 🟥 No
|
|
42
|
-
NetBSD | x86 | 🟧 Maybe | 🟥 No
|
|
43
|
-
NetBSD | ARM64 Little Endian | 🟧 Maybe | 🟥 No
|
|
29
|
+
Platform | Architecture | Sync calls | Async calls | Callbacks | Pre-built binary
|
|
30
|
+
--------- | -------------------------------- | ---------- | ----------- | --------- | ----------------
|
|
31
|
+
Windows | x86 (cdecl, stdcall, fastcall) | 🟩 Yes | 🟩 Yes | 🟥 No | 🟩 Yes
|
|
32
|
+
Windows | x86_64 | 🟩 Yes | 🟩 Yes | 🟥 No | 🟩 Yes
|
|
33
|
+
Linux | x86 | 🟩 Yes | 🟩 Yes | 🟥 No | 🟩 Yes
|
|
34
|
+
Linux | x86_64 | 🟩 Yes | 🟩 Yes | 🟥 No | 🟩 Yes
|
|
35
|
+
Linux | ARM32+VFP Little Endian | 🟩 Yes | 🟩 Yes | 🟥 No | 🟩 Yes
|
|
36
|
+
Linux | ARM64 Little Endian | 🟩 Yes | 🟩 Yes | 🟥 No | 🟩 Yes
|
|
37
|
+
FreeBSD | x86 | 🟩 Yes | 🟩 Yes | 🟥 No | 🟩 Yes
|
|
38
|
+
FreeBSD | x86_64 | 🟩 Yes | 🟩 Yes | 🟥 No | 🟩 Yes
|
|
39
|
+
FreeBSD | ARM64 Little Endian | 🟩 Yes | 🟩 Yes | 🟥 No | 🟩 Yes
|
|
40
|
+
macOS | x86_64 | 🟩 Yes | 🟩 Yes | 🟥 No | 🟩 Yes
|
|
41
|
+
macOS | ARM64 (M1) Little Endian | 🟩 Yes | 🟩 Yes | 🟥 No | 🟥 No
|
|
42
|
+
OpenBSD | x86_64 | 🟧 Maybe | 🟧 Maybe | 🟥 No | 🟥 No
|
|
43
|
+
OpenBSD | x86 | 🟧 Maybe | 🟧 Maybe | 🟥 No | 🟥 No
|
|
44
|
+
OpenBSD | ARM64 Little Endian | 🟧 Maybe | 🟧 Maybe | 🟥 No | 🟥 No
|
|
45
|
+
NetBSD | x86_64 | 🟧 Maybe | 🟧 Maybe | 🟥 No | 🟥 No
|
|
46
|
+
NetBSD | x86 | 🟧 Maybe | 🟧 Maybe | 🟥 No | 🟥 No
|
|
47
|
+
NetBSD | ARM64 Little Endian | 🟧 Maybe | 🟧 Maybe | 🟥 No | 🟥 No
|
|
44
48
|
|
|
45
49
|
🟩 Tested, fully operational
|
|
46
50
|
🟧 May work, but not actively tested
|
|
@@ -214,12 +218,16 @@ while (!WindowShouldClose()) {
|
|
|
214
218
|
|
|
215
219
|
# Extra features
|
|
216
220
|
|
|
221
|
+
## C arrays
|
|
222
|
+
|
|
223
|
+
Fixed-size arrays are declared with `koffi.array(type, length)`. Just like in C, they cannot be passed
|
|
224
|
+
as functions parameters (they degenerate to pointers), or returned by value. You can however embed them in struct types.
|
|
225
|
+
|
|
217
226
|
## Variadic functions
|
|
218
227
|
|
|
219
228
|
Variadic functions are declared with an ellipsis as the last argument.
|
|
220
229
|
|
|
221
|
-
In order to call a variadic function, you must provide two Javascript arguments for each C parameter,
|
|
222
|
-
the first one is the expected type and the second one is the value.
|
|
230
|
+
In order to call a variadic function, you must provide two Javascript arguments for each C parameter, the first one is the expected type and the second one is the value.
|
|
223
231
|
|
|
224
232
|
```js
|
|
225
233
|
const printf = lib.func('printf', 'int', ['string', '...']);
|
|
@@ -227,9 +235,31 @@ const printf = lib.func('printf', 'int', ['string', '...']);
|
|
|
227
235
|
printf('Integer %d, double %g, string %s', 'int', 6, 'double', 8.5, 'string', 'THE END');
|
|
228
236
|
```
|
|
229
237
|
|
|
238
|
+
## Asynchronous calls
|
|
239
|
+
|
|
240
|
+
You can issue asynchronous calls by calling the function through its async member. In this case, you need to provide a callback function as the last argument, with `(err, res)` parameters.
|
|
241
|
+
|
|
242
|
+
```js
|
|
243
|
+
const koffi = require('koffi');
|
|
244
|
+
const lib = koffi.load('libc.so.6');
|
|
245
|
+
|
|
246
|
+
const atoi = lib.func('int atoi(const char *str)');
|
|
247
|
+
|
|
248
|
+
atoi.async('1257', (err, res) => {
|
|
249
|
+
console.log('Result:', res);
|
|
250
|
+
})
|
|
251
|
+
console.log('Hello World!');
|
|
252
|
+
|
|
253
|
+
// This program will print "Hello World!", and then "Result: 1257"
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
You can easily convert this callback-style async function to a promise-based version with `util.promisify()` from the Node.js standard library.
|
|
257
|
+
|
|
258
|
+
Variadic functions do not support async.
|
|
259
|
+
|
|
230
260
|
## Callbacks
|
|
231
261
|
|
|
232
|
-
Koffi does not yet support passing JS functions as callbacks. This is planned for version 1.
|
|
262
|
+
Koffi does not yet support passing JS functions as callbacks. This is planned for version 1.2.
|
|
233
263
|
|
|
234
264
|
# Benchmarks
|
|
235
265
|
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
package/qemu/qemu.js
CHANGED
|
@@ -275,6 +275,7 @@ async function pack() {
|
|
|
275
275
|
let json = fs.readFileSync(root_dir + '/koffi/package.json', { encoding: 'utf-8' });
|
|
276
276
|
let version = JSON.parse(json).version;
|
|
277
277
|
|
|
278
|
+
console.log('>> Version:', version);
|
|
278
279
|
console.log('>> Checking build archives...');
|
|
279
280
|
for (let machine of machines) {
|
|
280
281
|
let needed = false;
|
|
@@ -430,16 +431,22 @@ async function copy(func) {
|
|
|
430
431
|
let copied = true;
|
|
431
432
|
|
|
432
433
|
for (let directory of func(machine)) {
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
434
|
+
for (let i = 0; i < 10; i++) {
|
|
435
|
+
try {
|
|
436
|
+
await machine.ssh.exec('rm', ['-rf', directory]);
|
|
437
|
+
break;
|
|
438
|
+
} catch (err) {
|
|
439
|
+
// Fails often on Windows (busy directory or whatever), but rarely a problem
|
|
440
|
+
|
|
441
|
+
await wait(1000);
|
|
442
|
+
continue;
|
|
443
|
+
}
|
|
437
444
|
}
|
|
438
445
|
|
|
439
446
|
try {
|
|
440
447
|
await machine.ssh.putDirectory(snapshot_dir, directory, {
|
|
441
448
|
recursive: true,
|
|
442
|
-
concurrency: 4
|
|
449
|
+
concurrency: (process.platform != 'win32') ? 4 : 1
|
|
443
450
|
});
|
|
444
451
|
} catch (err) {
|
|
445
452
|
ignore.add(machine);
|
|
@@ -35,8 +35,9 @@
|
|
|
35
35
|
"Build": "node ../cnoke/cnoke.js -C test"
|
|
36
36
|
},
|
|
37
37
|
"commands": {
|
|
38
|
+
"Test Sync": "node test/sync.js",
|
|
39
|
+
"Test Async": "node test/async.js",
|
|
38
40
|
"Test Raylib": "xvfb-run node test/raylib.js",
|
|
39
|
-
"Test Misc": "node test/misc.js",
|
|
40
41
|
"Test SQLite": "node test/sqlite.js"
|
|
41
42
|
}
|
|
42
43
|
}
|
|
@@ -79,8 +80,9 @@
|
|
|
79
80
|
"Build": "node ../cnoke/cnoke.js -C test"
|
|
80
81
|
},
|
|
81
82
|
"commands": {
|
|
83
|
+
"Test Sync": "node test/sync.js",
|
|
84
|
+
"Test Async": "node test/async.js",
|
|
82
85
|
"Test Raylib": "xvfb-run node test/raylib.js",
|
|
83
|
-
"Test Misc": "node test/misc.js",
|
|
84
86
|
"Test SQLite": "node test/sqlite.js"
|
|
85
87
|
}
|
|
86
88
|
}
|
|
@@ -123,8 +125,9 @@
|
|
|
123
125
|
"Build": "node ../cnoke/cnoke.js -C test"
|
|
124
126
|
},
|
|
125
127
|
"commands": {
|
|
128
|
+
"Test Sync": "node test/sync.js",
|
|
129
|
+
"Test Async": "node test/async.js",
|
|
126
130
|
"Test Raylib": "xvfb-run node test/raylib.js",
|
|
127
|
-
"Test Misc": "node test/misc.js",
|
|
128
131
|
"Test SQLite": "node test/sqlite.js"
|
|
129
132
|
}
|
|
130
133
|
}
|
|
@@ -167,8 +170,9 @@
|
|
|
167
170
|
"Build": "node ../cnoke/cnoke.js -C test"
|
|
168
171
|
},
|
|
169
172
|
"commands": {
|
|
173
|
+
"Test Sync": "node test/sync.js",
|
|
174
|
+
"Test Async": "node test/async.js",
|
|
170
175
|
"Test Raylib": "xvfb-run node test/raylib.js",
|
|
171
|
-
"Test Misc": "node test/misc.js",
|
|
172
176
|
"Test SQLite": "node test/sqlite.js"
|
|
173
177
|
}
|
|
174
178
|
}
|
|
@@ -218,8 +222,9 @@
|
|
|
218
222
|
"Build": "C:\\Node32\\node32.cmd node ../cnoke/cnoke.js -C test"
|
|
219
223
|
},
|
|
220
224
|
"commands": {
|
|
225
|
+
"Test Sync": "C:\\Node32\\node32.cmd node test/sync.js",
|
|
226
|
+
"Test Async": "C:\\Node32\\node32.cmd node test/async.js",
|
|
221
227
|
"Test Raylib": "seatsh C:\\Node32\\node32.cmd node test/raylib.js",
|
|
222
|
-
"Test Misc": "C:\\Node32\\node32.cmd node test/misc.js",
|
|
223
228
|
"Test SQLite": "C:\\Node32\\node32.cmd node test/sqlite.js"
|
|
224
229
|
}
|
|
225
230
|
},
|
|
@@ -230,8 +235,9 @@
|
|
|
230
235
|
"Build": "C:\\Node64\\node64.cmd node ../cnoke/cnoke.js -C test"
|
|
231
236
|
},
|
|
232
237
|
"commands": {
|
|
238
|
+
"Test Sync": "C:\\Node64\\node64.cmd node test/sync.js",
|
|
239
|
+
"Test Async": "C:\\Node64\\node64.cmd node test/async.js",
|
|
233
240
|
"Test Raylib": "seatsh C:\\Node64\\node64.cmd node test/raylib.js",
|
|
234
|
-
"Test Misc": "C:\\Node64\\node64.cmd node test/misc.js",
|
|
235
241
|
"Test SQLite": "C:\\Node64\\node64.cmd node test/sqlite.js"
|
|
236
242
|
}
|
|
237
243
|
}
|
|
@@ -274,8 +280,9 @@
|
|
|
274
280
|
"Build": "node ../cnoke/cnoke.js -C test"
|
|
275
281
|
},
|
|
276
282
|
"commands": {
|
|
283
|
+
"Test Sync": "node test/sync.js",
|
|
284
|
+
"Test Async": "node test/async.js",
|
|
277
285
|
"Test Raylib": "xvfb-run node test/raylib.js",
|
|
278
|
-
"Test Misc": "node test/misc.js",
|
|
279
286
|
"Test SQLite": "node test/sqlite.js"
|
|
280
287
|
}
|
|
281
288
|
}
|
|
@@ -318,8 +325,9 @@
|
|
|
318
325
|
"Build": "node ../cnoke/cnoke.js -C test"
|
|
319
326
|
},
|
|
320
327
|
"commands": {
|
|
328
|
+
"Test Sync": "node test/sync.js",
|
|
329
|
+
"Test Async": "node test/async.js",
|
|
321
330
|
"Test Raylib": "xvfb-run node test/raylib.js",
|
|
322
|
-
"Test Misc": "node test/misc.js",
|
|
323
331
|
"Test SQLite": "node test/sqlite.js"
|
|
324
332
|
}
|
|
325
333
|
}
|
|
@@ -362,8 +370,9 @@
|
|
|
362
370
|
"Build": "node ../cnoke/cnoke.js -C test"
|
|
363
371
|
},
|
|
364
372
|
"commands": {
|
|
373
|
+
"Test Sync": "node test/sync.js",
|
|
374
|
+
"Test Async": "node test/async.js",
|
|
365
375
|
"Test Raylib": "xvfb-run node test/raylib.js",
|
|
366
|
-
"Test Misc": "node test/misc.js",
|
|
367
376
|
"Test SQLite": "node test/sqlite.js"
|
|
368
377
|
}
|
|
369
378
|
}
|
|
@@ -406,7 +415,8 @@
|
|
|
406
415
|
"Build": "PATH=/usr/local/bin:/usr/bin:/bin SDKROOT=/Library/Developer/CommandLineTools/SDKs/MacOSX11.3.sdk node ../cnoke/cnoke.js -C test"
|
|
407
416
|
},
|
|
408
417
|
"commands": {
|
|
409
|
-
"Test
|
|
418
|
+
"Test Sync": "PATH=/usr/local/bin:/usr/bin:/bin node test/sync.js",
|
|
419
|
+
"Test Async": "PATH=/usr/local/bin:/usr/bin:/bin node test/async.js",
|
|
410
420
|
"Test SQLite": "PATH=/usr/local/bin:/usr/bin:/bin node test/sqlite.js"
|
|
411
421
|
}
|
|
412
422
|
}
|
package/src/abi_arm32.cc
CHANGED
|
@@ -37,28 +37,9 @@ extern "C" uint64_t ForwardCallXGG(const void *func, uint8_t *sp);
|
|
|
37
37
|
extern "C" float ForwardCallXF(const void *func, uint8_t *sp);
|
|
38
38
|
extern "C" HfaRet ForwardCallXDDDD(const void *func, uint8_t *sp);
|
|
39
39
|
|
|
40
|
-
static bool IsHFA(const TypeInfo *type)
|
|
41
|
-
{
|
|
42
|
-
if (type->primitive != PrimitiveKind::Record)
|
|
43
|
-
return false;
|
|
44
|
-
|
|
45
|
-
if (type->members.len < 1 || type->members.len > 4)
|
|
46
|
-
return false;
|
|
47
|
-
if (type->members[0].type->primitive != PrimitiveKind::Float32 &&
|
|
48
|
-
type->members[0].type->primitive != PrimitiveKind::Float64)
|
|
49
|
-
return false;
|
|
50
|
-
|
|
51
|
-
for (Size i = 1; i < type->members.len; i++) {
|
|
52
|
-
if (type->members[i].type != type->members[0].type)
|
|
53
|
-
return false;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
return true;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
40
|
bool AnalyseFunction(InstanceData *, FunctionInfo *func)
|
|
60
41
|
{
|
|
61
|
-
if (IsHFA(func->ret.type)) {
|
|
42
|
+
if (IsHFA(func->ret.type, 1, 4)) {
|
|
62
43
|
func->ret.vec_count = func->ret.type->members.len *
|
|
63
44
|
(func->ret.type->members[0].type->size / 4);
|
|
64
45
|
} else if (func->ret.type->primitive != PrimitiveKind::Record ||
|
|
@@ -93,7 +74,6 @@ bool AnalyseFunction(InstanceData *, FunctionInfo *func)
|
|
|
93
74
|
started_stack = true;
|
|
94
75
|
}
|
|
95
76
|
} break;
|
|
96
|
-
|
|
97
77
|
case PrimitiveKind::Int64:
|
|
98
78
|
case PrimitiveKind::UInt64: {
|
|
99
79
|
if (gpr_avail >= 2) {
|
|
@@ -103,31 +83,8 @@ bool AnalyseFunction(InstanceData *, FunctionInfo *func)
|
|
|
103
83
|
started_stack = true;
|
|
104
84
|
}
|
|
105
85
|
} break;
|
|
106
|
-
|
|
107
|
-
case PrimitiveKind::Float32:
|
|
108
|
-
case PrimitiveKind::Float64: {
|
|
109
|
-
Size need = param.type->size / 4;
|
|
110
|
-
bool vfp = !param.variadic;
|
|
111
|
-
|
|
112
|
-
if (vfp) {
|
|
113
|
-
if (need <= vec_avail) {
|
|
114
|
-
param.vec_count = need;
|
|
115
|
-
vec_avail -= need;
|
|
116
|
-
} else {
|
|
117
|
-
started_stack = true;
|
|
118
|
-
}
|
|
119
|
-
} else {
|
|
120
|
-
if (need <= gpr_avail) {
|
|
121
|
-
param.gpr_count = need;
|
|
122
|
-
gpr_avail -= need;
|
|
123
|
-
} else {
|
|
124
|
-
started_stack = true;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
} break;
|
|
128
|
-
|
|
129
86
|
case PrimitiveKind::Record: {
|
|
130
|
-
if (IsHFA(param.type)) {
|
|
87
|
+
if (IsHFA(param.type, 1, 4)) {
|
|
131
88
|
int vec_count = (int)(param.type->members.len *
|
|
132
89
|
param.type->members[0].type->size / 4);
|
|
133
90
|
|
|
@@ -152,6 +109,28 @@ bool AnalyseFunction(InstanceData *, FunctionInfo *func)
|
|
|
152
109
|
}
|
|
153
110
|
}
|
|
154
111
|
} break;
|
|
112
|
+
case PrimitiveKind::Array: { RG_UNREACHABLE(); } break;
|
|
113
|
+
case PrimitiveKind::Float32:
|
|
114
|
+
case PrimitiveKind::Float64: {
|
|
115
|
+
Size need = param.type->size / 4;
|
|
116
|
+
bool vfp = !param.variadic;
|
|
117
|
+
|
|
118
|
+
if (vfp) {
|
|
119
|
+
if (need <= vec_avail) {
|
|
120
|
+
param.vec_count = need;
|
|
121
|
+
vec_avail -= need;
|
|
122
|
+
} else {
|
|
123
|
+
started_stack = true;
|
|
124
|
+
}
|
|
125
|
+
} else {
|
|
126
|
+
if (need <= gpr_avail) {
|
|
127
|
+
param.gpr_count = need;
|
|
128
|
+
gpr_avail -= need;
|
|
129
|
+
} else {
|
|
130
|
+
started_stack = true;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
} break;
|
|
155
134
|
}
|
|
156
135
|
|
|
157
136
|
func->args_size += AlignLen(param.type->size, 16);
|
|
@@ -305,8 +284,11 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
|
|
|
305
284
|
memset(ptr, 0, param.type->size);
|
|
306
285
|
}
|
|
307
286
|
if (param.directions & 2) {
|
|
308
|
-
OutObject out =
|
|
309
|
-
|
|
287
|
+
OutObject *out = out_objects.AppendDefault();
|
|
288
|
+
|
|
289
|
+
out->ref.Reset(obj, 1);
|
|
290
|
+
out->ptr = ptr;
|
|
291
|
+
out->type = param.type->ref;
|
|
310
292
|
}
|
|
311
293
|
} else if (IsNullOrUndefined(value)) {
|
|
312
294
|
ptr = nullptr;
|
|
@@ -351,6 +333,7 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
|
|
|
351
333
|
args_ptr += AlignLen(param.type->size, 4);
|
|
352
334
|
}
|
|
353
335
|
} break;
|
|
336
|
+
case PrimitiveKind::Array: { RG_UNREACHABLE(); } break;
|
|
354
337
|
case PrimitiveKind::Float32: {
|
|
355
338
|
if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
|
|
356
339
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), i + 1);
|
|
@@ -391,6 +374,9 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
|
|
|
391
374
|
}
|
|
392
375
|
}
|
|
393
376
|
|
|
377
|
+
stack = MakeSpan(mem->stack.end(), old_stack_mem.end() - mem->stack.end());
|
|
378
|
+
heap = MakeSpan(old_heap_mem.ptr, mem->heap.ptr - old_heap_mem.ptr);
|
|
379
|
+
|
|
394
380
|
return true;
|
|
395
381
|
}
|
|
396
382
|
|
|
@@ -398,8 +384,8 @@ void CallData::Execute()
|
|
|
398
384
|
{
|
|
399
385
|
#define PERFORM_CALL(Suffix) \
|
|
400
386
|
([&]() { \
|
|
401
|
-
auto ret = (func->forward_fp ? ForwardCallX ## Suffix(func->func,
|
|
402
|
-
: ForwardCall ## Suffix(func->func,
|
|
387
|
+
auto ret = (func->forward_fp ? ForwardCallX ## Suffix(func->func, stack.ptr) \
|
|
388
|
+
: ForwardCall ## Suffix(func->func, stack.ptr)); \
|
|
403
389
|
return ret; \
|
|
404
390
|
})()
|
|
405
391
|
|
|
@@ -426,6 +412,7 @@ void CallData::Execute()
|
|
|
426
412
|
result.u64 = PERFORM_CALL(GG);
|
|
427
413
|
}
|
|
428
414
|
} break;
|
|
415
|
+
case PrimitiveKind::Array: { RG_UNREACHABLE(); } break;
|
|
429
416
|
case PrimitiveKind::Float32: { result.f = PERFORM_CALL(F); } break;
|
|
430
417
|
case PrimitiveKind::Float64: { result.d = PERFORM_CALL(DDDD).d0; } break;
|
|
431
418
|
}
|
|
@@ -435,8 +422,9 @@ void CallData::Execute()
|
|
|
435
422
|
|
|
436
423
|
Napi::Value CallData::Complete()
|
|
437
424
|
{
|
|
438
|
-
for (const OutObject &
|
|
439
|
-
|
|
425
|
+
for (const OutObject &out: out_objects) {
|
|
426
|
+
Napi::Object obj = out.ref.Value().As<Napi::Object>();
|
|
427
|
+
PopObject(obj, out.ptr, out.type);
|
|
440
428
|
}
|
|
441
429
|
|
|
442
430
|
switch (func->ret.type->primitive) {
|
|
@@ -465,6 +453,7 @@ Napi::Value CallData::Complete()
|
|
|
465
453
|
Napi::Object obj = PopObject(ptr, func->ret.type);
|
|
466
454
|
return obj;
|
|
467
455
|
} break;
|
|
456
|
+
case PrimitiveKind::Array: { RG_UNREACHABLE(); } break;
|
|
468
457
|
case PrimitiveKind::Float32: return Napi::Number::New(env, (double)result.f);
|
|
469
458
|
case PrimitiveKind::Float64: return Napi::Number::New(env, result.d);
|
|
470
459
|
}
|