koffi 2.14.0-beta.3 → 2.14.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.
- package/CHANGELOG.md +18 -1
- package/README.md +1 -1
- package/build/koffi/darwin_arm64/koffi.node +0 -0
- package/build/koffi/darwin_x64/koffi.node +0 -0
- package/build/koffi/freebsd_arm64/koffi.node +0 -0
- package/build/koffi/freebsd_ia32/koffi.node +0 -0
- package/build/koffi/freebsd_x64/koffi.node +0 -0
- package/build/koffi/linux_arm64/koffi.node +0 -0
- package/build/koffi/linux_armhf/koffi.node +0 -0
- package/build/koffi/linux_ia32/koffi.node +0 -0
- package/build/koffi/linux_loong64/koffi.node +0 -0
- package/build/koffi/linux_riscv64d/koffi.node +0 -0
- package/build/koffi/linux_x64/koffi.node +0 -0
- package/build/koffi/musl_arm64/koffi.node +0 -0
- package/build/koffi/musl_x64/koffi.node +0 -0
- package/build/koffi/openbsd_ia32/koffi.node +0 -0
- package/build/koffi/openbsd_x64/koffi.node +0 -0
- package/build/koffi/win32_arm64/koffi.node +0 -0
- package/build/koffi/win32_ia32/koffi.node +0 -0
- package/build/koffi/win32_x64/koffi.node +0 -0
- package/doc/pages/index.md +43 -4
- package/doc/pages/input.md +66 -0
- package/doc/pages/platforms.md +8 -19
- package/doc/pages.ini +0 -7
- package/doc/static/perf_windows.png +0 -0
- package/index.d.ts +0 -1
- package/index.js +10 -9
- package/indirect.js +10 -9
- package/package.json +3 -2
- package/src/cnoke/src/builder.js +1 -2
- package/src/core/base/base.cc +815 -554
- package/src/core/base/base.hh +578 -450
- package/src/core/base/crc.inc +1 -1
- package/src/core/base/crc_gen.py +1 -1
- package/src/core/base/unicode.inc +1 -1
- package/src/core/base/unicode_gen.py +1 -1
- package/src/koffi/src/abi_arm32.cc +24 -24
- package/src/koffi/src/abi_arm64.cc +29 -29
- package/src/koffi/src/abi_riscv64.cc +27 -27
- package/src/koffi/src/abi_x64_sysv.cc +29 -29
- package/src/koffi/src/abi_x64_win.cc +20 -20
- package/src/koffi/src/abi_x86.cc +26 -26
- package/src/koffi/src/call.cc +83 -237
- package/src/koffi/src/call.hh +8 -8
- package/src/koffi/src/ffi.cc +71 -67
- package/src/koffi/src/ffi.hh +9 -9
- package/src/koffi/src/parser.cc +2 -2
- package/src/koffi/src/parser.hh +1 -1
- package/src/koffi/src/trampolines/prototypes.inc +1 -1
- package/src/koffi/src/util.cc +43 -43
- package/src/koffi/src/util.hh +5 -5
- package/src/koffi/src/win32.cc +5 -5
- package/src/koffi/src/win32.hh +1 -1
package/src/koffi/src/ffi.cc
CHANGED
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
|
|
51
51
|
#include <napi.h>
|
|
52
52
|
|
|
53
|
-
namespace
|
|
53
|
+
namespace K {
|
|
54
54
|
|
|
55
55
|
SharedData shared;
|
|
56
56
|
|
|
@@ -147,7 +147,7 @@ static Napi::Value GetSetConfig(const Napi::CallbackInfo &info)
|
|
|
147
147
|
if (!ChangeMemorySize(key.c_str(), value, &new_config.async_heap_size))
|
|
148
148
|
return env.Null();
|
|
149
149
|
} else if (key == "resident_async_pools") {
|
|
150
|
-
if (!ChangeAsyncLimit(key.c_str(), value,
|
|
150
|
+
if (!ChangeAsyncLimit(key.c_str(), value, K_LEN(instance->memories.data) - 1, &new_config.resident_async_pools))
|
|
151
151
|
return env.Null();
|
|
152
152
|
} else if (key == "max_async_calls") {
|
|
153
153
|
if (!ChangeAsyncLimit(key.c_str(), value, MaxAsyncCalls, &max_async_calls))
|
|
@@ -259,7 +259,7 @@ static Napi::Value CreateStructType(const Napi::CallbackInfo &info, bool pad)
|
|
|
259
259
|
Napi::Object obj = info[skip].As<Napi::Object>();
|
|
260
260
|
Napi::Array keys = GetOwnPropertyNames(obj);
|
|
261
261
|
|
|
262
|
-
|
|
262
|
+
K_DEFER_NC(err_guard, count = instance->types.count) {
|
|
263
263
|
Size start = count + !skip;
|
|
264
264
|
|
|
265
265
|
for (Size i = start; i < instance->types.count; i++) {
|
|
@@ -454,7 +454,7 @@ static Napi::Value CreateUnionType(const Napi::CallbackInfo &info)
|
|
|
454
454
|
Napi::Object obj = info[skip].As<Napi::Object>();
|
|
455
455
|
Napi::Array keys = GetOwnPropertyNames(obj);
|
|
456
456
|
|
|
457
|
-
|
|
457
|
+
K_DEFER_NC(err_guard, count = instance->types.count) {
|
|
458
458
|
Size start = count + !skip;
|
|
459
459
|
|
|
460
460
|
for (Size i = start; i < instance->types.count; i++) {
|
|
@@ -629,7 +629,7 @@ static Napi::Value CreateOpaqueType(const Napi::CallbackInfo &info)
|
|
|
629
629
|
Napi::String name = info[0].As<Napi::String>();
|
|
630
630
|
|
|
631
631
|
TypeInfo *type = instance->types.AppendDefault();
|
|
632
|
-
|
|
632
|
+
K_DEFER_N(err_guard) { instance->types.RemoveLast(1); };
|
|
633
633
|
|
|
634
634
|
type->name = named ? DuplicateString(name.Utf8Value().c_str(), &instance->str_alloc).ptr
|
|
635
635
|
: Fmt(&instance->str_alloc, "<anonymous_%1>", instance->types.count).ptr;
|
|
@@ -690,13 +690,13 @@ static Napi::Value CreatePointerType(const Napi::CallbackInfo &info)
|
|
|
690
690
|
}
|
|
691
691
|
|
|
692
692
|
TypeInfo *type = MakePointerType(instance, ref, count);
|
|
693
|
-
|
|
693
|
+
K_ASSERT(type);
|
|
694
694
|
|
|
695
695
|
if (named || !countedby.IsEmpty()) {
|
|
696
696
|
TypeInfo *copy = instance->types.AppendDefault();
|
|
697
|
-
|
|
697
|
+
K_DEFER_N(err_guard) { instance->types.RemoveLast(1); };
|
|
698
698
|
|
|
699
|
-
memcpy((void *)copy, type,
|
|
699
|
+
memcpy((void *)copy, type, K_SIZE(*type));
|
|
700
700
|
copy->name = named ? DuplicateString(name.c_str(), &instance->str_alloc).ptr : copy->name;
|
|
701
701
|
|
|
702
702
|
if (!countedby.IsEmpty()) {
|
|
@@ -717,7 +717,7 @@ static Napi::Value CreatePointerType(const Napi::CallbackInfo &info)
|
|
|
717
717
|
|
|
718
718
|
static Napi::Value EncodePointerDirection(const Napi::CallbackInfo &info, int directions)
|
|
719
719
|
{
|
|
720
|
-
|
|
720
|
+
K_ASSERT(directions >= 1 && directions <= 3);
|
|
721
721
|
|
|
722
722
|
Napi::Env env = info.Env();
|
|
723
723
|
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
@@ -817,7 +817,7 @@ static Napi::Value CreateDisposableType(const Napi::CallbackInfo &info)
|
|
|
817
817
|
external
|
|
818
818
|
};
|
|
819
819
|
|
|
820
|
-
ref.Call(self,
|
|
820
|
+
ref.Call(self, K_LEN(args), args);
|
|
821
821
|
instance->stats.disposed++;
|
|
822
822
|
};
|
|
823
823
|
dispose_func = func;
|
|
@@ -831,9 +831,9 @@ static Napi::Value CreateDisposableType(const Napi::CallbackInfo &info)
|
|
|
831
831
|
}
|
|
832
832
|
|
|
833
833
|
TypeInfo *type = instance->types.AppendDefault();
|
|
834
|
-
|
|
834
|
+
K_DEFER_N(err_guard) { instance->types.RemoveLast(1); };
|
|
835
835
|
|
|
836
|
-
memcpy((void *)type, (const void *)src,
|
|
836
|
+
memcpy((void *)type, (const void *)src, K_SIZE(*src));
|
|
837
837
|
type->members.allocator = GetNullAllocator();
|
|
838
838
|
|
|
839
839
|
type->name = named ? DuplicateString(name.Utf8Value().c_str(), &instance->str_alloc).ptr
|
|
@@ -986,7 +986,11 @@ static Napi::Value CreateArrayType(const Napi::CallbackInfo &info)
|
|
|
986
986
|
return env.Null();
|
|
987
987
|
}
|
|
988
988
|
if (!info[1 + dynamic].IsNumber()) {
|
|
989
|
-
|
|
989
|
+
if (info.Length() == 2 && info[1].IsString()) {
|
|
990
|
+
ThrowError<Napi::TypeError>(env, "Missing maxLen argument");
|
|
991
|
+
} else {
|
|
992
|
+
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for %2, expected integer", GetValueType(instance, info[1]), dynamic ? "maxLen" : "len");
|
|
993
|
+
}
|
|
990
994
|
return env.Null();
|
|
991
995
|
}
|
|
992
996
|
|
|
@@ -1003,7 +1007,7 @@ static Napi::Value CreateArrayType(const Napi::CallbackInfo &info)
|
|
|
1003
1007
|
|
|
1004
1008
|
TypeInfo *type = nullptr;
|
|
1005
1009
|
|
|
1006
|
-
if (info.Length() >=
|
|
1010
|
+
if (info.Length() >= 3u + dynamic && !IsNullOrUndefined(info[2 + dynamic])) {
|
|
1007
1011
|
if (!info[2 + dynamic].IsString()) {
|
|
1008
1012
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value for hint, expected string", GetValueType(instance, info[2]));
|
|
1009
1013
|
return env.Null();
|
|
@@ -1048,7 +1052,7 @@ static Napi::Value CreateArrayType(const Napi::CallbackInfo &info)
|
|
|
1048
1052
|
|
|
1049
1053
|
static bool ParseClassicFunction(const Napi::CallbackInfo &info, bool concrete, FunctionInfo *out_func)
|
|
1050
1054
|
{
|
|
1051
|
-
|
|
1055
|
+
K_ASSERT(info.Length() >= 2);
|
|
1052
1056
|
|
|
1053
1057
|
Napi::Env env = info.Env();
|
|
1054
1058
|
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
@@ -1154,7 +1158,7 @@ static Napi::Value CreateFunctionType(const Napi::CallbackInfo &info)
|
|
|
1154
1158
|
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
1155
1159
|
|
|
1156
1160
|
FunctionInfo *func = instance->callbacks.AppendDefault();
|
|
1157
|
-
|
|
1161
|
+
K_DEFER_N(err_guard) { instance->callbacks.RemoveLast(1); };
|
|
1158
1162
|
|
|
1159
1163
|
if (info.Length() >= 2) {
|
|
1160
1164
|
if (!ParseClassicFunction(info, false, func))
|
|
@@ -1201,7 +1205,7 @@ static Napi::Value CreateFunctionType(const Napi::CallbackInfo &info)
|
|
|
1201
1205
|
|
|
1202
1206
|
type->primitive = PrimitiveKind::Prototype;
|
|
1203
1207
|
type->align = alignof(void *);
|
|
1204
|
-
type->size =
|
|
1208
|
+
type->size = K_SIZE(void *);
|
|
1205
1209
|
type->ref.proto = func;
|
|
1206
1210
|
|
|
1207
1211
|
instance->types_map.Set(type->name, type);
|
|
@@ -1424,7 +1428,7 @@ static InstanceMemory *AllocateMemory(InstanceData *instance, Size stack_size, S
|
|
|
1424
1428
|
return nullptr;
|
|
1425
1429
|
|
|
1426
1430
|
InstanceMemory *mem = new InstanceMemory();
|
|
1427
|
-
|
|
1431
|
+
K_DEFER_N(mem_guard) { delete mem; };
|
|
1428
1432
|
|
|
1429
1433
|
stack_size = AlignLen(stack_size, Kibibytes(64));
|
|
1430
1434
|
|
|
@@ -1433,12 +1437,12 @@ static InstanceMemory *AllocateMemory(InstanceData *instance, Size stack_size, S
|
|
|
1433
1437
|
mem->stack.len = stack_size;
|
|
1434
1438
|
mem->stack.ptr = (uint8_t *)VirtualAlloc(nullptr, mem->stack.len, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
|
|
1435
1439
|
|
|
1436
|
-
|
|
1440
|
+
K_CRITICAL(mem->stack.ptr, "Failed to allocate %1 of memory", mem->stack.len);
|
|
1437
1441
|
#else
|
|
1438
1442
|
mem->stack.len = stack_size;
|
|
1439
1443
|
mem->stack.ptr = (uint8_t *)mmap(nullptr, mem->stack.len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON | MAP_STACK, -1, 0);
|
|
1440
1444
|
|
|
1441
|
-
|
|
1445
|
+
K_CRITICAL(mem->stack.ptr, "Failed to allocate %1 of memory", mem->stack.len);
|
|
1442
1446
|
#endif
|
|
1443
1447
|
|
|
1444
1448
|
#if defined(__OpenBSD__)
|
|
@@ -1455,7 +1459,7 @@ static InstanceMemory *AllocateMemory(InstanceData *instance, Size stack_size, S
|
|
|
1455
1459
|
#else
|
|
1456
1460
|
mem->heap.ptr = (uint8_t *)mmap(nullptr, mem->heap.len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
|
|
1457
1461
|
#endif
|
|
1458
|
-
|
|
1462
|
+
K_CRITICAL(mem->heap.ptr, "Failed to allocate %1 of memory", mem->heap.len);
|
|
1459
1463
|
|
|
1460
1464
|
if (temporary) {
|
|
1461
1465
|
instance->temporaries++;
|
|
@@ -1494,7 +1498,7 @@ static Napi::Value TranslateNormalCall(const FunctionInfo *func, void *native,
|
|
|
1494
1498
|
|
|
1495
1499
|
// Execute call
|
|
1496
1500
|
{
|
|
1497
|
-
|
|
1501
|
+
K_DEFER_C(prev_call = exec_call) { exec_call = prev_call; };
|
|
1498
1502
|
exec_call = &call;
|
|
1499
1503
|
|
|
1500
1504
|
call.Execute(func, native);
|
|
@@ -1516,11 +1520,11 @@ static Napi::Value TranslateVariadicCall(const FunctionInfo *func, void *native,
|
|
|
1516
1520
|
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
1517
1521
|
|
|
1518
1522
|
FunctionInfo copy;
|
|
1519
|
-
memcpy((void *)©, func,
|
|
1523
|
+
memcpy((void *)©, func, K_SIZE(*func));
|
|
1520
1524
|
copy.lib = nullptr;
|
|
1521
1525
|
|
|
1522
1526
|
// This makes variadic calls non-reentrant
|
|
1523
|
-
|
|
1527
|
+
K_DEFER_C(len = copy.parameters.len) {
|
|
1524
1528
|
copy.parameters.RemoveFrom(len);
|
|
1525
1529
|
copy.parameters.Leak();
|
|
1526
1530
|
};
|
|
@@ -1575,7 +1579,7 @@ static Napi::Value TranslateVariadicCall(const FunctionInfo *func, void *native,
|
|
|
1575
1579
|
|
|
1576
1580
|
// Execute call
|
|
1577
1581
|
{
|
|
1578
|
-
|
|
1582
|
+
K_DEFER_C(prev_call = exec_call) { exec_call = prev_call; };
|
|
1579
1583
|
exec_call = &call;
|
|
1580
1584
|
|
|
1581
1585
|
call.Execute(©, native);
|
|
@@ -1625,7 +1629,7 @@ public:
|
|
|
1625
1629
|
void AsyncCall::Execute()
|
|
1626
1630
|
{
|
|
1627
1631
|
if (prepared) {
|
|
1628
|
-
|
|
1632
|
+
K_DEFER_C(prev_call = exec_call) { exec_call = prev_call; };
|
|
1629
1633
|
exec_call = &call;
|
|
1630
1634
|
|
|
1631
1635
|
call.Execute(func, native);
|
|
@@ -1634,7 +1638,7 @@ void AsyncCall::Execute()
|
|
|
1634
1638
|
|
|
1635
1639
|
void AsyncCall::OnOK()
|
|
1636
1640
|
{
|
|
1637
|
-
|
|
1641
|
+
K_ASSERT(prepared);
|
|
1638
1642
|
|
|
1639
1643
|
Napi::FunctionReference &callback = Callback();
|
|
1640
1644
|
|
|
@@ -1644,13 +1648,13 @@ void AsyncCall::OnOK()
|
|
|
1644
1648
|
call.Complete(func)
|
|
1645
1649
|
};
|
|
1646
1650
|
|
|
1647
|
-
callback.Call(self,
|
|
1651
|
+
callback.Call(self, K_LEN(args), args);
|
|
1648
1652
|
}
|
|
1649
1653
|
|
|
1650
1654
|
static Napi::Value TranslateAsyncCall(const FunctionInfo *func, void *native,
|
|
1651
1655
|
const Napi::CallbackInfo &info)
|
|
1652
1656
|
{
|
|
1653
|
-
|
|
1657
|
+
K_ASSERT(!func->variadic);
|
|
1654
1658
|
|
|
1655
1659
|
Napi::Env env = info.Env();
|
|
1656
1660
|
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
@@ -1708,7 +1712,7 @@ extern "C" void RelayCallback(Size idx, uint8_t *own_sp, uint8_t *caller_sp, Bac
|
|
|
1708
1712
|
}
|
|
1709
1713
|
|
|
1710
1714
|
// Avoid triggering the "use callback beyond FFI" check
|
|
1711
|
-
|
|
1715
|
+
K_DEFER_C(generation = trampoline->generation) { trampoline->generation = generation; };
|
|
1712
1716
|
trampoline->generation = -1;
|
|
1713
1717
|
|
|
1714
1718
|
// We set dispose_call to true so that the main thread will dispose of CallData itself
|
|
@@ -1724,7 +1728,7 @@ static Napi::Value FindLibraryFunction(const Napi::CallbackInfo &info)
|
|
|
1724
1728
|
LibraryHolder *lib = (LibraryHolder *)info.Data();
|
|
1725
1729
|
|
|
1726
1730
|
FunctionInfo *func = new FunctionInfo();
|
|
1727
|
-
|
|
1731
|
+
K_DEFER { func->Unref(); };
|
|
1728
1732
|
|
|
1729
1733
|
func->lib = lib->Ref();
|
|
1730
1734
|
|
|
@@ -1872,7 +1876,7 @@ static Napi::Value LoadSharedLibrary(const Napi::CallbackInfo &info)
|
|
|
1872
1876
|
|
|
1873
1877
|
if (!instance->memories.len) {
|
|
1874
1878
|
AllocateMemory(instance, instance->config.sync_stack_size, instance->config.sync_heap_size);
|
|
1875
|
-
|
|
1879
|
+
K_ASSERT(instance->memories.len);
|
|
1876
1880
|
}
|
|
1877
1881
|
|
|
1878
1882
|
// Load shared library
|
|
@@ -1886,7 +1890,7 @@ static Napi::Value LoadSharedLibrary(const Napi::CallbackInfo &info)
|
|
|
1886
1890
|
return env.Null();
|
|
1887
1891
|
} else {
|
|
1888
1892
|
module = GetModuleHandle(nullptr);
|
|
1889
|
-
|
|
1893
|
+
K_ASSERT(module);
|
|
1890
1894
|
}
|
|
1891
1895
|
#else
|
|
1892
1896
|
if (info[0].IsString()) {
|
|
@@ -1913,7 +1917,7 @@ static Napi::Value LoadSharedLibrary(const Napi::CallbackInfo &info)
|
|
|
1913
1917
|
#endif
|
|
1914
1918
|
|
|
1915
1919
|
LibraryHolder *lib = new LibraryHolder(module);
|
|
1916
|
-
|
|
1920
|
+
K_DEFER { lib->Unref(); };
|
|
1917
1921
|
|
|
1918
1922
|
Napi::Object obj = Napi::Object::New(env);
|
|
1919
1923
|
|
|
@@ -2036,7 +2040,7 @@ static Napi::Value UnregisterCallback(const Napi::CallbackInfo &info)
|
|
|
2036
2040
|
std::lock_guard<std::mutex> lock(shared.mutex);
|
|
2037
2041
|
|
|
2038
2042
|
TrampolineInfo *trampoline = &shared.trampolines[idx];
|
|
2039
|
-
|
|
2043
|
+
K_ASSERT(!trampoline->func.IsEmpty());
|
|
2040
2044
|
|
|
2041
2045
|
trampoline->func.Reset();
|
|
2042
2046
|
trampoline->recv.Reset();
|
|
@@ -2087,7 +2091,7 @@ static Napi::Value DecodeValue(const Napi::CallbackInfo &info)
|
|
|
2087
2091
|
Napi::Env env = info.Env();
|
|
2088
2092
|
|
|
2089
2093
|
bool has_offset = (info.Length() >= 2 && info[1].IsNumber());
|
|
2090
|
-
bool has_len = (info.Length() >= 3u + has_offset && info[
|
|
2094
|
+
bool has_len = (info.Length() >= 3u + has_offset && info[2 + has_offset].IsNumber());
|
|
2091
2095
|
|
|
2092
2096
|
if (info.Length() < 2u + has_offset) [[unlikely]] {
|
|
2093
2097
|
ThrowError<Napi::TypeError>(env, "Expected %1 to 4 arguments, got %2", 2 + has_offset, info.Length());
|
|
@@ -2102,7 +2106,7 @@ static Napi::Value DecodeValue(const Napi::CallbackInfo &info)
|
|
|
2102
2106
|
int64_t offset = has_offset ? info[1].As<Napi::Number>().Int64Value() : 0;
|
|
2103
2107
|
|
|
2104
2108
|
if (has_len) {
|
|
2105
|
-
Size len = info[
|
|
2109
|
+
Size len = info[2 + has_offset].As<Napi::Number>();
|
|
2106
2110
|
|
|
2107
2111
|
Napi::Value ret = Decode(value, offset, type, &len);
|
|
2108
2112
|
return ret;
|
|
@@ -2164,7 +2168,7 @@ static Napi::Value EncodeValue(const Napi::CallbackInfo &info)
|
|
|
2164
2168
|
Napi::Env env = info.Env();
|
|
2165
2169
|
|
|
2166
2170
|
bool has_offset = (info.Length() >= 2 && info[1].IsNumber());
|
|
2167
|
-
bool has_len = (info.Length() >= 4u + has_offset && info[
|
|
2171
|
+
bool has_len = (info.Length() >= 4u + has_offset && info[3 + has_offset].IsNumber());
|
|
2168
2172
|
|
|
2169
2173
|
if (info.Length() < 3u + has_offset) [[unlikely]] {
|
|
2170
2174
|
ThrowError<Napi::TypeError>(env, "Expected %1 to 5 arguments, got %2", 3 + has_offset, info.Length());
|
|
@@ -2177,10 +2181,10 @@ static Napi::Value EncodeValue(const Napi::CallbackInfo &info)
|
|
|
2177
2181
|
|
|
2178
2182
|
Napi::Value ref = info[0];
|
|
2179
2183
|
int64_t offset = has_offset ? info[1].As<Napi::Number>().Int64Value() : 0;
|
|
2180
|
-
Napi::Value value = info[
|
|
2184
|
+
Napi::Value value = info[2 + has_offset];
|
|
2181
2185
|
|
|
2182
2186
|
if (has_len) {
|
|
2183
|
-
Size len = info[
|
|
2187
|
+
Size len = info[3 + has_offset].As<Napi::Number>();
|
|
2184
2188
|
|
|
2185
2189
|
if (!Encode(ref, offset, value, type, &len))
|
|
2186
2190
|
return env.Null();
|
|
@@ -2350,8 +2354,8 @@ bool InitAsyncBroker(Napi::Env env, InstanceData *instance)
|
|
|
2350
2354
|
static void RegisterPrimitiveType(Napi::Env env, Napi::Object map, std::initializer_list<const char *> names,
|
|
2351
2355
|
PrimitiveKind primitive, int32_t size, int16_t align, const char *ref = nullptr)
|
|
2352
2356
|
{
|
|
2353
|
-
|
|
2354
|
-
|
|
2357
|
+
K_ASSERT(names.size() > 0);
|
|
2358
|
+
K_ASSERT(align <= size);
|
|
2355
2359
|
|
|
2356
2360
|
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
2357
2361
|
|
|
@@ -2375,7 +2379,7 @@ static void RegisterPrimitiveType(Napi::Env env, Napi::Object map, std::initiali
|
|
|
2375
2379
|
|
|
2376
2380
|
if (ref) {
|
|
2377
2381
|
const TypeInfo *marker = instance->types_map.FindValue(ref, nullptr);
|
|
2378
|
-
|
|
2382
|
+
K_ASSERT(marker);
|
|
2379
2383
|
|
|
2380
2384
|
type->ref.marker = marker;
|
|
2381
2385
|
}
|
|
@@ -2385,7 +2389,7 @@ static void RegisterPrimitiveType(Napi::Env env, Napi::Object map, std::initiali
|
|
|
2385
2389
|
for (const char *name: names) {
|
|
2386
2390
|
bool inserted;
|
|
2387
2391
|
instance->types_map.TrySet(name, type, &inserted);
|
|
2388
|
-
|
|
2392
|
+
K_ASSERT(inserted);
|
|
2389
2393
|
|
|
2390
2394
|
if (!EndsWith(name, "*")) {
|
|
2391
2395
|
map.Set(name, wrapper);
|
|
@@ -2402,12 +2406,12 @@ static inline PrimitiveKind GetSignPrimitive(Size len, bool sign)
|
|
|
2402
2406
|
case 8: return sign ? PrimitiveKind::Int64 : PrimitiveKind::UInt64;
|
|
2403
2407
|
}
|
|
2404
2408
|
|
|
2405
|
-
|
|
2409
|
+
K_UNREACHABLE();
|
|
2406
2410
|
}
|
|
2407
2411
|
|
|
2408
2412
|
static inline PrimitiveKind GetLittleEndianPrimitive(PrimitiveKind kind)
|
|
2409
2413
|
{
|
|
2410
|
-
#if defined(
|
|
2414
|
+
#if defined(K_BIG_ENDIAN)
|
|
2411
2415
|
return (PrimitiveKind)((int)kind + 1);
|
|
2412
2416
|
#else
|
|
2413
2417
|
return kind;
|
|
@@ -2416,7 +2420,7 @@ static inline PrimitiveKind GetLittleEndianPrimitive(PrimitiveKind kind)
|
|
|
2416
2420
|
|
|
2417
2421
|
static inline PrimitiveKind GetBigEndianPrimitive(PrimitiveKind kind)
|
|
2418
2422
|
{
|
|
2419
|
-
#if defined(
|
|
2423
|
+
#if defined(K_BIG_ENDIAN)
|
|
2420
2424
|
return kind;
|
|
2421
2425
|
#else
|
|
2422
2426
|
return (PrimitiveKind)((int)kind + 1);
|
|
@@ -2426,7 +2430,7 @@ static inline PrimitiveKind GetBigEndianPrimitive(PrimitiveKind kind)
|
|
|
2426
2430
|
static InstanceData *CreateInstance()
|
|
2427
2431
|
{
|
|
2428
2432
|
InstanceData *instance = new InstanceData();
|
|
2429
|
-
|
|
2433
|
+
K_DEFER_N(err_guard) { delete instance; };
|
|
2430
2434
|
|
|
2431
2435
|
instance->main_thread_id = std::this_thread::get_id();
|
|
2432
2436
|
|
|
@@ -2446,7 +2450,7 @@ static InstanceData *CreateInstance()
|
|
|
2446
2450
|
static Napi::Object InitModule(Napi::Env env, Napi::Object exports)
|
|
2447
2451
|
{
|
|
2448
2452
|
InstanceData *instance = CreateInstance();
|
|
2449
|
-
|
|
2453
|
+
K_CRITICAL(instance, "Failed to initialize Koffi");
|
|
2450
2454
|
|
|
2451
2455
|
env.SetInstanceData(instance);
|
|
2452
2456
|
|
|
@@ -2521,16 +2525,16 @@ static Napi::Object InitModule(Napi::Env env, Napi::Object exports)
|
|
|
2521
2525
|
exports.Set("types", types);
|
|
2522
2526
|
|
|
2523
2527
|
RegisterPrimitiveType(env, types, {"void"}, PrimitiveKind::Void, 0, 0);
|
|
2524
|
-
RegisterPrimitiveType(env, types, {"bool"}, PrimitiveKind::Bool,
|
|
2528
|
+
RegisterPrimitiveType(env, types, {"bool"}, PrimitiveKind::Bool, K_SIZE(bool), alignof(bool));
|
|
2525
2529
|
RegisterPrimitiveType(env, types, {"int8_t", "int8"}, PrimitiveKind::Int8, 1, 1);
|
|
2526
2530
|
RegisterPrimitiveType(env, types, {"uint8_t", "uint8"}, PrimitiveKind::UInt8, 1, 1);
|
|
2527
2531
|
RegisterPrimitiveType(env, types, {"char"}, PrimitiveKind::Int8, 1, 1);
|
|
2528
2532
|
RegisterPrimitiveType(env, types, {"unsigned char", "uchar"}, PrimitiveKind::UInt8, 1, 1);
|
|
2529
2533
|
RegisterPrimitiveType(env, types, {"char16_t", "char16"}, PrimitiveKind::Int16, 2, 2);
|
|
2530
2534
|
RegisterPrimitiveType(env, types, {"char32_t", "char32"}, PrimitiveKind::Int32, 4, 4);
|
|
2531
|
-
if (
|
|
2535
|
+
if (K_SIZE(wchar_t) == 2) {
|
|
2532
2536
|
RegisterPrimitiveType(env, types, {"wchar_t", "wchar"}, PrimitiveKind::Int16, 2, 2);
|
|
2533
|
-
} else if (
|
|
2537
|
+
} else if (K_SIZE(wchar_t) == 4) {
|
|
2534
2538
|
RegisterPrimitiveType(env, types, {"wchar_t", "wchar"}, PrimitiveKind::Int32, 4, 4);
|
|
2535
2539
|
}
|
|
2536
2540
|
RegisterPrimitiveType(env, types, {"int16_t", "int16"}, PrimitiveKind::Int16, 2, 2);
|
|
@@ -2555,22 +2559,22 @@ static Napi::Object InitModule(Napi::Env env, Napi::Object exports)
|
|
|
2555
2559
|
RegisterPrimitiveType(env, types, {"uint64_t", "uint64"}, PrimitiveKind::UInt64, 8, alignof(int64_t));
|
|
2556
2560
|
RegisterPrimitiveType(env, types, {"uint64_le_t", "uint64_le"}, GetLittleEndianPrimitive(PrimitiveKind::UInt64), 8, alignof(int64_t));
|
|
2557
2561
|
RegisterPrimitiveType(env, types, {"uint64_be_t", "uint64_be"}, GetBigEndianPrimitive(PrimitiveKind::UInt64), 8, alignof(int64_t));
|
|
2558
|
-
RegisterPrimitiveType(env, types, {"intptr_t", "intptr"}, GetSignPrimitive(
|
|
2559
|
-
RegisterPrimitiveType(env, types, {"uintptr_t", "uintptr"}, GetSignPrimitive(
|
|
2560
|
-
RegisterPrimitiveType(env, types, {"size_t"}, GetSignPrimitive(
|
|
2561
|
-
RegisterPrimitiveType(env, types, {"long"}, GetSignPrimitive(
|
|
2562
|
-
RegisterPrimitiveType(env, types, {"unsigned long", "ulong"}, GetSignPrimitive(
|
|
2563
|
-
RegisterPrimitiveType(env, types, {"long long", "longlong"}, PrimitiveKind::Int64,
|
|
2564
|
-
RegisterPrimitiveType(env, types, {"unsigned long long", "ulonglong"}, PrimitiveKind::UInt64,
|
|
2562
|
+
RegisterPrimitiveType(env, types, {"intptr_t", "intptr"}, GetSignPrimitive(K_SIZE(intptr_t), true), K_SIZE(intptr_t), alignof(intptr_t));
|
|
2563
|
+
RegisterPrimitiveType(env, types, {"uintptr_t", "uintptr"}, GetSignPrimitive(K_SIZE(intptr_t), false), K_SIZE(intptr_t), alignof(intptr_t));
|
|
2564
|
+
RegisterPrimitiveType(env, types, {"size_t"}, GetSignPrimitive(K_SIZE(size_t), false), K_SIZE(size_t), alignof(size_t));
|
|
2565
|
+
RegisterPrimitiveType(env, types, {"long"}, GetSignPrimitive(K_SIZE(long), true), K_SIZE(long), alignof(long));
|
|
2566
|
+
RegisterPrimitiveType(env, types, {"unsigned long", "ulong"}, GetSignPrimitive(K_SIZE(long), false), K_SIZE(long), alignof(long));
|
|
2567
|
+
RegisterPrimitiveType(env, types, {"long long", "longlong"}, PrimitiveKind::Int64, K_SIZE(int64_t), alignof(int64_t));
|
|
2568
|
+
RegisterPrimitiveType(env, types, {"unsigned long long", "ulonglong"}, PrimitiveKind::UInt64, K_SIZE(uint64_t), alignof(uint64_t));
|
|
2565
2569
|
RegisterPrimitiveType(env, types, {"float", "float32"}, PrimitiveKind::Float32, 4, alignof(float));
|
|
2566
2570
|
RegisterPrimitiveType(env, types, {"double", "float64"}, PrimitiveKind::Float64, 8, alignof(double));
|
|
2567
|
-
RegisterPrimitiveType(env, types, {"char *", "str", "string"}, PrimitiveKind::String,
|
|
2568
|
-
RegisterPrimitiveType(env, types, {"char16_t *", "char16 *", "str16", "string16"}, PrimitiveKind::String16,
|
|
2569
|
-
RegisterPrimitiveType(env, types, {"char32_t *", "char32 *", "str32", "string32"}, PrimitiveKind::String32,
|
|
2570
|
-
if (
|
|
2571
|
-
RegisterPrimitiveType(env, types, {"wchar_t *", "wchar *"}, PrimitiveKind::String16,
|
|
2572
|
-
} else if (
|
|
2573
|
-
RegisterPrimitiveType(env, types, {"wchar_t *", "wchar *"}, PrimitiveKind::String32,
|
|
2571
|
+
RegisterPrimitiveType(env, types, {"char *", "str", "string"}, PrimitiveKind::String, K_SIZE(void *), alignof(void *), "char");
|
|
2572
|
+
RegisterPrimitiveType(env, types, {"char16_t *", "char16 *", "str16", "string16"}, PrimitiveKind::String16, K_SIZE(void *), alignof(void *), "char16_t");
|
|
2573
|
+
RegisterPrimitiveType(env, types, {"char32_t *", "char32 *", "str32", "string32"}, PrimitiveKind::String32, K_SIZE(void *), alignof(void *), "char32_t");
|
|
2574
|
+
if (K_SIZE(wchar_t) == 2) {
|
|
2575
|
+
RegisterPrimitiveType(env, types, {"wchar_t *", "wchar *"}, PrimitiveKind::String16, K_SIZE(void *), alignof(void *), "wchar_t");
|
|
2576
|
+
} else if (K_SIZE(wchar_t) == 4) {
|
|
2577
|
+
RegisterPrimitiveType(env, types, {"wchar_t *", "wchar *"}, PrimitiveKind::String32, K_SIZE(void *), alignof(void *), "wchar_t");
|
|
2574
2578
|
}
|
|
2575
2579
|
|
|
2576
2580
|
instance->void_type = instance->types_map.FindValue("void", nullptr);
|
|
@@ -2597,7 +2601,7 @@ static Napi::Object InitModule(Napi::Env env, Napi::Object exports)
|
|
|
2597
2601
|
node.Set("env", external);
|
|
2598
2602
|
}
|
|
2599
2603
|
|
|
2600
|
-
exports.Set("version", Napi::String::New(env,
|
|
2604
|
+
exports.Set("version", Napi::String::New(env, K_STRINGIFY(VERSION)));
|
|
2601
2605
|
|
|
2602
2606
|
return exports;
|
|
2603
2607
|
}
|
package/src/koffi/src/ffi.hh
CHANGED
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
|
|
26
26
|
#include <napi.h>
|
|
27
27
|
|
|
28
|
-
namespace
|
|
28
|
+
namespace K {
|
|
29
29
|
|
|
30
30
|
static const Size DefaultSyncStackSize = Mebibytes(1);
|
|
31
31
|
static const Size DefaultSyncHeapSize = Mebibytes(2);
|
|
@@ -47,17 +47,17 @@ enum class PrimitiveKind {
|
|
|
47
47
|
Int8,
|
|
48
48
|
UInt8,
|
|
49
49
|
Int16,
|
|
50
|
-
Int16S,
|
|
50
|
+
Int16S, // Keep behind Int16
|
|
51
51
|
UInt16,
|
|
52
|
-
UInt16S,
|
|
52
|
+
UInt16S, // Keep behind UInt16
|
|
53
53
|
Int32,
|
|
54
|
-
Int32S,
|
|
54
|
+
Int32S, // Keep behind Int32
|
|
55
55
|
UInt32,
|
|
56
|
-
UInt32S,
|
|
56
|
+
UInt32S, // Keep behind UInt32
|
|
57
57
|
Int64,
|
|
58
|
-
Int64S,
|
|
58
|
+
Int64S, // Keep behind Int64
|
|
59
59
|
UInt64,
|
|
60
|
-
UInt64S,
|
|
60
|
+
UInt64S, // Keep behind UInt64
|
|
61
61
|
String,
|
|
62
62
|
String16,
|
|
63
63
|
String32,
|
|
@@ -152,7 +152,7 @@ struct TypeInfo {
|
|
|
152
152
|
mutable Napi::FunctionReference construct; // Union only
|
|
153
153
|
mutable Napi::ObjectReference defn;
|
|
154
154
|
|
|
155
|
-
|
|
155
|
+
K_HASHTABLE_HANDLER(TypeInfo, name);
|
|
156
156
|
};
|
|
157
157
|
|
|
158
158
|
struct RecordMember {
|
|
@@ -329,7 +329,7 @@ struct InstanceData {
|
|
|
329
329
|
int64_t disposed = 0;
|
|
330
330
|
} stats;
|
|
331
331
|
};
|
|
332
|
-
static_assert(DefaultResidentAsyncPools <=
|
|
332
|
+
static_assert(DefaultResidentAsyncPools <= K_LEN(InstanceData::memories.data) - 1);
|
|
333
333
|
static_assert(DefaultMaxAsyncCalls >= DefaultResidentAsyncPools);
|
|
334
334
|
static_assert(MaxAsyncCalls >= DefaultMaxAsyncCalls);
|
|
335
335
|
|
package/src/koffi/src/parser.cc
CHANGED
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
|
|
26
26
|
#include <napi.h>
|
|
27
27
|
|
|
28
|
-
namespace
|
|
28
|
+
namespace K {
|
|
29
29
|
|
|
30
30
|
bool PrototypeParser::Parse(const char *str, bool concrete, FunctionInfo *out_func)
|
|
31
31
|
{
|
|
@@ -221,7 +221,7 @@ bool PrototypeParser::Match(const char *expect)
|
|
|
221
221
|
|
|
222
222
|
bool PrototypeParser::IsIdentifier(Span<const char> tok) const
|
|
223
223
|
{
|
|
224
|
-
|
|
224
|
+
K_ASSERT(tok.len);
|
|
225
225
|
return IsAsciiAlpha(tok[0]) || tok[0] == '_';
|
|
226
226
|
}
|
|
227
227
|
|
package/src/koffi/src/parser.hh
CHANGED
|
@@ -16406,4 +16406,4 @@ static void *const Trampolines[][2] = {
|
|
|
16406
16406
|
{ &Trampoline8190, &TrampolineX8190 },
|
|
16407
16407
|
{ &Trampoline8191, &TrampolineX8191 }
|
|
16408
16408
|
};
|
|
16409
|
-
static_assert(
|
|
16409
|
+
static_assert(K_LEN(Trampolines) == MaxTrampolines);
|