koffi 1.2.4 → 1.3.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 (126) hide show
  1. package/README.md +7 -489
  2. package/benchmark/CMakeLists.txt +13 -9
  3. package/benchmark/raylib_node_raylib.js +67 -0
  4. package/build/qemu/1.3.1/koffi_darwin_arm64.tar.gz +0 -0
  5. package/build/qemu/1.3.1/koffi_darwin_x64.tar.gz +0 -0
  6. package/build/qemu/1.3.1/koffi_freebsd_arm64.tar.gz +0 -0
  7. package/build/qemu/1.3.1/koffi_freebsd_ia32.tar.gz +0 -0
  8. package/build/qemu/1.3.1/koffi_freebsd_x64.tar.gz +0 -0
  9. package/build/qemu/1.3.1/koffi_linux_arm32hf.tar.gz +0 -0
  10. package/build/qemu/1.3.1/koffi_linux_arm64.tar.gz +0 -0
  11. package/build/qemu/1.3.1/koffi_linux_ia32.tar.gz +0 -0
  12. package/build/qemu/1.3.1/koffi_linux_riscv64hf64.tar.gz +0 -0
  13. package/build/qemu/1.3.1/koffi_linux_x64.tar.gz +0 -0
  14. package/build/qemu/1.3.1/koffi_openbsd_ia32.tar.gz +0 -0
  15. package/build/qemu/1.3.1/koffi_openbsd_x64.tar.gz +0 -0
  16. package/build/qemu/1.3.1/koffi_win32_arm64.tar.gz +0 -0
  17. package/build/qemu/1.3.1/koffi_win32_ia32.tar.gz +0 -0
  18. package/build/qemu/1.3.1/koffi_win32_x64.tar.gz +0 -0
  19. package/doc/Makefile +20 -0
  20. package/doc/_static/bench_linux.png +0 -0
  21. package/doc/_static/bench_windows.png +0 -0
  22. package/doc/_static/custom.css +22 -0
  23. package/doc/benchmarks.md +113 -0
  24. package/doc/benchmarks.xlsx +0 -0
  25. package/doc/conf.py +54 -0
  26. package/doc/contribute.md +115 -0
  27. package/doc/dist/doctrees/benchmarks.doctree +0 -0
  28. package/doc/dist/doctrees/contribute.doctree +0 -0
  29. package/doc/dist/doctrees/environment.pickle +0 -0
  30. package/doc/dist/doctrees/functions.doctree +0 -0
  31. package/doc/dist/doctrees/index.doctree +0 -0
  32. package/doc/dist/doctrees/memory.doctree +0 -0
  33. package/doc/dist/doctrees/platforms.doctree +0 -0
  34. package/doc/dist/doctrees/start.doctree +0 -0
  35. package/doc/dist/doctrees/types.doctree +0 -0
  36. package/doc/dist/html/.buildinfo +4 -0
  37. package/doc/dist/html/_sources/benchmarks.md.txt +113 -0
  38. package/doc/dist/html/_sources/contribute.md.txt +115 -0
  39. package/doc/dist/html/_sources/functions.md.txt +224 -0
  40. package/doc/dist/html/_sources/index.rst.txt +33 -0
  41. package/doc/dist/html/_sources/memory.md.txt +29 -0
  42. package/doc/dist/html/_sources/platforms.md.txt +17 -0
  43. package/doc/dist/html/_sources/start.md.txt +89 -0
  44. package/doc/dist/html/_sources/types.md.txt +514 -0
  45. package/doc/dist/html/_static/_sphinx_javascript_frameworks_compat.js +134 -0
  46. package/doc/dist/html/_static/basic.css +932 -0
  47. package/doc/dist/html/_static/bench_linux.png +0 -0
  48. package/doc/dist/html/_static/bench_windows.png +0 -0
  49. package/doc/dist/html/_static/custom.css +22 -0
  50. package/doc/dist/html/_static/debug.css +69 -0
  51. package/doc/dist/html/_static/doctools.js +264 -0
  52. package/doc/dist/html/_static/documentation_options.js +14 -0
  53. package/doc/dist/html/_static/file.png +0 -0
  54. package/doc/dist/html/_static/jquery-3.6.0.js +10881 -0
  55. package/doc/dist/html/_static/jquery.js +2 -0
  56. package/doc/dist/html/_static/language_data.js +199 -0
  57. package/doc/dist/html/_static/minus.png +0 -0
  58. package/doc/dist/html/_static/plus.png +0 -0
  59. package/doc/dist/html/_static/pygments.css +252 -0
  60. package/doc/dist/html/_static/scripts/furo-extensions.js +0 -0
  61. package/doc/dist/html/_static/scripts/furo.js +3 -0
  62. package/doc/dist/html/_static/scripts/furo.js.LICENSE.txt +7 -0
  63. package/doc/dist/html/_static/scripts/furo.js.map +1 -0
  64. package/doc/dist/html/_static/searchtools.js +531 -0
  65. package/doc/dist/html/_static/skeleton.css +296 -0
  66. package/doc/dist/html/_static/styles/furo-extensions.css +2 -0
  67. package/doc/dist/html/_static/styles/furo-extensions.css.map +1 -0
  68. package/doc/dist/html/_static/styles/furo.css +2 -0
  69. package/doc/dist/html/_static/styles/furo.css.map +1 -0
  70. package/doc/dist/html/_static/underscore-1.13.1.js +2042 -0
  71. package/doc/dist/html/_static/underscore.js +6 -0
  72. package/doc/dist/html/benchmarks.html +547 -0
  73. package/doc/dist/html/contribute.html +382 -0
  74. package/doc/dist/html/functions.html +530 -0
  75. package/doc/dist/html/genindex.html +249 -0
  76. package/doc/dist/html/index.html +342 -0
  77. package/doc/dist/html/memory.html +337 -0
  78. package/doc/dist/html/objects.inv +0 -0
  79. package/doc/dist/html/platforms.html +332 -0
  80. package/doc/dist/html/search.html +257 -0
  81. package/doc/dist/html/searchindex.js +1 -0
  82. package/doc/dist/html/start.html +367 -0
  83. package/doc/dist/html/types.html +1001 -0
  84. package/doc/functions.md +224 -0
  85. package/doc/index.rst +33 -0
  86. package/doc/make.bat +35 -0
  87. package/doc/memory.md +29 -0
  88. package/doc/platforms.md +17 -0
  89. package/doc/start.md +89 -0
  90. package/doc/types.md +514 -0
  91. package/package.json +6 -3
  92. package/qemu/qemu.js +41 -27
  93. package/qemu/registry/machines.json +59 -79
  94. package/qemu/registry/sha256sum.txt +4 -4
  95. package/src/abi_arm32.cc +20 -48
  96. package/src/abi_arm64.cc +18 -46
  97. package/src/abi_arm64_fwd.S +5 -0
  98. package/src/abi_riscv64.cc +19 -47
  99. package/src/abi_x64_sysv.cc +18 -46
  100. package/src/abi_x64_win.cc +19 -47
  101. package/src/abi_x86.cc +21 -49
  102. package/src/call.cc +505 -242
  103. package/src/call.hh +14 -7
  104. package/src/ffi.cc +50 -27
  105. package/src/ffi.hh +1 -1
  106. package/src/parser.cc +2 -20
  107. package/src/util.cc +50 -11
  108. package/src/util.hh +2 -0
  109. package/test/misc.c +31 -0
  110. package/test/sync.js +41 -4
  111. package/benchmark/atoi_cc.cc +0 -59
  112. package/build/qemu/1.2.4/koffi_darwin_arm64.tar.gz +0 -0
  113. package/build/qemu/1.2.4/koffi_darwin_x64.tar.gz +0 -0
  114. package/build/qemu/1.2.4/koffi_freebsd_arm64.tar.gz +0 -0
  115. package/build/qemu/1.2.4/koffi_freebsd_ia32.tar.gz +0 -0
  116. package/build/qemu/1.2.4/koffi_freebsd_x64.tar.gz +0 -0
  117. package/build/qemu/1.2.4/koffi_linux_arm.tar.gz +0 -0
  118. package/build/qemu/1.2.4/koffi_linux_arm64.tar.gz +0 -0
  119. package/build/qemu/1.2.4/koffi_linux_ia32.tar.gz +0 -0
  120. package/build/qemu/1.2.4/koffi_linux_riscv64.tar.gz +0 -0
  121. package/build/qemu/1.2.4/koffi_linux_x64.tar.gz +0 -0
  122. package/build/qemu/1.2.4/koffi_openbsd_ia32.tar.gz +0 -0
  123. package/build/qemu/1.2.4/koffi_openbsd_x64.tar.gz +0 -0
  124. package/build/qemu/1.2.4/koffi_win32_arm64.tar.gz +0 -0
  125. package/build/qemu/1.2.4/koffi_win32_ia32.tar.gz +0 -0
  126. package/build/qemu/1.2.4/koffi_win32_x64.tar.gz +0 -0
