koffi 2.8.11 → 2.9.0-beta.1

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 (48) hide show
  1. package/CHANGELOG.md +12 -1
  2. package/build/koffi/darwin_arm64/koffi.node +0 -0
  3. package/build/koffi/darwin_x64/koffi.node +0 -0
  4. package/build/koffi/freebsd_arm64/koffi.node +0 -0
  5. package/build/koffi/freebsd_i386/koffi.node +0 -0
  6. package/build/koffi/freebsd_x64/koffi.node +0 -0
  7. package/build/koffi/linux_arm32/koffi.node +0 -0
  8. package/build/koffi/linux_arm64/koffi.node +0 -0
  9. package/build/koffi/linux_i386/koffi.node +0 -0
  10. package/build/koffi/linux_riscv64/koffi.node +0 -0
  11. package/build/koffi/linux_x64/koffi.node +0 -0
  12. package/build/koffi/musl_x64/koffi.node +0 -0
  13. package/build/koffi/openbsd_i386/koffi.node +0 -0
  14. package/build/koffi/openbsd_x64/koffi.node +0 -0
  15. package/build/koffi/windows_arm64/koffi.node +0 -0
  16. package/build/koffi/{win32_ia32 → windows_i386}/koffi.node +0 -0
  17. package/build/koffi/{win32_x64 → windows_x64}/koffi.node +0 -0
  18. package/doc/contribute.md +3 -2
  19. package/doc/input.md +23 -13
  20. package/index.js +160 -97
  21. package/indirect.js +113 -81
  22. package/package.json +2 -2
  23. package/src/koffi/CMakeLists.txt +11 -1
  24. package/src/koffi/src/abi_arm32.cc +23 -0
  25. package/src/koffi/src/abi_arm64.cc +30 -0
  26. package/src/koffi/src/abi_riscv64.cc +22 -0
  27. package/src/koffi/src/abi_x64_sysv.cc +23 -0
  28. package/src/koffi/src/abi_x64_win.cc +23 -0
  29. package/src/koffi/src/abi_x86.cc +22 -0
  30. package/src/koffi/src/call.cc +155 -5
  31. package/src/koffi/src/call.hh +3 -0
  32. package/src/koffi/src/ffi.cc +26 -4
  33. package/src/koffi/src/ffi.hh +4 -0
  34. package/src/koffi/src/init.js +122 -0
  35. package/src/koffi/src/util.cc +85 -2
  36. package/src/koffi/src/util.hh +13 -0
  37. package/build/koffi/freebsd_ia32/koffi.node +0 -0
  38. package/build/koffi/linux_armhf/koffi.node +0 -0
  39. package/build/koffi/linux_ia32/koffi.node +0 -0
  40. package/build/koffi/linux_riscv64d/koffi.node +0 -0
  41. package/build/koffi/openbsd_ia32/koffi.node +0 -0
  42. package/build/koffi/win32_arm64/koffi.node +0 -0
  43. /package/build/koffi/{win32_arm64 → windows_arm64}/koffi.exp +0 -0
  44. /package/build/koffi/{win32_arm64 → windows_arm64}/koffi.lib +0 -0
  45. /package/build/koffi/{win32_ia32 → windows_i386}/koffi.exp +0 -0
  46. /package/build/koffi/{win32_ia32 → windows_i386}/koffi.lib +0 -0
  47. /package/build/koffi/{win32_x64 → windows_x64}/koffi.exp +0 -0
  48. /package/build/koffi/{win32_x64 → windows_x64}/koffi.lib +0 -0
