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_arm32.cc CHANGED
@@ -155,9 +155,13 @@ bool AnalyseFunction(Napi::Env, InstanceData *, FunctionInfo *func)
155
155
  case PrimitiveKind::Int8:
156
156
  case PrimitiveKind::UInt8:
157
157
  case PrimitiveKind::Int16:
158
+ case PrimitiveKind::Int16S:
158
159
  case PrimitiveKind::UInt16:
160
+ case PrimitiveKind::UInt16S:
159
161
  case PrimitiveKind::Int32:
162
+ case PrimitiveKind::Int32S:
160
163
  case PrimitiveKind::UInt32:
164
+ case PrimitiveKind::UInt32S:
161
165
  case PrimitiveKind::String:
162
166
  case PrimitiveKind::String16:
163
167
  case PrimitiveKind::Pointer:
@@ -170,7 +174,9 @@ bool AnalyseFunction(Napi::Env, InstanceData *, FunctionInfo *func)
170
174
  }
171
175
  } break;
172
176
  case PrimitiveKind::Int64:
173
- case PrimitiveKind::UInt64: {
177
+ case PrimitiveKind::Int64S:
178
+ case PrimitiveKind::UInt64:
179
+ case PrimitiveKind::UInt64S: {
174
180
  bool realign = gpr_avail % 2;
175
181
  int need = 2 + realign;
176
182
 
@@ -269,6 +275,65 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
269
275
  *(uint8_t **)(gpr_ptr++) = return_ptr;
270
276
  }
271
277
 
278
+ #define PUSH_INTEGER_32(CType) \
279
+ do { \
280
+ if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) { \
281
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), param.offset + 1); \
282
+ return false; \
283
+ } \
284
+ \
285
+ CType v = CopyNumber<CType>(value); \
286
+ *((param.gpr_count ? gpr_ptr : args_ptr)++) = (uint32_t)v; \
287
+ } while (false)
288
+ #define PUSH_INTEGER_32_SWAP(CType) \
289
+ do { \
290
+ if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) { \
291
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), param.offset + 1); \
292
+ return false; \
293
+ } \
294
+ \
295
+ CType v = CopyNumber<CType>(value); \
296
+ *((param.gpr_count ? gpr_ptr : args_ptr)++) = (uint32_t)ReverseBytes(v); \
297
+ } while (false)
298
+ #define PUSH_INTEGER_64(CType) \
299
+ do { \
300
+ if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) { \
301
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), param.offset + 1); \
302
+ return false; \
303
+ } \
304
+ \
305
+ CType v = CopyNumber<CType>(value); \
306
+ \
307
+ if (RG_LIKELY(param.gpr_count)) { \
308
+ gpr_ptr = AlignUp(gpr_ptr, 8); \
309
+ *(uint64_t *)gpr_ptr = (uint64_t)v; \
310
+ gpr_ptr += param.gpr_count; \
311
+ } else { \
312
+ args_ptr = AlignUp(args_ptr, 8); \
313
+ *(uint64_t *)args_ptr = (uint64_t)v; \
314
+ args_ptr += 2; \
315
+ } \
316
+ } while (false)
317
+ #define PUSH_INTEGER_64_SWAP(CType) \
318
+ do { \
319
+ if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) { \
320
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), param.offset + 1); \
321
+ return false; \
322
+ } \
323
+ \
324
+ CType v = CopyNumber<CType>(value); \
325
+ \
326
+ if (RG_LIKELY(param.gpr_count)) { \
327
+ gpr_ptr = AlignUp(gpr_ptr, 8); \
328
+ *(uint64_t *)gpr_ptr = (uint64_t)ReverseBytes(v); \
329
+ gpr_ptr += param.gpr_count; \
330
+ } else { \
331
+ args_ptr = AlignUp(args_ptr, 8); \
332
+ *(uint64_t *)args_ptr = (uint64_t)ReverseBytes(v); \
333
+ args_ptr += 2; \
334
+ } \
335
+ } while (false)
336
+
272
337
  // Push arguments
273
338
  for (Size i = 0; i < func->parameters.len; i++) {
274
339
  const ParameterInfo &param = func->parameters[i];
@@ -288,64 +353,20 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
288
353
  bool b = value.As<Napi::Boolean>();
289
354
  *((param.gpr_count ? gpr_ptr : args_ptr)++) = (uint32_t)b;
290
355
  } break;
