koffi 2.0.1 → 2.1.0-beta.3

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 (90) hide show
  1. package/CMakeLists.txt +2 -9
  2. package/ChangeLog.md +17 -0
  3. package/benchmark/atoi_koffi.js +12 -8
  4. package/benchmark/atoi_napi.js +12 -8
  5. package/benchmark/atoi_node_ffi.js +11 -10
  6. package/benchmark/raylib_cc.cc +12 -9
  7. package/benchmark/raylib_koffi.js +15 -13
  8. package/benchmark/raylib_node_ffi.js +15 -13
  9. package/benchmark/raylib_node_raylib.js +14 -11
  10. package/build/qemu/2.1.0-beta.3/koffi_darwin_arm64.tar.gz +0 -0
  11. package/build/qemu/2.1.0-beta.3/koffi_darwin_x64.tar.gz +0 -0
  12. package/build/qemu/2.1.0-beta.3/koffi_freebsd_arm64.tar.gz +0 -0
  13. package/build/qemu/2.1.0-beta.3/koffi_freebsd_ia32.tar.gz +0 -0
  14. package/build/qemu/2.1.0-beta.3/koffi_freebsd_x64.tar.gz +0 -0
  15. package/build/qemu/2.1.0-beta.3/koffi_linux_arm32hf.tar.gz +0 -0
  16. package/build/qemu/2.1.0-beta.3/koffi_linux_arm64.tar.gz +0 -0
  17. package/build/qemu/2.1.0-beta.3/koffi_linux_ia32.tar.gz +0 -0
  18. package/build/qemu/2.1.0-beta.3/koffi_linux_riscv64hf64.tar.gz +0 -0
  19. package/build/qemu/2.1.0-beta.3/koffi_linux_x64.tar.gz +0 -0
  20. package/build/qemu/2.1.0-beta.3/koffi_openbsd_ia32.tar.gz +0 -0
  21. package/build/qemu/2.1.0-beta.3/koffi_openbsd_x64.tar.gz +0 -0
  22. package/build/qemu/2.1.0-beta.3/koffi_win32_arm64.tar.gz +0 -0
  23. package/build/qemu/2.1.0-beta.3/koffi_win32_ia32.tar.gz +0 -0
  24. package/build/qemu/2.1.0-beta.3/koffi_win32_x64.tar.gz +0 -0
  25. package/doc/Makefile +1 -1
  26. package/doc/changes.md +12 -8
  27. package/doc/conf.py +5 -0
  28. package/doc/dist/doctrees/changes.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/types.doctree +0 -0
  33. package/doc/dist/html/.buildinfo +1 -1
  34. package/doc/dist/html/_sources/changes.md.txt +12 -8
  35. package/doc/dist/html/_sources/functions.md.txt +71 -5
  36. package/doc/dist/html/_sources/types.md.txt +147 -159
  37. package/doc/dist/html/benchmarks.html +2 -3
  38. package/doc/dist/html/changes.html +64 -35
  39. package/doc/dist/html/contribute.html +2 -3
  40. package/doc/dist/html/functions.html +73 -12
  41. package/doc/dist/html/genindex.html +2 -3
  42. package/doc/dist/html/index.html +6 -7
  43. package/doc/dist/html/memory.html +2 -3
  44. package/doc/dist/html/objects.inv +0 -0
  45. package/doc/dist/html/platforms.html +3 -4
  46. package/doc/dist/html/search.html +2 -3
  47. package/doc/dist/html/searchindex.js +1 -1
  48. package/doc/dist/html/start.html +2 -3
  49. package/doc/dist/html/types.html +238 -237
  50. package/doc/functions.md +71 -5
  51. package/doc/make.bat +1 -1
  52. package/doc/templates/badges.html +1 -2
  53. package/doc/types.md +149 -159
  54. package/package.json +3 -2
  55. package/qemu/qemu.js +1 -1
  56. package/src/abi_arm32.cc +208 -102
  57. package/src/abi_arm64.cc +239 -55
  58. package/src/abi_riscv64.cc +128 -40
  59. package/src/abi_x64_sysv.cc +135 -41
  60. package/src/abi_x64_win.cc +134 -40
  61. package/src/abi_x86.cc +182 -67
  62. package/src/call.cc +241 -26
  63. package/src/call.hh +15 -3
  64. package/src/ffi.cc +120 -31
  65. package/src/ffi.hh +19 -0
  66. package/src/index.js +4 -2
  67. package/src/parser.cc +3 -5
  68. package/src/util.cc +44 -1
  69. package/src/util.hh +4 -0
  70. package/test/async.js +1 -2
  71. package/test/callbacks.js +2 -3
  72. package/test/misc.c +64 -1
  73. package/test/raylib.js +1 -1
  74. package/test/sqlite.js +3 -3
  75. package/test/sync.js +108 -3
  76. package/build/qemu/2.0.1/koffi_darwin_arm64.tar.gz +0 -0
  77. package/build/qemu/2.0.1/koffi_darwin_x64.tar.gz +0 -0
  78. package/build/qemu/2.0.1/koffi_freebsd_arm64.tar.gz +0 -0
  79. package/build/qemu/2.0.1/koffi_freebsd_ia32.tar.gz +0 -0
  80. package/build/qemu/2.0.1/koffi_freebsd_x64.tar.gz +0 -0
  81. package/build/qemu/2.0.1/koffi_linux_arm32hf.tar.gz +0 -0
  82. package/build/qemu/2.0.1/koffi_linux_arm64.tar.gz +0 -0
  83. package/build/qemu/2.0.1/koffi_linux_ia32.tar.gz +0 -0
  84. package/build/qemu/2.0.1/koffi_linux_riscv64hf64.tar.gz +0 -0
  85. package/build/qemu/2.0.1/koffi_linux_x64.tar.gz +0 -0
  86. package/build/qemu/2.0.1/koffi_openbsd_ia32.tar.gz +0 -0
  87. package/build/qemu/2.0.1/koffi_openbsd_x64.tar.gz +0 -0
  88. package/build/qemu/2.0.1/koffi_win32_arm64.tar.gz +0 -0
  89. package/build/qemu/2.0.1/koffi_win32_ia32.tar.gz +0 -0
  90. package/build/qemu/2.0.1/koffi_win32_x64.tar.gz +0 -0
