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/abi_arm64.cc CHANGED
@@ -151,11 +151,17 @@ bool AnalyseFunction(Napi::Env, InstanceData *, FunctionInfo *func)
151
151
  case PrimitiveKind::Int8:
152
152
  case PrimitiveKind::UInt8:
153
153
  case PrimitiveKind::Int16:
154
+ case PrimitiveKind::Int16S:
154
155
  case PrimitiveKind::UInt16:
156
+ case PrimitiveKind::UInt16S:
155
157
  case PrimitiveKind::Int32:
158
+ case PrimitiveKind::Int32S:
156
159
  case PrimitiveKind::UInt32:
160
+ case PrimitiveKind::UInt32S:
157
161
  case PrimitiveKind::Int64:
162
+ case PrimitiveKind::Int64S:
158
163
  case PrimitiveKind::UInt64:
164
+ case PrimitiveKind::UInt64S:
159
165
  case PrimitiveKind::String:
160
166
  case PrimitiveKind::String16:
161
167
  case PrimitiveKind::Pointer:
@@ -259,6 +265,64 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
259
265
  gpr_ptr[8] = (uint64_t)return_ptr;
260
266
  }
261
267
 
268
+ #ifdef __APPLE__
269
+ #define PUSH_INTEGER(CType) \
270
+ do { \
271
+ if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) { \
272
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), param.offset + 1); \
273
+ return false; \
274
+ } \
275
+ \
276
+ CType v = CopyNumber<CType>(value); \
277
+ \
278
+ if (RG_LIKELY(param.gpr_count)) { \
279
+ *(gpr_ptr++) = (uint64_t)v; \
280
+ } else { \
281
+ args_ptr = AlignUp(args_ptr, param.type->align); \
282
+ *args_ptr = (uint64_t)v; \
283
+ args_ptr = (uint64_t *)((uint8_t *)args_ptr + param.type->size); \
284
+ } \
285
+ } while (false)
286
+ #define PUSH_INTEGER_SWAP(CType) \
287
+ do { \
288
+ if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) { \
289
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), param.offset + 1); \
290
+ return false; \
291
+ } \
292
+ \
293
+ CType v = CopyNumber<CType>(value); \
294
+ \
295
+ if (RG_LIKELY(param.gpr_count)) { \
296
+ *(gpr_ptr++) = (uint64_t)ReverseBytes(v); \
297
+ } else { \
298
+ args_ptr = AlignUp(args_ptr, param.type->align); \
299
+ *args_ptr = (uint64_t)ReverseBytes(v); \
300
+ args_ptr = (uint64_t *)((uint8_t *)args_ptr + param.type->size); \
301
+ } \
302
+ } while (false)
303
+ #else
304
+ #define PUSH_INTEGER(CType) \
305
+ do { \
306
+ if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) { \
307
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), param.offset + 1); \
308
+ return false; \
309
+ } \
310
+ \
311
+ CType v = CopyNumber<CType>(value); \
312
+ *((param.gpr_count ? gpr_ptr : args_ptr)++) = (uint64_t)v; \
313
+ } while (false)
314
+ #define PUSH_INTEGER_SWAP(CType) \
315
+ do { \
316
+ if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) { \
317
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), param.offset + 1); \
318
+ return false; \
319
+ } \
320
+ \
321
+ CType v = CopyNumber<CType>(value); \
322
+ *((param.gpr_count ? gpr_ptr : args_ptr)++) = (uint64_t)ReverseBytes(v); \
323
+ } while (false)
324
+ #endif
325
+
262
326
  // Push arguments
263
327
  for (Size i = 0; i < func->parameters.len; i++) {
264
328
  const ParameterInfo &param = func->parameters[i];
@@ -288,45 +352,20 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
288
352
  *((param.gpr_count ? gpr_ptr : args_ptr)++) = (uint64_t)b;
289
353
  #endif
290
354
  } break;