package/src/abi_arm32.cc CHANGED
@@ -247,7 +247,7 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
247
247
 
248
248
  case PrimitiveKind::Bool: {
249
249
  if (RG_UNLIKELY(!value.IsBoolean())) {
250
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected boolean", GetValueType(instance, value), i + 1);
250
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected boolean", GetValueType(instance, value), param.offset + 1);
251
251
  return false;
252
252
  }
253
253
 
@@ -260,7 +260,7 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
260
260
  case PrimitiveKind::UInt16:
261
261
  case PrimitiveKind::Int32: {
262
262
  if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
263
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), i + 1);
263
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), param.offset + 1);
264
264
  return false;
265
265
  }
266
266
 
@@ -269,7 +269,7 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
269
269
  } break;
270
270
  case PrimitiveKind::UInt32: {
271
271
  if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
272
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), i + 1);
272
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), param.offset + 1);
273
273
  return false;
274
274
  }
275
275
 
@@ -278,7 +278,7 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
278
278
  } break;
279
279
  case PrimitiveKind::Int64: {
280
280
  if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
281
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), i + 1);
281
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), param.offset + 1);
282
282
  return false;
283
283
  }
284
284
 
@@ -296,7 +296,7 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
296
296
  } break;
297
297
  case PrimitiveKind::UInt64: {
298
298
  if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
299
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), i + 1);
299
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), param.offset + 1);
300
300
  return false;