package/src/call.cc CHANGED
@@ -178,6 +178,15 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
178
178
  int16_t v = CopyNumber<int16_t>(value);
179
179
  *(int16_t *)dest = v;
180
180
  } break;
181
+ case PrimitiveKind::Int16S: {
182
+ if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
183
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for member '%2', expected number", GetValueType(instance, value), member.name);
184
+ return false;
185
+ }
186
+
187
+ int16_t v = CopyNumber<int16_t>(value);
188
+ *(int16_t *)dest = ReverseBytes(v);
189
+ } break;
181
190
  case PrimitiveKind::UInt16: {
182
191
  if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
183
192
  ThrowError<Napi::TypeError>(env, "Unexpected %1 value for member '%2', expected number", GetValueType(instance, value), member.name);
@@ -187,6 +196,15 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
187
196
  uint16_t v = CopyNumber<uint16_t>(value);
188
197
  *(uint16_t *)dest = v;
189
198
  } break;
199
+ case PrimitiveKind::UInt16S: {
200
+ if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
201
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for member '%2', expected number", GetValueType(instance, value), member.name);
202
+ return false;
203
+ }
204
+
205
+ uint16_t v = CopyNumber<uint16_t>(value);
206
+ *(uint16_t *)dest = ReverseBytes(v);
207
+ } break;
190
208
  case PrimitiveKind::Int32: {
191
209
  if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
192
210
  ThrowError<Napi::TypeError>(env, "Unexpected %1 value for member '%2', expected number", GetValueType(instance, value), member.name);
@@ -196,6 +214,15 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
196
214
  int32_t v = CopyNumber<int32_t>(value);
197
215
  *(int32_t *)dest = v;
198
216
  } break;
217
+ case PrimitiveKind::Int32S: {
218
+ if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
219
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for member '%2', expected number", GetValueType(instance, value), member.name);
220
+ return false;
221
+ }
222
+
223
+ int32_t v = CopyNumber<int32_t>(value);
224
+ *(int32_t *)dest = ReverseBytes(v);
225
+ } break;
199
226
  case PrimitiveKind::UInt32: {
200
227
  if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
201
228
  ThrowError<Napi::TypeError>(env, "Unexpected %1 value for member '%2', expected number", GetValueType(instance, value), member.name);
@@ -205,6 +232,15 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
205
232
  uint32_t v = CopyNumber<uint32_t>(value);
206
233
  *(uint32_t *)dest = v;
207
234
  } break;