291
- case PrimitiveKind::Int8:
292
- case PrimitiveKind::UInt8:
293
- case PrimitiveKind::Int16:
294
- case PrimitiveKind::UInt16:
295
- case PrimitiveKind::Int32:
296
- case PrimitiveKind::UInt32:
297
- case PrimitiveKind::Int64: {
298
- if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
299
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), param.offset + 1);
300
- return false;
301
- }
302
-
303
- int64_t v = CopyNumber<int64_t>(value);
304
-
305
- #ifdef __APPLE__
306
- if (RG_LIKELY(param.gpr_count)) {
307
- *(int64_t *)(gpr_ptr++) = v;
308
- } else {
309
- args_ptr = AlignUp(args_ptr, param.type->align);
310
- *(int64_t *)args_ptr = v;
311
- args_ptr = (uint64_t *)((uint8_t *)args_ptr + param.type->size);
312
- }
313
- #else
314
- *(int64_t *)((param.gpr_count ? gpr_ptr : args_ptr)++) = v;
315
- #endif
316
- } break;
317
- case PrimitiveKind::UInt64: {
318
- if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
319
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), param.offset + 1);
320
- return false;
321
- }
322
-
323
- uint64_t v = CopyNumber<uint64_t>(value);
324
-
325
- #ifdef __APPLE__
326
- args_ptr = param.gpr_count ? args_ptr : AlignUp(args_ptr, 8);
327
- #endif
328
- *((param.gpr_count ? gpr_ptr : args_ptr)++) = v;
329
- } break;
355
+ case PrimitiveKind::Int8: { PUSH_INTEGER(int8_t); } break;
356
+ case PrimitiveKind::UInt8: { PUSH_INTEGER(uint8_t); } break;
357
+ case PrimitiveKind::Int16: { PUSH_INTEGER(int16_t); } break;
358
+ case PrimitiveKind::Int16S: { PUSH_INTEGER_SWAP(int16_t); } break;
359
+ case PrimitiveKind::UInt16: { PUSH_INTEGER(uint16_t); } break;
360
+ case PrimitiveKind::UInt16S: { PUSH_INTEGER_SWAP(uint16_t); } break;
361
+ case PrimitiveKind::Int32: { PUSH_INTEGER(int32_t); } break;
362
+ case PrimitiveKind::Int32S: { PUSH_INTEGER_SWAP(int32_t); } break;
363
+ case PrimitiveKind::UInt32: { PUSH_INTEGER(uint32_t); } break;
364
+ case PrimitiveKind::UInt32S: { PUSH_INTEGER_SWAP(uint32_t); } break;
365
+ case PrimitiveKind::Int64: { PUSH_INTEGER(int64_t); } break;
366
+ case PrimitiveKind::Int64S: { PUSH_INTEGER_SWAP(int64_t); } break;
367
+ case PrimitiveKind::UInt64: { PUSH_INTEGER(uint64_t); } break;
368
+ case PrimitiveKind::UInt64S: { PUSH_INTEGER_SWAP(uint64_t); } break;
330
369
  case PrimitiveKind::String: {
331
370
  const char *str;
332
371
  if (RG_LIKELY(value.IsString())) {
@@ -496,6 +535,9 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
496
535
  }
497
536
  }
498
537
 
538
+ #undef PUSH_INTEGER_SWAP
539
+ #undef PUSH_INTEGER
540
+
499
541
  new_sp = mem->stack.end();
500
542
 
501
543
  return true;
@@ -519,11 +561,17 @@ void CallData::Execute()
519
561
  case PrimitiveKind::Int8:
520
562
  case PrimitiveKind::UInt8:
521
563
  case PrimitiveKind::Int16:
564
+ case PrimitiveKind::Int16S:
522
565
  case PrimitiveKind::UInt16:
566
+ case PrimitiveKind::UInt16S:
523
567
  case PrimitiveKind::Int32:
568
+ case PrimitiveKind::Int32S:
524
569
  case PrimitiveKind::UInt32:
570
+ case PrimitiveKind::UInt32S:
525
571
  case PrimitiveKind::Int64:
572
+ case PrimitiveKind::Int64S:
526
573
  case PrimitiveKind::UInt64:
574
+ case PrimitiveKind::UInt64S:
527
575
  case PrimitiveKind::String:
528
576
  case PrimitiveKind::String16:
529
577
  case PrimitiveKind::Pointer:
@@ -565,11 +613,17 @@ Napi::Value CallData::Complete()
565
613
  case PrimitiveKind::Int8: return Napi::Number::New(env, (double)result.i8);
566
614
  case PrimitiveKind::UInt8: return Napi::Number::New(env, (double)result.u8);
567
615
  case PrimitiveKind::Int16: return Napi::Number::New(env, (double)result.i16);