301
301
  }
302
302
 
@@ -321,7 +321,7 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
321
321
  } else if (IsNullOrUndefined(value)) {
322
322
  str = nullptr;
323
323
  } else {
324
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected string", GetValueType(instance, value), i + 1);
324
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected string", GetValueType(instance, value), param.offset + 1);
325
325
  return false;
326
326
  }
327
327
 
@@ -336,47 +336,22 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
336
336
  } else if (IsNullOrUndefined(value)) {
337
337
  str16 = nullptr;
338
338
  } else {
339
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected string", GetValueType(instance, value), i + 1);
339
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected string", GetValueType(instance, value), param.offset + 1);
340
340
  return false;
341
341
  }
342
342
 
343
343
  *(const char16_t **)((param.gpr_count ? gpr_ptr : args_ptr)++) = str16;
344
344
  } break;
345
345
  case PrimitiveKind::Pointer: {
346
- uint8_t *ptr;
347
-
348
- if (CheckValueTag(instance, value, param.type)) {
349
- ptr = value.As<Napi::External<uint8_t>>().Data();
350
- } else if (IsObject(value) && param.type->ref->primitive == PrimitiveKind::Record) {
351
- Napi::Object obj = value.As<Napi::Object>();
352
-
353
- ptr = AllocHeap(param.type->ref->size, 16);
354
-
355
- if (param.directions & 1) {
356
- if (!PushObject(obj, param.type->ref, ptr))
357
- return false;
358
- } else {
359
- memset(ptr, 0, param.type->size);
360
- }
361
- if (param.directions & 2) {
362
- OutObject *out = out_objects.AppendDefault();
363
-
364
- out->ref.Reset(obj, 1);
365
- out->ptr = ptr;
366
- out->type = param.type->ref;
367
- }
368
- } else if (IsNullOrUndefined(value)) {
369
- ptr = nullptr;
370
- } else {
371
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected %3", GetValueType(instance, value), i + 1, param.type->name);
346
+ void *ptr;
347
+ if (RG_UNLIKELY(!PushPointer(value, param, &ptr)))
372
348
  return false;
373
- }
374
349
 
375
350
  *(void **)((param.gpr_count ? gpr_ptr : args_ptr)++) = ptr;
376
351
  } break;