235
+ case PrimitiveKind::UInt32S: {
236
+ if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
237
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for member '%2', expected number", GetValueType(instance, value), member.name);
238
+ return false;
239
+ }
240
+
241
+ uint32_t v = CopyNumber<uint32_t>(value);
242
+ *(uint32_t *)dest = ReverseBytes(v);
243
+ } break;
208
244
  case PrimitiveKind::Int64: {
209
245
  if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
210
246
  ThrowError<Napi::TypeError>(env, "Unexpected %1 value for member '%2', expected number", GetValueType(instance, value), member.name);
@@ -214,6 +250,15 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
214
250
  int64_t v = CopyNumber<int64_t>(value);
215
251
  *(int64_t *)dest = v;
216
252
  } break;
253
+ case PrimitiveKind::Int64S: {
254
+ if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
255
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for member '%2', expected number", GetValueType(instance, value), member.name);
256
+ return false;
257
+ }
258
+
259
+ int64_t v = CopyNumber<int64_t>(value);
260
+ *(int64_t *)dest = ReverseBytes(v);
261
+ } break;
217
262
  case PrimitiveKind::UInt64: {
218
263
  if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
219
264
  ThrowError<Napi::TypeError>(env, "Unexpected %1 value for member '%2', expected number", GetValueType(instance, value), member.name);
@@ -223,6 +268,15 @@ bool CallData::PushObject(Napi::Object obj, const TypeInfo *type, uint8_t *origi
223
268
  uint64_t v = CopyNumber<uint64_t>(value);
224
269
  *(uint64_t *)dest = v;
225
270
  } break;
271
+ case PrimitiveKind::UInt64S: {
272
+ if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
273
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for member '%2', expected number", GetValueType(instance, value), member.name);
274
+ return false;
275
+ }
276
+
277
+ uint64_t v = CopyNumber<uint64_t>(value);
278
+ *(uint64_t *)dest = ReverseBytes(v);
279
+ } break;
226
280
  case PrimitiveKind::String: {
227
281
  const char *str;
228
282
  if (RG_LIKELY(value.IsString())) {
@@ -402,36 +456,72 @@ bool CallData::PushNormalArray(Napi::Array array, Size len, const TypeInfo *ref,
402
456
  *(int16_t *)dest = v;
403
457
  });
404
458
  } break;
459
+ case PrimitiveKind::Int16S: {
460
+ PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
461
+ int16_t v = CopyNumber<int16_t>(value);
462
+ *(int16_t *)dest = ReverseBytes(v);
463
+ });
464
+ } break;
405
465
  case PrimitiveKind::UInt16: {
406
466
  PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
407
467
  uint16_t v = CopyNumber<uint16_t>(value);
408
468
  *(uint16_t *)dest = v;
409
469
  });
410
470
  } break;
471
+ case PrimitiveKind::UInt16S: {
472
+ PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
473
+ uint16_t v = CopyNumber<uint16_t>(value);
474
+ *(uint16_t *)dest = ReverseBytes(v);
475
+ });
476
+ } break;
411
477
  case PrimitiveKind::Int32: {
412
478
  PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
413
479
  int32_t v = CopyNumber<int32_t>(value);
414
480
  *(int32_t *)dest = v;
415
481
  });
416
482
  } break;
483
+ case PrimitiveKind::Int32S: {
484
+ PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
485
+ int32_t v = CopyNumber<int32_t>(value);
486
+ *(int32_t *)dest = ReverseBytes(v);
487
+ });
488
+ } break;
417
489
  case PrimitiveKind::UInt32: {
418
490
  PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
419
491
  uint32_t v = CopyNumber<uint32_t>(value);
420
492
  *(uint32_t *)dest = v;
421
493
  });
422
494
  } break;
495
+ case PrimitiveKind::UInt32S: {
496
+ PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
497
+ uint32_t v = CopyNumber<uint32_t>(value);
498
+ *(uint32_t *)dest = ReverseBytes(v);
499
+ });
500
+ } break;
423
501
  case PrimitiveKind::Int64: {
424
502
  PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
425
503
  int64_t v = CopyNumber<int64_t>(value);
426
504
  *(int64_t *)dest = v;
427
505
  });
428
506
  } break;
507
+ case PrimitiveKind::Int64S: {
508
+ PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
509
+ int64_t v = CopyNumber<int64_t>(value);
510
+ *(int64_t *)dest = ReverseBytes(v);
511
+ });
512
+ } break;
429
513
  case PrimitiveKind::UInt64: {
430
514
  PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
431
515
  uint64_t v = CopyNumber<uint64_t>(value);
432
516
  *(uint64_t *)dest = v;
433
517
  });
