koffi 3.0.2 → 3.1.0

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 (47) hide show
  1. package/CHANGELOG.md +25 -7
  2. package/cnoke.cjs +9 -9
  3. package/doc/benchmarks.md +2 -2
  4. package/doc/callbacks.md +7 -26
  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 +66 -24
  20. package/lib/native/base/base.hh +55 -153
  21. package/package.json +15 -15
  22. package/src/koffi/CMakeLists.txt +19 -17
  23. package/src/koffi/index.cjs +15 -10
  24. package/src/koffi/index.js +6 -6
  25. package/src/koffi/indirect.cjs +15 -10
  26. package/src/koffi/indirect.js +6 -6
  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.js +3 -0
  39. package/src/koffi/src/type.cc +43 -33
  40. package/src/koffi/src/type.hh +1 -1
  41. package/src/koffi/src/util.cc +73 -173
  42. package/src/koffi/src/util.hh +84 -43
  43. package/src/koffi/src/uv.cc +1 -1
  44. package/vendor/node-addon-api/README.md +1 -1
  45. package/vendor/node-addon-api/napi-inl.h +213 -35
  46. package/vendor/node-addon-api/napi.h +118 -7
  47. package/doc/variables.md +0 -102
@@ -46,12 +46,12 @@ const napi_type_tag CastMarker = { 0x77f459614a0a412f, 0x80b3dda1341dc8df };
46
46
  SharedData shared;
47
47
 
48
48
  // Some Node-API functions are loaded dynamically to work around bugs or because they are recent
49
+ napi_status (NAPI_CDECL *node_api_delete_reference)(node_api_basic_env env, napi_ref ref);
49
50
  napi_status (NAPI_CDECL *node_api_get_buffer_info)(napi_env env, napi_value value, void **data, size_t *length);
50
51
  napi_status (NAPI_CDECL *node_api_create_property_key_utf8)(napi_env env, const char* str, size_t length, napi_value* result);
51
52
  napi_status (NAPI_CDECL *node_api_post_finalizer)(node_api_basic_env env, napi_finalize finalize_cb, void* finalize_data, void* finalize_hint);
52
53
  napi_status (NAPI_CDECL *node_api_create_object_with_properties)(napi_env env, napi_value prototype_or_null, const napi_value *property_names,
53
54
  const napi_value *property_values, size_t property_count, napi_value *result);
54
- napi_value (*translate_zero_call)(napi_env env, napi_callback_info info);
55
55
 
56
56
  static bool ChangeSize(InstanceData *instance, const char *name, Napi::Value value, Size min_size, Size max_size, Size *out_size)
57
57
  {
@@ -308,6 +308,7 @@ static Napi::Value CreateStructType(const Napi::CallbackInfo &info, bool pad)
308
308
  replace = (TypeInfo *)defn->GetType();
309
309
  #endif
310
310
 
311
+ type->instance = instance;
311
312
  type->name = replace->name;
312
313
 
313
314
  if (replace->primitive != PrimitiveKind::Void || replace == instance->void_type) {
@@ -315,11 +316,13 @@ static Napi::Value CreateStructType(const Napi::CallbackInfo &info, bool pad)
315
316
  return env.Null();
316
317
  }
317
318
  } else if (named) {
319
+ type->instance = instance;
318
320
  type->name = DuplicateString(name.Utf8Value().c_str(), &instance->str_alloc).ptr;
319
321
 
320
322
  if (!MapType(env, instance, type, type->name))
321
323
  return env.Null();
322
324
  } else {
325
+ type->instance = instance;
323
326
  type->name = Fmt(&instance->str_alloc, "<anonymous_%1>", instance->types.count).ptr;
324
327
  }
325
328
 
@@ -429,11 +432,11 @@ static Napi::Value CreateStructType(const Napi::CallbackInfo &info, bool pad)
429
432
  err_guard.Disable();
430
433
 
431
434
  if (replace) {
432
- std::swap(*type, *replace);
435
+ *replace = std::move(*type);
433
436
  type = replace;
434
437
  }
435
438
 
436
- napi_value wrapper = WrapType(env, type);
439
+ napi_value wrapper = WrapType(instance, type);
437
440
  return Napi::Value(env, wrapper);
438
441
  }
439
442
 
@@ -507,6 +510,7 @@ static Napi::Value CreateUnionType(const Napi::CallbackInfo &info)
507
510
  replace = (TypeInfo *)defn->GetType();
508
511
  #endif
509
512
 
513
+ type->instance = instance;
510
514
  type->name = replace->name;
511
515
 
512
516
  if (replace->primitive != PrimitiveKind::Void || replace == instance->void_type) {
@@ -514,11 +518,13 @@ static Napi::Value CreateUnionType(const Napi::CallbackInfo &info)
514
518
  return env.Null();
515
519
  }
516
520
  } else if (named) {
521
+ type->instance = instance;
517
522
  type->name = DuplicateString(name.Utf8Value().c_str(), &instance->str_alloc).ptr;
518
523
 
519
524
  if (!MapType(env, instance, type, type->name))
520
525
  return env.Null();
521
526
  } else {
527
+ type->instance = instance;
522
528
  type->name = Fmt(&instance->str_alloc, "<anonymous_%1>", instance->types.count).ptr;
523
529
  }
524
530
 
@@ -597,14 +603,15 @@ static Napi::Value CreateUnionType(const Napi::CallbackInfo &info)
597
603
  return env.Null();
598
604
  err_guard.Disable();
599
605
 
600
- type->construct = Napi::Persistent(UnionValue::InitClass(instance, type));
606
+ Napi::Object construct = UnionValue::InitClass(instance, type);
607
+ NAPI_OK(napi_create_reference(env, construct, 1, &type->construct));
601
608
 
602
609
  if (replace) {
603
- std::swap(*type, *replace);
610
+ *replace = std::move(*type);
604
611
  type = replace;
605
612
  }
606
613
 
607
- napi_value wrapper = WrapType(env, type);
614
+ napi_value wrapper = WrapType(instance, type);
608
615
  return Napi::Value(env, wrapper);
609
616
  }
610
617
 
@@ -630,7 +637,15 @@ Napi::Value InstantiateUnion(const Napi::CallbackInfo &info)
630
637
  return env.Null();
