koffi 2.8.11 → 2.9.0-beta.2

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 (43) hide show
  1. package/CHANGELOG.md +12 -1
  2. package/build/koffi/darwin_arm64/koffi.node +0 -0
  3. package/build/koffi/darwin_x64/koffi.node +0 -0
  4. package/build/koffi/freebsd_arm64/koffi.node +0 -0
  5. package/build/koffi/freebsd_i386/koffi.node +0 -0
  6. package/build/koffi/freebsd_x64/koffi.node +0 -0
  7. package/build/koffi/linux_arm32/koffi.node +0 -0
  8. package/build/koffi/linux_arm64/koffi.node +0 -0
  9. package/build/koffi/linux_i386/koffi.node +0 -0
  10. package/build/koffi/linux_riscv64/koffi.node +0 -0
  11. package/build/koffi/linux_x64/koffi.node +0 -0
  12. package/build/koffi/musl_x64/koffi.node +0 -0
  13. package/build/koffi/openbsd_i386/koffi.node +0 -0
  14. package/build/koffi/openbsd_x64/koffi.node +0 -0
  15. package/build/koffi/win32_arm64/koffi.node +0 -0
  16. package/build/koffi/{win32_ia32 → win32_i386}/koffi.node +0 -0
  17. package/build/koffi/win32_x64/koffi.node +0 -0
  18. package/doc/contribute.md +3 -2
  19. package/doc/input.md +23 -13
  20. package/index.js +160 -97
  21. package/indirect.js +113 -81
  22. package/package.json +2 -2
  23. package/src/koffi/CMakeLists.txt +11 -1
  24. package/src/koffi/src/abi_arm32.cc +23 -0
  25. package/src/koffi/src/abi_arm64.cc +30 -0
  26. package/src/koffi/src/abi_riscv64.cc +22 -0
  27. package/src/koffi/src/abi_x64_sysv.cc +23 -0
  28. package/src/koffi/src/abi_x64_win.cc +23 -0
  29. package/src/koffi/src/abi_x86.cc +22 -0
  30. package/src/koffi/src/call.cc +155 -5
  31. package/src/koffi/src/call.hh +3 -0
  32. package/src/koffi/src/ffi.cc +26 -4
  33. package/src/koffi/src/ffi.hh +4 -0
  34. package/src/koffi/src/init.js +122 -0
  35. package/src/koffi/src/util.cc +85 -2
  36. package/src/koffi/src/util.hh +13 -0
  37. package/build/koffi/freebsd_ia32/koffi.node +0 -0
  38. package/build/koffi/linux_armhf/koffi.node +0 -0
  39. package/build/koffi/linux_ia32/koffi.node +0 -0
  40. package/build/koffi/linux_riscv64d/koffi.node +0 -0
  41. package/build/koffi/openbsd_ia32/koffi.node +0 -0
  42. /package/build/koffi/{win32_ia32 → win32_i386}/koffi.exp +0 -0
  43. /package/build/koffi/{win32_ia32 → win32_i386}/koffi.lib +0 -0
@@ -328,7 +328,8 @@ const TypeInfo *ResolveType(Napi::Env env, Span<const char> str, int *out_direct
328
328
  if (disposables & (1u << i)) {
329
329
  if (type->primitive != PrimitiveKind::Pointer &&
330
330
  type->primitive != PrimitiveKind::String &&
331
- type->primitive != PrimitiveKind::String16) [[unlikely]] {
331
+ type->primitive != PrimitiveKind::String16 &&
332
+ type->primitive != PrimitiveKind::String32) [[unlikely]] {
332
333
  ThrowError<Napi::Error>(env, "Cannot create disposable type for non-pointer");
333
334
  return nullptr;
334
335
  }
@@ -482,6 +483,8 @@ bool CanPassType(const TypeInfo *type, int directions)
482
483
  return true;
483
484
  if (type->primitive == PrimitiveKind::String16)
484
485
  return true;
486
+ if (type->primitive == PrimitiveKind::String32)
487
+ return true;
485
488
 
486
489
  return false;
487
490
  } else {
@@ -628,6 +631,34 @@ int GetTypedArrayType(const TypeInfo *type)
628
631
  RG_UNREACHABLE();
629
632
  }
630
633
 
634
+ Napi::String MakeStringFromUTF32(Napi::Env env, const char32_t *ptr, Size len)
635
+ {
636
+ HeapArray<char16_t> buf;
637
+ buf.Reserve(len * 2);
638
+
639
+ for (Size i = 0; i < len; i++) {
640
+ char32_t uc = ptr[i];
641
+
642
+ if (uc < 0xFFFF) {
643
+ if (uc < 0xD800 || uc > 0xDFFF) {
644
+ buf.Append((char16_t)uc);
645
+ } else {
646
+ buf.Append('?');
647
+ }
648
+ } else if (uc < 0x10FFFF) {
649
+ uc -= 0x0010000UL;
650
+
651
+ buf.Append((char16_t)((uc >> 10) + 0xD800));
652
+ buf.Append((char16_t)((uc & 0x3FFul) + 0xDC00));
653
+ } else {
654
+ buf.Append('?');
655
+ }
656
+ }
657
+
658
+ Napi::String str = Napi::String::New(env, buf.ptr, buf.len);
659
+ return str;
660
+ }
661
+
631
662
  Napi::Object DecodeObject(Napi::Env env, const uint8_t *origin, const TypeInfo *type)
632
663
  {
633
664
  // We can't decode unions because we don't know which member is valid
@@ -747,6 +778,10 @@ void DecodeObject(Napi::Object obj, const uint8_t *origin, const TypeInfo *type)
747
778
  member.type->dispose(env, member.type, str16);
748
779
  }
749
780
  } break;