616
+ case PrimitiveKind::Int16S: return Napi::Number::New(env, (double)ReverseBytes(result.i16));
568
617
  case PrimitiveKind::UInt16: return Napi::Number::New(env, (double)result.u16);
618
+ case PrimitiveKind::UInt16S: return Napi::Number::New(env, (double)ReverseBytes(result.u16));
569
619
  case PrimitiveKind::Int32: return Napi::Number::New(env, (double)result.i32);
620
+ case PrimitiveKind::Int32S: return Napi::Number::New(env, (double)ReverseBytes(result.i32));
570
621
  case PrimitiveKind::UInt32: return Napi::Number::New(env, (double)result.u32);
622
+ case PrimitiveKind::UInt32S: return Napi::Number::New(env, (double)ReverseBytes(result.u32));
571
623
  case PrimitiveKind::Int64: return NewBigInt(env, result.i64);
624
+ case PrimitiveKind::Int64S: return NewBigInt(env, ReverseBytes(result.i64));
572
625
  case PrimitiveKind::UInt64: return NewBigInt(env, result.u64);
626
+ case PrimitiveKind::UInt64S: return NewBigInt(env, ReverseBytes(result.u64));
573
627
  case PrimitiveKind::String: return result.ptr ? Napi::String::New(env, (const char *)result.ptr) : env.Null();
574
628
  case PrimitiveKind::String16: return result.ptr ? Napi::String::New(env, (const char16_t *)result.ptr) : env.Null();
575
629
  case PrimitiveKind::Pointer:
@@ -703,6 +757,28 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
703
757
  Napi::Value arg = Napi::Number::New(env, d);
704
758
  arguments.Append(arg);
705
759
  } break;
