koffi 2.1.0-beta.2 → 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 (104) hide show
  1. package/ChangeLog.md +2 -2
  2. package/build/qemu/2.1.0-beta.3/koffi_darwin_arm64.tar.gz +0 -0
  3. package/build/qemu/2.1.0-beta.3/koffi_darwin_x64.tar.gz +0 -0
  4. package/build/qemu/2.1.0-beta.3/koffi_freebsd_arm64.tar.gz +0 -0
  5. package/build/qemu/2.1.0-beta.3/koffi_freebsd_ia32.tar.gz +0 -0
  6. package/build/qemu/2.1.0-beta.3/koffi_freebsd_x64.tar.gz +0 -0
  7. package/build/qemu/2.1.0-beta.3/koffi_linux_arm32hf.tar.gz +0 -0
  8. package/build/qemu/2.1.0-beta.3/koffi_linux_arm64.tar.gz +0 -0
  9. package/build/qemu/2.1.0-beta.3/koffi_linux_ia32.tar.gz +0 -0
  10. package/build/qemu/2.1.0-beta.3/koffi_linux_riscv64hf64.tar.gz +0 -0
  11. package/build/qemu/2.1.0-beta.3/koffi_linux_x64.tar.gz +0 -0
  12. package/build/qemu/2.1.0-beta.3/koffi_openbsd_ia32.tar.gz +0 -0
  13. package/build/qemu/2.1.0-beta.3/koffi_openbsd_x64.tar.gz +0 -0
  14. package/build/qemu/2.1.0-beta.3/koffi_win32_arm64.tar.gz +0 -0
  15. package/build/qemu/2.1.0-beta.3/koffi_win32_ia32.tar.gz +0 -0
  16. package/build/qemu/2.1.0-beta.3/koffi_win32_x64.tar.gz +0 -0
  17. package/doc/Makefile +1 -1
  18. package/doc/conf.py +5 -0
  19. package/doc/dist/doctrees/changes.doctree +0 -0
  20. package/doc/dist/doctrees/environment.pickle +0 -0
  21. package/doc/dist/doctrees/functions.doctree +0 -0
  22. package/doc/dist/doctrees/index.doctree +0 -0
  23. package/doc/dist/doctrees/types.doctree +0 -0
  24. package/doc/dist/html/.buildinfo +4 -0
  25. package/doc/dist/html/_sources/benchmarks.md.txt +137 -0
  26. package/doc/dist/html/_sources/changes.md.txt +161 -0
  27. package/doc/dist/html/_sources/contribute.md.txt +127 -0
  28. package/doc/dist/html/_sources/functions.md.txt +421 -0
  29. package/doc/dist/html/_sources/index.rst.txt +39 -0
  30. package/doc/dist/html/_sources/memory.md.txt +32 -0
  31. package/doc/dist/html/_sources/platforms.md.txt +31 -0
  32. package/doc/dist/html/_sources/start.md.txt +100 -0
  33. package/doc/dist/html/_sources/types.md.txt +541 -0
  34. package/doc/dist/html/_static/_sphinx_javascript_frameworks_compat.js +134 -0
  35. package/doc/dist/html/_static/basic.css +932 -0
  36. package/doc/dist/html/_static/bench_linux.png +0 -0
  37. package/doc/dist/html/_static/bench_windows.png +0 -0
  38. package/doc/dist/html/_static/custom.css +22 -0
  39. package/doc/dist/html/_static/debug.css +69 -0
  40. package/doc/dist/html/_static/doctools.js +264 -0
  41. package/doc/dist/html/_static/documentation_options.js +14 -0
  42. package/doc/dist/html/_static/file.png +0 -0
  43. package/doc/dist/html/_static/jquery-3.6.0.js +10881 -0
  44. package/doc/dist/html/_static/jquery.js +2 -0
  45. package/doc/dist/html/_static/language_data.js +199 -0
  46. package/doc/dist/html/_static/minus.png +0 -0
  47. package/doc/dist/html/_static/perf_linux_20220623.png +0 -0
  48. package/doc/dist/html/_static/perf_linux_20220623_2.png +0 -0
  49. package/doc/dist/html/_static/perf_windows_20220623.png +0 -0
  50. package/doc/dist/html/_static/perf_windows_20220623_2.png +0 -0
  51. package/doc/dist/html/_static/plus.png +0 -0
  52. package/doc/dist/html/_static/pygments.css +252 -0
  53. package/doc/dist/html/_static/scripts/furo-extensions.js +0 -0
  54. package/doc/dist/html/_static/scripts/furo.js +3 -0
  55. package/doc/dist/html/_static/scripts/furo.js.LICENSE.txt +7 -0
  56. package/doc/dist/html/_static/scripts/furo.js.map +1 -0
  57. package/doc/dist/html/_static/searchtools.js +531 -0
  58. package/doc/dist/html/_static/skeleton.css +296 -0
  59. package/doc/dist/html/_static/styles/furo-extensions.css +2 -0
  60. package/doc/dist/html/_static/styles/furo-extensions.css.map +1 -0
  61. package/doc/dist/html/_static/styles/furo.css +2 -0
  62. package/doc/dist/html/_static/styles/furo.css.map +1 -0
  63. package/doc/dist/html/_static/underscore-1.13.1.js +2042 -0
  64. package/doc/dist/html/_static/underscore.js +6 -0
  65. package/doc/dist/html/benchmarks.html +571 -0
  66. package/doc/dist/html/changes.html +686 -0
  67. package/doc/dist/html/contribute.html +403 -0
  68. package/doc/dist/html/functions.html +718 -0
  69. package/doc/dist/html/genindex.html +253 -0
  70. package/doc/dist/html/index.html +359 -0
  71. package/doc/dist/html/memory.html +346 -0
  72. package/doc/dist/html/objects.inv +0 -0
  73. package/doc/dist/html/platforms.html +371 -0
  74. package/doc/dist/html/search.html +261 -0
  75. package/doc/dist/html/searchindex.js +1 -0
  76. package/doc/dist/html/start.html +384 -0
  77. package/doc/dist/html/types.html +1061 -0
  78. package/doc/make.bat +1 -1
  79. package/doc/templates/badges.html +1 -1
  80. package/doc/types.md +2 -0
  81. package/package.json +2 -1
  82. package/src/abi_arm32.cc +142 -200
  83. package/src/abi_arm64.cc +113 -122
  84. package/src/abi_riscv64.cc +76 -92
  85. package/src/abi_x64_sysv.cc +76 -92
  86. package/src/abi_x64_win.cc +76 -92
  87. package/src/abi_x86.cc +128 -164
  88. package/test/misc.c +43 -0
  89. package/test/sync.js +81 -0
  90. package/build/qemu/2.1.0-beta.2/koffi_darwin_arm64.tar.gz +0 -0
  91. package/build/qemu/2.1.0-beta.2/koffi_darwin_x64.tar.gz +0 -0
  92. package/build/qemu/2.1.0-beta.2/koffi_freebsd_arm64.tar.gz +0 -0
  93. package/build/qemu/2.1.0-beta.2/koffi_freebsd_ia32.tar.gz +0 -0
  94. package/build/qemu/2.1.0-beta.2/koffi_freebsd_x64.tar.gz +0 -0
  95. package/build/qemu/2.1.0-beta.2/koffi_linux_arm32hf.tar.gz +0 -0
  96. package/build/qemu/2.1.0-beta.2/koffi_linux_arm64.tar.gz +0 -0
  97. package/build/qemu/2.1.0-beta.2/koffi_linux_ia32.tar.gz +0 -0
  98. package/build/qemu/2.1.0-beta.2/koffi_linux_riscv64hf64.tar.gz +0 -0
  99. package/build/qemu/2.1.0-beta.2/koffi_linux_x64.tar.gz +0 -0
  100. package/build/qemu/2.1.0-beta.2/koffi_openbsd_ia32.tar.gz +0 -0
  101. package/build/qemu/2.1.0-beta.2/koffi_openbsd_x64.tar.gz +0 -0
  102. package/build/qemu/2.1.0-beta.2/koffi_win32_arm64.tar.gz +0 -0
  103. package/build/qemu/2.1.0-beta.2/koffi_win32_ia32.tar.gz +0 -0
  104. package/build/qemu/2.1.0-beta.2/koffi_win32_x64.tar.gz +0 -0