package/indirect.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  var __getOwnPropNames = Object.getOwnPropertyNames;
3
- var __commonJS = (cb, mod) => function __require() {
4
- return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
3
+ var __commonJS = (cb, mod3) => function __require() {
4
+ return mod3 || (0, cb[__getOwnPropNames(cb)[0]])((mod3 = { exports: {} }).exports, mod3), mod3.exports;
5
5
  };
6
6
 
7
7
  // ../../bin/Koffi/package/src/cnoke/src/tools.js
@@ -11,7 +11,7 @@ var require_tools = __commonJS({
11
11
  var crypto = require("crypto");
12
12
  var fs2 = require("fs");
13
13
  var http = require("https");
14
- var path = require("path");
14
+ var path2 = require("path");
15
15
  var zlib = require("zlib");
16
16
  async function download_http(url, dest) {
17
17
  console.log(">> Downloading " + url);
@@ -107,7 +107,7 @@ var require_tools = __commonJS({
107
107
  data = data.subarray(0, header.size);
108
108
  if (header.type == "0" || header.type == "7") {
109
109
  let filename3 = dest_dir + "/" + header.filename;
110
- let dirname = path.dirname(filename3);
110
+ let dirname = path2.dirname(filename3);
111
111
  fs2.mkdirSync(dirname, { recursive: true, mode: 493 });
112
112
  fs2.writeFileSync(filename3, data, { mode: header.mode });
113
113
  } else if (header.type == "5") {
@@ -151,21 +151,21 @@ var require_tools = __commonJS({
151
151
  reader.on("end", resolve);
152
152
  });
153
153
  }
154
- function path_is_absolute(path2) {
155
- if (process.platform == "win32" && path2.match(/^[a-zA-Z]:/))
156
- path2 = path2.substr(2);
157
- return is_path_separator(path2[0]);
154
+ function path_is_absolute(path3) {
155
+ if (process.platform == "win32" && path3.match(/^[a-zA-Z]:/))
156
+ path3 = path3.substr(2);
157
+ return is_path_separator(path3[0]);
158
158
  }
159
- function path_has_dotdot(path2) {
159
+ function path_has_dotdot(path3) {
160
160
  let start = 0;
161
161
  for (; ; ) {
162
- let offset = path2.indexOf("..", start);
162
+ let offset = path3.indexOf("..", start);
163
163
  if (offset < 0)
164
164
  break;
165
165
  start = offset + 2;
166
- if (offset && !is_path_separator(path2[offset - 1]))
166
+ if (offset && !is_path_separator(path3[offset - 1]))
167
167
  continue;
168
- if (offset + 2 < path2.length && !is_path_separator(path2[offset + 2]))
168
+ if (offset + 2 < path3.length && !is_path_separator(path3[offset + 2]))
169
169
  continue;
170
170
  return true;
171
171
  }
@@ -179,8 +179,8 @@ var require_tools = __commonJS({
179
179
  return false;
180
180
  }
181
181
  function determine_arch2() {
182
- let arch2 = process.arch;
183
- if (arch2 == "riscv32" || arch2 == "riscv64") {
182
+ let arch = process.arch;
183
+ if (arch == "riscv32" || arch == "riscv64") {
184
184
  let buf = read_file_header(process.execPath, 512);
185
185
  let header = decode_elf_header(buf);
186
186
  let float_abi = header.e_flags & 6;
@@ -191,32 +191,32 @@ var require_tools = __commonJS({
191
191
  break;
192
192
  case 2:
193
193
  {
194
- arch2 += "f";
194
+ arch += "f";
195
195
  }
196
196
  break;
197
197
  case 4:
198
198
  {
199
- arch2 += "d";
199
+ arch += "d";
200
200
  }
201
201
  break;
202
202
  case 6:
203
203
  {
204
- arch2 += "q";
204
+ arch += "q";
205
205
  }
206
206
  break;
207
207
  }
208
- } else if (arch2 == "arm") {
208
+ } else if (arch == "arm") {
209
209
  let buf = read_file_header(process.execPath, 512);
210
210
  let header = decode_elf_header(buf);
211
211
  if (header.e_flags & 1024) {
212
- arch2 += "hf";
212
+ arch += "hf";
213
213
  } else if (header.e_flags & 512) {
214
- arch2 += "sf";
214
+ arch += "sf";
215
215
  } else {
216
216
  throw new Error("Unknown ARM floating-point ABI");
217
217
  }
218
218
  }
219
- return arch2;
219
+ return arch;
220
220
  }
221
221
  function read_file_header(filename2, read) {
222
222
  let fd = null;
@@ -305,12 +305,12 @@ var require_tools = __commonJS({
305
305
  }
306
306
  return header;
307
307
  }
308
- function unlink_recursive(path2) {
308
+ function unlink_recursive(path3) {
309
309
  try {
310
310
  if (fs2.rmSync != null) {
311
- fs2.rmSync(path2, { recursive: true, maxRetries: process.platform == "win32" ? 3 : 0 });
311
+ fs2.rmSync(path3, { recursive: true, maxRetries: process.platform == "win32" ? 3 : 0 });
312
312
  } else {
313
- fs2.rmdirSync(path2, { recursive: true, maxRetries: process.platform == "win32" ? 3 : 0 });
313
+ fs2.rmdirSync(path3, { recursive: true, maxRetries: process.platform == "win32" ? 3 : 0 });
314
314
  }
315
315
  } catch (err) {
316
316
  if (err.code !== "ENOENT")
@@ -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.8.10",
367
- stable: "2.8.10",
366
+ version: "2.9.0-beta.1",
367
+ stable: "2.8.11",
368
368
  description: "Fast and simple C FFI (foreign function interface) for Node.js",
369
369
  keywords: [
370
370
  "foreign",
@@ -408,61 +408,93 @@ var require_package = __commonJS({
408
408
  }
409
409
  });
410
410
 
411
- // ../../bin/Koffi/package/src/koffi/indirect.js
412
- var util = require("util");
413
- var fs = require("fs");
414
- var { get_napi_version, determine_arch } = require_tools();
415
- var pkg = require_package();
416
- if (process.versions.napi == null || process.versions.napi < pkg.cnoke.napi) {
417
- let major = parseInt(process.versions.node, 10);
418
- let required = get_napi_version(pkg.cnoke.napi, major);
419
- if (required != null) {
420
- throw new Error(`This engine is based on Node ${process.versions.node}, but ${pkg.name} requires Node >= ${required} in the Node ${major}.x branch (N-API >= ${pkg.cnoke.napi})`);
421
- } else {
422
- throw new Error(`This engine is based on Node ${process.versions.node}, but ${pkg.name} does not support the Node ${major}.x branch (N-API < ${pkg.cnoke.napi})`);
423
- }
424
- }
425
- var arch = determine_arch();
426
- var triplet = `${process.platform}_${arch}`;
427
- var native = null;
428
- {
429
- let roots = [__dirname];
430
- if (process.resourcesPath != null)
431
- roots.push(process.resourcesPath);
432
- let names = [
433
- `/build/koffi/${process.platform}_${arch}/koffi.node`,
434
- `/koffi/${process.platform}_${arch}/koffi.node`,
435
- `/node_modules/koffi/build/koffi/${process.platform}_${arch}/koffi.node`,
436
- `/../../bin/Koffi/${process.platform}_${arch}/koffi.node`
437
- ];
438
- for (let root of roots) {
439
- for (let name of names) {
440
- let filename = root + name;
441
- if (fs.existsSync(filename)) {
442
- native = eval("require")(filename);
443
- break;
411
+ // ../../bin/Koffi/package/src/koffi/src/init.js
412
+ var require_init = __commonJS({
413
+ "../../bin/Koffi/package/src/koffi/src/init.js"(exports, module) {
414
+ var fs = require("fs");
415
+ var path = require("path");
416
+ var util = require("util");
417
+ var { get_napi_version, determine_arch } = require_tools();
418
+ var pkg = require_package();
419
+ function detect() {
420
+ if (process.versions.napi == null || process.versions.napi < pkg.cnoke.napi) {
421
+ let major = parseInt(process.versions.node, 10);
422
+ let required = get_napi_version(pkg.cnoke.napi, major);
423
+ if (required != null) {
424
+ throw new Error(`This engine is based on Node ${process.versions.node}, but ${pkg.name} requires Node >= ${required} in the Node ${major}.x branch (N-API >= ${pkg.cnoke.napi})`);
425
+ } else {
426
+ throw new Error(`This engine is based on Node ${process.versions.node}, but ${pkg.name} does not support the Node ${major}.x branch (N-API < ${pkg.cnoke.napi})`);
427
+ }
444
428
  }
429
+ let arch = determine_arch();
430
+ let triplet3 = `${process.platform}_${arch}`;
431
+ return triplet3;
445
432
  }
446
- if (native != null)
447
- break;
433
+ function init(triplet, native) {
434
+ if (native == null) {
435
+ let roots = [path.join(__dirname, "..")];
436
+ let triplets = [triplet];
437
+ if (process.resourcesPath != null)
438
+ roots.push(process.resourcesPath);
439
+ if (triplet.startsWith("linux_")) {
440
+ let musl = triplet.replace(/^linux_/, "musl_");
441
+ triplets.push(musl);
442
+ }
443
+ let filenames = roots.flatMap((root) => triplets.flatMap((triplet3) => [
444
+ `${root}/build/koffi/${triplet3}/koffi.node`,
445
+ `${root}/koffi/${triplet3}/koffi.node`,
446
+ `${root}/node_modules/koffi/build/koffi/${triplet3}/koffi.node`,
447
+ `${root}/../../bin/Koffi/${triplet3}/koffi.node`
448
+ ]));
449
+ let first_err = null;
450
+ for (let filename of filenames) {
451
+ if (!fs.existsSync(filename))
452
+ continue;
453
+ try {
454
+ native = eval("require")(filename);
455
+ } catch (err) {
456
+ if (first_err == null)
457
+ first_err = err;
458
+ continue;
459
+ }
460
+ break;
461
+ }
462
+ if (first_err != null)
463
+ throw first_err;
464
+ }
465
+ if (native == null)
466
+ throw new Error("Cannot find the native Koffi module; did you bundle it correctly?");
467
+ if (native.version != pkg.version)
468
+ throw new Error("Mismatched native Koffi modules");
469
+ let mod = wrap(native);
470
+ return mod;
471
+ }
472
+ function wrap(native2) {
473
+ let obj = {
474
+ ...native2,
475
+ // Deprecated functions
476
+ handle: util.deprecate(native2.opaque, "The koffi.handle() function was deprecated in Koffi 2.1, use koffi.opaque() instead", "KOFFI001"),
477
+ callback: util.deprecate(native2.proto, "The koffi.callback() function was deprecated in Koffi 2.4, use koffi.proto() instead", "KOFFI002")
478
+ };
479
+ obj.load = (...args) => {
480
+ let lib = native2.load(...args);
481
+ lib.cdecl = util.deprecate((...args2) => lib.func("__cdecl", ...args2), "The koffi.cdecl() function was deprecated in Koffi 2.7, use koffi.func(...) instead", "KOFFI003");
482
+ lib.stdcall = util.deprecate((...args2) => lib.func("__stdcall", ...args2), 'The koffi.stdcall() function was deprecated in Koffi 2.7, use koffi.func("__stdcall", ...) instead', "KOFFI004");
483
+ lib.fastcall = util.deprecate((...args2) => lib.func("__fastcall", ...args2), 'The koffi.fastcall() function was deprecated in Koffi 2.7, use koffi.func("__fastcall", ...) instead', "KOFFI005");
484
+ lib.thiscall = util.deprecate((...args2) => lib.func("__thiscall", ...args2), 'The koffi.thiscall() function was deprecated in Koffi 2.7, use koffi.func("__thiscall", ...) instead', "KOFFI006");
485
+ return lib;
486
+ };
487
+ return obj;
488
+ }
489
+ module.exports = {
490
+ detect,
491
+ init
492
+ };
448
493
  }
449
- }
450
- if (native == null)
451
- throw new Error("Cannot find the native Koffi module; did you bundle it correctly?");
452
- if (native.version != pkg.version)
453
- throw new Error("Mismatched native Koffi modules");
454
- module.exports = {
455
- ...native,
456
- // Deprecated functions
457
- handle: util.deprecate(native.opaque, "The koffi.handle() function was deprecated in Koffi 2.1, use koffi.opaque() instead", "KOFFI001"),
458
- callback: util.deprecate(native.proto, "The koffi.callback() function was deprecated in Koffi 2.4, use koffi.proto() instead", "KOFFI002")
459
- };
460
- var load = module.exports.load;
461
- module.exports.load = (...args) => {
462
- let lib = load(...args);
463
- lib.cdecl = util.deprecate((...args2) => lib.func("__cdecl", ...args2), "The koffi.stdcall() function was deprecated in Koffi 2.7, use koffi.func(...) instead", "KOFFI003");
464
- lib.stdcall = util.deprecate((...args2) => lib.func("__stdcall", ...args2), 'The koffi.stdcall() function was deprecated in Koffi 2.7, use koffi.func("__stdcall", ...) instead', "KOFFI004");
465
- lib.fastcall = util.deprecate((...args2) => lib.func("__fastcall", ...args2), 'The koffi.fastcall() function was deprecated in Koffi 2.7, use koffi.func("__fastcall", ...) instead', "KOFFI005");
466
- lib.thiscall = util.deprecate((...args2) => lib.func("__thiscall", ...args2), 'The koffi.thiscall() function was deprecated in Koffi 2.7, use koffi.func("__thiscall", ...) instead', "KOFFI006");
467
- return lib;
468
- };
494
+ });
495
+
496
+ // ../../bin/Koffi/package/src/koffi/indirect.js
497
+ var { detect: detect2, init: init2 } = require_init();
498
+ var triplet2 = detect2();
499
+ var mod2 = init2(triplet2, null);
500
+ module.exports = mod2;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "koffi",
3
- "version": "2.8.11",
3
+ "version": "2.9.0-beta.1",
4
4
  "stable": "2.8.11",
5
5
  "description": "Fast and simple C FFI (foreign function interface) for Node.js",
6
6
  "keywords": [
@@ -35,4 +35,4 @@
35
35
  "napi": 8,
36
36
  "require": "./index.js"
37
37
  }
38
- }
38
+ }
@@ -50,7 +50,17 @@ endif()
50
50
 
51
51
  # ---- Koffi ----
52
52
 
53
- set(KOFFI_VERSION 2.8.10)
53
+ # Recompute the version string after each commit
54
+ if(EXISTS "${CMAKE_SOURCE_DIR}/../../.git/logs/HEAD")
55
+ configure_file("${CMAKE_SOURCE_DIR}/../../.git/logs/HEAD" git_logs_HEAD COPYONLY)
56
+ endif()
57
+ if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/package.json)
58
+ file(READ ${CMAKE_CURRENT_SOURCE_DIR}/package.json PKG)
59
+ else()
60
+ file(READ ${CMAKE_CURRENT_SOURCE_DIR}/../../package.json PKG)
61
+ endif()
62
+ string(REGEX MATCH "\"version\": \"([^\"]+)\"" XX "${PKG}")
63
+ set(KOFFI_VERSION ${CMAKE_MATCH_1})
54
64
 
55
65
  set_source_files_properties(src/ffi.cc PROPERTIES COMPILE_DEFINITIONS VERSION=${KOFFI_VERSION})
56
66
 
@@ -125,6 +125,7 @@ bool AnalyseFunction(Napi::Env, InstanceData *, FunctionInfo *func)
125
125
  case PrimitiveKind::UInt32S:
126
126
  case PrimitiveKind::String:
127
127
  case PrimitiveKind::String16:
128
+ case PrimitiveKind::String32:
128
129
  case PrimitiveKind::Pointer:
129
130
  case PrimitiveKind::Callback: {
130
131
  if (gpr_avail) {
@@ -343,6 +344,13 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
343
344
 
344
345
  *(const char16_t **)((param.gpr_count ? gpr_ptr : args_ptr)++) = str16;
345
346
  } break;
347
+ case PrimitiveKind::String32: {
348
+ const char32_t *str32;
349
+ if (!PushString32(value, param.directions, &str32)) [[unlikely]]
350
+ return false;
351
+
352
+ *(const char32_t **)((param.gpr_count ? gpr_ptr : args_ptr)++) = str32;
353
+ } break;
346
354
  case PrimitiveKind::Pointer: {
347
355
  void *ptr;
348
356
  if (!PushPointer(value, param.type, param.directions, &ptr)) [[unlikely]]
@@ -485,6 +493,7 @@ void CallData::Execute(const FunctionInfo *func, void *native)
485
493
  case PrimitiveKind::UInt64S:
486
494
  case PrimitiveKind::String:
487
495
  case PrimitiveKind::String16:
496
+ case PrimitiveKind::String32:
488
497
  case PrimitiveKind::Pointer:
489
498
  case PrimitiveKind::Callback: { result.u64 = PERFORM_CALL(GG); } break;
490
499
  case PrimitiveKind::Record:
@@ -535,6 +544,7 @@ Napi::Value CallData::Complete(const FunctionInfo *func)
535
544
  case PrimitiveKind::UInt64S: return NewBigInt(env, ReverseBytes(result.u64));
536
545
  case PrimitiveKind::String: return result.ptr ? Napi::String::New(env, (const char *)result.ptr) : env.Null();
537
546
  case PrimitiveKind::String16: return result.ptr ? Napi::String::New(env, (const char16_t *)result.ptr) : env.Null();
547
+ case PrimitiveKind::String32: return result.ptr ? MakeStringFromUTF32(env, (const char32_t *)result.ptr) : env.Null();
538
548
  case PrimitiveKind::Pointer:
539
549
  case PrimitiveKind::Callback: {
540
550
  if (result.ptr) {
@@ -726,6 +736,12 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_
726
736
  param.type->dispose(env, param.type, str16);
727
737
  }
728
738
  } break;
739
+ case PrimitiveKind::String32: {
740
+ const char32_t *str32 = *(const char32_t **)((param.gpr_count ? gpr_ptr : args_ptr)++);
741
+
742
+ Napi::Value arg = str32 ? MakeStringFromUTF32(env, str32) : env.Null();
743
+ arguments.Append(arg);
744
+ } break;
729
745
  case PrimitiveKind::Pointer:
730
746
  case PrimitiveKind::Callback: {
731
747
  void *ptr2 = *(void **)((param.gpr_count ? gpr_ptr : args_ptr)++);
@@ -923,6 +939,13 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_
923
939
 
924
940
  out_reg->r0 = (uint32_t)str16;
925
941
  } break;
942
+ case PrimitiveKind::String32: {
943
+ const char32_t *str32;
944
+ if (!PushString32(value, 1, &str32)) [[unlikely]]
945
+ return;
946
+
947
+ out_reg->r0 = (uint32_t)str32;
948
+ } break;
926
949
  case PrimitiveKind::Pointer: {
927
950
  uint8_t *ptr;
928
951
 
@@ -162,6 +162,7 @@ bool AnalyseFunction(Napi::Env, InstanceData *, FunctionInfo *func)
162
162
  case PrimitiveKind::UInt64S:
163
163
  case PrimitiveKind::String:
164
164
  case PrimitiveKind::String16:
165
+ case PrimitiveKind::String32:
165
166
  case PrimitiveKind::Pointer:
166
167
  case PrimitiveKind::Callback: {
167
168
  #ifdef __APPLE__
@@ -415,6 +416,16 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
415
416
  #endif
416
417
  *(const char16_t **)((param.gpr_count ? gpr_ptr : args_ptr)++) = str16;
417
418
  } break;
419
+ case PrimitiveKind::String32: {
420
+ const char32_t *str32;
421
+ if (!PushString32(value, param.directions, &str32)) [[unlikely]]
422
+ return false;
423
+
424
+ #if defined(__APPLE__)
425
+ args_ptr = param.gpr_count ? args_ptr : AlignUp(args_ptr, 8);
426
+ #endif
427
+ *(const char32_t **)((param.gpr_count ? gpr_ptr : args_ptr)++) = str32;
428
+ } break;
418
429
  case PrimitiveKind::Pointer: {
419
430
  void *ptr;
420
431
  if (!PushPointer(value, param.type, param.directions, &ptr)) [[unlikely]]
@@ -618,6 +629,7 @@ void CallData::Execute(const FunctionInfo *func, void *native)
618
629
  case PrimitiveKind::UInt64S:
619
630
  case PrimitiveKind::String:
620
631
  case PrimitiveKind::String16:
632
+ case PrimitiveKind::String32:
621
633
  case PrimitiveKind::Pointer:
622
634
  case PrimitiveKind::Callback: { result.u64 = PERFORM_CALL(GG).x0; } break;
623
635
  case PrimitiveKind::Record:
@@ -671,6 +683,7 @@ Napi::Value CallData::Complete(const FunctionInfo *func)
671
683
  case PrimitiveKind::UInt64S: return NewBigInt(env, ReverseBytes(result.u64));
672
684
  case PrimitiveKind::String: return result.ptr ? Napi::String::New(env, (const char *)result.ptr) : env.Null();
673
685
  case PrimitiveKind::String16: return result.ptr ? Napi::String::New(env, (const char16_t *)result.ptr) : env.Null();
686
+ case PrimitiveKind::String32: return result.ptr ? MakeStringFromUTF32(env, (const char32_t *)result.ptr) : env.Null();
674
687
  case PrimitiveKind::Pointer:
675
688
  case PrimitiveKind::Callback: {
676
689
  if (result.ptr) {
@@ -1034,6 +1047,16 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_
1034
1047
  param.type->dispose(env, param.type, str16);
1035
1048
  }
1036
1049
  } break;
1050
+ case PrimitiveKind::String32: {
1051
+ #if defined(__APPLE__)
1052
+ args_ptr = AlignUp(args_ptr, 8);
1053
+ #endif
1054
+
1055
+ const char32_t *str32 = *(const char32_t **)((param.gpr_count ? gpr_ptr : args_ptr)++);
1056
+
1057
+ Napi::Value arg = str32 ? MakeStringFromUTF32(env, str32) : env.Null();
1058
+ arguments.Append(arg);
1059
+ } break;
1037
1060
  case PrimitiveKind::Pointer:
1038
1061
  case PrimitiveKind::Callback: {
1039
1062
  #ifdef __APPLE__
@@ -1215,6 +1238,13 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_
1215
1238
 
1216
1239
  out_reg->x0 = (uint64_t)str16;
1217
1240
  } break;
1241
+ case PrimitiveKind::String32: {
1242
+ const char32_t *str32;
1243
+ if (!PushString32(value, 1, &str32)) [[unlikely]]
1244
+ return;
1245
+
1246
+ out_reg->x0 = (uint64_t)str32;
1247
+ } break;
1218
1248
  case PrimitiveKind::Pointer: {
1219
1249
  uint8_t *ptr;
1220
1250
 
@@ -252,6 +252,13 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
252
252
 
253
253
  *(const char16_t **)((param.gpr_count ? gpr_ptr : args_ptr)++) = str16;
254
254
  } break;
255
+ case PrimitiveKind::String32: {
256
+ const char32_t *str32;
257
+ if (!PushString32(value, param.directions, &str32)) [[unlikely]]
258
+ return false;
259
+
260
+ *(const char32_t **)((param.gpr_count ? gpr_ptr : args_ptr)++) = str32;
261
+ } break;
255
262
  case PrimitiveKind::Pointer: {
256
263
  void *ptr;
257
264
  if (!PushPointer(value, param.type, param.directions, &ptr)) [[unlikely]]
@@ -415,6 +422,7 @@ void CallData::Execute(const FunctionInfo *func, void *native)
415
422
  case PrimitiveKind::UInt64S:
416
423
  case PrimitiveKind::String:
417
424
  case PrimitiveKind::String16:
425
+ case PrimitiveKind::String32:
418
426
  case PrimitiveKind::Pointer:
419
427
  case PrimitiveKind::Callback: { result.u64 = PERFORM_CALL(GG).a0; } break;
420
428
  case PrimitiveKind::Record:
@@ -472,6 +480,7 @@ Napi::Value CallData::Complete(const FunctionInfo *func)
472
480
  case PrimitiveKind::UInt64S: return NewBigInt(env, ReverseBytes(result.u64));
473
481
  case PrimitiveKind::String: return result.ptr ? Napi::String::New(env, (const char *)result.ptr) : env.Null();
474
482
  case PrimitiveKind::String16: return result.ptr ? Napi::String::New(env, (const char16_t *)result.ptr) : env.Null();
483
+ case PrimitiveKind::String32: return result.ptr ? MakeStringFromUTF32(env, (const char32_t *)result.ptr) : env.Null();
475
484
  case PrimitiveKind::Pointer:
476
485
  case PrimitiveKind::Callback: {
477
486
  if (result.ptr) {
@@ -656,6 +665,12 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_
656
665
  param.type->dispose(env, param.type, str16);
657
666
  }
658
667
  } break;
668
+ case PrimitiveKind::String32: {
669
+ const char32_t *str32 = *(const char32_t **)((param.gpr_count ? gpr_ptr : args_ptr)++);
670
+
671
+ Napi::Value arg = str32 ? MakeStringFromUTF32(env, str32) : env.Null();
672
+ arguments.Append(arg);
673
+ } break;
659
674
  case PrimitiveKind::Pointer:
660
675
  case PrimitiveKind::Callback: {
661
676
  void *ptr2 = *(void **)((param.gpr_count ? gpr_ptr : args_ptr)++);
@@ -812,6 +827,13 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_
812
827
 
813
828
  out_reg->a0 = (uint64_t)str16;
814
829
  } break;
830
+ case PrimitiveKind::String32: {
831
+ const char32_t *str32;
832
+ if (!PushString32(value, 1, &str32)) [[unlikely]]
833
+ return;
834
+
835
+ out_reg->a0 = (uint64_t)str32;
836
+ } break;
815
837
  case PrimitiveKind::Pointer: {
816
838
  uint8_t *ptr;
817
839
 
@@ -121,6 +121,7 @@ static Size ClassifyType(const TypeInfo *type, Size offset, Span<RegisterClass>
121
121
  case PrimitiveKind::UInt64S:
122
122
  case PrimitiveKind::String:
123
123
  case PrimitiveKind::String16:
124
+ case PrimitiveKind::String32:
124
125
  case PrimitiveKind::Pointer:
125
126
  case PrimitiveKind::Callback: {
126
127
  classes[0] = MergeClasses(classes[0], RegisterClass::Integer);
@@ -326,6 +327,13 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
326
327
 
327
328
  *(const char16_t **)((param.gpr_count ? gpr_ptr : args_ptr)++) = str16;
328
329
  } break;
330
+ case PrimitiveKind::String32: {
331
+ const char32_t *str32;
332
+ if (!PushString32(value, param.directions, &str32)) [[unlikely]]
333
+ return false;
334
+
335
+ *(const char32_t **)((param.gpr_count ? gpr_ptr : args_ptr)++) = str32;
336
+ } break;
329
337
  case PrimitiveKind::Pointer: {
330
338
  void *ptr;
331
339
  if (!PushPointer(value, param.type, param.directions, &ptr)) [[unlikely]]
@@ -455,6 +463,7 @@ void CallData::Execute(const FunctionInfo *func, void *native)
455
463
  case PrimitiveKind::UInt64S:
456
464
  case PrimitiveKind::String:
457
465
  case PrimitiveKind::String16:
466
+ case PrimitiveKind::String32:
458
467
  case PrimitiveKind::Pointer:
459
468
  case PrimitiveKind::Callback: { result.u64 = PERFORM_CALL(GG).rax; } break;
460
469
  case PrimitiveKind::Record:
@@ -512,6 +521,7 @@ Napi::Value CallData::Complete(const FunctionInfo *func)
512
521
  case PrimitiveKind::UInt64S: return NewBigInt(env, ReverseBytes(result.u64));
513
522
  case PrimitiveKind::String: return result.ptr ? Napi::String::New(env, (const char *)result.ptr) : env.Null();
514
523
  case PrimitiveKind::String16: return result.ptr ? Napi::String::New(env, (const char16_t *)result.ptr) : env.Null();
524
+ case PrimitiveKind::String32: return result.ptr ? MakeStringFromUTF32(env, (const char32_t *)result.ptr) : env.Null();
515
525
  case PrimitiveKind::Pointer:
516
526
  case PrimitiveKind::Callback: {
517
527
  if (result.ptr) {
@@ -691,6 +701,12 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_
691
701
  param.type->dispose(env, param.type, str16);
692
702
  }
693
703
  } break;
704
+ case PrimitiveKind::String32: {
705
+ const char32_t *str32 = *(const char32_t **)((param.gpr_count ? gpr_ptr : args_ptr)++);
706
+
707
+ Napi::Value arg = str32 ? MakeStringFromUTF32(env, str32) : env.Null();
708
+ arguments.Append(arg);
709
+ } break;
694
710
  case PrimitiveKind::Pointer:
695
711
  case PrimitiveKind::Callback: {
696
712
  void *ptr2 = *(void **)((param.gpr_count ? gpr_ptr : args_ptr)++);
@@ -836,6 +852,13 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_
836
852
 
837
853
  out_reg->rax = (uint64_t)str16;
838
854
  } break;
855
+ case PrimitiveKind::String32: {
856
+ const char32_t *str32;
857
+ if (!PushString32(value, 1, &str32)) [[unlikely]]
858
+ return;
859
+
860
+ out_reg->rax = (uint64_t)str32;
861
+ } break;
839
862
  case PrimitiveKind::Pointer: {
840
863
  uint8_t *ptr;
841
864
 
@@ -144,6 +144,13 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
144
144
 
145
145
  *(const char16_t **)(args_ptr++) = str16;
146
146
  } break;
147
+ case PrimitiveKind::String32: {
148
+ const char32_t *str32;
149
+ if (!PushString32(value, param.directions, &str32)) [[unlikely]]
150
+ return false;
151
+
152
+ *(const char32_t **)(args_ptr++) = str32;
153
+ } break;
147
154
  case PrimitiveKind::Pointer: {
148
155
  void *ptr;
149
156
  if (!PushPointer(value, param.type, param.directions, &ptr)) [[unlikely]]
@@ -281,6 +288,7 @@ void CallData::Execute(const FunctionInfo *func, void *native)
281
288
  case PrimitiveKind::UInt64S:
282
289
  case PrimitiveKind::String:
283
290
  case PrimitiveKind::String16:
291
+ case PrimitiveKind::String32:
284
292
  case PrimitiveKind::Pointer:
285
293
  case PrimitiveKind::Record:
286
294
  case PrimitiveKind::Union:
@@ -324,6 +332,7 @@ Napi::Value CallData::Complete(const FunctionInfo *func)
324
332
  case PrimitiveKind::UInt64S: return NewBigInt(env, ReverseBytes(result.u64));
325
333
  case PrimitiveKind::String: return result.ptr ? Napi::String::New(env, (const char *)result.ptr) : env.Null();
326
334
  case PrimitiveKind::String16: return result.ptr ? Napi::String::New(env, (const char16_t *)result.ptr) : env.Null();
335
+ case PrimitiveKind::String32: return result.ptr ? MakeStringFromUTF32(env, (const char32_t *)result.ptr) : env.Null();
327
336
  case PrimitiveKind::Pointer:
328
337
  case PrimitiveKind::Callback: {
329
338
  if (result.ptr) {
@@ -535,6 +544,13 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_
535
544
  param.type->dispose(env, param.type, str16);
536
545
  }
537
546
  } break;
547
+ case PrimitiveKind::String32: {
548
+ const char32_t *str32 = *(const char32_t **)(j < 4 ? gpr_ptr + j : args_ptr);
549
+ args_ptr += (j >= 4);
550
+
551
+ Napi::Value arg = str32 ? MakeStringFromUTF32(env, str32) : env.Null();
552
+ arguments.Append(arg);
553
+ } break;
538
554
  case PrimitiveKind::Pointer:
539
555
  case PrimitiveKind::Callback: {
540
556
  void *ptr2 = *(void **)(j < 4 ? gpr_ptr + j : args_ptr);
@@ -661,6 +677,13 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool switch_
661
677
 
662
678
  out_reg->rax = (uint64_t)str16;
663
679
  } break;
680
+ case PrimitiveKind::String32: {
681
+ const char32_t *str32;
682
+ if (!PushString32(value, 1, &str32)) [[unlikely]]
683
+ return;
684
+
685
+ out_reg->rax = (uint64_t)str32;
686
+ } break;
664
687
  case PrimitiveKind::Pointer: {
665
688
  uint8_t *ptr;
666
689