koffi 2.14.0 → 2.15.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 +26 -1
- package/README.md +1 -1
- 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_arm64/koffi.node +0 -0
- package/build/koffi/linux_armhf/koffi.node +0 -0
- package/build/koffi/linux_ia32/koffi.node +0 -0
- package/build/koffi/linux_loong64/koffi.node +0 -0
- package/build/koffi/linux_riscv64d/koffi.node +0 -0
- package/build/koffi/linux_x64/koffi.node +0 -0
- package/build/koffi/musl_arm64/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/assets.ini +2 -1
- package/doc/build.sh +9 -0
- package/doc/pages/404.md +17 -0
- package/doc/pages/index.md +43 -4
- package/doc/pages/misc.md +16 -11
- package/doc/pages/platforms.md +8 -19
- package/doc/pages.ini +4 -7
- package/doc/static/highlight.js +2 -14
- package/doc/static/koffi.css +3 -15
- package/doc/static/perf_windows.png +0 -0
- package/doc/static/print.css +2 -14
- package/index.d.ts +29 -24
- package/index.js +10 -9
- package/indirect.js +10 -9
- package/{src/core → lib/native}/base/base.cc +1753 -1089
- package/{src/core → lib/native}/base/base.hh +868 -572
- package/{src/core → lib/native}/base/crc.inc +3 -21
- package/lib/native/base/crc_gen.py +72 -0
- package/{src/core → lib/native}/base/mimetypes.inc +2 -20
- package/{src/core → lib/native}/base/mimetypes_gen.py +2 -21
- package/lib/native/base/tower.cc +821 -0
- package/lib/native/base/tower.hh +81 -0
- package/{src/core → lib/native}/base/unicode.inc +3 -21
- package/{src/core → lib/native}/base/unicode_gen.py +5 -42
- package/package.json +3 -2
- package/src/cnoke/assets/FindCNoke.cmake +8 -20
- package/src/cnoke/assets/win_delay_hook.c +2 -20
- package/src/cnoke/cnoke.js +2 -21
- package/src/cnoke/src/builder.js +3 -22
- package/src/cnoke/src/index.js +2 -20
- package/src/cnoke/src/tools.js +2 -20
- package/src/koffi/CMakeLists.txt +19 -22
- package/src/koffi/cmake/raylib.cmake +5 -22
- package/src/koffi/cmake/sqlite3.cmake +2 -20
- package/src/koffi/src/abi_arm32.cc +31 -49
- package/src/koffi/src/abi_arm32_asm.S +2 -20
- package/src/koffi/src/abi_arm64.cc +36 -54
- package/src/koffi/src/abi_arm64_asm.S +2 -20
- package/src/koffi/src/abi_arm64_asm.asm +2 -20
- package/src/koffi/src/abi_loong64.cc +2 -20
- package/src/koffi/src/abi_loong64_asm.S +2 -20
- package/src/koffi/src/abi_riscv64.cc +34 -52
- package/src/koffi/src/abi_riscv64_asm.S +2 -20
- package/src/koffi/src/abi_x64_sysv.cc +36 -54
- package/src/koffi/src/abi_x64_sysv_asm.S +2 -20
- package/src/koffi/src/abi_x64_win.cc +32 -50
- package/src/koffi/src/abi_x64_win_asm.asm +2 -20
- package/src/koffi/src/abi_x86.cc +33 -51
- package/src/koffi/src/abi_x86_asm.S +2 -20
- package/src/koffi/src/abi_x86_asm.asm +2 -20
- package/src/koffi/src/call.cc +107 -281
- package/src/koffi/src/call.hh +9 -27
- package/src/koffi/src/errno.inc +2 -20
- package/src/koffi/src/ffi.cc +121 -121
- package/src/koffi/src/ffi.hh +23 -38
- package/src/koffi/src/init.js +2 -20
- package/src/koffi/src/parser.cc +15 -29
- package/src/koffi/src/parser.hh +4 -22
- package/src/koffi/src/trampolines/armasm.inc +0 -21
- package/src/koffi/src/trampolines/gnu.inc +0 -21
- package/src/koffi/src/trampolines/masm32.inc +0 -21
- package/src/koffi/src/trampolines/masm64.inc +0 -21
- package/src/koffi/src/trampolines/prototypes.inc +1 -22
- package/src/koffi/src/util.cc +87 -102
- package/src/koffi/src/util.hh +11 -29
- package/src/koffi/src/uv.cc +193 -0
- package/src/koffi/src/uv.def +10 -0
- package/src/koffi/src/uv.hh +40 -0
- package/src/koffi/src/win32.cc +7 -25
- package/src/koffi/src/win32.hh +4 -22
- package/vendor/node-api-headers/include/uv/aix.h +32 -0
- package/vendor/node-api-headers/include/uv/bsd.h +34 -0
- package/vendor/node-api-headers/include/uv/darwin.h +61 -0
- package/vendor/node-api-headers/include/uv/errno.h +483 -0
- package/vendor/node-api-headers/include/uv/linux.h +34 -0
- package/vendor/node-api-headers/include/uv/os390.h +33 -0
- package/vendor/node-api-headers/include/uv/posix.h +31 -0
- package/vendor/node-api-headers/include/uv/sunos.h +44 -0
- package/vendor/node-api-headers/include/uv/threadpool.h +37 -0
- package/vendor/node-api-headers/include/uv/tree.h +521 -0
- package/vendor/node-api-headers/include/uv/unix.h +512 -0
- package/vendor/node-api-headers/include/uv/version.h +43 -0
- package/vendor/node-api-headers/include/uv/win.h +698 -0
- package/vendor/node-api-headers/include/uv.h +1990 -0
- package/src/core/base/crc_gen.py +0 -109
package/src/koffi/src/call.cc
CHANGED
|
@@ -1,32 +1,14 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
// the Software without restriction, including without limitation the rights to use,
|
|
6
|
-
// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
|
7
|
-
// Software, and to permit persons to whom the Software is furnished to do so,
|
|
8
|
-
// subject to the following conditions:
|
|
9
|
-
//
|
|
10
|
-
// The above copyright notice and this permission notice shall be included in all
|
|
11
|
-
// copies or substantial portions of the Software.
|
|
12
|
-
//
|
|
13
|
-
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
|
|
14
|
-
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
15
|
-
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
16
|
-
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
17
|
-
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
18
|
-
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
19
|
-
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
20
|
-
// OTHER DEALINGS IN THE SOFTWARE.
|
|
21
|
-
|
|
22
|
-
#include "src/core/base/base.hh"
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
// SPDX-FileCopyrightText: 2025 Niels Martignène <niels.martignene@protonmail.com>
|
|
3
|
+
|
|
4
|
+
#include "lib/native/base/base.hh"
|
|
23
5
|
#include "call.hh"
|
|
24
6
|
#include "ffi.hh"
|
|
25
7
|
#include "util.hh"
|
|
26
8
|
|
|
27
9
|
#include <napi.h>
|
|
28
10
|
|
|
29
|
-
namespace
|
|
11
|
+
namespace K {
|
|
30
12
|
|
|
31
13
|
struct RelayContext {
|
|
32
14
|
CallData *call;
|
|
@@ -49,8 +31,8 @@ CallData::CallData(Napi::Env env, InstanceData *instance, InstanceMemory *mem)
|
|
|
49
31
|
mem->generation += !mem->depth;
|
|
50
32
|
mem->depth++;
|
|
51
33
|
|
|
52
|
-
|
|
53
|
-
|
|
34
|
+
K_ASSERT(AlignUp(mem->stack.ptr, 16) == mem->stack.ptr);
|
|
35
|
+
K_ASSERT(AlignUp(mem->stack.end(), 16) == mem->stack.end());
|
|
54
36
|
}
|
|
55
37
|
|
|
56
38
|
CallData::~CallData()
|
|
@@ -77,8 +59,8 @@ void CallData::Dispose()
|
|
|
77
59
|
int16_t idx = used_trampolines[i];
|
|
78
60
|
TrampolineInfo *trampoline = &shared.trampolines[idx];
|
|
79
61
|
|
|
80
|
-
|
|
81
|
-
|
|
62
|
+
K_ASSERT(trampoline->instance == instance);
|
|
63
|
+
K_ASSERT(!trampoline->func.IsEmpty());
|
|
82
64
|
|
|
83
65
|
trampoline->instance = nullptr;
|
|
84
66
|
trampoline->func.Reset();
|
|
@@ -88,15 +70,7 @@ void CallData::Dispose()
|
|
|
88
70
|
}
|
|
89
71
|
}
|
|
90
72
|
|
|
91
|
-
instance
|
|
92
|
-
|
|
93
|
-
if (!--mem->depth) {
|
|
94
|
-
mem->busy = false;
|
|
95
|
-
|
|
96
|
-
if (mem->temporary) {
|
|
97
|
-
delete mem;
|
|
98
|
-
}
|
|
99
|
-
}
|
|
73
|
+
ReleaseMemory(instance, mem);
|
|
100
74
|
|
|
101
75
|
instance = nullptr;
|
|
102
76
|
}
|
|
@@ -147,6 +121,7 @@ void CallData::RelayAsync(napi_env, napi_value, void *, void *udata)
|
|
|
147
121
|
|
|
148
122
|
bool CallData::PushString(Napi::Value value, int directions, const char **out_str)
|
|
149
123
|
{
|
|
124
|
+
// Fast path
|
|
150
125
|
if (value.IsString()) {
|
|
151
126
|
if (directions & 2) [[unlikely]] {
|
|
152
127
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected [string]", GetValueType(instance, value));
|
|
@@ -155,62 +130,41 @@ bool CallData::PushString(Napi::Value value, int directions, const char **out_st
|
|
|
155
130
|
|
|
156
131
|
PushStringValue(value, out_str);
|
|
157
132
|
return true;
|
|
158
|
-
}
|
|
159
|
-
*out_str = nullptr;
|
|
160
|
-
return true;
|
|
161
|
-
} else if (value.IsArray()) {
|
|
162
|
-
Napi::Array array = value.As<Napi::Array>();
|
|
133
|
+
}
|
|
163
134
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
135
|
+
return PushPointer(value, instance->str_type, directions, (void **)out_str);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
bool CallData::PushString16(Napi::Value value, int directions, const char16_t **out_str16)
|
|
139
|
+
{
|
|
140
|
+
// Fast path
|
|
141
|
+
if (value.IsString()) {
|
|
142
|
+
if (directions & 2) [[unlikely]] {
|
|
169
143
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected [string]", GetValueType(instance, value));
|
|
170
144
|
return false;
|
|
171
145
|
}
|
|
172
146
|
|
|
173
|
-
value
|
|
147
|
+
PushString16Value(value, out_str16);
|
|
148
|
+
return true;
|
|
149
|
+
}
|
|
174
150
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
return false;
|
|
178
|
-
}
|
|
151
|
+
return PushPointer(value, instance->str16_type, directions, (void **)out_str16);
|
|
152
|
+
}
|
|
179
153
|
|
|
180
|
-
|
|
181
|
-
|
|
154
|
+
bool CallData::PushString32(Napi::Value value, int directions, const char32_t **out_str32)
|
|
155
|
+
{
|
|
156
|
+
// Fast path
|
|
157
|
+
if (value.IsString()) {
|
|
158
|
+
if (directions & 2) [[unlikely]] {
|
|
159
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected [string]", GetValueType(instance, value));
|
|
182
160
|
return false;
|
|
183
|
-
|
|
184
|
-
// Create array type
|
|
185
|
-
TypeInfo *type;
|
|
186
|
-
{
|
|
187
|
-
type = AllocateOne<TypeInfo>(&call_alloc, (int)AllocFlag::Zero);
|
|
188
|
-
|
|
189
|
-
type->name = "<temporary>";
|
|
190
|
-
|
|
191
|
-
type->primitive = PrimitiveKind::Array;
|
|
192
|
-
type->align = 1;
|
|
193
|
-
type->size = (int32_t)len;
|
|
194
|
-
type->ref.type = instance->char_type;
|
|
195
|
-
type->hint = ArrayHint::String;
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
// Prepare output argument
|
|
199
|
-
{
|
|
200
|
-
OutArgument *out = out_arguments.AppendDefault();
|
|
201
|
-
|
|
202
|
-
napi_status status = napi_create_reference(env, array, 1, &out->ref);
|
|
203
|
-
RG_ASSERT(status == napi_ok);
|
|
204
|
-
|
|
205
|
-
out->kind = OutArgument::Kind::Array;
|
|
206
|
-
out->ptr = (const uint8_t *)*out_str;
|
|
207
|
-
out->type = type;
|
|
208
161
|
}
|
|
209
162
|
|
|
163
|
+
PushString32Value(value, out_str32);
|
|
210
164
|
return true;
|
|
211
|
-
} else {
|
|
212
|
-
return PushPointer(value, instance->str_type, directions, (void **)out_str);
|
|
213
165
|
}
|
|
166
|
+
|
|
167
|
+
return PushPointer(value, instance->str32_type, directions, (void **)out_str32);
|
|
214
168
|
}
|
|
215
169
|
|
|
216
170
|
Size CallData::PushStringValue(Napi::Value value, const char **out_str)
|
|
@@ -223,7 +177,7 @@ Size CallData::PushStringValue(Napi::Value value, const char **out_str)
|
|
|
223
177
|
buf.len = std::max((Size)0, mem->heap.len - Kibibytes(32));
|
|
224
178
|
|
|
225
179
|
status = napi_get_value_string_utf8(env, value, buf.ptr, (size_t)buf.len, &len);
|
|
226
|
-
|
|
180
|
+
K_ASSERT(status == napi_ok);
|
|
227
181
|
|
|
228
182
|
len++;
|
|
229
183
|
|
|
@@ -232,13 +186,13 @@ Size CallData::PushStringValue(Napi::Value value, const char **out_str)
|
|
|
232
186
|
mem->heap.len -= (Size)len;
|
|
233
187
|
} else {
|
|
234
188
|
status = napi_get_value_string_utf8(env, value, nullptr, 0, &len);
|
|
235
|
-
|
|
189
|
+
K_ASSERT(status == napi_ok);
|
|
236
190
|
|
|
237
191
|
len++;
|
|
238
192
|
buf = AllocateSpan<char>(&call_alloc, (Size)len);
|
|
239
193
|
|
|
240
194
|
status = napi_get_value_string_utf8(env, value, buf.ptr, (size_t)buf.len, &len);
|
|
241
|
-
|
|
195
|
+
K_ASSERT(status == napi_ok);
|
|
242
196
|
|
|
243
197
|
len++;
|
|
244
198
|
}
|
|
@@ -247,74 +201,6 @@ Size CallData::PushStringValue(Napi::Value value, const char **out_str)
|
|
|
247
201
|
return (Size)len;
|
|
248
202
|
}
|
|
249
203
|
|
|
250
|
-
bool CallData::PushString16(Napi::Value value, int directions, const char16_t **out_str16)
|
|
251
|
-
{
|
|
252
|
-
if (value.IsString()) {
|
|
253
|
-
if (directions & 2) [[unlikely]] {
|
|
254
|
-
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected string", GetValueType(instance, value));
|
|
255
|
-
return false;
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
PushString16Value(value, out_str16);
|
|
259
|
-
return true;
|
|
260
|
-
} else if (IsNullOrUndefined(value)) {
|
|
261
|
-
*out_str16 = nullptr;
|
|
262
|
-
return true;
|
|
263
|
-
} else if (value.IsArray()) {
|
|
264
|
-
Napi::Array array = value.As<Napi::Array>();
|
|
265
|
-
|
|
266
|
-
if (!(directions & 2)) [[unlikely]] {
|
|
267
|
-
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected string", GetValueType(instance, value));
|
|
268
|
-
return false;
|
|
269
|
-
}
|
|
270
|
-
if (array.Length() != 1) [[unlikely]] {
|
|
271
|
-
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected [string]", GetValueType(instance, value));
|
|
272
|
-
return false;
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
value = array[0u];
|
|
276
|
-
|
|
277
|
-
if (!value.IsString()) [[unlikely]] {
|
|
278
|
-
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected [string]", GetValueType(instance, array[0u]));
|
|
279
|
-
return false;
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
Size len = PushString16Value(value, out_str16);
|
|
283
|
-
if (len < 0) [[unlikely]]
|
|
284
|
-
return false;
|
|
285
|
-
|
|
286
|
-
// Create array type
|
|
287
|
-
TypeInfo *type;
|
|
288
|
-
{
|
|
289
|
-
type = AllocateOne<TypeInfo>(&call_alloc, (int)AllocFlag::Zero);
|
|
290
|
-
|
|
291
|
-
type->name = "<temporary>";
|
|
292
|
-
|
|
293
|
-
type->primitive = PrimitiveKind::Array;
|
|
294
|
-
type->align = 2;
|
|
295
|
-
type->size = (int32_t)(len * 2);
|
|
296
|
-
type->ref.type = instance->char16_type;
|
|
297
|
-
type->hint = ArrayHint::String;
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
// Prepare output argument
|
|
301
|
-
{
|
|
302
|
-
OutArgument *out = out_arguments.AppendDefault();
|
|
303
|
-
|
|
304
|
-
napi_status status = napi_create_reference(env, array, 1, &out->ref);
|
|
305
|
-
RG_ASSERT(status == napi_ok);
|
|
306
|
-
|
|
307
|
-
out->kind = OutArgument::Kind::Array;
|
|
308
|
-
out->ptr = (const uint8_t *)*out_str16;
|
|
309
|
-
out->type = type;
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
return true;
|
|
313
|
-
} else {
|
|
314
|
-
return PushPointer(value, instance->str16_type, directions, (void **)out_str16);
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
|
|
318
204
|
Size CallData::PushString16Value(Napi::Value value, const char16_t **out_str16)
|
|
319
205
|
{
|
|
320
206
|
Span<char16_t> buf;
|
|
@@ -326,7 +212,7 @@ Size CallData::PushString16Value(Napi::Value value, const char16_t **out_str16)
|
|
|
326
212
|
buf.len = std::max((Size)0, mem->heap.len - Kibibytes(32)) / 2;
|
|
327
213
|
|
|
328
214
|
status = napi_get_value_string_utf16(env, value, buf.ptr, (size_t)buf.len, &len);
|
|
329
|
-
|
|
215
|
+
K_ASSERT(status == napi_ok);
|
|
330
216
|
|
|
331
217
|
len++;
|
|
332
218
|
|
|
@@ -335,13 +221,13 @@ Size CallData::PushString16Value(Napi::Value value, const char16_t **out_str16)
|
|
|
335
221
|
mem->heap.len -= (Size)len * 2;
|
|
336
222
|
} else {
|
|
337
223
|
status = napi_get_value_string_utf16(env, value, nullptr, 0, &len);
|
|
338
|
-
|
|
224
|
+
K_ASSERT(status == napi_ok);
|
|
339
225
|
|
|
340
226
|
len++;
|
|
341
227
|
buf = AllocateSpan<char16_t>(&call_alloc, (Size)len);
|
|
342
228
|
|
|
343
229
|
status = napi_get_value_string_utf16(env, value, buf.ptr, (size_t)buf.len, &len);
|
|
344
|
-
|
|
230
|
+
K_ASSERT(status == napi_ok);
|
|
345
231
|
|
|
346
232
|
len++;
|
|
347
233
|
}
|
|
@@ -350,76 +236,10 @@ Size CallData::PushString16Value(Napi::Value value, const char16_t **out_str16)
|
|
|
350
236
|
return (Size)len;
|
|
351
237
|
}
|
|
352
238
|
|
|
353
|
-
bool CallData::PushString32(Napi::Value value, int directions, const char32_t **out_str32)
|
|
354
|
-
{
|
|
355
|
-
if (value.IsString()) {
|
|
356
|
-
if (directions & 2) [[unlikely]] {
|
|
357
|
-
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected string", GetValueType(instance, value));
|
|
358
|
-
return false;
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
PushString32Value(value, out_str32);
|
|
362
|
-
return true;
|
|
363
|
-
} else if (IsNullOrUndefined(value)) {
|
|
364
|
-
*out_str32 = nullptr;
|
|
365
|
-
return true;
|
|
366
|
-
} else if (value.IsArray()) {
|
|
367
|
-
Napi::Array array = value.As<Napi::Array>();
|
|
368
|
-
|
|
369
|
-
if (!(directions & 2)) [[unlikely]] {
|
|
370
|
-
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected string", GetValueType(instance, value));
|
|
371
|
-
return false;
|
|
372
|
-
}
|
|
373
|
-
if (array.Length() != 1) [[unlikely]] {
|
|
374
|
-
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected [string]", GetValueType(instance, value));
|
|
375
|
-
return false;
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
value = array[0u];
|
|
379
|
-
|
|
380
|
-
if (!value.IsString()) [[unlikely]] {
|
|
381
|
-
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected [string]", GetValueType(instance, array[0u]));
|
|
382
|
-
return false;
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
Size len = PushString32Value(value, out_str32);
|
|
386
|
-
if (len < 0) [[unlikely]]
|
|
387
|
-
return false;
|
|
388
|
-
|
|
389
|
-
// Create array type
|
|
390
|
-
TypeInfo *type;
|
|
391
|
-
{
|
|
392
|
-
type = AllocateOne<TypeInfo>(&call_alloc, (int)AllocFlag::Zero);
|
|
393
|
-
|
|
394
|
-
type->name = "<temporary>";
|
|
395
|
-
|
|
396
|
-
type->primitive = PrimitiveKind::Array;
|
|
397
|
-
type->align = 4;
|
|
398
|
-
type->size = (int32_t)(len * 4);
|
|
399
|
-
type->ref.type = instance->char32_type;
|
|
400
|
-
type->hint = ArrayHint::String;
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
// Prepare output argument
|
|
404
|
-
{
|
|
405
|
-
OutArgument *out = out_arguments.AppendDefault();
|
|
406
|
-
|
|
407
|
-
napi_status status = napi_create_reference(env, array, 1, &out->ref);
|
|
408
|
-
RG_ASSERT(status == napi_ok);
|
|
409
|
-
|
|
410
|
-
out->kind = OutArgument::Kind::Array;
|
|
411
|
-
out->ptr = (const uint8_t *)*out_str32;
|
|
412
|
-
out->type = type;
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
return true;
|
|
416
|
-
} else {
|
|
417
|
-
return PushPointer(value, instance->str32_type, directions, (void **)out_str32);
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
|
|
421
239
|
Size CallData::PushString32Value(Napi::Value value, const char32_t **out_str32)
|
|
422
240
|
{
|
|
241
|
+
static const char32_t ReplacementChar = 0x0000FFFD;
|
|
242
|
+
|
|
423
243
|
Span<char32_t> buf;
|
|
424
244
|
|
|
425
245
|
Span<const char16_t> buf16;
|
|
@@ -443,15 +263,19 @@ Size CallData::PushString32Value(Napi::Value value, const char32_t **out_str32)
|
|
|
443
263
|
char32_t uc = buf16[i];
|
|
444
264
|
|
|
445
265
|
if (uc >= 0xD800 && uc <= 0xDBFF) {
|
|
446
|
-
|
|
266
|
+
if (++i < buf16.len) {
|
|
267
|
+
char16_t uc2 = buf16.ptr[i];
|
|
447
268
|
|
|
448
|
-
|
|
449
|
-
|
|
269
|
+
if (uc2 >= 0xDC00 && uc2 <= 0xDFFF) [[likely]] {
|
|
270
|
+
uc = ((uc - 0xD800) << 10) + (uc2 - 0xDC00) + 0x10000u;
|
|
271
|
+
} else {
|
|
272
|
+
uc = ReplacementChar;
|
|
273
|
+
}
|
|
450
274
|
} else {
|
|
451
|
-
uc =
|
|
275
|
+
uc = ReplacementChar;
|
|
452
276
|
}
|
|
453
|
-
} else if (uc >= 0xDC00 && uc <= 0xDFFF) {
|
|
454
|
-
uc =
|
|
277
|
+
} else if (uc >= 0xDC00 && uc <= 0xDFFF) [[unlikely]] {
|
|
278
|
+
uc = ReplacementChar;
|
|
455
279
|
}
|
|
456
280
|
|
|
457
281
|
buf[j++] = uc;
|
|
@@ -463,8 +287,8 @@ Size CallData::PushString32Value(Napi::Value value, const char32_t **out_str32)
|
|
|
463
287
|
|
|
464
288
|
bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origin)
|
|
465
289
|
{
|
|
466
|
-
|
|
467
|
-
|
|
290
|
+
K_ASSERT(IsObject(obj));
|
|
291
|
+
K_ASSERT(type->primitive == PrimitiveKind::Record ||
|
|
468
292
|
type->primitive == PrimitiveKind::Union);
|
|
469
293
|
|
|
470
294
|
Span<const RecordMember> members = {};
|
|
@@ -472,7 +296,7 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
|
|
|
472
296
|
if (type->primitive == PrimitiveKind::Record) {
|
|
473
297
|
members = type->members;
|
|
474
298
|
} else if (type->primitive == PrimitiveKind::Union) {
|
|
475
|
-
if (CheckValueTag(
|
|
299
|
+
if (CheckValueTag(obj, &MagicUnionMarker)) {
|
|
476
300
|
MagicUnion *u = MagicUnion::Unwrap(obj);
|
|
477
301
|
const uint8_t *raw = u->GetRaw();
|
|
478
302
|
|
|
@@ -514,7 +338,7 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
|
|
|
514
338
|
}
|
|
515
339
|
}
|
|
516
340
|
} else {
|
|
517
|
-
|
|
341
|
+
K_UNREACHABLE();
|
|
518
342
|
}
|
|
519
343
|
|
|
520
344
|
MemSet(origin, 0, type->size);
|
|
@@ -536,7 +360,7 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
|
|
|
536
360
|
uint8_t *dest = origin + member.offset;
|
|
537
361
|
|
|
538
362
|
switch (member.type->primitive) {
|
|
539
|
-
case PrimitiveKind::Void: {
|
|
363
|
+
case PrimitiveKind::Void: { K_UNREACHABLE(); } break;
|
|
540
364
|
|
|
541
365
|
case PrimitiveKind::Bool: {
|
|
542
366
|
if (!value.IsBoolean()) [[unlikely]] {
|
|
@@ -754,7 +578,7 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
|
|
|
754
578
|
*(void **)dest = ptr;
|
|
755
579
|
} break;
|
|
756
580
|
|
|
757
|
-
case PrimitiveKind::Prototype: {
|
|
581
|
+
case PrimitiveKind::Prototype: { K_UNREACHABLE(); } break;
|
|
758
582
|
}
|
|
759
583
|
}
|
|
760
584
|
|
|
@@ -763,7 +587,7 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
|
|
|
763
587
|
|
|
764
588
|
bool CallData::PushNormalArray(Napi::Array array, const TypeInfo *type, Size size, uint8_t *origin)
|
|
765
589
|
{
|
|
766
|
-
|
|
590
|
+
K_ASSERT(array.IsArray());
|
|
767
591
|
|
|
768
592
|
const TypeInfo *ref = type->ref.type;
|
|
769
593
|
Size len = (Size)array.Length();
|
|
@@ -992,7 +816,7 @@ bool CallData::PushNormalArray(Napi::Array array, const TypeInfo *type, Size siz
|
|
|
992
816
|
}
|
|
993
817
|
} break;
|
|
994
818
|
|
|
995
|
-
case PrimitiveKind::Prototype: {
|
|
819
|
+
case PrimitiveKind::Prototype: { K_UNREACHABLE(); } break;
|
|
996
820
|
}
|
|
997
821
|
|
|
998
822
|
#undef PUSH_ARRAY
|
|
@@ -1011,7 +835,7 @@ void CallData::PushBuffer(Span<const uint8_t> buffer, const TypeInfo *type, uint
|
|
|
1011
835
|
#define SWAP(CType) \
|
|
1012
836
|
do { \
|
|
1013
837
|
CType *data = (CType *)origin; \
|
|
1014
|
-
Size len = buffer.len /
|
|
838
|
+
Size len = buffer.len / K_SIZE(CType); \
|
|
1015
839
|
\
|
|
1016
840
|
for (Size i = 0; i < len; i++) { \
|
|
1017
841
|
data[i] = ReverseBytes(data[i]); \
|
|
@@ -1035,19 +859,19 @@ void CallData::PushBuffer(Span<const uint8_t> buffer, const TypeInfo *type, uint
|
|
|
1035
859
|
|
|
1036
860
|
bool CallData::PushStringArray(Napi::Value obj, const TypeInfo *type, uint8_t *origin)
|
|
1037
861
|
{
|
|
1038
|
-
|
|
1039
|
-
|
|
862
|
+
K_ASSERT(obj.IsString());
|
|
863
|
+
K_ASSERT(type->primitive == PrimitiveKind::Array);
|
|
1040
864
|
|
|
1041
865
|
size_t encoded = 0;
|
|
1042
866
|
|
|
1043
867
|
switch (type->ref.type->primitive) {
|
|
1044
868
|
case PrimitiveKind::Int8: {
|
|
1045
869
|
napi_status status = napi_get_value_string_utf8(env, obj, (char *)origin, type->size, &encoded);
|
|
1046
|
-
|
|
870
|
+
K_ASSERT(status == napi_ok);
|
|
1047
871
|
} break;
|
|
1048
872
|
case PrimitiveKind::Int16: {
|
|
1049
873
|
napi_status status = napi_get_value_string_utf16(env, obj, (char16_t *)origin, type->size / 2, &encoded);
|
|
1050
|
-
|
|
874
|
+
K_ASSERT(status == napi_ok);
|
|
1051
875
|
|
|
1052
876
|
encoded *= 2;
|
|
1053
877
|
} break;
|
|
@@ -1065,7 +889,7 @@ bool CallData::PushStringArray(Napi::Value obj, const TypeInfo *type, uint8_t *o
|
|
|
1065
889
|
|
|
1066
890
|
bool CallData::PushPointer(Napi::Value value, const TypeInfo *type, int directions, void **out_ptr)
|
|
1067
891
|
{
|
|
1068
|
-
if (CheckValueTag(
|
|
892
|
+
if (CheckValueTag(value, &CastMarker)) {
|
|
1069
893
|
Napi::External<ValueCast> external = value.As<Napi::External<ValueCast>>();
|
|
1070
894
|
ValueCast *cast = external.Data();
|
|
1071
895
|
|
|
@@ -1073,6 +897,8 @@ bool CallData::PushPointer(Napi::Value value, const TypeInfo *type, int directio
|
|
|
1073
897
|
type = cast->type;
|
|
1074
898
|
}
|
|
1075
899
|
|
|
900
|
+
const TypeInfo *ref = type->ref.type;
|
|
901
|
+
|
|
1076
902
|
switch (value.Type()) {
|
|
1077
903
|
case napi_undefined:
|
|
1078
904
|
case napi_null: {
|
|
@@ -1081,14 +907,14 @@ bool CallData::PushPointer(Napi::Value value, const TypeInfo *type, int directio
|
|
|
1081
907
|
} break;
|
|
1082
908
|
|
|
1083
909
|
case napi_external: {
|
|
1084
|
-
|
|
910
|
+
K_ASSERT(type->primitive == PrimitiveKind::Pointer ||
|
|
1085
911
|
type->primitive == PrimitiveKind::String ||
|
|
1086
912
|
type->primitive == PrimitiveKind::String16 ||
|
|
1087
913
|
type->primitive == PrimitiveKind::String32);
|
|
1088
914
|
|
|
1089
|
-
if (!CheckValueTag(
|
|
1090
|
-
!CheckValueTag(
|
|
1091
|
-
|
|
915
|
+
if (!CheckValueTag(value, type->ref.marker) &&
|
|
916
|
+
!CheckValueTag(value, instance->void_type) &&
|
|
917
|
+
ref != instance->void_type) [[unlikely]]
|
|
1092
918
|
goto unexpected;
|
|
1093
919
|
|
|
1094
920
|
*out_ptr = value.As<Napi::External<uint8_t>>().Data();
|
|
@@ -1103,29 +929,29 @@ bool CallData::PushPointer(Napi::Value value, const TypeInfo *type, int directio
|
|
|
1103
929
|
|
|
1104
930
|
if (value.IsArray()) {
|
|
1105
931
|
Napi::Array array = value.As<Napi::Array>();
|
|
1106
|
-
Size len = PushIndirectString(array,
|
|
932
|
+
Size len = PushIndirectString(array, ref, &ptr);
|
|
1107
933
|
|
|
1108
934
|
if (len >= 0) {
|
|
1109
|
-
if (!
|
|
935
|
+
if (!ref->size && ref != instance->void_type) [[unlikely]] {
|
|
1110
936
|
ThrowError<Napi::TypeError>(env, "Cannot pass [string] value to %1", type->name);
|
|
1111
937
|
return false;
|
|
1112
938
|
}
|
|
1113
939
|
|
|
1114
|
-
switch (
|
|
940
|
+
switch (ref->size) {
|
|
1115
941
|
default: { out_kind = OutArgument::Kind::String; } break;
|
|
1116
942
|
case 2: { out_kind = OutArgument::Kind::String16; } break;
|
|
1117
943
|
case 4: { out_kind = OutArgument::Kind::String32; } break;
|
|
1118
944
|
}
|
|
1119
945
|
out_max_len = len;
|
|
1120
946
|
} else {
|
|
1121
|
-
if (!
|
|
947
|
+
if (!ref->size) [[unlikely]] {
|
|
1122
948
|
ThrowError<Napi::TypeError>(env, "Cannot pass %1 value to %2, use koffi.as()",
|
|
1123
|
-
|
|
949
|
+
ref != instance->void_type ? "opaque" : "ambiguous", type->name);
|
|
1124
950
|
return false;
|
|
1125
951
|
}
|
|
1126
952
|
|
|
1127
953
|
Size len = (Size)array.Length();
|
|
1128
|
-
Size size = len *
|
|
954
|
+
Size size = len * ref->size;
|
|
1129
955
|
|
|
1130
956
|
ptr = AllocHeap(size, 16);
|
|
1131
957
|
|
|
@@ -1146,24 +972,24 @@ bool CallData::PushPointer(Napi::Value value, const TypeInfo *type, int directio
|
|
|
1146
972
|
directions = 1;
|
|
1147
973
|
|
|
1148
974
|
out_kind = OutArgument::Kind::Buffer;
|
|
1149
|
-
} else if (
|
|
1150
|
-
|
|
975
|
+
} else if (ref->primitive == PrimitiveKind::Record ||
|
|
976
|
+
ref->primitive == PrimitiveKind::Union) [[likely]] {
|
|
1151
977
|
Napi::Object obj = value.As<Napi::Object>();
|
|
1152
|
-
|
|
978
|
+
K_ASSERT(IsObject(value));
|
|
1153
979
|
|
|
1154
|
-
ptr = AllocHeap(
|
|
980
|
+
ptr = AllocHeap(ref->size, 16);
|
|
1155
981
|
|
|
1156
|
-
if (
|
|
1157
|
-
(directions & 2) && !CheckValueTag(
|
|
982
|
+
if (ref->primitive == PrimitiveKind::Union &&
|
|
983
|
+
(directions & 2) && !CheckValueTag(obj, &MagicUnionMarker)) [[unlikely]] {
|
|
1158
984
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected union value", GetValueType(instance, obj));
|
|
1159
985
|
return false;
|
|
1160
986
|
}
|
|
1161
987
|
|
|
1162
988
|
if (directions & 1) {
|
|
1163
|
-
if (!PushObject(obj,
|
|
989
|
+
if (!PushObject(obj, ref, ptr))
|
|
1164
990
|
return false;
|
|
1165
991
|
} else {
|
|
1166
|
-
MemSet(ptr, 0,
|
|
992
|
+
MemSet(ptr, 0, ref->size);
|
|
1167
993
|
}
|
|
1168
994
|
|
|
1169
995
|
out_kind = OutArgument::Kind::Object;
|
|
@@ -1175,11 +1001,11 @@ bool CallData::PushPointer(Napi::Value value, const TypeInfo *type, int directio
|
|
|
1175
1001
|
OutArgument *out = out_arguments.AppendDefault();
|
|
1176
1002
|
|
|
1177
1003
|
napi_status status = napi_create_reference(env, value, 1, &out->ref);
|
|
1178
|
-
|
|
1004
|
+
K_ASSERT(status == napi_ok);
|
|
1179
1005
|
|
|
1180
1006
|
out->kind = out_kind;
|
|
1181
1007
|
out->ptr = ptr;
|
|
1182
|
-
out->type =
|
|
1008
|
+
out->type = ref;
|
|
1183
1009
|
out->max_len = out_max_len;
|
|
1184
1010
|
}
|
|
1185
1011
|
|
|
@@ -1188,21 +1014,21 @@ bool CallData::PushPointer(Napi::Value value, const TypeInfo *type, int directio
|
|
|
1188
1014
|
} break;
|
|
1189
1015
|
|
|
1190
1016
|
case napi_string: {
|
|
1191
|
-
|
|
1017
|
+
K_ASSERT(type->primitive == PrimitiveKind::Pointer);
|
|
1192
1018
|
|
|
1193
1019
|
if (directions & 2) [[unlikely]]
|
|
1194
1020
|
goto unexpected;
|
|
1195
1021
|
|
|
1196
|
-
if (
|
|
1022
|
+
if (ref == instance->void_type) {
|
|
1197
1023
|
PushStringValue(value, (const char **)out_ptr);
|
|
1198
1024
|
return true;
|
|
1199
|
-
} else if (
|
|
1025
|
+
} else if (ref->primitive == PrimitiveKind::Int8) {
|
|
1200
1026
|
PushStringValue(value, (const char **)out_ptr);
|
|
1201
1027
|
return true;
|
|
1202
|
-
} else if (
|
|
1028
|
+
} else if (ref->primitive == PrimitiveKind::Int16) {
|
|
1203
1029
|
PushString16Value(value, (const char16_t **)out_ptr);
|
|
1204
1030
|
return true;
|
|
1205
|
-
} else if (
|
|
1031
|
+
} else if (ref->primitive == PrimitiveKind::Int32) {
|
|
1206
1032
|
PushString32Value(value, (const char32_t **)out_ptr);
|
|
1207
1033
|
return true;
|
|
1208
1034
|
} else {
|
|
@@ -1262,9 +1088,9 @@ bool CallData::PushCallback(Napi::Value value, const TypeInfo *type, void **out_
|
|
|
1262
1088
|
return false;
|
|
1263
1089
|
|
|
1264
1090
|
*out_ptr = ptr;
|
|
1265
|
-
} else if (CheckValueTag(
|
|
1091
|
+
} else if (CheckValueTag(value, type->ref.marker)) {
|
|
1266
1092
|
*out_ptr = value.As<Napi::External<void>>().Data();
|
|
1267
|
-
} else if (CheckValueTag(
|
|
1093
|
+
} else if (CheckValueTag(value, &CastMarker)) {
|
|
1268
1094
|
Napi::External<ValueCast> external = value.As<Napi::External<ValueCast>>();
|
|
1269
1095
|
ValueCast *cast = external.Data();
|
|
1270
1096
|
|
|
@@ -1324,7 +1150,7 @@ void *CallData::ReserveTrampoline(const FunctionInfo *proto, Napi::Function func
|
|
|
1324
1150
|
return env.Null();
|
|
1325
1151
|
}
|
|
1326
1152
|
if (!used_trampolines.Available()) [[unlikely]] {
|
|
1327
|
-
ThrowError<Napi::Error>(env, "This call uses too many temporary callbacks (max = %1)",
|
|
1153
|
+
ThrowError<Napi::Error>(env, "This call uses too many temporary callbacks (max = %1)", K_LEN(used_trampolines.data));
|
|
1328
1154
|
return env.Null();
|
|
1329
1155
|
}
|
|
1330
1156
|
|
|
@@ -1413,7 +1239,7 @@ static inline Napi::Value GetReferenceValue(Napi::Env env, napi_ref ref)
|
|
|
1413
1239
|
napi_value value;
|
|
1414
1240
|
|
|
1415
1241
|
napi_status status = napi_get_reference_value(env, ref, &value);
|
|
1416
|
-
|
|
1242
|
+
K_ASSERT(status == napi_ok);
|
|
1417
1243
|
|
|
1418
1244
|
return Napi::Value(env, value);
|
|
1419
1245
|
}
|
|
@@ -1422,18 +1248,18 @@ void CallData::PopOutArguments()
|
|
|
1422
1248
|
{
|
|
1423
1249
|
for (const OutArgument &out: out_arguments) {
|
|
1424
1250
|
Napi::Value value = GetReferenceValue(env, out.ref);
|
|
1425
|
-
|
|
1251
|
+
K_ASSERT(!value.IsEmpty());
|
|
1426
1252
|
|
|
1427
1253
|
switch (out.kind) {
|
|
1428
1254
|
case OutArgument::Kind::Array: {
|
|
1429
|
-
|
|
1255
|
+
K_ASSERT(value.IsArray());
|
|
1430
1256
|
|
|
1431
1257
|
Napi::Array array(env, value);
|
|
1432
1258
|
DecodeNormalArray(array, out.ptr, out.type);
|
|
1433
1259
|
} break;
|
|
1434
1260
|
|
|
1435
1261
|
case OutArgument::Kind::Buffer: {
|
|
1436
|
-
|
|
1262
|
+
K_ASSERT(IsRawBuffer(value));
|
|
1437
1263
|
|
|
1438
1264
|
Span<uint8_t> buffer = GetRawBuffer(value);
|
|
1439
1265
|
DecodeBuffer(buffer, out.ptr, out.type);
|
|
@@ -1442,8 +1268,8 @@ void CallData::PopOutArguments()
|
|
|
1442
1268
|
case OutArgument::Kind::String: {
|
|
1443
1269
|
Napi::Array array(env, value);
|
|
1444
1270
|
|
|
1445
|
-
|
|
1446
|
-
|
|
1271
|
+
K_ASSERT(array.IsArray());
|
|
1272
|
+
K_ASSERT(array.Length() == 1);
|
|
1447
1273
|
|
|
1448
1274
|
Size len = strnlen((const char *)out.ptr, out.max_len);
|
|
1449
1275
|
Napi::String str = Napi::String::New(env, (const char *)out.ptr, len);
|
|
@@ -1454,8 +1280,8 @@ void CallData::PopOutArguments()
|
|
|
1454
1280
|
case OutArgument::Kind::String16: {
|
|
1455
1281
|
Napi::Array array(env, value);
|
|
1456
1282
|
|
|
1457
|
-
|
|
1458
|
-
|
|
1283
|
+
K_ASSERT(array.IsArray());
|
|
1284
|
+
K_ASSERT(array.Length() == 1);
|
|
1459
1285
|
|
|
1460
1286
|
Size len = NullTerminatedLength((const char16_t *)out.ptr, out.max_len);
|
|
1461
1287
|
Napi::String str = Napi::String::New(env, (const char16_t *)out.ptr, len);
|
|
@@ -1466,8 +1292,8 @@ void CallData::PopOutArguments()
|
|
|
1466
1292
|
case OutArgument::Kind::String32: {
|
|
1467
1293
|
Napi::Array array(env, value);
|
|
1468
1294
|
|
|
1469
|
-
|
|
1470
|
-
|
|
1295
|
+
K_ASSERT(array.IsArray());
|
|
1296
|
+
K_ASSERT(array.Length() == 1);
|
|
1471
1297
|
|
|
1472
1298
|
Size len = NullTerminatedLength((const char32_t *)out.ptr, out.max_len);
|
|
1473
1299
|
Napi::String str = MakeStringFromUTF32(env, (const char32_t *)out.ptr, len);
|
|
@@ -1478,7 +1304,7 @@ void CallData::PopOutArguments()
|
|
|
1478
1304
|
case OutArgument::Kind::Object: {
|
|
1479
1305
|
Napi::Object obj = value.As<Napi::Object>();
|
|
1480
1306
|
|
|
1481
|
-
if (CheckValueTag(
|
|
1307
|
+
if (CheckValueTag(value, &MagicUnionMarker)) {
|
|
1482
1308
|
MagicUnion *u = MagicUnion::Unwrap(obj);
|
|
1483
1309
|
u->SetRaw(out.ptr);
|
|
1484
1310
|
} else {
|