koffi 2.2.2-beta.6 → 2.2.3-beta.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 +14 -0
- package/doc/callbacks.md +9 -2
- package/package.json +2 -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/src/koffi/src/abi_x64_win.cc +28 -0
- package/src/koffi/src/abi_x86.cc +35 -1
- package/src/koffi/src/call.cc +3 -0
- package/src/koffi/src/ffi.cc +19 -4
- package/src/koffi/src/ffi.hh +6 -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-beta.6/koffi_darwin_arm64.tar.gz +0 -0
- package/src/koffi/build/2.2.2-beta.6/koffi_darwin_x64.tar.gz +0 -0
- package/src/koffi/build/2.2.2-beta.6/koffi_freebsd_arm64.tar.gz +0 -0
- package/src/koffi/build/2.2.2-beta.6/koffi_freebsd_ia32.tar.gz +0 -0
- package/src/koffi/build/2.2.2-beta.6/koffi_freebsd_x64.tar.gz +0 -0
- package/src/koffi/build/2.2.2-beta.6/koffi_linux_arm32hf.tar.gz +0 -0
- package/src/koffi/build/2.2.2-beta.6/koffi_linux_arm64.tar.gz +0 -0
- package/src/koffi/build/2.2.2-beta.6/koffi_linux_ia32.tar.gz +0 -0
- package/src/koffi/build/2.2.2-beta.6/koffi_linux_riscv64hf64.tar.gz +0 -0
- package/src/koffi/build/2.2.2-beta.6/koffi_linux_x64.tar.gz +0 -0
- package/src/koffi/build/2.2.2-beta.6/koffi_openbsd_ia32.tar.gz +0 -0
- package/src/koffi/build/2.2.2-beta.6/koffi_openbsd_x64.tar.gz +0 -0
- package/src/koffi/build/2.2.2-beta.6/koffi_win32_arm64.tar.gz +0 -0
- package/src/koffi/build/2.2.2-beta.6/koffi_win32_ia32.tar.gz +0 -0
- package/src/koffi/build/2.2.2-beta.6/koffi_win32_x64.tar.gz +0 -0
package/ChangeLog.md
CHANGED
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
## History
|
|
4
4
|
|
|
5
|
+
### Koffi 2.2.2
|
|
6
|
+
|
|
7
|
+
**Main fixes:**
|
|
8
|
+
|
|
9
|
+
- Support transparent [asynchronous callbacks](callbacks.md#asynchronous-callbacks)
|
|
10
|
+
- Expand from a maximum of 16+16 to 1024 callbacks running in parallel
|
|
11
|
+
|
|
12
|
+
**Other fixes:**
|
|
13
|
+
|
|
14
|
+
- Fix bundler support by removing shebang from index.js
|
|
15
|
+
- Fix bugs when loading Koffi multiples times in same process (context aware module)
|
|
16
|
+
- Check N-API version when module is loaded
|
|
17
|
+
- Optimize callback unregistration
|
|
18
|
+
|
|
5
19
|
### Koffi 2.2.1
|
|
6
20
|
|
|
7
21
|
**Main fixes:**
|
package/doc/callbacks.md
CHANGED
|
@@ -172,9 +172,16 @@ console.log(array); // Prints ['123', 'bar', 'foo', 'foobar']
|
|
|
172
172
|
|
|
173
173
|
*New in Koffi 2.2.2*
|
|
174
174
|
|
|
175
|
-
|
|
175
|
+
JS execution is inherently single-threaded, so JS callbacks must run on the main thread. There are two ways you may want to call a callback function from another thread:
|
|
176
176
|
|
|
177
|
-
|
|
177
|
+
- Call the callback from an asynchronous FFI call (e.g. `waitpid.async`)
|
|
178
|
+
- Inside a synchronous FFI call, pass the callback to another thread
|
|
179
|
+
|
|
180
|
+
In both cases, Koffi will queue the call back to JS to run on the main thread, as soon as the JS event loop has a chance to run (for example when you await a promise).
|
|
181
|
+
|
|
182
|
+
```{warning}
|
|
183
|
+
Be careful, you can easily get into a deadlock situation if you call a callback from a secondary thread and your main thread never lets the JS event loop run (for example, if the main thread waits for the secondary thread to finish something itself).
|
|
184
|
+
```
|
|
178
185
|
|
|
179
186
|
## Handling of exceptions
|
|
180
187
|
|
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,6 +18,14 @@
|
|
|
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
|
+
|
|
21
29
|
#include <napi.h>
|
|
22
30
|
|
|
23
31
|
namespace RG {
|
|
@@ -216,6 +224,16 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
216
224
|
|
|
217
225
|
void CallData::Execute(const FunctionInfo *func)
|
|
218
226
|
{
|
|
227
|
+
NT_TIB *tib = (NT_TIB *)__readgsqword(0x30);
|
|
228
|
+
|
|
229
|
+
// Adjust TIB stack limits so SEH works correctly
|
|
230
|
+
RG_DEFER_C(base = tib->StackBase, limit = tib->StackLimit) {
|
|
231
|
+
tib->StackBase = base;
|
|
232
|
+
tib->StackLimit = limit;
|
|
233
|
+
};
|
|
234
|
+
tib->StackBase = mem->stack0.end();
|
|
235
|
+
tib->StackLimit = mem->stack0.ptr;
|
|
236
|
+
|
|
219
237
|
#define PERFORM_CALL(Suffix) \
|
|
220
238
|
([&]() { \
|
|
221
239
|
auto ret = (func->forward_fp ? ForwardCallX ## Suffix(func->func, new_sp, &old_sp) \
|
|
@@ -317,6 +335,16 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
|
|
|
317
335
|
if (RG_UNLIKELY(env.IsExceptionPending()))
|
|
318
336
|
return;
|
|
319
337
|
|
|
338
|
+
NT_TIB *tib = (NT_TIB *)__readgsqword(0x30);
|
|
339
|
+
|
|
340
|
+
// Restore real thread stack limits
|
|
341
|
+
RG_DEFER_C(base = tib->StackBase, limit = tib->StackLimit) {
|
|
342
|
+
tib->StackBase = base;
|
|
343
|
+
tib->StackLimit = limit;
|
|
344
|
+
};
|
|
345
|
+
tib->StackBase = instance->main_stack_base;
|
|
346
|
+
tib->StackLimit = instance->main_stack_limit;
|
|
347
|
+
|
|
320
348
|
const TrampolineInfo &trampoline = shared.trampolines[idx];
|
|
321
349
|
|
|
322
350
|
const FunctionInfo *proto = trampoline.proto;
|
package/src/koffi/src/abi_x86.cc
CHANGED
|
@@ -18,6 +18,16 @@
|
|
|
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
|
+
|
|
21
31
|
#include <napi.h>
|
|
22
32
|
|
|
23
33
|
namespace RG {
|
|
@@ -297,6 +307,18 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
297
307
|
|
|
298
308
|
void CallData::Execute(const FunctionInfo *func)
|
|
299
309
|
{
|
|
310
|
+
#ifdef _WIN32
|
|
311
|
+
NT_TIB *tib = (NT_TIB *)__readfsdword(0x18);
|
|
312
|
+
|
|
313
|
+
// Adjust TIB stack limits so SEH works correctly
|
|
314
|
+
RG_DEFER_C(base = tib->StackBase, limit = tib->StackLimit) {
|
|
315
|
+
tib->StackBase = base;
|
|
316
|
+
tib->StackLimit = limit;
|
|
317
|
+
};
|
|
318
|
+
tib->StackBase = mem->stack0.end();
|
|
319
|
+
tib->StackLimit = mem->stack0.ptr;
|
|
320
|
+
#endif
|
|
321
|
+
|
|
300
322
|
#define PERFORM_CALL(Suffix) \
|
|
301
323
|
([&]() { \
|
|
302
324
|
auto ret = (func->fast ? ForwardCallR ## Suffix(func->func, new_sp, &old_sp) \
|
|
@@ -394,11 +416,23 @@ Napi::Value CallData::Complete(const FunctionInfo *func)
|
|
|
394
416
|
RG_UNREACHABLE();
|
|
395
417
|
}
|
|
396
418
|
|
|
397
|
-
void CallData::Relay(Size idx, uint8_t
|
|
419
|
+
void CallData::Relay(Size idx, uint8_t *, uint8_t *caller_sp, bool async, BackRegisters *out_reg)
|
|
398
420
|
{
|
|
399
421
|
if (RG_UNLIKELY(env.IsExceptionPending()))
|
|
400
422
|
return;
|
|
401
423
|
|
|
424
|
+
#ifdef _WIN32
|
|
425
|
+
NT_TIB *tib = (NT_TIB *)__readfsdword(0x18);
|
|
426
|
+
|
|
427
|
+
// Restore real thread stack limits
|
|
428
|
+
RG_DEFER_C(base = tib->StackBase, limit = tib->StackLimit) {
|
|
429
|
+
tib->StackBase = base;
|
|
430
|
+
tib->StackLimit = limit;
|
|
431
|
+
};
|
|
432
|
+
tib->StackBase = instance->main_stack_base;
|
|
433
|
+
tib->StackLimit = instance->main_stack_limit;
|
|
434
|
+
#endif
|
|
435
|
+
|
|
402
436
|
const TrampolineInfo &trampoline = shared.trampolines[idx];
|
|
403
437
|
|
|
404
438
|
const FunctionInfo *proto = trampoline.proto;
|
package/src/koffi/src/call.cc
CHANGED
|
@@ -81,6 +81,9 @@ CallData::~CallData()
|
|
|
81
81
|
void CallData::RelaySafe(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegisters *out_reg)
|
|
82
82
|
{
|
|
83
83
|
if (std::this_thread::get_id() != instance->main_thread_id) {
|
|
84
|
+
// JS/V8 is single-threaded, and runs on main_thread_id. Forward the call
|
|
85
|
+
// to the JS event loop.
|
|
86
|
+
|
|
84
87
|
RelayContext ctx;
|
|
85
88
|
|
|
86
89
|
ctx.call = this;
|
package/src/koffi/src/ffi.cc
CHANGED
|
@@ -1030,6 +1030,9 @@ static InstanceMemory *AllocateMemory(InstanceData *instance, Size stack_size, S
|
|
|
1030
1030
|
mem->stack.len -= 16;
|
|
1031
1031
|
#endif
|
|
1032
1032
|
|
|
1033
|
+
// Keep real stack limits intact, in case we need them
|
|
1034
|
+
mem->stack0 = mem->stack;
|
|
1035
|
+
|
|
1033
1036
|
mem->heap.len = heap_size;
|
|
1034
1037
|
#ifdef _WIN32
|
|
1035
1038
|
mem->heap.ptr = (uint8_t *)VirtualAlloc(nullptr, mem->heap.len, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
|
|
@@ -1065,9 +1068,6 @@ static Napi::Value TranslateNormalCall(const Napi::CallbackInfo &info)
|
|
|
1065
1068
|
InstanceMemory *mem = instance->memories[0];
|
|
1066
1069
|
CallData call(env, instance, mem);
|
|
1067
1070
|
|
|
1068
|
-
RG_DEFER_C(prev_call = exec_call) { exec_call = prev_call; };
|
|
1069
|
-
exec_call = &call;
|
|
1070
|
-
|
|
1071
1071
|
if (!RG_UNLIKELY(call.Prepare(func, info)))
|
|
1072
1072
|
return env.Null();
|
|
1073
1073
|
|
|
@@ -1113,7 +1113,7 @@ static Napi::Value TranslateVariadicCall(const Napi::CallbackInfo &info)
|
|
|
1113
1113
|
for (Size i = func.parameters.len; i < (Size)info.Length(); i += 2) {
|
|
1114
1114
|
ParameterInfo param = {};
|
|
1115
1115
|
|
|
1116
|
-
param.type = ResolveType(info[i], ¶m.directions);
|
|
1116
|
+
param.type = ResolveType(info[(uint32_t)i], ¶m.directions);
|
|
1117
1117
|
|
|
1118
1118
|
if (RG_UNLIKELY(!param.type))
|
|
1119
1119
|
return env.Null();
|
|
@@ -1893,6 +1893,9 @@ extern "C" void RelayCallback(Size idx, uint8_t *own_sp, uint8_t *caller_sp, Bac
|
|
|
1893
1893
|
if (RG_LIKELY(exec_call)) {
|
|
1894
1894
|
exec_call->RelaySafe(idx, own_sp, caller_sp, out_reg);
|
|
1895
1895
|
} else {
|
|
1896
|
+
// This happens if the callback pointer is called from a different thread
|
|
1897
|
+
// than the one that runs the FFI call (sync or async).
|
|
1898
|
+
|
|
1896
1899
|
TrampolineInfo *trampoline = &shared.trampolines[idx];
|
|
1897
1900
|
|
|
1898
1901
|
Napi::Env env = trampoline->func.Env();
|
|
@@ -1929,6 +1932,18 @@ static InstanceData *CreateInstance(Napi::Env env)
|
|
|
1929
1932
|
}
|
|
1930
1933
|
napi_unref_threadsafe_function(env, instance->broker);
|
|
1931
1934
|
|
|
1935
|
+
#if defined(_WIN32) && (defined(__x86_64__) || defined(_M_AMD64))
|
|
1936
|
+
NT_TIB *tib = (NT_TIB *)__readgsqword(0x30);
|
|
1937
|
+
|
|
1938
|
+
instance->main_stack_base = tib->StackBase;
|
|
1939
|
+
instance->main_stack_limit = tib->StackLimit;
|
|
1940
|
+
#elif defined(_WIN32) && (defined(__i386__) || defined(_M_IX86))
|
|
1941
|
+
NT_TIB *tib = (NT_TIB *)__readfsdword(0x18);
|
|
1942
|
+
|
|
1943
|
+
instance->main_stack_base = tib->StackBase;
|
|
1944
|
+
instance->main_stack_limit = tib->StackLimit;
|
|
1945
|
+
#endif
|
|
1946
|
+
|
|
1932
1947
|
err_guard.Disable();
|
|
1933
1948
|
return instance;
|
|
1934
1949
|
}
|
package/src/koffi/src/ffi.hh
CHANGED
|
@@ -225,6 +225,7 @@ 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
|
|
@@ -254,6 +255,11 @@ struct InstanceData {
|
|
|
254
255
|
std::thread::id main_thread_id;
|
|
255
256
|
napi_threadsafe_function broker = nullptr;
|
|
256
257
|
|
|
258
|
+
#ifdef _WIN32
|
|
259
|
+
void *main_stack_base;
|
|
260
|
+
void *main_stack_limit;
|
|
261
|
+
#endif
|
|
262
|
+
|
|
257
263
|
HashMap<void *, int16_t> trampolines_map;
|
|
258
264
|
|
|
259
265
|
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
|