koffi 1.3.2 → 1.3.5
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 +27 -3
- package/ChangeLog.md +46 -14
- package/build/qemu/1.3.5/koffi_darwin_arm64.tar.gz +0 -0
- package/build/qemu/1.3.5/koffi_darwin_x64.tar.gz +0 -0
- package/build/qemu/1.3.5/koffi_freebsd_arm64.tar.gz +0 -0
- package/build/qemu/1.3.5/koffi_freebsd_ia32.tar.gz +0 -0
- package/build/qemu/1.3.5/koffi_freebsd_x64.tar.gz +0 -0
- package/build/qemu/1.3.5/koffi_linux_arm32hf.tar.gz +0 -0
- package/build/qemu/1.3.5/koffi_linux_arm64.tar.gz +0 -0
- package/build/qemu/1.3.5/koffi_linux_ia32.tar.gz +0 -0
- package/build/qemu/1.3.5/koffi_linux_riscv64hf64.tar.gz +0 -0
- package/build/qemu/1.3.5/koffi_linux_x64.tar.gz +0 -0
- package/build/qemu/1.3.5/koffi_openbsd_ia32.tar.gz +0 -0
- package/build/qemu/1.3.5/koffi_openbsd_x64.tar.gz +0 -0
- package/build/qemu/1.3.5/koffi_win32_arm64.tar.gz +0 -0
- package/build/qemu/1.3.5/koffi_win32_ia32.tar.gz +0 -0
- package/build/qemu/1.3.5/koffi_win32_x64.tar.gz +0 -0
- package/doc/_static/perf_linux_20220623.png +0 -0
- package/doc/_static/perf_linux_20220623_2.png +0 -0
- package/doc/_static/perf_windows_20220623.png +0 -0
- package/doc/_static/perf_windows_20220623_2.png +0 -0
- package/doc/benchmarks.md +40 -36
- package/doc/benchmarks.xlsx +0 -0
- package/doc/changes.md +2 -0
- package/doc/conf.py +10 -3
- package/doc/contribute.md +16 -0
- package/doc/dist/doctrees/benchmarks.doctree +0 -0
- package/doc/dist/doctrees/changes.doctree +0 -0
- package/doc/dist/doctrees/contribute.doctree +0 -0
- package/doc/dist/doctrees/environment.pickle +0 -0
- package/doc/dist/doctrees/functions.doctree +0 -0
- package/doc/dist/doctrees/index.doctree +0 -0
- package/doc/dist/doctrees/memory.doctree +0 -0
- package/doc/dist/doctrees/platforms.doctree +0 -0
- package/doc/dist/doctrees/start.doctree +0 -0
- package/doc/dist/doctrees/types.doctree +0 -0
- package/doc/dist/html/_sources/benchmarks.md.txt +40 -36
- package/doc/dist/html/_sources/changes.md.txt +2 -0
- package/doc/dist/html/_sources/contribute.md.txt +16 -0
- package/doc/dist/html/_sources/functions.md.txt +18 -14
- package/doc/dist/html/_sources/index.rst.txt +2 -1
- package/doc/dist/html/_sources/memory.md.txt +6 -3
- package/doc/dist/html/_sources/platforms.md.txt +2 -0
- package/doc/dist/html/_sources/start.md.txt +3 -3
- package/doc/dist/html/_sources/types.md.txt +10 -8
- package/doc/dist/html/_static/perf_linux_20220623.png +0 -0
- package/doc/dist/html/_static/perf_linux_20220623_2.png +0 -0
- package/doc/dist/html/_static/perf_windows_20220623.png +0 -0
- package/doc/dist/html/_static/perf_windows_20220623_2.png +0 -0
- package/doc/dist/html/_static/pygments.css +54 -54
- package/doc/dist/html/benchmarks.html +52 -20
- package/doc/dist/html/changes.html +391 -0
- package/doc/dist/html/contribute.html +24 -2
- package/doc/dist/html/functions.html +83 -84
- package/doc/dist/html/genindex.html +1 -0
- package/doc/dist/html/index.html +18 -3
- package/doc/dist/html/memory.html +11 -5
- package/doc/dist/html/objects.inv +0 -0
- package/doc/dist/html/platforms.html +3 -1
- package/doc/dist/html/search.html +1 -0
- package/doc/dist/html/searchindex.js +1 -1
- package/doc/dist/html/start.html +48 -47
- package/doc/dist/html/types.html +161 -159
- package/doc/functions.md +18 -14
- package/doc/index.rst +2 -1
- package/doc/memory.md +6 -3
- package/doc/platforms.md +2 -0
- package/doc/start.md +3 -3
- package/doc/types.md +10 -8
- package/package.json +2 -2
- package/qemu/qemu.js +1 -0
- package/qemu/registry/machines.json +6 -11
- package/src/abi_arm32.cc +9 -9
- package/src/abi_arm64.cc +9 -9
- package/src/abi_riscv64.cc +9 -9
- package/src/abi_x64_sysv.cc +9 -9
- package/src/abi_x64_win.cc +9 -9
- package/src/abi_x86.cc +9 -9
- package/src/call.cc +8 -7
- package/src/call.hh +6 -0
- package/src/ffi.cc +73 -22
- package/src/ffi.hh +11 -4
- package/src/parser.cc +1 -1
- package/src/util.hh +21 -1
- package/test/async.js +1 -1
- package/test/misc.c +20 -0
- package/test/sync.js +13 -3
- package/vendor/libcc/libcc.hh +1 -1
- package/build/qemu/1.3.2/koffi_darwin_arm64.tar.gz +0 -0
- package/build/qemu/1.3.2/koffi_darwin_x64.tar.gz +0 -0
- package/build/qemu/1.3.2/koffi_freebsd_arm64.tar.gz +0 -0
- package/build/qemu/1.3.2/koffi_freebsd_ia32.tar.gz +0 -0
- package/build/qemu/1.3.2/koffi_freebsd_x64.tar.gz +0 -0
- package/build/qemu/1.3.2/koffi_linux_arm32hf.tar.gz +0 -0
- package/build/qemu/1.3.2/koffi_linux_arm64.tar.gz +0 -0
- package/build/qemu/1.3.2/koffi_linux_ia32.tar.gz +0 -0
- package/build/qemu/1.3.2/koffi_linux_riscv64hf64.tar.gz +0 -0
- package/build/qemu/1.3.2/koffi_linux_x64.tar.gz +0 -0
- package/build/qemu/1.3.2/koffi_openbsd_ia32.tar.gz +0 -0
- package/build/qemu/1.3.2/koffi_openbsd_x64.tar.gz +0 -0
- package/build/qemu/1.3.2/koffi_win32_arm64.tar.gz +0 -0
- package/build/qemu/1.3.2/koffi_win32_ia32.tar.gz +0 -0
- package/build/qemu/1.3.2/koffi_win32_x64.tar.gz +0 -0
package/doc/functions.md
CHANGED
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
## Function definitions
|
|
4
4
|
|
|
5
|
-
To declare functions, start by loading the shared library with `koffi.load()`.
|
|
5
|
+
To declare functions, start by loading the shared library with `koffi.load(filename)`.
|
|
6
6
|
|
|
7
7
|
```js
|
|
8
8
|
const koffi = require('koffi');
|
|
9
9
|
const lib = koffi.load('/path/to/shared/library'); // File extension depends on platforms: .so, .dll, .dylib, etc.
|
|
10
10
|
```
|
|
11
11
|
|
|
12
|
-
You can use the returned object to load C functions from the library.
|
|
12
|
+
You can use the returned object to load C functions from the library. To do so, you can use two syntaxes:
|
|
13
13
|
|
|
14
|
-
-
|
|
14
|
+
- The classic syntax, inspired by node-ffi
|
|
15
15
|
- C-like prototypes
|
|
16
16
|
|
|
17
17
|
### Classic syntax
|
|
@@ -27,18 +27,20 @@ Koffi automatically tries mangled names for non-standard x86 calling conventions
|
|
|
27
27
|
|
|
28
28
|
### C-like prototypes
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
If you prefer, you can declare functions using simple C-like prototype strings, as shown below:
|
|
31
31
|
|
|
32
32
|
```js
|
|
33
33
|
const printf = lib.func('int printf(const char *fmt, ...)');
|
|
34
34
|
const atoi = lib.func('int atoi(string)'); // The parameter name is not used by Koffi, and optional
|
|
35
35
|
```
|
|
36
36
|
|
|
37
|
+
You can use `()` or `(void)` for functions that take no argument.
|
|
38
|
+
|
|
37
39
|
## Synchronous calls
|
|
38
40
|
|
|
39
41
|
By default, calling a C function happens synchronously.
|
|
40
42
|
|
|
41
|
-
Most architectures only support one procedure call standard per process. The 32-bit x86 platform is an exception to this, and Koffi
|
|
43
|
+
Most architectures only support one procedure call standard per process. The 32-bit x86 platform is an exception to this, and Koffi supports several x86 conventions:
|
|
42
44
|
|
|
43
45
|
Convention | Classic form | Prototype form | Description
|
|
44
46
|
------------- | ----------------------------- | -------------- | -------------------------------------------------------------------
|
|
@@ -49,7 +51,7 @@ Most architectures only support one procedure call standard per process. The 32-
|
|
|
49
51
|
|
|
50
52
|
You can safely use these on non-x86 platforms, they are simply ignored.
|
|
51
53
|
|
|
52
|
-
Below you can find a small example showing how to use a non-default calling convention:
|
|
54
|
+
Below you can find a small example showing how to use a non-default calling convention, with the two syntaxes:
|
|
53
55
|
|
|
54
56
|
```js
|
|
55
57
|
const koffi = require('koffi');
|
|
@@ -75,9 +77,13 @@ atoi.async('1257', (err, res) => {
|
|
|
75
77
|
})
|
|
76
78
|
console.log('Hello World!');
|
|
77
79
|
|
|
78
|
-
// This program will print
|
|
80
|
+
// This program will print:
|
|
81
|
+
// Hello World!
|
|
82
|
+
// Result: 1257
|
|
79
83
|
```
|
|
80
84
|
|
|
85
|
+
These calls are executed by worker threads. It is **your responsibility to deal with data sharing issues** in the native code that may be caused by multi-threading.
|
|
86
|
+
|
|
81
87
|
You can easily convert this callback-style async function to a promise-based version with `util.promisify()` from the Node.js standard library.
|
|
82
88
|
|
|
83
89
|
Variadic functions cannot be called asynchronously.
|
|
@@ -101,7 +107,7 @@ On x86 platforms, only the Cdecl convention can be used for variadic functions.
|
|
|
101
107
|
|
|
102
108
|
By default, Koffi will only forward arguments from Javascript to C. However, many C functions use pointer arguments for output values, or input/output values.
|
|
103
109
|
|
|
104
|
-
For
|
|
110
|
+
For simplicity, and because Javascript only has value semantics for primitive types, Koffi can marshal out (or in/out) two types of parameters:
|
|
105
111
|
|
|
106
112
|
- [Structs](types.md#struct-types) (to/from JS objects)
|
|
107
113
|
- [Opaque handles](types.md#opaque-handles)
|
|
@@ -166,8 +172,6 @@ sqlite3_close_v2(db);
|
|
|
166
172
|
|
|
167
173
|
## Javascript callbacks
|
|
168
174
|
|
|
169
|
-
### Using callbacks
|
|
170
|
-
|
|
171
175
|
In order to pass a JS function to a C function expecting a callback, you must first create a callback type with the expected return type and parameters. The syntax is similar to the one used to load functions from a shared library.
|
|
172
176
|
|
|
173
177
|
```js
|
|
@@ -180,7 +184,7 @@ const ExampleCallback = koffi.callback('ExampleCallback', 'void', ['int']);
|
|
|
180
184
|
const AddDoubleFloat = koffi.callback('double AddDoubleFloat(double d, float f)');
|
|
181
185
|
```
|
|
182
186
|
|
|
183
|
-
Once your callback type is declared, you can use
|
|
187
|
+
Once your callback type is declared, you can use it in struct definitions, or as function parameter and/or return type.
|
|
184
188
|
|
|
185
189
|
Here is a small example with the C part and the JS part.
|
|
186
190
|
|
|
@@ -217,8 +221,8 @@ console.log(ret);
|
|
|
217
221
|
|
|
218
222
|
On x86 platforms, only Cdecl and Stdcall callbacks are supported.
|
|
219
223
|
|
|
220
|
-
|
|
224
|
+
## Thread safety
|
|
221
225
|
|
|
222
|
-
|
|
226
|
+
Asynchronous functions run on worker threads. You need to deal with thread safety issues if you share data between threads.
|
|
223
227
|
|
|
224
|
-
|
|
228
|
+
Callbacks must be called from the main thread, or more precisely from the same thread as the V8 intepreter. Calling a callback from another thread is undefined behavior, and will likely lead to a crash or a big mess. You've been warned!
|
package/doc/index.rst
CHANGED
|
@@ -6,7 +6,7 @@ Overview
|
|
|
6
6
|
|
|
7
7
|
Koffi is a **fast and easy-to-use C FFI module for Node.js**, featuring:
|
|
8
8
|
|
|
9
|
-
* Low-overhead and fast performance (see :ref:`Benchmarks
|
|
9
|
+
* Low-overhead and fast performance (see :ref:`benchmarks<Benchmarks>`)
|
|
10
10
|
* Support for primitive and aggregate data types (structs and fixed-size arrays), both by reference (pointer) and by value
|
|
11
11
|
* Javascript functions can be used as C callbacks (since 1.2.0)
|
|
12
12
|
* Well-tested code base for :ref:`popular OS/architecture combinations<Supported platforms>`
|
|
@@ -24,6 +24,7 @@ Table of contents
|
|
|
24
24
|
memory
|
|
25
25
|
benchmarks
|
|
26
26
|
contribute
|
|
27
|
+
changes
|
|
27
28
|
|
|
28
29
|
License
|
|
29
30
|
-------
|
package/doc/memory.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
For synchronous/normal calls, Koffi uses two preallocated memory blocks:
|
|
6
6
|
|
|
7
|
-
- One to construct
|
|
7
|
+
- One to construct the C stack and assign registers, subsequently used by the platform-specific assembly code (1 MiB by default)
|
|
8
8
|
- One to allocate strings and big objects/structs (2 MiB by default)
|
|
9
9
|
|
|
10
10
|
Unless very big strings or objects (at least more than one page of memory) are used, no extra allocation ever happens during calls or callbacks.
|
|
@@ -18,12 +18,15 @@ console.log(config);
|
|
|
18
18
|
|
|
19
19
|
The same is true for asynchronous calls. When an asynchronous call is made, Koffi will allocate new blocks unless there is an unused (resident) set of blocks still available. Once the asynchronous call is finished, these blocks are freed if there are more than `resident_async_pools` sets of blocks left around.
|
|
20
20
|
|
|
21
|
+
There cannot be more than `max_async_calls` running at the same time.
|
|
22
|
+
|
|
21
23
|
## Default settings
|
|
22
24
|
|
|
23
25
|
Setting | Default | Description
|
|
24
26
|
-------------------- | ------- | -----------------------------------------------
|
|
25
27
|
sync_stack_size | 1 MiB | Stack size for synchronous calls
|
|
26
28
|
sync_heap_size | 2 MiB | Heap size for synchronous calls
|
|
27
|
-
async_stack_size |
|
|
28
|
-
async_heap_size |
|
|
29
|
+
async_stack_size | 256 kiB | Stack size for asynchronous calls
|
|
30
|
+
async_heap_size | 512 kiB | Heap size for asynchronous calls
|
|
29
31
|
resident_async_pools | 2 | Number of resident pools for asynchronous calls
|
|
32
|
+
max_async_calls | 64 | Maximum number of ongoing asynchronous calls
|
package/doc/platforms.md
CHANGED
|
@@ -12,6 +12,8 @@ RISC-V 64 [^3] | ⬜️ *N/A* | ✅ Yes | ⬜️ *N/A* | 🟨 Probab
|
|
|
12
12
|
|
|
13
13
|
For all fully supported platforms (green check marks), a prebuilt binary is included in the NPM package which means you can install Koffi without a C++ compiler.
|
|
14
14
|
|
|
15
|
+
Node 12 or later is required, earlier versions are not supported. Use [NVM](https://github.com/nvm-sh/nvm) to install recent Node versions on older Linux distributions.
|
|
16
|
+
|
|
15
17
|
[^1]: The following call conventions are supported for forward calls: cdecl, stdcall, MS fastcall, thiscall. Only cdecl and stdcall can be used for C to JS callbacks.
|
|
16
18
|
[^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).
|
|
17
19
|
[^3]: The prebuilt binary uses the LP64D (double-precision float) ABI. The LP64 ABI is supported in theory if you build Koffi from source (untested), the LP64F ABI is not supported.
|
package/doc/start.md
CHANGED
|
@@ -19,7 +19,7 @@ Below you can find three examples:
|
|
|
19
19
|
|
|
20
20
|
## Small Linux example
|
|
21
21
|
|
|
22
|
-
This is a small example for Linux systems, which uses `gettimeofday()` and `printf()` to print the current time
|
|
22
|
+
This is a small example for Linux systems, which uses `gettimeofday()`, `localtime_r()` and `printf()` to print the current time.
|
|
23
23
|
|
|
24
24
|
It illustrates the use of output parameters.
|
|
25
25
|
|
|
@@ -69,7 +69,7 @@ printf('Local time: %02d:%02d:%02d\n', 'int', now.tm_hour, 'int', now.tm_min, 'i
|
|
|
69
69
|
|
|
70
70
|
## Small Windows example
|
|
71
71
|
|
|
72
|
-
This is a small example targeting the Win32 API, using `MessageBox()` to show a Hello message to the user.
|
|
72
|
+
This is a small example targeting the Win32 API, using `MessageBox()` to show a *Hello World!* message to the user.
|
|
73
73
|
|
|
74
74
|
It illustrates the use of the x86 stdcall calling convention.
|
|
75
75
|
|
|
@@ -85,5 +85,5 @@ const MB_ICONINFORMATION = 0x40;
|
|
|
85
85
|
// Find functions
|
|
86
86
|
const MessageBoxA = lib.stdcall('MessageBoxA', 'int', ['void *', 'string', 'string', 'uint']);
|
|
87
87
|
|
|
88
|
-
MessageBoxA(null, 'Hello', '
|
|
88
|
+
MessageBoxA(null, 'Hello World!', 'Koffi', MB_ICONINFORMATION);
|
|
89
89
|
```
|
package/doc/types.md
CHANGED
|
@@ -42,6 +42,8 @@ Number (float) | float64 | 8 | |
|
|
|
42
42
|
Number (float) | float | 4 | |
|
|
43
43
|
Number (float) | double | 8 | |
|
|
44
44
|
|
|
45
|
+
Koffi also accepts BigInt values when converting from JS to C integers. If the value exceeds the range of the C type, Koffi will convert the number to an undefined value. In the reverse direction, BigInt values are automatically used when needed for big 64-bit integers.
|
|
46
|
+
|
|
45
47
|
Koffi defines a few more types that can change size depending on the OS and the architecture:
|
|
46
48
|
|
|
47
49
|
JS type | C type | Signedness | Note
|
|
@@ -95,7 +97,7 @@ const A = koffi.struct('A', {
|
|
|
95
97
|
|
|
96
98
|
Koffi follows the C and ABI rules regarding struct alignment and padding.
|
|
97
99
|
|
|
98
|
-
Once a struct is declared, you can use it by name (with a string, like you can do for primitive types) or
|
|
100
|
+
Once a struct is declared, you can use it by name (with a string, like you can do for primitive types) or through the value returned by the call to `koffi.struct()`. Only the latter is possible when declaring an anonymous struct.
|
|
99
101
|
|
|
100
102
|
```js
|
|
101
103
|
// The following two function declarations are equivalent, and declare a function taking an A value and returning A
|
|
@@ -107,9 +109,9 @@ const Function2 = lib.func('Function', A, [A]);
|
|
|
107
109
|
|
|
108
110
|
In C, pointer arguments are used for differenty purposes. It is important to distinguish these use cases because Koffi provides different ways to deal with each of them:
|
|
109
111
|
|
|
110
|
-
- **Struct pointers**: Use of struct pointers by C libraries fall in two cases: avoid (potentially) expensive copies, and to let the function change struct contents (output or input/output
|
|
111
|
-
- **Opaque handles**: the library does not expose the contents of the structs, and only provides you with a pointer to it (e.g. `
|
|
112
|
-
- **Arrays**: in C, you dynamically-sized arrays are usually passed to functions with pointers, either NULL-terminated or with an additional length argument.
|
|
112
|
+
- **Struct pointers**: Use of struct pointers by C libraries fall in two cases: avoid (potentially) expensive copies, and to let the function change struct contents (output or input/output arguments).
|
|
113
|
+
- **Opaque handles**: the library does not expose the contents of the structs, and only provides you with a pointer to it (e.g. `FILE *`). Only the functions provided by the library can do something with this pointer, in Koffi we call this a handle. This is usually done for ABI-stability reason, and to prevent library users from messing directly with library internals.
|
|
114
|
+
- **Arrays**: in C, you dynamically-sized arrays are usually passed to functions with pointers, either NULL-terminated (or any other sentinel value) or with an additional length argument.
|
|
113
115
|
- **Pointers to primitive types**: This is more rare, and generally used for output or input/output arguments. The Win32 API has a lot of these.
|
|
114
116
|
|
|
115
117
|
### Struct pointers
|
|
@@ -351,7 +353,7 @@ const ComputeTotalLength = lib.func('int64_t ComputeTotalLength(const char **str
|
|
|
351
353
|
let strings = ['Get', 'Total', 'Length', null];
|
|
352
354
|
let total = ComputeTotalLength(strings);
|
|
353
355
|
|
|
354
|
-
console.log(total); // Prints
|
|
356
|
+
console.log(total); // Prints 14
|
|
355
357
|
```
|
|
356
358
|
|
|
357
359
|
By default, just like for objects, array arguments are copied from JS to C but not vice-versa. You can however change the direction as documented in the section on [output parameters](functions.md#output-parameters).
|
|
@@ -423,7 +425,7 @@ console.log(filenames);
|
|
|
423
425
|
|
|
424
426
|
In javascript, it is not possible to pass a primitive value by reference to another function. This means that you cannot call a function and expect it to modify the value of one of its number or string parameter.
|
|
425
427
|
|
|
426
|
-
However, arrays and objects (among others) are reference type values. Assigning an array or an object from one variable to another does not invole any copy. Instead, as the following example illustrates, the new variable references the same
|
|
428
|
+
However, arrays and objects (among others) are reference type values. Assigning an array or an object from one variable to another does not invole any copy. Instead, as the following example illustrates, the new variable references the same array as the first:
|
|
427
429
|
|
|
428
430
|
```js
|
|
429
431
|
let list1 = [1, 2];
|
|
@@ -436,7 +438,7 @@ console.log(list1); // Prints [1, 42]
|
|
|
436
438
|
|
|
437
439
|
All of this means that C functions that are expected to modify their primitive output values (such as an `int *` parameter) cannot be used directly. However, thanks to Koffi's transparent array support, you can use Javascript arrays to approximate reference semantics with single-element arrays.
|
|
438
440
|
|
|
439
|
-
Below, you can find an example of an addition function where the result is stored in an `int *` output parameter and how to use this function from Koffi.
|
|
441
|
+
Below, you can find an example of an addition function where the result is stored in an `int *` input/output parameter and how to use this function from Koffi.
|
|
440
442
|
|
|
441
443
|
```c
|
|
442
444
|
void AddInt(int *dest, int add)
|
|
@@ -445,7 +447,7 @@ void AddInt(int *dest, int add)
|
|
|
445
447
|
}
|
|
446
448
|
```
|
|
447
449
|
|
|
448
|
-
You can simply pass a single-element array as the
|
|
450
|
+
You can simply pass a single-element array as the first argument:
|
|
449
451
|
|
|
450
452
|
```js
|
|
451
453
|
const AddInt = lib.func('void AddInt(_Inout_ int *dest, int add)');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "koffi",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.5",
|
|
4
4
|
"description": "Fast and simple C FFI (foreign function interface) for Node.js",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"foreign",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
},
|
|
26
26
|
"license": "AGPL-3.0",
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"cnoke": "^2.0.
|
|
28
|
+
"cnoke": "^2.0.4"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"chalk": "^4.1.2",
|
package/qemu/qemu.js
CHANGED
|
@@ -392,6 +392,12 @@
|
|
|
392
392
|
"arch": "x64",
|
|
393
393
|
"directory": "/Users/macos/luigi",
|
|
394
394
|
"build": "PATH=/usr/local/bin:/usr/bin:/bin SDKROOT=/Library/Developer/CommandLineTools/SDKs/MacOSX11.3.sdk node ../cnoke/cnoke.js"
|
|
395
|
+
},
|
|
396
|
+
|
|
397
|
+
"macOS ARM64": {
|
|
398
|
+
"arch": "arm64",
|
|
399
|
+
"directory": "/Users/macos/luigi_arm64",
|
|
400
|
+
"build": "PATH=/usr/local/bin:/usr/bin:/bin SDKROOT=/Library/Developer/CommandLineTools/SDKs/MacOSX11.3.sdk node ../cnoke/cnoke.js --arch arm64"
|
|
395
401
|
}
|
|
396
402
|
},
|
|
397
403
|
|
|
@@ -538,16 +544,5 @@
|
|
|
538
544
|
}
|
|
539
545
|
}
|
|
540
546
|
}
|
|
541
|
-
},
|
|
542
|
-
|
|
543
|
-
"macos_arm64": {
|
|
544
|
-
"name": "macOS ARM64",
|
|
545
|
-
"platform": "darwin",
|
|
546
|
-
|
|
547
|
-
"builds": {
|
|
548
|
-
"macOS ARM64": {
|
|
549
|
-
"arch": "arm64"
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
547
|
}
|
|
553
548
|
}
|
package/src/abi_arm32.cc
CHANGED
|
@@ -497,14 +497,14 @@ Napi::Value CallData::Complete()
|
|
|
497
497
|
switch (func->ret.type->primitive) {
|
|
498
498
|
case PrimitiveKind::Void: return env.Null();
|
|
499
499
|
case PrimitiveKind::Bool: return Napi::Boolean::New(env, result.u32);
|
|
500
|
-
case PrimitiveKind::Int8:
|
|
501
|
-
case PrimitiveKind::UInt8:
|
|
502
|
-
case PrimitiveKind::Int16:
|
|
503
|
-
case PrimitiveKind::UInt16:
|
|
504
|
-
case PrimitiveKind::Int32:
|
|
500
|
+
case PrimitiveKind::Int8: return Napi::Number::New(env, (double)result.i8);
|
|
501
|
+
case PrimitiveKind::UInt8: return Napi::Number::New(env, (double)result.u8);
|
|
502
|
+
case PrimitiveKind::Int16: return Napi::Number::New(env, (double)result.i16);
|
|
503
|
+
case PrimitiveKind::UInt16: return Napi::Number::New(env, (double)result.u16);
|
|
504
|
+
case PrimitiveKind::Int32: return Napi::Number::New(env, (double)result.i32);
|
|
505
505
|
case PrimitiveKind::UInt32: return Napi::Number::New(env, (double)result.u32);
|
|
506
|
-
case PrimitiveKind::Int64: return
|
|
507
|
-
case PrimitiveKind::UInt64: return
|
|
506
|
+
case PrimitiveKind::Int64: return NewBigInt(env, result.i64);
|
|
507
|
+
case PrimitiveKind::UInt64: return NewBigInt(env, result.u64);
|
|
508
508
|
case PrimitiveKind::String: return result.ptr ? Napi::String::New(env, (const char *)result.ptr) : env.Null();
|
|
509
509
|
case PrimitiveKind::String16: return result.ptr ? Napi::String::New(env, (const char16_t *)result.ptr) : env.Null();
|
|
510
510
|
case PrimitiveKind::Pointer:
|
|
@@ -603,7 +603,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
|
|
|
603
603
|
int64_t v = *(int64_t *)(param.gpr_count ? gpr_ptr : args_ptr);
|
|
604
604
|
(param.gpr_count ? gpr_ptr : args_ptr) += 2;
|
|
605
605
|
|
|
606
|
-
Napi::Value arg =
|
|
606
|
+
Napi::Value arg = NewBigInt(env, v);
|
|
607
607
|
arguments.Append(arg);
|
|
608
608
|
} break;
|
|
609
609
|
case PrimitiveKind::UInt64: {
|
|
@@ -612,7 +612,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
|
|
|
612
612
|
uint64_t v = *(uint64_t *)(param.gpr_count ? gpr_ptr : args_ptr);
|
|
613
613
|
(param.gpr_count ? gpr_ptr : args_ptr) += 2;
|
|
614
614
|
|
|
615
|
-
Napi::Value arg =
|
|
615
|
+
Napi::Value arg = NewBigInt(env, v);
|
|
616
616
|
arguments.Append(arg);
|
|
617
617
|
} break;
|
|
618
618
|
case PrimitiveKind::String: {
|
package/src/abi_arm64.cc
CHANGED
|
@@ -518,14 +518,14 @@ Napi::Value CallData::Complete()
|
|
|
518
518
|
switch (func->ret.type->primitive) {
|
|
519
519
|
case PrimitiveKind::Void: return env.Null();
|
|
520
520
|
case PrimitiveKind::Bool: return Napi::Boolean::New(env, result.u32);
|
|
521
|
-
case PrimitiveKind::Int8:
|
|
522
|
-
case PrimitiveKind::UInt8:
|
|
523
|
-
case PrimitiveKind::Int16:
|
|
524
|
-
case PrimitiveKind::UInt16:
|
|
525
|
-
case PrimitiveKind::Int32:
|
|
521
|
+
case PrimitiveKind::Int8: return Napi::Number::New(env, (double)result.i8);
|
|
522
|
+
case PrimitiveKind::UInt8: return Napi::Number::New(env, (double)result.u8);
|
|
523
|
+
case PrimitiveKind::Int16: return Napi::Number::New(env, (double)result.i16);
|
|
524
|
+
case PrimitiveKind::UInt16: return Napi::Number::New(env, (double)result.u16);
|
|
525
|
+
case PrimitiveKind::Int32: return Napi::Number::New(env, (double)result.i32);
|
|
526
526
|
case PrimitiveKind::UInt32: return Napi::Number::New(env, (double)result.u32);
|
|
527
|
-
case PrimitiveKind::Int64: return
|
|
528
|
-
case PrimitiveKind::UInt64: return
|
|
527
|
+
case PrimitiveKind::Int64: return NewBigInt(env, result.i64);
|
|
528
|
+
case PrimitiveKind::UInt64: return NewBigInt(env, result.u64);
|
|
529
529
|
case PrimitiveKind::String: return result.ptr ? Napi::String::New(env, (const char *)result.ptr) : env.Null();
|
|
530
530
|
case PrimitiveKind::String16: return result.ptr ? Napi::String::New(env, (const char16_t *)result.ptr) : env.Null();
|
|
531
531
|
case PrimitiveKind::Pointer:
|
|
@@ -703,7 +703,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
|
|
|
703
703
|
|
|
704
704
|
int64_t v = *(int64_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
|
|
705
705
|
|
|
706
|
-
Napi::Value arg =
|
|
706
|
+
Napi::Value arg = NewBigInt(env, v);
|
|
707
707
|
arguments.Append(arg);
|
|
708
708
|
} break;
|
|
709
709
|
case PrimitiveKind::UInt64: {
|
|
@@ -713,7 +713,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
|
|
|
713
713
|
|
|
714
714
|
uint64_t v = *(uint64_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
|
|
715
715
|
|
|
716
|
-
Napi::Value arg =
|
|
716
|
+
Napi::Value arg = NewBigInt(env, v);
|
|
717
717
|
arguments.Append(arg);
|
|
718
718
|
} break;
|
|
719
719
|
case PrimitiveKind::String: {
|
package/src/abi_riscv64.cc
CHANGED
|
@@ -433,14 +433,14 @@ Napi::Value CallData::Complete()
|
|
|
433
433
|
switch (func->ret.type->primitive) {
|
|
434
434
|
case PrimitiveKind::Void: return env.Null();
|
|
435
435
|
case PrimitiveKind::Bool: return Napi::Boolean::New(env, result.u32);
|
|
436
|
-
case PrimitiveKind::Int8:
|
|
437
|
-
case PrimitiveKind::UInt8:
|
|
438
|
-
case PrimitiveKind::Int16:
|
|
439
|
-
case PrimitiveKind::UInt16:
|
|
440
|
-
case PrimitiveKind::Int32:
|
|
436
|
+
case PrimitiveKind::Int8: return Napi::Number::New(env, (double)result.i8);
|
|
437
|
+
case PrimitiveKind::UInt8: return Napi::Number::New(env, (double)result.u8);
|
|
438
|
+
case PrimitiveKind::Int16: return Napi::Number::New(env, (double)result.i16);
|
|
439
|
+
case PrimitiveKind::UInt16: return Napi::Number::New(env, (double)result.u16);
|
|
440
|
+
case PrimitiveKind::Int32: return Napi::Number::New(env, (double)result.i32);
|
|
441
441
|
case PrimitiveKind::UInt32: return Napi::Number::New(env, (double)result.u32);
|
|
442
|
-
case PrimitiveKind::Int64: return
|
|
443
|
-
case PrimitiveKind::UInt64: return
|
|
442
|
+
case PrimitiveKind::Int64: return NewBigInt(env, result.i64);
|
|
443
|
+
case PrimitiveKind::UInt64: return NewBigInt(env, result.u64);
|
|
444
444
|
case PrimitiveKind::String: return result.ptr ? Napi::String::New(env, (const char *)result.ptr) : env.Null();
|
|
445
445
|
case PrimitiveKind::String16: return result.ptr ? Napi::String::New(env, (const char16_t *)result.ptr) : env.Null();
|
|
446
446
|
case PrimitiveKind::Pointer:
|
|
@@ -541,13 +541,13 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
|
|
|
541
541
|
case PrimitiveKind::Int64: {
|
|
542
542
|
int64_t v = *(int64_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
|
|
543
543
|
|
|
544
|
-
Napi::Value arg =
|
|
544
|
+
Napi::Value arg = NewBigInt(env, v);
|
|
545
545
|
arguments.Append(arg);
|
|
546
546
|
} break;
|
|
547
547
|
case PrimitiveKind::UInt64: {
|
|
548
548
|
uint64_t v = *(uint64_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
|
|
549
549
|
|
|
550
|
-
Napi::Value arg =
|
|
550
|
+
Napi::Value arg = NewBigInt(env, v);
|
|
551
551
|
arguments.Append(arg);
|
|
552
552
|
} break;
|
|
553
553
|
case PrimitiveKind::String: {
|
package/src/abi_x64_sysv.cc
CHANGED
|
@@ -489,14 +489,14 @@ Napi::Value CallData::Complete()
|
|
|
489
489
|
switch (func->ret.type->primitive) {
|
|
490
490
|
case PrimitiveKind::Void: return env.Null();
|
|
491
491
|
case PrimitiveKind::Bool: return Napi::Boolean::New(env, result.u32);
|
|
492
|
-
case PrimitiveKind::Int8:
|
|
493
|
-
case PrimitiveKind::UInt8:
|
|
494
|
-
case PrimitiveKind::Int16:
|
|
495
|
-
case PrimitiveKind::UInt16:
|
|
496
|
-
case PrimitiveKind::Int32:
|
|
492
|
+
case PrimitiveKind::Int8: return Napi::Number::New(env, (double)result.i8);
|
|
493
|
+
case PrimitiveKind::UInt8: return Napi::Number::New(env, (double)result.u8);
|
|
494
|
+
case PrimitiveKind::Int16: return Napi::Number::New(env, (double)result.i16);
|
|
495
|
+
case PrimitiveKind::UInt16: return Napi::Number::New(env, (double)result.u16);
|
|
496
|
+
case PrimitiveKind::Int32: return Napi::Number::New(env, (double)result.i32);
|
|
497
497
|
case PrimitiveKind::UInt32: return Napi::Number::New(env, (double)result.u32);
|
|
498
|
-
case PrimitiveKind::Int64: return
|
|
499
|
-
case PrimitiveKind::UInt64: return
|
|
498
|
+
case PrimitiveKind::Int64: return NewBigInt(env, result.i64);
|
|
499
|
+
case PrimitiveKind::UInt64: return NewBigInt(env, result.u64);
|
|
500
500
|
case PrimitiveKind::String: return result.ptr ? Napi::String::New(env, (const char *)result.ptr) : env.Null();
|
|
501
501
|
case PrimitiveKind::String16: return result.ptr ? Napi::String::New(env, (const char16_t *)result.ptr) : env.Null();
|
|
502
502
|
case PrimitiveKind::Pointer:
|
|
@@ -592,13 +592,13 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
|
|
|
592
592
|
case PrimitiveKind::Int64: {
|
|
593
593
|
int64_t v = *(int64_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
|
|
594
594
|
|
|
595
|
-
Napi::Value arg =
|
|
595
|
+
Napi::Value arg = NewBigInt(env, v);
|
|
596
596
|
arguments.Append(arg);
|
|
597
597
|
} break;
|
|
598
598
|
case PrimitiveKind::UInt64: {
|
|
599
599
|
uint64_t v = *(uint64_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
|
|
600
600
|
|
|
601
|
-
Napi::Value arg =
|
|
601
|
+
Napi::Value arg = NewBigInt(env, v);
|
|
602
602
|
arguments.Append(arg);
|
|
603
603
|
} break;
|
|
604
604
|
case PrimitiveKind::String: {
|
package/src/abi_x64_win.cc
CHANGED
|
@@ -299,14 +299,14 @@ Napi::Value CallData::Complete()
|
|
|
299
299
|
switch (func->ret.type->primitive) {
|
|
300
300
|
case PrimitiveKind::Void: return env.Null();
|
|
301
301
|
case PrimitiveKind::Bool: return Napi::Boolean::New(env, result.u32);
|
|
302
|
-
case PrimitiveKind::Int8:
|
|
303
|
-
case PrimitiveKind::UInt8:
|
|
304
|
-
case PrimitiveKind::Int16:
|
|
305
|
-
case PrimitiveKind::UInt16:
|
|
306
|
-
case PrimitiveKind::Int32:
|
|
302
|
+
case PrimitiveKind::Int8: return Napi::Number::New(env, (double)result.i8);
|
|
303
|
+
case PrimitiveKind::UInt8: return Napi::Number::New(env, (double)result.u8);
|
|
304
|
+
case PrimitiveKind::Int16: return Napi::Number::New(env, (double)result.i16);
|
|
305
|
+
case PrimitiveKind::UInt16: return Napi::Number::New(env, (double)result.u16);
|
|
306
|
+
case PrimitiveKind::Int32: return Napi::Number::New(env, (double)result.i32);
|
|
307
307
|
case PrimitiveKind::UInt32: return Napi::Number::New(env, (double)result.u32);
|
|
308
|
-
case PrimitiveKind::Int64: return
|
|
309
|
-
case PrimitiveKind::UInt64: return
|
|
308
|
+
case PrimitiveKind::Int64: return NewBigInt(env, result.i64);
|
|
309
|
+
case PrimitiveKind::UInt64: return NewBigInt(env, result.u64);
|
|
310
310
|
case PrimitiveKind::String: return result.ptr ? Napi::String::New(env, (const char *)result.ptr) : env.Null();
|
|
311
311
|
case PrimitiveKind::String16: return result.ptr ? Napi::String::New(env, (const char16_t *)result.ptr) : env.Null();
|
|
312
312
|
case PrimitiveKind::Pointer:
|
|
@@ -409,14 +409,14 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
|
|
|
409
409
|
int64_t v = *(int64_t *)(j < 4 ? gpr_ptr + j : args_ptr);
|
|
410
410
|
args_ptr += (j >= 4);
|
|
411
411
|
|
|
412
|
-
Napi::Value arg =
|
|
412
|
+
Napi::Value arg = NewBigInt(env, v);
|
|
413
413
|
arguments.Append(arg);
|
|
414
414
|
} break;
|
|
415
415
|
case PrimitiveKind::UInt64: {
|
|
416
416
|
uint64_t v = *(uint64_t *)(j < 4 ? gpr_ptr + j : args_ptr);
|
|
417
417
|
args_ptr += (j >= 4);
|
|
418
418
|
|
|
419
|
-
Napi::Value arg =
|
|
419
|
+
Napi::Value arg = NewBigInt(env, v);
|
|
420
420
|
arguments.Append(arg);
|
|
421
421
|
} break;
|
|
422
422
|
case PrimitiveKind::String: {
|
package/src/abi_x86.cc
CHANGED
|
@@ -373,14 +373,14 @@ Napi::Value CallData::Complete()
|
|
|
373
373
|
switch (func->ret.type->primitive) {
|
|
374
374
|
case PrimitiveKind::Void: return env.Null();
|
|
375
375
|
case PrimitiveKind::Bool: return Napi::Boolean::New(env, result.u32);
|
|
376
|
-
case PrimitiveKind::Int8:
|
|
377
|
-
case PrimitiveKind::UInt8:
|
|
378
|
-
case PrimitiveKind::Int16:
|
|
379
|
-
case PrimitiveKind::UInt16:
|
|
380
|
-
case PrimitiveKind::Int32:
|
|
376
|
+
case PrimitiveKind::Int8: return Napi::Number::New(env, (double)result.i8);
|
|
377
|
+
case PrimitiveKind::UInt8: return Napi::Number::New(env, (double)result.u8);
|
|
378
|
+
case PrimitiveKind::Int16: return Napi::Number::New(env, (double)result.i16);
|
|
379
|
+
case PrimitiveKind::UInt16: return Napi::Number::New(env, (double)result.u16);
|
|
380
|
+
case PrimitiveKind::Int32: return Napi::Number::New(env, (double)result.i32);
|
|
381
381
|
case PrimitiveKind::UInt32: return Napi::Number::New(env, (double)result.u32);
|
|
382
|
-
case PrimitiveKind::Int64: return
|
|
383
|
-
case PrimitiveKind::UInt64: return
|
|
382
|
+
case PrimitiveKind::Int64: return NewBigInt(env, result.i64);
|
|
383
|
+
case PrimitiveKind::UInt64: return NewBigInt(env, result.u64);
|
|
384
384
|
case PrimitiveKind::String: return result.ptr ? Napi::String::New(env, (const char *)result.ptr) : env.Null();
|
|
385
385
|
case PrimitiveKind::String16: return result.ptr ? Napi::String::New(env, (const char16_t *)result.ptr) : env.Null();
|
|
386
386
|
case PrimitiveKind::Pointer:
|
|
@@ -485,14 +485,14 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
|
|
|
485
485
|
int64_t v = *(int64_t *)args_ptr;
|
|
486
486
|
args_ptr += 2;
|
|
487
487
|
|
|
488
|
-
Napi::Value arg =
|
|
488
|
+
Napi::Value arg = NewBigInt(env, v);
|
|
489
489
|
arguments.Append(arg);
|
|
490
490
|
} break;
|
|
491
491
|
case PrimitiveKind::UInt64: {
|
|
492
492
|
uint64_t v = *(uint64_t *)args_ptr;
|
|
493
493
|
args_ptr += 2;
|
|
494
494
|
|
|
495
|
-
Napi::Value arg =
|
|
495
|
+
Napi::Value arg = NewBigInt(env, v);
|
|
496
496
|
arguments.Append(arg);
|
|
497
497
|
} break;
|
|
498
498
|
case PrimitiveKind::String: {
|
package/src/call.cc
CHANGED
|
@@ -40,8 +40,9 @@ CallData::~CallData()
|
|
|
40
40
|
mem->heap = old_heap_mem;
|
|
41
41
|
|
|
42
42
|
instance->free_trampolines |= used_trampolines;
|
|
43
|
+
instance->temporaries -= mem->temporary;
|
|
43
44
|
|
|
44
|
-
if (
|
|
45
|
+
if (!--mem->depth && mem->temporary) {
|
|
45
46
|
delete mem;
|
|
46
47
|
}
|
|
47
48
|
}
|
|
@@ -801,11 +802,11 @@ void CallData::PopObject(Napi::Object obj, const uint8_t *origin, const TypeInfo
|
|
|
801
802
|
} break;
|
|
802
803
|
case PrimitiveKind::Int64: {
|
|
803
804
|
int64_t v = *(int64_t *)src;
|
|
804
|
-
obj.Set(member.name,
|
|
805
|
+
obj.Set(member.name, NewBigInt(env, v));
|
|
805
806
|
} break;
|
|
806
807
|
case PrimitiveKind::UInt64: {
|
|
807
808
|
uint64_t v = *(uint64_t *)src;
|
|
808
|
-
obj.Set(member.name,
|
|
809
|
+
obj.Set(member.name, NewBigInt(env, v));
|
|
809
810
|
} break;
|
|
810
811
|
case PrimitiveKind::String: {
|
|
811
812
|
const char *str = *(const char **)src;
|
|
@@ -914,13 +915,13 @@ void CallData::PopNormalArray(Napi::Array array, const uint8_t *origin, const Ty
|
|
|
914
915
|
case PrimitiveKind::Int64: {
|
|
915
916
|
POP_ARRAY({
|
|
916
917
|
int64_t v = *(int64_t *)src;
|
|
917
|
-
array.Set(i,
|
|
918
|
+
array.Set(i, NewBigInt(env, v));
|
|
918
919
|
});
|
|
919
920
|
} break;
|
|
920
921
|
case PrimitiveKind::UInt64: {
|
|
921
922
|
POP_ARRAY({
|
|
922
923
|
uint64_t v = *(uint64_t *)src;
|
|
923
|
-
array.Set(i,
|
|
924
|
+
array.Set(i, NewBigInt(env, v));
|
|
924
925
|
});
|
|
925
926
|
} break;
|
|
926
927
|
case PrimitiveKind::String: {
|
|
@@ -1078,13 +1079,13 @@ Napi::Value CallData::PopArray(const uint8_t *origin, const TypeInfo *type, int1
|
|
|
1078
1079
|
case PrimitiveKind::Int64: {
|
|
1079
1080
|
POP_ARRAY({
|
|
1080
1081
|
int64_t v = *(int64_t *)src;
|
|
1081
|
-
array.Set(i,
|
|
1082
|
+
array.Set(i, NewBigInt(env, v));
|
|
1082
1083
|
});
|
|
1083
1084
|
} break;
|
|
1084
1085
|
case PrimitiveKind::UInt64: {
|
|
1085
1086
|
POP_ARRAY({
|
|
1086
1087
|
uint64_t v = *(uint64_t *)src;
|
|
1087
|
-
array.Set(i,
|
|
1088
|
+
array.Set(i, NewBigInt(env, v));
|
|
1088
1089
|
});
|
|
1089
1090
|
} break;
|
|
1090
1091
|
case PrimitiveKind::String: {
|