631
638
  }
632
639
 
633
- Napi::Object wrapper = type->construct.New({}).As<Napi::Object>();
640
+ Napi::Function construct;
641
+ {
642
+ napi_value value;
643
+ NAPI_OK(napi_get_reference_value(env, type->construct, &value));
644
+
645
+ construct = Napi::Function(env, value);
646
+ }
647
+
648
+ Napi::Object wrapper = construct.New({}).As<Napi::Object>();
634
649
  SetValueTag(env, wrapper, &UnionValueMarker);
635
650
 
636
651
  return wrapper;
@@ -653,6 +668,7 @@ static Napi::Value CreateOpaqueType(const Napi::CallbackInfo &info)
653
668
  TypeInfo *type = instance->types.AppendDefault();
654
669
  K_DEFER_N(err_guard) { instance->types.RemoveLast(1); };
655
670
 
671
+ type->instance = instance;
656
672
  type->name = named ? DuplicateString(name.Utf8Value().c_str(), &instance->str_alloc).ptr
657
673
  : Fmt(&instance->str_alloc, "<anonymous_%1>", instance->types.count).ptr;
658
674
 
@@ -665,7 +681,7 @@ static Napi::Value CreateOpaqueType(const Napi::CallbackInfo &info)
665
681
  return env.Null();
666
682
  err_guard.Disable();
667
683
 
668
- napi_value wrapper = WrapType(env, type);
684
+ napi_value wrapper = WrapType(instance, type);
669
685
  return Napi::Value(env, wrapper);
670
686
  }
671
687
 
@@ -721,7 +737,7 @@ static Napi::Value CreatePointerType(const Napi::CallbackInfo &info)
721
737
 
722
738
  memcpy((void *)copy, type, K_SIZE(*type));
723
739
  copy->name = named ? DuplicateString(name.c_str(), &instance->str_alloc).ptr : copy->name;
724
- memset((void *)&copy->defn, 0, K_SIZE(copy->defn));
740
+ copy->defn = nullptr;
725
741
 
726
742
  static_assert(!std::is_polymorphic_v<Napi::ObjectReference>);
727
743
 
@@ -738,7 +754,7 @@ static Napi::Value CreatePointerType(const Napi::CallbackInfo &info)
738
754
  type = copy;
739
755
  }
740
756
 
741
- napi_value wrapper = WrapType(env, type);
757
+ napi_value wrapper = WrapType(instance, type);
742
758
  return Napi::Value(env, wrapper);
743
759
  }
744
760
 
@@ -835,21 +851,21 @@ static Napi::Value CreateDisposableType(const Napi::CallbackInfo &info)
835
851
  return env.Null();
836
852
  }
837
853
 
838
- dispose = [](Napi::Env env, const TypeInfo *type, const void *ptr) {
839
- InstanceData *instance = env.GetInstanceData<InstanceData>();
840
- const Napi::FunctionReference &ref = type->dispose_ref;
854
+ dispose = [](InstanceData *instance, const TypeInfo *type, const void *ptr) {
855
+ Napi::Env env = instance->env;
856
+
857
+ napi_value func;
858
+ NAPI_OK(napi_get_reference_value(env, type->dispose_ref, &func));
841
859
 
842
860
  napi_value self = env.Null();
843
861
  napi_value wrapper = WrapPointer(env, type->ref.type, (void *)ptr);
844
862
 
845
- ref.Call(self, 1, &wrapper);
863
+ NAPI_OK(napi_call_function(env, self, func, 1, &wrapper, nullptr));
846
864
  instance->stats.disposed++;
847
865
  };
848
866
  dispose_func = func;
849
867
  } else {
850
- dispose = [](Napi::Env env, const TypeInfo *, const void *ptr) {
851
- InstanceData *instance = env.GetInstanceData<InstanceData>();
852
-
868
+ dispose = [](InstanceData *instance, const TypeInfo *, const void *ptr) {
853
869
  free((void *)ptr);
854
870
  instance->stats.disposed++;
855
871
  };
@@ -859,9 +875,8 @@ static Napi::Value CreateDisposableType(const Napi::CallbackInfo &info)
859
875
  K_DEFER_N(err_guard) { instance->types.RemoveLast(1); };
860
876
 
861
877
  memcpy((void *)type, (const void *)src, K_SIZE(*src));
862
- type->members.allocator = GetNullAllocator();
863
- type->members.allocator = GetNullAllocator();
864
- memset((void *)&type->defn, 0, K_SIZE(type->defn));
878
+ type->defn = nullptr;
879
+ K_ASSERT(!type->members.len);
865
880
 
866
881
  static_assert(!std::is_polymorphic_v<Napi::ObjectReference>);
867
882
 
@@ -869,7 +884,7 @@ static Napi::Value CreateDisposableType(const Napi::CallbackInfo &info)
869
884
  : Fmt(&instance->str_alloc, "<anonymous_%1>", instance->types.count).ptr;
870
885
 
871
886
  type->dispose = dispose;
872
- type->dispose_ref = Napi::Persistent(dispose_func);
887
+ NAPI_OK(napi_create_reference(env, dispose_func, 1, &type->dispose_ref));
873
888
 
874
889
  // If the insert succeeds, we cannot fail anymore
875
890
  if (named) {
@@ -883,7 +898,7 @@ static Napi::Value CreateDisposableType(const Napi::CallbackInfo &info)
883
898
  }
884
899
  err_guard.Disable();
885
900
 
886
- napi_value wrapper = WrapType(env, type);
901
+ napi_value wrapper = WrapType(instance, type);
887
902
  return Napi::Value(env, wrapper);
888
903
  }
889
904
 
@@ -1066,7 +1081,7 @@ static Napi::Value CreateArrayType(const Napi::CallbackInfo &info)
1066
1081
  type->countedby = DuplicateString(str.Utf8Value().c_str(), &instance->str_alloc).ptr;
1067
1082
  }
1068
1083
 
1069
- napi_value wrapper = WrapType(env, type);
1084
+ napi_value wrapper = WrapType(instance, type);
1070
1085
  return Napi::Value(env, wrapper);
1071
1086
  }
1072
1087
 
@@ -1189,7 +1204,7 @@ static Napi::Value CreateFunctionType(const Napi::CallbackInfo &info)
1189
1204
  }
