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.
Files changed (105) hide show
  1. package/CHANGELOG.md +26 -1
  2. package/README.md +1 -1
  3. package/build/koffi/darwin_arm64/koffi.node +0 -0
  4. package/build/koffi/darwin_x64/koffi.node +0 -0
  5. package/build/koffi/freebsd_arm64/koffi.node +0 -0
  6. package/build/koffi/freebsd_ia32/koffi.node +0 -0
  7. package/build/koffi/freebsd_x64/koffi.node +0 -0
  8. package/build/koffi/linux_arm64/koffi.node +0 -0
  9. package/build/koffi/linux_armhf/koffi.node +0 -0
  10. package/build/koffi/linux_ia32/koffi.node +0 -0
  11. package/build/koffi/linux_loong64/koffi.node +0 -0
  12. package/build/koffi/linux_riscv64d/koffi.node +0 -0
  13. package/build/koffi/linux_x64/koffi.node +0 -0
  14. package/build/koffi/musl_arm64/koffi.node +0 -0
  15. package/build/koffi/musl_x64/koffi.node +0 -0
  16. package/build/koffi/openbsd_ia32/koffi.node +0 -0
  17. package/build/koffi/openbsd_x64/koffi.node +0 -0
  18. package/build/koffi/win32_arm64/koffi.node +0 -0
  19. package/build/koffi/win32_ia32/koffi.node +0 -0
  20. package/build/koffi/win32_x64/koffi.node +0 -0
  21. package/doc/assets.ini +2 -1
  22. package/doc/build.sh +9 -0
  23. package/doc/pages/404.md +17 -0
  24. package/doc/pages/index.md +43 -4
  25. package/doc/pages/misc.md +16 -11
  26. package/doc/pages/platforms.md +8 -19
  27. package/doc/pages.ini +4 -7
  28. package/doc/static/highlight.js +2 -14
  29. package/doc/static/koffi.css +3 -15
  30. package/doc/static/perf_windows.png +0 -0
  31. package/doc/static/print.css +2 -14
  32. package/index.d.ts +29 -24
  33. package/index.js +10 -9
  34. package/indirect.js +10 -9
  35. package/{src/core → lib/native}/base/base.cc +1753 -1089
  36. package/{src/core → lib/native}/base/base.hh +868 -572
  37. package/{src/core → lib/native}/base/crc.inc +3 -21
  38. package/lib/native/base/crc_gen.py +72 -0
  39. package/{src/core → lib/native}/base/mimetypes.inc +2 -20
  40. package/{src/core → lib/native}/base/mimetypes_gen.py +2 -21
  41. package/lib/native/base/tower.cc +821 -0
  42. package/lib/native/base/tower.hh +81 -0
  43. package/{src/core → lib/native}/base/unicode.inc +3 -21
  44. package/{src/core → lib/native}/base/unicode_gen.py +5 -42
  45. package/package.json +3 -2
  46. package/src/cnoke/assets/FindCNoke.cmake +8 -20
  47. package/src/cnoke/assets/win_delay_hook.c +2 -20
  48. package/src/cnoke/cnoke.js +2 -21
  49. package/src/cnoke/src/builder.js +3 -22
  50. package/src/cnoke/src/index.js +2 -20
  51. package/src/cnoke/src/tools.js +2 -20
  52. package/src/koffi/CMakeLists.txt +19 -22
  53. package/src/koffi/cmake/raylib.cmake +5 -22
  54. package/src/koffi/cmake/sqlite3.cmake +2 -20
  55. package/src/koffi/src/abi_arm32.cc +31 -49
  56. package/src/koffi/src/abi_arm32_asm.S +2 -20
  57. package/src/koffi/src/abi_arm64.cc +36 -54
  58. package/src/koffi/src/abi_arm64_asm.S +2 -20
  59. package/src/koffi/src/abi_arm64_asm.asm +2 -20
  60. package/src/koffi/src/abi_loong64.cc +2 -20
  61. package/src/koffi/src/abi_loong64_asm.S +2 -20
  62. package/src/koffi/src/abi_riscv64.cc +34 -52
  63. package/src/koffi/src/abi_riscv64_asm.S +2 -20
  64. package/src/koffi/src/abi_x64_sysv.cc +36 -54
  65. package/src/koffi/src/abi_x64_sysv_asm.S +2 -20
  66. package/src/koffi/src/abi_x64_win.cc +32 -50
  67. package/src/koffi/src/abi_x64_win_asm.asm +2 -20
  68. package/src/koffi/src/abi_x86.cc +33 -51
  69. package/src/koffi/src/abi_x86_asm.S +2 -20
  70. package/src/koffi/src/abi_x86_asm.asm +2 -20
  71. package/src/koffi/src/call.cc +107 -281
  72. package/src/koffi/src/call.hh +9 -27
  73. package/src/koffi/src/errno.inc +2 -20
  74. package/src/koffi/src/ffi.cc +121 -121
  75. package/src/koffi/src/ffi.hh +23 -38
  76. package/src/koffi/src/init.js +2 -20
  77. package/src/koffi/src/parser.cc +15 -29
  78. package/src/koffi/src/parser.hh +4 -22
  79. package/src/koffi/src/trampolines/armasm.inc +0 -21
  80. package/src/koffi/src/trampolines/gnu.inc +0 -21
  81. package/src/koffi/src/trampolines/masm32.inc +0 -21
  82. package/src/koffi/src/trampolines/masm64.inc +0 -21
  83. package/src/koffi/src/trampolines/prototypes.inc +1 -22
  84. package/src/koffi/src/util.cc +87 -102
  85. package/src/koffi/src/util.hh +11 -29
  86. package/src/koffi/src/uv.cc +193 -0
  87. package/src/koffi/src/uv.def +10 -0
  88. package/src/koffi/src/uv.hh +40 -0
  89. package/src/koffi/src/win32.cc +7 -25
  90. package/src/koffi/src/win32.hh +4 -22
  91. package/vendor/node-api-headers/include/uv/aix.h +32 -0
  92. package/vendor/node-api-headers/include/uv/bsd.h +34 -0
  93. package/vendor/node-api-headers/include/uv/darwin.h +61 -0
  94. package/vendor/node-api-headers/include/uv/errno.h +483 -0
  95. package/vendor/node-api-headers/include/uv/linux.h +34 -0
  96. package/vendor/node-api-headers/include/uv/os390.h +33 -0
  97. package/vendor/node-api-headers/include/uv/posix.h +31 -0
  98. package/vendor/node-api-headers/include/uv/sunos.h +44 -0
  99. package/vendor/node-api-headers/include/uv/threadpool.h +37 -0
  100. package/vendor/node-api-headers/include/uv/tree.h +521 -0
  101. package/vendor/node-api-headers/include/uv/unix.h +512 -0
  102. package/vendor/node-api-headers/include/uv/version.h +43 -0
  103. package/vendor/node-api-headers/include/uv/win.h +698 -0
  104. package/vendor/node-api-headers/include/uv.h +1990 -0
  105. package/src/core/base/crc_gen.py +0 -109
