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
@@ -45,6 +45,8 @@ static const Size TrampolineSize = ((const uint8_t *)&TrampolineEnd - Trampoline
45
45
 
46
46
  #endif
47
47
 
48
+ static napi_value (*translate_zero_call)(napi_env env, napi_callback_info info);
49
+
48
50
  #if defined(K_DEBUG)
49
51
  CallData::~CallData()
50
52
  {
@@ -77,7 +79,7 @@ void CallData::Finalize()
77
79
  K_ASSERT(GetArrayLength(env, value) == 1);
78
80
 
79
81
  Size len = strnlen((const char *)out.ptr, out.max_len);
80
- Napi::String str = Napi::String::New(env, (const char *)out.ptr, len);
82
+ napi_value str = NewString(env, (const char *)out.ptr, len);
81
83
 
82
84
  napi_set_element(env, value, 0, str);
83
85
  } break;
@@ -87,7 +89,7 @@ void CallData::Finalize()
87
89
  K_ASSERT(GetArrayLength(env, value) == 1);
88
90
 
89
91
  Size len = NullTerminatedLength((const char16_t *)out.ptr, out.max_len);
90
- Napi::String str = Napi::String::New(env, (const char16_t *)out.ptr, len);
92
+ napi_value str = NewString(env, (const char16_t *)out.ptr, len);
91
93
 
92
94
  napi_set_element(env, value, 0, str);
93
95
  } break;
@@ -97,7 +99,7 @@ void CallData::Finalize()
97
99
  K_ASSERT(GetArrayLength(env, value) == 1);
98
100
 
99
101
  Size len = NullTerminatedLength((const char32_t *)out.ptr, out.max_len);
100
- Napi::String str = MakeStringFromUTF32(env, (const char32_t *)out.ptr, len);
102
+ napi_value str = NewString(env, (const char32_t *)out.ptr, len);
101
103
 
102
104
  napi_set_element(env, value, 0, str);
103
105
  } break;
@@ -117,7 +119,7 @@ void CallData::Finalize()
117
119
  }
118
120
 
119
121
  for (const OutArgument &out: out_arguments) {
120
- napi_delete_reference(env, out.ref);
122
+ node_api_delete_reference(env, out.ref);
121
123
  }
122
124
  }
123
125
 
@@ -132,7 +134,7 @@ void CallData::Finalize()
132
134
  K_ASSERT(trampoline->func);
133
135
 
134
136
  trampoline->state = 0;
135
- napi_delete_reference(env, trampoline->func);
137
+ node_api_delete_reference(env, trampoline->func);
136
138
  trampoline->func = nullptr;
137
139
 
138
140
  shared.available.Append(idx);
@@ -255,8 +257,6 @@ Size CallData::PushStringValue(napi_value value, const char **out_str)
255
257
 
256
258
  // Fast path for small strings
257
259
  if (available >= 4096) [[likely]] {
258
- char *ptr = (char *)mem->heap.ptr;
259
-
260
260
  napi_status status = napi_get_value_string_utf8(env, value, ptr, 4096, &len);
261
261
  if (status == napi_string_expected)
262
262
  return -1;
@@ -376,17 +376,16 @@ Size CallData::PushString32Value(napi_value value, const char32_t **out_str32)
376
376
  return j;
377
377
  }
378
378
 