1190
1205
 
1191
1206
  std::string proto = info[0u].As<Napi::String>();
1192
- if (!ParsePrototype(env, proto.c_str(), false, func))
1207
+ if (!ParsePrototype(instance, proto.c_str(), false, func))
1193
1208
  return env.Null();
1194
1209
  } else {
1195
1210
  ThrowError<Napi::TypeError>(env, "Expected 1 to 4 arguments, got %1", info.Length());
@@ -1214,6 +1229,7 @@ static Napi::Value CreateFunctionType(const Napi::CallbackInfo &info)
1214
1229
 
1215
1230
  TypeInfo *type = instance->types.AppendDefault();
1216
1231
 
1232
+ type->instance = instance;
1217
1233
  type->name = func->name;
1218
1234
 
1219
1235
  type->primitive = PrimitiveKind::Prototype;
@@ -1223,7 +1239,7 @@ static Napi::Value CreateFunctionType(const Napi::CallbackInfo &info)
1223
1239
 
1224
1240
  instance->types_map.Set(type->name, type);
1225
1241
 
1226
- napi_value wrapper = WrapType(env, type);
1242
+ napi_value wrapper = WrapType(instance, type);
1227
1243
  return Napi::Value(env, wrapper);
1228
1244
  }
1229
1245
 
@@ -1256,6 +1272,7 @@ static Napi::Value CreateEnumType(const Napi::CallbackInfo &info)
1256
1272
  TypeInfo *type = instance->types.AppendDefault();
1257
1273
  K_DEFER_N(err_guard) { instance->types.RemoveLast(1); };
1258
1274
 
1275
+ type->instance = instance;
1259
1276
  type->name = named ? DuplicateString(name.Utf8Value().c_str(), &instance->str_alloc).ptr
1260
1277
  : Fmt(&instance->str_alloc, "<anonymous_%1>", instance->types.count).ptr;
1261
1278
 
@@ -1380,8 +1397,19 @@ static Napi::Value CreateEnumType(const Napi::CallbackInfo &info)
1380
1397
  return env.Null();
1381
1398
  err_guard.Disable();
1382
1399
 
1383
- napi_value wrapper = WrapType(env, type, false);
1384
- Napi::Object defn = type->defn.Value();
1400
+ napi_value wrapper = WrapType(instance, type, false);
1401
+
1402
+ #if defined(EXTERNAL_TYPES)
1403
+ Napi::Object defn;
1404
+ {
1405
+ napi_value value;
1406
+ NAPI_OK(napi_get_reference_value(env, type->defn, &defn));
1407
+
1408
+ defn = Napi::Object(env, value);
1409
+ }
1410
+ #else
1411
+ Napi::Object defn(env, wrapper);
1412
+ #endif
1385
1413
 
1386
1414
  defn.Set("values", values);
1387
1415
  defn.Freeze();
@@ -1414,7 +1442,7 @@ static Napi::Value CreateTypeAlias(const Napi::CallbackInfo &info)
1414
1442
  if (!MapType(env, instance, type, alias))
1415
1443
  return env.Null();
1416
1444
 
1417
- napi_value wrapper = WrapType(env, type);
1445
+ napi_value wrapper = WrapType(instance, type);
1418
1446
  return Napi::Value(env, wrapper);
1419
1447
  }
1420
1448
 
@@ -1432,7 +1460,7 @@ static Napi::Value GetResolvedType(const Napi::CallbackInfo &info)
1432
1460
  if (!type)
1433
1461
  return env.Null();
1434
1462
 
1435
- napi_value wrapper = WrapType(env, type);
1463
+ napi_value wrapper = WrapType(instance, type);
1436
1464
  return Napi::Value(env, wrapper);
1437
1465
  }
1438
1466
 
@@ -1441,6 +1469,7 @@ static Napi::Value GetResolvedType(const Napi::CallbackInfo &info)
1441
1469
  static Napi::Value GetTypeDefinition(const Napi::CallbackInfo &info)
1442
1470
  {
1443
1471
  Napi::Env env = info.Env();
1472
+ InstanceData *instance = (InstanceData *)info.Data();
1444
1473
 
1445
1474
  if (info.Length() < 1) {
1446
1475
  ThrowError<Napi::TypeError>(env, "Expected 1 argument, got %1", info.Length());
@@ -1452,9 +1481,12 @@ static Napi::Value GetTypeDefinition(const Napi::CallbackInfo &info)
1452
1481
  return env.Null();
1453
1482
 
1454
1483
  // Make sure definition is available
1455
- WrapType(env, type);
1484
+ WrapType(instance, type);
1456
1485
 
1457
- return type->defn.Value();
1486
+ napi_value defn;
1487
+ NAPI_OK(napi_get_reference_value(env, instance->defn, &defn));
1488
+
1489
+ return defn;
1458
1490
  }
1459
1491
 
1460
1492
  #endif
@@ -1553,6 +1585,23 @@ void ReleaseMemory(InstanceData *instance, InstanceMemory *mem)
1553
1585
  }
1554
1586
  }
1555
1587
 
1588
+ TypeInfo::~TypeInfo()
1589
+ {
1590
+ if (!instance)
1591
+ return;
1592
+
1593
+ Napi::Env env = instance->env;
1594
+
1595
+ for (RecordMember &member: members) {
1596
+ node_api_delete_reference(env, member.key);
1597
+ member.key = nullptr;
1598
+ }
1599
+
1600
+ node_api_delete_reference(env, dispose_ref);
1601
+ node_api_delete_reference(env, construct);
1602
+ node_api_delete_reference(env, defn);
1603
+ }
1604
+
1556
1605
  Napi::Function LibraryHandle::InitClass(InstanceData *instance)