781
+ case PrimitiveKind::String32: {
782
+ const char32_t *str32 = *(const char32_t **)src;
783
+ obj.Set(member.name, str32 ? MakeStringFromUTF32(env, str32) : env.Null());
784
+ } break;
750
785
  case PrimitiveKind::Pointer:
751
786
  case PrimitiveKind::Callback: {
752
787
  void *ptr2 = *(void **)src;
@@ -881,7 +916,17 @@ Napi::Value DecodeArray(Napi::Env env, const uint8_t *origin, const TypeInfo *ty
881
916
  case PrimitiveKind::Int16S: { POP_NUMBER_ARRAY_SWAP(Int16Array, int16_t); } break;
882
917
  case PrimitiveKind::UInt16: { POP_NUMBER_ARRAY(Uint16Array, uint16_t); } break;
883
918
  case PrimitiveKind::UInt16S: { POP_NUMBER_ARRAY_SWAP(Uint16Array, uint16_t); } break;
884
- case PrimitiveKind::Int32: { POP_NUMBER_ARRAY(Int32Array, int32_t); } break;
919
+ case PrimitiveKind::Int32: {
920
+ if (type->hint == ArrayHint::String) {
921
+ const char32_t *ptr = (const char32_t *)origin;
922
+ Size count = NullTerminatedLength(ptr, len);
923
+
924
+ Napi::String str = MakeStringFromUTF32(env, ptr, count);
925
+ return str;
926
+ }
927
+
928
+ POP_NUMBER_ARRAY(Int32Array, int32_t);
929
+ } break;
885
930
  case PrimitiveKind::Int32S: { POP_NUMBER_ARRAY_SWAP(Int32Array, int32_t); } break;
886
931
  case PrimitiveKind::UInt32: { POP_NUMBER_ARRAY(Uint32Array, uint32_t); } break;
887
932
  case PrimitiveKind::UInt32S: { POP_NUMBER_ARRAY_SWAP(Uint32Array, uint32_t); } break;
@@ -921,6 +966,12 @@ Napi::Value DecodeArray(Napi::Env env, const uint8_t *origin, const TypeInfo *ty
921
966
  array.Set(i, str16 ? Napi::String::New(env, str16) : env.Null());
922
967
  });
923
968
  } break;
969
+ case PrimitiveKind::String32: {
970
+ POP_ARRAY({
971
+ const char32_t *str32 = *(const char32_t **)src;
972
+ array.Set(i, str32 ? MakeStringFromUTF32(env, str32) : env.Null());
973
+ });
974
+ } break;
924
975
  case PrimitiveKind::Pointer:
925
976
  case PrimitiveKind::Callback: {
926
977
  POP_ARRAY({
@@ -1063,6 +1114,16 @@ void DecodeNormalArray(Napi::Array array, const uint8_t *origin, const TypeInfo
1063
1114
  }
1064
1115
  });
1065
1116
  } break;
1117
+ case PrimitiveKind::String32: {
1118
+ POP_ARRAY({
1119
+ const char32_t *str32 = *(const char32_t **)src;
1120
+ array.Set(i, str32 ? MakeStringFromUTF32(env, str32) : env.Null());
1121
+
1122
+ if (ref->dispose) {
1123
+ ref->dispose(env, ref, str32);
1124
+ }
1125
+ });
1126
+ } break;
1066
1127
  case PrimitiveKind::Pointer:
1067
1128
  case PrimitiveKind::Callback: {
1068
1129
  POP_ARRAY({
@@ -1171,6 +1232,7 @@ Napi::Value Decode(Napi::Env env, const uint8_t *ptr, const TypeInfo *type, cons
1171
1232
 
1172
1233
  if (len && type->primitive != PrimitiveKind::String &&
1173
1234
  type->primitive != PrimitiveKind::String16 &&
1235
+ type->primitive != PrimitiveKind::String32 &&
1174
1236
  type->primitive != PrimitiveKind::Prototype) {
1175
1237
  if (*len >= 0) {
1176
1238
  type = MakeArrayType(instance, type, *len);
@@ -1186,6 +1248,11 @@ Napi::Value Decode(Napi::Env env, const uint8_t *ptr, const TypeInfo *type, cons
1186
1248
  Size count = NullTerminatedLength((const char16_t *)ptr, RG_SIZE_MAX);
1187
1249
  type = MakeArrayType(instance, type, count);
1188
1250
  } break;
1251
+ case PrimitiveKind::Int32:
1252
+ case PrimitiveKind::UInt32: {
1253
+ Size count = NullTerminatedLength((const char32_t *)ptr, RG_SIZE_MAX);
1254
+ type = MakeArrayType(instance, type, count);
1255
+ } break;
1189
1256
 
1190
1257
  case PrimitiveKind::Pointer: {
1191
1258
  Size count = NullTerminatedLength((const void **)ptr, RG_SIZE_MAX);
@@ -1253,6 +1320,15 @@ Napi::Value Decode(Napi::Env env, const uint8_t *ptr, const TypeInfo *type, cons
1253
1320
  return str16 ? Napi::String::New(env, str16) : env.Null();
1254
1321
  }
1255
1322
  } break;
1323
+ case PrimitiveKind::String32: {
1324
+ if (len) {
1325
+ const char32_t *str32 = *(const char32_t **)ptr;
1326
+ return str32 ? MakeStringFromUTF32(env, str32, *len) : env.Null();
1327
+ } else {
1328
+ const char32_t *str32 = *(const char32_t **)ptr;
1329
+ return str32 ? MakeStringFromUTF32(env, str32) : env.Null();
1330
+ }
1331
+ } break;
1256
1332
  case PrimitiveKind::Pointer:
1257
1333
  case PrimitiveKind::Callback: {
1258
1334
  void *ptr2 = *(void **)ptr;
@@ -1348,6 +1424,7 @@ bool Encode(Napi::Env env, uint8_t *origin, Napi::Value value, const TypeInfo *t
1348
1424
 
1349
1425
  if (len && type->primitive != PrimitiveKind::String &&
1350
1426
  type->primitive != PrimitiveKind::String16 &&
1427
+ type->primitive != PrimitiveKind::String32 &&
1351
1428
  type->primitive != PrimitiveKind::Prototype) {
1352
1429
  if (*len < 0) [[unlikely]] {
1353
1430
  ThrowError<Napi::TypeError>(env, "Automatic (negative) length is only supported when decoding");
@@ -1419,6 +1496,12 @@ bool Encode(Napi::Env env, uint8_t *origin, Napi::Value value, const TypeInfo *t
1419
1496
  return false;
1420
1497
  *(const char16_t **)origin = str16;
1421
1498
  } break;
1499
+ case PrimitiveKind::String32: {
1500
+ const char32_t *str32;
1501
+ if (!call.PushString32(value, 1, &str32)) [[unlikely]]
1502
+ return false;
1503
+ *(const char32_t **)origin = str32;
1504
+ } break;
1422
1505
  case PrimitiveKind::Pointer: {
1423
1506
  void *ptr;
1424
1507
  if (!call.PushPointer(value, type, 1, &ptr)) [[unlikely]]
@@ -156,6 +156,15 @@ T GetNumber(Napi::Value value)
156
156
  RG_UNREACHABLE();
157
157
  }
158
158
 
159
+ template <typename T>
160
+ Size NullTerminatedLength(const T *ptr)
161
+ {
162
+ Size len = 0;
163
+ while (ptr[len]) {
164
+ len++;
165
+ }
166
+ return len;
167
+ }
159
168
  template <typename T>
160
169
  Size NullTerminatedLength(const T *ptr, Size max)
161
170
  {
@@ -166,6 +175,10 @@ Size NullTerminatedLength(const T *ptr, Size max)
166
175
  return len;
167
176
  }
168
177
 
178
+ Napi::String MakeStringFromUTF32(Napi::Env env, const char32_t *ptr, Size len);
179
+ static inline Napi::String MakeStringFromUTF32(Napi::Env env, const char32_t *ptr)
180
+ { return MakeStringFromUTF32(env, ptr, NullTerminatedLength(ptr)); }
181
+
169
182
  Napi::Object DecodeObject(Napi::Env env, const uint8_t *origin, const TypeInfo *type);
170
183
  void DecodeObject(Napi::Object obj, const uint8_t *origin, const TypeInfo *type);
171
184
  Napi::Value DecodeArray(Napi::Env env, const uint8_t *origin, const TypeInfo *type);
Binary file
Binary file
Binary file
Binary file