package/src/abi_x86.cc CHANGED
@@ -197,6 +197,51 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
197
197
  *((func->ret.fast ? fast_ptr : args_ptr)++) = (uint32_t)return_ptr;
198
198
  }
199
199
 
200
+ #define PUSH_INTEGER_32(CType) \
201
+ do { \
202
+ if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) { \
203
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), param.offset + 1); \
204
+ return false; \
205
+ } \
206
+ \
207
+ CType v = CopyNumber<CType>(value); \
208
+ *((param.fast ? fast_ptr : args_ptr)++) = (uint32_t)v; \
209
+ } while (false)
210
+ #define PUSH_INTEGER_32_SWAP(CType) \
211
+ do { \
212
+ if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) { \
213
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), param.offset + 1); \
214
+ return false; \
215
+ } \
216
+ \
217
+ CType v = CopyNumber<CType>(value); \
218
+ *((param.fast ? fast_ptr : args_ptr)++) = (uint32_t)ReverseBytes(v); \
219
+ } while (false)
220
+ #define PUSH_INTEGER_64(CType) \
221
+ do { \
222
+ if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) { \
223
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), param.offset + 1); \
224
+ return false; \
225
+ } \
226
+ \
227
+ CType v = CopyNumber<CType>(value); \
228
+ \
229
+ *(uint64_t *)args_ptr = (uint64_t)v; \
230
+ args_ptr += 2; \
231
+ } while (false)
232
+ #define PUSH_INTEGER_64_SWAP(CType) \
233
+ do { \
234
+ if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) { \
235
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), param.offset + 1); \
236
+ return false; \
237
+ } \
238
+ \
239
+ CType v = CopyNumber<CType>(value); \
240
+ \
241
+ *(uint64_t *)args_ptr = (uint64_t)ReverseBytes(v); \
242
+ args_ptr += 2; \
243
+ } while (false)
244
+
200
245
  // Push arguments