291
- case PrimitiveKind::Int8:
292
- case PrimitiveKind::UInt8:
293
- case PrimitiveKind::Int16:
294
- case PrimitiveKind::UInt16:
295
- case PrimitiveKind::Int32: {
296
- if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
297
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), param.offset + 1);
298
- return false;
299
- }
300
-
301
- int32_t v = CopyNumber<int32_t>(value);
302
- *(int32_t *)((param.gpr_count ? gpr_ptr : args_ptr)++) = v;
303
- } break;
304
- case PrimitiveKind::UInt32: {
305
- if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
306
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), param.offset + 1);
307
- return false;
308
- }
309
-
310
- uint32_t v = CopyNumber<uint32_t>(value);
311
- *((param.gpr_count ? gpr_ptr : args_ptr)++) = v;
312
- } break;
313
- case PrimitiveKind::Int64: {
314
- if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
315
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), param.offset + 1);
316
- return false;
317
- }
318
-
319
- int64_t v = CopyNumber<int64_t>(value);
320
-
321
- if (RG_LIKELY(param.gpr_count)) {
322
- gpr_ptr = AlignUp(gpr_ptr, 8);
323
- *(int64_t *)gpr_ptr = v;
324
- gpr_ptr += param.gpr_count;
325
- } else {
326
- args_ptr = AlignUp(args_ptr, 8);
327
- *(int64_t *)args_ptr = v;
328
- args_ptr += 2;
329
- }
330
- } break;
331
- case PrimitiveKind::UInt64: {
332
- if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
333
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), param.offset + 1);
334
- return false;
335
- }
336
-
337
- uint64_t v = CopyNumber<uint64_t>(value);
338
-
339
- if (RG_LIKELY(param.gpr_count)) {
340
- gpr_ptr = AlignUp(gpr_ptr, 8);
341
- *(uint64_t *)gpr_ptr = v;
342
- gpr_ptr += param.gpr_count;
343
- } else {
344
- args_ptr = AlignUp(args_ptr, 8);
345
- *(uint64_t *)args_ptr = v;
346
- args_ptr += 2;
347
- }
348
- } break;
356
+ case PrimitiveKind::Int8: { PUSH_INTEGER_32(int8_t); } break;
357
+ case PrimitiveKind::UInt8: { PUSH_INTEGER_32(uint8_t); } break;
358
+ case PrimitiveKind::Int16: { PUSH_INTEGER_32(int16_t); } break;
359
+ case PrimitiveKind::Int16S: { PUSH_INTEGER_32_SWAP(int16_t); } break;
360
+ case PrimitiveKind::UInt16: { PUSH_INTEGER_32(uint16_t); } break;
361
+ case PrimitiveKind::UInt16S: { PUSH_INTEGER_32_SWAP(uint16_t); } break;
362
+ case PrimitiveKind::Int32: { PUSH_INTEGER_32(int32_t); } break;
363
+ case PrimitiveKind::Int32S: { PUSH_INTEGER_32_SWAP(int32_t); } break;
364
+ case PrimitiveKind::UInt32: { PUSH_INTEGER_32(uint32_t); } break;
365
+ case PrimitiveKind::UInt32S: { PUSH_INTEGER_32_SWAP(uint32_t); } break;
366
+ case PrimitiveKind::Int64: { PUSH_INTEGER_64(int64_t); } break;
367
+ case PrimitiveKind::Int64S: { PUSH_INTEGER_64_SWAP(int64_t); } break;
368
+ case PrimitiveKind::UInt64: { PUSH_INTEGER_64(uint64_t); } break;
369
+ case PrimitiveKind::UInt64S: { PUSH_INTEGER_64_SWAP(uint64_t); } break;
349
370
  case PrimitiveKind::String: {
350
371
  const char *str;
351
372
  if (RG_LIKELY(value.IsString())) {
@@ -478,6 +499,11 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
478
499
  }
479
500
  }
480
501
 
502
+ #undef PUSH_INTEGER_64_SWAP
503
+ #undef PUSH_INTEGER_64
504
+ #undef PUSH_INTEGER_32_SWAP
505
+ #undef PUSH_INTEGER_32
506
+
481
507
  new_sp = mem->stack.end();
482
508
 
483
509
  return true;
