koffi 2.3.8 → 2.3.10-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/LICENSE.txt +22 -165
- package/README.md +2 -2
- package/{src/koffi/build/2.3.8 → build/2.3.10-beta.1}/koffi_darwin_arm64/koffi.node +0 -0
- package/{src/koffi/build/2.3.8 → build/2.3.10-beta.1}/koffi_darwin_x64/koffi.node +0 -0
- package/build/2.3.10-beta.1/koffi_freebsd_arm64/koffi.node +0 -0
- package/build/2.3.10-beta.1/koffi_freebsd_ia32/koffi.node +0 -0
- package/build/2.3.10-beta.1/koffi_freebsd_x64/koffi.node +0 -0
- package/build/2.3.10-beta.1/koffi_linux_arm32hf/koffi.node +0 -0
- package/build/2.3.10-beta.1/koffi_linux_arm64/koffi.node +0 -0
- package/build/2.3.10-beta.1/koffi_linux_ia32/koffi.node +0 -0
- package/build/2.3.10-beta.1/koffi_linux_riscv64hf64/koffi.node +0 -0
- package/build/2.3.10-beta.1/koffi_linux_x64/koffi.node +0 -0
- package/build/2.3.10-beta.1/koffi_openbsd_ia32/koffi.node +0 -0
- package/build/2.3.10-beta.1/koffi_openbsd_x64/koffi.node +0 -0
- package/{src/koffi/build/2.3.8 → build/2.3.10-beta.1}/koffi_win32_arm64/koffi.node +0 -0
- package/{src/koffi/build/2.3.8 → build/2.3.10-beta.1}/koffi_win32_ia32/koffi.node +0 -0
- package/{src/koffi/build/2.3.8 → build/2.3.10-beta.1}/koffi_win32_x64/koffi.node +0 -0
- package/doc/index.rst +2 -2
- package/doc/static/custom.css +18 -10
- package/package.json +7 -7
- package/src/cnoke/LICENSE.txt +22 -165
- package/src/cnoke/assets/FindCNoke.cmake +18 -10
- package/src/cnoke/assets/win_delay_hook.c +18 -10
- package/src/cnoke/cnoke.js +18 -10
- package/src/cnoke/package.json +1 -1
- package/src/cnoke/src/builder.js +18 -10
- package/src/cnoke/src/index.js +18 -10
- package/src/cnoke/src/tools.js +18 -10
- package/src/core/libcc/libcc.cc +93 -33
- package/src/core/libcc/libcc.hh +31 -14
- package/src/{koffi/src/index.d.ts → index.d.ts} +22 -14
- package/src/index.js +50 -0
- package/src/koffi/CMakeLists.txt +27 -19
- package/src/koffi/src/abi_arm32.cc +19 -11
- package/src/koffi/src/abi_arm32_asm.S +211 -0
- package/src/koffi/src/abi_arm64.cc +19 -11
- package/src/koffi/src/abi_arm64_asm.S +238 -0
- package/src/koffi/src/abi_arm64_asm.asm +207 -0
- package/src/koffi/src/abi_riscv64.cc +19 -11
- package/src/koffi/src/abi_riscv64_asm.S +239 -0
- package/src/koffi/src/abi_x64_sysv.cc +19 -11
- package/src/koffi/src/abi_x64_sysv_asm.S +272 -0
- package/src/koffi/src/abi_x64_win.cc +19 -11
- package/src/koffi/src/abi_x64_win_asm.asm +203 -0
- package/src/koffi/src/abi_x86.cc +19 -11
- package/src/koffi/src/abi_x86_asm.S +213 -0
- package/src/koffi/src/abi_x86_asm.asm +191 -0
- package/src/koffi/src/call.cc +18 -10
- package/src/koffi/src/call.hh +18 -10
- package/src/koffi/src/ffi.cc +18 -10
- package/src/koffi/src/ffi.hh +18 -10
- package/src/koffi/src/parser.cc +18 -10
- package/src/koffi/src/parser.hh +18 -10
- package/src/koffi/src/{abi_arm64_fwd.asm → trampolines/armasm.inc} +18 -193
- package/src/koffi/src/{abi_arm64_fwd.S → trampolines/gnu.inc} +18 -226
- package/src/koffi/src/{abi_x86_fwd.asm → trampolines/masm32.inc} +1042 -1203
- package/src/koffi/src/{abi_x64_win_fwd.asm → trampolines/masm64.inc} +1042 -1215
- package/src/koffi/src/{abi_trampolines.inc → trampolines/prototypes.inc} +18 -10
- package/src/koffi/src/util.cc +18 -10
- package/src/koffi/src/util.hh +18 -10
- package/src/koffi/src/win32.hh +18 -10
- package/src/koffi/build/2.3.8/koffi_freebsd_arm64/koffi.node +0 -0
- package/src/koffi/build/2.3.8/koffi_freebsd_ia32/koffi.node +0 -0
- package/src/koffi/build/2.3.8/koffi_freebsd_x64/koffi.node +0 -0
- package/src/koffi/build/2.3.8/koffi_linux_arm32hf/koffi.node +0 -0
- package/src/koffi/build/2.3.8/koffi_linux_arm64/koffi.node +0 -0
- package/src/koffi/build/2.3.8/koffi_linux_ia32/koffi.node +0 -0
- package/src/koffi/build/2.3.8/koffi_linux_riscv64hf64/koffi.node +0 -0
- package/src/koffi/build/2.3.8/koffi_linux_x64/koffi.node +0 -0
- package/src/koffi/build/2.3.8/koffi_openbsd_ia32/koffi.node +0 -0
- package/src/koffi/build/2.3.8/koffi_openbsd_x64/koffi.node +0 -0
- package/src/koffi/src/abi_arm32_fwd.S +0 -6344
- package/src/koffi/src/abi_riscv64_fwd.S +0 -6375
- package/src/koffi/src/abi_x64_sysv_fwd.S +0 -6410
- package/src/koffi/src/abi_x86_fwd.S +0 -6346
- package/src/koffi/src/index.js +0 -57
- /package/{src/koffi/build/2.3.8 → build/2.3.10-beta.1}/koffi_win32_arm64/koffi.exp +0 -0
- /package/{src/koffi/build/2.3.8 → build/2.3.10-beta.1}/koffi_win32_arm64/koffi.lib +0 -0
- /package/{src/koffi/build/2.3.8 → build/2.3.10-beta.1}/koffi_win32_ia32/koffi.exp +0 -0
- /package/{src/koffi/build/2.3.8 → build/2.3.10-beta.1}/koffi_win32_ia32/koffi.lib +0 -0
- /package/{src/koffi/build/2.3.8 → build/2.3.10-beta.1}/koffi_win32_x64/koffi.exp +0 -0
- /package/{src/koffi/build/2.3.8 → build/2.3.10-beta.1}/koffi_win32_x64/koffi.lib +0 -0
|
@@ -1,15 +1,23 @@
|
|
|
1
|
-
//
|
|
2
|
-
// it under the terms of the GNU Lesser 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.
|
|
1
|
+
// Copyright 2023 Niels Martignène <niels.martignene@protonmail.com>
|
|
5
2
|
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
3
|
+
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
4
|
+
// this software and associated documentation files (the “Software”), to deal in
|
|
5
|
+
// the Software without restriction, including without limitation the rights to use,
|
|
6
|
+
// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
|
7
|
+
// Software, and to permit persons to whom the Software is furnished to do so,
|
|
8
|
+
// subject to the following conditions:
|
|
10
9
|
//
|
|
11
|
-
//
|
|
12
|
-
//
|
|
10
|
+
// The above copyright notice and this permission notice shall be included in all
|
|
11
|
+
// copies or substantial portions of the Software.
|
|
12
|
+
//
|
|
13
|
+
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
|
|
14
|
+
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
15
|
+
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
16
|
+
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
17
|
+
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
18
|
+
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
19
|
+
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
20
|
+
// OTHER DEALINGS IN THE SOFTWARE.
|
|
13
21
|
|
|
14
22
|
#if __riscv_xlen == 64
|
|
15
23
|
|
|
@@ -62,7 +70,7 @@ extern "C" napi_value CallSwitchStack(Napi::Function *func, size_t argc, napi_va
|
|
|
62
70
|
uint8_t *old_sp, Span<uint8_t> *new_stack,
|
|
63
71
|
napi_value (*call)(Napi::Function *func, size_t argc, napi_value *argv));
|
|
64
72
|
|
|
65
|
-
#include "
|
|
73
|
+
#include "trampolines/prototypes.inc"
|
|
66
74
|
|
|
67
75
|
static inline void ExpandPair(const uint8_t raw[16], int size1, int size2, uint64_t out_regs[2])
|
|
68
76
|
{
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
# Copyright 2023 Niels Martignène <niels.martignene@protonmail.com>
|
|
2
|
+
#
|
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
4
|
+
# this software and associated documentation files (the “Software”), to deal in
|
|
5
|
+
# the Software without restriction, including without limitation the rights to use,
|
|
6
|
+
# copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
|
7
|
+
# Software, and to permit persons to whom the Software is furnished to do so,
|
|
8
|
+
# subject to the following conditions:
|
|
9
|
+
#
|
|
10
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
11
|
+
# copies or substantial portions of the Software.
|
|
12
|
+
#
|
|
13
|
+
# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
|
|
14
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
15
|
+
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
16
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
17
|
+
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
18
|
+
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
19
|
+
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
20
|
+
# OTHER DEALINGS IN THE SOFTWARE.
|
|
21
|
+
|
|
22
|
+
#define SYMBOL(Symbol) Symbol
|
|
23
|
+
|
|
24
|
+
# Forward
|
|
25
|
+
# ----------------------------
|
|
26
|
+
|
|
27
|
+
# These three are the same, but they differ (in the C side) by their return type.
|
|
28
|
+
# Unlike the three next functions, these ones don't forward FA argument registers.
|
|
29
|
+
.global ForwardCallGG
|
|
30
|
+
.global ForwardCallF
|
|
31
|
+
.global ForwardCallDG
|
|
32
|
+
.global ForwardCallGD
|
|
33
|
+
.global ForwardCallDD
|
|
34
|
+
|
|
35
|
+
# The X variants are slightly slower, and are used when FA arguments must be forwarded.
|
|
36
|
+
.global ForwardCallXGG
|
|
37
|
+
.global ForwardCallXF
|
|
38
|
+
.global ForwardCallXDG
|
|
39
|
+
.global ForwardCallXGD
|
|
40
|
+
.global ForwardCallXDD
|
|
41
|
+
|
|
42
|
+
# Copy function pointer to t0, in order to save it through argument forwarding.
|
|
43
|
+
# Also make a copy of the SP to CallData::old_sp because the callback system might need it.
|
|
44
|
+
# Save SP in s1, and use carefully assembled stack provided by caller.
|
|
45
|
+
.macro prologue
|
|
46
|
+
addi sp, sp, -16
|
|
47
|
+
mv t0, a0
|
|
48
|
+
sd ra, 0(sp)
|
|
49
|
+
sd s1, 8(sp)
|
|
50
|
+
mv s1, sp
|
|
51
|
+
sd sp, 0(a2)
|
|
52
|
+
addi sp, a1, 128
|
|
53
|
+
.endm
|
|
54
|
+
|
|
55
|
+
# Call native function.
|
|
56
|
+
# Once done, restore normal stack pointer and return.
|
|
57
|
+
# The return value is passed untouched through registers.
|
|
58
|
+
.macro epilogue
|
|
59
|
+
jalr t0
|
|
60
|
+
mv sp, s1
|
|
61
|
+
ld ra, 0(sp)
|
|
62
|
+
ld s1, 8(sp)
|
|
63
|
+
addi sp, sp, 16
|
|
64
|
+
ret
|
|
65
|
+
.endm
|
|
66
|
+
|
|
67
|
+
# Prepare general purpose argument registers from array passed by caller.
|
|
68
|
+
.macro forward_gpr
|
|
69
|
+
ld a7, 120(a1)
|
|
70
|
+
ld a6, 112(a1)
|
|
71
|
+
ld a5, 104(a1)
|
|
72
|
+
ld a4, 96(a1)
|
|
73
|
+
ld a3, 88(a1)
|
|
74
|
+
ld a2, 80(a1)
|
|
75
|
+
ld a0, 64(a1)
|
|
76
|
+
ld a1, 72(a1)
|
|
77
|
+
.endm
|
|
78
|
+
|
|
79
|
+
# Prepare vector argument registers from array passed by caller.
|
|
80
|
+
.macro forward_vec
|
|
81
|
+
fld fa7, 56(a1)
|
|
82
|
+
fld fa6, 48(a1)
|
|
83
|
+
fld fa5, 40(a1)
|
|
84
|
+
fld fa4, 32(a1)
|
|
85
|
+
fld fa3, 24(a1)
|
|
86
|
+
fld fa2, 16(a1)
|
|
87
|
+
fld fa1, 8(a1)
|
|
88
|
+
fld fa0, 0(a1)
|
|
89
|
+
.endm
|
|
90
|
+
|
|
91
|
+
ForwardCallGG:
|
|
92
|
+
prologue
|
|
93
|
+
forward_gpr
|
|
94
|
+
epilogue
|
|
95
|
+
|
|
96
|
+
ForwardCallF:
|
|
97
|
+
prologue
|
|
98
|
+
forward_gpr
|
|
99
|
+
epilogue
|
|
100
|
+
|
|
101
|
+
ForwardCallDG:
|
|
102
|
+
prologue
|
|
103
|
+
forward_gpr
|
|
104
|
+
epilogue
|
|
105
|
+
|
|
106
|
+
ForwardCallGD:
|
|
107
|
+
prologue
|
|
108
|
+
forward_gpr
|
|
109
|
+
epilogue
|
|
110
|
+
|
|
111
|
+
ForwardCallDD:
|
|
112
|
+
prologue
|
|
113
|
+
forward_gpr
|
|
114
|
+
epilogue
|
|
115
|
+
|
|
116
|
+
ForwardCallXGG:
|
|
117
|
+
prologue
|
|
118
|
+
forward_vec
|
|
119
|
+
forward_gpr
|
|
120
|
+
epilogue
|
|
121
|
+
|
|
122
|
+
ForwardCallXF:
|
|
123
|
+
prologue
|
|
124
|
+
forward_vec
|
|
125
|
+
forward_gpr
|
|
126
|
+
epilogue
|
|
127
|
+
|
|
128
|
+
ForwardCallXDG:
|
|
129
|
+
prologue
|
|
130
|
+
forward_vec
|
|
131
|
+
forward_gpr
|
|
132
|
+
epilogue
|
|
133
|
+
|
|
134
|
+
ForwardCallXGD:
|
|
135
|
+
prologue
|
|
136
|
+
forward_vec
|
|
137
|
+
forward_gpr
|
|
138
|
+
epilogue
|
|
139
|
+
|
|
140
|
+
ForwardCallXDD:
|
|
141
|
+
prologue
|
|
142
|
+
forward_vec
|
|
143
|
+
forward_gpr
|
|
144
|
+
epilogue
|
|
145
|
+
|
|
146
|
+
# Callbacks
|
|
147
|
+
# ----------------------------
|
|
148
|
+
|
|
149
|
+
.global RelayCallback
|
|
150
|
+
.global CallSwitchStack
|
|
151
|
+
|
|
152
|
+
# First, make a copy of the GPR argument registers (a0 to a7).
|
|
153
|
+
# Then call the C function RelayCallback with the following arguments:
|
|
154
|
+
# static trampoline ID, a pointer to the saved GPR array, a pointer to the stack
|
|
155
|
+
# arguments of this call, and a pointer to a struct that will contain the result registers.
|
|
156
|
+
# After the call, simply load these registers from the output struct.
|
|
157
|
+
.macro trampoline id
|
|
158
|
+
addi sp, sp, -176
|
|
159
|
+
sd ra, 0(sp)
|
|
160
|
+
sd a0, 8(sp)
|
|
161
|
+
sd a1, 16(sp)
|
|
162
|
+
sd a2, 24(sp)
|
|
163
|
+
sd a3, 32(sp)
|
|
164
|
+
sd a4, 40(sp)
|
|
165
|
+
sd a5, 48(sp)
|
|
166
|
+
sd a6, 56(sp)
|
|
167
|
+
sd a7, 64(sp)
|
|
168
|
+
li a0, \id
|
|
169
|
+
addi a1, sp, 8
|
|
170
|
+
addi a2, sp, 176
|
|
171
|
+
addi a3, sp, 136
|
|
172
|
+
jal RelayCallback
|
|
173
|
+
ld ra, 0(sp)
|
|
174
|
+
ld a0, 136(sp)
|
|
175
|
+
ld a1, 144(sp)
|
|
176
|
+
addi sp, sp, 176
|
|
177
|
+
ret
|
|
178
|
+
.endm
|
|
179
|
+
|
|
180
|
+
# Same thing, but also forwards the floating-point argument registers and loads them at the end.
|
|
181
|
+
.macro trampoline_vec id
|
|
182
|
+
addi sp, sp, -176
|
|
183
|
+
sd ra, 0(sp)
|
|
184
|
+
sd a0, 8(sp)
|
|
185
|
+
sd a1, 16(sp)
|
|
186
|
+
sd a2, 24(sp)
|
|
187
|
+
sd a3, 32(sp)
|
|
188
|
+
sd a4, 40(sp)
|
|
189
|
+
sd a5, 48(sp)
|
|
190
|
+
sd a6, 56(sp)
|
|
191
|
+
sd a7, 64(sp)
|
|
192
|
+
fsd fa0, 72(sp)
|
|
193
|
+
fsd fa1, 80(sp)
|
|
194
|
+
fsd fa2, 88(sp)
|
|
195
|
+
fsd fa3, 96(sp)
|
|
196
|
+
fsd fa4, 104(sp)
|
|
197
|
+
fsd fa5, 112(sp)
|
|
198
|
+
fsd fa6, 120(sp)
|
|
199
|
+
fsd fa7, 128(sp)
|
|
200
|
+
li a0, \id
|
|
201
|
+
addi a1, sp, 8
|
|
202
|
+
addi a2, sp, 176
|
|
203
|
+
addi a3, sp, 136
|
|
204
|
+
jal RelayCallback
|
|
205
|
+
ld ra, 0(sp)
|
|
206
|
+
ld a0, 136(sp)
|
|
207
|
+
ld a1, 144(sp)
|
|
208
|
+
fld fa0, 152(sp)
|
|
209
|
+
fld fa1, 160(sp)
|
|
210
|
+
addi sp, sp, 176
|
|
211
|
+
ret
|
|
212
|
+
.endm
|
|
213
|
+
|
|
214
|
+
# When a callback is relayed, Koffi will call into Node.js and V8 to execute Javascript.
|
|
215
|
+
# The problem is that we're still running on the separate Koffi stack, and V8 will
|
|
216
|
+
# probably misdetect this as a "stack overflow". We have to restore the old
|
|
217
|
+
# stack pointer, call Node.js/V8 and go back to ours.
|
|
218
|
+
# The first three parameters (a0, a1, a2) are passed through untouched.
|
|
219
|
+
CallSwitchStack:
|
|
220
|
+
addi sp, sp, -16
|
|
221
|
+
sd ra, 0(sp)
|
|
222
|
+
sd s1, 8(sp)
|
|
223
|
+
mv s1, sp
|
|
224
|
+
ld t0, 0(a4)
|
|
225
|
+
sub t0, sp, t0
|
|
226
|
+
andi t0, t0, -16
|
|
227
|
+
sd t0, 8(a4)
|
|
228
|
+
mv sp, a3
|
|
229
|
+
jalr a5
|
|
230
|
+
mv sp, s1
|
|
231
|
+
ld ra, 0(sp)
|
|
232
|
+
ld s1, 8(sp)
|
|
233
|
+
addi sp, sp, 16
|
|
234
|
+
ret
|
|
235
|
+
|
|
236
|
+
# Trampolines
|
|
237
|
+
# ----------------------------
|
|
238
|
+
|
|
239
|
+
#include "trampolines/gnu.inc"
|
|
@@ -1,15 +1,23 @@
|
|
|
1
|
-
//
|
|
2
|
-
// it under the terms of the GNU Lesser 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.
|
|
1
|
+
// Copyright 2023 Niels Martignène <niels.martignene@protonmail.com>
|
|
5
2
|
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
3
|
+
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
4
|
+
// this software and associated documentation files (the “Software”), to deal in
|
|
5
|
+
// the Software without restriction, including without limitation the rights to use,
|
|
6
|
+
// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
|
7
|
+
// Software, and to permit persons to whom the Software is furnished to do so,
|
|
8
|
+
// subject to the following conditions:
|
|
10
9
|
//
|
|
11
|
-
//
|
|
12
|
-
//
|
|
10
|
+
// The above copyright notice and this permission notice shall be included in all
|
|
11
|
+
// copies or substantial portions of the Software.
|
|
12
|
+
//
|
|
13
|
+
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
|
|
14
|
+
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
15
|
+
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
16
|
+
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
17
|
+
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
18
|
+
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
19
|
+
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
20
|
+
// OTHER DEALINGS IN THE SOFTWARE.
|
|
13
21
|
|
|
14
22
|
#if defined(__x86_64__) && !defined(_WIN32)
|
|
15
23
|
|
|
@@ -69,7 +77,7 @@ extern "C" napi_value CallSwitchStack(Napi::Function *func, size_t argc, napi_va
|
|
|
69
77
|
uint8_t *old_sp, Span<uint8_t> *new_stack,
|
|
70
78
|
napi_value (*call)(Napi::Function *func, size_t argc, napi_value *argv));
|
|
71
79
|
|
|
72
|
-
#include "
|
|
80
|
+
#include "trampolines/prototypes.inc"
|
|
73
81
|
|
|
74
82
|
static inline RegisterClass MergeClasses(RegisterClass cls1, RegisterClass cls2)
|
|
75
83
|
{
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
# Copyright 2023 Niels Martignène <niels.martignene@protonmail.com>
|
|
2
|
+
#
|
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
4
|
+
# this software and associated documentation files (the “Software”), to deal in
|
|
5
|
+
# the Software without restriction, including without limitation the rights to use,
|
|
6
|
+
# copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
|
7
|
+
# Software, and to permit persons to whom the Software is furnished to do so,
|
|
8
|
+
# subject to the following conditions:
|
|
9
|
+
#
|
|
10
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
11
|
+
# copies or substantial portions of the Software.
|
|
12
|
+
#
|
|
13
|
+
# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
|
|
14
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
15
|
+
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
16
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
17
|
+
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
18
|
+
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
19
|
+
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
20
|
+
# OTHER DEALINGS IN THE SOFTWARE.
|
|
21
|
+
|
|
22
|
+
#ifdef __APPLE__
|
|
23
|
+
#define SYMBOL(Symbol) _ ## Symbol
|
|
24
|
+
#else
|
|
25
|
+
#define SYMBOL(Symbol) Symbol
|
|
26
|
+
#endif
|
|
27
|
+
|
|
28
|
+
# Forward
|
|
29
|
+
# ----------------------------
|
|
30
|
+
|
|
31
|
+
# These five are the same, but they differ (in the C side) by their return type.
|
|
32
|
+
# Unlike the five next functions, these ones don't forward XMM argument registers.
|
|
33
|
+
.global SYMBOL(ForwardCallGG)
|
|
34
|
+
.global SYMBOL(ForwardCallF)
|
|
35
|
+
.global SYMBOL(ForwardCallDG)
|
|
36
|
+
.global SYMBOL(ForwardCallGD)
|
|
37
|
+
.global SYMBOL(ForwardCallDD)
|
|
38
|
+
|
|
39
|
+
# The X variants are slightly slower, and are used when XMM arguments must be forwarded.
|
|
40
|
+
.global SYMBOL(ForwardCallXGG)
|
|
41
|
+
.global SYMBOL(ForwardCallXF)
|
|
42
|
+
.global SYMBOL(ForwardCallXDG)
|
|
43
|
+
.global SYMBOL(ForwardCallXGD)
|
|
44
|
+
.global SYMBOL(ForwardCallXDD)
|
|
45
|
+
|
|
46
|
+
#define ENDBR64 .byte 0xf3, 0x0f, 0x1e, 0xfa
|
|
47
|
+
|
|
48
|
+
# Copy function pointer to R11, in order to save it through argument forwarding.
|
|
49
|
+
# Also make a copy of the SP to CallData::old_sp because the callback system might need it.
|
|
50
|
+
# Save RSP in RBX (non-volatile), and use carefully assembled stack provided by caller.
|
|
51
|
+
.macro prologue
|
|
52
|
+
.cfi_startproc
|
|
53
|
+
.cfi_def_cfa rsp, 8
|
|
54
|
+
ENDBR64
|
|
55
|
+
movq %rdi, %r11
|
|
56
|
+
pushq %rbp
|
|
57
|
+
.cfi_def_cfa rsp, 16
|
|
58
|
+
movq %rsp, (%rdx)
|
|
59
|
+
movq %rsp, %rbp
|
|
60
|
+
.cfi_def_cfa rbp, 16
|
|
61
|
+
leaq 112(%rsi), %rsp
|
|
62
|
+
.endm
|
|
63
|
+
|
|
64
|
+
# Call native function.
|
|
65
|
+
# Once done, restore normal stack pointer and return.
|
|
66
|
+
# The return value is passed untouched through RAX or XMM0.
|
|
67
|
+
.macro epilogue
|
|
68
|
+
call *%r11
|
|
69
|
+
movq %rbp, %rsp
|
|
70
|
+
popq %rbp
|
|
71
|
+
.cfi_def_cfa rsp, 8
|
|
72
|
+
ret
|
|
73
|
+
.cfi_endproc
|
|
74
|
+
.endm
|
|
75
|
+
|
|
76
|
+
# Prepare integer argument registers from array passed by caller.
|
|
77
|
+
.macro forward_gpr
|
|
78
|
+
movq 40(%rsi), %r9
|
|
79
|
+
movq 32(%rsi), %r8
|
|
80
|
+
movq 24(%rsi), %rcx
|
|
81
|
+
movq 16(%rsi), %rdx
|
|
82
|
+
movq 0(%rsi), %rdi
|
|
83
|
+
movq 8(%rsi), %rsi
|
|
84
|
+
.endm
|
|
85
|
+
|
|
86
|
+
# Prepare XMM argument registers from array passed by caller.
|
|
87
|
+
.macro forward_xmm
|
|
88
|
+
movsd 104(%rsi), %xmm7
|
|
89
|
+
movsd 96(%rsi), %xmm6
|
|
90
|
+
movsd 88(%rsi), %xmm5
|
|
91
|
+
movsd 80(%rsi), %xmm4
|
|
92
|
+
movsd 72(%rsi), %xmm3
|
|
93
|
+
movsd 64(%rsi), %xmm2
|
|
94
|
+
movsd 56(%rsi), %xmm1
|
|
95
|
+
movsd 48(%rsi), %xmm0
|
|
96
|
+
.endm
|
|
97
|
+
|
|
98
|
+
SYMBOL(ForwardCallGG):
|
|
99
|
+
prologue
|
|
100
|
+
forward_gpr
|
|
101
|
+
movb $0, %al
|
|
102
|
+
epilogue
|
|
103
|
+
|
|
104
|
+
SYMBOL(ForwardCallF):
|
|
105
|
+
prologue
|
|
106
|
+
forward_gpr
|
|
107
|
+
movb $0, %al
|
|
108
|
+
epilogue
|
|
109
|
+
|
|
110
|
+
SYMBOL(ForwardCallDG):
|
|
111
|
+
prologue
|
|
112
|
+
forward_gpr
|
|
113
|
+
movb $0, %al
|
|
114
|
+
epilogue
|
|
115
|
+
|
|
116
|
+
SYMBOL(ForwardCallGD):
|
|
117
|
+
prologue
|
|
118
|
+
forward_gpr
|
|
119
|
+
movb $0, %al
|
|
120
|
+
epilogue
|
|
121
|
+
|
|
122
|
+
SYMBOL(ForwardCallDD):
|
|
123
|
+
prologue
|
|
124
|
+
forward_gpr
|
|
125
|
+
movb $0, %al
|
|
126
|
+
epilogue
|
|
127
|
+
|
|
128
|
+
SYMBOL(ForwardCallXGG):
|
|
129
|
+
prologue
|
|
130
|
+
forward_xmm
|
|
131
|
+
forward_gpr
|
|
132
|
+
movb $8, %al
|
|
133
|
+
epilogue
|
|
134
|
+
|
|
135
|
+
SYMBOL(ForwardCallXF):
|
|
136
|
+
prologue
|
|
137
|
+
forward_xmm
|
|
138
|
+
forward_gpr
|
|
139
|
+
movb $8, %al
|
|
140
|
+
epilogue
|
|
141
|
+
|
|
142
|
+
SYMBOL(ForwardCallXDG):
|
|
143
|
+
prologue
|
|
144
|
+
forward_xmm
|
|
145
|
+
forward_gpr
|
|
146
|
+
movb $8, %al
|
|
147
|
+
epilogue
|
|
148
|
+
|
|
149
|
+
SYMBOL(ForwardCallXGD):
|
|
150
|
+
prologue
|
|
151
|
+
forward_xmm
|
|
152
|
+
forward_gpr
|
|
153
|
+
movb $8, %al
|
|
154
|
+
epilogue
|
|
155
|
+
|
|
156
|
+
SYMBOL(ForwardCallXDD):
|
|
157
|
+
prologue
|
|
158
|
+
forward_xmm
|
|
159
|
+
forward_gpr
|
|
160
|
+
movb $8, %al
|
|
161
|
+
epilogue
|
|
162
|
+
|
|
163
|
+
# Callbacks
|
|
164
|
+
# ----------------------------
|
|
165
|
+
|
|
166
|
+
.global SYMBOL(RelayCallback)
|
|
167
|
+
.global SYMBOL(CallSwitchStack)
|
|
168
|
+
|
|
169
|
+
# First, make a copy of the GPR argument registers (rdi, rsi, rdx, rcx, r8, r9).
|
|
170
|
+
# Then call the C function RelayCallback with the following arguments:
|
|
171
|
+
# static trampoline ID, a pointer to the saved GPR array, a pointer to the stack
|
|
172
|
+
# arguments of this call, and a pointer to a struct that will contain the result registers.
|
|
173
|
+
# After the call, simply load these registers from the output struct.
|
|
174
|
+
.macro trampoline id
|
|
175
|
+
.cfi_startproc
|
|
176
|
+
.cfi_def_cfa rsp, 8
|
|
177
|
+
ENDBR64
|
|
178
|
+
subq $152, %rsp
|
|
179
|
+
.cfi_def_cfa rsp, 160
|
|
180
|
+
movq %rdi, 0(%rsp)
|
|
181
|
+
movq %rsi, 8(%rsp)
|
|
182
|
+
movq %rdx, 16(%rsp)
|
|
183
|
+
movq %rcx, 24(%rsp)
|
|
184
|
+
movq %r8, 32(%rsp)
|
|
185
|
+
movq %r9, 40(%rsp)
|
|
186
|
+
movq $\id, %rdi
|
|
187
|
+
movq %rsp, %rsi
|
|
188
|
+
leaq 160(%rsp), %rdx
|
|
189
|
+
leaq 112(%rsp), %rcx
|
|
190
|
+
#ifdef __linux__
|
|
191
|
+
call *RelayCallback@GOTPCREL(%rip)
|
|
192
|
+
#else
|
|
193
|
+
call SYMBOL(RelayCallback)
|
|
194
|
+
#endif
|
|
195
|
+
movq 112(%rsp), %rax
|
|
196
|
+
movq 120(%rsp), %rdx
|
|
197
|
+
addq $152, %rsp
|
|
198
|
+
.cfi_def_cfa rsp, 8
|
|
199
|
+
ret
|
|
200
|
+
.cfi_endproc
|
|
201
|
+
.endm
|
|
202
|
+
|
|
203
|
+
# Same thing, but also forward the XMM argument registers and load the XMM result registers.
|
|
204
|
+
.macro trampoline_vec id
|
|
205
|
+
.cfi_startproc
|
|
206
|
+
.cfi_def_cfa rsp, 8
|
|
207
|
+
ENDBR64
|
|
208
|
+
subq $152, %rsp
|
|
209
|
+
.cfi_def_cfa rsp, 160
|
|
210
|
+
movq %rdi, 0(%rsp)
|
|
211
|
+
movq %rsi, 8(%rsp)
|
|
212
|
+
movq %rdx, 16(%rsp)
|
|
213
|
+
movq %rcx, 24(%rsp)
|
|
214
|
+
movq %r8, 32(%rsp)
|
|
215
|
+
movq %r9, 40(%rsp)
|
|
216
|
+
movsd %xmm0, 48(%rsp)
|
|
217
|
+
movsd %xmm1, 56(%rsp)
|
|
218
|
+
movsd %xmm2, 64(%rsp)
|
|
219
|
+
movsd %xmm3, 72(%rsp)
|
|
220
|
+
movsd %xmm4, 80(%rsp)
|
|
221
|
+
movsd %xmm5, 88(%rsp)
|
|
222
|
+
movsd %xmm6, 96(%rsp)
|
|
223
|
+
movsd %xmm7, 104(%rsp)
|
|
224
|
+
movq $\id, %rdi
|
|
225
|
+
movq %rsp, %rsi
|
|
226
|
+
leaq 160(%rsp), %rdx
|
|
227
|
+
leaq 112(%rsp), %rcx
|
|
228
|
+
#ifdef __linux__
|
|
229
|
+
call *RelayCallback@GOTPCREL(%rip)
|
|
230
|
+
#else
|
|
231
|
+
call SYMBOL(RelayCallback)
|
|
232
|
+
#endif
|
|
233
|
+
movq 112(%rsp), %rax
|
|
234
|
+
movq 120(%rsp), %rdx
|
|
235
|
+
movsd 128(%rsp), %xmm0
|
|
236
|
+
movsd 136(%rsp), %xmm1
|
|
237
|
+
addq $152, %rsp
|
|
238
|
+
.cfi_def_cfa rsp, 8
|
|
239
|
+
ret
|
|
240
|
+
.cfi_endproc
|
|
241
|
+
.endm
|
|
242
|
+
|
|
243
|
+
# When a callback is relayed, Koffi will call into Node.js and V8 to execute Javascript.
|
|
244
|
+
# The problem is that we're still running on the separate Koffi stack, and V8 will
|
|
245
|
+
# probably misdetect this as a "stack overflow". We have to restore the old
|
|
246
|
+
# stack pointer, call Node.js/V8 and go back to ours.
|
|
247
|
+
# The first three parameters (rdi, rsi, rdx) are passed through untouched.
|
|
248
|
+
SYMBOL(CallSwitchStack):
|
|
249
|
+
.cfi_startproc
|
|
250
|
+
.cfi_def_cfa rsp, 8
|
|
251
|
+
ENDBR64
|
|
252
|
+
push %rbp
|
|
253
|
+
.cfi_def_cfa rsp, 16
|
|
254
|
+
movq %rsp, %rbp
|
|
255
|
+
movq %rsp, %r10
|
|
256
|
+
subq 0(%r8), %r10
|
|
257
|
+
andq $-16, %r10
|
|
258
|
+
movq %r10, 8(%r8)
|
|
259
|
+
movq %rcx, %rsp
|
|
260
|
+
.cfi_def_cfa rsp, 16
|
|
261
|
+
call *%r9
|
|
262
|
+
mov %rbp, %rsp
|
|
263
|
+
.cfi_def_cfa rsp, 16
|
|
264
|
+
pop %rbp
|
|
265
|
+
.cfi_def_cfa rsp, 8
|
|
266
|
+
ret
|
|
267
|
+
.cfi_endproc
|
|
268
|
+
|
|
269
|
+
# Trampolines
|
|
270
|
+
# ----------------------------
|
|
271
|
+
|
|
272
|
+
#include "trampolines/gnu.inc"
|
|
@@ -1,15 +1,23 @@
|
|
|
1
|
-
//
|
|
2
|
-
// it under the terms of the GNU Lesser 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.
|
|
1
|
+
// Copyright 2023 Niels Martignène <niels.martignene@protonmail.com>
|
|
5
2
|
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
3
|
+
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
4
|
+
// this software and associated documentation files (the “Software”), to deal in
|
|
5
|
+
// the Software without restriction, including without limitation the rights to use,
|
|
6
|
+
// copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
|
7
|
+
// Software, and to permit persons to whom the Software is furnished to do so,
|
|
8
|
+
// subject to the following conditions:
|
|
10
9
|
//
|
|
11
|
-
//
|
|
12
|
-
//
|
|
10
|
+
// The above copyright notice and this permission notice shall be included in all
|
|
11
|
+
// copies or substantial portions of the Software.
|
|
12
|
+
//
|
|
13
|
+
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
|
|
14
|
+
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
15
|
+
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
16
|
+
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
17
|
+
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
18
|
+
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
19
|
+
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
20
|
+
// OTHER DEALINGS IN THE SOFTWARE.
|
|
13
21
|
|
|
14
22
|
#if defined(_WIN32) && (defined(__x86_64__) || defined(_M_AMD64))
|
|
15
23
|
|
|
@@ -39,7 +47,7 @@ extern "C" napi_value CallSwitchStack(Napi::Function *func, size_t argc, napi_va
|
|
|
39
47
|
uint8_t *old_sp, Span<uint8_t> *new_stack,
|
|
40
48
|
napi_value (*call)(Napi::Function *func, size_t argc, napi_value *argv));
|
|
41
49
|
|
|
42
|
-
#include "
|
|
50
|
+
#include "trampolines/prototypes.inc"
|
|
43
51
|
|
|
44
52
|
bool AnalyseFunction(Napi::Env, InstanceData *, FunctionInfo *func)
|
|
45
53
|
{
|