201
246
  for (Size i = 0; i < func->parameters.len; i++) {
202
247
  const ParameterInfo &param = func->parameters[i];
@@ -216,88 +261,20 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
216
261
  bool b = value.As<Napi::Boolean>();
217
262
  *(bool *)((param.fast ? fast_ptr : args_ptr)++) = b;
218
263
  } break;
219
- case PrimitiveKind::Int8:
220
- case PrimitiveKind::UInt8:
221
- case PrimitiveKind::Int16:
222
- case PrimitiveKind::UInt16:
223
- case PrimitiveKind::Int32: {
224
- if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
225
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), param.offset + 1);
226
- return false;
227
- }
228
-
229
- int32_t v = CopyNumber<int32_t>(value);
230
- *(int32_t *)((param.fast ? fast_ptr : args_ptr)++) = v;
231
- } break;
232
- case PrimitiveKind::Int16S:
233
- case PrimitiveKind::UInt16S:
234
- case PrimitiveKind::Int32S: {
235
- if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
236
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), param.offset + 1);
237
- return false;
238
- }
239
-
240
- int32_t v = CopyNumber<int32_t>(value);
241
- *(int32_t *)((param.fast ? fast_ptr : args_ptr)++) = ReverseBytes(v);
242
- } break;
243
- case PrimitiveKind::UInt32: {
244
- if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
245
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), param.offset + 1);
246
- return false;
247
- }
248
-
249
- uint32_t v = CopyNumber<uint32_t>(value);
250
- *((param.fast ? fast_ptr : args_ptr)++) = v;
251
- } break;
252
- case PrimitiveKind::UInt32S: {
253
- if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
254
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), param.offset + 1);
255
- return false;
256
- }
257
-
258
- uint32_t v = CopyNumber<uint32_t>(value);
259
- *((param.fast ? fast_ptr : args_ptr)++) = ReverseBytes(v);
260
- } break;
261
- case PrimitiveKind::Int64: {
262
- if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
263
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), param.offset + 1);
264
- return false;
265
- }
266
-
267
- int64_t v = CopyNumber<int64_t>(value);
268
- *(int64_t *)args_ptr = v;
269
- args_ptr += 2;
270
- } break;
271
- case PrimitiveKind::Int64S: {
272
- if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
273
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), param.offset + 1);
274
- return false;
275
- }
276
-
277
- int64_t v = CopyNumber<int64_t>(value);
278
- *(int64_t *)args_ptr = ReverseBytes(v);
279
- args_ptr += 2;
280
- } break;
281
- case PrimitiveKind::UInt64: {
282
- if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
283
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), param.offset + 1);
284
- return false;
285
- }
286
-
287
- uint64_t v = CopyNumber<uint64_t>(value);
288
- *(uint64_t *)args_ptr = v;
289
- args_ptr += 2;
290
- } break;
291
- case PrimitiveKind::UInt64S: {
292
- if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
293
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for argument %2, expected number", GetValueType(instance, value), param.offset + 1);
294
- return false;
295
- }
296
-
297
- uint64_t v = CopyNumber<uint64_t>(value);
298
- *(uint64_t *)args_ptr = ReverseBytes(v);
299
- args_ptr += 2;
300
- } break;
264
+ case PrimitiveKind::Int8: { PUSH_INTEGER_32(int8_t); } break;
265
+ case PrimitiveKind::UInt8: { PUSH_INTEGER_32(uint8_t); } break;
266
+ case PrimitiveKind::Int16: { PUSH_INTEGER_32(int16_t); } break;
267
+ case PrimitiveKind::Int16S: { PUSH_INTEGER_32_SWAP(int16_t); } break;
268
+ case PrimitiveKind::UInt16: { PUSH_INTEGER_32(uint16_t); } break;
269
+ case PrimitiveKind::UInt16S: { PUSH_INTEGER_32_SWAP(uint16_t); } break;
270
+ case PrimitiveKind::Int32: { PUSH_INTEGER_32(int32_t); } break;
271
+ case PrimitiveKind::Int32S: { PUSH_INTEGER_32_SWAP(int32_t); } break;
272
+ case PrimitiveKind::UInt32: { PUSH_INTEGER_32(uint32_t); } break;
273
+ case PrimitiveKind::UInt32S: { PUSH_INTEGER_32_SWAP(uint32_t); } break;
274
+ case PrimitiveKind::Int64: { PUSH_INTEGER_64(int64_t); } break;
275
+ case PrimitiveKind::Int64S: { PUSH_INTEGER_64_SWAP(int64_t); } break;
276
+ case PrimitiveKind::UInt64: { PUSH_INTEGER_64(uint64_t); } break;
277
+ case PrimitiveKind::UInt64S: { PUSH_INTEGER_64_SWAP(uint64_t); } break;
301
278
  case PrimitiveKind::String: {
302
279
  const char *str;
303
280
  if (RG_LIKELY(value.IsString())) {
@@ -399,6 +376,11 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
399
376
  }
400
377
  }