@@ -1,32 +1,14 @@
1
- // Copyright (C) 2025 Niels Martignène <niels.martignene@protonmail.com>
2
- //
3
- // Permission is hereby granted, free of charge, to any person obtaining a copy of
4
- // this software and associated documentation files (the “Software”), to deal in
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 RG {
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
- RG_ASSERT(AlignUp(mem->stack.ptr, 16) == mem->stack.ptr);
53
- RG_ASSERT(AlignUp(mem->stack.end(), 16) == mem->stack.end());
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
- RG_ASSERT(trampoline->instance == instance);
81
- RG_ASSERT(!trampoline->func.IsEmpty());
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->temporaries -= mem->temporary;
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
- } else if (IsNullOrUndefined(value)) {
159
- *out_str = nullptr;
160
- return true;
161
- } else if (value.IsArray()) {
162
- Napi::Array array = value.As<Napi::Array>();
133
+ }
163
134
 
164
- if (!(directions & 2)) [[unlikely]] {
165
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected string", GetValueType(instance, value));
166
- return false;
167
- }
168
- if (array.Length() != 1) [[unlikely]] {
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 = array[0u];
147
+ PushString16Value(value, out_str16);
148
+ return true;
149
+ }
174
150
 
175
- if (!value.IsString()) [[unlikely]] {
176
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected [string]", GetValueType(instance, array[0u]));
177
- return false;
178
- }
151
+ return PushPointer(value, instance->str16_type, directions, (void **)out_str16);
152
+ }
179
153
 
