koffi 3.0.2 → 3.1.1

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 (48) hide show
  1. package/CHANGELOG.md +32 -7
  2. package/cnoke.cjs +2 -2
  3. package/doc/benchmarks.md +2 -2
  4. package/doc/callbacks.md +8 -27
  5. package/doc/{input.md → composites.md} +161 -147
  6. package/doc/contribute.md +2 -1
  7. package/doc/index.md +0 -14
  8. package/doc/{functions.md → load.md} +54 -113
  9. package/doc/migration.md +4 -7
  10. package/doc/misc.md +0 -103
  11. package/doc/output.md +5 -11
  12. package/doc/pointers.md +76 -17
  13. package/doc/primitives.md +151 -0
  14. package/doc/start.md +3 -13
  15. package/doc/types.md +88 -0
  16. package/doc/unions.md +0 -186
  17. package/doc/values.md +134 -0
  18. package/index.d.ts +23 -4
  19. package/lib/native/base/base.cc +142 -90
  20. package/lib/native/base/base.hh +69 -165
  21. package/package.json +16 -15
  22. package/src/koffi/CMakeLists.txt +19 -17
  23. package/src/koffi/index.cjs +8 -3
  24. package/src/koffi/index.js +1 -1
  25. package/src/koffi/indirect.cjs +8 -3
  26. package/src/koffi/indirect.js +1 -1
  27. package/src/koffi/src/abi/arm64.cc +47 -62
  28. package/src/koffi/src/abi/riscv64.cc +38 -57
  29. package/src/koffi/src/abi/x64sysv.cc +38 -57
  30. package/src/koffi/src/abi/x64win.cc +47 -65
  31. package/src/koffi/src/abi/x86.cc +46 -59
  32. package/src/koffi/src/call.cc +239 -133
  33. package/src/koffi/src/call.hh +5 -10
  34. package/src/koffi/src/ffi.cc +211 -90
  35. package/src/koffi/src/ffi.hh +36 -16
  36. package/src/koffi/src/parser.cc +3 -3
  37. package/src/koffi/src/parser.hh +2 -2
  38. package/src/koffi/src/static.cjs +8 -0
  39. package/src/koffi/src/static.js +11 -0
  40. package/src/koffi/src/type.cc +43 -33
  41. package/src/koffi/src/type.hh +1 -1
  42. package/src/koffi/src/util.cc +73 -173
  43. package/src/koffi/src/util.hh +84 -43
  44. package/src/koffi/src/uv.cc +1 -1
  45. package/vendor/node-addon-api/README.md +1 -1
  46. package/vendor/node-addon-api/napi-inl.h +213 -35
  47. package/vendor/node-addon-api/napi.h +118 -7
  48. package/doc/variables.md +0 -102