377
352
  case PrimitiveKind::Record: {
378
353
  if (RG_UNLIKELY(!IsObject(value))) {
379
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected object", GetValueType(instance, value), i + 1);
354
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected object", GetValueType(instance, value), param.offset + 1);
380
355
  return false;
381
356
  }
382
357
 
@@ -409,7 +384,7 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
409
384
  case PrimitiveKind::Array: { RG_UNREACHABLE(); } break;
410
385
  case PrimitiveKind::Float32: {
411
386
  if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
412
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), i + 1);
387
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), param.offset + 1);
413
388
  return false;
414
389
  }
415
390
 
@@ -425,7 +400,7 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
425
400
  } break;
426
401
  case PrimitiveKind::Float64: {
427
402
  if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
428
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), i + 1);
403
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), param.offset + 1);
429
404
  return false;
430
405
  }
431
406
 
@@ -458,7 +433,7 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
458
433
  } else if (IsNullOrUndefined(value)) {
459
434
  ptr = nullptr;
460
435
  } else {
461
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected %3", GetValueType(instance, value), i + 1, param.type->name);
436
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected %3", GetValueType(instance, value), param.offset + 1, param.type->name);
462
437
  return false;
463
438
  }
464
439
 
@@ -517,10 +492,7 @@ void CallData::Execute()
517
492
 
518
493
  Napi::Value CallData::Complete()
519
494
  {
520
- for (const OutObject &out: out_objects) {
521
- Napi::Object obj = out.ref.Value().As<Napi::Object>();
522
- PopObject(obj, out.ptr, out.type);
523
- }
495
+ PopOutArguments();
524
496
 
525
497
  switch (func->ret.type->primitive) {
526
498
  case PrimitiveKind::Void: return env.Null();
@@ -533,8 +505,8 @@ Napi::Value CallData::Complete()
533
505
  case PrimitiveKind::UInt32: return Napi::Number::New(env, (double)result.u32);
534
506
  case PrimitiveKind::Int64: return Napi::BigInt::New(env, (int64_t)result.u64);
535
507
  case PrimitiveKind::UInt64: return Napi::BigInt::New(env, result.u64);
536
- case PrimitiveKind::String: return Napi::String::New(env, (const char *)result.ptr);
537
- case PrimitiveKind::String16: return Napi::String::New(env, (const char16_t *)result.ptr);
508
+ case PrimitiveKind::String: return result.ptr ? Napi::String::New(env, (const char *)result.ptr) : env.Null();
509
+ case PrimitiveKind::String16: return result.ptr ? Napi::String::New(env, (const char16_t *)result.ptr) : env.Null();
538
510
  case PrimitiveKind::Pointer:
539
511
  case PrimitiveKind::Callback: {
540
512
  if (result.ptr) {
@@ -646,13 +618,13 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
646
618
  case PrimitiveKind::String: {
647
619
  const char *str = *(const char **)((param.gpr_count ? gpr_ptr : args_ptr)++);
648
620
 
649
- Napi::Value arg = Napi::String::New(env, str);
621
+ Napi::Value arg = str ? Napi::String::New(env, str) : env.Null();
650
622
  arguments.Append(arg);
651
623
  } break;
652
624
  case PrimitiveKind::String16: {
653
625
  const char16_t *str16 = *(const char16_t **)((param.gpr_count ? gpr_ptr : args_ptr)++);
654
626
 
655
- Napi::Value arg = Napi::String::New(env, str16);
627
+ Napi::Value arg = str16 ? Napi::String::New(env, str16) : env.Null();
656
628
  arguments.Append(arg);
657
629
  } break;
658
630
  case PrimitiveKind::Pointer:
@@ -906,9 +878,9 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
906
878
  void *ptr;
907
879
 
908
880
  if (value.IsFunction()) {
909
- Napi::Function func = value.As<Napi::Function>();
881
+ Napi::Function func2 = value.As<Napi::Function>();
910
882
 
911
- ptr = ReserveTrampoline(type->proto, func);
883
+ ptr = ReserveTrampoline(type->proto, func2);
912
884
  if (RG_UNLIKELY(!ptr))
913
885
  return;
914
886
  } else if (CheckValueTag(instance, value, type)) {
package/src/abi_arm64.cc CHANGED
@@ -237,7 +237,7 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
237
237
 
238
238
  case PrimitiveKind::Bool: {
239
239
  if (RG_UNLIKELY(!value.IsBoolean())) {
240
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected boolean", GetValueType(instance, value), i + 1);
240
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected boolean", GetValueType(instance, value), param.offset + 1);
241
241
  return false;
242
242
  }
243
243
 
@@ -262,7 +262,7 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
262
262
  case PrimitiveKind::UInt32:
263
263
  case PrimitiveKind::Int64: {
264
264
  if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
265
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), i + 1);
265
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), param.offset + 1);
266
266
  return false;
267
267
  }
268
268
 
@@ -282,7 +282,7 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
282
282
  } break;
283
283
  case PrimitiveKind::UInt64: {
284
284
  if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
285
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), i + 1);
285
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), param.offset + 1);
286
286
  return false;