401
378
 
379
+ #undef PUSH_INTEGER_64_SWAP
380
+ #undef PUSH_INTEGER_64
381
+ #undef PUSH_INTEGER_32_SWAP
382
+ #undef PUSH_INTEGER_32
383
+
402
384
  new_sp = mem->stack.end();
403
385
 
404
386
  return true;
@@ -726,6 +708,51 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
726
708
  if (RG_UNLIKELY(env.IsExceptionPending()))
727
709
  return;
728
710
 
711
+ #define RETURN_INTEGER_32(CType) \
712
+ do { \
713
+ if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) { \
714
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for return value, expected number", GetValueType(instance, value)); \
715
+ return; \
716
+ } \
717
+ \
718
+ CType v = CopyNumber<CType>(value); \
719
+ out_reg->eax = (uint32_t)v; \
720
+ } while (false)
721
+ #define RETURN_INTEGER_32_SWAP(CType) \
722
+ do { \
723
+ if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) { \
724
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for return value, expected number", GetValueType(instance, value)); \
725
+ return; \
726
+ } \
727
+ \
728
+ CType v = CopyNumber<CType>(value); \
729
+ out_reg->eax = (uint32_t)ReverseBytes(v); \
730
+ } while (false)
731
+ #define RETURN_INTEGER_64(CType) \
732
+ do { \
733
+ if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) { \
734
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for return value, expected number", GetValueType(instance, value)); \
735
+ return; \
736
+ } \
737
+ \
738
+ CType v = CopyNumber<CType>(value); \
739
+ \
740
+ out_reg->eax = (uint32_t)((uint64_t)v >> 32); \
741
+ out_reg->edx = (uint32_t)((uint64_t)v & 0xFFFFFFFFu); \
742
+ } while (false)
743
+ #define RETURN_INTEGER_64_SWAP(CType) \
744
+ do { \
745
+ if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) { \
746
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for return value, expected number", GetValueType(instance, value)); \
747
+ return; \
748
+ } \
749
+ \
750
+ CType v = ReverseBytes(CopyNumber<CType>(value)); \
751
+ \
752
+ out_reg->eax = (uint32_t)((uint64_t)v >> 32); \
753
+ out_reg->edx = (uint32_t)((uint64_t)v & 0xFFFFFFFFu); \
754
+ } while (false)
755
+
729
756
  switch (type->primitive) {
730
757
  case PrimitiveKind::Void: {} break;
731
758
  case PrimitiveKind::Bool: {
@@ -737,88 +764,20 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
737
764
  bool b = value.As<Napi::Boolean>();
738
765
  out_reg->eax = (uint32_t)b;
739
766
  } break;
740
- case PrimitiveKind::Int8:
741
- case PrimitiveKind::UInt8:
742
- case PrimitiveKind::Int16:
743
- case PrimitiveKind::UInt16:
744
- case PrimitiveKind::Int32: {
745
- if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
746
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for return value, expected number", GetValueType(instance, value));
747
- return;
748
- }
749
-
750
- int32_t v = CopyNumber<int32_t>(value);
751
- out_reg->eax = (uint32_t)v;
752
- } break;
753
- case PrimitiveKind::Int16S:
754
- case PrimitiveKind::UInt16S:
755
- case PrimitiveKind::Int32S: {
756
- if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
757
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for return value, expected number", GetValueType(instance, value));
758
- return;
759
- }
760
-
761
- int32_t v = CopyNumber<int32_t>(value);
762
- out_reg->eax = (uint32_t)ReverseBytes(v);
763
- } break;
764
- case PrimitiveKind::UInt32: {
765
- if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
766
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for return value, expected number", GetValueType(instance, value));
767
- return;
768
- }
769
-
770
- uint32_t v = CopyNumber<uint32_t>(value);
771
- out_reg->eax = v;
772
- } break;
773
- case PrimitiveKind::UInt32S: {
774
- if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
775
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for return value, expected number", GetValueType(instance, value));
776
- return;
777
- }
778
-
779
- uint32_t v = CopyNumber<uint32_t>(value);
780
- out_reg->eax = ReverseBytes(v);
781
- } break;
782
- case PrimitiveKind::Int64: {
783
- if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
784
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for return value, expected number", GetValueType(instance, value));
785
- return;
786
- }
787
-
788
- int64_t v = CopyNumber<int64_t>(value);
789
- out_reg->eax = (uint32_t)(v & 0xFFFFFFFFul);
790
- out_reg->edx = (uint32_t)(v << 32);
791
- } break;
792
- case PrimitiveKind::Int64S: {
793
- if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
794
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for return value, expected number", GetValueType(instance, value));
795
- return;
796
- }
797
-
798
- int64_t v = ReverseBytes(CopyNumber<int64_t>(value));
799
- out_reg->eax = (uint32_t)(v & 0xFFFFFFFFul);
800
- out_reg->edx = (uint32_t)(v << 32);
801
- } break;
802
- case PrimitiveKind::UInt64: {
803
- if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
804
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for return value, expected number", GetValueType(instance, value));
805
- return;
806
- }
807
-
808
- uint64_t v = CopyNumber<uint64_t>(value);
809
- out_reg->eax = (uint32_t)(v & 0xFFFFFFFFul);
810
- out_reg->edx = (uint32_t)(v << 32);
811
- } break;
812
- case PrimitiveKind::UInt64S: {
813
- if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
814
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value for return value, expected number", GetValueType(instance, value));
815
- return;
816
- }
817
-
818
- uint64_t v = ReverseBytes(CopyNumber<uint64_t>(value));
819
- out_reg->eax = (uint32_t)(v & 0xFFFFFFFFul);
820
- out_reg->edx = (uint32_t)(v << 32);
821
- } break;
767
+ case PrimitiveKind::Int8: { RETURN_INTEGER_32(int8_t); } break;
768
+ case PrimitiveKind::UInt8: { RETURN_INTEGER_32(uint8_t); } break;
769
+ case PrimitiveKind::Int16: { RETURN_INTEGER_32(int16_t); } break;
770
+ case PrimitiveKind::Int16S: { RETURN_INTEGER_32_SWAP(int16_t); } break;
771
+ case PrimitiveKind::UInt16: { RETURN_INTEGER_32(uint16_t); } break;
772
+ case PrimitiveKind::UInt16S: { RETURN_INTEGER_32_SWAP(uint16_t); } break;
773
+ case PrimitiveKind::Int32: { RETURN_INTEGER_32(int32_t); } break;
774
+ case PrimitiveKind::Int32S: { RETURN_INTEGER_32_SWAP(int32_t); } break;
775
+ case PrimitiveKind::UInt32: { RETURN_INTEGER_32(uint32_t); } break;
776
+ case PrimitiveKind::UInt32S: { RETURN_INTEGER_32_SWAP(uint32_t); } break;
777
+ case PrimitiveKind::Int64: { RETURN_INTEGER_64(int64_t); } break;
778
+ case PrimitiveKind::Int64S: { RETURN_INTEGER_64_SWAP(int64_t); } break;
779
+ case PrimitiveKind::UInt64: { RETURN_INTEGER_64(uint64_t); } break;
780
+ case PrimitiveKind::UInt64S: { RETURN_INTEGER_64_SWAP(uint64_t); } break;
822
781
  case PrimitiveKind::String: {
823
782
  const char *str;
824
783
  if (RG_LIKELY(value.IsString())) {
@@ -929,6 +888,11 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
929
888
  case PrimitiveKind::Prototype: { RG_UNREACHABLE(); } break;
930
889
  }
931
890
 
891
+ #undef RETURN_INTEGER_64_SWAP
892
+ #undef RETURN_INTEGER_64
893
+ #undef RETURN_INTEGER_32_SWAP
894
+ #undef RETURN_INTEGER_32
895
+
932
896
  err_guard.Disable();
933
897
  }