1557
1606
  {
1558
1607
  Napi::Env env = instance->env;
@@ -1589,7 +1638,7 @@ LibraryHandle::LibraryHandle(const Napi::CallbackInfo &info)
1589
1638
 
1590
1639
  void LibraryHandle::Finalize(Napi::BasicEnv env)
1591
1640
  {
1592
- DeleteReferenceSafe(env, *this);
1641
+ node_api_delete_reference(env, *this);
1593
1642
  SuppressDestruct();
1594
1643
 
1595
1644
  lib->Unref();
@@ -1617,7 +1666,7 @@ Napi::Value LibraryHandle::Func(const Napi::CallbackInfo &info)
1617
1666
  }
1618
1667
 
1619
1668
  std::string proto = info[0u].As<Napi::String>();
1620
- if (!ParsePrototype(env, proto.c_str(), true, func))
1669
+ if (!ParsePrototype(instance, proto.c_str(), true, func))
1621
1670
  return env.Null();
1622
1671
  } else {
1623
1672
  ThrowError<Napi::TypeError>(env, "Expected 1 to 4 arguments, got %1", info.Length());
@@ -1660,7 +1709,7 @@ Napi::Value LibraryHandle::Func(const Napi::CallbackInfo &info)
1660
1709
  return env.Null();
1661
1710
  }
1662
1711
 
1663
- napi_value wrapper = WrapFunction(env, func);
1712
+ napi_value wrapper = WrapFunction(instance, func);
1664
1713
  return Napi::Value(env, wrapper);
1665
1714
  }
1666
1715
 
@@ -1669,20 +1718,31 @@ Napi::Value LibraryHandle::Symbol(const Napi::CallbackInfo &info)
1669
1718
  Napi::Env env = info.Env();
1670
1719
  InstanceData *instance = (InstanceData *)info.Data();
1671
1720
 
1721
+ #if defined(EXTERNAL_POINTERS)
1672
1722
  if (info.Length() < 2) {
1673
- ThrowError<Napi::TypeError>(env, "Expected 2, got %1", info.Length());
1723
+ ThrowError<Napi::TypeError>(env, "Expected 2 arguments, got %1", info.Length());
1674
1724
  return env.Null();
1675
1725
  }