760
+ case PrimitiveKind::Int16S: {
761
+ #ifdef __APPLE__
762
+ double d;
763
+ if (param.gpr_count) {
764
+ int16_t v = *(int16_t *)(gpr_ptr++);
765
+ d = (double)ReverseBytes(v);
766
+ } else {
767
+ args_ptr = AlignUp(args_ptr, 2);
768
+
769
+ int16_t v = *(int16_t *)args_ptr;
770
+ d = (double)ReverseBytes(v);
771
+
772
+ args_ptr = (uint64_t *)((uint8_t *)args_ptr + 2);
773
+ }
774
+ #else
775
+ int16_t v = *(int16_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
776
+ double d = (double)ReverseBytes(v);
777
+ #endif
778
+
779
+ Napi::Value arg = Napi::Number::New(env, d);
780
+ arguments.Append(arg);
781
+ } break;
706
782
  case PrimitiveKind::UInt16: {
707
783
  #ifdef __APPLE__
708
784
  double d;
@@ -720,6 +796,28 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
720
796
  Napi::Value arg = Napi::Number::New(env, d);
721
797
  arguments.Append(arg);
722
798
  } break;
799
+ case PrimitiveKind::UInt16S: {
800
+ #ifdef __APPLE__
801
+ double d;
802
+ if (param.gpr_count) {
803
+ uint16_t v = *(uint16_t *)(gpr_ptr++);
804
+ d = (double)ReverseBytes(v);
805
+ } else {
806
+ args_ptr = AlignUp(args_ptr, 2);
807
+
808
+ uint16_t v = *(uint16_t *)args_ptr;
809
+ d = (double)ReverseBytes(v);
810
+
811
+ args_ptr = (uint64_t *)((uint8_t *)args_ptr + 2);
812
+ }
813
+ #else
814
+ uint16_t v = *(uint16_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
815
+ double d = (double)ReverseBytes(v);
816
+ #endif
817
+
818
+ Napi::Value arg = Napi::Number::New(env, d);
819
+ arguments.Append(arg);
820
+ } break;
723
821
  case PrimitiveKind::Int32: {
724
822
  #ifdef __APPLE__
725
823
  double d;
@@ -737,6 +835,28 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
737
835
  Napi::Value arg = Napi::Number::New(env, d);
738
836
  arguments.Append(arg);
739
837
  } break;
838
+ case PrimitiveKind::Int32S: {
839
+ #ifdef __APPLE__
840
+ double d;
841
+ if (param.gpr_count) {
842
+ int32_t v = *(int32_t *)(gpr_ptr++);
843
+ d = (double)ReverseBytes(v);
844
+ } else {
845
+ args_ptr = AlignUp(args_ptr, 4);
846
+
847
+ int32_t v = *(int32_t *)args_ptr;
848
+ d = (double)ReverseBytes(v);
849
+
850
+ args_ptr = (uint64_t *)((uint8_t *)args_ptr + 4);
851
+ }
852
+ #else
853
+ int32_t v = *(int32_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
854
+ double d = (double)ReverseBytes(v);
855
+ #endif
856
+
857
+ Napi::Value arg = Napi::Number::New(env, d);
858
+ arguments.Append(arg);
859
+ } break;
740
860
  case PrimitiveKind::UInt32: {
741
861
  #ifdef __APPLE__
742
862
  double d;
@@ -754,6 +874,28 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
754
874
  Napi::Value arg = Napi::Number::New(env, d);
755
875
  arguments.Append(arg);
756
876
  } break;
877
+ case PrimitiveKind::UInt32S: {
878
+ #ifdef __APPLE__
879
+ double d;
880
+ if (param.gpr_count) {
881
+ uint32_t v = *(uint32_t *)(gpr_ptr++);
882
+ d = (double)ReverseBytes(v);
883
+ } else {
884
+ args_ptr = AlignUp(args_ptr, 4);
885
+
886
+ uint32_t v = *(uint32_t *)args_ptr;
887
+ d = (double)ReverseBytes(v);
888
+
889
+ args_ptr = (uint64_t *)((uint8_t *)args_ptr + 4);
890
+ }
891
+ #else
892
+ uint32_t v = *(uint32_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
893
+ double d = (double)ReverseBytes(v);
894
+ #endif
895
+
896
+ Napi::Value arg = Napi::Number::New(env, d);
897
+ arguments.Append(arg);
898
+ } break;
757
899
  case PrimitiveKind::Int64: {
758
900
  #ifdef __APPLE__
759
901
  args_ptr = AlignUp(args_ptr, 8);
@@ -764,6 +906,16 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
764
906
  Napi::Value arg = NewBigInt(env, v);
765
907
  arguments.Append(arg);
766
908
  } break;
909
+ case PrimitiveKind::Int64S: {
910
+ #ifdef __APPLE__
911
+ args_ptr = AlignUp(args_ptr, 8);
912
+ #endif
913
+
914
+ int64_t v = *(int64_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
915
+
916
+ Napi::Value arg = NewBigInt(env, ReverseBytes(v));
917
+ arguments.Append(arg);
918
+ } break;
767
919
  case PrimitiveKind::UInt64: {
768
920
  #ifdef __APPLE__
769
921
  args_ptr = AlignUp(args_ptr, 8);
@@ -774,6 +926,16 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
774
926
  Napi::Value arg = NewBigInt(env, v);
775
927
  arguments.Append(arg);
776
928
  } break;
929
+ case PrimitiveKind::UInt64S: {
930
+ #ifdef __APPLE__
931
+ args_ptr = AlignUp(args_ptr, 8);
932
+ #endif
933
+
934
+ uint64_t v = *(uint64_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
935
+
936
+ Napi::Value arg = NewBigInt(env, ReverseBytes(v));
937
+ arguments.Append(arg);
938
+ } break;
777
939
  case PrimitiveKind::String: {
778
940
  #ifdef __APPLE__
779
941
  args_ptr = AlignUp(args_ptr, 8);
@@ -912,6 +1074,27 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
912
1074
  if (RG_UNLIKELY(env.IsExceptionPending()))
913
1075
  return;
914
1076
 
1077
+ #define RETURN_INTEGER(CType) \
1078
+ do { \
1079
+ if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) { \
1080
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for return value, expected number", GetValueType(instance, value)); \
1081
+ return; \
1082
+ } \
1083
+ \
1084
+ CType v = CopyNumber<CType>(value); \
1085
+ out_reg->x0 = (uint64_t)v; \
1086
+ } while (false)
1087
+ #define RETURN_INTEGER_SWAP(CType) \
1088
+ do { \
1089
+ if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) { \
1090
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for return value, expected number", GetValueType(instance, value)); \
1091
+ return; \
1092
+ } \
1093
+ \
1094
+ CType v = CopyNumber<CType>(value); \
1095
+ out_reg->x0 = (uint64_t)ReverseBytes(v); \
1096
+ } while (false)
1097
+
915
1098
  // Convert the result
916
1099
  switch (type->primitive) {
917
1100
  case PrimitiveKind::Void: {} break;
@@ -924,22 +1107,20 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
924
1107
  bool b = value.As<Napi::Boolean>();
925
1108
  out_reg->x0 = (uint64_t)b;
926
1109
  } break;
927
- case PrimitiveKind::Int8:
928
- case PrimitiveKind::UInt8:
929
- case PrimitiveKind::Int16:
930
- case PrimitiveKind::UInt16:
931
- case PrimitiveKind::Int32:
932
- case PrimitiveKind::UInt32:
933
- case PrimitiveKind::Int64:
934
- case PrimitiveKind::UInt64: {
935
- if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
936
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for return value, expected number", GetValueType(instance, value));
937
- return;
938
- }
939
-
940
- int64_t v = CopyNumber<int64_t>(value);
941
- out_reg->x0 = (uint64_t)v;
942
- } break;
1110
+ case PrimitiveKind::Int8: { RETURN_INTEGER(int8_t); } break;
1111
+ case PrimitiveKind::UInt8: { RETURN_INTEGER(uint8_t); } break;
1112
+ case PrimitiveKind::Int16: { RETURN_INTEGER(int16_t); } break;
1113
+ case PrimitiveKind::Int16S: { RETURN_INTEGER_SWAP(int16_t); } break;
1114
+ case PrimitiveKind::UInt16: { RETURN_INTEGER(uint16_t); } break;
1115
+ case PrimitiveKind::UInt16S: { RETURN_INTEGER_SWAP(uint16_t); } break;
1116
+ case PrimitiveKind::Int32: { RETURN_INTEGER(int32_t); } break;
1117
+ case PrimitiveKind::Int32S: { RETURN_INTEGER_SWAP(int32_t); } break;
1118
+ case PrimitiveKind::UInt32: { RETURN_INTEGER(uint32_t); } break;
1119
+ case PrimitiveKind::UInt32S: { RETURN_INTEGER_SWAP(uint32_t); } break;
1120
+ case PrimitiveKind::Int64: { RETURN_INTEGER(int64_t); } break;
1121
+ case PrimitiveKind::Int64S: { RETURN_INTEGER_SWAP(int64_t); } break;
1122
+ case PrimitiveKind::UInt64: { RETURN_INTEGER(uint64_t); } break;
1123
+ case PrimitiveKind::UInt64S: { RETURN_INTEGER_SWAP(uint64_t); } break;
943
1124
  case PrimitiveKind::String: {
944
1125
  const char *str;
945
1126
  if (RG_LIKELY(value.IsString())) {
@@ -1054,6 +1235,9 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
1054
1235
  case PrimitiveKind::Prototype: { RG_UNREACHABLE(); } break;
1055
1236
  }
1056
1237
 
1238
+ #undef RETURN_INTEGER_SWAP
1239
+ #undef RETURN_INTEGER
1240
+
1057
1241
  err_guard.Disable();
1058
1242
  }
1059
1243
 
@@ -216,6 +216,27 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
216
216
  *(uint8_t **)(gpr_ptr++) = return_ptr;
217
217
  }
218
218
 
219
+ #define PUSH_INTEGER(CType) \
220
+ do { \
221
+ if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) { \
222
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), param.offset + 1); \
223
+ return false; \
224
+ } \
225
+ \
226
+ CType v = CopyNumber<CType>(value); \
227
+ *((param.gpr_count ? gpr_ptr : args_ptr)++) = (uint64_t)v; \
228
+ } while (false)
229
+ #define PUSH_INTEGER_SWAP(CType) \
230
+ do { \
231
+ if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) { \
232
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), param.offset + 1); \
233
+ return false; \
234
+ } \
235
+ \
236
+ CType v = CopyNumber<CType>(value); \
237
+ *((param.gpr_count ? gpr_ptr : args_ptr)++) = (uint64_t)ReverseBytes(v); \
238
+ } while (false)
239
+
219
240
  // Push arguments