934
898
 
package/test/misc.c CHANGED
@@ -143,6 +143,21 @@ typedef struct StructCallbacks {
143
143
  IntCallback *third;
144
144
  } StructCallbacks;
145
145
 
146
+ typedef struct EndianInts {
147
+ int16_t i16le;
148
+ int16_t i16be;
149
+ uint16_t u16le;
150
+ uint16_t u16be;
151
+ int32_t i32le;
152
+ int32_t i32be;
153
+ uint32_t u32le;
154
+ uint32_t u32be;
155
+ int64_t i64le;
156
+ int64_t i64be;
157
+ uint64_t u64le;
158
+ uint64_t u64be;
159
+ } EndianInts;
160
+
146
161
  EXPORT int8_t GetMinusOne1(void)
147
162
  {
148
163
  return -1;
@@ -653,3 +668,31 @@ EXPORT void ReverseBytes(void *p, int len)
653
668
  bytes[len - i - 1] = tmp;
654
669
  }
655
670
  }
671
+
672
+ EXPORT void CopyEndianInts1(EndianInts ints, uint8_t buf[56])
673
+ {
674
+ memcpy(buf, &ints, sizeof(ints));
675
+ }
676
+
677
+ EXPORT void CopyEndianInts2(int16_t i16le, int16_t i16be, uint16_t u16le, uint16_t u16be,
678
+ int32_t i32le, int32_t i32be, uint32_t u32le, uint32_t u32be,
679
+ int64_t i64le, int64_t i64be, uint64_t u64le, uint64_t u64be,
680
+ EndianInts *out)
681
+ {
682
+ out->i16le = i16le;
683
+ out->i16be = i16be;
684
+ out->u16le = u16le;
685
+ out->u16be = u16be;
686
+ out->i32le = i32le;
687
+ out->i32be = i32be;
688
+ out->u32le = u32le;
689
+ out->u32be = u32be;
690
+ out->i64le = i64le;
691
+ out->i64be = i64be;
692
+ out->u64le = u64le;
693
+ out->u64be = u64be;
694
+ }
695
+
696
+ EXPORT uint16_t ReturnEndianInt2(uint16_t v) { return v; }
697
+ EXPORT uint32_t ReturnEndianInt4(uint32_t v) { return v; }
698
+ EXPORT uint64_t ReturnEndianInt8(uint64_t v) { return v; }
package/test/sync.js CHANGED
@@ -114,6 +114,21 @@ const StrStruct = koffi.struct('StrStruct', {
114
114
  str16: koffi.types.string16
115
115
  });