1676
- if (!info[0].IsString()) {
1726
+ #else
1727
+ if (info.Length() < 1) {
1728
+ ThrowError<Napi::TypeError>(env, "Expected 1 argument, got %1", info.Length());
1729
+ return env.Null();
1730
+ }
1731
+ #endif
1732
+ if (!info[0].IsString()) {
1677
1733
  ThrowError<Napi::TypeError>(env, "Unexpected %1 value for name, expected string", GetValueType(instance, info[0]));
1678
1734
  return env.Null();
1679
1735
  }
1680
1736
 
1681
1737
  std::string name = info[0].As<Napi::String>();
1682
1738
 
1739
+ #if defined(EXTERNAL_POINTERS)
1683
1740
  const TypeInfo *type = ResolveType(instance, info[1]);
1684
1741
  if (!type)
1685
1742
  return env.Null();
1743
+ #else
1744
+ const TypeInfo *type = nullptr;
1745
+ #endif
1686
1746
 
1687
1747
  #if defined(_WIN32)
1688
1748
  void *ptr = (void *)GetProcAddress((HMODULE)lib->module, name.c_str());
@@ -1886,7 +1946,7 @@ static Napi::Value UnregisterCallback(const Napi::CallbackInfo &info)
1886
1946
  K_ASSERT(trampoline->func);
1887
1947
 
1888
1948
  trampoline->state = 0;
1889
- napi_delete_reference(env, trampoline->func);
1949
+ node_api_delete_reference(env, trampoline->func);
1890
1950
  trampoline->func = nullptr;
1891
1951
 
1892
1952
  shared.available.Append(idx);
@@ -1925,7 +1985,7 @@ static Napi::Value CastValue(const Napi::CallbackInfo &info)
1925
1985
  NAPI_OK(napi_create_reference(env, value, 1, &cast->ref));
1926
1986
  cast->type = type;
1927
1987
 
1928
- Napi::External<ValueCast> external = Napi::External<ValueCast>::New(env, cast, [](Napi::Env, ValueCast *cast) { delete cast; });
1988
+ Napi::External<ValueCast> external = Napi::External<ValueCast>::New(env, cast, [](Napi::BasicEnv, ValueCast *cast) { delete cast; });
1929
1989
  SetValueTag(env, external, &CastMarker);
1930
1990
 
1931
1991
  return external;
@@ -2023,8 +2083,9 @@ static FORCE_INLINE napi_value DecodeInteger(napi_env env, napi_callback_info in
2023
2083
  {
2024
2084
  napi_value arg;
2025
2085
  size_t count = 1;
2086
+ InstanceData *instance;
2026
2087
 
2027
- NAPI_OK(napi_get_cb_info(env, info, &count, &arg, nullptr, nullptr));
2088
+ NAPI_OK(napi_get_cb_info(env, info, &count, &arg, nullptr, (void **)&instance));
2028
2089
 
2029
2090
  if (count < 1) [[unlikely]] {
2030
2091
  ThrowError<Napi::TypeError>(env, "Expected 1 argument, got %1", count);
@@ -2033,8 +2094,6 @@ static FORCE_INLINE napi_value DecodeInteger(napi_env env, napi_callback_info in
2033
2094
 
2034
2095
  void *ptr = nullptr;
2035
2096
  if (!TryPointer(env, arg, &ptr)) [[unlikely]] {
2036
- InstanceData *instance = Napi::Env(env).GetInstanceData<InstanceData>();
2037
-
2038
2097
  ThrowError<Napi::TypeError>(env, "Unexpected %1 value for ptr, expected pointer", GetValueType(instance, arg));
2039
2098
  return Napi::Env(env).Null();
2040
2099
  }
@@ -2045,12 +2104,14 @@ static FORCE_INLINE napi_value DecodeInteger(napi_env env, napi_callback_info in
2045
2104
  return NewInt(env, i);
2046
2105
  }
2047
2106
 
2048
- static napi_value DecodeFloat(napi_env env, napi_callback_info info)
2107
+ template <typename T>
2108
+ static FORCE_INLINE napi_value DecodeIntegerSwap(napi_env env, napi_callback_info info)
2049
2109
  {
2050
2110
  napi_value arg;
2051
2111
  size_t count = 1;
2112
+ InstanceData *instance;
2052
2113
 
2053
- NAPI_OK(napi_get_cb_info(env, info, &count, &arg, nullptr, nullptr));
2114
+ NAPI_OK(napi_get_cb_info(env, info, &count, &arg, nullptr, (void **)&instance));
2054
2115
 
2055
2116
  if (count < 1) [[unlikely]] {
2056
2117
  ThrowError<Napi::TypeError>(env, "Expected 1 argument, got %1", count);
@@ -2059,8 +2120,47 @@ static napi_value DecodeFloat(napi_env env, napi_callback_info info)
2059
2120
 
2060
2121
  void *ptr = nullptr;
2061
2122
  if (!TryPointer(env, arg, &ptr)) [[unlikely]] {
2062
- InstanceData *instance = Napi::Env(env).GetInstanceData<InstanceData>();
2123
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value for ptr, expected pointer", GetValueType(instance, arg));
2124
+ return Napi::Env(env).Null();
2125
+ }
2126
+
2127
+ T i;
2128
+ memcpy(&i, ptr, K_SIZE(i));
2129
+
2130
+ return NewInt(env, ReverseBytes(i));
2131
+ }
2132
+
2133
+ #if defined(K_BIG_ENDIAN)
2134
+
2135
+ template <typename T>
2136
+ static FORCE_INLINE napi_value DecodeIntegerLE(napi_env env, napi_callback_info info) { return DecodeIntegerSwap<T>(env, info); }
2137
+ template <typename T>
2138
+ static FORCE_INLINE napi_value DecodeIntegerBE(napi_env env, napi_callback_info info) { return DecodeInteger<T>(env, info); }
2139
+
2140
+ #else
2141
+
2142
+ template <typename T>
2143
+ static FORCE_INLINE napi_value DecodeIntegerLE(napi_env env, napi_callback_info info) { return DecodeInteger<T>(env, info); }
2144
+ template <typename T>
2145
+ static FORCE_INLINE napi_value DecodeIntegerBE(napi_env env, napi_callback_info info) { return DecodeIntegerSwap<T>(env, info); }
2146
+
2147
+ #endif
2063
2148
 
2149
+ static napi_value DecodeFloat(napi_env env, napi_callback_info info)
2150
+ {
2151
+ napi_value arg;
2152
+ size_t count = 1;
2153
+ InstanceData *instance;
2154
+
2155
+ NAPI_OK(napi_get_cb_info(env, info, &count, &arg, nullptr, (void **)&instance));
2156
+
2157
+ if (count < 1) [[unlikely]] {
2158
+ ThrowError<Napi::TypeError>(env, "Expected 1 argument, got %1", count);
2159
+ return Napi::Env(env).Null();
2160
+ }
2161
+
2162
+ void *ptr = nullptr;
2163
+ if (!TryPointer(env, arg, &ptr)) [[unlikely]] {
2064
2164
  ThrowError<Napi::TypeError>(env, "Unexpected %1 value for ptr, expected pointer", GetValueType(instance, arg));
2065
2165
  return Napi::Env(env).Null();
2066
2166
  }
@@ -2068,15 +2168,16 @@ static napi_value DecodeFloat(napi_env env, napi_callback_info info)
2068
2168
  float f;
2069
2169
  memcpy(&f, ptr, K_SIZE(f));
2070
2170
 
2071
- return Napi::Number::New(env, (double)f);
2171
+ return NewFloat(env, f);
2072
2172
  }
2073
2173
 
2074
2174
  static napi_value DecodeDouble(napi_env env, napi_callback_info info)
2075
2175
  {
2076
2176
  napi_value arg;
2077
2177
  size_t count = 1;
2178
+ InstanceData *instance;
2078
2179
 
2079
- NAPI_OK(napi_get_cb_info(env, info, &count, &arg, nullptr, nullptr));
2180
+ NAPI_OK(napi_get_cb_info(env, info, &count, &arg, nullptr, (void **)&instance));
2080
2181
 
2081
2182
  if (count < 1) [[unlikely]] {
2082
2183
  ThrowError<Napi::TypeError>(env, "Expected 1 argument, got %1", count);
@@ -2085,8 +2186,6 @@ static napi_value DecodeDouble(napi_env env, napi_callback_info info)
2085
2186
 
2086
2187
  void *ptr = nullptr;
2087
2188
  if (!TryPointer(env, arg, &ptr)) [[unlikely]] {
2088
- InstanceData *instance = Napi::Env(env).GetInstanceData<InstanceData>();
2089
-
2090
2189
  ThrowError<Napi::TypeError>(env, "Unexpected %1 value for ptr, expected pointer", GetValueType(instance, arg));
2091
2190
  return Napi::Env(env).Null();
2092
2191
  }
@@ -2094,15 +2193,16 @@ static napi_value DecodeDouble(napi_env env, napi_callback_info info)
2094
2193
  double d;
2095
2194
  memcpy(&d, ptr, K_SIZE(d));
2096
2195
 
2097
- return Napi::Number::New(env, d);
2196
+ return NewFloat(env, d);
2098
2197
  }
2099
2198
 
2100
2199
  static napi_value DecodeString(napi_env env, napi_callback_info info)
2101
2200
  {
2102
2201
  napi_value args[2];
2103
2202
  size_t count = 2;
2203
+ InstanceData *instance;
2104
2204
 
2105
- NAPI_OK(napi_get_cb_info(env, info, &count, args, nullptr, nullptr));
2205
+ NAPI_OK(napi_get_cb_info(env, info, &count, args, nullptr, (void **)&instance));
2106
2206
 
2107
2207
  if (count < 1) [[unlikely]] {
2108
2208
  ThrowError<Napi::TypeError>(env, "Expected 1 to 2 arguments, got %1", count);
@@ -2111,8 +2211,6 @@ static napi_value DecodeString(napi_env env, napi_callback_info info)
2111
2211
 
2112
2212
  void *ptr = nullptr;
2113
2213
  if (!TryPointer(env, args[0], &ptr)) [[unlikely]] {
2114
- InstanceData *instance = Napi::Env(env).GetInstanceData<InstanceData>();
2115
-
2116
2214
  ThrowError<Napi::TypeError>(env, "Unexpected %1 value for ptr, expected pointer", GetValueType(instance, args[0]));
2117
2215
  return Napi::Env(env).Null();
2118
2216
  }
@@ -2120,15 +2218,13 @@ static napi_value DecodeString(napi_env env, napi_callback_info info)
2120
2218
  if (count >= 2) {
2121
2219
  Size len;
2122
2220
  if (!TryNumber(env, args[1], &len)) [[unlikely]] {
2123
- InstanceData *instance = Napi::Env(env).GetInstanceData<InstanceData>();
2124
-
2125
2221
  ThrowError<Napi::TypeError>(env, "Unexpected %1 value for length, expected number", GetValueType(instance, args[1]));
2126
2222
  return Napi::Env(env).Null();
2127
2223
  }
2128
2224
 
2129
- return Napi::String::New(env, (const char *)ptr, (size_t)len);
2225
+ return NewString(env, (const char *)ptr, (size_t)len);
2130
2226
  } else {
2131
- return Napi::String::New(env, (const char *)ptr);
2227
+ return NewString(env, (const char *)ptr);
2132
2228
  }
2133
2229
  }
2134
2230
 
@@ -2136,8 +2232,9 @@ static napi_value DecodeString16(napi_env env, napi_callback_info info)
2136
2232
  {
2137
2233
  napi_value args[2];
2138
2234
  size_t count = 2;
2235
+ InstanceData *instance;
2139
2236
 
2140
- NAPI_OK(napi_get_cb_info(env, info, &count, args, nullptr, nullptr));
2237
+ NAPI_OK(napi_get_cb_info(env, info, &count, args, nullptr, (void **)&instance));
2141
2238
 
2142
2239
  if (count < 1) [[unlikely]] {
2143
2240
  ThrowError<Napi::TypeError>(env, "Expected 1 to 2 arguments, got %1", count);
@@ -2146,8 +2243,6 @@ static napi_value DecodeString16(napi_env env, napi_callback_info info)
2146
2243
 
2147
2244
  void *ptr = nullptr;
2148
2245
  if (!TryPointer(env, args[0], &ptr)) [[unlikely]] {
2149
- InstanceData *instance = Napi::Env(env).GetInstanceData<InstanceData>();
2150
-
2151
2246
  ThrowError<Napi::TypeError>(env, "Unexpected %1 value for ptr, expected pointer", GetValueType(instance, args[0]));
2152
2247
  return Napi::Env(env).Null();
2153
2248
  }
@@ -2155,15 +2250,13 @@ static napi_value DecodeString16(napi_env env, napi_callback_info info)
2155
2250
  if (count >= 2) {
2156
2251
  Size len;
2157
2252
  if (!TryNumber(env, args[1], &len)) [[unlikely]] {
2158
- InstanceData *instance = Napi::Env(env).GetInstanceData<InstanceData>();
2159
-
2160
2253
  ThrowError<Napi::TypeError>(env, "Unexpected %1 value for length, expected number", GetValueType(instance, args[1]));
2161
2254
  return Napi::Env(env).Null();
2162
2255
  }
2163
2256
 
2164
- return Napi::String::New(env, (const char16_t *)ptr, (size_t)len);
2257
+ return NewString(env, (const char16_t *)ptr, (size_t)len);
2165
2258
  } else {
2166
- return Napi::String::New(env, (const char16_t *)ptr);
2259
+ return NewString(env, (const char16_t *)ptr);
2167
2260
  }
2168
2261
  }
2169
2262
 
@@ -2171,8 +2264,9 @@ static napi_value DecodeString32(napi_env env, napi_callback_info info)
2171
2264
  {
2172
2265
  napi_value args[2];
2173
2266
  size_t count = 2;
2267
+ InstanceData *instance;
2174
2268
 
2175
- NAPI_OK(napi_get_cb_info(env, info, &count, args, nullptr, nullptr));
2269
+ NAPI_OK(napi_get_cb_info(env, info, &count, args, nullptr, (void **)&instance));
2176
2270
 
2177
2271
  if (count < 1) [[unlikely]] {
2178
2272
  ThrowError<Napi::TypeError>(env, "Expected 1 to 2 arguments, got %1", count);
@@ -2181,8 +2275,6 @@ static napi_value DecodeString32(napi_env env, napi_callback_info info)
2181
2275
 
2182
2276
  void *ptr = nullptr;
2183
2277
  if (!TryPointer(env, args[0], &ptr)) [[unlikely]] {
2184
- InstanceData *instance = Napi::Env(env).GetInstanceData<InstanceData>();
2185
-
2186
2278
  ThrowError<Napi::TypeError>(env, "Unexpected %1 value for ptr, expected pointer", GetValueType(instance, args[0]));
2187
2279
  return Napi::Env(env).Null();
2188
2280
  }
@@ -2190,15 +2282,13 @@ static napi_value DecodeString32(napi_env env, napi_callback_info info)
2190
2282
  if (count >= 2) {
2191
2283
  Size len;
2192
2284
  if (!TryNumber(env, args[1], &len)) [[unlikely]] {
2193
- InstanceData *instance = Napi::Env(env).GetInstanceData<InstanceData>();
2194
-
2195
2285
  ThrowError<Napi::TypeError>(env, "Unexpected %1 value for length, expected number", GetValueType(instance, args[1]));
2196
2286
  return Napi::Env(env).Null();
2197
2287
  }
2198
2288
 
2199
- return MakeStringFromUTF32(env, (const char32_t *)ptr, len);
2289
+ return NewString(env, (const char32_t *)ptr, len);
2200
2290
  } else {
2201
- return MakeStringFromUTF32(env, (const char32_t *)ptr);
2291
+ return NewString(env, (const char32_t *)ptr);
2202
2292
  }
2203
2293
  }
2204
2294
 
@@ -2419,7 +2509,7 @@ void LibraryHolder::Unload()
2419
2509
 
2420
2510
  ValueCast::~ValueCast()
2421
2511
  {
2422
- DeleteReferenceSafe(env, ref);
2512
+ node_api_delete_reference(env, ref);
2423
2513
  }
2424
2514
 
2425
2515
  FunctionInfo::~FunctionInfo()
@@ -2454,10 +2544,9 @@ static void RegisterPrimitiveType(InstanceData *instance, Napi::Object map, std:
2454
2544
  K_ASSERT(names.size() > 0);
2455
2545
  K_ASSERT(align <= size);
2456
2546
 
2457
- Napi::Env env = instance->env;
2458
-
2459
2547
  TypeInfo *type = instance->types.AppendDefault();
2460
2548
 
2549
+ type->instance = instance;
2461
2550
  type->name = *names.begin();
2462
2551
 
2463
2552
  type->primitive = primitive;
@@ -2479,7 +2568,7 @@ static void RegisterPrimitiveType(InstanceData *instance, Napi::Object map, std:
2479
2568
  K_ASSERT(type->ref.type);
2480
2569
  }
2481
2570
 
2482
- napi_value wrapper = WrapType(env, type);
2571
+ napi_value wrapper = WrapType(instance, type);
2483
2572
 
2484
2573
  for (const char *name: names) {
2485
2574
  bool inserted;
@@ -2538,12 +2627,12 @@ static bool CanCallNapiGetBufferInfoDirectly(const napi_node_version &node, uint
2538
2627
  return false;
2539
2628
  }
2540
2629
 
2541
- static bool CanReferencePrimitiveValues(const napi_node_version &node, uint32_t napi)
2630
+ static bool CanReferencePrimitiveValues(const napi_node_version &, uint32_t napi)
2542
2631
  {
2543
2632
  return napi >= 10;
2544
2633
  }
2545
2634
 
2546
- static bool CanDeleteReferenceInFinalizer(const napi_node_version &node, uint32_t napi)
2635
+ static bool CanDeleteReferenceInFinalizer(const napi_node_version &node, uint32_t)
2547
2636
  {
2548
2637
  if (node.major >= 24)
2549
2638
  return true;
@@ -2618,6 +2707,21 @@ static Napi::Object InitModule(Napi::Env env, Napi::Object exports)
2618
2707
  // errors out (or even asserts) if it gets called in a finalizer. In this case,
2619
2708
  // use experimental API to try to run it later.
2620
2709
  node_api_post_finalizer = SYMBOL(node_api_post_finalizer);
2710
+
2711
+ if (node_api_post_finalizer) {
2712
+ node_api_delete_reference = [](node_api_basic_env env, napi_ref ref) {
2713
+ node_api_post_finalizer((napi_env)env, [](napi_env env, void *data, void *) {
2714
+ napi_ref ref = (napi_ref)data;
2715
+ napi_delete_reference(env, ref);
2716
+ }, (void *)ref, nullptr);
2717
+
2718
+ return napi_ok;
2719
+ };
2720
+ } else {
2721
+ node_api_delete_reference = napi_delete_reference;
2722
+ }
2723
+ } else {
2724
+ node_api_delete_reference = napi_delete_reference;
2621
2725
  }
2622
2726
 
2623
2727
  node_api_create_object_with_properties = SYMBOL(node_api_create_object_with_properties);
@@ -2630,12 +2734,11 @@ static Napi::Object InitModule(Napi::Env env, Napi::Object exports)
2630
2734
  K_CRITICAL(instance, "Failed to initialize Koffi");
2631
2735
 
2632
2736
  instance->env = env;
2633
- env.SetInstanceData(instance);
2634
2737
 
2635
2738
  #if defined(__clang__)
2636
2739
  // First call to napi_create_double() does some weird stuff I can't explain
2637
2740
  // in clang-cl builds. I don't like this... but this fixes it, somehow ><
2638
- Napi::Number::New(env, 0.0);
2741
+ NewFloat(env, 0.0);
2639
2742
  #endif
2640
2743
 
2641
2744
  exports.Set("config", Napi::Function::New(env, GetSetConfig, "config", instance));
@@ -2692,16 +2795,34 @@ static Napi::Object InitModule(Napi::Env env, Napi::Object exports)
2692
2795
  decode.Set("int8", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeInteger<int8_t>(env, info); }, "int8"));
2693
2796
  decode.Set("uint8", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeInteger<uint8_t>(env, info); }, "uint8"));
2694
2797
  decode.Set("int16", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeInteger<int16_t>(env, info); }, "int16"));
2798
+ decode.Set("int16le", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeIntegerLE<int16_t>(env, info); }, "int16le"));
2799
+ decode.Set("int16be", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeIntegerBE<int16_t>(env, info); }, "int16be"));
2695
2800
  decode.Set("uint16", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeInteger<uint16_t>(env, info); }, "uint16"));