180
- Size len = PushStringValue(value, out_str);
181
- if (len < 0) [[unlikely]]
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
- RG_ASSERT(status == napi_ok);
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
- RG_ASSERT(status == napi_ok);
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
- RG_ASSERT(status == napi_ok);
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
- RG_ASSERT(status == napi_ok);
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
- RG_ASSERT(status == napi_ok);
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
- RG_ASSERT(status == napi_ok);
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
- char16_t uc2 = buf16.ptr[++i];
266
+ if (++i < buf16.len) {
267
+ char16_t uc2 = buf16.ptr[i];
447
268
 
448
- if (uc2 >= 0xDC00 && uc2 <= 0xDFFF) {
449
- uc = ((uc - 0xD800) << 10) + (uc2 - 0xDC00) + 0x10000u;
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
- RG_ASSERT(IsObject(obj));
467
- RG_ASSERT(type->primitive == PrimitiveKind::Record ||
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(instance, obj, &MagicUnionMarker)) {
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
- RG_UNREACHABLE();
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: { RG_UNREACHABLE(); } break;
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: { RG_UNREACHABLE(); } break;
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
- RG_ASSERT(array.IsArray());
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: { RG_UNREACHABLE(); } break;
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 / RG_SIZE(CType); \
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
- RG_ASSERT(obj.IsString());
1039
- RG_ASSERT(type->primitive == PrimitiveKind::Array);
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
- RG_ASSERT(status == napi_ok);
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
- RG_ASSERT(status == napi_ok);
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(instance, value, &CastMarker)) {
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
- RG_ASSERT(type->primitive == PrimitiveKind::Pointer ||
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(instance, value, type->ref.marker) &&
1090
- !CheckValueTag(instance, value, instance->void_type) &&
1091
- type->ref.type != instance->void_type) [[unlikely]]
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, type->ref.type, &ptr);
932
+ Size len = PushIndirectString(array, ref, &ptr);
1107
933
 
1108
934
  if (len >= 0) {
1109
- if (!type->ref.type->size && type->ref.type != instance->void_type) [[unlikely]] {
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 (type->ref.type->size) {
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 (!type->ref.type->size) [[unlikely]] {
947
+ if (!ref->size) [[unlikely]] {
1122
948
  ThrowError<Napi::TypeError>(env, "Cannot pass %1 value to %2, use koffi.as()",
1123
- type->ref.type != instance->void_type ? "opaque" : "ambiguous", type->name);
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 * type->ref.type->size;
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 (type->ref.type->primitive == PrimitiveKind::Record ||
1150
- type->ref.type->primitive == PrimitiveKind::Union) [[likely]] {
975
+ } else if (ref->primitive == PrimitiveKind::Record ||
976
+ ref->primitive == PrimitiveKind::Union) [[likely]] {
1151
977
  Napi::Object obj = value.As<Napi::Object>();
1152
- RG_ASSERT(IsObject(value));
978
+ K_ASSERT(IsObject(value));
1153
979
 
1154
- ptr = AllocHeap(type->ref.type->size, 16);
980
+ ptr = AllocHeap(ref->size, 16);
1155
981
 
1156
- if (type->ref.type->primitive == PrimitiveKind::Union &&
1157
- (directions & 2) && !CheckValueTag(instance, obj, &MagicUnionMarker)) [[unlikely]] {
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, type->ref.type, ptr))
989
+ if (!PushObject(obj, ref, ptr))
1164
990
  return false;
1165
991
  } else {
1166
- MemSet(ptr, 0, type->size);
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
- RG_ASSERT(status == napi_ok);
1004
+ K_ASSERT(status == napi_ok);
1179
1005
 
1180
1006
  out->kind = out_kind;
1181
1007
  out->ptr = ptr;
1182
- out->type = type->ref.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
- RG_ASSERT(type->primitive == PrimitiveKind::Pointer);
1017
+ K_ASSERT(type->primitive == PrimitiveKind::Pointer);
1192
1018
 
1193
1019
  if (directions & 2) [[unlikely]]
1194
1020
  goto unexpected;
1195
1021
 
1196
- if (type->ref.type == instance->void_type) {
1022
+ if (ref == instance->void_type) {
1197
1023
  PushStringValue(value, (const char **)out_ptr);
1198
1024
  return true;
1199
- } else if (type->ref.type->primitive == PrimitiveKind::Int8) {
1025
+ } else if (ref->primitive == PrimitiveKind::Int8) {
1200
1026
  PushStringValue(value, (const char **)out_ptr);
1201
1027
  return true;
1202
- } else if (type->ref.type->primitive == PrimitiveKind::Int16) {
1028
+ } else if (ref->primitive == PrimitiveKind::Int16) {
1203
1029
  PushString16Value(value, (const char16_t **)out_ptr);
1204
1030
  return true;
1205
- } else if (type->ref.type->primitive == PrimitiveKind::Int32) {
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(instance, value, type->ref.marker)) {
1091
+ } else if (CheckValueTag(value, type->ref.marker)) {
1266
1092
  *out_ptr = value.As<Napi::External<void>>().Data();
1267
- } else if (CheckValueTag(instance, value, &CastMarker)) {
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)", RG_LEN(used_trampolines.data));
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
- RG_ASSERT(status == napi_ok);
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
- RG_ASSERT(!value.IsEmpty());
1251
+ K_ASSERT(!value.IsEmpty());
1426
1252
 
1427
1253
  switch (out.kind) {
1428
1254
  case OutArgument::Kind::Array: {
1429
- RG_ASSERT(value.IsArray());
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
- RG_ASSERT(IsRawBuffer(value));
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
- RG_ASSERT(array.IsArray());
1446
- RG_ASSERT(array.Length() == 1);
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
- RG_ASSERT(array.IsArray());
1458
- RG_ASSERT(array.Length() == 1);
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
- RG_ASSERT(array.IsArray());
1470
- RG_ASSERT(array.Length() == 1);
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(instance, value, &MagicUnionMarker)) {
1307
+ if (CheckValueTag(value, &MagicUnionMarker)) {
1482
1308
  MagicUnion *u = MagicUnion::Unwrap(obj);
1483
1309
  u->SetRaw(out.ptr);
1484
1310
  } else {