koffi 2.15.2 → 2.15.4
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 +15 -0
- 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/index.js +8 -8
- package/indirect.js +8 -8
- package/package.json +1 -1
- package/src/koffi/src/abi_arm32.cc +7 -14
- package/src/koffi/src/abi_arm32_asm.S +6 -10
- package/src/koffi/src/abi_arm64.cc +11 -17
- package/src/koffi/src/abi_arm64_asm.S +4 -7
- package/src/koffi/src/abi_arm64_asm.asm +5 -7
- package/src/koffi/src/abi_loong64_asm.S +4 -7
- package/src/koffi/src/abi_riscv64.cc +7 -14
- package/src/koffi/src/abi_riscv64_asm.S +4 -7
- package/src/koffi/src/abi_x64_sysv.cc +7 -14
- package/src/koffi/src/abi_x64_sysv_asm.S +4 -7
- package/src/koffi/src/abi_x64_win.cc +7 -14
- package/src/koffi/src/abi_x64_win_asm.S +29 -24
- package/src/koffi/src/abi_x64_win_asm.asm +28 -25
- package/src/koffi/src/abi_x86.cc +17 -15
- package/src/koffi/src/abi_x86_asm.S +11 -17
- package/src/koffi/src/abi_x86_asm.asm +6 -14
- package/src/koffi/src/call.cc +37 -47
- package/src/koffi/src/call.hh +7 -9
- package/src/koffi/src/ffi.cc +41 -20
- package/src/koffi/src/ffi.hh +1 -1
- package/src/koffi/src/util.cc +7 -11
- package/src/koffi/src/win32.cc +13 -0
- package/src/koffi/src/win32.hh +2 -0
package/src/koffi/src/call.hh
CHANGED
|
@@ -17,7 +17,7 @@ struct BackRegisters;
|
|
|
17
17
|
|
|
18
18
|
// I'm not sure why the alignas(8), because alignof(CallData) is 8 without it.
|
|
19
19
|
// But on Windows i386, without it, the alignment may not be correct (compiler bug?).
|
|
20
|
-
|
|
20
|
+
struct alignas(8) CallData {
|
|
21
21
|
struct OutArgument {
|
|
22
22
|
enum class Kind {
|
|
23
23
|
Array,
|
|
@@ -66,7 +66,7 @@ class alignas(8) CallData {
|
|
|
66
66
|
LocalArray<int16_t, 16> used_trampolines;
|
|
67
67
|
HeapArray<OutArgument> out_arguments;
|
|
68
68
|
|
|
69
|
-
BlockAllocator
|
|
69
|
+
BlockAllocator alloc;
|
|
70
70
|
|
|
71
71
|
public:
|
|
72
72
|
CallData(Napi::Env env, InstanceData *instance, InstanceMemory *mem);
|
|
@@ -90,9 +90,8 @@ public:
|
|
|
90
90
|
|
|
91
91
|
#undef INLINE_IF_UNITY
|
|
92
92
|
|
|
93
|
-
void Relay(Size idx, uint8_t *
|
|
94
|
-
void
|
|
95
|
-
static void RelayAsync(napi_env, napi_value, void *, void *udata);
|
|
93
|
+
void Relay(Size idx, uint8_t *sp);
|
|
94
|
+
void RelayAsync(Size idx, uint8_t *sp);
|
|
96
95
|
|
|
97
96
|
void DumpForward(const FunctionInfo *func) const;
|
|
98
97
|
|
|
@@ -112,9 +111,6 @@ public:
|
|
|
112
111
|
|
|
113
112
|
void *ReserveTrampoline(const FunctionInfo *proto, Napi::Function func);
|
|
114
113
|
|
|
115
|
-
BlockAllocator *GetAllocator() { return &call_alloc; }
|
|
116
|
-
|
|
117
|
-
private:
|
|
118
114
|
template <typename T>
|
|
119
115
|
bool AllocStack(Size size, Size align, T **out_ptr);
|
|
120
116
|
template <typename T = uint8_t>
|
|
@@ -169,13 +165,15 @@ inline T *CallData::AllocHeap(Size size, Size align)
|
|
|
169
165
|
int flags = 0;
|
|
170
166
|
#endif
|
|
171
167
|
|
|
172
|
-
ptr = (uint8_t *)AllocateRaw(&
|
|
168
|
+
ptr = (uint8_t *)AllocateRaw(&alloc, size + align, flags);
|
|
173
169
|
ptr = AlignUp(ptr, align);
|
|
174
170
|
|
|
175
171
|
return ptr;
|
|
176
172
|
}
|
|
177
173
|
}
|
|
178
174
|
|
|
175
|
+
void PerformAsyncRelay(napi_env env, napi_value callback, void *ctx, void *udata);
|
|
176
|
+
|
|
179
177
|
void *GetTrampoline(int16_t idx, const FunctionInfo *proto);
|
|
180
178
|
|
|
181
179
|
}
|
package/src/koffi/src/ffi.cc
CHANGED
|
@@ -39,6 +39,8 @@ SharedData shared;
|
|
|
39
39
|
|
|
40
40
|
static thread_local CallData *exec_call;
|
|
41
41
|
|
|
42
|
+
extern "C" napi_value SwitchAndRelay(CallData *call, Size idx, uint8_t *sp, uint8_t *saved_sp, Span<uint8_t> *new_stack);
|
|
43
|
+
|
|
42
44
|
static bool ChangeSize(const char *name, Napi::Value value, Size min_size, Size max_size, Size *out_size)
|
|
43
45
|
{
|
|
44
46
|
Napi::Env env = value.Env();
|
|
@@ -1690,35 +1692,54 @@ Napi::Value TranslateAsyncCall(const Napi::CallbackInfo &info)
|
|
|
1690
1692
|
return TranslateAsyncCall(func, func->native, info);
|
|
1691
1693
|
}
|
|
1692
1694
|
|
|
1693
|
-
extern "C" void RelayCallback(Size idx, uint8_t *
|
|
1695
|
+
extern "C" void RelayCallback(Size idx, uint8_t *sp)
|
|
1694
1696
|
{
|
|
1695
|
-
|
|
1696
|
-
exec_call->RelaySafe(idx, own_sp, caller_sp, false, out_reg);
|
|
1697
|
-
} else {
|
|
1698
|
-
// This happens if the callback pointer is called from a different thread
|
|
1699
|
-
// than the one that runs the FFI call (sync or async).
|
|
1697
|
+
CallData *call = exec_call;
|
|
1700
1698
|
|
|
1701
|
-
|
|
1699
|
+
// Try the fast path first: we are on the main thread and we are running a native call through Koffi.
|
|
1700
|
+
// It should be easy, but in this case we are running on the custom Koffi stack, which will trip up
|
|
1701
|
+
// Node and V8. So we need to switch back to the normal/main stack.
|
|
1702
|
+
if (call && std::this_thread::get_id() == call->instance->main_thread_id) {
|
|
1703
|
+
SwitchAndRelay(call, idx, sp, call->old_sp, &call->mem->stack);
|
|
1704
|
+
return;
|
|
1705
|
+
}
|
|
1702
1706
|
|
|
1703
|
-
|
|
1704
|
-
|
|
1707
|
+
// Otherwise, we need to allocate memory to perform the callback.
|
|
1708
|
+
// Since the necessary machinery live in CallData, just use a temporary instance.
|
|
1709
|
+
// In some cases we would reuse the existing call (exec_call may be not null),
|
|
1710
|
+
// but it is rare so let's ignore this for simplicity.
|
|
1705
1711
|
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1712
|
+
TrampolineInfo *trampoline = &shared.trampolines[idx];
|
|
1713
|
+
Napi::Env env = trampoline->func.Env();
|
|
1714
|
+
InstanceData *instance = env.GetInstanceData<InstanceData>();
|
|
1715
|
+
|
|
1716
|
+
InstanceMemory *mem = AllocateMemory(instance, instance->config.async_stack_size, instance->config.async_heap_size);
|
|
1717
|
+
if (!mem) [[unlikely]] {
|
|
1718
|
+
ThrowError<Napi::Error>(env, "Too many asynchronous calls are running");
|
|
1719
|
+
return;
|
|
1720
|
+
}
|
|
1711
1721
|
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1722
|
+
// Avoid triggering the "use callback beyond FFI" check
|
|
1723
|
+
K_DEFER_C(generation = trampoline->generation) { trampoline->generation = generation; };
|
|
1724
|
+
trampoline->generation = -1;
|
|
1715
1725
|
|
|
1716
|
-
|
|
1726
|
+
if (std::this_thread::get_id() == instance->main_thread_id) {
|
|
1717
1727
|
CallData call(env, instance, mem);
|
|
1718
|
-
|
|
1728
|
+
|
|
1729
|
+
Napi::HandleScope scope(env);
|
|
1730
|
+
call.Relay(idx, sp);
|
|
1731
|
+
} else {
|
|
1732
|
+
CallData call(env, instance, mem);
|
|
1733
|
+
call.RelayAsync(idx, sp);
|
|
1719
1734
|
}
|
|
1720
1735
|
}
|
|
1721
1736
|
|
|
1737
|
+
extern "C" void RelayDirect(CallData *call, Size idx, uint8_t *sp)
|
|
1738
|
+
{
|
|
1739
|
+
Napi::HandleScope scope(call->env);
|
|
1740
|
+
call->Relay(idx, sp);
|
|
1741
|
+
}
|
|
1742
|
+
|
|
1722
1743
|
static Napi::Value FindLibraryFunction(const Napi::CallbackInfo &info)
|
|
1723
1744
|
{
|
|
1724
1745
|
Napi::Env env = info.Env();
|
|
@@ -2338,7 +2359,7 @@ bool InitAsyncBroker(Napi::Env env, InstanceData *instance)
|
|
|
2338
2359
|
if (napi_create_threadsafe_function(env, nullptr, nullptr,
|
|
2339
2360
|
Napi::String::New(env, "Koffi Async Callback Broker"),
|
|
2340
2361
|
0, 1, nullptr, nullptr, nullptr,
|
|
2341
|
-
|
|
2362
|
+
PerformAsyncRelay, &instance->broker) != napi_ok) {
|
|
2342
2363
|
LogError("Failed to create async callback broker");
|
|
2343
2364
|
return false;
|
|
2344
2365
|
}
|
package/src/koffi/src/ffi.hh
CHANGED
package/src/koffi/src/util.cc
CHANGED
|
@@ -1683,19 +1683,15 @@ bool Encode(Napi::Env env, uint8_t *origin, Napi::Value value, const TypeInfo *t
|
|
|
1683
1683
|
#undef PUSH_INTEGER
|
|
1684
1684
|
|
|
1685
1685
|
// Keep memory around if any was allocated
|
|
1686
|
-
{
|
|
1687
|
-
BlockAllocator *
|
|
1688
|
-
|
|
1689
|
-
if (alloc->IsUsed()) {
|
|
1690
|
-
BlockAllocator *copy = instance->encode_map.FindValue(origin, nullptr);
|
|
1686
|
+
if (call.alloc.IsUsed()) {
|
|
1687
|
+
BlockAllocator *copy = instance->encode_map.FindValue(origin, nullptr);
|
|
1691
1688
|
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
}
|
|
1696
|
-
|
|
1697
|
-
std::swap(*alloc, *copy);
|
|
1689
|
+
if (!copy) {
|
|
1690
|
+
copy = instance->encode_allocators.AppendDefault();
|
|
1691
|
+
instance->encode_map.Set(origin, copy);
|
|
1698
1692
|
}
|
|
1693
|
+
|
|
1694
|
+
std::swap(call.alloc, *copy);
|
|
1699
1695
|
}
|
|
1700
1696
|
|
|
1701
1697
|
return true;
|
package/src/koffi/src/win32.cc
CHANGED
|
@@ -180,6 +180,19 @@ int GetDllMachine(const wchar_t *filename)
|
|
|
180
180
|
return GetFileMachine(h, true);
|
|
181
181
|
}
|
|
182
182
|
|
|
183
|
+
extern "C" int __cdecl SehHandler(void *ptr, void *, void *ctx, void *)
|
|
184
|
+
{
|
|
185
|
+
EXCEPTION_RECORD *rec = (EXCEPTION_RECORD *)ptr;
|
|
186
|
+
|
|
187
|
+
if (!(rec->ExceptionFlags & (EXCEPTION_UNWINDING | EXCEPTION_EXIT_UNWIND))) {
|
|
188
|
+
EXCEPTION_POINTERS ep = { rec, (CONTEXT *)ctx };
|
|
189
|
+
UnhandledExceptionFilter(&ep);
|
|
190
|
+
ExitProcess(rec->ExceptionCode);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
return ExceptionContinueSearch;
|
|
194
|
+
}
|
|
195
|
+
|
|
183
196
|
}
|
|
184
197
|
|
|
185
198
|
#endif
|
package/src/koffi/src/win32.hh
CHANGED