@@ -498,14 +524,20 @@ void CallData::Execute()
498
524
  switch (func->ret.type->primitive) {
499
525
  case PrimitiveKind::Void:
500
526
  case PrimitiveKind::Bool:
501
- case PrimitiveKind::Int8:
527
+ case PrimitiveKind::Int8:
502
528
  case PrimitiveKind::UInt8:
503
529
  case PrimitiveKind::Int16:
530
+ case PrimitiveKind::Int16S:
504
531
  case PrimitiveKind::UInt16:
532
+ case PrimitiveKind::UInt16S:
505
533
  case PrimitiveKind::Int32:
534
+ case PrimitiveKind::Int32S:
506
535
  case PrimitiveKind::UInt32:
536
+ case PrimitiveKind::UInt32S:
507
537
  case PrimitiveKind::Int64:
538
+ case PrimitiveKind::Int64S:
508
539
  case PrimitiveKind::UInt64:
540
+ case PrimitiveKind::UInt64S:
509
541
  case PrimitiveKind::String:
510
542
  case PrimitiveKind::String16:
511
543
  case PrimitiveKind::Pointer:
@@ -544,11 +576,17 @@ Napi::Value CallData::Complete()
544
576
  case PrimitiveKind::Int8: return Napi::Number::New(env, (double)result.i8);
545
577
  case PrimitiveKind::UInt8: return Napi::Number::New(env, (double)result.u8);
546
578
  case PrimitiveKind::Int16: return Napi::Number::New(env, (double)result.i16);
579
+ case PrimitiveKind::Int16S: return Napi::Number::New(env, (double)ReverseBytes(result.i16));
547
580
  case PrimitiveKind::UInt16: return Napi::Number::New(env, (double)result.u16);
581
+ case PrimitiveKind::UInt16S: return Napi::Number::New(env, (double)ReverseBytes(result.u16));
548
582
  case PrimitiveKind::Int32: return Napi::Number::New(env, (double)result.i32);
583
+ case PrimitiveKind::Int32S: return Napi::Number::New(env, (double)ReverseBytes(result.i32));
549
584
  case PrimitiveKind::UInt32: return Napi::Number::New(env, (double)result.u32);
585
+ case PrimitiveKind::UInt32S: return Napi::Number::New(env, (double)ReverseBytes(result.u32));
550
586
  case PrimitiveKind::Int64: return NewBigInt(env, result.i64);
587
+ case PrimitiveKind::Int64S: return NewBigInt(env, ReverseBytes(result.i64));
551
588
  case PrimitiveKind::UInt64: return NewBigInt(env, result.u64);
589
+ case PrimitiveKind::UInt64S: return NewBigInt(env, ReverseBytes(result.u64));
552
590
  case PrimitiveKind::String: return result.ptr ? Napi::String::New(env, (const char *)result.ptr) : env.Null();
553
591
  case PrimitiveKind::String16: return result.ptr ? Napi::String::New(env, (const char16_t *)result.ptr) : env.Null();
554
592
  case PrimitiveKind::Pointer:
@@ -637,24 +675,52 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
637
675
  Napi::Value arg = Napi::Number::New(env, d);
638
676
  arguments.Append(arg);
639
677
  } break;