@@ -40,7 +40,8 @@ UnionValue::UnionValue(const Napi::CallbackInfo &info)
40
40
  {
41
41
  Napi::Env env = info.Env();
42
42
 
43
- instance = env.GetInstanceData<InstanceData>();
43
+ K_ASSERT(type->instance);
44
+ instance = type->instance;
44
45
 
45
46
  if (info.Length() >= 1) {
46
47
  if (!info[0].IsExternal()) [[unlikely]] {
@@ -57,7 +58,7 @@ UnionValue::UnionValue(const Napi::CallbackInfo &info)
57
58
 
58
59
  void UnionValue::Finalize(Napi::BasicEnv env)
59
60
  {
60
- DeleteReferenceSafe(env, *this);
61
+ node_api_delete_reference(env, *this);
61
62
  SuppressDestruct();
62
63
  }
63
64
 
@@ -137,18 +138,6 @@ bool CheckValueTag(napi_env env, napi_value value, const void *marker)
137
138
  return match;
138
139
  }
139
140
 
140
- void DeleteReferenceSafe(napi_env env, napi_ref ref)
141
- {
142
- if (node_api_post_finalizer) {
143
- node_api_post_finalizer(env, [](napi_env env, void *data, void *) {
144
- napi_ref ref = (napi_ref)data;
145
- napi_delete_reference(env, ref);
146
- }, (void *)ref, nullptr);
147
- } else {
148
- napi_delete_reference(env, ref);
149
- }
150
- }
151
-
152
141
  int GetTypedArrayType(const TypeInfo *type)
153
142
  {
154
143
  switch (type->primitive) {
@@ -167,7 +156,7 @@ int GetTypedArrayType(const TypeInfo *type)
167
156
  K_UNREACHABLE();
168
157
  }
169
158
 
170
- Napi::String MakeStringFromUTF32(Napi::Env env, const char32_t *ptr, Size len)
159
+ static FORCE_INLINE napi_value NewStringUTF32(Napi::Env env, const char32_t *ptr, Size len)
171
160
  {
172
161
  static const char16_t ReplacementChar = 0xFFFD;
173
162
 
@@ -193,8 +182,30 @@ Napi::String MakeStringFromUTF32(Napi::Env env, const char32_t *ptr, Size len)
193
182
  }
194
183
  }
195
184
 
196
- Napi::String str = Napi::String::New(env, buf.ptr, buf.len);
197
- return str;
185
+ return NewString(env, buf.ptr, buf.len);
186
+ }
187
+
188
+ napi_value NewString(Napi::Env env, const char32_t *ptr, Size len)
189
+ {
190
+ if (ptr) {
191
+ return NewStringUTF32(env, ptr, len);
192
+ } else {
193
+ napi_value value;
194
+ NAPI_OK(napi_get_null(env, &value));
195
+ return value;
196
+ }
197
+ }
198
+
199
+ napi_value NewString(Napi::Env env, const char32_t *ptr)
200
+ {
201
+ if (ptr) {
202
+ Size len = NullTerminatedLength(ptr);
203
+ return NewStringUTF32(env, ptr, len);
204
+ } else {
205
+ napi_value value;
206
+ NAPI_OK(napi_get_null(env, &value));
207
+ return value;
208
+ }
198
209
  }
199
210
 
200
211
  static uint32_t DecodeDynamicLength(const uint8_t *origin, const RecordMember &by)
@@ -379,25 +390,25 @@ static FORCE_INLINE void DecodeObject(InstanceData *instance, const uint8_t *ori
379
390
  case PrimitiveKind::String: {
380
391
  const char *str;
381
392
  memcpy(&str, src, K_SIZE(void *));
382
- set(i, member, str ? Napi::String::New(env, str) : env.Null());
393
+ set(i, member, NewString(env, str));
383
394
 
384
395
  if (member.type->dispose) {
385
- member.type->dispose(env, member.type, str);
396
+ member.type->dispose(instance, member.type, str);
386
397
  }
387
398
  } break;
388
399
  case PrimitiveKind::String16: {
389
400
  const char16_t *str16;
390
401
  memcpy(&str16, src, K_SIZE(void *));
391
- set(i, member, str16 ? Napi::String::New(env, str16) : env.Null());
402
+ set(i, member, NewString(env, str16));
392
403
 
393
404
  if (member.type->dispose) {
394
- member.type->dispose(env, member.type, str16);
405
+ member.type->dispose(instance, member.type, str16);
395
406
  }
396
407
  } break;
397
408
  case PrimitiveKind::String32: {
398
409
  const char32_t *str32;
399
410
  memcpy(&str32, src, K_SIZE(void *));
400
- set(i, member, str32 ? MakeStringFromUTF32(env, str32) : env.Null());
411
+ set(i, member, NewString(env, str32));
401
412
  } break;
402
413
  case PrimitiveKind::Pointer: {
403
414
  void *ptr2;
@@ -410,23 +421,23 @@ static FORCE_INLINE void DecodeObject(InstanceData *instance, const uint8_t *ori
410
421
  napi_value value = DecodeArray(instance, (const uint8_t *)ptr2, member.type, len);
411
422
  set(i, member, value);
412
423
  } else {
413
- napi_value p = ptr2 ? WrapPointer(env, member.type->ref.type, ptr2) : env.Null();
424
+ napi_value p = WrapPointer(env, member.type->ref.type, ptr2);
414
425
  set(i, member, p);
415
426
  }
416
427
 
417
428
  if (member.type->dispose) {
418
- member.type->dispose(env, member.type, ptr2);
429
+ member.type->dispose(instance, member.type, ptr2);
419
430
  }
420
431
  } break;
421
432
  case PrimitiveKind::Callback: {
422
433
  void *ptr2;
423
434
  memcpy(&ptr2, src, K_SIZE(void *));
424
435
 
425
- napi_value p = ptr2 ? WrapPointer(env, member.type->ref.type, ptr2) : env.Null();
436
+ napi_value p = WrapPointer(env, member.type->ref.type, ptr2);
426
437
  set(i, member, p);
427
438
 
428
439
  if (member.type->dispose) {
429
- member.type->dispose(env, member.type, ptr2);
440
+ member.type->dispose(instance, member.type, ptr2);
430
441
  }
431
442
  } break;
432
443
  case PrimitiveKind::Record:
@@ -454,12 +465,12 @@ static FORCE_INLINE void DecodeObject(InstanceData *instance, const uint8_t *ori
454
465
  case PrimitiveKind::Float32: {
455
466
  float f;
456
467
  memcpy(&f, src, 4);
457
- set(i, member, Napi::Number::New(env, (double)f));
468
+ set(i, member, NewFloat(env, f));
458
469
  } break;
459
470
  case PrimitiveKind::Float64: {
460
471
  double d;
461
472
  memcpy(&d, src, 8);
462
- set(i, member, Napi::Number::New(env, d));
473
+ set(i, member, NewFloat(env, d));
463
474
  } break;
464
475
 
465
476
  case PrimitiveKind::Prototype: { K_UNREACHABLE(); } break;
@@ -473,8 +484,16 @@ napi_value DecodeObject(InstanceData *instance, const uint8_t *origin, const Typ
473
484
 
474
485
  // We can't decode unions because we don't know which member is valid
475
486
  if (type->primitive == PrimitiveKind::Union) {
487
+ Napi::Function construct;
488
+ {
489
+ napi_value value;
490
+ NAPI_OK(napi_get_reference_value(env, type->construct, &value));
491
+
492
+ construct = Napi::Function(env, value);
493
+ }
494
+
476
495
  Napi::External<void> external = Napi::External<void>::New(env, (void *)origin);
477
- Napi::Object wrapper = type->construct.New({ external }).As<Napi::Object>();
496
+ Napi::Object wrapper = construct.New({ external }).As<Napi::Object>();
478
497
  SetValueTag(env, wrapper, &UnionValueMarker);
479
498
 
480
499
  return wrapper;
@@ -507,14 +526,14 @@ void DecodeObject(InstanceData *instance, napi_value obj, const uint8_t *origin,
507
526
  Napi::Env env = instance->env;
508
527
 
509
528
  if (node_api_create_property_key_utf8) {
510
- DecodeObject(instance, origin, type, [&](Size i, const RecordMember &member, napi_value value) {
529
+ DecodeObject(instance, origin, type, [&](Size, const RecordMember &member, napi_value value) {
511
530
  napi_value key = nullptr;
512
531
  napi_get_reference_value(env, member.key, &key);
513
532
 
514
533
  NAPI_OK(napi_set_property(env, obj, key, value));
515
534
  });
516
535
  } else {
517
- DecodeObject(instance, origin, type, [&](Size i, const RecordMember &member, napi_value value) {
536
+ DecodeObject(instance, origin, type, [&](Size, const RecordMember &member, napi_value value) {
518
537
  NAPI_OK(napi_set_named_property(env, obj, member.name, value));
519
538
  });
520
539
  }
@@ -602,22 +621,19 @@ napi_value DecodeArray(InstanceData *instance, const uint8_t *origin, const Type
602
621
  const char *ptr = (const char *)origin;
603
622
  size_t count = strnlen(ptr, (size_t)len);
604
623
 
605
- Napi::String str = Napi::String::New(env, ptr, count);
606
- return str;
624
+ return NewString(env, ptr, count);
607
625
  } break;
608
626
  case PrimitiveKind::Int16: {
609
627
  const char16_t *ptr = (const char16_t *)origin;
610
628
  Size count = NullTerminatedLength(ptr, len);
611
629
 
612
- Napi::String str = Napi::String::New(env, ptr, count);
613
- return str;
630
+ return NewString(env, ptr, count);
614
631
  } break;
615
632
  case PrimitiveKind::Int32: {
616
633
  const char32_t *ptr = (const char32_t *)origin;
617
634
  Size count = NullTerminatedLength(ptr, len);
618
635
 
619
- Napi::String str = MakeStringFromUTF32(env, ptr, count);
620
- return str;
636
+ return NewString(env, ptr, count);
621
637
  } break;
622
638
 
623
639
  case PrimitiveKind::Void:
@@ -717,30 +733,30 @@ void DecodeElements(InstanceData *instance, napi_value array, const uint8_t *ori
717
733
  case PrimitiveKind::String: {
718
734
  POP_ARRAY({
719
735
  const char *str = *(const char **)src;
720
- napi_set_element(env, array, i, str ? Napi::String::New(env, str) : env.Null());
736
+ napi_set_element(env, array, i, NewString(env, str));
721
737
 
722
738
  if (ref->dispose) {
723
- ref->dispose(env, ref, str);
739
+ ref->dispose(instance, ref, str);
724
740
  }
725
741
  });
726
742
  } break;
727
743
  case PrimitiveKind::String16: {
728
744
  POP_ARRAY({
729
745
  const char16_t *str16 = *(const char16_t **)src;
730
- napi_set_element(env, array, i, str16 ? Napi::String::New(env, str16) : env.Null());
746
+ napi_set_element(env, array, i, NewString(env, str16));
731
747
 
732
748
  if (ref->dispose) {
733
- ref->dispose(env, ref, str16);
749
+ ref->dispose(instance, ref, str16);
734
750
  }
735
751
  });
736
752
  } break;
737
753
  case PrimitiveKind::String32: {
738
754
  POP_ARRAY({
739
755
  const char32_t *str32 = *(const char32_t **)src;
740
- napi_set_element(env, array, i, str32 ? MakeStringFromUTF32(env, str32) : env.Null());
756
+ napi_set_element(env, array, i, NewString(env, str32));
741
757
 
742
758
  if (ref->dispose) {
743
- ref->dispose(env, ref, str32);
759
+ ref->dispose(instance, ref, str32);
744
760
  }
745
761
  });
746
762
  } break;
@@ -748,11 +764,11 @@ void DecodeElements(InstanceData *instance, napi_value array, const uint8_t *ori
748
764
  POP_ARRAY({
749
765
  void *ptr2 = *(void **)src;
750
766
 
751
- napi_value p = ptr2 ? WrapPointer(env, ref->ref.type, ptr2) : env.Null();
767
+ napi_value p = WrapPointer(env, ref->ref.type, ptr2);
752
768
  napi_set_element(env, array, i, p);
753
769
 
754
770
  if (ref->dispose) {
755
- ref->dispose(env, ref, ptr2);
771
+ ref->dispose(instance, ref, ptr2);
756
772
  }
757
773
  });
758
774
  } break;
@@ -760,11 +776,11 @@ void DecodeElements(InstanceData *instance, napi_value array, const uint8_t *ori
760
776
  POP_ARRAY({
761
777
  void *ptr2 = *(void **)src;
762
778
 
763
- napi_value p = ptr2 ? WrapPointer(env, ref->ref.type, ptr2) : env.Null();
779
+ napi_value p = WrapPointer(env, ref->ref.type, ptr2);
764
780
  napi_set_element(env, array, i, p);
765
781
 
766
782
  if (ref->dispose) {
767
- ref->dispose(env, ref, ptr2);
783
+ ref->dispose(instance, ref, ptr2);
768
784
  }
769
785
  });
770
786
  } break;
@@ -786,7 +802,7 @@ void DecodeElements(InstanceData *instance, napi_value array, const uint8_t *ori
786
802
  float f;
787
803
  memcpy(&f, src, 4);
788
804
 
789
- napi_set_element(env, array, i, Napi::Number::New(env, (double)f));
805
+ napi_set_element(env, array, i, NewFloat(env, f));
790
806
  });
791
807
  } break;
792
808
  case PrimitiveKind::Float64: {
@@ -794,7 +810,7 @@ void DecodeElements(InstanceData *instance, napi_value array, const uint8_t *ori
794
810
  double d;
795
811
  memcpy(&d, src, 8);
796
812
 
797
- napi_set_element(env, array, i, Napi::Number::New(env, d));
813
+ napi_set_element(env, array, i, NewFloat(env, d));
798
814
  });
799
815
  } break;
800
816
 
@@ -888,23 +904,23 @@ napi_value Decode(InstanceData *instance, const uint8_t *ptr, const TypeInfo *ty
888
904
  case PrimitiveKind::UInt64S: { RETURN_INT_SWAP(uint64_t, NewInt); } break;
889
905
  case PrimitiveKind::String: {
890
906
  const char *str = *(const char **)ptr;
891
- return str ? Napi::String::New(env, str) : env.Null();
907
+ return NewString(env, str);
892
908
  } break;
893
909
  case PrimitiveKind::String16: {
894
910
  const char16_t *str16 = *(const char16_t **)ptr;
895
- return str16 ? Napi::String::New(env, str16) : env.Null();
911
+ return NewString(env, str16);
896
912
  } break;
897
913
  case PrimitiveKind::String32: {
898
914
  const char32_t *str32 = *(const char32_t **)ptr;
899
- return str32 ? MakeStringFromUTF32(env, str32) : env.Null();
915
+ return NewString(env, str32);
900
916
  } break;
901
917
  case PrimitiveKind::Pointer: {
902
918
  void *ptr2 = *(void **)ptr;
903
- return ptr2 ? WrapPointer(env, type->ref.type, ptr2) : env.Null();
919
+ return WrapPointer(env, type->ref.type, ptr2);
904
920
  } break;
905
921
  case PrimitiveKind::Callback: {
906
922
  void *ptr2 = *(void **)ptr;
907
- return ptr2 ? WrapPointer(env, type->ref.type, ptr2) : env.Null();
923
+ return WrapPointer(env, type->ref.type, ptr2);
908
924
  } break;
909
925
  case PrimitiveKind::Record:
910
926
  case PrimitiveKind::Union: { return DecodeObject(instance, ptr, type); } break;
@@ -916,13 +932,13 @@ napi_value Decode(InstanceData *instance, const uint8_t *ptr, const TypeInfo *ty
916
932
  float f;
917
933
  memcpy(&f, ptr, 4);
918
934
 
919
- return Napi::Number::New(env, (double)f);
935
+ return NewFloat(env, f);
920
936
  } break;
921
937
  case PrimitiveKind::Float64: {
922
938
  double d;
923
939
  memcpy(&d, ptr, 8);
924
940
 
925
- return Napi::Number::New(env, d);
941
+ return NewFloat(env, d);
926
942
  } break;
927
943
 
928
944
  case PrimitiveKind::Prototype: {
@@ -944,7 +960,7 @@ napi_value Decode(InstanceData *instance, const uint8_t *ptr, const TypeInfo *ty
944
960
  func->sync = proto->sync;
945
961
  func->async = proto->async;
946
962
 
947
- return WrapFunction(env, func);
963
+ return WrapFunction(instance, func);
948
964
  } break;
949
965
  }
950
966
 
@@ -954,122 +970,6 @@ napi_value Decode(InstanceData *instance, const uint8_t *ptr, const TypeInfo *ty
954
970
  return env.Null();
955
971
  }
956
972
 
957
- static bool CanTypeAcceptCallbacks(const TypeInfo *type)
958
- {
959
- if (type->primitive == PrimitiveKind::Pointer)
960
- return true;
961
- if (type->primitive == PrimitiveKind::Callback)
962
- return true;
963
-
964
- if (type->primitive == PrimitiveKind::Record ||
965
- type->primitive == PrimitiveKind::Union) {
966
- for (const RecordMember &member: type->members) {
967
- if (CanTypeAcceptCallbacks(member.type))
968
- return false;
969
- }
970
- }
971
-
972
- return true;
973
- }
974
-
975
- static bool CanUseFastCall(const FunctionInfo *func)
976
- {
977
- if (func->parameters.len > 6)
978
- return false;
979
-
980
- // Fast calls basically skip CallData::Finalize(), which handles output arguments
981
- // and temporary callback trampolines. If the function does not use any
982
- // output argument and cannot accept callbacks (so no pointer or callback arguments),
983
- // we can skip finalization!
984
-
985
- for (const ParameterInfo &param: func->parameters) {
986
- if (param.directions & 2)
987
- return false;
988
- if (CanTypeAcceptCallbacks(param.type))
989
- return false;
990
- }
991
-
992
- return true;
993
- }
994
-
995
- napi_value DescribeFunction(Napi::Env env, const FunctionInfo *func)
996
- {
997
- static const char *const DirectionNames[] = {
998
- nullptr,
999
- "Input",
1000
- "Output",
1001
- "Input/Output"
1002
- };
1003
-
1004
- Napi::Object meta = Napi::Object::New(env);
1005
- Napi::Array arguments = Napi::Array::New(env, func->parameters.len);
1006
-
1007
- meta.Set("name", Napi::String::New(env, func->name));
1008
- meta.Set("arguments", arguments);
1009
- meta.Set("result", WrapType(env, func->ret.type));
1010
-
1011
- for (Size i = 0; i < func->parameters.len; i++) {
1012
- const ParameterInfo &param = func->parameters[i];
1013
- Napi::Object obj = Napi::Object::New(env);
1014
-
1015
- obj.Set("type", WrapType(env, param.type));
1016
- obj.Set("direction", Napi::String::New(env, DirectionNames[param.directions]));
1017
-
1018
- arguments.Set((uint32_t)i, obj);
1019
- }
1020
-
1021
- meta.Freeze();
1022
-
1023
- return meta;
1024
- }
1025
-
1026
- static bool IsDebugAsyncEnabled()
1027
- {
1028
- static bool debug = GetDebugFlag("DEBUG_ASYNC");
1029
- return debug;
1030
- }
1031
-
1032
- napi_value WrapFunction(Napi::Env env, const FunctionInfo *func)
1033
- {
1034
- Napi::Function wrapper;
1035
-
1036
- // Pick appropriate wrapper
1037
- {
1038
- napi_value value;
1039
-
1040
- if (func->variadic) {
1041
- NAPI_OK(napi_create_function(env, func->name, NAPI_AUTO_LENGTH, TranslateVariadicCall, (void *)func->Ref(), &value));
1042
- } else if (IsDebugAsyncEnabled()) {
1043
- NAPI_OK(napi_create_function(env, func->name, NAPI_AUTO_LENGTH, TranslateNormalCallDebugAsync, (void *)func->Ref(), &value));
1044
- } else if (!func->parameters.len) {
1045
- InstanceData *instance = env.GetInstanceData<InstanceData>();
1046
- NAPI_OK(napi_create_function(env, func->name, NAPI_AUTO_LENGTH, instance->translate_zero_call, (void *)func->Ref(), &value));
1047
- } else if (CanUseFastCall(func)) {
1048
- NAPI_OK(napi_create_function(env, func->name, NAPI_AUTO_LENGTH, TranslateFastCall, (void *)func->Ref(), &value));
1049
- } else {
1050
- NAPI_OK(napi_create_function(env, func->name, NAPI_AUTO_LENGTH, TranslateNormalCall, (void *)func->Ref(), &value));
1051
- }
1052
-
1053
- wrapper = Napi::Function(env, value);
1054
- wrapper.AddFinalizer([](Napi::Env, FunctionInfo *func) { func->Unref(); }, (FunctionInfo *)func);
1055
- }
1056
-
1057
- if (!func->variadic) {
1058
- napi_value value;
1059
- NAPI_OK(napi_create_function(env, func->name, NAPI_AUTO_LENGTH, TranslateAsyncCall, (void *)func->Ref(), &value));
1060
-
1061
- Napi::Function async = Napi::Function(env, value);
1062
- async.AddFinalizer([](Napi::Env, FunctionInfo *func) { func->Unref(); }, (FunctionInfo *)func);
1063
-
1064
- wrapper.Set("async", async);
1065
- }
1066
-
1067
- napi_value meta = DescribeFunction(env, func);
1068
- wrapper.Set("info", meta);
1069
-
1070
- return wrapper;
1071
- }
1072
-
1073
973
  bool DetectCallConvention(Span<const char> name, CallConvention *out_convention)
1074
974
  {
1075
975
  if (name == "__cdecl") {
@@ -57,8 +57,6 @@ static FORCE_INLINE napi_valuetype GetKindOf(napi_env env, napi_value value)
57
57
  void SetValueTag(napi_env env, napi_value value, const void *marker);
58
58
  bool CheckValueTag(napi_env env, napi_value value, const void *marker);
59
59
 
60
- void DeleteReferenceSafe(napi_env env, napi_ref ref);
61
-
62
60
  static FORCE_INLINE bool IsNullOrUndefined(napi_valuetype kind)
63
61
  {
64
62
  return kind == napi_null || kind == napi_undefined;
@@ -343,39 +341,6 @@ static FORCE_INLINE bool TryBuffer(napi_env env, napi_value value, Span<uint8_t>
343
341
 
344
342
  int GetTypedArrayType(const TypeInfo *type);
345
343
 
346
- template <typename T>
347
- Size NullTerminatedLength(const T *ptr)
348
- {
349
- Size len = 0;
350
- while (ptr[len]) {
351
- len++;
352
- }
353
- return len;
354
- }
355
- template <typename T>
356
- Size NullTerminatedLength(const T *ptr, Size max)
357
- {
358
- Size len = 0;
359
- while (len < max && ptr[len]) {
360
- len++;
361
- }
362
- return len;
363
- }
364
-
365
- Napi::String MakeStringFromUTF32(Napi::Env env, const char32_t *ptr, Size len);
366
- static inline Napi::String MakeStringFromUTF32(Napi::Env env, const char32_t *ptr)
367
- { return MakeStringFromUTF32(env, ptr, NullTerminatedLength(ptr)); }
368
-
369
- napi_value DecodeObject(InstanceData *instance, const uint8_t *origin, const TypeInfo *type);
370
- void DecodeObject(InstanceData *instance, napi_value obj, const uint8_t *origin, const TypeInfo *type);
371
-
372
- napi_value DecodeArray(InstanceData *instance, const uint8_t *origin, const TypeInfo *type);
373
- napi_value DecodeArray(InstanceData *instance, const uint8_t *origin, const TypeInfo *type, uint32_t len);
374
- void DecodeElements(InstanceData *instance, napi_value array, const uint8_t *origin, const TypeInfo *type, uint32_t len);
375
- INLINE_UNITY void DecodeBuffer(Span<uint8_t> buffer, const uint8_t *origin, const TypeInfo *type);
376
-
377
- napi_value Decode(InstanceData *instance, const uint8_t *ptr, const TypeInfo *type);
378
-
379
344
  static FORCE_INLINE napi_value NewInt(Napi::Env env, char i) { napi_value value; napi_create_int32(env, (int32_t)i, &value); return value; }
380
345
  static FORCE_INLINE napi_value NewInt(Napi::Env env, signed char i) { napi_value value; napi_create_int32(env, (int32_t)i, &value); return value; }
381
346
  static FORCE_INLINE napi_value NewInt(Napi::Env env, unsigned char i) { napi_value value; napi_create_uint32(env, (uint32_t)i, &value); return value; }
@@ -414,6 +379,83 @@ static FORCE_INLINE napi_value NewInt(Napi::Env env, T i)
414
379
  }
415
380
  }
416
381
 
382
+ static FORCE_INLINE napi_value NewFloat(Napi::Env env, float f) { napi_value value; napi_create_double(env, (double)f, &value); return value; }
383
+ static FORCE_INLINE napi_value NewFloat(Napi::Env env, double d) { napi_value value; napi_create_double(env, d, &value); return value; }
384
+
385
+ template <typename T>
386
+ static FORCE_INLINE Size NullTerminatedLength(const T *ptr)
387
+ {
388
+ Size len = 0;
389
+ while (ptr[len]) {
390
+ len++;
391
+ }
392
+ return len;
393
+ }
394
+ template <typename T>
395
+ static FORCE_INLINE Size NullTerminatedLength(const T *ptr, Size max)
396
+ {
397
+ Size len = 0;
398
+ while (len < max && ptr[len]) {
399
+ len++;
400
+ }
401
+ return len;
402
+ }
403
+
404
+ static FORCE_INLINE napi_value NewString(Napi::Env env, const char *ptr, Size len)
405
+ {
406
+ napi_value value;
407
+ if (ptr) {
408
+ NAPI_OK(napi_create_string_utf8(env, ptr, (size_t)len, &value));
409
+ } else {
410
+ NAPI_OK(napi_get_null(env, &value));
411
+ }
412
+ return value;
413
+ }
414
+ static FORCE_INLINE napi_value NewString(Napi::Env env, const char *ptr)
415
+ {
416
+ napi_value value;
417
+ if (ptr) {
418
+ NAPI_OK(napi_create_string_utf8(env, ptr, NAPI_AUTO_LENGTH, &value));
419
+ } else {
420
+ NAPI_OK(napi_get_null(env, &value));
421
+ }
422
+ return value;
423
+ }
424
+
425
+ static FORCE_INLINE napi_value NewString(Napi::Env env, const char16_t *ptr, Size len)
426
+ {
427
+ napi_value value;
428
+ if (ptr) {
429
+ NAPI_OK(napi_create_string_utf16(env, ptr, (size_t)len, &value));
430
+ } else {
431
+ NAPI_OK(napi_get_null(env, &value));
432
+ }
433
+ return value;
434
+ }
435
+ static FORCE_INLINE napi_value NewString(Napi::Env env, const char16_t *ptr)
436
+ {
437
+ napi_value value;
438
+ if (ptr) {
439
+ NAPI_OK(napi_create_string_utf16(env, ptr, NAPI_AUTO_LENGTH, &value));
440
+ } else {
441
+ NAPI_OK(napi_get_null(env, &value));
442
+ }
443
+ return value;
444
+ }
445
+
446
+ napi_value NewString(Napi::Env env, const char32_t *ptr, Size len);
447
+ napi_value NewString(Napi::Env env, const char32_t *ptr);
448
+
449
+ napi_value DecodeObject(InstanceData *instance, const uint8_t *origin, const TypeInfo *type);
450
+ void DecodeObject(InstanceData *instance, napi_value obj, const uint8_t *origin, const TypeInfo *type);
451
+
452
+ napi_value DecodeArray(InstanceData *instance, const uint8_t *origin, const TypeInfo *type);
453
+ napi_value DecodeArray(InstanceData *instance, const uint8_t *origin, const TypeInfo *type, uint32_t len);
454
+ void DecodeElements(InstanceData *instance, napi_value array, const uint8_t *origin, const TypeInfo *type, uint32_t len);
455
+ INLINE_UNITY void DecodeBuffer(Span<uint8_t> buffer, const uint8_t *origin, const TypeInfo *type);
456
+
457
+ napi_value Decode(InstanceData *instance, const uint8_t *ptr, const TypeInfo *type);
458
+
417
459
  static FORCE_INLINE Napi::Array GetOwnPropertyNames(napi_env env, napi_value obj)
418
460
  {
419
461
  K_ASSERT(IsObject(env, obj));
@@ -427,24 +469,23 @@ static FORCE_INLINE Napi::Array GetOwnPropertyNames(napi_env env, napi_value obj
427
469
  return Napi::Array(env, result);
428
470
  }
429
471
 
430
- napi_value DescribeFunction(Napi::Env env, const FunctionInfo *func);
431
- napi_value WrapFunction(Napi::Env env, const FunctionInfo *func);
432
-
433
- static FORCE_INLINE napi_value WrapPointer(Napi::Env env, const TypeInfo *ref, void *ptr)
472
+ static FORCE_INLINE napi_value WrapPointer(Napi::Env env, const TypeInfo *, void *ptr)
434
473
  {
435
474
  napi_value value;
436
475
 
476
+ if (ptr) {
437
477
  #if defined(EXTERNAL_POINTERS)
438
- NAPI_OK(napi_create_external(env, ptr, nullptr, nullptr, &value));
478
+ NAPI_OK(napi_create_external(env, ptr, nullptr, nullptr, &value));
439
479
  #else
440
- NAPI_OK(napi_create_bigint_uint64(env, (uint64_t)(uintptr_t)ptr, &value));
480
+ NAPI_OK(napi_create_bigint_uint64(env, (uint64_t)(uintptr_t)ptr, &value));
441
481
  #endif
482
+ } else {
483
+ NAPI_OK(napi_get_null(env, &value));
484
+ }
442
485
 
443
486
  return value;
444
487
  }
445
488
 
446
- bool DetectCallConvention(Span<const char> name, CallConvention *out_convention);
447
-
448
489
  int AnalyseFlat(const TypeInfo *type, FunctionRef<void(const TypeInfo *type, int offset, int count)> func);
449
490
 
450
491
  void DumpMemory(const char *type, Span<const uint8_t> bytes);
@@ -104,7 +104,7 @@ void PollHandle::Start(const Napi::CallbackInfo &info)
104
104
 
105
105
  void PollHandle::Finalize(Napi::BasicEnv env)
106
106
  {
107
- DeleteReferenceSafe(env, *this);
107
+ node_api_delete_reference(env, *this);
108
108
  SuppressDestruct();
109
109
 
110
110
  Close();
@@ -19,7 +19,7 @@ and exception handling semantics with low overhead.
19
19
  API references are available in the [doc](doc/README.md) directory.
20
20
 
21
21
  <!-- x-release-please-start-version -->
22
- ## Current version: 8.5.0
22
+ ## Current version: 8.9.0
23
23
  <!-- x-release-please-end -->
24
24
 
25
25
  (See [CHANGELOG.md](CHANGELOG.md) for complete Changelog)