2801
+ decode.Set("uint16le", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeIntegerLE<uint16_t>(env, info); }, "uint16le"));
2802
+ decode.Set("uint16be", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeIntegerBE<uint16_t>(env, info); }, "uint16be"));
2696
2803
  decode.Set("int32", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeInteger<int32_t>(env, info); }, "int32"));
2804
+ decode.Set("int32le", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeIntegerLE<int32_t>(env, info); }, "int32le"));
2805
+ decode.Set("int32be", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeIntegerBE<int32_t>(env, info); }, "int32be"));
2697
2806
  decode.Set("uint32", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeInteger<uint32_t>(env, info); }, "uint32"));
2807
+ decode.Set("uint32le", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeIntegerLE<uint32_t>(env, info); }, "uint32le"));
2808
+ decode.Set("uint32be", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeIntegerBE<uint32_t>(env, info); }, "uint32be"));
2698
2809
  decode.Set("int64", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeInteger<int64_t>(env, info); }, "int64"));
2810
+ decode.Set("int64le", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeIntegerLE<int64_t>(env, info); }, "int64le"));
2811
+ decode.Set("int64be", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeIntegerBE<int64_t>(env, info); }, "int64be"));
2699
2812
  decode.Set("uint64", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeInteger<uint64_t>(env, info); }, "uint64"));