220
241
  for (Size i = 0; i < func->parameters.len; i++) {
221
242
  const ParameterInfo &param = func->parameters[i];
@@ -235,30 +256,20 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
235
256
  bool b = value.As<Napi::Boolean>();
236
257
  *((param.gpr_count ? gpr_ptr : args_ptr)++) = (uint64_t)b;
237
258
  } break;
238
- case PrimitiveKind::Int8:
239
- case PrimitiveKind::Int16:
240
- case PrimitiveKind::Int32:
241
- case PrimitiveKind::Int64: {
242
- if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
243
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), param.offset + 1);
244
- return false;
245
- }
246
-
247
- int64_t v = CopyNumber<int64_t>(value);
248
- *(int64_t *)((param.gpr_count ? gpr_ptr : args_ptr)++) = v;
249
- } break;
250
- case PrimitiveKind::UInt8:
251
- case PrimitiveKind::UInt16:
252
- case PrimitiveKind::UInt32:
253
- case PrimitiveKind::UInt64: {
254
- if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
255
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), param.offset + 1);
256
- return false;
257
- }
258
-
259
- uint64_t v = CopyNumber<uint64_t>(value);
260
- *((param.gpr_count ? gpr_ptr : args_ptr)++) = v;
261
- } break;
259
+ case PrimitiveKind::Int8: { PUSH_INTEGER(int8_t); } break;
260
+ case PrimitiveKind::UInt8: { PUSH_INTEGER(uint8_t); } break;
261
+ case PrimitiveKind::Int16: { PUSH_INTEGER(int16_t); } break;
262
+ case PrimitiveKind::Int16S: { PUSH_INTEGER_SWAP(int16_t); } break;
263
+ case PrimitiveKind::UInt16: { PUSH_INTEGER(uint16_t); } break;
264
+ case PrimitiveKind::UInt16S: { PUSH_INTEGER_SWAP(uint16_t); } break;
265
+ case PrimitiveKind::Int32: { PUSH_INTEGER(int32_t); } break;
266
+ case PrimitiveKind::Int32S: { PUSH_INTEGER_SWAP(int32_t); } break;
267
+ case PrimitiveKind::UInt32: { PUSH_INTEGER(uint32_t); } break;
268
+ case PrimitiveKind::UInt32S: { PUSH_INTEGER_SWAP(uint32_t); } break;
269
+ case PrimitiveKind::Int64: { PUSH_INTEGER(int64_t); } break;
270
+ case PrimitiveKind::Int64S: { PUSH_INTEGER_SWAP(int64_t); } break;
271
+ case PrimitiveKind::UInt64: { PUSH_INTEGER(uint64_t); } break;
272
+ case PrimitiveKind::UInt64S: { PUSH_INTEGER_SWAP(uint64_t); } break;
262
273
  case PrimitiveKind::String: {
263
274
  const char *str;
264
275
  if (RG_LIKELY(value.IsString())) {
@@ -405,6 +416,9 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
405
416
  }
406
417
  }
