koffi 2.2.3-beta.3 → 2.2.3
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 +10 -0
- package/package.json +2 -2
- package/src/koffi/build/2.2.3/koffi_darwin_arm64.tar.gz +0 -0
- package/src/koffi/build/2.2.3/koffi_darwin_x64.tar.gz +0 -0
- package/src/koffi/build/2.2.3/koffi_freebsd_arm64.tar.gz +0 -0
- package/src/koffi/build/2.2.3/koffi_freebsd_ia32.tar.gz +0 -0
- package/src/koffi/build/2.2.3/koffi_freebsd_x64.tar.gz +0 -0
- package/src/koffi/build/2.2.3/koffi_linux_arm32hf.tar.gz +0 -0
- package/src/koffi/build/2.2.3/koffi_linux_arm64.tar.gz +0 -0
- package/src/koffi/build/2.2.3/koffi_linux_ia32.tar.gz +0 -0
- package/src/koffi/build/2.2.3/koffi_linux_riscv64hf64.tar.gz +0 -0
- package/src/koffi/build/2.2.3/koffi_linux_x64.tar.gz +0 -0
- package/src/koffi/build/2.2.3/koffi_openbsd_ia32.tar.gz +0 -0
- package/src/koffi/build/2.2.3/koffi_openbsd_x64.tar.gz +0 -0
- package/src/koffi/build/2.2.3/koffi_win32_arm64.tar.gz +0 -0
- package/src/koffi/build/2.2.3/koffi_win32_ia32.tar.gz +0 -0
- package/src/koffi/build/2.2.3/koffi_win32_x64.tar.gz +0 -0
- package/src/koffi/src/abi_arm64.cc +39 -0
- package/src/koffi/src/abi_x64_sysv_fwd.S +9 -9
- package/src/koffi/src/abi_x64_win_fwd.asm +12 -12
- package/src/koffi/src/abi_x86_fwd.S +13 -13
- package/src/koffi/src/abi_x86_fwd.asm +11 -11
- package/src/koffi/src/ffi.cc +27 -50
- package/src/koffi/test/CMakeLists.txt +7 -0
- package/src/koffi/test/win32.c +39 -0
- package/src/koffi/test/win32.js +70 -0
- package/src/koffi/tools/qemu.js +20 -9
- package/src/koffi/tools/registry/machines.json +10 -2
- package/src/koffi/build/2.2.3-beta.3/koffi_darwin_arm64.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.3/koffi_darwin_x64.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.3/koffi_freebsd_arm64.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.3/koffi_freebsd_ia32.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.3/koffi_freebsd_x64.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.3/koffi_linux_arm32hf.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.3/koffi_linux_arm64.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.3/koffi_linux_ia32.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.3/koffi_linux_riscv64hf64.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.3/koffi_linux_x64.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.3/koffi_openbsd_ia32.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.3/koffi_openbsd_x64.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.3/koffi_win32_arm64.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.3/koffi_win32_ia32.tar.gz +0 -0
- package/src/koffi/build/2.2.3-beta.3/koffi_win32_x64.tar.gz +0 -0
package/ChangeLog.md
CHANGED
|
@@ -2,6 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
## History
|
|
4
4
|
|
|
5
|
+
### Koffi 2.2.3
|
|
6
|
+
|
|
7
|
+
**Main fixes:**
|
|
8
|
+
|
|
9
|
+
- Support native code that uses [Structured Exception Handling (SEH)](https://learn.microsoft.com/en-us/cpp/cpp/structured-exception-handling-c-cpp) on Windows (x86, x64 and ARM64)
|
|
10
|
+
|
|
11
|
+
**Other changes:**
|
|
12
|
+
|
|
13
|
+
- Try to use ebp/rbp as frame pointer in x86/x64 ASM code
|
|
14
|
+
|
|
5
15
|
### Koffi 2.2.2
|
|
6
16
|
|
|
7
17
|
**Main fixes:**
|
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
|
|
@@ -17,6 +17,9 @@
|
|
|
17
17
|
#include "ffi.hh"
|
|
18
18
|
#include "call.hh"
|
|
19
19
|
#include "util.hh"
|
|
20
|
+
#ifdef _WIN32
|
|
21
|
+
#include "win32.hh"
|
|
22
|
+
#endif
|
|
20
23
|
|
|
21
24
|
#include <napi.h>
|
|
22
25
|
|
|
@@ -494,6 +497,24 @@ bool CallData::Prepare(const FunctionInfo *func, const Napi::CallbackInfo &info)
|
|
|
494
497
|
|
|
495
498
|
void CallData::Execute(const FunctionInfo *func)
|
|
496
499
|
{
|
|
500
|
+
#ifdef _WIN32
|
|
501
|
+
TEB *teb = GetTEB();
|
|
502
|
+
|
|
503
|
+
// Restore previous stack limits at the end
|
|
504
|
+
RG_DEFER_C(base = teb->StackBase,
|
|
505
|
+
limit = teb->StackLimit,
|
|
506
|
+
dealloc = teb->DeallocationStack) {
|
|
507
|
+
teb->StackBase = base;
|
|
508
|
+
teb->StackLimit = limit;
|
|
509
|
+
teb->DeallocationStack = dealloc;
|
|
510
|
+
};
|
|
511
|
+
|
|
512
|
+
// Adjust stack limits so SEH works correctly
|
|
513
|
+
teb->StackBase = mem->stack0.end();
|
|
514
|
+
teb->StackLimit = mem->stack0.ptr;
|
|
515
|
+
teb->DeallocationStack = mem->stack0.ptr;
|
|
516
|
+
#endif
|
|
517
|
+
|
|
497
518
|
#define PERFORM_CALL(Suffix) \
|
|
498
519
|
([&]() { \
|
|
499
520
|
auto ret = (func->forward_fp ? ForwardCallX ## Suffix(func->func, new_sp, &old_sp) \
|
|
@@ -611,6 +632,24 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, bool async,
|
|
|
611
632
|
if (RG_UNLIKELY(env.IsExceptionPending()))
|
|
612
633
|
return;
|
|
613
634
|
|
|
635
|
+
#ifdef _WIN32
|
|
636
|
+
TEB *teb = GetTEB();
|
|
637
|
+
|
|
638
|
+
// Restore previous stack limits at the end
|
|
639
|
+
RG_DEFER_C(base = teb->StackBase,
|
|
640
|
+
limit = teb->StackLimit,
|
|
641
|
+
dealloc = teb->DeallocationStack) {
|
|
642
|
+
teb->StackBase = base;
|
|
643
|
+
teb->StackLimit = limit;
|
|
644
|
+
teb->DeallocationStack = dealloc;
|
|
645
|
+
};
|
|
646
|
+
|
|
647
|
+
// Adjust stack limits so SEH works correctly
|
|
648
|
+
teb->StackBase = instance->main_stack_max;
|
|
649
|
+
teb->StackLimit = instance->main_stack_min;
|
|
650
|
+
teb->DeallocationStack = instance->main_stack_min;
|
|
651
|
+
#endif
|
|
652
|
+
|
|
614
653
|
const TrampolineInfo &trampoline = shared.trampolines[idx];
|
|
615
654
|
|
|
616
655
|
const FunctionInfo *proto = trampoline.proto;
|
|
@@ -45,11 +45,11 @@
|
|
|
45
45
|
.cfi_def_cfa rsp, 8
|
|
46
46
|
ENDBR64
|
|
47
47
|
movq %rdi, %r11
|
|
48
|
-
pushq %
|
|
48
|
+
pushq %rbp
|
|
49
49
|
.cfi_def_cfa rsp, 16
|
|
50
50
|
movq %rsp, (%rdx)
|
|
51
|
-
movq %rsp, %
|
|
52
|
-
.cfi_def_cfa
|
|
51
|
+
movq %rsp, %rbp
|
|
52
|
+
.cfi_def_cfa rbp, 16
|
|
53
53
|
leaq 112(%rsi), %rsp
|
|
54
54
|
.endm
|
|
55
55
|
|
|
@@ -58,8 +58,8 @@
|
|
|
58
58
|
# The return value is passed untouched through RAX or XMM0.
|
|
59
59
|
.macro epilogue
|
|
60
60
|
call *%r11
|
|
61
|
-
movq %
|
|
62
|
-
popq %
|
|
61
|
+
movq %rbp, %rsp
|
|
62
|
+
popq %rbp
|
|
63
63
|
.cfi_def_cfa rsp, 8
|
|
64
64
|
ret
|
|
65
65
|
.cfi_endproc
|
|
@@ -241,9 +241,9 @@ SYMBOL(CallSwitchStack):
|
|
|
241
241
|
.cfi_startproc
|
|
242
242
|
.cfi_def_cfa rsp, 8
|
|
243
243
|
ENDBR64
|
|
244
|
-
push %
|
|
244
|
+
push %rbp
|
|
245
245
|
.cfi_def_cfa rsp, 16
|
|
246
|
-
movq %rsp, %
|
|
246
|
+
movq %rsp, %rbp
|
|
247
247
|
movq %rsp, %r10
|
|
248
248
|
subq 0(%r8), %r10
|
|
249
249
|
andq $-16, %r10
|
|
@@ -251,9 +251,9 @@ SYMBOL(CallSwitchStack):
|
|
|
251
251
|
movq %rcx, %rsp
|
|
252
252
|
.cfi_def_cfa rsp, 16
|
|
253
253
|
call *%r9
|
|
254
|
-
mov %
|
|
254
|
+
mov %rbp, %rsp
|
|
255
255
|
.cfi_def_cfa rsp, 16
|
|
256
|
-
pop %
|
|
256
|
+
pop %rbp
|
|
257
257
|
.cfi_def_cfa rsp, 8
|
|
258
258
|
ret
|
|
259
259
|
.cfi_endproc
|
|
@@ -33,11 +33,11 @@ public ForwardCallXD
|
|
|
33
33
|
prologue macro
|
|
34
34
|
endbr64
|
|
35
35
|
mov rax, rcx
|
|
36
|
-
push
|
|
37
|
-
.pushreg
|
|
38
|
-
mov
|
|
36
|
+
push rbp
|
|
37
|
+
.pushreg rbp
|
|
38
|
+
mov rbp, rsp
|
|
39
39
|
mov qword ptr [r8+0], rsp
|
|
40
|
-
.setframe
|
|
40
|
+
.setframe rbp, 0
|
|
41
41
|
.endprolog
|
|
42
42
|
mov rsp, rdx
|
|
43
43
|
endm
|
|
@@ -47,8 +47,8 @@ endm
|
|
|
47
47
|
; The return value is passed untouched through RAX or XMM0.
|
|
48
48
|
epilogue macro
|
|
49
49
|
call rax
|
|
50
|
-
mov rsp,
|
|
51
|
-
pop
|
|
50
|
+
mov rsp, rbp
|
|
51
|
+
pop rbp
|
|
52
52
|
ret
|
|
53
53
|
endm
|
|
54
54
|
|
|
@@ -169,10 +169,10 @@ endm
|
|
|
169
169
|
; The first three parameters (rcx, rdx, r8) are passed through untouched.
|
|
170
170
|
CallSwitchStack proc frame
|
|
171
171
|
endbr64
|
|
172
|
-
push
|
|
173
|
-
.pushreg
|
|
174
|
-
mov
|
|
175
|
-
.setframe
|
|
172
|
+
push rbp
|
|
173
|
+
.pushreg rbp
|
|
174
|
+
mov rbp, rsp
|
|
175
|
+
.setframe rbp, 0
|
|
176
176
|
.endprolog
|
|
177
177
|
mov rax, qword ptr [rsp+56]
|
|
178
178
|
mov r10, rsp
|
|
@@ -182,8 +182,8 @@ CallSwitchStack proc frame
|
|
|
182
182
|
mov qword ptr [r11+8], r10
|
|
183
183
|
lea rsp, [r9-32]
|
|
184
184
|
call rax
|
|
185
|
-
mov rsp,
|
|
186
|
-
pop
|
|
185
|
+
mov rsp, rbp
|
|
186
|
+
pop rbp
|
|
187
187
|
ret
|
|
188
188
|
CallSwitchStack endp
|
|
189
189
|
|
|
@@ -27,10 +27,10 @@
|
|
|
27
27
|
.cfi_startproc
|
|
28
28
|
.cfi_def_cfa esp, 4
|
|
29
29
|
ENDBR32
|
|
30
|
-
push %
|
|
30
|
+
push %ebp
|
|
31
31
|
.cfi_def_cfa esp, 8
|
|
32
|
-
movl %esp, %
|
|
33
|
-
.cfi_def_cfa
|
|
32
|
+
movl %esp, %ebp
|
|
33
|
+
.cfi_def_cfa ebp, 8
|
|
34
34
|
movl 16(%esp), %eax
|
|
35
35
|
movl %esp, 0(%eax)
|
|
36
36
|
movl 8(%esp), %eax
|
|
@@ -48,8 +48,8 @@
|
|
|
48
48
|
# The return value is passed back untouched.
|
|
49
49
|
.macro epilogue
|
|
50
50
|
call *%eax
|
|
51
|
-
movl %
|
|
52
|
-
pop %
|
|
51
|
+
movl %ebp, %esp
|
|
52
|
+
pop %ebp
|
|
53
53
|
.cfi_def_cfa esp, 4
|
|
54
54
|
ret
|
|
55
55
|
.cfi_endproc
|
|
@@ -168,10 +168,10 @@ CallSwitchStack:
|
|
|
168
168
|
.cfi_startproc
|
|
169
169
|
.cfi_def_cfa esp, 4
|
|
170
170
|
ENDBR32
|
|
171
|
-
push %
|
|
171
|
+
push %ebp
|
|
172
172
|
.cfi_def_cfa esp, 8
|
|
173
|
-
movl %esp, %
|
|
174
|
-
.cfi_def_cfa
|
|
173
|
+
movl %esp, %ebp
|
|
174
|
+
.cfi_def_cfa ebp, 8
|
|
175
175
|
movl 28(%esp), %edx
|
|
176
176
|
movl 24(%esp), %ecx
|
|
177
177
|
movl %esp, %eax
|
|
@@ -180,16 +180,16 @@ CallSwitchStack:
|
|
|
180
180
|
movl %eax, 4(%ecx)
|
|
181
181
|
movl 20(%esp), %esp
|
|
182
182
|
subl $28, %esp
|
|
183
|
-
movl 8(%
|
|
183
|
+
movl 8(%ebp), %eax
|
|
184
184
|
movl %eax, 0(%esp)
|
|
185
|
-
movl 12(%
|
|
185
|
+
movl 12(%ebp), %eax
|
|
186
186
|
movl %eax, 4(%esp)
|
|
187
|
-
movl 16(%
|
|
187
|
+
movl 16(%ebp), %eax
|
|
188
188
|
movl %eax, 8(%esp)
|
|
189
189
|
call *%edx
|
|
190
|
-
mov %
|
|
190
|
+
mov %ebp, %esp
|
|
191
191
|
.cfi_def_cfa esp, 8
|
|
192
|
-
pop %
|
|
192
|
+
pop %ebp
|
|
193
193
|
.cfi_def_cfa esp, 4
|
|
194
194
|
ret
|
|
195
195
|
.cfi_endproc
|
|
@@ -29,8 +29,8 @@ public ForwardCallRD
|
|
|
29
29
|
; Save ESP in EBX (non-volatile), and use carefully assembled stack provided by caller.
|
|
30
30
|
prologue macro
|
|
31
31
|
endbr32
|
|
32
|
-
push
|
|
33
|
-
mov
|
|
32
|
+
push ebp
|
|
33
|
+
mov ebp, esp
|
|
34
34
|
mov eax, dword ptr [esp+16]
|
|
35
35
|
mov dword ptr [eax+0], esp
|
|
36
36
|
mov eax, dword ptr [esp+8]
|
|
@@ -48,8 +48,8 @@ endm
|
|
|
48
48
|
; The return value is passed back untouched.
|
|
49
49
|
epilogue macro
|
|
50
50
|
call eax
|
|
51
|
-
mov esp,
|
|
52
|
-
pop
|
|
51
|
+
mov esp, ebp
|
|
52
|
+
pop ebp
|
|
53
53
|
ret
|
|
54
54
|
endm
|
|
55
55
|
|
|
@@ -153,8 +153,8 @@ endm
|
|
|
153
153
|
; stack pointer, call Node.js/V8 and go back to ours.
|
|
154
154
|
CallSwitchStack proc
|
|
155
155
|
endbr32
|
|
156
|
-
push
|
|
157
|
-
mov
|
|
156
|
+
push ebp
|
|
157
|
+
mov ebp, esp
|
|
158
158
|
mov edx, dword ptr [esp+28]
|
|
159
159
|
mov ecx, dword ptr [esp+24]
|
|
160
160
|
mov eax, esp
|
|
@@ -163,15 +163,15 @@ CallSwitchStack proc
|
|
|
163
163
|
mov dword ptr [ecx+4], eax
|
|
164
164
|
mov esp, dword ptr [esp+20]
|
|
165
165
|
sub esp, 28
|
|
166
|
-
mov eax, dword ptr [
|
|
166
|
+
mov eax, dword ptr [ebp+8]
|
|
167
167
|
mov dword ptr [esp+0], eax
|
|
168
|
-
mov eax, dword ptr [
|
|
168
|
+
mov eax, dword ptr [ebp+12]
|
|
169
169
|
mov dword ptr [esp+4], eax
|
|
170
|
-
mov eax, dword ptr [
|
|
170
|
+
mov eax, dword ptr [ebp+16]
|
|
171
171
|
mov dword ptr [esp+8], eax
|
|
172
172
|
call edx
|
|
173
|
-
mov esp,
|
|
174
|
-
pop
|
|
173
|
+
mov esp, ebp
|
|
174
|
+
pop ebp
|
|
175
175
|
ret
|
|
176
176
|
CallSwitchStack endp
|
|
177
177
|
|
package/src/koffi/src/ffi.cc
CHANGED
|
@@ -33,6 +33,9 @@
|
|
|
33
33
|
#include <dlfcn.h>
|
|
34
34
|
#include <unistd.h>
|
|
35
35
|
#include <sys/mman.h>
|
|
36
|
+
#ifndef MAP_STACK
|
|
37
|
+
#define MAP_STACK 0
|
|
38
|
+
#endif
|
|
36
39
|
#endif
|
|
37
40
|
|
|
38
41
|
#include <napi.h>
|
|
@@ -1019,60 +1022,39 @@ static InstanceMemory *AllocateMemory(InstanceData *instance, Size stack_size, S
|
|
|
1019
1022
|
InstanceMemory *mem = new InstanceMemory();
|
|
1020
1023
|
RG_DEFER_N(mem_guard) { delete mem; };
|
|
1021
1024
|
|
|
1025
|
+
stack_size = AlignLen(stack_size, Kibibytes(64));
|
|
1026
|
+
|
|
1022
1027
|
#if defined(_WIN32)
|
|
1023
|
-
{
|
|
1024
|
-
|
|
1025
|
-
InstanceMemory *mem;
|
|
1026
|
-
void *self;
|
|
1027
|
-
bool was_fiber;
|
|
1028
|
-
};
|
|
1028
|
+
static const int PageSize = ([]() {
|
|
1029
|
+
SYSTEM_INFO info = {};
|
|
1029
1030
|
|
|
1030
|
-
|
|
1031
|
-
|
|
1031
|
+
GetNativeSystemInfo(&info);
|
|
1032
|
+
RG_ASSERT(info.dwPageSize);
|
|
1032
1033
|
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
if (!ctx.self) {
|
|
1036
|
-
LogError("Failed to make initial fiber: %1", GetWin32ErrorString());
|
|
1037
|
-
return nullptr;
|
|
1038
|
-
}
|
|
1039
|
-
RG_DEFER {
|
|
1040
|
-
if (!is_fiber) {
|
|
1041
|
-
ConvertFiberToThread();
|
|
1042
|
-
}
|
|
1043
|
-
};
|
|
1034
|
+
return (int)info.dwPageSize;
|
|
1035
|
+
})();
|
|
1044
1036
|
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
mem->
|
|
1048
|
-
|
|
1049
|
-
FiberContext *ctx = (FiberContext *)udata;
|
|
1050
|
-
|
|
1051
|
-
TEB *teb = GetTEB();
|
|
1037
|
+
// Allocate stack memory
|
|
1038
|
+
{
|
|
1039
|
+
mem->stack.len = stack_size;
|
|
1040
|
+
mem->stack.ptr = (uint8_t *)VirtualAlloc(nullptr, mem->stack.len + 2 * PageSize, MEM_RESERVE, PAGE_NOACCESS);
|
|
1052
1041
|
|
|
1053
|
-
|
|
1054
|
-
ctx->mem->stack.len = (uint8_t *)teb->StackBase - ctx->mem->stack.ptr;
|
|
1042
|
+
RG_CRITICAL(mem->stack.ptr, "Failed to allocate %1 of memory", mem->stack.len);
|
|
1055
1043
|
|
|
1056
|
-
|
|
1057
|
-
}, &ctx);
|
|
1044
|
+
bool success = true;
|
|
1058
1045
|
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
}
|
|
1046
|
+
success &= !!VirtualAlloc(mem->stack.ptr + 0 * PageSize, PageSize, MEM_COMMIT, PAGE_NOACCESS);
|
|
1047
|
+
success &= !!VirtualAlloc(mem->stack.ptr + 1 * PageSize, PageSize, MEM_COMMIT, PAGE_READWRITE | PAGE_GUARD);
|
|
1048
|
+
success &= !!VirtualAlloc(mem->stack.ptr + 2 * PageSize, mem->stack.len, MEM_COMMIT, PAGE_READWRITE);
|
|
1063
1049
|
|
|
1064
|
-
|
|
1050
|
+
RG_CRITICAL(success, "Cannot commit stack memory: %1", GetWin32ErrorString());
|
|
1065
1051
|
}
|
|
1066
|
-
|
|
1067
|
-
RG_ASSERT(mem->stack.ptr);
|
|
1068
|
-
#elif defined(__APPLE__)
|
|
1069
|
-
mem->stack.len = stack_size;
|
|
1070
|
-
mem->stack.ptr = (uint8_t *)mmap(nullptr, mem->stack.len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
|
|
1071
1052
|
#else
|
|
1072
1053
|
mem->stack.len = stack_size;
|
|
1073
1054
|
mem->stack.ptr = (uint8_t *)mmap(nullptr, mem->stack.len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON | MAP_STACK, -1, 0);
|
|
1074
|
-
|
|
1055
|
+
|
|
1075
1056
|
RG_CRITICAL(mem->stack.ptr, "Failed to allocate %1 of memory", mem->stack.len);
|
|
1057
|
+
#endif
|
|
1076
1058
|
|
|
1077
1059
|
#ifdef __OpenBSD__
|
|
1078
1060
|
// Make sure the SP points inside the MAP_STACK area, or (void) functions may crash on OpenBSD i386
|
|
@@ -1773,16 +1755,11 @@ static InstanceData *CreateInstance(Napi::Env env)
|
|
|
1773
1755
|
}
|
|
1774
1756
|
napi_unref_threadsafe_function(env, instance->broker);
|
|
1775
1757
|
|
|
1776
|
-
#
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
instance->main_stack_max = *(void **)((uint8_t *)teb + 0x08); // StackBase
|
|
1780
|
-
instance->main_stack_min = *(void **)((uint8_t *)teb + 0x1478); // DeallocationStack
|
|
1781
|
-
#elif defined(_WIN32) && (defined(__i386__) || defined(_M_IX86))
|
|
1782
|
-
void *teb = (void *)__readfsdword(0x18);
|
|
1758
|
+
#ifdef _WIN32
|
|
1759
|
+
TEB *teb = GetTEB();
|
|
1783
1760
|
|
|
1784
|
-
instance->main_stack_max =
|
|
1785
|
-
instance->main_stack_min =
|
|
1761
|
+
instance->main_stack_max = teb->StackBase;
|
|
1762
|
+
instance->main_stack_min = teb->DeallocationStack;
|
|
1786
1763
|
#endif
|
|
1787
1764
|
|
|
1788
1765
|
err_guard.Disable();
|
|
@@ -116,3 +116,10 @@ if(MSVC)
|
|
|
116
116
|
target_compile_options(misc PRIVATE /wd4116)
|
|
117
117
|
target_link_options(misc PRIVATE "/DEF:${CMAKE_CURRENT_SOURCE_DIR}/misc.def")
|
|
118
118
|
endif()
|
|
119
|
+
|
|
120
|
+
# ---- Win32 ----
|
|
121
|
+
|
|
122
|
+
if(WIN32)
|
|
123
|
+
add_library(win32 SHARED win32.c)
|
|
124
|
+
set_target_properties(win32 PROPERTIES PREFIX "")
|
|
125
|
+
endif()
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// This program is free software: you can redistribute it and/or modify
|
|
2
|
+
// it under the terms of the GNU Affero General Public License as published by
|
|
3
|
+
// the Free Software Foundation, either version 3 of the License, or
|
|
4
|
+
// (at your option) any later version.
|
|
5
|
+
//
|
|
6
|
+
// This program is distributed in the hope that it will be useful,
|
|
7
|
+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
8
|
+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
9
|
+
// GNU Affero General Public License for more details.
|
|
10
|
+
//
|
|
11
|
+
// You should have received a copy of the GNU Affero General Public License
|
|
12
|
+
// along with this program. If not, see https://www.gnu.org/licenses/.
|
|
13
|
+
|
|
14
|
+
#include <stdlib.h>
|
|
15
|
+
#include <stdio.h>
|
|
16
|
+
#include <inttypes.h>
|
|
17
|
+
#include <string.h>
|
|
18
|
+
#include <stdarg.h>
|
|
19
|
+
|
|
20
|
+
#define NOMINMAX
|
|
21
|
+
#define WIN32_LEAN_AND_MEAN
|
|
22
|
+
#include <windows.h>
|
|
23
|
+
|
|
24
|
+
#define EXPORT __declspec(dllexport)
|
|
25
|
+
|
|
26
|
+
EXPORT int DivideBySafe(int a, int b)
|
|
27
|
+
{
|
|
28
|
+
__try {
|
|
29
|
+
return a / b;
|
|
30
|
+
} __except (GetExceptionCode() == EXCEPTION_INT_DIVIDE_BY_ZERO) {
|
|
31
|
+
return -42;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
EXPORT int CallThrough(int (*func)(void))
|
|
36
|
+
{
|
|
37
|
+
int ret = func();
|
|
38
|
+
return ret;
|
|
39
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// This program is free software: you can redistribute it and/or modify
|
|
4
|
+
// it under the terms of the GNU Affero General Public License as published by
|
|
5
|
+
// the Free Software Foundation, either version 3 of the License, or
|
|
6
|
+
// (at your option) any later version.
|
|
7
|
+
//
|
|
8
|
+
// This program is distributed in the hope that it will be useful,
|
|
9
|
+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
10
|
+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
11
|
+
// GNU Affero General Public License for more details.
|
|
12
|
+
//
|
|
13
|
+
// You should have received a copy of the GNU Affero General Public License
|
|
14
|
+
// along with this program. If not, see https://www.gnu.org/licenses/.
|
|
15
|
+
|
|
16
|
+
const koffi = require('./build/koffi.node');
|
|
17
|
+
const assert = require('assert');
|
|
18
|
+
const util = require('util');
|
|
19
|
+
|
|
20
|
+
const CallThroughFunc = koffi.callback('int CallThroughFunc()');
|
|
21
|
+
|
|
22
|
+
main();
|
|
23
|
+
|
|
24
|
+
async function main() {
|
|
25
|
+
try {
|
|
26
|
+
await test();
|
|
27
|
+
console.log('Success!');
|
|
28
|
+
} catch (err) {
|
|
29
|
+
console.error(err);
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async function test() {
|
|
35
|
+
let lib_filename = __dirname + '/build/win32.dll';
|
|
36
|
+
let lib = koffi.load(lib_filename);
|
|
37
|
+
|
|
38
|
+
const DivideBySafe = lib.func('int DivideBySafe(int a, int b)');
|
|
39
|
+
const CallThrough = lib.func('int CallThrough(CallThroughFunc *func)');
|
|
40
|
+
|
|
41
|
+
// Sync SEH support
|
|
42
|
+
assert.equal(DivideBySafe(12, 3), 4);
|
|
43
|
+
assert.equal(DivideBySafe(84, 0), -42);
|
|
44
|
+
|
|
45
|
+
// Async SEH support
|
|
46
|
+
{
|
|
47
|
+
let results = await Promise.all([
|
|
48
|
+
util.promisify(DivideBySafe.async)(90, -9),
|
|
49
|
+
util.promisify(DivideBySafe.async)(227, 0)
|
|
50
|
+
]);
|
|
51
|
+
|
|
52
|
+
assert.equal(results[0], -10);
|
|
53
|
+
assert.equal(results[1], -42);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Test SEH inside callback
|
|
57
|
+
assert.equal(CallThrough(() => DivideBySafe(16, 2)), 8);
|
|
58
|
+
assert.equal(CallThrough(() => DivideBySafe(16 * 2, 0)), -42);
|
|
59
|
+
|
|
60
|
+
// Test SEH inside callback running async
|
|
61
|
+
{
|
|
62
|
+
let results = await Promise.all([
|
|
63
|
+
util.promisify(CallThrough.async)(() => DivideBySafe(75, -5)),
|
|
64
|
+
util.promisify(CallThrough.async)(() => DivideBySafe(7, 5 - 5))
|
|
65
|
+
]);
|
|
66
|
+
|
|
67
|
+
assert.equal(results[0], -15);
|
|
68
|
+
assert.equal(results[1], -42);
|
|
69
|
+
}
|
|
70
|
+
}
|
package/src/koffi/tools/qemu.js
CHANGED
|
@@ -571,7 +571,7 @@ async function upload(snapshot_dir, func) {
|
|
|
571
571
|
}
|
|
572
572
|
|
|
573
573
|
let status = copied ? chalk.bold.green('[ok]') : chalk.bold.red('[error]');
|
|
574
|
-
log(machine, '
|
|
574
|
+
log(machine, 'Upload', status);
|
|
575
575
|
}));
|
|
576
576
|
|
|
577
577
|
return success;
|
|
@@ -605,7 +605,7 @@ async function test() {
|
|
|
605
605
|
let ret = await exec_remote(machine, cmd, cwd);
|
|
606
606
|
let time = Number((process.hrtime.bigint() - start) / 1000000n);
|
|
607
607
|
|
|
608
|
-
if (ret.code
|
|
608
|
+
if (ret.code === 0) {
|
|
609
609
|
log(machine, `${suite} > ${name}`, chalk.bold.green(`[${(time / 1000).toFixed(2)}s]`));
|
|
610
610
|
} else {
|
|
611
611
|
log(machine, `${suite} > ${name}`, chalk.bold.red('[error]'));
|
|
@@ -654,8 +654,6 @@ async function stop(all = true) {
|
|
|
654
654
|
|
|
655
655
|
console.log('>> Sending shutdown commands...');
|
|
656
656
|
await Promise.all(machines.map(async machine => {
|
|
657
|
-
if (ignore.has(machine))
|
|
658
|
-
return;
|
|
659
657
|
if (machine.qemu == null)
|
|
660
658
|
return;
|
|
661
659
|
if (!machine.started && !all)
|
|
@@ -916,19 +914,32 @@ function log(machine, action, status) {
|
|
|
916
914
|
}
|
|
917
915
|
|
|
918
916
|
async function exec_remote(machine, cmd, cwd = null) {
|
|
917
|
+
if (typeof cmd == 'string') {
|
|
918
|
+
cmd = {
|
|
919
|
+
command: cmd,
|
|
920
|
+
repeat: 1
|
|
921
|
+
};
|
|
922
|
+
}
|
|
923
|
+
|
|
919
924
|
try {
|
|
925
|
+
let ret = { code: 0 };
|
|
926
|
+
|
|
920
927
|
if (machine.platform == 'win32') {
|
|
928
|
+
let cmd_line = cmd.command;
|
|
929
|
+
|
|
921
930
|
if (cwd != null) {
|
|
922
931
|
cwd = cwd.replaceAll('/', '\\');
|
|
923
|
-
|
|
932
|
+
cmd_line = `cd "${cwd}" && ${cmd_line}`;
|
|
924
933
|
}
|
|
925
934
|
|
|
926
|
-
let
|
|
927
|
-
|
|
935
|
+
for (let i = 0; ret.code === 0 && i < cmd.repeat; i++)
|
|
936
|
+
ret = await machine.ssh.execCommand(cmd_line);
|
|
928
937
|
} else {
|
|
929
|
-
let
|
|
930
|
-
|
|
938
|
+
for (let i = 0; ret.code === 0 && i < cmd.repeat; i++)
|
|
939
|
+
ret = await machine.ssh.execCommand(cmd.command, { cwd: cwd });
|
|
931
940
|
}
|
|
941
|
+
|
|
942
|
+
return ret;
|
|
932
943
|
} catch (err) {
|
|
933
944
|
console.log(err);
|
|
934
945
|
return err;
|
|
@@ -230,7 +230,11 @@
|
|
|
230
230
|
"Test Async": "C:\\Node32\\node32.cmd node test/async.js",
|
|
231
231
|
"Test Callbacks": "C:\\Node32\\node32.cmd node test/callbacks.js",
|
|
232
232
|
"Test Raylib": "seatsh C:\\Node32\\node32.cmd node test/raylib.js",
|
|
233
|
-
"Test SQLite": "C:\\Node32\\node32.cmd node test/sqlite.js"
|
|
233
|
+
"Test SQLite": "C:\\Node32\\node32.cmd node test/sqlite.js",
|
|
234
|
+
"Test Win32": {
|
|
235
|
+
"command": "C:\\Node32\\node32.cmd node test/win32.js",
|
|
236
|
+
"repeat": 8
|
|
237
|
+
}
|
|
234
238
|
}
|
|
235
239
|
},
|
|
236
240
|
|
|
@@ -244,7 +248,11 @@
|
|
|
244
248
|
"Test Async": "C:\\Node64\\node64.cmd node test/async.js",
|
|
245
249
|
"Test Callbacks": "C:\\Node64\\node64.cmd node test/callbacks.js",
|
|
246
250
|
"Test Raylib": "seatsh C:\\Node64\\node64.cmd node test/raylib.js",
|
|
247
|
-
"Test SQLite": "C:\\Node64\\node64.cmd node test/sqlite.js"
|
|
251
|
+
"Test SQLite": "C:\\Node64\\node64.cmd node test/sqlite.js",
|
|
252
|
+
"Test Win32": {
|
|
253
|
+
"command": "C:\\Node64\\node64.cmd node test/win32.js",
|
|
254
|
+
"repeat": 8
|
|
255
|
+
}
|
|
248
256
|
}
|
|
249
257
|
}
|
|
250
258
|
}
|
|
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
|