116
116
 
117
+ const EndianInts = koffi.struct('EndianInts', {
118
+ i16le: 'int16_le_t',
119
+ i16be: 'int16_be_t',
120
+ u16le: 'uint16_le_t',
121
+ u16be: 'uint16_be_t',
122
+ i32le: 'int32_le_t',
123
+ i32be: 'int32_be_t',
124
+ u32le: 'uint32_le_t',
125
+ u32be: 'uint32_be_t',
126
+ i64le: 'int64_le_t',
127
+ i64be: 'int64_be_t',
128
+ u64le: 'uint64_le_t',
129
+ u64be: 'uint64_be_t'
130
+ });
131
+
117
132
  main();
118
133
 
119
134
  async function main() {
@@ -187,6 +202,23 @@ async function test() {
187
202
  const ThroughStr = lib.func('str ThroughStr(StrStruct s)');
188
203
  const ThroughStr16 = lib.func('str16 ThroughStr16(StrStruct s)');
189
204
  const ReverseBytes = lib.func('void ReverseBytes(_Inout_ void *array, int len)');
205
+ const CopyEndianInts1 = lib.func('void CopyEndianInts1(EndianInts ints, _Out_ uint8_t *buf)');
206
+ const CopyEndianInts2 = lib.func('void CopyEndianInts2(int16_le_t i16le, int16_be_t i16be, uint16_le_t u16le, uint16_be_t u16be, ' +
207
+ 'int32_le_t i32le, int32_be_t i32be, uint32_le_t u32le, uint32_be_t u32be, ' +
208
+ 'int64_le_t i64le, int64_be_t i64be, uint64_le_t u64le, uint64_be_t u64be, ' +
209
+ '_Out_ void *out)');
210
+ const ReturnEndianInt2SL = lib.func('int16_le_t ReturnEndianInt2(int16_be_t v)');
211
+ const ReturnEndianInt2SB = lib.func('int16_be_t ReturnEndianInt2(int16_le_t v)');
212
+ const ReturnEndianInt2UL = lib.func('uint16_le_t ReturnEndianInt2(uint16_be_t v)');
213
+ const ReturnEndianInt2UB = lib.func('uint16_be_t ReturnEndianInt2(uint16_le_t v)');
214
+ const ReturnEndianInt4SL = lib.func('int32_le_t ReturnEndianInt4(int32_be_t v)');
215
+ const ReturnEndianInt4SB = lib.func('int32_be_t ReturnEndianInt4(int32_le_t v)');
216
+ const ReturnEndianInt4UL = lib.func('uint32_le_t ReturnEndianInt4(uint32_be_t v)');
217
+ const ReturnEndianInt4UB = lib.func('uint32_be_t ReturnEndianInt4(uint32_le_t v)');
218
+ const ReturnEndianInt8SL = lib.func('int64_le_t ReturnEndianInt8(int64_be_t v)');
219
+ const ReturnEndianInt8SB = lib.func('int64_be_t ReturnEndianInt8(int64_le_t v)');
220
+ const ReturnEndianInt8UL = lib.func('uint64_le_t ReturnEndianInt8(uint64_be_t v)');
221
+ const ReturnEndianInt8UB = lib.func('uint64_be_t ReturnEndianInt8(uint64_le_t v)');
190
222
 
191
223
  // Simple signed value returns
192
224
  assert.equal(GetMinusOne1(), -1);
@@ -418,4 +450,53 @@ async function test() {
418
450
  ReverseBytes(arr16, arr16.byteLength);
419
451
  assert.deepEqual(arr16, Int16Array.from([1280, 1024, 768, 512, 256]));
420
452
  }
453
+
454
+ // Endian-sensitive integer types
455
+ {
456
+ let ints = {
457
+ i16le: 0x7BCD,
458
+ i16be: 0x7BCD,
459
+ u16le: 0x7BCD,
460
+ u16be: 0x7BCD,
461
+ i32le: 0x4EADBEEF,
462
+ i32be: 0x4EADBEEF,
463
+ u32le: 0x4EADBEEF,
464
+ u32be: 0x4EADBEEF,
465
+ i64le: 0x0123456789ABCDEFn,
466
+ i64be: 0x0123456789ABCDEFn,
467
+ u64le: 0x0123456789ABCDEFn,
468
+ u64be: 0x0123456789ABCDEFn
469
+ };
470
+
471
+ let out1 = new Uint8Array(56);
472
+ let out2 = new Uint8Array(56);
473
+
474
+ CopyEndianInts1(ints, out1);
475
+ CopyEndianInts2(ints.i16le, ints.i16be, ints.u16le, ints.u16be,
476
+ ints.i32le, ints.i32be, ints.u32le, ints.u32be,
477
+ ints.u64le, ints.u64be, ints.u64le, ints.u64be, out2);
478
+
479
+ assert.deepEqual(out1, Uint8Array.from([
480
+ 0xCD, 0x7B, 0x7B, 0xCD,
481
+ 0xCD, 0x7B, 0x7B, 0xCD,
482
+ 0xEF, 0xBE, 0xAD, 0x4E, 0x4E, 0xAD, 0xBE, 0xEF,
483
+ 0xEF, 0xBE, 0xAD, 0x4E, 0x4E, 0xAD, 0xBE, 0xEF,
484
+ 0xEF, 0xCD, 0xAB, 0x89, 0x67, 0x45, 0x23, 0x01, 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
485
+ 0xEF, 0xCD, 0xAB, 0x89, 0x67, 0x45, 0x23, 0x01, 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF
486
+ ]));
487
+ assert.deepEqual(out2, out1);
488
+
489
+ assert.equal(ReturnEndianInt2SL(0x7B6D), 0x6D7B);
490
+ assert.equal(ReturnEndianInt2SB(0x7B6D), 0x6D7B);
491
+ assert.equal(ReturnEndianInt2UL(0x7B6D), 0x6D7B);
492
+ assert.equal(ReturnEndianInt2UB(0x7B6D), 0x6D7B);
493
+ assert.equal(ReturnEndianInt4SL(0x4EADBE4F), 0x4FBEAD4E);
494
+ assert.equal(ReturnEndianInt4SB(0x4EADBE4F), 0x4FBEAD4E);
495
+ assert.equal(ReturnEndianInt4UL(0x4EADBE4F), 0x4FBEAD4E);
496
+ assert.equal(ReturnEndianInt4UB(0x4EADBE4F), 0x4FBEAD4E);
497
+ assert.equal(ReturnEndianInt8SL(0x0123456789ABCD3Fn), 0x3FCDAB8967452301n);
498
+ assert.equal(ReturnEndianInt8SB(0x0123456789ABCD3Fn), 0x3FCDAB8967452301n);
499
+ assert.equal(ReturnEndianInt8UL(0x0123456789ABCD3Fn), 0x3FCDAB8967452301n);
500
+ assert.equal(ReturnEndianInt8UB(0x0123456789ABCD3Fn), 0x3FCDAB8967452301n);
501
+ }
421
502
  }