379
- static inline napi_value GetMemberValue(napi_env env, napi_value obj, const RecordMember &member)
379
+ static FORCE_INLINE napi_value GetMemberValue(napi_env env, napi_value obj, const RecordMember &member)
380
380
  {
381
- napi_value value = nullptr;
381
+ napi_value value;
382
382
 
383
383
  if (member.key) {
384
- napi_value key = nullptr;
385
- napi_get_reference_value(env, member.key, &key);
386
-
387
- napi_get_property(env, obj, key, &value);
384
+ napi_value key;
385
+ NAPI_OK(napi_get_reference_value(env, member.key, &key));
386
+ NAPI_OK(napi_get_property(env, obj, key, &value));
388
387
  } else {
389
- napi_get_named_property(env, obj, member.name, &value);
388
+ NAPI_OK(napi_get_named_property(env, obj, member.name, &value));
390
389
  }
391
390
 
392
391
  return value;
@@ -394,10 +393,14 @@ static inline napi_value GetMemberValue(napi_env env, napi_value obj, const Reco
394
393
 
395
394
  bool CallData::PushObject(napi_value obj, const TypeInfo *type, uint8_t *origin)
396
395
  {
397
- K_ASSERT(IsObject(env, obj));
398
396
  K_ASSERT(type->primitive == PrimitiveKind::Record ||
399
397
  type->primitive == PrimitiveKind::Union);
400
398
 
399
+ if (GetKindOf(env, obj) != napi_object) [[unlikely]] {
400
+ ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected object", GetValueType(instance, obj));
401
+ return false;
402
+ }
403
+
401
404
  Span<const RecordMember> members = type->members;
402
405
 
403
406
  if (type->primitive == PrimitiveKind::Union) {
@@ -547,12 +550,7 @@ bool CallData::PushObject(napi_value obj, const TypeInfo *type, uint8_t *origin)
547
550
  } break;
548
551
  case PrimitiveKind::Record:
549
552
  case PrimitiveKind::Union: {
550
- if (!IsObject(env, value)) [[unlikely]] {
551
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected object", GetValueType(instance, value));
552
- return false;
553
- }
554
-
555
- if (!PushObject(value, member.type, dest))
553
+ if (!PushObject(value, member.type, dest)) [[unlikely]]
556
554
  return false;
557
555
  } break;
558
556
  case PrimitiveKind::Array: {
@@ -739,12 +737,7 @@ bool CallData::PushNormalArray(Napi::Array array, const TypeInfo *type, Size siz
739
737
  case PrimitiveKind::Record:
740
738
  case PrimitiveKind::Union: {
741
739
  PUSH_ARRAY({
742
- if (!IsObject(env, value)) [[unlikely]] {
743
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected object", GetValueType(instance, value));
744
- return false;
745
- }
746
-
747
- if (!PushObject(value, ref, dest))
740
+ if (!PushObject(value, ref, dest)) [[unlikely]]
748
741
  return false;
749
742
  });
750
743
  } break;
@@ -1010,8 +1003,6 @@ bool CallData::PushPointerSlow(napi_value value, napi_valuetype kind, const Type
1010
1003
  return true;
1011
1004
  } else if (ref->primitive == PrimitiveKind::Record ||
1012
1005
  ref->primitive == PrimitiveKind::Union) [[likely]] {
1013
- K_ASSERT(IsObject(env, value));
1014
-
1015
1006
  ptr = (void *)AllocHeap(ref->size);
1016
1007
 
1017
1008
  if (ref->primitive == PrimitiveKind::Union &&
@@ -1021,9 +1012,12 @@ bool CallData::PushPointerSlow(napi_value value, napi_valuetype kind, const Type
1021
1012
  }
1022
1013
 
1023
1014
  if (directions & 1) {
1024
- if (!PushObject(value, ref, (uint8_t *)ptr))
1015
+ if (!PushObject(value, ref, (uint8_t *)ptr)) [[unlikely]]
1025
1016
  return false;
1026
1017
  } else {
1018
+ if (kind != napi_object) [[unlikely]]
1019
+ return false;
1020
+
1027
1021
  MemSet(ptr, 0, ref->size);
1028
1022
  }
1029
1023
 
@@ -1247,71 +1241,7 @@ void CallData::DebugForward()
1247
1241
 
1248
1242
  #endif
1249
1243
 
1250
- static bool DetectDeno(Napi::Env env)
1251
- {
1252
- Napi::Value ret = env.RunScript("typeof Deno != 'undefined'");
1253
- Napi::Boolean b = ret.ToBoolean();
1254
-
1255
- return b.Value();
1256
- }
1257
-
1258
- static bool DetectBun(Napi::Env env)
1259
- {
1260
- Napi::Value ret = env.RunScript("process.isBun");
1261
- Napi::Boolean b = ret.ToBoolean();
1262
-
1263
- return b.Value();
1264
- }
1265
-
1266
- void InitTranslateZeroCall(Napi::Env env)
1267
- {
1268
- if (DetectDeno(env) || DetectBun(env)) {
1269
- translate_zero_call = TranslateFastCall;
1270
- return;
1271
- }
1272
-
1273
- Napi::Object self = Napi::Object::New(env);
1274
-
1275
- napi_value func;
1276
- napi_value ret;
1277
-
1278
- auto cb = [](napi_env env, napi_callback_info info) {
1279
- napi_value self;
1280
- NAPI_OK(napi_get_cb_info(env, info, nullptr, nullptr, &self, nullptr));
1281
-
1282
- napi_value *ptr = (napi_value *)info;
1283
-
1284
- if (ptr[0] != self && ptr[1] != self) {
1285
- translate_zero_call = TranslateZeroCall;
1286
- } else {
1287
- translate_zero_call = TranslateFastCall;
1288
- }
1289
-
1290
- return self;
1291
- };
1292
-
1293
- NAPI_OK(napi_create_function(env, nullptr, 0, cb, nullptr, &func));
1294
- NAPI_OK(napi_call_function(env, self, func, 0, nullptr, &ret));
1295
- }
1296
-
1297
- bool InitAsyncBroker(Napi::Env env, InstanceData *instance)
1298
- {
1299
- if (!instance->broker) {
1300
- if (napi_create_threadsafe_function(env, nullptr, nullptr,
1301
- Napi::String::New(env, "Koffi Async Callback Broker"),
1302
- 0, 1, nullptr, nullptr, nullptr,
1303
- PerformAsyncRelay, &instance->broker) != napi_ok) {
1304
- LogError("Failed to create async callback broker");
1305
- return false;
1306
- }
1307
-
1308
- NAPI_OK(napi_unref_threadsafe_function(env, instance->broker));
1309
- }
1310
-
1311
- return true;
1312
- }
1313
-
1314
- napi_value TranslateZeroCall(napi_env env, napi_callback_info info)
1244
+ static napi_value TranslateZeroCall(napi_env env, napi_callback_info info)
1315
1245
  {
1316
1246
  struct CallbackBundle {
1317
1247
  napi_env env;
@@ -1386,7 +1316,7 @@ static FORCE_INLINE napi_value TranslateNormalCall(napi_env env, const FunctionI
1386
1316
  return ret;
1387
1317
  }
1388
1318
 
1389
- napi_value TranslateNormalCall(napi_env env, napi_callback_info info)
1319
+ static napi_value TranslateNormalCall(napi_env env, napi_callback_info info)
1390
1320
  {
1391
1321
  static_assert(MaxParameters >= 8);
1392
1322
 
@@ -1436,7 +1366,7 @@ static FORCE_INLINE napi_value TranslateNormalCallDebugAsync(napi_env env, const
1436
1366
  return ret;
1437
1367
  }
1438
1368
 
1439
- napi_value TranslateNormalCallDebugAsync(napi_env env, napi_callback_info info)
1369
+ static napi_value TranslateNormalCallDebugAsync(napi_env env, napi_callback_info info)
1440
1370
  {
1441
1371
  static_assert(MaxParameters >= 8);
1442
1372
 
@@ -1558,7 +1488,7 @@ static napi_value TranslateVariadicCall(napi_env env, const FunctionInfo *func,
1558
1488
  return ret;
1559
1489
  }
1560
1490
 
1561
- napi_value TranslateVariadicCall(napi_env env, napi_callback_info info)
1491
+ static napi_value TranslateVariadicCall(napi_env env, napi_callback_info info)
1562
1492
  {
1563
1493
  static_assert(MaxParameters >= 8);
1564
1494
 
@@ -1651,7 +1581,7 @@ void AsyncCall::OnError(const Napi::Error& err)
1651
1581
  callback.Call(self, K_LEN(args), args);
1652
1582
  }
1653
1583
 
1654
- napi_value TranslateAsyncCall(napi_env env, napi_callback_info info)
1584
+ static napi_value TranslateAsyncCall(napi_env env, napi_callback_info info)
1655
1585
  {
1656
1586
  static_assert(MaxParameters >= 6);
1657
1587
 
@@ -1693,6 +1623,215 @@ napi_value TranslateAsyncCall(napi_env env, napi_callback_info info)
1693
1623
  return Napi::Env(env).Undefined();
1694
1624
  }
1695
1625
 
1626
+ static bool DetectDeno(Napi::Env env)
1627
+ {
1628
+ Napi::Value ret = env.RunScript("typeof Deno != 'undefined'");
1629
+ Napi::Boolean b = ret.ToBoolean();
1630
+
1631
+ return b.Value();
1632
+ }
1633
+
1634
+ static bool DetectBun(Napi::Env env)
1635
+ {
1636
+ Napi::Value ret = env.RunScript("process.isBun");
1637
+ Napi::Boolean b = ret.ToBoolean();
1638
+
1639
+ return b.Value();
1640
+ }
1641
+
1642
+ void InitTranslateZeroCall(Napi::Env env)
1643
+ {
1644
+ if (DetectDeno(env) || DetectBun(env)) {
1645
+ translate_zero_call = TranslateFastCall;
1646
+ return;
1647
+ }
1648
+
1649
+ Napi::Object self = Napi::Object::New(env);
1650
+
1651
+ napi_value func;
1652
+ napi_value ret;
1653
+
1654
+ auto cb = [](napi_env env, napi_callback_info info) {
1655
+ napi_value self;
1656
+ NAPI_OK(napi_get_cb_info(env, info, nullptr, nullptr, &self, nullptr));
1657
+
1658
+ napi_value *ptr = (napi_value *)info;
1659
+
1660
+ if (ptr[0] != self && ptr[1] != self) {
1661
+ translate_zero_call = TranslateZeroCall;
1662
+ } else {
1663
+ translate_zero_call = TranslateFastCall;
1664
+ }
1665
+
1666
+ return self;
1667
+ };
1668
+
1669
+ NAPI_OK(napi_create_function(env, nullptr, 0, cb, nullptr, &func));
1670
+ NAPI_OK(napi_call_function(env, self, func, 0, nullptr, &ret));
1671
+ }
1672
+
1673
+ napi_value CallPointer(Napi::Env env, const FunctionInfo *proto, void *native, napi_value *args, Size count)
1674
+ {
1675
+ if (proto->variadic) {
1676
+ return TranslateVariadicCall(env, proto, native, args, count);
1677
+ } else {
1678
+ return TranslateNormalCall(env, proto, native, args, count);
1679
+ }
1680
+ }
1681
+
1682
+ static void PerformAsyncRelay(napi_env, napi_value, void *, void *udata)
1683
+ {
1684
+ RelayContext *ctx = (RelayContext *)udata;
1685
+ CallData *call = ctx->call;
1686
+
1687
+ call->Relay(ctx->idx, ctx->sp);
1688
+ call->Finalize();
1689
+
1690
+ // We're done!
1691
+ std::lock_guard<std::mutex> lock(ctx->mutex);
1692
+ ctx->done = true;
1693
+ ctx->cv.notify_one();
1694
+ }
1695
+
1696
+ bool InitAsyncBroker(Napi::Env env, InstanceData *instance)
1697
+ {
1698
+ if (!instance->broker) {
1699
+ if (napi_create_threadsafe_function(env, nullptr, nullptr,
1700
+ NewString(env, "Koffi Async Callback Broker"),
1701
+ 0, 1, nullptr, nullptr, nullptr,
1702
+ PerformAsyncRelay, &instance->broker) != napi_ok) {
1703
+ LogError("Failed to create async callback broker");
1704
+ return false;
1705
+ }
1706
+
1707
+ NAPI_OK(napi_unref_threadsafe_function(env, instance->broker));
1708
+ }
1709
+
1710
+ return true;
1711
+ }
1712
+
1713
+ void *GetTrampoline(int idx)
1714
+ {
1715
+ return (void *)(TrampolineStart + TrampolineSize * idx);
1716
+ }
1717
+
1718
+ static bool CanTypeAcceptCallbacks(const TypeInfo *type)
1719
+ {
1720
+ if (type->primitive == PrimitiveKind::Pointer)
1721
+ return true;
1722
+ if (type->primitive == PrimitiveKind::Callback)
1723
+ return true;
1724
+
1725
+ if (type->primitive == PrimitiveKind::Record ||
1726
+ type->primitive == PrimitiveKind::Union) {
1727
+ for (const RecordMember &member: type->members) {
1728
+ if (CanTypeAcceptCallbacks(member.type))
1729
+ return false;
1730
+ }
1731
+ }
1732
+
1733
+ return true;
1734
+ }
1735
+
1736
+ static bool CanUseFastCall(const FunctionInfo *func)
1737
+ {
1738
+ if (func->parameters.len > 6)
1739
+ return false;
1740
+
1741
+ // Fast calls basically skip CallData::Finalize(), which handles output arguments
1742
+ // and temporary callback trampolines. If the function does not use any
1743
+ // output argument and cannot accept callbacks (so no pointer or callback arguments),
1744
+ // we can skip finalization!
1745
+
1746
+ for (const ParameterInfo &param: func->parameters) {
1747
+ if (param.directions & 2)
1748
+ return false;
1749
+ if (CanTypeAcceptCallbacks(param.type))
1750
+ return false;
1751
+ }
1752
+
1753
+ return true;
1754
+ }
1755
+
1756
+ napi_value DescribeFunction(InstanceData *instance, const FunctionInfo *func)
1757
+ {
1758
+ static const char *const DirectionNames[] = {
1759
+ nullptr,
1760
+ "Input",
1761
+ "Output",
1762
+ "Input/Output"
1763
+ };
1764
+
1765
+ Napi::Env env = instance->env;
1766
+
1767
+ Napi::Object meta = Napi::Object::New(env);
1768
+ Napi::Array arguments = Napi::Array::New(env, func->parameters.len);
1769
+
1770
+ meta.Set("name", NewString(env, func->name));
1771
+ meta.Set("arguments", arguments);
1772
+ meta.Set("result", WrapType(instance, func->ret.type));
1773
+
1774
+ for (Size i = 0; i < func->parameters.len; i++) {
1775
+ const ParameterInfo &param = func->parameters[i];
1776
+ Napi::Object obj = Napi::Object::New(env);
1777
+
1778
+ obj.Set("type", WrapType(instance, param.type));
1779
+ obj.Set("direction", NewString(env, DirectionNames[param.directions]));
1780
+
1781
+ arguments.Set((uint32_t)i, obj);
1782
+ }
1783
+
1784
+ meta.Freeze();
1785
+
1786
+ return meta;
1787
+ }
1788
+
1789
+ static bool IsDebugAsyncEnabled()
1790
+ {
1791
+ static bool debug = GetDebugFlag("DEBUG_ASYNC");
1792
+ return debug;
1793
+ }
1794
+
1795
+ napi_value WrapFunction(InstanceData *instance, const FunctionInfo *func)
1796
+ {
1797
+ Napi::Env env = instance->env;
1798
+
1799
+ Napi::Function wrapper;
1800
+ {
1801
+ napi_value value;
1802
+
1803
+ if (func->variadic) {
1804
+ NAPI_OK(napi_create_function(env, func->name, NAPI_AUTO_LENGTH, TranslateVariadicCall, (void *)func->Ref(), &value));
1805
+ } else if (IsDebugAsyncEnabled()) {
1806
+ NAPI_OK(napi_create_function(env, func->name, NAPI_AUTO_LENGTH, TranslateNormalCallDebugAsync, (void *)func->Ref(), &value));
1807
+ } else if (!func->parameters.len) {
1808
+ NAPI_OK(napi_create_function(env, func->name, NAPI_AUTO_LENGTH, translate_zero_call, (void *)func->Ref(), &value));
1809
+ } else if (CanUseFastCall(func)) {
1810
+ NAPI_OK(napi_create_function(env, func->name, NAPI_AUTO_LENGTH, TranslateFastCall, (void *)func->Ref(), &value));
1811
+ } else {
1812
+ NAPI_OK(napi_create_function(env, func->name, NAPI_AUTO_LENGTH, TranslateNormalCall, (void *)func->Ref(), &value));
1813
+ }
1814
+
1815
+ wrapper = Napi::Function(env, value);
1816
+ wrapper.AddFinalizer([](Napi::BasicEnv, FunctionInfo *func) { func->Unref(); }, (FunctionInfo *)func);
1817
+ }
1818
+
1819
+ if (!func->variadic) {
1820
+ napi_value value;
1821
+ NAPI_OK(napi_create_function(env, func->name, NAPI_AUTO_LENGTH, TranslateAsyncCall, (void *)func->Ref(), &value));
1822
+
1823
+ Napi::Function async = Napi::Function(env, value);
1824
+ async.AddFinalizer([](Napi::BasicEnv, FunctionInfo *func) { func->Unref(); }, (FunctionInfo *)func);
1825
+
1826
+ wrapper.Set("async", async);
1827
+ }
1828
+
1829
+ napi_value meta = DescribeFunction(instance, func);
1830
+ wrapper.Set("info", meta);
1831
+
1832
+ return wrapper;
1833
+ }
1834
+
1696
1835
  static FORCE_INLINE bool CheckTrampolineStatus(TrampolineInfo *trampoline)
1697
1836
  {
1698
1837
  if (trampoline->state == 1) [[likely]]
@@ -1799,34 +1938,6 @@ extern "C" void RelayDirect(CallData *call, Size idx, uint8_t *sp)
1799
1938
  }
1800
1939
  }
1801
1940
 
1802
- napi_value CallPointer(napi_env env, const FunctionInfo *proto, void *native, napi_value *args, Size count)
1803
- {
1804
- if (proto->variadic) {
1805
- return TranslateVariadicCall(env, proto, native, args, count);
1806
- } else {
1807
- return TranslateNormalCall(env, proto, native, args, count);
1808
- }
1809
- }
1810
-
1811
- void PerformAsyncRelay(napi_env, napi_value, void *, void *udata)
1812
- {
1813
- RelayContext *ctx = (RelayContext *)udata;
1814
- CallData *call = ctx->call;
1815
-
1816
- call->Relay(ctx->idx, ctx->sp);
1817
- call->Finalize();
1818
-
1819
- // We're done!
1820
- std::lock_guard<std::mutex> lock(ctx->mutex);
1821
- ctx->done = true;
1822
- ctx->cv.notify_one();
1823
- }
1824
-
1825
- void *GetTrampoline(int idx)
1826
- {
1827
- return (void *)(TrampolineStart + TrampolineSize * idx);
1828
- }
1829
-
1830
1941
  bool Encode(InstanceData *instance, uint8_t *origin, napi_value value, const TypeInfo *type)
1831
1942
  {
1832
1943
  Napi::Env env = instance->env;
@@ -1909,12 +2020,7 @@ bool Encode(InstanceData *instance, uint8_t *origin, napi_value value, const Typ
1909
2020
  } break;
1910
2021
  case PrimitiveKind::Record:
1911
2022
  case PrimitiveKind::Union: {
1912
- if (!IsObject(env, value)) [[unlikely]] {
1913
- ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected object", GetValueType(instance, value));
1914
- return false;
1915
- }
1916
-
1917
- if (!call.PushObject(value, type, origin))
2023
+ if (!call.PushObject(value, type, origin)) [[unlikely]]
1918
2024
  return false;
1919
2025
  } break;
1920
2026
  case PrimitiveKind::Array: {
@@ -164,19 +164,14 @@ inline T *CallData::AllocHeap(Size size)
164
164
  }
165
165
 
166
166
  void InitTranslateZeroCall(Napi::Env env);
167
- bool InitAsyncBroker(Napi::Env env, InstanceData *instance);
168
-
169
- napi_value TranslateZeroCall(napi_env env, napi_callback_info info);
170
- napi_value TranslateFastCall(napi_env env, napi_callback_info info);
171
- napi_value TranslateNormalCall(napi_env env, napi_callback_info info);
172
- napi_value TranslateNormalCallDebugAsync(napi_env env, napi_callback_info info);
173
- napi_value TranslateVariadicCall(napi_env env, napi_callback_info info);
174
- napi_value TranslateAsyncCall(napi_env env, napi_callback_info info);
175
167
 
176
- napi_value CallPointer(napi_env env, const FunctionInfo *proto, void *native, napi_value *args, Size count);
168
+ napi_value DescribeFunction(InstanceData *instance, const FunctionInfo *func);
169
+ napi_value WrapFunction(InstanceData *instance, const FunctionInfo *func);
170
+ bool DetectCallConvention(Span<const char> name, CallConvention *out_convention);
177
171
 
178
- void PerformAsyncRelay(napi_env env, napi_value callback, void *ctx, void *udata);
172
+ napi_value CallPointer(Napi::Env env, const FunctionInfo *proto, void *native, napi_value *args, Size count);
179
173
 
174
+ bool InitAsyncBroker(Napi::Env env, InstanceData *instance);
180
175
  void *GetTrampoline(int idx);
181
176
 
182
177
  bool Encode(InstanceData *instance, uint8_t *ptr, napi_value value, const TypeInfo *type);