2813
+ decode.Set("uint64le", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeIntegerLE<uint64_t>(env, info); }, "uint64le"));
2814
+ decode.Set("uint64be", CreateFunction(instance, [](napi_env env, napi_callback_info info) { return DecodeIntegerBE<uint64_t>(env, info); }, "uint64be"));
2700
2815
  decode.Set("float", CreateFunction(instance, DecodeFloat, "float"));
2701
2816
  decode.Set("double", CreateFunction(instance, DecodeDouble, "double"));
2702
2817
  decode.Set("string", CreateFunction(instance, DecodeString, "string"));
2703
2818
  decode.Set("string16", CreateFunction(instance, DecodeString16, "string16"));
2704
2819
  decode.Set("string32", CreateFunction(instance, DecodeString32, "string32"));
2820
+ if constexpr (K_SIZE(wchar_t) == 2) {
2821
+ decode.Set("wstring", CreateFunction(instance, DecodeString16, "wstring"));
2822
+ } else if constexpr (K_SIZE(wchar_t) == 4) {
2823
+ decode.Set("wstring", CreateFunction(instance, DecodeString32, "wstring"));
2824
+ }
2825
+ static_assert(K_SIZE(wchar_t) == 2 || K_SIZE(wchar_t) == 4);
2705
2826
 
