koffi 1.2.0 → 1.2.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/CMakeLists.txt +1 -1
- package/README.md +2 -0
- package/benchmark/CMakeLists.txt +1 -1
- package/build/qemu/1.2.1/koffi_darwin_x64.tar.gz +0 -0
- package/build/qemu/1.2.1/koffi_freebsd_arm64.tar.gz +0 -0
- package/build/qemu/1.2.1/koffi_freebsd_ia32.tar.gz +0 -0
- package/build/qemu/1.2.1/koffi_freebsd_x64.tar.gz +0 -0
- package/build/qemu/1.2.1/koffi_linux_arm.tar.gz +0 -0
- package/build/qemu/1.2.1/koffi_linux_arm64.tar.gz +0 -0
- package/build/qemu/1.2.1/koffi_linux_ia32.tar.gz +0 -0
- package/build/qemu/1.2.1/koffi_linux_riscv64.tar.gz +0 -0
- package/build/qemu/1.2.1/koffi_linux_x64.tar.gz +0 -0
- package/build/qemu/1.2.1/koffi_openbsd_ia32.tar.gz +0 -0
- package/build/qemu/1.2.1/koffi_openbsd_x64.tar.gz +0 -0
- package/build/qemu/1.2.1/koffi_win32_ia32.tar.gz +0 -0
- package/build/qemu/1.2.1/koffi_win32_x64.tar.gz +0 -0
- package/package.json +1 -1
- package/src/abi_arm32.cc +2 -2
- package/src/abi_arm32_fwd.S +4 -4
- package/src/abi_arm64.cc +2 -2
- package/src/abi_arm64_fwd.S +4 -4
- package/src/abi_arm64_fwd.asm +5 -5
- package/src/abi_riscv64.cc +2 -2
- package/src/abi_riscv64_fwd.S +4 -4
- package/src/abi_x64_sysv.cc +2 -2
- package/src/abi_x64_sysv_fwd.S +4 -4
- package/src/abi_x64_win.cc +2 -2
- package/src/abi_x64_win_fwd.asm +4 -4
- package/src/abi_x86.cc +26 -14
- package/src/abi_x86_fwd.S +15 -16
- package/src/abi_x86_fwd.asm +15 -9
- package/src/call.hh +1 -1
- package/src/ffi.cc +3 -8
- package/test/callbacks.js +8 -0
- package/test/misc.c +8 -0
- package/build/qemu/1.2.0/koffi_darwin_x64.tar.gz +0 -0
- package/build/qemu/1.2.0/koffi_freebsd_arm64.tar.gz +0 -0
- package/build/qemu/1.2.0/koffi_freebsd_ia32.tar.gz +0 -0
- package/build/qemu/1.2.0/koffi_freebsd_x64.tar.gz +0 -0
- package/build/qemu/1.2.0/koffi_linux_arm.tar.gz +0 -0
- package/build/qemu/1.2.0/koffi_linux_arm64.tar.gz +0 -0
- package/build/qemu/1.2.0/koffi_linux_ia32.tar.gz +0 -0
- package/build/qemu/1.2.0/koffi_linux_riscv64.tar.gz +0 -0
- package/build/qemu/1.2.0/koffi_linux_x64.tar.gz +0 -0
- package/build/qemu/1.2.0/koffi_openbsd_ia32.tar.gz +0 -0
- package/build/qemu/1.2.0/koffi_openbsd_x64.tar.gz +0 -0
- package/build/qemu/1.2.0/koffi_win32_ia32.tar.gz +0 -0
- package/build/qemu/1.2.0/koffi_win32_x64.tar.gz +0 -0
package/CMakeLists.txt
CHANGED
|
@@ -18,7 +18,7 @@ find_package(CNoke)
|
|
|
18
18
|
|
|
19
19
|
set(CMAKE_CXX_STANDARD 17)
|
|
20
20
|
if(MSVC)
|
|
21
|
-
add_compile_options(/W4 /wd4200 /wd4458 /wd4706 /wd4100 /wd4127 /wd4702 /wd4201)
|
|
21
|
+
add_compile_options(/W4 /wd4200 /wd4458 /wd4706 /wd4100 /wd4127 /wd4702 /wd4201 /wd4324)
|
|
22
22
|
enable_language(ASM_MASM)
|
|
23
23
|
else()
|
|
24
24
|
add_compile_options(-Wall -Wextra -Wno-missing-field-initializers -Wno-unused-parameter)
|
package/README.md
CHANGED
|
@@ -341,6 +341,8 @@ console.log(ret);
|
|
|
341
341
|
// This example prints "Hello Niels!" first, and then prints 42
|
|
342
342
|
```
|
|
343
343
|
|
|
344
|
+
On x86 platforms, only Cdecl and Stdcall callbacks are supported.
|
|
345
|
+
|
|
344
346
|
## Memory settings
|
|
345
347
|
|
|
346
348
|
For synchronous/normal calls, Koffi uses two preallocated memory blocks, one to construct the C stack and the other to allocate strings and big objects/structs. Unless very big strings or objects (at least more than one page of memory) are used, no extra allocation is needed during calls or callbacks.
|
package/benchmark/CMakeLists.txt
CHANGED
|
@@ -26,7 +26,7 @@ add_subdirectory(../test test)
|
|
|
26
26
|
|
|
27
27
|
set(CMAKE_CXX_STANDARD 17)
|
|
28
28
|
if(MSVC)
|
|
29
|
-
add_compile_options(/W4 /wd4200 /wd4458 /wd4706 /wd4100 /wd4127 /wd4702 /wd4201)
|
|
29
|
+
add_compile_options(/W4 /wd4200 /wd4458 /wd4706 /wd4100 /wd4127 /wd4702 /wd4201 /wd4324)
|
|
30
30
|
else()
|
|
31
31
|
add_compile_options(-Wall -Wextra -Wno-missing-field-initializers -Wno-unused-parameter)
|
|
32
32
|
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
|
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/package.json
CHANGED
package/src/abi_arm32.cc
CHANGED
|
@@ -100,7 +100,7 @@ static inline int IsHFA(const TypeInfo *type)
|
|
|
100
100
|
#endif
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
-
bool AnalyseFunction(InstanceData *, FunctionInfo *func)
|
|
103
|
+
bool AnalyseFunction(Napi::Env, InstanceData *, FunctionInfo *func)
|
|
104
104
|
{
|
|
105
105
|
if (int hfa = IsHFA(func->ret.type); hfa) {
|
|
106
106
|
func->ret.vec_count = hfa;
|
|
@@ -931,7 +931,7 @@ void *GetTrampoline(Size idx, const FunctionInfo *proto)
|
|
|
931
931
|
return Trampolines[idx][vec];
|
|
932
932
|
}
|
|
933
933
|
|
|
934
|
-
extern "C" void
|
|
934
|
+
extern "C" void RelayCallback(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegisters *out_reg)
|
|
935
935
|
{
|
|
936
936
|
exec_call->Relay(idx, own_sp, caller_sp, out_reg);
|
|
937
937
|
}
|
package/src/abi_arm32_fwd.S
CHANGED
|
@@ -144,11 +144,11 @@ ForwardCallXDDDD:
|
|
|
144
144
|
.global TrampolineX13
|
|
145
145
|
.global TrampolineX14
|
|
146
146
|
.global TrampolineX15
|
|
147
|
-
.global
|
|
147
|
+
.global RelayCallback
|
|
148
148
|
.global CallSwitchStack
|
|
149
149
|
|
|
150
150
|
# First, make a copy of the GPR argument registers (r0 to r7).
|
|
151
|
-
# Then call the C function
|
|
151
|
+
# Then call the C function RelayCallback with the following arguments:
|
|
152
152
|
# static trampoline ID, a pointer to the saved GPR array, a pointer to the stack
|
|
153
153
|
# arguments of this call, and a pointer to a struct that will contain the result registers.
|
|
154
154
|
# After the call, simply load these registers from the output struct.
|
|
@@ -168,7 +168,7 @@ ForwardCallXDDDD:
|
|
|
168
168
|
mov r1, sp
|
|
169
169
|
add r2, sp, #128
|
|
170
170
|
add r3, sp, #80
|
|
171
|
-
bl
|
|
171
|
+
bl RelayCallback
|
|
172
172
|
ldr r0, [sp, 80]
|
|
173
173
|
ldr r1, [sp, 84]
|
|
174
174
|
add sp, sp, #120
|
|
@@ -206,7 +206,7 @@ ForwardCallXDDDD:
|
|
|
206
206
|
mov r1, sp
|
|
207
207
|
add r2, sp, #128
|
|
208
208
|
add r3, sp, #80
|
|
209
|
-
bl
|
|
209
|
+
bl RelayCallback
|
|
210
210
|
ldr r0, [sp, 80]
|
|
211
211
|
ldr r1, [sp, 84]
|
|
212
212
|
vldr d0, [sp, 88]
|
package/src/abi_arm64.cc
CHANGED
|
@@ -98,7 +98,7 @@ static inline int IsHFA(const TypeInfo *type)
|
|
|
98
98
|
return IsHFA(type, 1, 4);
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
-
bool AnalyseFunction(InstanceData *, FunctionInfo *func)
|
|
101
|
+
bool AnalyseFunction(Napi::Env, InstanceData *, FunctionInfo *func)
|
|
102
102
|
{
|
|
103
103
|
if (int hfa = IsHFA(func->ret.type); hfa) {
|
|
104
104
|
func->ret.vec_count = hfa;
|
|
@@ -999,7 +999,7 @@ void *GetTrampoline(Size idx, const FunctionInfo *proto)
|
|
|
999
999
|
return Trampolines[idx][vec];
|
|
1000
1000
|
}
|
|
1001
1001
|
|
|
1002
|
-
extern "C" void
|
|
1002
|
+
extern "C" void RelayCallback(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegisters *out_reg)
|
|
1003
1003
|
{
|
|
1004
1004
|
exec_call->Relay(idx, own_sp, caller_sp, out_reg);
|
|
1005
1005
|
}
|
package/src/abi_arm64_fwd.S
CHANGED
|
@@ -147,11 +147,11 @@ SYMBOL(ForwardCallXDDDD):
|
|
|
147
147
|
.global SYMBOL(TrampolineX13)
|
|
148
148
|
.global SYMBOL(TrampolineX14)
|
|
149
149
|
.global SYMBOL(TrampolineX15)
|
|
150
|
-
.global SYMBOL(
|
|
150
|
+
.global SYMBOL(RelayCallback)
|
|
151
151
|
.global SYMBOL(CallSwitchStack)
|
|
152
152
|
|
|
153
153
|
# First, make a copy of the GPR argument registers (x0 to x7).
|
|
154
|
-
# Then call the C function
|
|
154
|
+
# Then call the C function RelayCallback with the following arguments:
|
|
155
155
|
# static trampoline ID, a pointer to the saved GPR array, a pointer to the stack
|
|
156
156
|
# arguments of this call, and a pointer to a struct that will contain the result registers.
|
|
157
157
|
# After the call, simply load these registers from the output struct.
|
|
@@ -172,7 +172,7 @@ SYMBOL(ForwardCallXDDDD):
|
|
|
172
172
|
mov x1, sp
|
|
173
173
|
add x2, sp, #208
|
|
174
174
|
add x3, sp, #136
|
|
175
|
-
bl SYMBOL(
|
|
175
|
+
bl SYMBOL(RelayCallback)
|
|
176
176
|
ldp x0, x1, [sp, 136]
|
|
177
177
|
add sp, sp, #192
|
|
178
178
|
.cfi_def_cfa sp, 16
|
|
@@ -206,7 +206,7 @@ SYMBOL(ForwardCallXDDDD):
|
|
|
206
206
|
mov x1, sp
|
|
207
207
|
add x2, sp, #208
|
|
208
208
|
add x3, sp, #136
|
|
209
|
-
bl SYMBOL(
|
|
209
|
+
bl SYMBOL(RelayCallback)
|
|
210
210
|
ldp x0, x1, [sp, 136]
|
|
211
211
|
ldp d0, d1, [sp, 152]
|
|
212
212
|
ldp d2, d3, [sp, 168]
|
package/src/abi_arm64_fwd.asm
CHANGED
|
@@ -145,12 +145,12 @@ ForwardCallXDDDD PROC
|
|
|
145
145
|
EXPORT TrampolineX13
|
|
146
146
|
EXPORT TrampolineX14
|
|
147
147
|
EXPORT TrampolineX15
|
|
148
|
-
EXPORT
|
|
149
|
-
EXTERN
|
|
148
|
+
EXPORT RelayCallback
|
|
149
|
+
EXTERN RelayCallback
|
|
150
150
|
EXPORT CallSwitchStack
|
|
151
151
|
|
|
152
152
|
; First, make a copy of the GPR argument registers (x0 to x7).
|
|
153
|
-
; Then call the C function
|
|
153
|
+
; Then call the C function RelayCallback with the following arguments:
|
|
154
154
|
; static trampoline ID, a pointer to the saved GPR array, a pointer to the stack
|
|
155
155
|
; arguments of this call, and a pointer to a struct that will contain the result registers.
|
|
156
156
|
; After the call, simply load these registers from the output struct.
|
|
@@ -168,7 +168,7 @@ ForwardCallXDDDD PROC
|
|
|
168
168
|
mov x1, sp
|
|
169
169
|
add x2, sp, #208
|
|
170
170
|
add x3, sp, #136
|
|
171
|
-
bl
|
|
171
|
+
bl RelayCallback
|
|
172
172
|
ldp x0, x1, [sp, 136]
|
|
173
173
|
add sp, sp, #192
|
|
174
174
|
ldp x29, x30, [sp], 16
|
|
@@ -194,7 +194,7 @@ ForwardCallXDDDD PROC
|
|
|
194
194
|
mov x1, sp
|
|
195
195
|
add x2, sp, #208
|
|
196
196
|
add x3, sp, #136
|
|
197
|
-
bl
|
|
197
|
+
bl RelayCallback
|
|
198
198
|
ldp x0, x1, [sp, 136]
|
|
199
199
|
ldp d0, d1, [sp, 152]
|
|
200
200
|
ldp d2, d3, [sp, 168]
|
package/src/abi_riscv64.cc
CHANGED
|
@@ -146,7 +146,7 @@ static void AnalyseParameter(ParameterInfo *param, int gpr_avail, int vec_avail)
|
|
|
146
146
|
}
|
|
147
147
|
}
|
|
148
148
|
|
|
149
|
-
bool AnalyseFunction(InstanceData *, FunctionInfo *func)
|
|
149
|
+
bool AnalyseFunction(Napi::Env, InstanceData *, FunctionInfo *func)
|
|
150
150
|
{
|
|
151
151
|
AnalyseParameter(&func->ret, 2, 2);
|
|
152
152
|
|
|
@@ -817,7 +817,7 @@ void *GetTrampoline(Size idx, const FunctionInfo *proto)
|
|
|
817
817
|
return Trampolines[idx][fp];
|
|
818
818
|
}
|
|
819
819
|
|
|
820
|
-
extern "C" void
|
|
820
|
+
extern "C" void RelayCallback(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegisters *out_reg)
|
|
821
821
|
{
|
|
822
822
|
exec_call->Relay(idx, own_sp, caller_sp, out_reg);
|
|
823
823
|
}
|
package/src/abi_riscv64_fwd.S
CHANGED
|
@@ -168,11 +168,11 @@ ForwardCallXDD:
|
|
|
168
168
|
.global TrampolineX13
|
|
169
169
|
.global TrampolineX14
|
|
170
170
|
.global TrampolineX15
|
|
171
|
-
.global
|
|
171
|
+
.global RelayCallback
|
|
172
172
|
.global CallSwitchStack
|
|
173
173
|
|
|
174
174
|
# First, make a copy of the GPR argument registers (a0 to a7).
|
|
175
|
-
# Then call the C function
|
|
175
|
+
# Then call the C function RelayCallback with the following arguments:
|
|
176
176
|
# static trampoline ID, a pointer to the saved GPR array, a pointer to the stack
|
|
177
177
|
# arguments of this call, and a pointer to a struct that will contain the result registers.
|
|
178
178
|
# After the call, simply load these registers from the output struct.
|
|
@@ -191,7 +191,7 @@ ForwardCallXDD:
|
|
|
191
191
|
addi a1, sp, 8
|
|
192
192
|
addi a2, sp, 176
|
|
193
193
|
addi a3, sp, 136
|
|
194
|
-
jal
|
|
194
|
+
jal RelayCallback
|
|
195
195
|
ld ra, 0(sp)
|
|
196
196
|
ld a0, 136(sp)
|
|
197
197
|
ld a1, 144(sp)
|
|
@@ -223,7 +223,7 @@ ForwardCallXDD:
|
|
|
223
223
|
addi a1, sp, 8
|
|
224
224
|
addi a2, sp, 176
|
|
225
225
|
addi a3, sp, 136
|
|
226
|
-
jal
|
|
226
|
+
jal RelayCallback
|
|
227
227
|
ld ra, 0(sp)
|
|
228
228
|
ld a0, 136(sp)
|
|
229
229
|
ld a1, 144(sp)
|
package/src/abi_x64_sysv.cc
CHANGED
|
@@ -225,7 +225,7 @@ static void AnalyseParameter(ParameterInfo *param, int gpr_avail, int xmm_avail)
|
|
|
225
225
|
}
|
|
226
226
|
}
|
|
227
227
|
|
|
228
|
-
bool AnalyseFunction(InstanceData *, FunctionInfo *func)
|
|
228
|
+
bool AnalyseFunction(Napi::Env, InstanceData *, FunctionInfo *func)
|
|
229
229
|
{
|
|
230
230
|
AnalyseParameter(&func->ret, 2, 2);
|
|
231
231
|
|
|
@@ -874,7 +874,7 @@ void *GetTrampoline(Size idx, const FunctionInfo *proto)
|
|
|
874
874
|
return Trampolines[idx][xmm];
|
|
875
875
|
}
|
|
876
876
|
|
|
877
|
-
extern "C" void
|
|
877
|
+
extern "C" void RelayCallback(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegisters *out_reg)
|
|
878
878
|
{
|
|
879
879
|
exec_call->Relay(idx, own_sp, caller_sp, out_reg);
|
|
880
880
|
}
|
package/src/abi_x64_sysv_fwd.S
CHANGED
|
@@ -185,11 +185,11 @@ SYMBOL(ForwardCallXDD):
|
|
|
185
185
|
.global SYMBOL(TrampolineX13)
|
|
186
186
|
.global SYMBOL(TrampolineX14)
|
|
187
187
|
.global SYMBOL(TrampolineX15)
|
|
188
|
-
.global SYMBOL(
|
|
188
|
+
.global SYMBOL(RelayCallback)
|
|
189
189
|
.global SYMBOL(CallSwitchStack)
|
|
190
190
|
|
|
191
191
|
# First, make a copy of the GPR argument registers (rdi, rsi, rdx, rcx, r8, r9).
|
|
192
|
-
# Then call the C function
|
|
192
|
+
# Then call the C function RelayCallback with the following arguments:
|
|
193
193
|
# static trampoline ID, a pointer to the saved GPR array, a pointer to the stack
|
|
194
194
|
# arguments of this call, and a pointer to a struct that will contain the result registers.
|
|
195
195
|
# After the call, simply load these registers from the output struct.
|
|
@@ -209,7 +209,7 @@ SYMBOL(ForwardCallXDD):
|
|
|
209
209
|
movq %rsp, %rsi
|
|
210
210
|
leaq 160(%rsp), %rdx
|
|
211
211
|
leaq 112(%rsp), %rcx
|
|
212
|
-
call SYMBOL(
|
|
212
|
+
call SYMBOL(RelayCallback)
|
|
213
213
|
movq 112(%rsp), %rax
|
|
214
214
|
movq 120(%rsp), %rdx
|
|
215
215
|
addq $152, %rsp
|
|
@@ -243,7 +243,7 @@ SYMBOL(ForwardCallXDD):
|
|
|
243
243
|
movq %rsp, %rsi
|
|
244
244
|
leaq 160(%rsp), %rdx
|
|
245
245
|
leaq 112(%rsp), %rcx
|
|
246
|
-
call SYMBOL(
|
|
246
|
+
call SYMBOL(RelayCallback)
|
|
247
247
|
movq 112(%rsp), %rax
|
|
248
248
|
movq 120(%rsp), %rdx
|
|
249
249
|
movsd 128(%rsp), %xmm0
|
package/src/abi_x64_win.cc
CHANGED
|
@@ -83,7 +83,7 @@ static inline bool IsRegular(Size size)
|
|
|
83
83
|
return regular;
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
bool AnalyseFunction(InstanceData *, FunctionInfo *func)
|
|
86
|
+
bool AnalyseFunction(Napi::Env, InstanceData *, FunctionInfo *func)
|
|
87
87
|
{
|
|
88
88
|
func->ret.regular = IsRegular(func->ret.type->size);
|
|
89
89
|
|
|
@@ -656,7 +656,7 @@ void *GetTrampoline(Size idx, const FunctionInfo *proto)
|
|
|
656
656
|
return Trampolines[idx][xmm];
|
|
657
657
|
}
|
|
658
658
|
|
|
659
|
-
extern "C" void
|
|
659
|
+
extern "C" void RelayCallback(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegisters *out_reg)
|
|
660
660
|
{
|
|
661
661
|
exec_call->Relay(idx, own_sp, caller_sp, out_reg);
|
|
662
662
|
}
|
package/src/abi_x64_win_fwd.asm
CHANGED
|
@@ -142,11 +142,11 @@ public TrampolineX12
|
|
|
142
142
|
public TrampolineX13
|
|
143
143
|
public TrampolineX14
|
|
144
144
|
public TrampolineX15
|
|
145
|
-
extern
|
|
145
|
+
extern RelayCallback : PROC
|
|
146
146
|
public CallSwitchStack
|
|
147
147
|
|
|
148
148
|
; First, make a copy of the GPR argument registers (rcx, rdx, r8, r9).
|
|
149
|
-
; Then call the C function
|
|
149
|
+
; Then call the C function RelayCallback with the following arguments:
|
|
150
150
|
; static trampoline ID, a pointer to the saved GPR array, a pointer to the stack
|
|
151
151
|
; arguments of this call, and a pointer to a struct that will contain the result registers.
|
|
152
152
|
; After the call, simply load these registers from the output struct.
|
|
@@ -163,7 +163,7 @@ trampoline macro ID
|
|
|
163
163
|
lea rdx, qword ptr [rsp+32]
|
|
164
164
|
lea r8, qword ptr [rsp+128]
|
|
165
165
|
lea r9, qword ptr [rsp+96]
|
|
166
|
-
call
|
|
166
|
+
call RelayCallback
|
|
167
167
|
mov rax, qword ptr [rsp+96]
|
|
168
168
|
add rsp, 120
|
|
169
169
|
ret
|
|
@@ -187,7 +187,7 @@ trampoline_xmm macro ID
|
|
|
187
187
|
lea rdx, qword ptr [rsp+32]
|
|
188
188
|
lea r8, qword ptr [rsp+128]
|
|
189
189
|
lea r9, qword ptr [rsp+96]
|
|
190
|
-
call
|
|
190
|
+
call RelayCallback
|
|
191
191
|
mov rax, qword ptr [rsp+96]
|
|
192
192
|
movsd xmm0, qword ptr [rsp+104]
|
|
193
193
|
add rsp, 120
|
package/src/abi_x86.cc
CHANGED
|
@@ -25,12 +25,12 @@ namespace RG {
|
|
|
25
25
|
struct BackRegisters {
|
|
26
26
|
uint32_t eax;
|
|
27
27
|
uint32_t edx;
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
bool
|
|
33
|
-
|
|
28
|
+
union {
|
|
29
|
+
double d;
|
|
30
|
+
float f;
|
|
31
|
+
} x87;
|
|
32
|
+
bool x87_double;
|
|
33
|
+
int ret_pop;
|
|
34
34
|
};
|
|
35
35
|
|
|
36
36
|
extern "C" uint64_t ForwardCallG(const void *func, uint8_t *sp, uint8_t **out_old_sp);
|
|
@@ -89,8 +89,14 @@ static inline bool IsRegular(Size size)
|
|
|
89
89
|
return regular;
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
-
bool AnalyseFunction(InstanceData *instance, FunctionInfo *func)
|
|
92
|
+
bool AnalyseFunction(Napi::Env env, InstanceData *instance, FunctionInfo *func)
|
|
93
93
|
{
|
|
94
|
+
if (!func->lib && func->convention != CallConvention::Cdecl &&
|
|
95
|
+
func->convention != CallConvention::Stdcall) {
|
|
96
|
+
ThrowError<Napi::Error>(env, "Only Cdecl and Stdcall callbacks are supported");
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
|
|
94
100
|
int fast = (func->convention == CallConvention::Fastcall) ? 2 :
|
|
95
101
|
(func->convention == CallConvention::Thiscall) ? 1 : 0;
|
|
96
102
|
func->fast = fast;
|
|
@@ -116,7 +122,7 @@ bool AnalyseFunction(InstanceData *instance, FunctionInfo *func)
|
|
|
116
122
|
fast--;
|
|
117
123
|
}
|
|
118
124
|
|
|
119
|
-
params_size += std::max(
|
|
125
|
+
params_size += std::max(4, AlignLen(param.type->size, 4));
|
|
120
126
|
}
|
|
121
127
|
func->args_size = params_size + 4 * !func->ret.trivial;
|
|
122
128
|
|
|
@@ -441,9 +447,15 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
|
|
|
441
447
|
uint8_t *return_ptr = !proto->ret.trivial ? (uint8_t *)args_ptr[0] : nullptr;
|
|
442
448
|
args_ptr += !proto->ret.trivial;
|
|
443
449
|
|
|
450
|
+
if (proto->convention == CallConvention::Stdcall) {
|
|
451
|
+
out_reg->ret_pop = (int)proto->args_size;
|
|
444
452
|
#ifndef _WIN32
|
|
445
|
-
|
|
453
|
+
} else if (return_ptr) {
|
|
454
|
+
out_reg->ret_pop = 4;
|
|
446
455
|
#endif
|
|
456
|
+
} else {
|
|
457
|
+
out_reg->ret_pop = 0;
|
|
458
|
+
}
|
|
447
459
|
|
|
448
460
|
LocalArray<napi_value, MaxParameters> arguments;
|
|
449
461
|
|
|
@@ -680,8 +692,8 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
|
|
|
680
692
|
return;
|
|
681
693
|
}
|
|
682
694
|
|
|
683
|
-
out_reg->f = CopyNumber<float>(value);
|
|
684
|
-
out_reg->
|
|
695
|
+
out_reg->x87.f = CopyNumber<float>(value);
|
|
696
|
+
out_reg->x87_double = false;
|
|
685
697
|
} break;
|
|
686
698
|
case PrimitiveKind::Float64: {
|
|
687
699
|
if (RG_UNLIKELY(!value.IsNumber() && !value.IsBigInt())) {
|
|
@@ -689,8 +701,8 @@ void CallData::Relay(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegister
|
|
|
689
701
|
return;
|
|
690
702
|
}
|
|
691
703
|
|
|
692
|
-
out_reg->d = CopyNumber<double>(value);
|
|
693
|
-
out_reg->
|
|
704
|
+
out_reg->x87.d = CopyNumber<double>(value);
|
|
705
|
+
out_reg->x87_double = true;
|
|
694
706
|
} break;
|
|
695
707
|
case PrimitiveKind::Callback: {
|
|
696
708
|
void *ptr;
|
|
@@ -721,7 +733,7 @@ void *GetTrampoline(Size idx, const FunctionInfo *proto)
|
|
|
721
733
|
return Trampolines[idx][x87];
|
|
722
734
|
}
|
|
723
735
|
|
|
724
|
-
extern "C" void
|
|
736
|
+
extern "C" void RelayCallback(Size idx, uint8_t *own_sp, uint8_t *caller_sp, BackRegisters *out_reg)
|
|
725
737
|
{
|
|
726
738
|
exec_call->Relay(idx, own_sp, caller_sp, out_reg);
|
|
727
739
|
}
|
package/src/abi_x86_fwd.S
CHANGED
|
@@ -115,10 +115,10 @@ ForwardCallRD:
|
|
|
115
115
|
.global TrampolineX13
|
|
116
116
|
.global TrampolineX14
|
|
117
117
|
.global TrampolineX15
|
|
118
|
-
.global
|
|
118
|
+
.global RelayCallback
|
|
119
119
|
.global CallSwitchStack
|
|
120
120
|
|
|
121
|
-
# Call the C function
|
|
121
|
+
# Call the C function RelayCallback with the following arguments:
|
|
122
122
|
# static trampoline ID, the current stack pointer, a pointer to the stack arguments of this call,
|
|
123
123
|
# and a pointer to a struct that will contain the result registers.
|
|
124
124
|
# After the call, simply load these registers from the output struct.
|
|
@@ -136,19 +136,15 @@ ForwardCallRD:
|
|
|
136
136
|
movl %eax, 12(%esp)
|
|
137
137
|
call GetEIP
|
|
138
138
|
addl $_GLOBAL_OFFSET_TABLE_, %ecx
|
|
139
|
-
call *
|
|
139
|
+
call *RelayCallback@GOT(%ecx)
|
|
140
|
+
movl 44(%esp), %edx
|
|
141
|
+
movl 36(%esp), %ecx
|
|
142
|
+
movl %edx, 44(%esp, %ecx)
|
|
140
143
|
movl 16(%esp), %eax
|
|
141
144
|
movl 20(%esp), %edx
|
|
142
|
-
|
|
143
|
-
jne 2f
|
|
144
|
-
1:
|
|
145
|
-
addl $44, %esp
|
|
145
|
+
leal 44(%esp, %ecx), %esp
|
|
146
146
|
.cfi_def_cfa esp, 4
|
|
147
147
|
ret
|
|
148
|
-
2:
|
|
149
|
-
addl $44, %esp
|
|
150
|
-
.cfi_def_cfa esp, 4
|
|
151
|
-
ret $4
|
|
152
148
|
.cfi_endproc
|
|
153
149
|
.endm
|
|
154
150
|
|
|
@@ -168,17 +164,20 @@ ForwardCallRD:
|
|
|
168
164
|
movl %eax, 12(%esp)
|
|
169
165
|
call GetEIP
|
|
170
166
|
addl $_GLOBAL_OFFSET_TABLE_, %ecx
|
|
171
|
-
call *
|
|
172
|
-
|
|
167
|
+
call *RelayCallback@GOT(%ecx)
|
|
168
|
+
movl 44(%esp), %edx
|
|
169
|
+
movl 36(%esp), %ecx
|
|
170
|
+
movl %edx, 44(%esp, %ecx, 4)
|
|
171
|
+
cmpb $0, 32(%esp)
|
|
173
172
|
jne 2f
|
|
174
173
|
1:
|
|
175
|
-
flds
|
|
176
|
-
|
|
174
|
+
flds 24(%esp)
|
|
175
|
+
leal 44(%esp, %ecx), %esp
|
|
177
176
|
.cfi_def_cfa esp, 4
|
|
178
177
|
ret
|
|
179
178
|
2:
|
|
180
179
|
fldl 24(%esp)
|
|
181
|
-
|
|
180
|
+
leal 44(%esp, %ecx), %esp
|
|
182
181
|
.cfi_def_cfa esp, 4
|
|
183
182
|
ret
|
|
184
183
|
.cfi_endproc
|
package/src/abi_x86_fwd.asm
CHANGED
|
@@ -121,10 +121,10 @@ public TrampolineX12
|
|
|
121
121
|
public TrampolineX13
|
|
122
122
|
public TrampolineX14
|
|
123
123
|
public TrampolineX15
|
|
124
|
-
extern
|
|
124
|
+
extern RelayCallback : PROC
|
|
125
125
|
public CallSwitchStack
|
|
126
126
|
|
|
127
|
-
; Call the C function
|
|
127
|
+
; Call the C function RelayCallback with the following arguments:
|
|
128
128
|
; static trampoline ID, the current stack pointer, a pointer to the stack arguments of this call,
|
|
129
129
|
; and a pointer to a struct that will contain the result registers.
|
|
130
130
|
; After the call, simply load these registers from the output struct.
|
|
@@ -137,10 +137,13 @@ trampoline macro ID
|
|
|
137
137
|
mov dword ptr [esp+8], eax
|
|
138
138
|
lea eax, dword ptr [esp+16]
|
|
139
139
|
mov dword ptr [esp+12], eax
|
|
140
|
-
call
|
|
140
|
+
call RelayCallback
|
|
141
|
+
mov edx, dword ptr [esp+44]
|
|
142
|
+
mov ecx, dword ptr [esp+36]
|
|
143
|
+
mov dword ptr [esp+ecx+44], edx
|
|
141
144
|
mov eax, dword ptr [esp+16]
|
|
142
145
|
mov edx, dword ptr [esp+20]
|
|
143
|
-
|
|
146
|
+
lea esp, [esp+ecx+44]
|
|
144
147
|
ret
|
|
145
148
|
endm
|
|
146
149
|
|
|
@@ -157,16 +160,19 @@ trampoline_x87 macro ID
|
|
|
157
160
|
mov dword ptr [esp+8], eax
|
|
158
161
|
lea eax, dword ptr [esp+16]
|
|
159
162
|
mov dword ptr [esp+12], eax
|
|
160
|
-
call
|
|
161
|
-
|
|
163
|
+
call RelayCallback
|
|
164
|
+
mov edx, dword ptr [esp+44]
|
|
165
|
+
mov ecx, dword ptr [esp+36]
|
|
166
|
+
mov dword ptr [esp+ecx+44], edx
|
|
167
|
+
cmp byte ptr [esp+32], 0
|
|
162
168
|
jne l2
|
|
163
169
|
l1:
|
|
164
|
-
fld dword ptr [esp+
|
|
165
|
-
|
|
170
|
+
fld dword ptr [esp+24]
|
|
171
|
+
lea esp, dword ptr [esp+ecx+44]
|
|
166
172
|
ret
|
|
167
173
|
l2:
|
|
168
174
|
fld qword ptr [esp+24]
|
|
169
|
-
|
|
175
|
+
lea esp, dword ptr [esp+ecx+44]
|
|
170
176
|
ret
|
|
171
177
|
endm
|
|
172
178
|
|
package/src/call.hh
CHANGED
package/src/ffi.cc
CHANGED
|
@@ -511,13 +511,8 @@ static Napi::Value CreateCallbackType(const Napi::CallbackInfo &info)
|
|
|
511
511
|
LogError("Variadic callbacks are not supported");
|
|
512
512
|
return env.Null();
|
|
513
513
|
}
|
|
514
|
-
if (func->convention != CallConvention::Cdecl &&
|
|
515
|
-
func->convention != CallConvention::Stdcall) {
|
|
516
|
-
ThrowError<Napi::Error>(env, "Only Cdecl and Stdcall callbacks are supported");
|
|
517
|
-
return env.Null();
|
|
518
|
-
}
|
|
519
514
|
|
|
520
|
-
if (!AnalyseFunction(instance, func))
|
|
515
|
+
if (!AnalyseFunction(env, instance, func))
|
|
521
516
|
return env.Null();
|
|
522
517
|
|
|
523
518
|
// We cannot fail after this check
|
|
@@ -713,7 +708,7 @@ static Napi::Value TranslateVariadicCall(const Napi::CallbackInfo &info)
|
|
|
713
708
|
func.parameters.Append(param);
|
|
714
709
|
}
|
|
715
710
|
|
|
716
|
-
if (RG_UNLIKELY(!AnalyseFunction(instance, &func)))
|
|
711
|
+
if (RG_UNLIKELY(!AnalyseFunction(env, instance, &func)))
|
|
717
712
|
return env.Null();
|
|
718
713
|
|
|
719
714
|
InstanceMemory *mem = instance->memories[0];
|
|
@@ -846,7 +841,7 @@ static Napi::Value FindLibraryFunction(const Napi::CallbackInfo &info, CallConve
|
|
|
846
841
|
func->convention = CallConvention::Cdecl;
|
|
847
842
|
}
|
|
848
843
|
|
|
849
|
-
if (!AnalyseFunction(instance, func))
|
|
844
|
+
if (!AnalyseFunction(env, instance, func))
|
|
850
845
|
return env.Null();
|
|
851
846
|
if (func->variadic) {
|
|
852
847
|
// Minimize reallocations
|
package/test/callbacks.js
CHANGED
|
@@ -32,6 +32,7 @@ const BFG = koffi.struct('BFG', {
|
|
|
32
32
|
const SimpleCallback = koffi.callback('int SimpleCallback(const char *str)');
|
|
33
33
|
const RecursiveCallback = koffi.callback('RecursiveCallback', 'float', ['int', 'string', 'double']);
|
|
34
34
|
const BigCallback = koffi.callback('BFG BigCallback(BFG bfg)');
|
|
35
|
+
const ApplyCallback = koffi.callback('int __stdcall ApplyCallback(int a, int b, int c)');
|
|
35
36
|
|
|
36
37
|
main();
|
|
37
38
|
|
|
@@ -52,6 +53,7 @@ async function test() {
|
|
|
52
53
|
const CallJS = lib.func('int CallJS(const char *str, SimpleCallback cb)');
|
|
53
54
|
const CallRecursiveJS = lib.func('float CallRecursiveJS(int i, RecursiveCallback func)');
|
|
54
55
|
const ModifyBFG = lib.func('BFG ModifyBFG(int x, double y, const char *str, BigCallback func, _Out_ BFG *p)');
|
|
56
|
+
const ApplyStd = lib.func('int ApplyStd(int a, int b, int c, ApplyCallback func)');
|
|
55
57
|
|
|
56
58
|
// Simple test similar to README example
|
|
57
59
|
{
|
|
@@ -84,4 +86,10 @@ async function test() {
|
|
|
84
86
|
assert.deepEqual(bfg, { a: 2, b: 4, c: -25, d: 'New!', e: 54, inner: { f: -10, g: 3 } });
|
|
85
87
|
assert.deepEqual(out, { a: 2, b: 4, c: -25, d: 'X/Yo!/X', e: 54, inner: { f: 10, g: 3 } });
|
|
86
88
|
}
|
|
89
|
+
|
|
90
|
+
// Stdcall callbacks
|
|
91
|
+
{
|
|
92
|
+
let ret = ApplyStd(1, 5, 9, (a, b, c) => a + b * c);
|
|
93
|
+
assert.equal(ret, 46);
|
|
94
|
+
}
|
|
87
95
|
}
|
package/test/misc.c
CHANGED
|
@@ -504,3 +504,11 @@ EXPORT BFG ModifyBFG(int x, double y, const char *str, BFG (*func)(BFG bfg), BFG
|
|
|
504
504
|
bfg = func(bfg);
|
|
505
505
|
return bfg;
|
|
506
506
|
}
|
|
507
|
+
|
|
508
|
+
typedef int STDCALL ApplyCallback(int a, int b, int c);
|
|
509
|
+
|
|
510
|
+
EXPORT int ApplyStd(int a, int b, int c, ApplyCallback *func)
|
|
511
|
+
{
|
|
512
|
+
int ret = func(a, b, c);
|
|
513
|
+
return ret;
|
|
514
|
+
}
|
|
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
|