koffi 2.15.3 → 2.15.5
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 +16 -0
- package/build/koffi/darwin_arm64/koffi.node +0 -0
- package/build/koffi/darwin_x64/koffi.node +0 -0
- package/build/koffi/freebsd_arm64/koffi.node +0 -0
- package/build/koffi/freebsd_ia32/koffi.node +0 -0
- package/build/koffi/freebsd_x64/koffi.node +0 -0
- package/build/koffi/linux_arm64/koffi.node +0 -0
- package/build/koffi/linux_armhf/koffi.node +0 -0
- package/build/koffi/linux_ia32/koffi.node +0 -0
- package/build/koffi/linux_loong64/koffi.node +0 -0
- package/build/koffi/linux_riscv64d/koffi.node +0 -0
- package/build/koffi/linux_x64/koffi.node +0 -0
- package/build/koffi/musl_arm64/koffi.node +0 -0
- package/build/koffi/musl_x64/koffi.node +0 -0
- package/build/koffi/openbsd_ia32/koffi.node +0 -0
- package/build/koffi/openbsd_x64/koffi.node +0 -0
- package/build/koffi/win32_arm64/koffi.node +0 -0
- package/build/koffi/win32_ia32/koffi.node +0 -0
- package/build/koffi/win32_x64/koffi.node +0 -0
- package/index.js +8 -8
- package/indirect.js +8 -8
- package/package.json +1 -1
- package/src/koffi/src/abi_arm32.cc +0 -8
- package/src/koffi/src/abi_arm32_asm.S +8 -29
- package/src/koffi/src/abi_arm64.cc +4 -11
- package/src/koffi/src/abi_arm64_asm.S +5 -28
- package/src/koffi/src/abi_arm64_asm.asm +6 -21
- package/src/koffi/src/abi_loong64_asm.S +5 -23
- package/src/koffi/src/abi_riscv64.cc +0 -8
- package/src/koffi/src/abi_riscv64_asm.S +5 -23
- package/src/koffi/src/abi_x64_sysv.cc +0 -8
- package/src/koffi/src/abi_x64_sysv_asm.S +5 -26
- package/src/koffi/src/abi_x64_win.cc +0 -8
- package/src/koffi/src/abi_x64_win_asm.S +5 -16
- package/src/koffi/src/abi_x64_win_asm.asm +7 -19
- package/src/koffi/src/abi_x86.cc +17 -13
- package/src/koffi/src/abi_x86_asm.S +15 -24
- package/src/koffi/src/abi_x86_asm.asm +14 -20
- package/src/koffi/src/call.cc +8 -2
- package/src/koffi/src/call.hh +1 -1
- package/src/koffi/src/ffi.cc +1 -1
- package/src/koffi/src/trampolines/armasm.inc +0 -32770
- package/src/koffi/src/trampolines/gnu.inc +0 -24578
- package/src/koffi/src/trampolines/masm32.inc +0 -32770
- package/src/koffi/src/trampolines/masm64.inc +0 -32770
- package/src/koffi/src/trampolines/prototypes.inc +16385 -16385
|
@@ -25,8 +25,6 @@ extern "C" uint64_t ForwardCallXG(const void *func, uint8_t *sp, uint8_t **out_o
|
|
|
25
25
|
extern "C" float ForwardCallXF(const void *func, uint8_t *sp, uint8_t **out_old_sp);
|
|
26
26
|
extern "C" double ForwardCallXD(const void *func, uint8_t *sp, uint8_t **out_old_sp);
|
|
27
27
|
|
|
28
|
-
#include "trampolines/prototypes.inc"
|
|
29
|
-
|
|
30
28
|
bool AnalyseFunction(Napi::Env, InstanceData *, FunctionInfo *func)
|
|
31
29
|
{
|
|
32
30
|
func->ret.regular = IsRegularSize(func->ret.type->size, 8);
|
|
@@ -736,12 +734,6 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
736
734
|
err_guard.Disable();
|
|
737
735
|
}
|
|
738
736
|
|
|
739
|
-
void *GetTrampoline(int16_t idx, const FunctionInfo *proto)
|
|
740
|
-
{
|
|
741
|
-
bool xmm = proto->forward_fp || IsFloat(proto->ret.type);
|
|
742
|
-
return Trampolines[idx][xmm];
|
|
743
|
-
}
|
|
744
|
-
|
|
745
737
|
}
|
|
746
738
|
|
|
747
739
|
#endif
|
|
@@ -100,28 +100,18 @@ ForwardCallXD:
|
|
|
100
100
|
.global SwitchAndRelay
|
|
101
101
|
.global RelayDirect
|
|
102
102
|
|
|
103
|
-
# First, make a copy of
|
|
103
|
+
# First, make a copy of argument registers.
|
|
104
104
|
# Then call the C function RelayCallback with the following arguments:
|
|
105
105
|
# static trampoline ID, a pointer to the saved GPR array, a pointer to the stack
|
|
106
106
|
# arguments of this call, and a pointer to a struct that will contain the result registers.
|
|
107
107
|
# After the call, simply load these registers from the output struct.
|
|
108
108
|
.macro trampoline id
|
|
109
109
|
endbr64
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
movq %rdx, 40(%rsp)
|
|
113
|
-
movq %r8, 48(%rsp)
|
|
114
|
-
movq %r9, 56(%rsp)
|
|
115
|
-
movq $\id, %rcx
|
|
116
|
-
leaq 32(%rsp), %rdx
|
|
117
|
-
call RelayCallback
|
|
118
|
-
movq 96(%rsp), %rax
|
|
119
|
-
addq $120, %rsp
|
|
120
|
-
ret
|
|
110
|
+
movq $\id, %rax
|
|
111
|
+
jmp RelayTrampoline
|
|
121
112
|
.endm
|
|
122
113
|
|
|
123
|
-
|
|
124
|
-
.macro trampoline_vec id
|
|
114
|
+
RelayTrampoline:
|
|
125
115
|
endbr64
|
|
126
116
|
subq $120, %rsp
|
|
127
117
|
movq %rcx, 32(%rsp)
|
|
@@ -132,14 +122,13 @@ ForwardCallXD:
|
|
|
132
122
|
movsd %xmm1, 72(%rsp)
|
|
133
123
|
movsd %xmm2, 80(%rsp)
|
|
134
124
|
movsd %xmm3, 88(%rsp)
|
|
135
|
-
movq
|
|
125
|
+
movq %rax, %rcx
|
|
136
126
|
leaq 32(%rsp), %rdx
|
|
137
127
|
call RelayCallback
|
|
138
128
|
movq 96(%rsp), %rax
|
|
139
129
|
movsd 104(%rsp), %xmm0
|
|
140
130
|
addq $120, %rsp
|
|
141
131
|
ret
|
|
142
|
-
.endm
|
|
143
132
|
|
|
144
133
|
# When a callback is relayed, Koffi will call into Node.js and V8 to execute Javascript.
|
|
145
134
|
# The problem is that we're still running on the separate Koffi stack, and V8 will
|
|
@@ -111,31 +111,19 @@ extern RelayCallback : PROC
|
|
|
111
111
|
public SwitchAndRelay
|
|
112
112
|
extern RelayDirect : PROC
|
|
113
113
|
|
|
114
|
-
; First, make a copy of
|
|
114
|
+
; First, make a copy of argument registers.
|
|
115
115
|
; Then call the C function RelayCallback with the following arguments:
|
|
116
116
|
; static trampoline ID, a pointer to the saved GPR array, a pointer to the stack
|
|
117
117
|
; arguments of this call, and a pointer to a struct that will contain the result registers.
|
|
118
118
|
; After the call, simply load these registers from the output struct.
|
|
119
119
|
trampoline macro ID
|
|
120
|
-
endbr64
|
|
121
|
-
sub rsp, 120
|
|
122
|
-
.allocstack 120
|
|
123
120
|
.endprolog
|
|
124
|
-
|
|
125
|
-
mov
|
|
126
|
-
|
|
127
|
-
mov qword ptr [rsp+56], r9
|
|
128
|
-
mov rcx, ID
|
|
129
|
-
lea rdx, qword ptr [rsp+32]
|
|
130
|
-
call RelayCallback
|
|
131
|
-
mov rax, qword ptr [rsp+96]
|
|
132
|
-
add rsp, 120
|
|
133
|
-
ret
|
|
121
|
+
endbr64
|
|
122
|
+
mov rax, ID
|
|
123
|
+
jmp RelayTrampoline
|
|
134
124
|
endm
|
|
135
125
|
|
|
136
|
-
|
|
137
|
-
trampoline_vec macro ID
|
|
138
|
-
endbr64
|
|
126
|
+
RelayTrampoline proc frame
|
|
139
127
|
sub rsp, 120
|
|
140
128
|
.allocstack 120
|
|
141
129
|
.endprolog
|
|
@@ -147,14 +135,14 @@ trampoline_vec macro ID
|
|
|
147
135
|
movsd qword ptr [rsp+72], xmm1
|
|
148
136
|
movsd qword ptr [rsp+80], xmm2
|
|
149
137
|
movsd qword ptr [rsp+88], xmm3
|
|
150
|
-
mov rcx,
|
|
138
|
+
mov rcx, rax
|
|
151
139
|
lea rdx, qword ptr [rsp+32]
|
|
152
140
|
call RelayCallback
|
|
153
141
|
mov rax, qword ptr [rsp+96]
|
|
154
142
|
movsd xmm0, qword ptr [rsp+104]
|
|
155
143
|
add rsp, 120
|
|
156
144
|
ret
|
|
157
|
-
|
|
145
|
+
RelayTrampoline endp
|
|
158
146
|
|
|
159
147
|
; When a callback is relayed, Koffi will call into Node.js and V8 to execute Javascript.
|
|
160
148
|
; The problem is that we're still running on the separate Koffi stack, and V8 will
|
package/src/koffi/src/abi_x86.cc
CHANGED
|
@@ -22,7 +22,7 @@ struct BackRegisters {
|
|
|
22
22
|
double d;
|
|
23
23
|
float f;
|
|
24
24
|
} x87;
|
|
25
|
-
|
|
25
|
+
int ret_type;
|
|
26
26
|
int ret_pop;
|
|
27
27
|
};
|
|
28
28
|
|
|
@@ -40,8 +40,6 @@ extern "C" uint64_t ForwardCallRG(const void *func, uint8_t *sp, uint8_t **out_o
|
|
|
40
40
|
extern "C" float ForwardCallRF(const void *func, uint8_t *sp, uint8_t **out_old_sp);
|
|
41
41
|
extern "C" double ForwardCallRD(const void *func, uint8_t *sp, uint8_t **out_old_sp);
|
|
42
42
|
|
|
43
|
-
#include "trampolines/prototypes.inc"
|
|
44
|
-
|
|
45
43
|
bool AnalyseFunction(Napi::Env env, InstanceData *instance, FunctionInfo *func)
|
|
46
44
|
{
|
|
47
45
|
if (!func->lib && func->convention != CallConvention::Cdecl &&
|
|
@@ -500,7 +498,7 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
500
498
|
K_DEFER_N(err_guard) {
|
|
501
499
|
int pop = out_reg->ret_pop;
|
|
502
500
|
memset(out_reg, 0, K_SIZE(*out_reg));
|
|
503
|
-
out_reg->
|
|
501
|
+
out_reg->ret_type = 0;
|
|
504
502
|
out_reg->ret_pop = pop;
|
|
505
503
|
};
|
|
506
504
|
|
|
@@ -709,6 +707,7 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
709
707
|
\
|
|
710
708
|
CType v = GetNumber<CType>(value); \
|
|
711
709
|
out_reg->eax = (uint32_t)v; \
|
|
710
|
+
out_reg->ret_type = 0; \
|
|
712
711
|
} while (false)
|
|
713
712
|
#define RETURN_INTEGER_32_SWAP(CType) \
|
|
714
713
|
do { \
|
|
@@ -719,6 +718,7 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
719
718
|
\
|
|
720
719
|
CType v = GetNumber<CType>(value); \
|
|
721
720
|
out_reg->eax = (uint32_t)ReverseBytes(v); \
|
|
721
|
+
out_reg->ret_type = 0; \
|
|
722
722
|
} while (false)
|
|
723
723
|
#define RETURN_INTEGER_64(CType) \
|
|
724
724
|
do { \
|
|
@@ -731,6 +731,7 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
731
731
|
\
|
|
732
732
|
out_reg->eax = (uint32_t)((uint64_t)v >> 32); \
|
|
733
733
|
out_reg->edx = (uint32_t)((uint64_t)v & 0xFFFFFFFFu); \
|
|
734
|
+
out_reg->ret_type = 0; \
|
|
734
735
|
} while (false)
|
|
735
736
|
#define RETURN_INTEGER_64_SWAP(CType) \
|
|
736
737
|
do { \
|
|
@@ -743,10 +744,11 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
743
744
|
\
|
|
744
745
|
out_reg->eax = (uint32_t)((uint64_t)v >> 32); \
|
|
745
746
|
out_reg->edx = (uint32_t)((uint64_t)v & 0xFFFFFFFFu); \
|
|
747
|
+
out_reg->ret_type = 0; \
|
|
746
748
|
} while (false)
|
|
747
749
|
|
|
748
750
|
switch (type->primitive) {
|
|
749
|
-
case PrimitiveKind::Void: {} break;
|
|
751
|
+
case PrimitiveKind::Void: { out_reg->ret_type = 0; } break;
|
|
750
752
|
case PrimitiveKind::Bool: {
|
|
751
753
|
if (!value.IsBoolean()) [[unlikely]] {
|
|
752
754
|
ThrowError<Napi::TypeError>(env, "Unexpected %1 value, expected boolean", GetValueType(instance, value));
|
|
@@ -755,6 +757,7 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
755
757
|
|
|
756
758
|
bool b = value.As<Napi::Boolean>();
|
|
757
759
|
out_reg->eax = (uint32_t)b;
|
|
760
|
+
out_reg->ret_type = 0;
|
|
758
761
|
} break;
|
|
759
762
|
case PrimitiveKind::Int8: { RETURN_INTEGER_32(int8_t); } break;
|
|
760
763
|
case PrimitiveKind::UInt8: { RETURN_INTEGER_32(uint8_t); } break;
|
|
@@ -776,6 +779,7 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
776
779
|
return;
|
|
777
780
|
|
|
778
781
|
out_reg->eax = (uint32_t)str;
|
|
782
|
+
out_reg->ret_type = 0;
|
|
779
783
|
} break;
|
|
780
784
|
case PrimitiveKind::String16: {
|
|
781
785
|
const char16_t *str16;
|
|
@@ -783,6 +787,7 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
783
787
|
return;
|
|
784
788
|
|
|
785
789
|
out_reg->eax = (uint32_t)str16;
|
|
790
|
+
out_reg->ret_type = 0;
|
|
786
791
|
} break;
|
|
787
792
|
case PrimitiveKind::String32: {
|
|
788
793
|
const char32_t *str32;
|
|
@@ -790,6 +795,7 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
790
795
|
return;
|
|
791
796
|
|
|
792
797
|
out_reg->eax = (uint32_t)str32;
|
|
798
|
+
out_reg->ret_type = 0;
|
|
793
799
|
} break;
|
|
794
800
|
case PrimitiveKind::Pointer: {
|
|
795
801
|
uint8_t *ptr;
|
|
@@ -812,6 +818,7 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
812
818
|
}
|
|
813
819
|
|
|
814
820
|
out_reg->eax = (uint32_t)ptr;
|
|
821
|
+
out_reg->ret_type = 0;
|
|
815
822
|
} break;
|
|
816
823
|
case PrimitiveKind::Record:
|
|
817
824
|
case PrimitiveKind::Union: {
|
|
@@ -829,6 +836,8 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
829
836
|
} else {
|
|
830
837
|
PushObject(obj, type, (uint8_t *)&out_reg->eax);
|
|
831
838
|
}
|
|
839
|
+
|
|
840
|
+
out_reg->ret_type = 0;
|
|
832
841
|
} break;
|
|
833
842
|
case PrimitiveKind::Array: { K_UNREACHABLE(); } break;
|
|
834
843
|
case PrimitiveKind::Float32: {
|
|
@@ -838,7 +847,7 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
838
847
|
}
|
|
839
848
|
|
|
840
849
|
out_reg->x87.f = GetNumber<float>(value);
|
|
841
|
-
out_reg->
|
|
850
|
+
out_reg->ret_type = 1;
|
|
842
851
|
} break;
|
|
843
852
|
case PrimitiveKind::Float64: {
|
|
844
853
|
if (!value.IsNumber() && !value.IsBigInt()) [[unlikely]] {
|
|
@@ -847,7 +856,7 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
847
856
|
}
|
|
848
857
|
|
|
849
858
|
out_reg->x87.d = GetNumber<double>(value);
|
|
850
|
-
out_reg->
|
|
859
|
+
out_reg->ret_type = 2;
|
|
851
860
|
} break;
|
|
852
861
|
case PrimitiveKind::Callback: {
|
|
853
862
|
void *ptr;
|
|
@@ -868,6 +877,7 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
868
877
|
}
|
|
869
878
|
|
|
870
879
|
out_reg->eax = (uint32_t)ptr;
|
|
880
|
+
out_reg->ret_type = 0;
|
|
871
881
|
} break;
|
|
872
882
|
|
|
873
883
|
case PrimitiveKind::Prototype: { K_UNREACHABLE(); } break;
|
|
@@ -881,12 +891,6 @@ void CallData::Relay(Size idx, uint8_t *sp)
|
|
|
881
891
|
err_guard.Disable();
|
|
882
892
|
}
|
|
883
893
|
|
|
884
|
-
void *GetTrampoline(int16_t idx, const FunctionInfo *proto)
|
|
885
|
-
{
|
|
886
|
-
bool x87 = IsFloat(proto->ret.type);
|
|
887
|
-
return Trampolines[idx][x87];
|
|
888
|
-
}
|
|
889
|
-
|
|
890
894
|
}
|
|
891
895
|
|
|
892
896
|
#endif
|
|
@@ -91,13 +91,21 @@ ForwardCallRD:
|
|
|
91
91
|
# Depending on ABI, call convention and return value size, we need to issue ret <something>. Since ret
|
|
92
92
|
# only takes an immediate value, and I prefer not to branch, the return address is moved instead according
|
|
93
93
|
# to BackRegisters::ret_pop before ret is issued.
|
|
94
|
+
# We need to branch at the end to avoid x87 stack imbalance.
|
|
94
95
|
.macro trampoline id
|
|
95
96
|
.cfi_startproc
|
|
96
|
-
.cfi_def_cfa esp, 4
|
|
97
97
|
ENDBR32
|
|
98
|
+
movl $\id, %eax
|
|
99
|
+
jmp RelayTrampoline
|
|
100
|
+
.cfi_endproc
|
|
101
|
+
.endm
|
|
102
|
+
|
|
103
|
+
RelayTrampoline:
|
|
104
|
+
.cfi_startproc
|
|
105
|
+
.cfi_def_cfa esp, 4
|
|
98
106
|
sub $44, %esp
|
|
99
107
|
.cfi_def_cfa esp, 48
|
|
100
|
-
movl
|
|
108
|
+
movl %eax, 0(%esp)
|
|
101
109
|
movl %esp, 4(%esp)
|
|
102
110
|
call GetEIP
|
|
103
111
|
addl $_GLOBAL_OFFSET_TABLE_, %ecx
|
|
@@ -105,32 +113,16 @@ ForwardCallRD:
|
|
|
105
113
|
movl 44(%esp), %edx
|
|
106
114
|
movl 36(%esp), %ecx
|
|
107
115
|
movl %edx, 44(%esp, %ecx)
|
|
116
|
+
cmpl $1, 32(%esp)
|
|
117
|
+
je 1f
|
|
118
|
+
cmpl $2, 32(%esp)
|
|
119
|
+
je 2f
|
|
120
|
+
0:
|
|
108
121
|
movl 16(%esp), %eax
|
|
109
122
|
movl 20(%esp), %edx
|
|
110
123
|
leal 44(%esp, %ecx), %esp
|
|
111
124
|
.cfi_def_cfa esp, 4
|
|
112
125
|
ret
|
|
113
|
-
.cfi_endproc
|
|
114
|
-
.endm
|
|
115
|
-
|
|
116
|
-
# This version also loads the x87 stack with the result, if need be.
|
|
117
|
-
# We have to branch to avoid x87 stack imbalance.
|
|
118
|
-
.macro trampoline_vec id
|
|
119
|
-
.cfi_startproc
|
|
120
|
-
.cfi_def_cfa esp, 4
|
|
121
|
-
ENDBR32
|
|
122
|
-
sub $44, %esp
|
|
123
|
-
.cfi_def_cfa esp, 48
|
|
124
|
-
movl $\id, 0(%esp)
|
|
125
|
-
movl %esp, 4(%esp)
|
|
126
|
-
call GetEIP
|
|
127
|
-
addl $_GLOBAL_OFFSET_TABLE_, %ecx
|
|
128
|
-
call *RelayCallback@GOT(%ecx)
|
|
129
|
-
movl 44(%esp), %edx
|
|
130
|
-
movl 36(%esp), %ecx
|
|
131
|
-
movl %edx, 44(%esp, %ecx, 4)
|
|
132
|
-
cmpb $0, 32(%esp)
|
|
133
|
-
jne 2f
|
|
134
126
|
1:
|
|
135
127
|
flds 24(%esp)
|
|
136
128
|
leal 44(%esp, %ecx), %esp
|
|
@@ -142,7 +134,6 @@ ForwardCallRD:
|
|
|
142
134
|
.cfi_def_cfa esp, 4
|
|
143
135
|
ret
|
|
144
136
|
.cfi_endproc
|
|
145
|
-
.endm
|
|
146
137
|
|
|
147
138
|
# When a callback is relayed, Koffi will call into Node.js and V8 to execute Javascript.
|
|
148
139
|
# The problem is that we're still running on the separate Koffi stack, and V8 will
|
|
@@ -90,36 +90,30 @@ extern RelayDirect : PROC
|
|
|
90
90
|
; Depending on ABI, call convention and return value size, we need to issue ret <something>. Since ret
|
|
91
91
|
; only takes an immediate value, and I prefer not to branch, the return address is moved instead according
|
|
92
92
|
; to BackRegisters::ret_pop before ret is issued.
|
|
93
|
+
; We need to branch at the end to avoid x87 stack imbalance.
|
|
93
94
|
trampoline macro ID
|
|
94
95
|
endbr32
|
|
96
|
+
mov eax, ID
|
|
97
|
+
jmp RelayTrampoline
|
|
98
|
+
endm
|
|
99
|
+
|
|
100
|
+
RelayTrampoline proc
|
|
95
101
|
sub esp, 44
|
|
96
|
-
mov dword ptr [esp+0],
|
|
102
|
+
mov dword ptr [esp+0], eax
|
|
97
103
|
mov dword ptr [esp+4], esp
|
|
98
104
|
call RelayCallback
|
|
99
105
|
mov edx, dword ptr [esp+44]
|
|
100
106
|
mov ecx, dword ptr [esp+36]
|
|
101
107
|
mov dword ptr [esp+ecx+44], edx
|
|
108
|
+
cmp dword ptr [esp+32], 1
|
|
109
|
+
je l1
|
|
110
|
+
cmp dword ptr [esp+32], 2
|
|
111
|
+
je l2
|
|
112
|
+
l0:
|
|
102
113
|
mov eax, dword ptr [esp+16]
|
|
103
114
|
mov edx, dword ptr [esp+20]
|
|
104
|
-
lea esp, [esp+ecx+44]
|
|
115
|
+
lea esp, dword ptr [esp+ecx+44]
|
|
105
116
|
ret
|
|
106
|
-
endm
|
|
107
|
-
|
|
108
|
-
; This version also loads the x87 stack with the result, if need be.
|
|
109
|
-
; We have to branch to avoid x87 stack imbalance.
|
|
110
|
-
trampoline_vec macro ID
|
|
111
|
-
local l1, l2, l3
|
|
112
|
-
|
|
113
|
-
endbr32
|
|
114
|
-
sub esp, 44
|
|
115
|
-
mov dword ptr [esp+0], ID
|
|
116
|
-
mov dword ptr [esp+4], esp
|
|
117
|
-
call RelayCallback
|
|
118
|
-
mov edx, dword ptr [esp+44]
|
|
119
|
-
mov ecx, dword ptr [esp+36]
|
|
120
|
-
mov dword ptr [esp+ecx+44], edx
|
|
121
|
-
cmp byte ptr [esp+32], 0
|
|
122
|
-
jne l2
|
|
123
117
|
l1:
|
|
124
118
|
fld dword ptr [esp+24]
|
|
125
119
|
lea esp, dword ptr [esp+ecx+44]
|
|
@@ -128,7 +122,7 @@ l2:
|
|
|
128
122
|
fld qword ptr [esp+24]
|
|
129
123
|
lea esp, dword ptr [esp+ecx+44]
|
|
130
124
|
ret
|
|
131
|
-
|
|
125
|
+
RelayTrampoline endp
|
|
132
126
|
|
|
133
127
|
; When a callback is relayed, Koffi will call into Node.js and V8 to execute Javascript.
|
|
134
128
|
; The problem is that we're still running on the separate Koffi stack, and V8 will
|
package/src/koffi/src/call.cc
CHANGED
|
@@ -21,6 +21,8 @@ struct RelayContext {
|
|
|
21
21
|
bool done = false;
|
|
22
22
|
};
|
|
23
23
|
|
|
24
|
+
#include "trampolines/prototypes.inc"
|
|
25
|
+
|
|
24
26
|
CallData::CallData(Napi::Env env, InstanceData *instance, InstanceMemory *mem)
|
|
25
27
|
: env(env), instance(instance),
|
|
26
28
|
mem(mem), old_stack_mem(mem->stack), old_heap_mem(mem->heap)
|
|
@@ -29,7 +31,6 @@ CallData::CallData(Napi::Env env, InstanceData *instance, InstanceMemory *mem)
|
|
|
29
31
|
mem->depth++;
|
|
30
32
|
|
|
31
33
|
K_ASSERT(AlignUp(mem->stack.ptr, 16) == mem->stack.ptr);
|
|
32
|
-
K_ASSERT(AlignUp(mem->stack.end(), 16) == mem->stack.end());
|
|
33
34
|
}
|
|
34
35
|
|
|
35
36
|
CallData::~CallData()
|
|
@@ -1139,7 +1140,7 @@ void *CallData::ReserveTrampoline(const FunctionInfo *proto, Napi::Function func
|
|
|
1139
1140
|
trampoline->recv.Reset();
|
|
1140
1141
|
trampoline->generation = (int32_t)mem->generation;
|
|
1141
1142
|
|
|
1142
|
-
void *ptr = GetTrampoline(idx
|
|
1143
|
+
void *ptr = GetTrampoline(idx);
|
|
1143
1144
|
|
|
1144
1145
|
return ptr;
|
|
1145
1146
|
}
|
|
@@ -1306,4 +1307,9 @@ void PerformAsyncRelay(napi_env, napi_value, void *, void *udata)
|
|
|
1306
1307
|
ctx->cv.notify_one();
|
|
1307
1308
|
}
|
|
1308
1309
|
|
|
1310
|
+
void *GetTrampoline(int16_t idx)
|
|
1311
|
+
{
|
|
1312
|
+
return Trampolines[idx];
|
|
1313
|
+
}
|
|
1314
|
+
|
|
1309
1315
|
}
|
package/src/koffi/src/call.hh
CHANGED
|
@@ -174,6 +174,6 @@ inline T *CallData::AllocHeap(Size size, Size align)
|
|
|
174
174
|
|
|
175
175
|
void PerformAsyncRelay(napi_env env, napi_value callback, void *ctx, void *udata);
|
|
176
176
|
|
|
177
|
-
void *GetTrampoline(int16_t idx
|
|
177
|
+
void *GetTrampoline(int16_t idx);
|
|
178
178
|
|
|
179
179
|
}
|
package/src/koffi/src/ffi.cc
CHANGED
|
@@ -2013,7 +2013,7 @@ static Napi::Value RegisterCallback(const Napi::CallbackInfo &info)
|
|
|
2013
2013
|
}
|
|
2014
2014
|
trampoline->generation = -1;
|
|
2015
2015
|
|
|
2016
|
-
void *ptr = GetTrampoline(idx
|
|
2016
|
+
void *ptr = GetTrampoline(idx);
|
|
2017
2017
|
|
|
2018
2018
|
Napi::External<void> external = Napi::External<void>::New(env, ptr);
|
|
2019
2019
|
SetValueTag(external, type->ref.marker);
|