koffi 2.9.2 → 2.10.0
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/CHANGELOG.md +10 -2
- package/build/koffi/darwin_arm64/koffi.node +0 -0
- package/build/koffi/darwin_x64/koffi.node +0 -0
- package/build/koffi/freebsd_arm64/koffi.node +0 -0
- package/build/koffi/freebsd_ia32/koffi.node +0 -0
- package/build/koffi/freebsd_x64/koffi.node +0 -0
- package/build/koffi/linux_arm32/koffi.node +0 -0
- package/build/koffi/linux_arm64/koffi.node +0 -0
- package/build/koffi/linux_ia32/koffi.node +0 -0
- package/build/koffi/linux_riscv64/koffi.node +0 -0
- package/build/koffi/linux_x64/koffi.node +0 -0
- package/build/koffi/musl_x64/koffi.node +0 -0
- package/build/koffi/openbsd_ia32/koffi.node +0 -0
- package/build/koffi/openbsd_x64/koffi.node +0 -0
- package/build/koffi/win32_arm64/koffi.node +0 -0
- package/build/koffi/win32_ia32/koffi.node +0 -0
- package/build/koffi/win32_x64/koffi.node +0 -0
- package/doc/flaat/normal.css +19 -4
- package/doc/flaat/small.css +8 -1
- package/doc/pages/index.md +1 -1
- package/doc/pages/misc.md +35 -0
- package/doc/pages/packaging.md +11 -2
- package/doc/pages/platforms.md +23 -7
- package/doc/pages.ini +8 -7
- package/doc/static/koffi.png +0 -0
- package/doc/static/logo.webp +0 -0
- package/doc/templates/page.html +9 -1
- package/index.js +2 -2
- package/indirect.js +2 -2
- package/package.json +2 -2
- package/src/koffi/CMakeLists.txt +6 -0
- package/src/koffi/examples/yao-pkg/README.md +17 -0
- package/src/koffi/examples/yao-pkg/index.js +2 -0
- package/src/koffi/examples/yao-pkg/package.json +22 -0
- package/src/koffi/src/ffi.cc +40 -4
- package/src/koffi/src/util.cc +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,13 @@
|
|
|
5
5
|
|
|
6
6
|
## Koffi 2
|
|
7
7
|
|
|
8
|
+
### Koffi 2.10
|
|
9
|
+
|
|
10
|
+
#### Koffi 2.10.0 (2024-12-22)
|
|
11
|
+
|
|
12
|
+
- Allow [redefinition of opaque types](misc#circular-references) to concrete struct or union
|
|
13
|
+
- Update documentation style
|
|
14
|
+
|
|
8
15
|
### Koffi 2.9
|
|
9
16
|
|
|
10
17
|
#### Koffi 2.9.2 (2024-11-08)
|
|
@@ -30,7 +37,7 @@
|
|
|
30
37
|
- Work around MSVC compiler bug introduced in Visual Studio 17.10
|
|
31
38
|
|
|
32
39
|
> [!WARNING]
|
|
33
|
-
Use on platforms without pre-built binaries is broken in Koffi 2.8.10, skip this version.
|
|
40
|
+
> Use on platforms without pre-built binaries is broken in Koffi 2.8.10, skip this version.
|
|
34
41
|
|
|
35
42
|
#### Koffi 2.8.9 (2024-05-17)
|
|
36
43
|
|
|
@@ -700,9 +707,10 @@ This entry documents changes since version 1.1.0.
|
|
|
700
707
|
|
|
701
708
|
The following features and improvements are planned, not necessarily in that order:
|
|
702
709
|
|
|
710
|
+
- Port Koffi to Loong64 ISA and ABI
|
|
711
|
+
- Port Koffi to PowerPC (POWER9+) ISA and ABI
|
|
703
712
|
- Optimize passing of structs and arrays (with auto-generated JS)
|
|
704
713
|
- Automate Windows/AArch64 (qemu) and macOS/AArch64 (how? ... thanks Apple) tests
|
|
705
714
|
- Create a real-world example, using several libraries (Raylib, SQLite, libsodium) to illustrate various C API styles
|
|
706
715
|
- Add simple struct type parser
|
|
707
|
-
- Port Koffi to PowerPC (POWER9+) ABI
|
|
708
716
|
- Fix assembly unwind and CFI directives for better debugging experience
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/doc/flaat/normal.css
CHANGED
|
@@ -20,8 +20,9 @@
|
|
|
20
20
|
OTHER DEALINGS IN THE SOFTWARE. */
|
|
21
21
|
|
|
22
22
|
html {
|
|
23
|
-
--top_height:
|
|
24
|
-
--
|
|
23
|
+
--top_height: 90px;
|
|
24
|
+
--top_padding: 6px;
|
|
25
|
+
--small_height: 80px;
|
|
25
26
|
|
|
26
27
|
height: 100%;
|
|
27
28
|
scroll-padding-top: calc(var(--top_height) + 10px);
|
|
@@ -68,7 +69,7 @@ a:has(> img) { text-decoration: none !important; }
|
|
|
68
69
|
height: var(--top_height);
|
|
69
70
|
box-sizing: border-box;
|
|
70
71
|
margin: 0 auto;
|
|
71
|
-
padding:
|
|
72
|
+
padding: var(--top_padding);
|
|
72
73
|
overflow: visible;
|
|
73
74
|
z-index: 1;
|
|
74
75
|
display: flex;
|
|
@@ -132,7 +133,6 @@ a:has(> img) { text-decoration: none !important; }
|
|
|
132
133
|
height: 100%;
|
|
133
134
|
object-fit: contain;
|
|
134
135
|
}
|
|
135
|
-
#top.border #logo { filter: saturate(0%) brightness(0); }
|
|
136
136
|
|
|
137
137
|
#side menu {
|
|
138
138
|
margin: 0;
|
|
@@ -175,6 +175,16 @@ main {
|
|
|
175
175
|
}
|
|
176
176
|
#side ~ main { padding-right: 290px; }
|
|
177
177
|
|
|
178
|
+
footer {
|
|
179
|
+
padding: 0.5em;
|
|
180
|
+
background: #f6f6f9;
|
|
181
|
+
display: flex;
|
|
182
|
+
gap: 1.5em;
|
|
183
|
+
align-items: center;
|
|
184
|
+
justify-content: center;
|
|
185
|
+
}
|
|
186
|
+
footer > img { filter: saturate(0%) brightness(0); }
|
|
187
|
+
|
|
178
188
|
p { margin: 1em 0 0 0; }
|
|
179
189
|
p:first-child, h1 + p, h2 + p, h3 + p { margin-top: 0; }
|
|
180
190
|
|
|
@@ -268,6 +278,11 @@ code:not(.hljs) {
|
|
|
268
278
|
font-size: 14px;
|
|
269
279
|
background: #eee;
|
|
270
280
|
}
|
|
281
|
+
pre > code:not(.hljs) {
|
|
282
|
+
padding: 0;
|
|
283
|
+
font-size: inherit;
|
|
284
|
+
background: transparent;
|
|
285
|
+
}
|
|
271
286
|
|
|
272
287
|
pre {
|
|
273
288
|
position: relative;
|
package/doc/flaat/small.css
CHANGED
|
@@ -36,7 +36,6 @@
|
|
|
36
36
|
#top menu {
|
|
37
37
|
height: var(--small_height);
|
|
38
38
|
padding-left: 60px;
|
|
39
|
-
padding-bottom: 16px;
|
|
40
39
|
flex-direction: column;
|
|
41
40
|
gap: 0;
|
|
42
41
|
align-items: start;
|
|
@@ -61,6 +60,14 @@
|
|
|
61
60
|
line-height: 1.6em;
|
|
62
61
|
}
|
|
63
62
|
|
|
63
|
+
footer {
|
|
64
|
+
flex-direction: column;
|
|
65
|
+
padding: 0.5em;
|
|
66
|
+
gap: 6px;
|
|
67
|
+
text-align: center;
|
|
68
|
+
}
|
|
69
|
+
footer > img { display: none; }
|
|
70
|
+
|
|
64
71
|
#logo {
|
|
65
72
|
height: 100%;
|
|
66
73
|
margin: 0 auto;
|
package/doc/pages/index.md
CHANGED
package/doc/pages/misc.md
CHANGED
|
@@ -59,6 +59,41 @@ console.log(koffi.sizeof(koffi.types.long));
|
|
|
59
59
|
|
|
60
60
|
You can alias a type with `koffi.alias(name, type)`. Aliased types are completely equivalent.
|
|
61
61
|
|
|
62
|
+
## Circular references
|
|
63
|
+
|
|
64
|
+
*New in Koffi 2.10.0*
|
|
65
|
+
|
|
66
|
+
In some cases, composite types can point to each other and thus depend on each other. This can also happen when a function takes a pointer to a struct that also contains a function pointer.
|
|
67
|
+
|
|
68
|
+
To deal with this, you can create an opaque type and redefine it later to a concrete struct or union type, as shown below.
|
|
69
|
+
|
|
70
|
+
```js
|
|
71
|
+
const Type1 = koffi.opaque('Type1');
|
|
72
|
+
|
|
73
|
+
const Type2 = koffi.struct('Type2', {
|
|
74
|
+
ptr: 'Type1 *',
|
|
75
|
+
i: 'int'
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
// Redefine Type1 to a concrete type
|
|
79
|
+
koffi.struct(Type1, {
|
|
80
|
+
ptr: 'Type2 *',
|
|
81
|
+
f: 'float'
|
|
82
|
+
});
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
> [!NOTE]
|
|
86
|
+
> You must use a proper type object when you redefine the type. If you only have the name, use `koffi.resolve()` to get a type object from a type string.
|
|
87
|
+
>
|
|
88
|
+
> ```js
|
|
89
|
+
> const MyType = koffi.opaque('MyType');
|
|
90
|
+
>
|
|
91
|
+
> // This does not work, you must use the MyType object and not a type string
|
|
92
|
+
> koffi.struct('MyType', {
|
|
93
|
+
> ptr: 'Type2 *',
|
|
94
|
+
> f: 'float'
|
|
95
|
+
> });
|
|
96
|
+
|
|
62
97
|
# Settings
|
|
63
98
|
|
|
64
99
|
## Memory usage
|
package/doc/pages/packaging.md
CHANGED
|
@@ -6,13 +6,16 @@
|
|
|
6
6
|
|
|
7
7
|
Koffi uses native modules to work. The NPM package contains binaries for various platforms and architectures, and the appropriate module is selected at runtime.
|
|
8
8
|
|
|
9
|
+
> [!IMPORTANT]
|
|
10
|
+
> Please note that Koffi is meant for Node.js (or Electron) and not for browsers! It it not possible to load native libraries inside a browser!
|
|
11
|
+
|
|
9
12
|
In theory, the **packagers/bundlers should be able to find all native modules** because they are explictly listed in the Javascript file (as static strings) and package them somehow.
|
|
10
13
|
|
|
11
14
|
If that is not the case, you can manually arrange to copy the `node_modules/koffi/build/koffi` directory next to your bundled script.
|
|
12
15
|
|
|
13
16
|
Here is an example that would work:
|
|
14
17
|
|
|
15
|
-
```
|
|
18
|
+
```text
|
|
16
19
|
koffi/
|
|
17
20
|
win32_x64/
|
|
18
21
|
koffi.node
|
|
@@ -24,7 +27,7 @@ MyBundle.js
|
|
|
24
27
|
|
|
25
28
|
When running in Electron, Koffi will also try to find the native module in `process.resourcesPath`. For an Electron app you could do something like this
|
|
26
29
|
|
|
27
|
-
```
|
|
30
|
+
```text
|
|
28
31
|
locales/
|
|
29
32
|
resources/
|
|
30
33
|
koffi/
|
|
@@ -77,3 +80,9 @@ esbuild index.js --platform=node --bundle --loader:.node=copy --outdir=dist/
|
|
|
77
80
|
```
|
|
78
81
|
|
|
79
82
|
You can find a full [working example in the repository](https://github.com/Koromix/rygel/tree/master/src/koffi/examples/node-esbuild).
|
|
83
|
+
|
|
84
|
+
## Node.js and yao-pkg
|
|
85
|
+
|
|
86
|
+
Use [yao-pkg](https://github.com/yao-pkg/pkg) to make binary packages of your Node.js-based project.
|
|
87
|
+
|
|
88
|
+
You can find a full [working example in the repository](https://github.com/Koromix/rygel/tree/master/src/koffi/examples/yao-pkg).
|
package/doc/pages/platforms.md
CHANGED
|
@@ -14,16 +14,32 @@ Use [NVM](https://github.com/nvm-sh/nvm) to install more recent Node versions on
|
|
|
14
14
|
|
|
15
15
|
The following combinations of OS and architectures __are officially supported and tested__ at the moment:
|
|
16
16
|
|
|
17
|
-
ISA / OS | Windows
|
|
18
|
-
------------------ |
|
|
19
|
-
x86 (IA32) [^1] | ✅
|
|
20
|
-
x86_64 (AMD64) | ✅
|
|
21
|
-
ARM32 LE [^2] | ⬜️
|
|
22
|
-
ARM64 (AArch64) LE | ✅
|
|
23
|
-
RISC-V 64 [^3] | ⬜️
|
|
17
|
+
ISA / OS | Windows | Linux (glibc) | Linux (musl)
|
|
18
|
+
------------------ | ------- | ------------- | ------------
|
|
19
|
+
x86 (IA32) [^1] | ✅ | ✅ | 🟨
|
|
20
|
+
x86_64 (AMD64) | ✅ | ✅ | ✅
|
|
21
|
+
ARM32 LE [^2] | ⬜️ | ✅ | 🟨
|
|
22
|
+
ARM64 (AArch64) LE | ✅ | ✅ | 🟨
|
|
23
|
+
RISC-V 64 [^3] | ⬜️ | ✅ | 🟨
|
|
24
|
+
|
|
25
|
+
<div class="legend">✅ Yes | 🟨 Probably | ⬜️ Not applicable</div>
|
|
26
|
+
|
|
27
|
+
ISA / OS | macOS | FreeBSD | OpenBSD
|
|
28
|
+
------------------ | ----- | ----------- | --------
|
|
29
|
+
x86 (IA32) [^1] | ⬜️ | ✅ | ✅
|
|
30
|
+
x86_64 (AMD64) | ✅ | ✅ | ✅
|
|
31
|
+
ARM32 LE [^2] | ⬜️ | 🟨 | 🟨
|
|
32
|
+
ARM64 (AArch64) LE | ✅ | ✅ | 🟨
|
|
33
|
+
RISC-V 64 [^3] | ⬜️ | 🟨 | 🟨
|
|
34
|
+
|
|
35
|
+
<div class="legend">✅ Yes | 🟨 Probably | ⬜️ Not applicable</div>
|
|
24
36
|
|
|
25
37
|
[^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.
|
|
26
38
|
[^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).
|
|
27
39
|
[^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.
|
|
28
40
|
|
|
29
41
|
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.
|
|
42
|
+
|
|
43
|
+
<style>
|
|
44
|
+
table td:not(:first-child) { text-align: center; }
|
|
45
|
+
</style>
|
package/doc/pages.ini
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Title = Koffi
|
|
3
3
|
Menu = Overview
|
|
4
4
|
Description = Koffi presentation and features
|
|
5
|
+
ToC = Off
|
|
5
6
|
Template = templates/page.html
|
|
6
7
|
|
|
7
8
|
[pages/platforms.md]
|
|
@@ -62,6 +63,12 @@ Title = Packaging | Koffi
|
|
|
62
63
|
Menu = Documentation / Bundlers and Koffi
|
|
63
64
|
Template = templates/page.html
|
|
64
65
|
|
|
66
|
+
[pages/migration.md]
|
|
67
|
+
Title = Migration | Koffi
|
|
68
|
+
Menu = Documentation / Migration guide
|
|
69
|
+
Description = Migration between major Koffi versions
|
|
70
|
+
Template = templates/page.html
|
|
71
|
+
|
|
65
72
|
[pages/benchmarks.md]
|
|
66
73
|
Title = Benchmarks | Koffi
|
|
67
74
|
Menu = Benchmarks
|
|
@@ -77,12 +84,6 @@ Template = templates/page.html
|
|
|
77
84
|
[changelog]
|
|
78
85
|
SourceFile = ../../src/koffi/CHANGELOG.md
|
|
79
86
|
Title = Changelog | Koffi
|
|
80
|
-
Menu = Changelog
|
|
87
|
+
Menu = Changelog
|
|
81
88
|
Description = List of Koffi versions
|
|
82
89
|
Template = templates/page.html
|
|
83
|
-
|
|
84
|
-
[pages/migration.md]
|
|
85
|
-
Title = Migration | Koffi
|
|
86
|
-
Menu = Changelog / Migration guide
|
|
87
|
-
Description = Migration between major Koffi versions
|
|
88
|
-
Template = templates/page.html
|
package/doc/static/koffi.png
CHANGED
|
Binary file
|
|
Binary file
|
package/doc/templates/page.html
CHANGED
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
|
|
21
21
|
<nav id="top">
|
|
22
22
|
<menu>
|
|
23
|
-
<a id="logo" href="/"><img src="{{ ASSET
|
|
23
|
+
<a id="logo" href="/"><img src="{{ ASSET static/logo.webp }}" alt="Logo Koffi" /></a>
|
|
24
24
|
|
|
25
25
|
{{ LINKS }}
|
|
26
26
|
|
|
@@ -36,5 +36,13 @@
|
|
|
36
36
|
<main>
|
|
37
37
|
{{ CONTENT }}
|
|
38
38
|
</main>
|
|
39
|
+
|
|
40
|
+
<footer>
|
|
41
|
+
<div>Koffi © 2024</div>
|
|
42
|
+
<div style="font-size: 0.8em;">
|
|
43
|
+
Niels Martignène (<a href="https://github.com/Koromix/" target="_blank">Koromix</a>)<br>
|
|
44
|
+
<a href="mailto:niels.martignene@protonmail.com" style="font-weight: bold; color: inherit;">niels.martignene@protonmail.com</a>
|
|
45
|
+
</div>
|
|
46
|
+
</footer>
|
|
39
47
|
</body>
|
|
40
48
|
</html>
|
package/index.js
CHANGED
|
@@ -363,8 +363,8 @@ var require_package = __commonJS({
|
|
|
363
363
|
"../../bin/Koffi/package/src/koffi/package.json"(exports2, module2) {
|
|
364
364
|
module2.exports = {
|
|
365
365
|
name: "koffi",
|
|
366
|
-
version: "2.
|
|
367
|
-
stable: "2.
|
|
366
|
+
version: "2.10.0",
|
|
367
|
+
stable: "2.10.0",
|
|
368
368
|
description: "Fast and simple C FFI (foreign function interface) for Node.js",
|
|
369
369
|
keywords: [
|
|
370
370
|
"foreign",
|
package/indirect.js
CHANGED
|
@@ -363,8 +363,8 @@ var require_package = __commonJS({
|
|
|
363
363
|
"../../bin/Koffi/package/src/koffi/package.json"(exports2, module2) {
|
|
364
364
|
module2.exports = {
|
|
365
365
|
name: "koffi",
|
|
366
|
-
version: "2.
|
|
367
|
-
stable: "2.
|
|
366
|
+
version: "2.10.0",
|
|
367
|
+
stable: "2.10.0",
|
|
368
368
|
description: "Fast and simple C FFI (foreign function interface) for Node.js",
|
|
369
369
|
keywords: [
|
|
370
370
|
"foreign",
|
package/package.json
CHANGED
package/src/koffi/CMakeLists.txt
CHANGED
|
@@ -48,6 +48,12 @@ else()
|
|
|
48
48
|
endif()
|
|
49
49
|
endif()
|
|
50
50
|
|
|
51
|
+
if(UNIX AND NOT APPLE)
|
|
52
|
+
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_FILE_OFFSET_BITS=64")
|
|
53
|
+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_FILE_OFFSET_BITS=64")
|
|
54
|
+
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -z noexecstack")
|
|
55
|
+
endif()
|
|
56
|
+
|
|
51
57
|
# ---- Koffi ----
|
|
52
58
|
|
|
53
59
|
# Recompute the version string after each commit
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
This is a simple example to bundle a CLI node.js app that uses Koffi, using [yao-pkg](https://github.com/yao-pkg/pkg).
|
|
2
|
+
|
|
3
|
+
To run the app, execute the following:
|
|
4
|
+
|
|
5
|
+
```sh
|
|
6
|
+
cd examples/yao-pkg
|
|
7
|
+
npm install
|
|
8
|
+
npm start
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
You can bundle the script and the native modules with the following command
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
cd examples/yao-pkg
|
|
15
|
+
npm install
|
|
16
|
+
npm run bundle
|
|
17
|
+
```
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "KoffiConfig",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"start": "node index.js",
|
|
8
|
+
"bundle": "pkg ."
|
|
9
|
+
},
|
|
10
|
+
"author": "",
|
|
11
|
+
"license": "ISC",
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"koffi": "^2.5.18"
|
|
14
|
+
},
|
|
15
|
+
"devDependencies": {
|
|
16
|
+
"@yao-pkg/pkg": "^6.1.1"
|
|
17
|
+
},
|
|
18
|
+
"bin": "index.js",
|
|
19
|
+
"pkg": {
|
|
20
|
+
"outputPath": "dist"
|
|
21
|
+
}
|
|
22
|
+
}
|
package/src/koffi/src/ffi.cc
CHANGED
|
@@ -244,8 +244,9 @@ static Napi::Value CreateStructType(const Napi::CallbackInfo &info, bool pad)
|
|
|
244
244
|
}
|
|
245
245
|
|
|
246
246
|
bool named = info.Length() > 1;
|
|
247
|
+
bool redefine = named && CheckValueTag(instance, info[0], &TypeInfoMarker);
|
|
247
248
|
|
|
248
|
-
if (named && !info[0].IsString()) {
|
|
249
|
+
if (named && !info[0].IsString() && !redefine) {
|
|
249
250
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for name, expected string", GetValueType(instance, info[0]));
|
|
250
251
|
return env.Null();
|
|
251
252
|
}
|
|
@@ -274,8 +275,20 @@ static Napi::Value CreateStructType(const Napi::CallbackInfo &info, bool pad)
|
|
|
274
275
|
};
|
|
275
276
|
|
|
276
277
|
TypeInfo *type = instance->types.AppendDefault();
|
|
278
|
+
TypeInfo *replace = nullptr;
|
|
277
279
|
|
|
278
|
-
if (
|
|
280
|
+
if (redefine) {
|
|
281
|
+
Napi::External<TypeInfo> external = name.As<Napi::External<TypeInfo>>();
|
|
282
|
+
const TypeInfo *raw = external.Data();
|
|
283
|
+
|
|
284
|
+
replace = (TypeInfo *)AlignDown(raw, 4);
|
|
285
|
+
type->name = replace->name;
|
|
286
|
+
|
|
287
|
+
if (replace->primitive != PrimitiveKind::Void || replace == instance->void_type) {
|
|
288
|
+
ThrowError<Napi::TypeError>(env, "Cannot redefine non-opaque type %1", replace->name);
|
|
289
|
+
return env.Null();
|
|
290
|
+
}
|
|
291
|
+
} else if (named) {
|
|
279
292
|
type->name = DuplicateString(name.Utf8Value().c_str(), &instance->str_alloc).ptr;
|
|
280
293
|
|
|
281
294
|
if (!MapType(env, instance, type, type->name))
|
|
@@ -366,6 +379,11 @@ static Napi::Value CreateStructType(const Napi::CallbackInfo &info, bool pad)
|
|
|
366
379
|
type->flags &= ~(int)TypeFlag::IsIncomplete;
|
|
367
380
|
err_guard.Disable();
|
|
368
381
|
|
|
382
|
+
if (replace) {
|
|
383
|
+
std::swap(*type, *replace);
|
|
384
|
+
type = replace;
|
|
385
|
+
}
|
|
386
|
+
|
|
369
387
|
return WrapType(env, instance, type);
|
|
370
388
|
}
|
|
371
389
|
|
|
@@ -390,8 +408,9 @@ static Napi::Value CreateUnionType(const Napi::CallbackInfo &info)
|
|
|
390
408
|
}
|
|
391
409
|
|
|
392
410
|
bool named = info.Length() > 1;
|
|
411
|
+
bool redefine = named && CheckValueTag(instance, info[0], &TypeInfoMarker);
|
|
393
412
|
|
|
394
|
-
if (named && !info[0].IsString()) {
|
|
413
|
+
if (named && !info[0].IsString() && !redefine) {
|
|
395
414
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for name, expected string", GetValueType(instance, info[0]));
|
|
396
415
|
return env.Null();
|
|
397
416
|
}
|
|
@@ -420,8 +439,20 @@ static Napi::Value CreateUnionType(const Napi::CallbackInfo &info)
|
|
|
420
439
|
};
|
|
421
440
|
|
|
422
441
|
TypeInfo *type = instance->types.AppendDefault();
|
|
442
|
+
TypeInfo *replace = nullptr;
|
|
423
443
|
|
|
424
|
-
if (
|
|
444
|
+
if (redefine) {
|
|
445
|
+
Napi::External<TypeInfo> external = name.As<Napi::External<TypeInfo>>();
|
|
446
|
+
const TypeInfo *raw = external.Data();
|
|
447
|
+
|
|
448
|
+
replace = (TypeInfo *)AlignDown(raw, 4);
|
|
449
|
+
type->name = replace->name;
|
|
450
|
+
|
|
451
|
+
if (replace->primitive != PrimitiveKind::Void || replace == instance->void_type) {
|
|
452
|
+
ThrowError<Napi::TypeError>(env, "Cannot redefine non-opaque type %1", replace->name);
|
|
453
|
+
return env.Null();
|
|
454
|
+
}
|
|
455
|
+
} else if (named) {
|
|
425
456
|
type->name = DuplicateString(name.Utf8Value().c_str(), &instance->str_alloc).ptr;
|
|
426
457
|
|
|
427
458
|
if (!MapType(env, instance, type, type->name))
|
|
@@ -507,6 +538,11 @@ static Napi::Value CreateUnionType(const Napi::CallbackInfo &info)
|
|
|
507
538
|
Napi::Function constructor = MagicUnion::InitClass(env, type);
|
|
508
539
|
type->construct.Reset(constructor, 1);
|
|
509
540
|
|
|
541
|
+
if (replace) {
|
|
542
|
+
std::swap(*type, *replace);
|
|
543
|
+
type = replace;
|
|
544
|
+
}
|
|
545
|
+
|
|
510
546
|
return WrapType(env, instance, type);
|
|
511
547
|
}
|
|
512
548
|
|
package/src/koffi/src/util.cc
CHANGED
|
@@ -146,8 +146,8 @@ const TypeInfo *ResolveType(Napi::Value value, int *out_directions)
|
|
|
146
146
|
return type;
|
|
147
147
|
} else if (CheckValueTag(instance, value, &TypeInfoMarker)) {
|
|
148
148
|
Napi::External<TypeInfo> external = value.As<Napi::External<TypeInfo>>();
|
|
149
|
-
|
|
150
149
|
const TypeInfo *raw = external.Data();
|
|
150
|
+
|
|
151
151
|
const TypeInfo *type = AlignDown(raw, 4);
|
|
152
152
|
RG_ASSERT(type);
|
|
153
153
|
|