2706
2827
  exports.Set("decode", decode);
2707
2828
  }
@@ -2725,11 +2846,11 @@ static Napi::Object InitModule(Napi::Env env, Napi::Object exports)
2725
2846
  }
2726
2847
 
2727
2848
  #if defined(_WIN32)
2728
- exports.Set("extension", Napi::String::New(env, ".dll"));
2849
+ exports.Set("extension", NewString(env, ".dll"));
2729
2850
  #elif defined(__APPLE__)
2730
- exports.Set("extension", Napi::String::New(env, ".dylib"));
2851
+ exports.Set("extension", NewString(env, ".dylib"));
2731
2852
  #else
2732
- exports.Set("extension", Napi::String::New(env, ".so"));
2853
+ exports.Set("extension", NewString(env, ".so"));
2733
2854
  #endif
2734
2855
 
2735
2856
  // Init object classes and symbols
@@ -2761,9 +2882,9 @@ static Napi::Object InitModule(Napi::Env env, Napi::Object exports)
2761
2882
  RegisterPrimitiveType(instance, types, {"unsigned char", "uchar"}, PrimitiveKind::UInt8, 1, 1);
2762
2883
  RegisterPrimitiveType(instance, types, {"char16_t", "char16"}, PrimitiveKind::Int16, 2, 2);
2763
2884
  RegisterPrimitiveType(instance, types, {"char32_t", "char32"}, PrimitiveKind::Int32, 4, 4);
2764
- if (K_SIZE(wchar_t) == 2) {
2885
+ if constexpr (K_SIZE(wchar_t) == 2) {
2765
2886
  RegisterPrimitiveType(instance, types, {"wchar_t", "wchar"}, PrimitiveKind::Int16, 2, 2);
2766
- } else if (K_SIZE(wchar_t) == 4) {
2887
+ } else if constexpr (K_SIZE(wchar_t) == 4) {
2767
2888
  RegisterPrimitiveType(instance, types, {"wchar_t", "wchar"}, PrimitiveKind::Int32, 4, 4);
2768
2889
  }
2769
2890
  RegisterPrimitiveType(instance, types, {"int16_t", "int16"}, PrimitiveKind::Int16, 2, 2);
@@ -2800,11 +2921,12 @@ static Napi::Object InitModule(Napi::Env env, Napi::Object exports)
2800
2921
  RegisterPrimitiveType(instance, types, {"char *", "str", "string"}, PrimitiveKind::String, K_SIZE(void *), alignof(void *), "char");
2801
2922
  RegisterPrimitiveType(instance, types, {"char16_t *", "char16 *", "str16", "string16"}, PrimitiveKind::String16, K_SIZE(void *), alignof(void *), "char16_t");
2802
2923
  RegisterPrimitiveType(instance, types, {"char32_t *", "char32 *", "str32", "string32"}, PrimitiveKind::String32, K_SIZE(void *), alignof(void *), "char32_t");
2803
- if (K_SIZE(wchar_t) == 2) {
2804
- RegisterPrimitiveType(instance, types, {"wchar_t *", "wchar *"}, PrimitiveKind::String16, K_SIZE(void *), alignof(void *), "wchar_t");
2805
- } else if (K_SIZE(wchar_t) == 4) {
2806
- RegisterPrimitiveType(instance, types, {"wchar_t *", "wchar *"}, PrimitiveKind::String32, K_SIZE(void *), alignof(void *), "wchar_t");
2924
+ if constexpr (K_SIZE(wchar_t) == 2) {
2925
+ RegisterPrimitiveType(instance, types, {"wchar_t *", "wchar *", "wstring"}, PrimitiveKind::String16, K_SIZE(void *), alignof(void *), "wchar_t");
2926
+ } else if constexpr (K_SIZE(wchar_t) == 4) {
2927
+ RegisterPrimitiveType(instance, types, {"wchar_t *", "wchar *", "wstring"}, PrimitiveKind::String32, K_SIZE(void *), alignof(void *), "wchar_t");
2807
2928
  }
2929
+ static_assert(K_SIZE(wchar_t) == 2 || K_SIZE(wchar_t) == 4);
2808
2930
 
2809
2931
  instance->void_type = instance->types_map.FindValue("void", nullptr);
2810
2932
  instance->char_type = instance->types_map.FindValue("char", nullptr);
@@ -2828,7 +2950,7 @@ static Napi::Object InitModule(Napi::Env env, Napi::Object exports)
2828
2950
  node.Set("PollHandle", instance->construct_poll.Value());
2829
2951
  }
2830
2952
 
2831
- exports.Set("version", Napi::String::New(env, K_STRINGIFY(VERSION)));
2953
+ exports.Set("version", NewString(env, K_STRINGIFY(VERSION)));
2832
2954
 
2833
2955
  #if defined(_WIN32)
2834
2956
  {
@@ -2839,7 +2961,6 @@ static Napi::Object InitModule(Napi::Env env, Napi::Object exports)
2839
2961
  }
2840
2962
  #endif
2841
2963
 
2842
- instance->translate_zero_call = translate_zero_call;
2843
2964
  instance->main_thread_id = std::this_thread::get_id();
2844
2965
 
2845
2966
  napi_add_env_cleanup_hook(env, [](void *udata) {
@@ -2874,7 +2995,7 @@ InstanceData::~InstanceData()
2874
2995
  if (trampoline->instance == this) {
2875
2996
  trampoline->instance = nullptr;
2876
2997
  if (trampoline->func) {
2877
- napi_delete_reference(env, trampoline->func);
2998
+ node_api_delete_reference(env, trampoline->func);
2878
2999
  trampoline->func = nullptr;
2879
3000
  }
2880
3001
  trampoline->state = 0;