koffi 2.2.3-beta.1 → 2.2.3-beta.2
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/package.json +1 -1
- package/src/koffi/build/2.2.3-beta.2/koffi_darwin_arm64.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.2/koffi_darwin_x64.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.2/koffi_freebsd_arm64.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.2/koffi_freebsd_ia32.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.2/koffi_freebsd_x64.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.2/koffi_linux_arm32hf.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.2/koffi_linux_arm64.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.2/koffi_linux_ia32.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.2/koffi_linux_riscv64hf64.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.2/koffi_linux_x64.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.2/koffi_openbsd_ia32.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.2/koffi_openbsd_x64.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.2/koffi_win32_arm64.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.2/koffi_win32_ia32.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.2/koffi_win32_x64.tar.gz +0 -0
- package/src/koffi/src/abi_x64_win.cc +30 -23
- package/src/koffi/src/abi_x86.cc +32 -25
- package/src/koffi/src/ffi.cc +64 -10
- package/src/koffi/src/ffi.hh +6 -2
- package/src/koffi/build/2.2.3-beta.1/koffi_darwin_arm64.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.1/koffi_darwin_x64.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.1/koffi_freebsd_arm64.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.1/koffi_freebsd_ia32.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.1/koffi_freebsd_x64.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.1/koffi_linux_arm32hf.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.1/koffi_linux_arm64.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.1/koffi_linux_ia32.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.1/koffi_linux_riscv64hf64.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.1/koffi_linux_x64.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.1/koffi_openbsd_ia32.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.1/koffi_openbsd_x64.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.1/koffi_win32_arm64.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.1/koffi_win32_ia32.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.1/koffi_win32_x64.tar.gz +0 -0
package/package.json
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -18,14 +18,6 @@
|
|
|
18
18
|
#include "call.hh"
|
|
19
19
|
#include "util.hh"
|
|
20
20
|
|
|
21
|
-
#ifndef NOMINMAX
|
|
22
|
-
#define NOMINMAX
|
|
23
|
-
#endif
|
|
24
|
-
#ifndef WIN32_LEAN_AND_MEAN
|
|
25
|
-
#define WIN32_LEAN_AND_MEAN
|
|
26
|
-
#endif
|
|
27
|
-
#include <windows.h>
|
|
28
|
-
|
|
29
21
|
#include <napi.h>
|
|
30
22
|
|
|
31
23
|
namespace RG {
|
|
@@ -48,6 +40,10 @@ extern "C" napi_value CallSwitchStack(Napi::Function *func, size_t argc, napi_va
|
|
|
48
40
|
|
|
49
41
|
#include "abi_trampolines.inc"
|
|
50
42
|
|
|
43
|
+
#define TEB_STACK_BASE(TEB) (*(void **)((uint8_t *)(TEB) + 0x08))
|
|
44
|
+
#define TEB_STACK_LIMIT(TEB) (*(void **)((uint8_t *)(TEB) + 0x10))
|
|
45
|
+
#define TEB_DEALLOCATION_STACK(TEB) (*(void **)((uint8_t *)(TEB) + 0x1478))
|
|
46
|
+
|
|
51
47
|
bool AnalyseFunction(Napi::Env, InstanceData *, FunctionInfo *func)
|
|
52
48
|
{
|
|
53
49
|
func->ret.regular = IsRegularSize(func->ret.type->size, 8);
|
|
@@ -224,15 +220,21 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
224
220
|
|
|
225
221
|
void CallData::Execute(const FunctionInfo *func)
|
|
226
222
|
{
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
//
|
|
230
|
-
RG_DEFER_C(base =
|
|
231
|
-
|
|
232
|
-
|
|
223
|
+
void *teb = (void *)__readgsqword(0x30);
|
|
224
|
+
|
|
225
|
+
// Store current stack limits
|
|
226
|
+
RG_DEFER_C(base = TEB_STACK_BASE(teb),
|
|
227
|
+
limit = TEB_STACK_LIMIT(teb),
|
|
228
|
+
dealloc = TEB_DEALLOCATION_STACK(teb)) {
|
|
229
|
+
TEB_STACK_BASE(teb) = base;
|
|
230
|
+
TEB_STACK_LIMIT(teb) = limit;
|
|
231
|
+
TEB_DEALLOCATION_STACK(teb) = dealloc;
|
|
233
232
|
};
|
|
234
|
-
|
|
235
|
-
|
|
233
|
+
|
|
234
|
+
// Adjust stack limits so SEH works correctly
|
|
235
|
+
TEB_STACK_BASE(teb) = mem->stack0.end();
|
|
236
|
+
TEB_STACK_LIMIT(teb) = mem->stack0.ptr;
|
|
237
|
+
TEB_DEALLOCATION_STACK(teb) = mem->stack0.ptr;
|
|
236
238
|
|
|
237
239
|
#define PERFORM_CALL(Suffix) \
|
|
238
240
|
([&]() { \
|
|
@@ -335,15 +337,20 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
|
|
|
335
337
|
if (RG_UNLIKELY(env.IsExceptionPending()))
|
|
336
338
|
return;
|
|
337
339
|
|
|
338
|
-
|
|
340
|
+
void *teb = (void *)__readgsqword(0x30);
|
|
339
341
|
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
342
|
+
RG_DEFER_C(base = TEB_STACK_BASE(teb),
|
|
343
|
+
limit = TEB_STACK_LIMIT(teb),
|
|
344
|
+
dealloc = TEB_DEALLOCATION_STACK(teb)) {
|
|
345
|
+
TEB_STACK_BASE(teb) = base;
|
|
346
|
+
TEB_STACK_LIMIT(teb) = limit;
|
|
347
|
+
TEB_DEALLOCATION_STACK(teb) = dealloc;
|
|
344
348
|
};
|
|
345
|
-
|
|
346
|
-
|
|
349
|
+
|
|
350
|
+
// Restore real thread stack limits
|
|
351
|
+
TEB_STACK_BASE(teb) = instance->main_stack_max;
|
|
352
|
+
TEB_STACK_LIMIT(teb) = instance->main_stack_min;
|
|
353
|
+
TEB_DEALLOCATION_STACK(teb) = instance->main_stack_min;
|
|
347
354
|
|
|
348
355
|
const TrampolineInfo &trampoline = shared.trampolines[idx];
|
|
349
356
|
|
package/src/koffi/src/abi_x86.cc
CHANGED
|
@@ -18,16 +18,6 @@
|
|
|
18
18
|
#include "call.hh"
|
|
19
19
|
#include "util.hh"
|
|
20
20
|
|
|
21
|
-
#ifdef _WIN32
|
|
22
|
-
#ifndef NOMINMAX
|
|
23
|
-
#define NOMINMAX
|
|
24
|
-
#endif
|
|
25
|
-
#ifndef WIN32_LEAN_AND_MEAN
|
|
26
|
-
#define WIN32_LEAN_AND_MEAN
|
|
27
|
-
#endif
|
|
28
|
-
#include <windows.h>
|
|
29
|
-
#endif
|
|
30
|
-
|
|
31
21
|
#include <napi.h>
|
|
32
22
|
|
|
33
23
|
namespace RG {
|
|
@@ -56,6 +46,12 @@ extern "C" napi_value CallSwitchStack(Napi::Function *func, size_t argc, napi_va
|
|
|
56
46
|
|
|
57
47
|
#include "abi_trampolines.inc"
|
|
58
48
|
|
|
49
|
+
#ifdef _WIN32
|
|
50
|
+
#define TEB_STACK_BASE(TEB) (*(void **)((uint8_t *)(TEB) + 0x04))
|
|
51
|
+
#define TEB_STACK_LIMIT(TEB) (*(void **)((uint8_t *)(TEB) + 0x08))
|
|
52
|
+
#define TEB_DEALLOCATION_STACK(TEB) (*(void **)((uint8_t *)(TEB) + 0xE0C))
|
|
53
|
+
#endif
|
|
54
|
+
|
|
59
55
|
bool AnalyseFunction(Napi::Env env, InstanceData *instance, FunctionInfo *func)
|
|
60
56
|
{
|
|
61
57
|
if (!func->lib && func->convention != CallConvention::Cdecl &&
|
|
@@ -308,15 +304,21 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
308
304
|
void CallData::Execute(const FunctionInfo *func)
|
|
309
305
|
{
|
|
310
306
|
#ifdef _WIN32
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
//
|
|
314
|
-
RG_DEFER_C(base =
|
|
315
|
-
|
|
316
|
-
|
|
307
|
+
void *teb = (void *)__readfsdword(0x18);
|
|
308
|
+
|
|
309
|
+
// Store current stack limits
|
|
310
|
+
RG_DEFER_C(base = TEB_STACK_BASE(teb),
|
|
311
|
+
limit = TEB_STACK_LIMIT(teb),
|
|
312
|
+
dealloc = TEB_DEALLOCATION_STACK(teb)) {
|
|
313
|
+
TEB_STACK_BASE(teb) = base;
|
|
314
|
+
TEB_STACK_LIMIT(teb) = limit;
|
|
315
|
+
TEB_DEALLOCATION_STACK(teb) = dealloc;
|
|
317
316
|
};
|
|
318
|
-
|
|
319
|
-
|
|
317
|
+
|
|
318
|
+
// Adjust stack limits so SEH works correctly
|
|
319
|
+
TEB_STACK_BASE(teb) = mem->stack0.end();
|
|
320
|
+
TEB_STACK_LIMIT(teb) = mem->stack0.ptr;
|
|
321
|
+
TEB_DEALLOCATION_STACK(teb) = mem->stack0.ptr;
|
|
320
322
|
#endif
|
|
321
323
|
|
|
322
324
|
#define PERFORM_CALL(Suffix) \
|
|
@@ -422,15 +424,20 @@ void CallData::Relay(Size idx, uint8_t *, uint8_t *caller_sp, bool async, BackRe
|
|
|
422
424
|
return;
|
|
423
425
|
|
|
424
426
|
#ifdef _WIN32
|
|
425
|
-
|
|
427
|
+
void *teb = (void *)__readfsdword(0x18);
|
|
428
|
+
|
|
429
|
+
RG_DEFER_C(base = TEB_STACK_BASE(teb),
|
|
430
|
+
limit = TEB_STACK_LIMIT(teb),
|
|
431
|
+
dealloc = TEB_DEALLOCATION_STACK(teb)) {
|
|
432
|
+
TEB_STACK_BASE(teb) = base;
|
|
433
|
+
TEB_STACK_LIMIT(teb) = limit;
|
|
434
|
+
TEB_DEALLOCATION_STACK(teb) = dealloc;
|
|
435
|
+
};
|
|
426
436
|
|
|
427
437
|
// Restore real thread stack limits
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
};
|
|
432
|
-
tib->StackBase = instance->main_stack_base;
|
|
433
|
-
tib->StackLimit = instance->main_stack_limit;
|
|
438
|
+
TEB_STACK_BASE(teb) = instance->main_stack_max;
|
|
439
|
+
TEB_STACK_LIMIT(teb) = instance->main_stack_min;
|
|
440
|
+
TEB_DEALLOCATION_STACK(teb) = instance->main_stack_min;
|
|
434
441
|
#endif
|
|
435
442
|
|
|
436
443
|
const TrampolineInfo &trampoline = shared.trampolines[idx];
|
package/src/koffi/src/ffi.cc
CHANGED
|
@@ -1014,13 +1014,66 @@ static InstanceMemory *AllocateMemory(InstanceData *instance, Size stack_size, S
|
|
|
1014
1014
|
return nullptr;
|
|
1015
1015
|
|
|
1016
1016
|
InstanceMemory *mem = new InstanceMemory();
|
|
1017
|
+
RG_DEFER_N(mem_guard) { delete mem; };
|
|
1017
1018
|
|
|
1018
|
-
mem->stack.len = stack_size;
|
|
1019
1019
|
#if defined(_WIN32)
|
|
1020
|
-
|
|
1020
|
+
{
|
|
1021
|
+
struct FiberContext {
|
|
1022
|
+
InstanceMemory *mem;
|
|
1023
|
+
void *self;
|
|
1024
|
+
bool was_fiber;
|
|
1025
|
+
};
|
|
1026
|
+
|
|
1027
|
+
FiberContext ctx;
|
|
1028
|
+
bool is_fiber = IsThreadAFiber();
|
|
1029
|
+
|
|
1030
|
+
ctx.mem = mem;
|
|
1031
|
+
ctx.self = is_fiber ? GetCurrentFiber() : ConvertThreadToFiber(nullptr);
|
|
1032
|
+
if (!ctx.self) {
|
|
1033
|
+
LogError("Failed to make initial fiber: %1", GetWin32ErrorString());
|
|
1034
|
+
return nullptr;
|
|
1035
|
+
}
|
|
1036
|
+
RG_DEFER {
|
|
1037
|
+
if (!is_fiber) {
|
|
1038
|
+
ConvertFiberToThread();
|
|
1039
|
+
}
|
|
1040
|
+
};
|
|
1041
|
+
|
|
1042
|
+
// Work around issue with CreateFiber() API and stack size
|
|
1043
|
+
// See here: https://github.com/google/marl/issues/12
|
|
1044
|
+
mem->fiber = CreateFiberEx(stack_size - 1, stack_size,
|
|
1045
|
+
FIBER_FLAG_FLOAT_SWITCH, [](void *udata) {
|
|
1046
|
+
FiberContext *ctx = (FiberContext *)udata;
|
|
1047
|
+
|
|
1048
|
+
// Handle initial call just below
|
|
1049
|
+
#if defined(__aarch64__) || defined(_M_ARM64)
|
|
1050
|
+
NT_TIB *tib = (NT_TIB *)__getReg(18);
|
|
1051
|
+
#elif defined(__x86_64__) || defined(_M_AMD64)
|
|
1052
|
+
NT_TIB *tib = (NT_TIB *)__readgsqword(0x30);
|
|
1053
|
+
#else
|
|
1054
|
+
NT_TIB *tib = (NT_TIB *)__readfsdword(0x18);
|
|
1055
|
+
#endif
|
|
1056
|
+
|
|
1057
|
+
ctx->mem->stack.ptr = (uint8_t *)tib->StackLimit;
|
|
1058
|
+
ctx->mem->stack.len = (uint8_t *)tib->StackBase - ctx->mem->stack.ptr;
|
|
1059
|
+
|
|
1060
|
+
SwitchToFiber(ctx->self);
|
|
1061
|
+
}, &ctx);
|
|
1062
|
+
|
|
1063
|
+
if (!mem->fiber) {
|
|
1064
|
+
LogError("Failed to create Win32 fiber: %1", GetWin32ErrorString());
|
|
1065
|
+
return nullptr;
|
|
1066
|
+
}
|
|
1067
|
+
|
|
1068
|
+
SwitchToFiber(mem->fiber);
|
|
1069
|
+
}
|
|
1070
|
+
|
|
1071
|
+
RG_ASSERT(mem->stack.ptr);
|
|
1021
1072
|
#elif defined(__APPLE__)
|
|
1073
|
+
mem->stack.len = stack_size;
|
|
1022
1074
|
mem->stack.ptr = (uint8_t *)mmap(nullptr, mem->stack.len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
|
|
1023
1075
|
#else
|
|
1076
|
+
mem->stack.len = stack_size;
|
|
1024
1077
|
mem->stack.ptr = (uint8_t *)mmap(nullptr, mem->stack.len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON | MAP_STACK, -1, 0);
|
|
1025
1078
|
#endif
|
|
1026
1079
|
RG_CRITICAL(mem->stack.ptr, "Failed to allocate %1 of memory", mem->stack.len);
|
|
@@ -1051,6 +1104,7 @@ static InstanceMemory *AllocateMemory(InstanceData *instance, Size stack_size, S
|
|
|
1051
1104
|
mem->temporary = true;
|
|
1052
1105
|
}
|
|
1053
1106
|
|
|
1107
|
+
mem_guard.Disable();
|
|
1054
1108
|
return mem;
|
|
1055
1109
|
}
|
|
1056
1110
|
|
|
@@ -1691,8 +1745,8 @@ void FunctionInfo::Unref() const
|
|
|
1691
1745
|
InstanceMemory::~InstanceMemory()
|
|
1692
1746
|
{
|
|
1693
1747
|
#ifdef _WIN32
|
|
1694
|
-
if (
|
|
1695
|
-
|
|
1748
|
+
if (fiber) {
|
|
1749
|
+
DeleteFiber(fiber);
|
|
1696
1750
|
}
|
|
1697
1751
|
if (heap.ptr) {
|
|
1698
1752
|
VirtualFree(heap.ptr, 0, MEM_RELEASE);
|
|
@@ -1933,15 +1987,15 @@ static InstanceData *CreateInstance(Napi::Env env)
|
|
|
1933
1987
|
napi_unref_threadsafe_function(env, instance->broker);
|
|
1934
1988
|
|
|
1935
1989
|
#if defined(_WIN32) && (defined(__x86_64__) || defined(_M_AMD64))
|
|
1936
|
-
|
|
1990
|
+
void *teb = (void *)__readgsqword(0x30);
|
|
1937
1991
|
|
|
1938
|
-
instance->
|
|
1939
|
-
instance->
|
|
1992
|
+
instance->main_stack_max = *(void **)((uint8_t *)teb + 0x08); // StackBase
|
|
1993
|
+
instance->main_stack_min = *(void **)((uint8_t *)teb + 0x1478); // DeallocationStack
|
|
1940
1994
|
#elif defined(_WIN32) && (defined(__i386__) || defined(_M_IX86))
|
|
1941
|
-
|
|
1995
|
+
void *teb = (void *)__readfsdword(0x18);
|
|
1942
1996
|
|
|
1943
|
-
instance->
|
|
1944
|
-
instance->
|
|
1997
|
+
instance->main_stack_max = *(void **)((uint8_t *)teb + 0x04); // StackBase
|
|
1998
|
+
instance->main_stack_min = *(void **)((uint8_t *)teb + 0xE0C); // DeallocationStack
|
|
1945
1999
|
#endif
|
|
1946
2000
|
|
|
1947
2001
|
err_guard.Disable();
|
package/src/koffi/src/ffi.hh
CHANGED
|
@@ -232,6 +232,10 @@ struct InstanceMemory {
|
|
|
232
232
|
|
|
233
233
|
int16_t depth;
|
|
234
234
|
bool temporary;
|
|
235
|
+
|
|
236
|
+
#ifdef _WIN32
|
|
237
|
+
void *fiber;
|
|
238
|
+
#endif
|
|
235
239
|
};
|
|
236
240
|
|
|
237
241
|
struct InstanceData {
|
|
@@ -256,8 +260,8 @@ struct InstanceData {
|
|
|
256
260
|
napi_threadsafe_function broker = nullptr;
|
|
257
261
|
|
|
258
262
|
#ifdef _WIN32
|
|
259
|
-
void *
|
|
260
|
-
void *
|
|
263
|
+
void *main_stack_max;
|
|
264
|
+
void *main_stack_min;
|
|
261
265
|
#endif
|
|
262
266
|
|
|
263
267
|
HashMap<void *, int16_t> trampolines_map;
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|