407
418
 
419
+ #undef PUSH_INTEGER_SWAP
420
+ #undef PUSH_INTEGER
421
+
408
422
  new_sp = mem->stack.end();
409
423
 
410
424
  return true;
@@ -428,11 +442,17 @@ void CallData::Execute()
428
442
  case PrimitiveKind::Int8:
429
443
  case PrimitiveKind::UInt8:
430
444
  case PrimitiveKind::Int16:
445
+ case PrimitiveKind::Int16S:
431
446
  case PrimitiveKind::UInt16:
447
+ case PrimitiveKind::UInt16S:
432
448
  case PrimitiveKind::Int32:
449
+ case PrimitiveKind::Int32S:
433
450
  case PrimitiveKind::UInt32:
451
+ case PrimitiveKind::UInt32S:
434
452
  case PrimitiveKind::Int64:
453
+ case PrimitiveKind::Int64S:
435
454
  case PrimitiveKind::UInt64:
455
+ case PrimitiveKind::UInt64S:
436
456
  case PrimitiveKind::String:
437
457
  case PrimitiveKind::String16:
438
458
  case PrimitiveKind::Pointer:
@@ -478,11 +498,17 @@ Napi::Value CallData::Complete()
478
498
  case PrimitiveKind::Int8: return Napi::Number::New(env, (double)result.i8);
479
499
  case PrimitiveKind::UInt8: return Napi::Number::New(env, (double)result.u8);
480
500
  case PrimitiveKind::Int16: return Napi::Number::New(env, (double)result.i16);