434
518
  } break;
519
+ case PrimitiveKind::UInt64S: {
520
+ PUSH_ARRAY(value.IsNumber() || value.IsBigInt(), "number", {
521
+ uint64_t v = CopyNumber<uint64_t>(value);
522
+ *(uint64_t *)dest = ReverseBytes(v);
523
+ });
524
+ } break;
435
525
  case PrimitiveKind::String: {
436
526
  PUSH_ARRAY(value.IsString() || IsNullOrUndefined(value), "string", {
437
527
  if (!IsNullOrUndefined(value)) {
@@ -567,24 +657,26 @@ bool CallData::PushTypedArray(Napi::TypedArray array, Size len, const TypeInfo *
567
657
  return false;
568
658
  }
569
659
 
570
- Size offset = 0;
571
660
  const uint8_t *buf = (const uint8_t *)array.ArrayBuffer().Data();
572
661
 
573
- if (RG_UNLIKELY(array.TypedArrayType() != GetTypedArrayType(ref))) {
662
+ if (RG_UNLIKELY(array.TypedArrayType() != GetTypedArrayType(ref) &&
663
+ ref != instance->void_type)) {
574
664
  ThrowError<Napi::TypeError>(env, "Cannot use %1 value for %2 array", GetValueType(instance, array), ref->name);
575
665
  return false;
576
666
  }
577
667
 
578
668
  if (realign) {
669
+ Size offset = 0;
670
+ Size size = (Size)array.ElementSize();
671
+
579
672
  for (uint32_t i = 0; i < len; i++) {
580
- int16_t align = std::max(ref->align, realign);
581
- offset = AlignLen(offset, align);
673
+ offset = AlignLen(offset, realign);
582
674
 
583
675
  uint8_t *dest = origin + offset;
676
+ const uint8_t *src = buf + i * size;
584
677
 
585
- memcpy(dest, buf + i * ref->size, ref->size);
586
-
587
- offset += ref->size;
678
+ memcpy(dest, src, size);
679
+ offset += size;
588
680
  }
589
681
  } else {
590
682
  memcpy_safe(origin, buf, (size_t)array.ByteLength());
@@ -625,6 +717,16 @@ bool CallData::PushStringArray(Napi::Value obj, const TypeInfo *type, uint8_t *o
625
717
 
626
718
  bool CallData::PushPointer(Napi::Value value, const ParameterInfo &param, void **out_ptr)
627
719
  {
720
+ const TypeInfo *type = param.type;
721
+
722
+ if (CheckValueTag(instance, value, &CastMarker)) {
723
+ Napi::External<ValueCast> external = value.As<Napi::External<ValueCast>>();
724
+ ValueCast *cast = external.Data();
725
+
726
+ value = cast->ref.Value();
727
+ type = cast->type;
728
+ }
729
+
628
730
  switch (value.Type()) {
629
731
  case napi_undefined:
630
732
  case napi_null: {
@@ -633,9 +735,11 @@ bool CallData::PushPointer(Napi::Value value, const ParameterInfo &param, void *
633
735
  } break;
634
736
 
635
737
  case napi_external: {
636
- RG_ASSERT(param.type->primitive == PrimitiveKind::Pointer);
738
+ RG_ASSERT(type->primitive == PrimitiveKind::Pointer);
637
739
 
638
- if (RG_UNLIKELY(!CheckValueTag(instance, value, param.type->ref.marker)))
740
+ if (RG_UNLIKELY(!CheckValueTag(instance, value, type->ref.marker) &&
741
+ !CheckValueTag(instance, value, instance->void_type) &&
742
+ type->ref.type != instance->void_type))
639
743
  goto unexpected;
640
744
 
641
745
  *out_ptr = value.As<Napi::External<uint8_t>>().Data();
@@ -649,12 +753,12 @@ bool CallData::PushPointer(Napi::Value value, const ParameterInfo &param, void *
649
753
  Napi::Array array = value.As<Napi::Array>();
650
754
 
651
755
  Size len = (Size)array.Length();
652
- Size size = len * param.type->ref.type->size;
756
+ Size size = len * type->ref.type->size;
653
757
 
654
758
  ptr = AllocHeap(size, 16);
655
759
 
656
760
  if (param.directions & 1) {
657
- if (!PushNormalArray(array, len, param.type->ref.type, ptr))
761
+ if (!PushNormalArray(array, len, type->ref.type, ptr))
658
762
  return false;
659
763
  } else {
660
764
  memset(ptr, 0, size);
@@ -668,27 +772,28 @@ bool CallData::PushPointer(Napi::Value value, const ParameterInfo &param, void *
668
772
  ptr = AllocHeap(size, 16);
669
773
 
670
774
  if (param.directions & 1) {
671
- if (!PushTypedArray(array, len, param.type->ref.type, ptr))
775
+ if (!PushTypedArray(array, len, type->ref.type, ptr))
672
776
  return false;
673
777
  } else {
674
- if (RG_UNLIKELY(array.TypedArrayType() != GetTypedArrayType(param.type->ref.type))) {
675
- ThrowError<Napi::TypeError>(env, "Cannot use %1 value for %2 array", GetValueType(instance, array), param.type->ref.type->name);
778
+ if (RG_UNLIKELY(array.TypedArrayType() != GetTypedArrayType(type->ref.type) &&
779
+ type->ref.type != instance->void_type)) {
780
+ ThrowError<Napi::TypeError>(env, "Cannot use %1 value for %2 array", GetValueType(instance, array), type->ref.type->name);
676
781
  return false;
677
782
  }
678
783
 
679
784
  memset(ptr, 0, size);
680
785
  }
681
- } else if (RG_LIKELY(param.type->ref.type->primitive == PrimitiveKind::Record)) {
786
+ } else if (RG_LIKELY(type->ref.type->primitive == PrimitiveKind::Record)) {
682
787
  Napi::Object obj = value.As<Napi::Object>();
683
788
  RG_ASSERT(IsObject(value));
684
789
 
685
- ptr = AllocHeap(param.type->ref.type->size, 16);
790
+ ptr = AllocHeap(type->ref.type->size, 16);
686
791
 
687
792
  if (param.directions & 1) {
688
- if (!PushObject(obj, param.type->ref.type, ptr))
793
+ if (!PushObject(obj, type->ref.type, ptr))
689
794
  return false;
690
795
  } else {
691
- memset(ptr, 0, param.type->size);
796
+ memset(ptr, 0, type->size);
692
797
  }
693
798
  } else {
694
799
  goto unexpected;
@@ -701,7 +806,7 @@ bool CallData::PushPointer(Napi::Value value, const ParameterInfo &param, void *
701
806
  RG_ASSERT(status == napi_ok);
702
807
 
703
808
  out->ptr = ptr;
704
- out->type = param.type->ref.type;
809
+ out->type = type->ref.type;
705
810
  }
706
811
 
707
812
  *out_ptr = ptr;
@@ -712,7 +817,7 @@ bool CallData::PushPointer(Napi::Value value, const ParameterInfo &param, void *
712
817
  }
713
818
 
714
819
  unexpected:
715
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected %3", GetValueType(instance, value), param.offset + 1, param.type->name);
820
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected %3", GetValueType(instance, value), param.offset + 1, type->name);
716
821
  return false;
717
822
  }
718
823
 
@@ -804,26 +909,58 @@ void CallData::PopObject(Napi::Object obj, const uint8_t *origin, const TypeInfo
804
909
  double d = (double)*(int16_t *)src;
805
910
  obj.Set(member.name, Napi::Number::New(env, d));
806
911
  } break;
912
+ case PrimitiveKind::Int16S: {
913
+ int16_t v = *(int16_t *)src;
914
+ double d = (double)ReverseBytes(v);
915
+
916
+ obj.Set(member.name, Napi::Number::New(env, d));
917
+ } break;
807
918
  case PrimitiveKind::UInt16: {
808
919
  double d = (double)*(uint16_t *)src;
809
920
  obj.Set(member.name, Napi::Number::New(env, d));
810
921
  } break;
922
+ case PrimitiveKind::UInt16S: {
923
+ uint16_t v = *(uint16_t *)src;
924
+ double d = (double)ReverseBytes(v);
925
+
926
+ obj.Set(member.name, Napi::Number::New(env, d));
927
+ } break;
811
928
  case PrimitiveKind::Int32: {
812
929
  double d = (double)*(int32_t *)src;
813
930
  obj.Set(member.name, Napi::Number::New(env, d));
814
931
  } break;
932
+ case PrimitiveKind::Int32S: {
933
+ int32_t v = *(int32_t *)src;
934
+ double d = (double)ReverseBytes(v);
935
+
936
+ obj.Set(member.name, Napi::Number::New(env, d));
937
+ } break;
815
938
  case PrimitiveKind::UInt32: {
816
939
  double d = (double)*(uint32_t *)src;
817
940
  obj.Set(member.name, Napi::Number::New(env, d));
818
941
  } break;
942
+ case PrimitiveKind::UInt32S: {
943
+ uint32_t v = *(uint32_t *)src;
944
+ double d = (double)ReverseBytes(v);
945
+
946
+ obj.Set(member.name, Napi::Number::New(env, d));
947
+ } break;
819
948
  case PrimitiveKind::Int64: {
820
949
  int64_t v = *(int64_t *)src;
821
950
  obj.Set(member.name, NewBigInt(env, v));
822
951
  } break;
952
+ case PrimitiveKind::Int64S: {
953
+ int64_t v = ReverseBytes(*(int64_t *)src);
954
+ obj.Set(member.name, NewBigInt(env, v));
955
+ } break;
823
956
  case PrimitiveKind::UInt64: {
824
957
  uint64_t v = *(uint64_t *)src;
825
958
  obj.Set(member.name, NewBigInt(env, v));
826
959
  } break;
960
+ case PrimitiveKind::UInt64S: {
961
+ uint64_t v = ReverseBytes(*(uint64_t *)src);
962
+ obj.Set(member.name, NewBigInt(env, v));
963
+ } break;
827
964
  case PrimitiveKind::String: {
828
965
  const char *str = *(const char **)src;
829
966
  obj.Set(member.name, str ? Napi::String::New(env, str) : env.Null());
@@ -924,6 +1061,14 @@ void CallData::PopNormalArray(Napi::Array array, const uint8_t *origin, const Ty
924
1061
  array.Set(i, Napi::Number::New(env, d)); \
925
1062
  }); \
926
1063
  } while (false)
1064
+ #define POP_NUMBER_ARRAY_SWAP(CType) \
1065
+ do { \
1066
+ POP_ARRAY({ \
1067
+ CType v = *(CType *)src; \
1068
+ double d = (double)ReverseBytes(v); \
1069
+ array.Set(i, Napi::Number::New(env, d)); \
1070
+ }); \
1071
+ } while (false)
927
1072
 
928
1073
  switch (ref->primitive) {
929
1074
  case PrimitiveKind::Void: { RG_UNREACHABLE(); } break;
@@ -937,21 +1082,37 @@ void CallData::PopNormalArray(Napi::Array array, const uint8_t *origin, const Ty
937
1082
  case PrimitiveKind::Int8: { POP_NUMBER_ARRAY(int8_t); } break;
938
1083
  case PrimitiveKind::UInt8: { POP_NUMBER_ARRAY(uint8_t); } break;
939
1084
  case PrimitiveKind::Int16: { POP_NUMBER_ARRAY(int16_t); } break;
1085
+ case PrimitiveKind::Int16S: { POP_NUMBER_ARRAY_SWAP(int16_t); } break;
940
1086
  case PrimitiveKind::UInt16: { POP_NUMBER_ARRAY(uint16_t); } break;
1087
+ case PrimitiveKind::UInt16S: { POP_NUMBER_ARRAY_SWAP(uint16_t); } break;
941
1088
  case PrimitiveKind::Int32: { POP_NUMBER_ARRAY(int32_t); } break;
1089
+ case PrimitiveKind::Int32S: { POP_NUMBER_ARRAY_SWAP(int32_t); } break;
942
1090
  case PrimitiveKind::UInt32: { POP_NUMBER_ARRAY(uint32_t); } break;
1091
+ case PrimitiveKind::UInt32S: { POP_NUMBER_ARRAY_SWAP(uint32_t); } break;
943
1092
  case PrimitiveKind::Int64: {
944
1093
  POP_ARRAY({
945
1094
  int64_t v = *(int64_t *)src;
946
1095
  array.Set(i, NewBigInt(env, v));
947
1096
  });
948
1097
  } break;
1098
+ case PrimitiveKind::Int64S: {
1099
+ POP_ARRAY({
1100
+ int64_t v = ReverseBytes(*(int64_t *)src);
1101
+ array.Set(i, NewBigInt(env, v));
1102
+ });
1103
+ } break;
949
1104
  case PrimitiveKind::UInt64: {
950
1105
  POP_ARRAY({
951
1106
  uint64_t v = *(uint64_t *)src;
952
1107
  array.Set(i, NewBigInt(env, v));
953
1108
  });
954
1109
  } break;
1110
+ case PrimitiveKind::UInt64S: {
1111
+ POP_ARRAY({
1112
+ uint64_t v = ReverseBytes(*(uint64_t *)src);
1113
+ array.Set(i, NewBigInt(env, v));
1114
+ });
1115
+ } break;
955
1116
  case PrimitiveKind::String: {
956
1117
  POP_ARRAY({
957
1118
  const char *str = *(const char **)src;
@@ -1009,6 +1170,7 @@ void CallData::PopNormalArray(Napi::Array array, const uint8_t *origin, const Ty
1009
1170
  case PrimitiveKind::Prototype: { RG_UNREACHABLE(); } break;
1010
1171
  }
1011
1172
 
1173
+ #undef POP_NUMBER_ARRAY_SWAP
1012
1174
  #undef POP_NUMBER_ARRAY
1013
1175
  #undef POP_ARRAY
1014
1176
  }
@@ -1016,28 +1178,49 @@ void CallData::PopNormalArray(Napi::Array array, const uint8_t *origin, const Ty
1016
1178
  void CallData::PopTypedArray(Napi::TypedArray array, const uint8_t *origin, const TypeInfo *ref, int16_t realign)
1017
1179
  {
1018
1180
  RG_ASSERT(array.IsTypedArray());
1019
- RG_ASSERT(GetTypedArrayType(ref) == array.TypedArrayType());
1181
+ RG_ASSERT(GetTypedArrayType(ref) == array.TypedArrayType() ||
1182
+ ref == instance->void_type);
1020
1183
 
1021
1184
  uint8_t *buf = (uint8_t *)array.ArrayBuffer().Data();
1022
1185
 
1023
1186
  if (realign) {
1024
1187
  Size offset = 0;
1025
1188
  Size len = (Size)array.ElementLength();
1189
+ Size size = (Size)array.ElementSize();
1026
1190
 
1027
1191
  for (Size i = 0; i < len; i++) {
1028
- int16_t align = std::max(ref->align, realign);
1029
- offset = AlignLen(offset, align);
1192
+ offset = AlignLen(offset, realign);
1030
1193
 
1031
- uint8_t *dest = buf + i * ref->size;
1194
+ uint8_t *dest = buf + i * size;
1032
1195
  const uint8_t *src = origin + offset;
1033
1196
 
1034
- memcpy(dest, src, ref->size);
1197
+ memcpy(dest, src, size);
1035
1198
 
1036
- offset += ref->size;
1199
+ offset += size;
1037
1200
  }
1038
1201
  } else {
1039
1202
  memcpy_safe(buf, origin, (size_t)array.ByteLength());
1040
1203
  }
1204
+
1205
+ #define SWAP(CType) \
1206
+ do { \
1207
+ CType *data = (CType *)buf; \
1208
+ Size len = (Size)array.ElementLength(); \
1209
+ \
1210
+ for (Size i = 0; i < len; i++) { \
1211
+ data[i] = ReverseBytes(data[i]); \
1212
+ } \
1213
+ } while (false)
1214
+
1215
+ if (ref->primitive == PrimitiveKind::Int16S || ref->primitive == PrimitiveKind::UInt16S) {
1216
+ SWAP(uint16_t);
1217
+ } else if (ref->primitive == PrimitiveKind::Int32S || ref->primitive == PrimitiveKind::UInt32S) {
1218
+ SWAP(uint32_t);
1219
+ } else if (ref->primitive == PrimitiveKind::Int64S || ref->primitive == PrimitiveKind::UInt64S) {
1220
+ SWAP(uint64_t);
1221
+ }
1222
+
1223
+ #undef SWAP
1041
1224
  }
1042
1225
 
1043
1226
  Napi::Value CallData::PopArray(const uint8_t *origin, const TypeInfo *type, int16_t realign)
@@ -1078,6 +1261,21 @@ Napi::Value CallData::PopArray(const uint8_t *origin, const TypeInfo *type, int1
1078
1261
  return array; \
1079
1262
  } \
1080
1263
  } while (false)
1264
+ #define POP_NUMBER_ARRAY_SWAP(TypedArrayType, CType) \
1265
+ do { \
1266
+ if (type->hint == TypeInfo::ArrayHint::Array) { \
1267
+ POP_ARRAY({ \
1268
+ CType v = *(CType *)src; \
1269
+ double d = (double)ReverseBytes(v); \
1270
+ array.Set(i, Napi::Number::New(env, d)); \
1271
+ }); \
1272
+ } else { \
1273
+ Napi::TypedArrayType array = Napi::TypedArrayType::New(env, len); \
1274
+ PopTypedArray(array, origin, type->ref.type, realign); \
1275
+ \
1276
+ return array; \
1277
+ } \
1278
+ } while (false)
1081
1279
 
1082
1280
  switch (type->ref.type->primitive) {
1083
1281
  case PrimitiveKind::Void: { RG_UNREACHABLE(); } break;
@@ -1115,21 +1313,37 @@ Napi::Value CallData::PopArray(const uint8_t *origin, const TypeInfo *type, int1
1115
1313
 
1116
1314
  POP_NUMBER_ARRAY(Int16Array, int16_t);
1117
1315
  } break;
1316
+ case PrimitiveKind::Int16S: { POP_NUMBER_ARRAY_SWAP(Int16Array, int16_t); } break;
1118
1317
  case PrimitiveKind::UInt16: { POP_NUMBER_ARRAY(Uint16Array, uint16_t); } break;
1318
+ case PrimitiveKind::UInt16S: { POP_NUMBER_ARRAY_SWAP(Uint16Array, uint16_t); } break;
1119
1319
  case PrimitiveKind::Int32: { POP_NUMBER_ARRAY(Int32Array, int32_t); } break;
1320
+ case PrimitiveKind::Int32S: { POP_NUMBER_ARRAY_SWAP(Int32Array, int32_t); } break;
1120
1321
  case PrimitiveKind::UInt32: { POP_NUMBER_ARRAY(Uint32Array, uint32_t); } break;
1322
+ case PrimitiveKind::UInt32S: { POP_NUMBER_ARRAY_SWAP(Uint32Array, uint32_t); } break;
1121
1323
  case PrimitiveKind::Int64: {
1122
1324
  POP_ARRAY({
1123
1325
  int64_t v = *(int64_t *)src;
1124
1326
  array.Set(i, NewBigInt(env, v));
1125
1327
  });
1126
1328
  } break;
1329
+ case PrimitiveKind::Int64S: {
1330
+ POP_ARRAY({
1331
+ int64_t v = ReverseBytes(*(int64_t *)src);
1332
+ array.Set(i, NewBigInt(env, v));
1333
+ });
1334
+ } break;
1127
1335
  case PrimitiveKind::UInt64: {
1128
1336
  POP_ARRAY({
1129
1337
  uint64_t v = *(uint64_t *)src;
1130
1338
  array.Set(i, NewBigInt(env, v));
1131
1339
  });
1132
1340
  } break;
1341
+ case PrimitiveKind::UInt64S: {
1342
+ POP_ARRAY({
1343
+ uint64_t v = ReverseBytes(*(uint64_t *)src);
1344
+ array.Set(i, NewBigInt(env, v));
1345
+ });
1346
+ } break;
1133
1347
  case PrimitiveKind::String: {
1134
1348
  POP_ARRAY({
1135
1349
  const char *str = *(const char **)src;
@@ -1175,6 +1389,7 @@ Napi::Value CallData::PopArray(const uint8_t *origin, const TypeInfo *type, int1
1175
1389
  case PrimitiveKind::Prototype: { RG_UNREACHABLE(); } break;
1176
1390
  }
1177
1391
 
1392
+ #undef POP_NUMBER_ARRAY_SWAP
1178
1393
  #undef POP_NUMBER_ARRAY
1179
1394
  #undef POP_ARRAY
1180
1395
 
package/src/call.hh CHANGED
@@ -71,9 +71,21 @@ public:
71
71
  CallData(Napi::Env env, InstanceData *instance, const FunctionInfo *func, InstanceMemory *mem);
72
72
  ~CallData();
73
73
 
74
- bool Prepare(const Napi::CallbackInfo &info);
75
- void Execute();
76
- Napi::Value Complete();
74
+ #ifdef UNITY_BUILD
75
+ #ifdef _MSC_VER
76
+ #define INLINE_IF_UNITY __forceinline
77
+ #else
78
+ #define INLINE_IF_UNITY __attribute__((always_inline)) inline
79
+ #endif
80
+ #else
81
+ #define INLINE_IF_UNITY
82
+ #endif
83
+
84
+ INLINE_IF_UNITY bool Prepare(const Napi::CallbackInfo &info);
85
+ INLINE_IF_UNITY void Execute();
86
+ INLINE_IF_UNITY Napi::Value Complete();
87
+
88
+ #undef INLINE_IF_UNITY
77
89
 
78
90
  void Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegisters *out_reg);
79
91