287
287
  }
288
288
 
@@ -302,7 +302,7 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
302
302
  } else if (IsNullOrUndefined(value)) {
303
303
  str = nullptr;
304
304
  } else {
305
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected string", GetValueType(instance, value), i + 1);
305
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected string", GetValueType(instance, value), param.offset + 1);
306
306
  return false;
307
307
  }
308
308
 
@@ -320,7 +320,7 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
320
320
  } else if (IsNullOrUndefined(value)) {
321
321
  str16 = nullptr;
322
322
  } else {
323
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected string", GetValueType(instance, value), i + 1);
323
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected string", GetValueType(instance, value), param.offset + 1);
324
324
  return false;
325
325
  }
326
326
 
@@ -330,34 +330,9 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
330
330
  *(const char16_t **)((param.gpr_count ? gpr_ptr : args_ptr)++) = str16;
331
331
  } break;
332
332
  case PrimitiveKind::Pointer: {
333
- uint8_t *ptr;
334
-
335
- if (CheckValueTag(instance, value, param.type)) {
336
- ptr = value.As<Napi::External<uint8_t>>().Data();
337
- } else if (IsObject(value) && param.type->ref->primitive == PrimitiveKind::Record) {
338
- Napi::Object obj = value.As<Napi::Object>();
339
-
340
- ptr = AllocHeap(param.type->ref->size, 16);
341
-
342
- if (param.directions & 1) {
343
- if (!PushObject(obj, param.type->ref, ptr))
344
- return false;
345
- } else {
346
- memset(ptr, 0, param.type->size);
347
- }
348
- if (param.directions & 2) {
349
- OutObject *out = out_objects.AppendDefault();
350
-
351
- out->ref.Reset(obj, 1);
352
- out->ptr = ptr;
353
- out->type = param.type->ref;
354
- }
355
- } else if (IsNullOrUndefined(value)) {
356
- ptr = nullptr;
357
- } else {
358
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected %3", GetValueType(instance, value), i + 1, param.type->name);
333
+ void *ptr;
334
+ if (RG_UNLIKELY(!PushPointer(value, param, &ptr)))
359
335
  return false;
360
- }
361
336
 
362
337
  #ifdef __APPLE__
363
338
  args_ptr = param.gpr_count ? args_ptr : AlignUp(args_ptr, 8);
@@ -366,7 +341,7 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
366
341
  } break;
