koffi 2.2.1 → 2.2.2-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.2-beta.2/koffi_darwin_arm64.tar.gz +0 -0
- package/src/koffi/build/2.2.2-beta.2/koffi_darwin_x64.tar.gz +0 -0
- package/src/koffi/build/2.2.2-beta.2/koffi_freebsd_arm64.tar.gz +0 -0
- package/src/koffi/build/2.2.2-beta.2/koffi_freebsd_ia32.tar.gz +0 -0
- package/src/koffi/build/2.2.2-beta.2/koffi_freebsd_x64.tar.gz +0 -0
- package/src/koffi/build/2.2.2-beta.2/koffi_linux_arm32hf.tar.gz +0 -0
- package/src/koffi/build/2.2.2-beta.2/koffi_linux_arm64.tar.gz +0 -0
- package/src/koffi/build/2.2.2-beta.2/koffi_linux_ia32.tar.gz +0 -0
- package/src/koffi/build/2.2.2-beta.2/koffi_linux_riscv64hf64.tar.gz +0 -0
- package/src/koffi/build/2.2.2-beta.2/koffi_linux_x64.tar.gz +0 -0
- package/src/koffi/build/2.2.2-beta.2/koffi_openbsd_ia32.tar.gz +0 -0
- package/src/koffi/build/2.2.2-beta.2/koffi_openbsd_x64.tar.gz +0 -0
- package/src/koffi/build/2.2.2-beta.2/koffi_win32_arm64.tar.gz +0 -0
- package/src/koffi/build/2.2.2-beta.2/koffi_win32_ia32.tar.gz +0 -0
- package/src/koffi/build/2.2.2-beta.2/koffi_win32_x64.tar.gz +0 -0
- package/src/koffi/qemu/qemu.js +12 -10
- package/src/koffi/src/abi_arm32.cc +7 -12
- package/src/koffi/src/abi_arm64.cc +7 -12
- package/src/koffi/src/abi_riscv64.cc +7 -12
- package/src/koffi/src/abi_x64_sysv.cc +7 -12
- package/src/koffi/src/abi_x64_win.cc +7 -12
- package/src/koffi/src/abi_x86.cc +7 -12
- package/src/koffi/src/call.cc +51 -2
- package/src/koffi/src/call.hh +6 -1
- package/src/koffi/src/ffi.cc +61 -7
- package/src/koffi/src/ffi.hh +2 -0
- package/src/koffi/src/index.js +7 -2
- package/src/koffi/test/CMakeLists.txt +1 -1
- package/src/koffi/test/async.js +3 -0
- package/src/koffi/test/callbacks.js +11 -0
- package/vendor/{sqlite3mc → sqlite3}/sqlite3.c +139 -43
- package/vendor/{sqlite3mc → sqlite3}/sqlite3.h +10 -3
- package/vendor/{sqlite3mc → sqlite3}/sqlite3ext.h +0 -0
- package/vendor/{sqlite3mc → sqlite3}/sqlite3mc.c +156 -53
- package/vendor/{sqlite3mc → sqlite3}/sqlite3mc.def +0 -0
- package/vendor/{sqlite3mc → sqlite3}/sqlite3mc.h +12 -5
- package/vendor/sqlite3/wasm/README.txt +23 -0
- package/vendor/sqlite3/wasm/common/SqliteTestUtil.js +236 -0
- package/vendor/sqlite3/wasm/common/emscripten.css +24 -0
- package/vendor/sqlite3/wasm/common/testing.css +63 -0
- package/vendor/sqlite3/wasm/demo-123-worker.html +44 -0
- package/vendor/sqlite3/wasm/demo-123.html +24 -0
- package/vendor/sqlite3/wasm/demo-123.js +289 -0
- package/vendor/sqlite3/wasm/demo-jsstorage.html +49 -0
- package/vendor/sqlite3/wasm/demo-jsstorage.js +114 -0
- package/vendor/sqlite3/wasm/demo-worker1-promiser.html +34 -0
- package/vendor/sqlite3/wasm/demo-worker1-promiser.js +270 -0
- package/vendor/sqlite3/wasm/demo-worker1.html +34 -0
- package/vendor/sqlite3/wasm/demo-worker1.js +345 -0
- package/vendor/sqlite3/wasm/index.html +90 -0
- package/vendor/sqlite3/wasm/jswasm/sqlite3-opfs-async-proxy.js +830 -0
- package/vendor/sqlite3/wasm/jswasm/sqlite3-worker1-promiser.js +259 -0
- package/vendor/sqlite3/wasm/jswasm/sqlite3-worker1.js +49 -0
- package/vendor/sqlite3/wasm/jswasm/sqlite3.js +10119 -0
- package/vendor/sqlite3/wasm/jswasm/sqlite3.wasm +0 -0
- package/vendor/sqlite3/wasm/tester1-worker.html +63 -0
- package/vendor/sqlite3/wasm/tester1.html +28 -0
- package/vendor/sqlite3/wasm/tester1.js +1864 -0
- package/src/koffi/build/2.2.1/koffi_darwin_arm64.tar.gz +0 -0
- package/src/koffi/build/2.2.1/koffi_darwin_x64.tar.gz +0 -0
- package/src/koffi/build/2.2.1/koffi_freebsd_arm64.tar.gz +0 -0
- package/src/koffi/build/2.2.1/koffi_freebsd_ia32.tar.gz +0 -0
- package/src/koffi/build/2.2.1/koffi_freebsd_x64.tar.gz +0 -0
- package/src/koffi/build/2.2.1/koffi_linux_arm32hf.tar.gz +0 -0
- package/src/koffi/build/2.2.1/koffi_linux_arm64.tar.gz +0 -0
- package/src/koffi/build/2.2.1/koffi_linux_ia32.tar.gz +0 -0
- package/src/koffi/build/2.2.1/koffi_linux_riscv64hf64.tar.gz +0 -0
- package/src/koffi/build/2.2.1/koffi_linux_x64.tar.gz +0 -0
- package/src/koffi/build/2.2.1/koffi_openbsd_ia32.tar.gz +0 -0
- package/src/koffi/build/2.2.1/koffi_openbsd_x64.tar.gz +0 -0
- package/src/koffi/build/2.2.1/koffi_win32_arm64.tar.gz +0 -0
- package/src/koffi/build/2.2.1/koffi_win32_ia32.tar.gz +0 -0
- package/src/koffi/build/2.2.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
|
package/src/koffi/qemu/qemu.js
CHANGED
|
@@ -63,6 +63,7 @@ async function main() {
|
|
|
63
63
|
switch (process.argv[2]) {
|
|
64
64
|
case 'pack': { command = pack; } break;
|
|
65
65
|
case 'publish': { command = publish; } break;
|
|
66
|
+
case 'prepare': { command = prepare; } break;
|
|
66
67
|
case 'test': { command = test; } break;
|
|
67
68
|
case 'start': { command = start; } break;
|
|
68
69
|
case 'stop': { command = stop; } break;
|
|
@@ -190,7 +191,7 @@ async function main() {
|
|
|
190
191
|
console.log();
|
|
191
192
|
|
|
192
193
|
try {
|
|
193
|
-
let success = await command();
|
|
194
|
+
let success = !!(await command());
|
|
194
195
|
process.exit(!success);
|
|
195
196
|
} catch (err) {
|
|
196
197
|
console.error(err);
|
|
@@ -205,6 +206,7 @@ Commands:
|
|
|
205
206
|
test Run the machines and perform the tests (default)
|
|
206
207
|
pack Create NPM package with prebuilt Koffi binaries
|
|
207
208
|
publish Publish NPM package with prebuilt Koffi binaries
|
|
209
|
+
prepare Prepare distribution-ready NPM package directory
|
|
208
210
|
|
|
209
211
|
start Start the machines but don't run anythingh
|
|
210
212
|
stop Stop running machines
|
|
@@ -290,10 +292,9 @@ async function start(detach = true) {
|
|
|
290
292
|
|
|
291
293
|
async function pack() {
|
|
292
294
|
let pack_dir = script_dir + '/../build';
|
|
293
|
-
let dist_dir =
|
|
295
|
+
let dist_dir = await prepare(dist_dir);
|
|
294
296
|
|
|
295
|
-
|
|
296
|
-
if (!success)
|
|
297
|
+
if (dist_dir == null)
|
|
297
298
|
return false;
|
|
298
299
|
|
|
299
300
|
let npm = (process.platform == 'win32') ? 'npm.cmd' : 'npm';
|
|
@@ -305,10 +306,9 @@ async function pack() {
|
|
|
305
306
|
}
|
|
306
307
|
|
|
307
308
|
async function publish() {
|
|
308
|
-
let dist_dir =
|
|
309
|
+
let dist_dir = await prepare();
|
|
309
310
|
|
|
310
|
-
|
|
311
|
-
if (!success)
|
|
311
|
+
if (dist_dir == null)
|
|
312
312
|
return false;
|
|
313
313
|
|
|
314
314
|
let npm = (process.platform == 'win32') ? 'npm.cmd' : 'npm';
|
|
@@ -319,7 +319,8 @@ async function publish() {
|
|
|
319
319
|
});
|
|
320
320
|
}
|
|
321
321
|
|
|
322
|
-
async function prepare(
|
|
322
|
+
async function prepare() {
|
|
323
|
+
let dist_dir = script_dir + '/../build/dist';
|
|
323
324
|
let snapshot_dir = snapshot();
|
|
324
325
|
|
|
325
326
|
let json = fs.readFileSync(root_dir + '/src/koffi/package.json', { encoding: 'utf-8' });
|
|
@@ -457,7 +458,7 @@ async function prepare(dist_dir) {
|
|
|
457
458
|
if (!success) {
|
|
458
459
|
console.log('');
|
|
459
460
|
console.log('>> Status: ' + chalk.bold.red('FAILED'));
|
|
460
|
-
return
|
|
461
|
+
return null;
|
|
461
462
|
}
|
|
462
463
|
}
|
|
463
464
|
|
|
@@ -495,7 +496,7 @@ async function prepare(dist_dir) {
|
|
|
495
496
|
fs.renameSync(dist_dir + '/web/koffi.dev', dist_dir + '/doc');
|
|
496
497
|
}
|
|
497
498
|
|
|
498
|
-
return
|
|
499
|
+
return dist_dir;
|
|
499
500
|
}
|
|
500
501
|
|
|
501
502
|
function snapshot() {
|
|
@@ -519,6 +520,7 @@ function snapshot() {
|
|
|
519
520
|
parts[1] == 'miniz' ||
|
|
520
521
|
parts[1] == 'node-addon-api' ||
|
|
521
522
|
parts[1] == 'raylib' ||
|
|
523
|
+
parts[1] == 'sqlite3' ||
|
|
522
524
|
parts[1] == 'sqlite3mc';
|
|
523
525
|
} else if (parts[0] == 'web') {
|
|
524
526
|
return parts[1] == null || parts[1] == 'koffi.dev';
|
|
@@ -121,8 +121,6 @@ static void *const Trampolines[][2] = {
|
|
|
121
121
|
};
|
|
122
122
|
RG_STATIC_ASSERT(RG_LEN(Trampolines) == MaxTrampolines * 2);
|
|
123
123
|
|
|
124
|
-
static RG_THREAD_LOCAL CallData *exec_call;
|
|
125
|
-
|
|
126
124
|
static inline int IsHFA(const TypeInfo *type)
|
|
127
125
|
{
|
|
128
126
|
#ifdef __ARM_PCS_VFP
|
|
@@ -495,9 +493,6 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
|
|
|
495
493
|
|
|
496
494
|
void CallData::Execute()
|
|
497
495
|
{
|
|
498
|
-
RG_DEFER_C(prev_call = exec_call) { exec_call = prev_call; };
|
|
499
|
-
exec_call = this;
|
|
500
|
-
|
|
501
496
|
#define PERFORM_CALL(Suffix) \
|
|
502
497
|
([&]() { \
|
|
503
498
|
auto ret = (func->forward_fp ? ForwardCallX ## Suffix(func->func, new_sp, &old_sp) \
|
|
@@ -863,8 +858,13 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
|
|
|
863
858
|
const TypeInfo *type = proto->ret.type;
|
|
864
859
|
|
|
865
860
|
// Make the call
|
|
866
|
-
napi_value ret
|
|
867
|
-
|
|
861
|
+
napi_value ret;
|
|
862
|
+
if (async) {
|
|
863
|
+
ret = (napi_value)func.Call(arguments[0], arguments.len - 1, arguments.data + 1);
|
|
864
|
+
} else {
|
|
865
|
+
ret = CallSwitchStack(&func, (size_t)arguments.len, arguments.data, old_sp, &mem->stack,
|
|
866
|
+
[](Napi::Function *func, size_t argc, napi_value *argv) { return (napi_value)func->Call(argv[0], argc - 1, argv + 1); });
|
|
867
|
+
}
|
|
868
868
|
Napi::Value value(env, ret);
|
|
869
869
|
|
|
870
870
|
if (RG_UNLIKELY(env.IsExceptionPending()))
|
|
@@ -1059,11 +1059,6 @@ void *GetTrampoline(Size idx, const FunctionInfo *proto)
|
|
|
1059
1059
|
return Trampolines[idx][vec];
|
|
1060
1060
|
}
|
|
1061
1061
|
|
|
1062
|
-
extern "C" void RelayCallback(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegisters *out_reg)
|
|
1063
|
-
{
|
|
1064
|
-
exec_call->Relay(idx, own_sp, caller_sp, out_reg);
|
|
1065
|
-
}
|
|
1066
|
-
|
|
1067
1062
|
}
|
|
1068
1063
|
|
|
1069
1064
|
#endif
|
|
@@ -123,8 +123,6 @@ static void *const Trampolines[][2] = {
|
|
|
123
123
|
};
|
|
124
124
|
RG_STATIC_ASSERT(RG_LEN(Trampolines) == MaxTrampolines * 2);
|
|
125
125
|
|
|
126
|
-
static RG_THREAD_LOCAL CallData *exec_call;
|
|
127
|
-
|
|
128
126
|
static inline int IsHFA(const TypeInfo *type)
|
|
129
127
|
{
|
|
130
128
|
return IsHFA(type, 1, 4);
|
|
@@ -563,9 +561,6 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
|
|
|
563
561
|
|
|
564
562
|
void CallData::Execute()
|
|
565
563
|
{
|
|
566
|
-
RG_DEFER_C(prev_call = exec_call) { exec_call = prev_call; };
|
|
567
|
-
exec_call = this;
|
|
568
|
-
|
|
569
564
|
#define PERFORM_CALL(Suffix) \
|
|
570
565
|
([&]() { \
|
|
571
566
|
auto ret = (func->forward_fp ? ForwardCallX ## Suffix(func->func, new_sp, &old_sp) \
|
|
@@ -1088,8 +1083,13 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
|
|
|
1088
1083
|
const TypeInfo *type = proto->ret.type;
|
|
1089
1084
|
|
|
1090
1085
|
// Make the call
|
|
1091
|
-
napi_value ret
|
|
1092
|
-
|
|
1086
|
+
napi_value ret;
|
|
1087
|
+
if (async) {
|
|
1088
|
+
ret = (napi_value)func.Call(arguments[0], arguments.len - 1, arguments.data + 1);
|
|
1089
|
+
} else {
|
|
1090
|
+
ret = CallSwitchStack(&func, (size_t)arguments.len, arguments.data, old_sp, &mem->stack,
|
|
1091
|
+
[](Napi::Function *func, size_t argc, napi_value *argv) { return (napi_value)func->Call(argv[0], argc - 1, argv + 1); });
|
|
1092
|
+
}
|
|
1093
1093
|
Napi::Value value(env, ret);
|
|
1094
1094
|
|
|
1095
1095
|
if (RG_UNLIKELY(env.IsExceptionPending()))
|
|
@@ -1252,11 +1252,6 @@ void *GetTrampoline(Size idx, const FunctionInfo *proto)
|
|
|
1252
1252
|
return Trampolines[idx][vec];
|
|
1253
1253
|
}
|
|
1254
1254
|
|
|
1255
|
-
extern "C" void RelayCallback(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegisters *out_reg)
|
|
1256
|
-
{
|
|
1257
|
-
exec_call->Relay(idx, own_sp, caller_sp, out_reg);
|
|
1258
|
-
}
|
|
1259
|
-
|
|
1260
1255
|
}
|
|
1261
1256
|
|
|
1262
1257
|
#endif
|
|
@@ -131,8 +131,6 @@ static void *const Trampolines[][2] = {
|
|
|
131
131
|
};
|
|
132
132
|
RG_STATIC_ASSERT(RG_LEN(Trampolines) == MaxTrampolines * 2);
|
|
133
133
|
|
|
134
|
-
static RG_THREAD_LOCAL CallData *exec_call;
|
|
135
|
-
|
|
136
134
|
static void AnalyseParameter(ParameterInfo *param, int gpr_avail, int vec_avail)
|
|
137
135
|
{
|
|
138
136
|
gpr_avail = std::min(2, gpr_avail);
|
|
@@ -410,9 +408,6 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
|
|
|
410
408
|
|
|
411
409
|
void CallData::Execute()
|
|
412
410
|
{
|
|
413
|
-
RG_DEFER_C(prev_call = exec_call) { exec_call = prev_call; };
|
|
414
|
-
exec_call = this;
|
|
415
|
-
|
|
416
411
|
#define PERFORM_CALL(Suffix) \
|
|
417
412
|
([&]() { \
|
|
418
413
|
auto ret = (func->forward_fp ? ForwardCallX ## Suffix(func->func, new_sp, &old_sp) \
|
|
@@ -762,8 +757,13 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
|
|
|
762
757
|
const TypeInfo *type = proto->ret.type;
|
|
763
758
|
|
|
764
759
|
// Make the call
|
|
765
|
-
napi_value ret
|
|
766
|
-
|
|
760
|
+
napi_value ret;
|
|
761
|
+
if (async) {
|
|
762
|
+
ret = (napi_value)func.Call(arguments[0], arguments.len - 1, arguments.data + 1);
|
|
763
|
+
} else {
|
|
764
|
+
ret = CallSwitchStack(&func, (size_t)arguments.len, arguments.data, old_sp, &mem->stack,
|
|
765
|
+
[](Napi::Function *func, size_t argc, napi_value *argv) { return (napi_value)func->Call(argv[0], argc - 1, argv + 1); });
|
|
766
|
+
}
|
|
767
767
|
Napi::Value value(env, ret);
|
|
768
768
|
|
|
769
769
|
if (RG_UNLIKELY(env.IsExceptionPending()))
|
|
@@ -925,11 +925,6 @@ void *GetTrampoline(Size idx, const FunctionInfo *proto)
|
|
|
925
925
|
return Trampolines[idx][fp];
|
|
926
926
|
}
|
|
927
927
|
|
|
928
|
-
extern "C" void RelayCallback(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegisters *out_reg)
|
|
929
|
-
{
|
|
930
|
-
exec_call->Relay(idx, own_sp, caller_sp, out_reg);
|
|
931
|
-
}
|
|
932
|
-
|
|
933
928
|
}
|
|
934
929
|
|
|
935
930
|
#endif
|
|
@@ -138,8 +138,6 @@ static void *const Trampolines[][2] = {
|
|
|
138
138
|
};
|
|
139
139
|
RG_STATIC_ASSERT(RG_LEN(Trampolines) == MaxTrampolines * 2);
|
|
140
140
|
|
|
141
|
-
static RG_THREAD_LOCAL CallData *exec_call;
|
|
142
|
-
|
|
143
141
|
static inline RegisterClass MergeClasses(RegisterClass cls1, RegisterClass cls2)
|
|
144
142
|
{
|
|
145
143
|
if (cls1 == cls2)
|
|
@@ -474,9 +472,6 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
|
|
|
474
472
|
|
|
475
473
|
void CallData::Execute()
|
|
476
474
|
{
|
|
477
|
-
RG_DEFER_C(prev_call = exec_call) { exec_call = prev_call; };
|
|
478
|
-
exec_call = this;
|
|
479
|
-
|
|
480
475
|
#define PERFORM_CALL(Suffix) \
|
|
481
476
|
([&]() { \
|
|
482
477
|
auto ret = (func->forward_fp ? ForwardCallX ## Suffix(func->func, new_sp, &old_sp) \
|
|
@@ -810,8 +805,13 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
|
|
|
810
805
|
const TypeInfo *type = proto->ret.type;
|
|
811
806
|
|
|
812
807
|
// Make the call
|
|
813
|
-
napi_value ret
|
|
814
|
-
|
|
808
|
+
napi_value ret;
|
|
809
|
+
if (async) {
|
|
810
|
+
ret = (napi_value)func.Call(arguments[0], arguments.len - 1, arguments.data + 1);
|
|
811
|
+
} else {
|
|
812
|
+
ret = CallSwitchStack(&func, (size_t)arguments.len, arguments.data, old_sp, &mem->stack,
|
|
813
|
+
[](Napi::Function *func, size_t argc, napi_value *argv) { return (napi_value)func->Call(argv[0], argc - 1, argv + 1); });
|
|
814
|
+
}
|
|
815
815
|
Napi::Value value(env, ret);
|
|
816
816
|
|
|
817
817
|
if (RG_UNLIKELY(env.IsExceptionPending()))
|
|
@@ -990,11 +990,6 @@ void *GetTrampoline(Size idx, const FunctionInfo *proto)
|
|
|
990
990
|
return Trampolines[idx][xmm];
|
|
991
991
|
}
|
|
992
992
|
|
|
993
|
-
extern "C" void RelayCallback(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegisters *out_reg)
|
|
994
|
-
{
|
|
995
|
-
exec_call->Relay(idx, own_sp, caller_sp, out_reg);
|
|
996
|
-
}
|
|
997
|
-
|
|
998
993
|
}
|
|
999
994
|
|
|
1000
995
|
#endif
|
|
@@ -107,8 +107,6 @@ static void *const Trampolines[][2] = {
|
|
|
107
107
|
};
|
|
108
108
|
RG_STATIC_ASSERT(RG_LEN(Trampolines) == MaxTrampolines * 2);
|
|
109
109
|
|
|
110
|
-
static RG_THREAD_LOCAL CallData *exec_call;
|
|
111
|
-
|
|
112
110
|
bool AnalyseFunction(Napi::Env, InstanceData *, FunctionInfo *func)
|
|
113
111
|
{
|
|
114
112
|
func->ret.regular = IsRegularSize(func->ret.type->size, 8);
|
|
@@ -285,9 +283,6 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
|
|
|
285
283
|
|
|
286
284
|
void CallData::Execute()
|
|
287
285
|
{
|
|
288
|
-
RG_DEFER_C(prev_call = exec_call) { exec_call = prev_call; };
|
|
289
|
-
exec_call = this;
|
|
290
|
-
|
|
291
286
|
#define PERFORM_CALL(Suffix) \
|
|
292
287
|
([&]() { \
|
|
293
288
|
auto ret = (func->forward_fp ? ForwardCallX ## Suffix(func->func, new_sp, &old_sp) \
|
|
@@ -603,8 +598,13 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
|
|
|
603
598
|
const TypeInfo *type = proto->ret.type;
|
|
604
599
|
|
|
605
600
|
// Make the call
|
|
606
|
-
napi_value ret
|
|
607
|
-
|
|
601
|
+
napi_value ret;
|
|
602
|
+
if (async) {
|
|
603
|
+
ret = (napi_value)func.Call(arguments[0], arguments.len - 1, arguments.data + 1);
|
|
604
|
+
} else {
|
|
605
|
+
ret = CallSwitchStack(&func, (size_t)arguments.len, arguments.data, old_sp, &mem->stack,
|
|
606
|
+
[](Napi::Function *func, size_t argc, napi_value *argv) { return (napi_value)func->Call(argv[0], argc - 1, argv + 1); });
|
|
607
|
+
}
|
|
608
608
|
Napi::Value value(env, ret);
|
|
609
609
|
|
|
610
610
|
if (RG_UNLIKELY(env.IsExceptionPending()))
|
|
@@ -764,11 +764,6 @@ void *GetTrampoline(Size idx, const FunctionInfo *proto)
|
|
|
764
764
|
return Trampolines[idx][xmm];
|
|
765
765
|
}
|
|
766
766
|
|
|
767
|
-
extern "C" void RelayCallback(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegisters *out_reg)
|
|
768
|
-
{
|
|
769
|
-
exec_call->Relay(idx, own_sp, caller_sp, out_reg);
|
|
770
|
-
}
|
|
771
|
-
|
|
772
767
|
}
|
|
773
768
|
|
|
774
769
|
#endif
|
package/src/koffi/src/abi_x86.cc
CHANGED
|
@@ -113,8 +113,6 @@ static void *const Trampolines[][2] = {
|
|
|
113
113
|
};
|
|
114
114
|
RG_STATIC_ASSERT(RG_LEN(Trampolines) == MaxTrampolines * 2);
|
|
115
115
|
|
|
116
|
-
static RG_THREAD_LOCAL CallData *exec_call;
|
|
117
|
-
|
|
118
116
|
bool AnalyseFunction(Napi::Env env, InstanceData *instance, FunctionInfo *func)
|
|
119
117
|
{
|
|
120
118
|
if (!func->lib && func->convention != CallConvention::Cdecl &&
|
|
@@ -366,9 +364,6 @@ bool CallData::Prepare(const Napi::CallbackInfo &info)
|
|
|
366
364
|
|
|
367
365
|
void CallData::Execute()
|
|
368
366
|
{
|
|
369
|
-
RG_DEFER_C(prev_call = exec_call) { exec_call = prev_call; };
|
|
370
|
-
exec_call = this;
|
|
371
|
-
|
|
372
367
|
#define PERFORM_CALL(Suffix) \
|
|
373
368
|
([&]() { \
|
|
374
369
|
auto ret = (func->fast ? ForwardCallR ## Suffix(func->func, new_sp, &old_sp) \
|
|
@@ -682,8 +677,13 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
|
|
|
682
677
|
const TypeInfo *type = proto->ret.type;
|
|
683
678
|
|
|
684
679
|
// Make the call
|
|
685
|
-
napi_value ret
|
|
686
|
-
|
|
680
|
+
napi_value ret;
|
|
681
|
+
if (async) {
|
|
682
|
+
ret = (napi_value)func.Call(arguments[0], arguments.len - 1, arguments.data + 1);
|
|
683
|
+
} else {
|
|
684
|
+
ret = CallSwitchStack(&func, (size_t)arguments.len, arguments.data, old_sp, &mem->stack,
|
|
685
|
+
[](Napi::Function *func, size_t argc, napi_value *argv) { return (napi_value)func->Call(argv[0], argc - 1, argv + 1); });
|
|
686
|
+
}
|
|
687
687
|
Napi::Value value(env, ret);
|
|
688
688
|
|
|
689
689
|
if (RG_UNLIKELY(env.IsExceptionPending()))
|
|
@@ -867,11 +867,6 @@ void *GetTrampoline(Size idx, const FunctionInfo *proto)
|
|
|
867
867
|
return Trampolines[idx][x87];
|
|
868
868
|
}
|
|
869
869
|
|
|
870
|
-
extern "C" void RelayCallback(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegisters *out_reg)
|
|
871
|
-
{
|
|
872
|
-
exec_call->Relay(idx, own_sp, caller_sp, out_reg);
|
|
873
|
-
}
|
|
874
|
-
|
|
875
870
|
}
|
|
876
871
|
|
|
877
872
|
#endif
|
package/src/koffi/src/call.cc
CHANGED
|
@@ -20,9 +20,23 @@
|
|
|
20
20
|
|
|
21
21
|
namespace RG {
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
struct RelayContext {
|
|
24
|
+
CallData *call;
|
|
25
|
+
|
|
26
|
+
Size idx;
|
|
27
|
+
uint8_t *own_sp;
|
|
28
|
+
uint8_t *caller_sp;
|
|
29
|
+
BackRegisters *out_reg;
|
|
30
|
+
|
|
31
|
+
std::mutex mutex;
|
|
32
|
+
std::condition_variable cv;
|
|
33
|
+
bool done = false;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
CallData::CallData(Napi::Env env, InstanceData *instance,
|
|
37
|
+
const FunctionInfo *func, InstanceMemory *mem, bool async)
|
|
24
38
|
: env(env), instance(instance), func(func),
|
|
25
|
-
mem(mem), old_stack_mem(mem->stack), old_heap_mem(mem->heap)
|
|
39
|
+
mem(mem), old_stack_mem(mem->stack), old_heap_mem(mem->heap), async(async)
|
|
26
40
|
{
|
|
27
41
|
mem->generation += !mem->depth;
|
|
28
42
|
mem->depth++;
|
|
@@ -50,6 +64,41 @@ CallData::~CallData()
|
|
|
50
64
|
instance = nullptr;
|
|
51
65
|
}
|
|
52
66
|
|
|
67
|
+
void CallData::RelaySafe(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegisters *out_reg)
|
|
68
|
+
{
|
|
69
|
+
if (async) {
|
|
70
|
+
RelayContext ctx;
|
|
71
|
+
|
|
72
|
+
ctx.call = this;
|
|
73
|
+
ctx.idx = idx;
|
|
74
|
+
ctx.own_sp = own_sp;
|
|
75
|
+
ctx.caller_sp = caller_sp;
|
|
76
|
+
ctx.out_reg = out_reg;
|
|
77
|
+
|
|
78
|
+
napi_call_threadsafe_function(instance->broker, &ctx, napi_tsfn_blocking);
|
|
79
|
+
|
|
80
|
+
// Wait until it executes
|
|
81
|
+
std::unique_lock<std::mutex> lock(ctx.mutex);
|
|
82
|
+
while (!ctx.done) {
|
|
83
|
+
ctx.cv.wait(lock);
|
|
84
|
+
}
|
|
85
|
+
} else {
|
|
86
|
+
Relay(idx, own_sp, caller_sp, out_reg);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
void CallData::RelayAsync(napi_env, napi_value, void *, void *udata)
|
|
91
|
+
{
|
|
92
|
+
RelayContext *ctx = (RelayContext *)udata;
|
|
93
|
+
|
|
94
|
+
ctx->call->Relay(ctx->idx, ctx->own_sp, ctx->caller_sp, ctx->out_reg);
|
|
95
|
+
|
|
96
|
+
// We're done!
|
|
97
|
+
std::lock_guard<std::mutex> lock(ctx->mutex);
|
|
98
|
+
ctx->done = true;
|
|
99
|
+
ctx->cv.notify_one();
|
|
100
|
+
}
|
|
101
|
+
|
|
53
102
|
bool CallData::PushString(Napi::Value value, int directions, const char **out_str)
|
|
54
103
|
{
|
|
55
104
|
if (value.IsString()) {
|
package/src/koffi/src/call.hh
CHANGED
|
@@ -42,6 +42,8 @@ class alignas(8) CallData {
|
|
|
42
42
|
Span<uint8_t> old_stack_mem;
|
|
43
43
|
Span<uint8_t> old_heap_mem;
|
|
44
44
|
|
|
45
|
+
bool async;
|
|
46
|
+
|
|
45
47
|
int16_t used_trampolines = 0;
|
|
46
48
|
|
|
47
49
|
LocalArray<OutArgument, MaxOutParameters> out_arguments;
|
|
@@ -68,7 +70,8 @@ class alignas(8) CallData {
|
|
|
68
70
|
BlockAllocator call_alloc;
|
|
69
71
|
|
|
70
72
|
public:
|
|
71
|
-
CallData(Napi::Env env, InstanceData *instance,
|
|
73
|
+
CallData(Napi::Env env, InstanceData *instance,
|
|
74
|
+
const FunctionInfo *func, InstanceMemory *mem, bool async);
|
|
72
75
|
~CallData();
|
|
73
76
|
|
|
74
77
|
#ifdef UNITY_BUILD
|
|
@@ -88,6 +91,8 @@ public:
|
|
|
88
91
|
#undef INLINE_IF_UNITY
|
|
89
92
|
|
|
90
93
|
void Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegisters *out_reg);
|
|
94
|
+
void RelaySafe(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegisters *out_reg);
|
|
95
|
+
static void RelayAsync(napi_env, napi_value, void *, void *udata);
|
|
91
96
|
|
|
92
97
|
void DumpForward() const;
|
|
93
98
|
|
package/src/koffi/src/ffi.cc
CHANGED
|
@@ -44,6 +44,8 @@ namespace RG {
|
|
|
44
44
|
const int TypeInfoMarker = 0xDEADBEEF;
|
|
45
45
|
const int CastMarker = 0xDEADBEEF;
|
|
46
46
|
|
|
47
|
+
static RG_THREAD_LOCAL CallData *exec_call;
|
|
48
|
+
|
|
47
49
|
static bool ChangeSize(const char *name, Napi::Value value, Size min_size, Size max_size, Size *out_size)
|
|
48
50
|
{
|
|
49
51
|
Napi::Env env = value.Env();
|
|
@@ -1057,7 +1059,10 @@ static Napi::Value TranslateNormalCall(const Napi::CallbackInfo &info)
|
|
|
1057
1059
|
}
|
|
1058
1060
|
|
|
1059
1061
|
InstanceMemory *mem = instance->memories[0];
|
|
1060
|
-
CallData call(env, instance, func, mem);
|
|
1062
|
+
CallData call(env, instance, func, mem, false);
|
|
1063
|
+
|
|
1064
|
+
RG_DEFER_C(prev_call = exec_call) { exec_call = prev_call; };
|
|
1065
|
+
exec_call = &call;
|
|
1061
1066
|
|
|
1062
1067
|
if (!RG_UNLIKELY(call.Prepare(info)))
|
|
1063
1068
|
return env.Null();
|
|
@@ -1065,7 +1070,14 @@ static Napi::Value TranslateNormalCall(const Napi::CallbackInfo &info)
|
|
|
1065
1070
|
if (instance->debug) {
|
|
1066
1071
|
call.DumpForward();
|
|
1067
1072
|
}
|
|
1068
|
-
|
|
1073
|
+
|
|
1074
|
+
// Execute call
|
|
1075
|
+
{
|
|
1076
|
+
RG_DEFER_C(prev_call = exec_call) { exec_call = prev_call; };
|
|
1077
|
+
exec_call = &call;
|
|
1078
|
+
|
|
1079
|
+
call.Execute();
|
|
1080
|
+
}
|
|
1069
1081
|
|
|
1070
1082
|
return call.Complete();
|
|
1071
1083
|
}
|
|
@@ -1124,7 +1136,7 @@ static Napi::Value TranslateVariadicCall(const Napi::CallbackInfo &info)
|
|
|
1124
1136
|
return env.Null();
|
|
1125
1137
|
|
|
1126
1138
|
InstanceMemory *mem = instance->memories[0];
|
|
1127
|
-
CallData call(env, instance, &func, mem);
|
|
1139
|
+
CallData call(env, instance, &func, mem, false);
|
|
1128
1140
|
|
|
1129
1141
|
if (!RG_UNLIKELY(call.Prepare(info)))
|
|
1130
1142
|
return env.Null();
|
|
@@ -1132,7 +1144,14 @@ static Napi::Value TranslateVariadicCall(const Napi::CallbackInfo &info)
|
|
|
1132
1144
|
if (instance->debug) {
|
|
1133
1145
|
call.DumpForward();
|
|
1134
1146
|
}
|
|
1135
|
-
|
|
1147
|
+
|
|
1148
|
+
// Execute call
|
|
1149
|
+
{
|
|
1150
|
+
RG_DEFER_C(prev_call = exec_call) { exec_call = prev_call; };
|
|
1151
|
+
exec_call = &call;
|
|
1152
|
+
|
|
1153
|
+
call.Execute();
|
|
1154
|
+
}
|
|
1136
1155
|
|
|
1137
1156
|
return call.Complete();
|
|
1138
1157
|
}
|
|
@@ -1148,7 +1167,7 @@ public:
|
|
|
1148
1167
|
AsyncCall(Napi::Env env, InstanceData *instance, const FunctionInfo *func,
|
|
1149
1168
|
InstanceMemory *mem, Napi::Function &callback)
|
|
1150
1169
|
: Napi::AsyncWorker(callback), env(env), func(func->Ref()),
|
|
1151
|
-
call(env, instance, func, mem) {}
|
|
1170
|
+
call(env, instance, func, mem, true) {}
|
|
1152
1171
|
~AsyncCall() { func->Unref(); }
|
|
1153
1172
|
|
|
1154
1173
|
bool Prepare(const Napi::CallbackInfo &info) {
|
|
@@ -1170,6 +1189,9 @@ public:
|
|
|
1170
1189
|
void AsyncCall::Execute()
|
|
1171
1190
|
{
|
|
1172
1191
|
if (prepared) {
|
|
1192
|
+
RG_DEFER_C(prev_call = exec_call) { exec_call = prev_call; };
|
|
1193
|
+
exec_call = &call;
|
|
1194
|
+
|
|
1173
1195
|
call.Execute();
|
|
1174
1196
|
}
|
|
1175
1197
|
}
|
|
@@ -1673,6 +1695,10 @@ InstanceData::~InstanceData()
|
|
|
1673
1695
|
for (InstanceMemory *mem: memories) {
|
|
1674
1696
|
delete mem;
|
|
1675
1697
|
}
|
|
1698
|
+
|
|
1699
|
+
if (broker) {
|
|
1700
|
+
napi_release_threadsafe_function(broker, napi_tsfn_abort);
|
|
1701
|
+
}
|
|
1676
1702
|
}
|
|
1677
1703
|
|
|
1678
1704
|
static Napi::Value CastValue(const Napi::CallbackInfo &info)
|
|
@@ -1828,6 +1854,30 @@ static Napi::Value DecodeValue(const Napi::CallbackInfo &info)
|
|
|
1828
1854
|
return env.Null();
|
|
1829
1855
|
}
|
|
1830
1856
|
|
|
1857
|
+
extern "C" void RelayCallback(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegisters *out_reg)
|
|
1858
|
+
{
|
|
1859
|
+
exec_call->RelaySafe(idx, own_sp, caller_sp, out_reg);
|
|
1860
|
+
}
|
|
1861
|
+
|
|
1862
|
+
static InstanceData *CreateInstance(Napi::Env env)
|
|
1863
|
+
{
|
|
1864
|
+
InstanceData *instance = new InstanceData();
|
|
1865
|
+
RG_DEFER_N(err_guard) { delete instance; };
|
|
1866
|
+
|
|
1867
|
+
Napi::String resource_name = Napi::String::New(env, "Koffi Async Callback Broker");
|
|
1868
|
+
|
|
1869
|
+
if (napi_create_threadsafe_function(env, nullptr, nullptr, resource_name,
|
|
1870
|
+
0, 1, nullptr, nullptr, nullptr,
|
|
1871
|
+
CallData::RelayAsync, &instance->broker) != napi_ok) {
|
|
1872
|
+
LogError("Failed to create async callback broker");
|
|
1873
|
+
return nullptr;
|
|
1874
|
+
}
|
|
1875
|
+
napi_unref_threadsafe_function(env, instance->broker);
|
|
1876
|
+
|
|
1877
|
+
err_guard.Disable();
|
|
1878
|
+
return instance;
|
|
1879
|
+
}
|
|
1880
|
+
|
|
1831
1881
|
template <typename Func>
|
|
1832
1882
|
static void SetExports(Napi::Env env, Func func)
|
|
1833
1883
|
{
|
|
@@ -1906,7 +1956,9 @@ static void InitInternal(v8::Local<v8::Object> target, v8::Local<v8::Value>,
|
|
|
1906
1956
|
delete env_napi;
|
|
1907
1957
|
}, env_napi);
|
|
1908
1958
|
|
|
1909
|
-
InstanceData *instance =
|
|
1959
|
+
InstanceData *instance = CreateInstance(env_cxx);
|
|
1960
|
+
RG_CRITICAL(instance, "Failed to initialize Koffi");
|
|
1961
|
+
|
|
1910
1962
|
env_cxx.SetInstanceData(instance);
|
|
1911
1963
|
|
|
1912
1964
|
instance->debug = GetDebugFlag("DUMP_CALLS");
|
|
@@ -1922,7 +1974,9 @@ static Napi::Object InitModule(Napi::Env env, Napi::Object exports)
|
|
|
1922
1974
|
{
|
|
1923
1975
|
using namespace RG;
|
|
1924
1976
|
|
|
1925
|
-
InstanceData *instance =
|
|
1977
|
+
InstanceData *instance = CreateInstance(env);
|
|
1978
|
+
RG_CRITICAL(instance, "Failed to initialize Koffi");
|
|
1979
|
+
|
|
1926
1980
|
env.SetInstanceData(instance);
|
|
1927
1981
|
|
|
1928
1982
|
instance->debug = GetDebugFlag("DUMP_CALLS");
|
package/src/koffi/src/ffi.hh
CHANGED
package/src/koffi/src/index.js
CHANGED
|
@@ -18,6 +18,11 @@
|
|
|
18
18
|
const util = require('util');
|
|
19
19
|
|
|
20
20
|
let filename = __dirname + '/../build/koffi.node';
|
|
21
|
-
|
|
21
|
+
let native = require(filename);
|
|
22
22
|
|
|
23
|
-
module.exports
|
|
23
|
+
module.exports = {
|
|
24
|
+
...native,
|
|
25
|
+
|
|
26
|
+
// Deprecated functions
|
|
27
|
+
handle: util.deprecate(native.opaque, 'The koffi.handle() function was deprecated in Koffi 2.1, use koffi.opaque() instead', 'KOFFI001')
|
|
28
|
+
};
|