501
+ case PrimitiveKind::Int16S: return Napi::Number::New(env, (double)ReverseBytes(result.i16));
481
502
  case PrimitiveKind::UInt16: return Napi::Number::New(env, (double)result.u16);
503
+ case PrimitiveKind::UInt16S: return Napi::Number::New(env, (double)ReverseBytes(result.u16));
482
504
  case PrimitiveKind::Int32: return Napi::Number::New(env, (double)result.i32);
505
+ case PrimitiveKind::Int32S: return Napi::Number::New(env, (double)ReverseBytes(result.i32));
483
506
  case PrimitiveKind::UInt32: return Napi::Number::New(env, (double)result.u32);
507
+ case PrimitiveKind::UInt32S: return Napi::Number::New(env, (double)ReverseBytes(result.u32));
484
508
  case PrimitiveKind::Int64: return NewBigInt(env, result.i64);
509
+ case PrimitiveKind::Int64S: return NewBigInt(env, ReverseBytes(result.i64));
485
510
  case PrimitiveKind::UInt64: return NewBigInt(env, result.u64);
511
+ case PrimitiveKind::UInt64S: return NewBigInt(env, ReverseBytes(result.u64));
486
512
  case PrimitiveKind::String: return result.ptr ? Napi::String::New(env, (const char *)result.ptr) : env.Null();
487
513
  case PrimitiveKind::String16: return result.ptr ? Napi::String::New(env, (const char16_t *)result.ptr) : env.Null();
488
514
  case PrimitiveKind::Pointer:
@@ -576,36 +602,76 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
576
602
  Napi::Value arg = Napi::Number::New(env, d);
577
603
  arguments.Append(arg);
578
604
  } break;