367
342
  case PrimitiveKind::Record: {
368
343
  if (RG_UNLIKELY(!IsObject(value))) {
369
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected object", GetValueType(instance, value), i + 1);
344
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected object", GetValueType(instance, value), param.offset + 1);
370
345
  return false;
371
346
  }
372
347
 
@@ -413,7 +388,7 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
413
388
  case PrimitiveKind::Array: { RG_UNREACHABLE(); } break;
414
389
  case PrimitiveKind::Float32: {
415
390
  if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
416
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), i + 1);
391
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), param.offset + 1);
417
392
  return false;
418
393
  }
419
394
 
@@ -440,7 +415,7 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
440
415
  } break;
441
416
  case PrimitiveKind::Float64: {
442
417
  if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
443
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), i + 1);
418
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), param.offset + 1);
444
419
  return false;
445
420
  }
446
421
 
@@ -473,7 +448,7 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
473
448
  } else if (IsNullOrUndefined(value)) {
474
449
  ptr = nullptr;
475
450
  } else {
476
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected %3", GetValueType(instance, value), i + 1, param.type->name);
451
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected %3", GetValueType(instance, value), param.offset + 1, param.type->name);
477
452
  return false;
478
453
  }
479
454
 
@@ -538,10 +513,7 @@ void CallData::Execute()
538
513
 
539
514
  Napi::Value CallData::Complete()
540
515
  {
541
- for (const OutObject &out: out_objects) {
542
- Napi::Object obj = out.ref.Value().As<Napi::Object>();
543
- PopObject(obj, out.ptr, out.type);
544
- }
516
+ PopOutArguments();
545
517
 
546
518
  switch (func->ret.type->primitive) {
547
519
  case PrimitiveKind::Void: return env.Null();
@@ -554,8 +526,8 @@ Napi::Value CallData::Complete()
554
526
  case PrimitiveKind::UInt32: return Napi::Number::New(env, (double)result.u32);
555
527
  case PrimitiveKind::Int64: return Napi::BigInt::New(env, (int64_t)result.u64);
556
528
  case PrimitiveKind::UInt64: return Napi::BigInt::New(env, result.u64);
557
- case PrimitiveKind::String: return Napi::String::New(env, (const char *)result.ptr);
558
- case PrimitiveKind::String16: return Napi::String::New(env, (const char16_t *)result.ptr);
529
+ case PrimitiveKind::String: return result.ptr ? Napi::String::New(env, (const char *)result.ptr) : env.Null();
530
+ case PrimitiveKind::String16: return result.ptr ? Napi::String::New(env, (const char16_t *)result.ptr) : env.Null();
559
531
  case PrimitiveKind::Pointer:
560
532
  case PrimitiveKind::Callback: {
561
533
  if (result.ptr) {
@@ -751,7 +723,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
751
723
 
752
724
  const char *str = *(const char **)((param.gpr_count ? gpr_ptr : args_ptr)++);
753
725
 
754
- Napi::Value arg = Napi::String::New(env, str);
726
+ Napi::Value arg = str ? Napi::String::New(env, str) : env.Null();
755
727
  arguments.Append(arg);
756
728
  } break;
757
729
  case PrimitiveKind::String16: {
@@ -761,7 +733,7 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
761
733
 
762
734
  const char16_t *str16 = *(const char16_t **)((param.gpr_count ? gpr_ptr : args_ptr)++);
763
735
 
764
- Napi::Value arg = Napi::String::New(env, str16);
736
+ Napi::Value arg = str16 ? Napi::String::New(env, str16) : env.Null();
765
737
  arguments.Append(arg);
766
738
  } break;
767
739
  case PrimitiveKind::Pointer:
@@ -987,9 +959,9 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
987
959
  void *ptr;
988
960
 
989
961
  if (value.IsFunction()) {
990
- Napi::Function func = value.As<Napi::Function>();
962
+ Napi::Function func2 = value.As<Napi::Function>();
991
963
 
992
- ptr = ReserveTrampoline(type->proto, func);
964
+ ptr = ReserveTrampoline(type->proto, func2);
993
965
  if (RG_UNLIKELY(!ptr))
994
966
  return;
995
967
  } else if (CheckValueTag(instance, value, type)) {
@@ -20,6 +20,11 @@
20
20
  # Forward
21
21
  # ----------------------------
22
22
 
23
+ #ifdef __APPLE__
24
+ # Fix "arm64 function not 4-byte aligned" linker warnings
25
+ .p2align 2
26
+ #endif
27
+
23
28
  # These three are the same, but they differ (in the C side) by their return type.
24
29
  # Unlike the three next functions, these ones don't forward XMM argument registers.
25
30
  .global SYMBOL(ForwardCallGG)
@@ -196,7 +196,7 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
196
196
 
197
197
  case PrimitiveKind::Bool: {
198
198
  if (RG_UNLIKELY(!value.IsBoolean())) {
199
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected boolean", GetValueType(instance, value), i + 1);
199
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected boolean", GetValueType(instance, value), param.offset + 1);
200
200
  return false;
201
201
  }
202
202
 
@@ -208,7 +208,7 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
208
208
  case PrimitiveKind::Int32:
209
209
  case PrimitiveKind::Int64: {
210
210
  if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
211
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), i + 1);
211
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), param.offset + 1);
212
212
  return false;
213
213
  }
214
214
 
@@ -220,7 +220,7 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
220
220
  case PrimitiveKind::UInt32:
221
221
  case PrimitiveKind::UInt64: {
222
222
  if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
223
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), i + 1);
223
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), param.offset + 1);
224
224
  return false;