678
+ case PrimitiveKind::Int16S: {
679
+ int16_t v = *(int16_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
680
+ double d = (double)ReverseBytes(v);
681
+
682
+ Napi::Value arg = Napi::Number::New(env, d);
683
+ arguments.Append(arg);
684
+ } break;
640
685
  case PrimitiveKind::UInt16: {
641
686
  double d = (double)*(uint16_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
642
687
 
643
688
  Napi::Value arg = Napi::Number::New(env, d);
644
689
  arguments.Append(arg);
645
690
  } break;
691
+ case PrimitiveKind::UInt16S: {
692
+ uint16_t v = *(uint16_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
693
+ double d = (double)ReverseBytes(v);
694
+
695
+ Napi::Value arg = Napi::Number::New(env, d);
696
+ arguments.Append(arg);
697
+ } break;
646
698
  case PrimitiveKind::Int32: {
647
699
  double d = (double)*(int32_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
648
700
 
649
701
  Napi::Value arg = Napi::Number::New(env, d);
650
702
  arguments.Append(arg);
651
703
  } break;
704
+ case PrimitiveKind::Int32S: {
705
+ int32_t v = *(int32_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
706
+ double d = (double)ReverseBytes(v);
707
+
708
+ Napi::Value arg = Napi::Number::New(env, d);
709
+ arguments.Append(arg);
710
+ } break;
652
711
  case PrimitiveKind::UInt32: {
653
712
  double d = (double)*(uint32_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
654
713
 
655
714
  Napi::Value arg = Napi::Number::New(env, d);
656
715
  arguments.Append(arg);
657
716
  } break;
717
+ case PrimitiveKind::UInt32S: {
718
+ uint32_t v = *(uint32_t *)((param.gpr_count ? gpr_ptr : args_ptr)++);
719
+ double d = (double)ReverseBytes(v);
720
+
721
+ Napi::Value arg = Napi::Number::New(env, d);
722
+ arguments.Append(arg);
723
+ } break;
658
724
  case PrimitiveKind::Int64: {
659
725
  gpr_ptr = AlignUp(gpr_ptr, 8);
660
726
 
@@ -664,6 +730,15 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
664
730
  Napi::Value arg = NewBigInt(env, v);
665
731
  arguments.Append(arg);
666
732
  } break;
733
+ case PrimitiveKind::Int64S: {
734
+ gpr_ptr = AlignUp(gpr_ptr, 8);
735
+
736
+ int64_t v = *(int64_t *)(param.gpr_count ? gpr_ptr : args_ptr);
737
+ (param.gpr_count ? gpr_ptr : args_ptr) += 2;
738
+
739
+ Napi::Value arg = NewBigInt(env, ReverseBytes(v));
740
+ arguments.Append(arg);
741
+ } break;
667
742
  case PrimitiveKind::UInt64: {
668
743
  gpr_ptr = AlignUp(gpr_ptr, 8);
669
744
 
@@ -673,6 +748,15 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
673
748
  Napi::Value arg = NewBigInt(env, v);
674
749
  arguments.Append(arg);
675
750
  } break;
751
+ case PrimitiveKind::UInt64S: {
752
+ gpr_ptr = AlignUp(gpr_ptr, 8);
753
+
754
+ uint64_t v = *(uint64_t *)(param.gpr_count ? gpr_ptr : args_ptr);
755
+ (param.gpr_count ? gpr_ptr : args_ptr) += 2;
756
+
757
+ Napi::Value arg = NewBigInt(env, ReverseBytes(v));
758
+ arguments.Append(arg);
759
+ } break;
676
760
  case PrimitiveKind::String: {
677
761
  const char *str = *(const char **)((param.gpr_count ? gpr_ptr : args_ptr)++);
678
762
 
@@ -799,6 +883,51 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
799
883
  if (RG_UNLIKELY(env.IsExceptionPending()))
800
884
  return;
801
885
 
886
+ #define RETURN_INTEGER_32(CType) \
887
+ do { \
888
+ if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) { \
889
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for return value, expected number", GetValueType(instance, value)); \
890
+ return; \
891
+ } \
892
+ \
893
+ CType v = CopyNumber<CType>(value); \
894
+ out_reg->r0 = (uint32_t)v; \
895
+ } while (false)
896
+ #define RETURN_INTEGER_32_SWAP(CType) \
897
+ do { \
898
+ if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) { \
899
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for return value, expected number", GetValueType(instance, value)); \
900
+ return; \
901
+ } \
902
+ \
903
+ CType v = CopyNumber<CType>(value); \
904
+ out_reg->r0 = (uint32_t)ReverseBytes(v); \
905
+ } while (false)
906
+ #define RETURN_INTEGER_64(CType) \
907
+ do { \
908
+ if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) { \
909
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for return value, expected number", GetValueType(instance, value)); \
910
+ return; \
911
+ } \
912
+ \
913
+ CType v = CopyNumber<CType>(value); \
914
+ \
915
+ out_reg->r0 = (uint32_t)((uint64_t)v >> 32); \
916
+ out_reg->r1 = (uint32_t)((uint64_t)v & 0xFFFFFFFFu); \
917
+ } while (false)
918
+ #define RETURN_INTEGER_64_SWAP(CType) \
919
+ do { \
920
+ if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) { \
921
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for return value, expected number", GetValueType(instance, value)); \
922
+ return; \
923
+ } \
924
+ \
925
+ CType v = ReverseBytes(CopyNumber<CType>(value)); \
926
+ \
927
+ out_reg->r0 = (uint32_t)((uint64_t)v >> 32); \
928
+ out_reg->r1 = (uint32_t)((uint64_t)v & 0xFFFFFFFFu); \
929
+ } while (false)
930
+
802
931
  // Convert the result
803
932
  switch (type->primitive) {
804
933
  case PrimitiveKind::Void: {} break;
@@ -811,48 +940,20 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
811
940
  bool b = value.As<Napi::Boolean>();
812
941
  out_reg->r0 = (uint32_t)b;
813
942
  } break;
814
- case PrimitiveKind::Int8:
815
- case PrimitiveKind::UInt8:
816
- case PrimitiveKind::Int16:
817
- case PrimitiveKind::UInt16:
818
- case PrimitiveKind::Int32: {
819
- if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
820
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for return value, expected number", GetValueType(instance, value));
821
- return;
822
- }
823
-
824
- int32_t v = CopyNumber<int32_t>(value);
825
- out_reg->r0 = (uint32_t)v;
826
- } break;
827
- case PrimitiveKind::UInt32: {
828
- if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
829
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for return value, expected number", GetValueType(instance, value));
830
- return;
831
- }
832
-
833
- uint32_t v = CopyNumber<uint32_t>(value);
834
- out_reg->r0 = v;
835
- } break;
836
- case PrimitiveKind::Int64: {
837
- if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
838
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for return value, expected number", GetValueType(instance, value));
839
- return;
840
- }
841
-
842
- int64_t v = CopyNumber<int64_t>(value);
843
- out_reg->r0 = (uint32_t)(v >> 32);
844
- out_reg->r1 = (uint32_t)((uint64_t)v & 0xFFFFFFFFu);
845
- } break;
846
- case PrimitiveKind::UInt64: {
847
- if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
848
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for return value, expected number", GetValueType(instance, value));
849
- return;
850
- }
851
-
852
- uint64_t v = CopyNumber<uint64_t>(value);
853
- out_reg->r0 = (uint32_t)(v >> 32);
854
- out_reg->r1 = (uint32_t)((uint64_t)v & 0xFFFFFFFFu);
855
- } break;
943
+ case PrimitiveKind::Int8: { RETURN_INTEGER_32(int8_t); } break;
944
+ case PrimitiveKind::UInt8: { RETURN_INTEGER_32(uint8_t); } break;
945
+ case PrimitiveKind::Int16: { RETURN_INTEGER_32(int16_t); } break;
946
+ case PrimitiveKind::Int16S: { RETURN_INTEGER_32_SWAP(int16_t); } break;
947
+ case PrimitiveKind::UInt16: { RETURN_INTEGER_32(uint16_t); } break;
948
+ case PrimitiveKind::UInt16S: { RETURN_INTEGER_32_SWAP(uint16_t); } break;
949
+ case PrimitiveKind::Int32: { RETURN_INTEGER_32(int32_t); } break;
950
+ case PrimitiveKind::Int32S: { RETURN_INTEGER_32_SWAP(int32_t); } break;
951
+ case PrimitiveKind::UInt32: { RETURN_INTEGER_32(uint32_t); } break;
952
+ case PrimitiveKind::UInt32S: { RETURN_INTEGER_32_SWAP(uint32_t); } break;
953
+ case PrimitiveKind::Int64: { RETURN_INTEGER_64(int64_t); } break;
954
+ case PrimitiveKind::Int64S: { RETURN_INTEGER_64_SWAP(int64_t); } break;
955
+ case PrimitiveKind::UInt64: { RETURN_INTEGER_64(uint64_t); } break;
956
+ case PrimitiveKind::UInt64S: { RETURN_INTEGER_64_SWAP(uint64_t); } break;
856
957
  case PrimitiveKind::String: {
857
958
  const char *str;
858
959
  if (RG_LIKELY(value.IsString())) {
@@ -973,6 +1074,11 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
973
1074
  case PrimitiveKind::Prototype: { RG_UNREACHABLE(); } break;
974
1075
  }
975
1076
 
1077
+ #undef RETURN_INTEGER_64_SWAP
1078
+ #undef RETURN_INTEGER_64
1079
+ #undef RETURN_INTEGER_32_SWAP
1080
+ #undef RETURN_INTEGER_32
1081
+
976
1082
  err_guard.Disable();
977
1083
  }
978
1084