koffi 2.2.2 → 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 +35 -0
- package/src/koffi/src/abi_x86.cc +42 -1
- package/src/koffi/src/ffi.cc +73 -4
- package/src/koffi/src/ffi.hh +10 -0
- package/vendor/miniz/ChangeLog.md +4 -0
- package/vendor/miniz/miniz.c +1 -1
- package/vendor/miniz/miniz.h +3 -3
- package/src/koffi/build/2.2.2/koffi_darwin_arm64.tar.gz +0 -0
- package/src/koffi/build/2.2.2/koffi_darwin_x64.tar.gz +0 -0
- package/src/koffi/build/2.2.2/koffi_freebsd_arm64.tar.gz +0 -0
- package/src/koffi/build/2.2.2/koffi_freebsd_ia32.tar.gz +0 -0
- package/src/koffi/build/2.2.2/koffi_freebsd_x64.tar.gz +0 -0
- package/src/koffi/build/2.2.2/koffi_linux_arm32hf.tar.gz +0 -0
- package/src/koffi/build/2.2.2/koffi_linux_arm64.tar.gz +0 -0
- package/src/koffi/build/2.2.2/koffi_linux_ia32.tar.gz +0 -0
- package/src/koffi/build/2.2.2/koffi_linux_riscv64hf64.tar.gz +0 -0
- package/src/koffi/build/2.2.2/koffi_linux_x64.tar.gz +0 -0
- package/src/koffi/build/2.2.2/koffi_openbsd_ia32.tar.gz +0 -0
- package/src/koffi/build/2.2.2/koffi_openbsd_x64.tar.gz +0 -0
- package/src/koffi/build/2.2.2/koffi_win32_arm64.tar.gz +0 -0
- package/src/koffi/build/2.2.2/koffi_win32_ia32.tar.gz +0 -0
- package/src/koffi/build/2.2.2/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
|
|
@@ -40,6 +40,10 @@ extern "C" napi_value CallSwitchStack(Napi::Function *func, size_t argc, napi_va
|
|
|
40
40
|
|
|
41
41
|
#include "abi_trampolines.inc"
|
|
42
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
|
+
|
|
43
47
|
bool AnalyseFunction(Napi::Env, InstanceData *, FunctionInfo *func)
|
|
44
48
|
{
|
|
45
49
|
func->ret.regular = IsRegularSize(func->ret.type->size, 8);
|
|
@@ -216,6 +220,22 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
216
220
|
|
|
217
221
|
void CallData::Execute(const FunctionInfo *func)
|
|
218
222
|
{
|
|
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;
|
|
232
|
+
};
|
|
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;
|
|
238
|
+
|
|
219
239
|
#define PERFORM_CALL(Suffix) \
|
|
220
240
|
([&]() { \
|
|
221
241
|
auto ret = (func->forward_fp ? ForwardCallX ## Suffix(func->func, new_sp, &old_sp) \
|
|
@@ -317,6 +337,21 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
|
|
|
317
337
|
if (RG_UNLIKELY(env.IsExceptionPending()))
|
|
318
338
|
return;
|
|
319
339
|
|
|
340
|
+
void *teb = (void *)__readgsqword(0x30);
|
|
341
|
+
|
|
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;
|
|
348
|
+
};
|
|
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;
|
|
354
|
+
|
|
320
355
|
const TrampolineInfo &trampoline = shared.trampolines[idx];
|
|
321
356
|
|
|
322
357
|
const FunctionInfo *proto = trampoline.proto;
|
package/src/koffi/src/abi_x86.cc
CHANGED
|
@@ -46,6 +46,12 @@ extern "C" napi_value CallSwitchStack(Napi::Function *func, size_t argc, napi_va
|
|
|
46
46
|
|
|
47
47
|
#include "abi_trampolines.inc"
|
|
48
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
|
+
|
|
49
55
|
bool AnalyseFunction(Napi::Env env, InstanceData *instance, FunctionInfo *func)
|
|
50
56
|
{
|
|
51
57
|
if (!func->lib && func->convention != CallConvention::Cdecl &&
|
|
@@ -297,6 +303,24 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
297
303
|
|
|
298
304
|
void CallData::Execute(const FunctionInfo *func)
|
|
299
305
|
{
|
|
306
|
+
#ifdef _WIN32
|
|
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;
|
|
316
|
+
};
|
|
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;
|
|
322
|
+
#endif
|
|
323
|
+
|
|
300
324
|
#define PERFORM_CALL(Suffix) \
|
|
301
325
|
([&]() { \
|
|
302
326
|
auto ret = (func->fast ? ForwardCallR ## Suffix(func->func, new_sp, &old_sp) \
|
|
@@ -394,11 +418,28 @@ Napi::Value CallData::Complete(const FunctionInfo *func)
|
|
|
394
418
|
RG_UNREACHABLE();
|
|
395
419
|
}
|
|
396
420
|
|
|
397
|
-
void CallData::Relay(Size idx, uint8_t
|
|
421
|
+
void CallData::Relay(Size idx, uint8_t *, uint8_t *caller_sp, bool async, BackRegisters *out_reg)
|
|
398
422
|
{
|
|
399
423
|
if (RG_UNLIKELY(env.IsExceptionPending()))
|
|
400
424
|
return;
|
|
401
425
|
|
|
426
|
+
#ifdef _WIN32
|
|
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
|
+
};
|
|
436
|
+
|
|
437
|
+
// Restore real thread stack limits
|
|
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;
|
|
441
|
+
#endif
|
|
442
|
+
|
|
402
443
|
const TrampolineInfo &trampoline = shared.trampolines[idx];
|
|
403
444
|
|
|
404
445
|
const FunctionInfo *proto = trampoline.proto;
|
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);
|
|
@@ -1030,6 +1083,9 @@ static InstanceMemory *AllocateMemory(InstanceData *instance, Size stack_size, S
|
|
|
1030
1083
|
mem->stack.len -= 16;
|
|
1031
1084
|
#endif
|
|
1032
1085
|
|
|
1086
|
+
// Keep real stack limits intact, in case we need them
|
|
1087
|
+
mem->stack0 = mem->stack;
|
|
1088
|
+
|
|
1033
1089
|
mem->heap.len = heap_size;
|
|
1034
1090
|
#ifdef _WIN32
|
|
1035
1091
|
mem->heap.ptr = (uint8_t *)VirtualAlloc(nullptr, mem->heap.len, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
|
|
@@ -1048,6 +1104,7 @@ static InstanceMemory *AllocateMemory(InstanceData *instance, Size stack_size, S
|
|
|
1048
1104
|
mem->temporary = true;
|
|
1049
1105
|
}
|
|
1050
1106
|
|
|
1107
|
+
mem_guard.Disable();
|
|
1051
1108
|
return mem;
|
|
1052
1109
|
}
|
|
1053
1110
|
|
|
@@ -1688,8 +1745,8 @@ void FunctionInfo::Unref() const
|
|
|
1688
1745
|
InstanceMemory::~InstanceMemory()
|
|
1689
1746
|
{
|
|
1690
1747
|
#ifdef _WIN32
|
|
1691
|
-
if (
|
|
1692
|
-
|
|
1748
|
+
if (fiber) {
|
|
1749
|
+
DeleteFiber(fiber);
|
|
1693
1750
|
}
|
|
1694
1751
|
if (heap.ptr) {
|
|
1695
1752
|
VirtualFree(heap.ptr, 0, MEM_RELEASE);
|
|
@@ -1929,6 +1986,18 @@ static InstanceData *CreateInstance(Napi::Env env)
|
|
|
1929
1986
|
}
|
|
1930
1987
|
napi_unref_threadsafe_function(env, instance->broker);
|
|
1931
1988
|
|
|
1989
|
+
#if defined(_WIN32) && (defined(__x86_64__) || defined(_M_AMD64))
|
|
1990
|
+
void *teb = (void *)__readgsqword(0x30);
|
|
1991
|
+
|
|
1992
|
+
instance->main_stack_max = *(void **)((uint8_t *)teb + 0x08); // StackBase
|
|
1993
|
+
instance->main_stack_min = *(void **)((uint8_t *)teb + 0x1478); // DeallocationStack
|
|
1994
|
+
#elif defined(_WIN32) && (defined(__i386__) || defined(_M_IX86))
|
|
1995
|
+
void *teb = (void *)__readfsdword(0x18);
|
|
1996
|
+
|
|
1997
|
+
instance->main_stack_max = *(void **)((uint8_t *)teb + 0x04); // StackBase
|
|
1998
|
+
instance->main_stack_min = *(void **)((uint8_t *)teb + 0xE0C); // DeallocationStack
|
|
1999
|
+
#endif
|
|
2000
|
+
|
|
1932
2001
|
err_guard.Disable();
|
|
1933
2002
|
return instance;
|
|
1934
2003
|
}
|
package/src/koffi/src/ffi.hh
CHANGED
|
@@ -225,12 +225,17 @@ struct InstanceMemory {
|
|
|
225
225
|
~InstanceMemory();
|
|
226
226
|
|
|
227
227
|
Span<uint8_t> stack;
|
|
228
|
+
Span<uint8_t> stack0;
|
|
228
229
|
Span<uint8_t> heap;
|
|
229
230
|
|
|
230
231
|
uint16_t generation; // Can wrap without risk
|
|
231
232
|
|
|
232
233
|
int16_t depth;
|
|
233
234
|
bool temporary;
|
|
235
|
+
|
|
236
|
+
#ifdef _WIN32
|
|
237
|
+
void *fiber;
|
|
238
|
+
#endif
|
|
234
239
|
};
|
|
235
240
|
|
|
236
241
|
struct InstanceData {
|
|
@@ -254,6 +259,11 @@ struct InstanceData {
|
|
|
254
259
|
std::thread::id main_thread_id;
|
|
255
260
|
napi_threadsafe_function broker = nullptr;
|
|
256
261
|
|
|
262
|
+
#ifdef _WIN32
|
|
263
|
+
void *main_stack_max;
|
|
264
|
+
void *main_stack_min;
|
|
265
|
+
#endif
|
|
266
|
+
|
|
257
267
|
HashMap<void *, int16_t> trampolines_map;
|
|
258
268
|
|
|
259
269
|
BlockAllocator str_alloc;
|
package/vendor/miniz/miniz.c
CHANGED
|
@@ -3068,7 +3068,7 @@ static WCHAR* mz_utf8z_to_widechar(const char* str)
|
|
|
3068
3068
|
{
|
|
3069
3069
|
int reqChars = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);
|
|
3070
3070
|
WCHAR* wStr = (WCHAR*)malloc(reqChars * sizeof(WCHAR));
|
|
3071
|
-
MultiByteToWideChar(CP_UTF8, 0, str, -1, wStr,
|
|
3071
|
+
MultiByteToWideChar(CP_UTF8, 0, str, -1, wStr, reqChars);
|
|
3072
3072
|
return wStr;
|
|
3073
3073
|
}
|
|
3074
3074
|
|
package/vendor/miniz/miniz.h
CHANGED
|
@@ -275,10 +275,10 @@ enum
|
|
|
275
275
|
MZ_DEFAULT_COMPRESSION = -1
|
|
276
276
|
};
|
|
277
277
|
|
|
278
|
-
#define MZ_VERSION "11.0.
|
|
279
|
-
#define MZ_VERNUM
|
|
278
|
+
#define MZ_VERSION "11.0.2"
|
|
279
|
+
#define MZ_VERNUM 0xB002
|
|
280
280
|
#define MZ_VER_MAJOR 11
|
|
281
|
-
#define MZ_VER_MINOR
|
|
281
|
+
#define MZ_VER_MINOR 2
|
|
282
282
|
#define MZ_VER_REVISION 0
|
|
283
283
|
#define MZ_VER_SUBREVISION 0
|
|
284
284
|
|
|
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
|