225
225
  }
226
226
 
@@ -236,7 +236,7 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
236
236
  } else if (IsNullOrUndefined(value)) {
237
237
  str = nullptr;
238
238
  } else {
239
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected string", GetValueType(instance, value), i + 1);
239
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected string", GetValueType(instance, value), param.offset + 1);
240
240
  return false;
241
241
  }
242
242
 
@@ -251,47 +251,22 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
251
251
  } else if (IsNullOrUndefined(value)) {
252
252
  str16 = nullptr;
253
253
  } else {
254
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected string", GetValueType(instance, value), i + 1);
254
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected string", GetValueType(instance, value), param.offset + 1);
255
255
  return false;
256
256
  }
257
257
 
258
258
  *(const char16_t **)((param.gpr_count ? gpr_ptr : args_ptr)++) = str16;
259
259
  } break;
260
260
  case PrimitiveKind::Pointer: {
261
- uint8_t *ptr;
262
-
263
- if (CheckValueTag(instance, value, param.type)) {
264
- ptr = value.As<Napi::External<uint8_t>>().Data();
265
- } else if (IsObject(value) && param.type->ref->primitive == PrimitiveKind::Record) {
266
- Napi::Object obj = value.As<Napi::Object>();
267
-
268
- ptr = AllocHeap(param.type->ref->size, 16);
269
-
270
- if (param.directions & 1) {
271
- if (!PushObject(obj, param.type->ref, ptr))
272
- return false;
273
- } else {
274
- memset(ptr, 0, param.type->size);
275
- }
276
- if (param.directions & 2) {
277
- OutObject *out = out_objects.AppendDefault();
278
-
279
- out->ref.Reset(obj, 1);
280
- out->ptr = ptr;
281
- out->type = param.type->ref;
282
- }
283
- } else if (IsNullOrUndefined(value)) {
284
- ptr = nullptr;
285
- } else {
286
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected %3", GetValueType(instance, value), i + 1, param.type->name);
261
+ void *ptr;
262
+ if (RG_UNLIKELY(!PushPointer(value, param, &ptr)))
287
263
  return false;
288
- }
289
264
 
290
- *(uint8_t **)((param.gpr_count ? gpr_ptr : args_ptr)++) = ptr;
265
+ *(void **)((param.gpr_count ? gpr_ptr : args_ptr)++) = ptr;
291
266
  } break;