605
+ case PrimitiveKind::Int16S: {
606
+ int16_t v = *(int16_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
607
+ double d = (double)ReverseBytes(v);
608
+
609
+ Napi::Value arg = Napi::Number::New(env, d);
610
+ arguments.Append(arg);
611
+ } break;
579
612
  case PrimitiveKind::UInt16: {
580
613
  double d = (double)*(uint16_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
581
614
 
582
615
  Napi::Value arg = Napi::Number::New(env, d);
583
616
  arguments.Append(arg);
584
617
  } break;
618
+ case PrimitiveKind::UInt16S: {
619
+ uint16_t v = *(uint16_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
620
+ double d = (double)ReverseBytes(v);
621
+
622
+ Napi::Value arg = Napi::Number::New(env, d);
623
+ arguments.Append(arg);
624
+ } break;
585
625
  case PrimitiveKind::Int32: {
586
626
  double d = (double)*(int32_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
587
627
 
588
628
  Napi::Value arg = Napi::Number::New(env, d);
589
629
  arguments.Append(arg);
590
630
  } break;
631
+ case PrimitiveKind::Int32S: {
632
+ int32_t v = *(int32_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
633
+ double d = (double)ReverseBytes(v);
634
+
635
+ Napi::Value arg = Napi::Number::New(env, d);
636
+ arguments.Append(arg);
637
+ } break;
591
638
  case PrimitiveKind::UInt32: {
592
639
  double d = (double)*(uint32_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
593
640
 
594
641
  Napi::Value arg = Napi::Number::New(env, d);
595
642
  arguments.Append(arg);
596
643
  } break;
644
+ case PrimitiveKind::UInt32S: {
645
+ uint32_t v = *(uint32_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
646
+ double d = (double)ReverseBytes(v);
647
+
648
+ Napi::Value arg = Napi::Number::New(env, d);
649
+ arguments.Append(arg);
650
+ } break;
597
651
  case PrimitiveKind::Int64: {
598
652
  int64_t v = *(int64_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
599
653
 
600
654
  Napi::Value arg = NewBigInt(env, v);
601
655
  arguments.Append(arg);
602
656
  } break;
657
+ case PrimitiveKind::Int64S: {
658
+ int64_t v = *(int64_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
659
+
660
+ Napi::Value arg = NewBigInt(env, ReverseBytes(v));
661
+ arguments.Append(arg);
662
+ } break;
603
663
  case PrimitiveKind::UInt64: {
604
664
  uint64_t v = *(uint64_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
605
665
 
606
666
  Napi::Value arg = NewBigInt(env, v);
607
667
  arguments.Append(arg);
608
668
  } break;
669
+ case PrimitiveKind::UInt64S: {
670
+ uint64_t v = *(uint64_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
671
+
672
+ Napi::Value arg = NewBigInt(env, ReverseBytes(v));
673
+ arguments.Append(arg);
674
+ } break;
609
675
  case PrimitiveKind::String: {
610
676
  const char *str = *(const char **)((param.gpr_count ? gpr_ptr : args_ptr)++);
611
677
 
@@ -716,6 +782,27 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
716
782
  if (RG_UNLIKELY(env.IsExceptionPending()))
717
783
  return;
718
784
 
785
+ #define RETURN_INTEGER(CType) \
786
+ do { \
787
+ if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) { \
788
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for return value, expected number", GetValueType(instance, value)); \
789
+ return; \
790
+ } \
791
+ \
792
+ CType v = CopyNumber<CType>(value); \
793
+ out_reg->a0 = (uint64_t)v; \
794
+ } while (false)
795
+ #define RETURN_INTEGER_SWAP(CType) \
796
+ do { \
797
+ if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) { \
798
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for return value, expected number", GetValueType(instance, value)); \
799
+ return; \
800
+ } \
801
+ \
802
+ CType v = CopyNumber<CType>(value); \
803
+ out_reg->a0 = (uint64_t)ReverseBytes(v); \
804
+ } while (false)
805
+
719
806
  // Convert the result
720
807
  switch (type->primitive) {
721
808
  case PrimitiveKind::Void: {} break;
@@ -728,22 +815,20 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
728
815
  bool b = value.As<Napi::Boolean>();
729
816
  out_reg->a0 = (uint64_t)b;
730
817
  } break;
731
- case PrimitiveKind::Int8:
732
- case PrimitiveKind::UInt8:
733
- case PrimitiveKind::Int16:
734
- case PrimitiveKind::UInt16:
735
- case PrimitiveKind::Int32:
736
- case PrimitiveKind::UInt32:
737
- case PrimitiveKind::Int64:
738
- case PrimitiveKind::UInt64: {
739
- if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
740
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for return value, expected number", GetValueType(instance, value));
741
- return;
742
- }
743
-
744
- int64_t v = CopyNumber<int64_t>(value);
745
- out_reg->a0 = (uint64_t)v;
746
- } break;
818
+ case PrimitiveKind::Int8: { RETURN_INTEGER(int8_t); } break;
819
+ case PrimitiveKind::UInt8: { RETURN_INTEGER(uint8_t); } break;
820
+ case PrimitiveKind::Int16: { RETURN_INTEGER(int16_t); } break;
821
+ case PrimitiveKind::Int16S: { RETURN_INTEGER_SWAP(int16_t); } break;
822
+ case PrimitiveKind::UInt16: { RETURN_INTEGER(uint16_t); } break;
823
+ case PrimitiveKind::UInt16S: { RETURN_INTEGER_SWAP(uint16_t); } break;
824
+ case PrimitiveKind::Int32: { RETURN_INTEGER(int32_t); } break;
825
+ case PrimitiveKind::Int32S: { RETURN_INTEGER_SWAP(int32_t); } break;
826
+ case PrimitiveKind::UInt32: { RETURN_INTEGER(uint32_t); } break;
827
+ case PrimitiveKind::UInt32S: { RETURN_INTEGER_SWAP(uint32_t); } break;
828
+ case PrimitiveKind::Int64: { RETURN_INTEGER(int64_t); } break;
829
+ case PrimitiveKind::Int64S: { RETURN_INTEGER_SWAP(int64_t); } break;
830
+ case PrimitiveKind::UInt64: { RETURN_INTEGER(uint64_t); } break;
831
+ case PrimitiveKind::UInt64S: { RETURN_INTEGER_SWAP(uint64_t); } break;
747
832
  case PrimitiveKind::String: {
748
833
  const char *str;
749
834
  if (RG_LIKELY(value.IsString())) {
@@ -857,6 +942,9 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
857
942
  case PrimitiveKind::Prototype: { RG_UNREACHABLE(); } break;
858
943
  }
859
944
 
945
+ #undef RETURN_INTEGER_SWAP
946
+ #undef RETURN_INTEGER
947
+
860
948
  err_guard.Disable();
861
949
  }
862
950