292
267
  case PrimitiveKind::Record: {
293
268
  if (RG_UNLIKELY(!IsObject(value))) {
294
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected object", GetValueType(instance, value), i + 1);
269
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected object", GetValueType(instance, value), param.offset + 1);
295
270
  return false;
296
271
  }
297
272
 
@@ -340,7 +315,7 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
340
315
  case PrimitiveKind::Array: { RG_UNREACHABLE(); } break;
341
316
  case PrimitiveKind::Float32: {
342
317
  if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
343
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), i + 1);
318
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), param.offset + 1);
344
319
  return false;
345
320
  }
346
321
 
@@ -359,7 +334,7 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
359
334
  } break;
360
335
  case PrimitiveKind::Float64: {
361
336
  if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
362
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), i + 1);
337
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), param.offset + 1);
363
338
  return false;
364
339
  }
365
340
 
@@ -387,7 +362,7 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
387
362
  } else if (IsNullOrUndefined(value)) {
388
363
  ptr = nullptr;
389
364
  } else {
390
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected %3", GetValueType(instance, value), i + 1, param.type->name);
365
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected %3", GetValueType(instance, value), param.offset + 1, param.type->name);
391
366
  return false;
392
367
  }
393
368
 
@@ -453,10 +428,7 @@ void CallData::Execute()
453
428
 
454
429
  Napi::Value CallData::Complete()
455
430
  {
456
- for (const OutObject &out: out_objects) {
457
- Napi::Object obj = out.ref.Value().As<Napi::Object>();
458
- PopObject(obj, out.ptr, out.type);
459
- }
431
+ PopOutArguments();
460
432
 
461
433
  switch (func->ret.type->primitive) {
462
434
  case PrimitiveKind::Void: return env.Null();
@@ -469,8 +441,8 @@ Napi::Value CallData::Complete()
469
441
  case PrimitiveKind::UInt32: return Napi::Number::New(env, (double)result.u32);
470
442
  case PrimitiveKind::Int64: return Napi::BigInt::New(env, (int64_t)result.u64);
471
443
  case PrimitiveKind::UInt64: return Napi::BigInt::New(env, result.u64);
472
- case PrimitiveKind::String: return Napi::String::New(env, (const char *)result.ptr);
473
- case PrimitiveKind::String16: return Napi::String::New(env, (const char16_t *)result.ptr);
444
+ case PrimitiveKind::String: return result.ptr ? Napi::String::New(env, (const char *)result.ptr) : env.Null();
445
+ case PrimitiveKind::String16: return result.ptr ? Napi::String::New(env, (const char16_t *)result.ptr) : env.Null();
474
446
  case PrimitiveKind::Pointer:
475
447
  case PrimitiveKind::Callback: {
476
448
  if (result.ptr) {
@@ -581,13 +553,13 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
581
553
  case PrimitiveKind::String: {
582
554
  const char *str = *(const char **)((param.gpr_count ? gpr_ptr : args_ptr)++);
583
555
 
584
- Napi::Value arg = Napi::String::New(env, str);
556
+ Napi::Value arg = str ? Napi::String::New(env, str) : env.Null();
585
557
  arguments.Append(arg);
586
558
  } break;
587
559
  case PrimitiveKind::String16: {
588
560
  const char16_t *str16 = *(const char16_t **)((param.gpr_count ? gpr_ptr : args_ptr)++);
589
561
 
590
- Napi::Value arg = Napi::String::New(env, str16);
562
+ Napi::Value arg = str16 ? Napi::String::New(env, str16) : env.Null();
591
563
  arguments.Append(arg);
592
564
  } break;
593
565
  case PrimitiveKind::Pointer:
@@ -792,9 +764,9 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
792
764
  void *ptr;
793
765
 
794
766
  if (value.IsFunction()) {
795
- Napi::Function func = value.As<Napi::Function>();
767
+ Napi::Function func2 = value.As<Napi::Function>();
796
768
 
797
- ptr = ReserveTrampoline(type->proto, func);
769
+ ptr = ReserveTrampoline(type->proto, func2);
798
770
  if (RG_UNLIKELY(!ptr))
799
771
  return;
800
772
  } else if (CheckValueTag(instance, value, type)) {