koffi 1.1.5 → 1.2.0-alpha.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.
@@ -11,6 +11,9 @@
11
11
  ; You should have received a copy of the GNU Affero General Public License
12
12
  ; along with this program. If not, see https://www.gnu.org/licenses/.
13
13
 
14
+ ; Forward
15
+ ; ----------------------------
16
+
14
17
  ; These three are the same, but they differ (in the C side) by their return type.
15
18
  ; Unlike the three next functions, these ones don't forward XMM argument registers.
16
19
  public ForwardCallG
@@ -25,6 +28,7 @@ public ForwardCallXD
25
28
  .code
26
29
 
27
30
  ; Copy function pointer to RAX, in order to save it through argument forwarding.
31
+ ; Also make a copy of the SP to CallData::old_sp because the callback system might need it.
28
32
  ; Save RSP in RBX (non-volatile), and use carefully assembled stack provided by caller.
29
33
  prologue macro
30
34
  endbr64
@@ -32,6 +36,7 @@ prologue macro
32
36
  push rbx
33
37
  .pushreg rbx
34
38
  mov rbx, rsp
39
+ mov qword ptr [r8+0], rsp
35
40
  .setframe rbx, 0
36
41
  .endprolog
37
42
  mov rsp, rdx
@@ -102,4 +107,214 @@ ForwardCallXD proc frame
102
107
  epilogue
103
108
  ForwardCallXD endp
104
109
 
110
+ ; Callback trampolines
111
+ ; ----------------------------
112
+
113
+ public Trampoline0
114
+ public Trampoline1
115
+ public Trampoline2
116
+ public Trampoline3
117
+ public Trampoline4
118
+ public Trampoline5
119
+ public Trampoline6
120
+ public Trampoline7
121
+ public Trampoline8
122
+ public Trampoline9
123
+ public Trampoline10
124
+ public Trampoline11
125
+ public Trampoline12
126
+ public Trampoline13
127
+ public Trampoline14
128
+ public Trampoline15
129
+ public TrampolineX0
130
+ public TrampolineX1
131
+ public TrampolineX2
132
+ public TrampolineX3
133
+ public TrampolineX4
134
+ public TrampolineX5
135
+ public TrampolineX6
136
+ public TrampolineX7
137
+ public TrampolineX8
138
+ public TrampolineX9
139
+ public TrampolineX10
140
+ public TrampolineX11
141
+ public TrampolineX12
142
+ public TrampolineX13
143
+ public TrampolineX14
144
+ public TrampolineX15
145
+ extern RelayCallBack : PROC
146
+ public CallSwitchStack
147
+
148
+ ; First, make a copy of the GPR argument registers (rcx, rdx, r8, r9).
149
+ ; Then call the C function RelayCallBack with the following arguments:
150
+ ; static trampoline ID, a pointer to the saved GPR array, a pointer to the stack
151
+ ; arguments of this call, and a pointer to a struct that will contain the result registers.
152
+ ; After the call, simply load these registers from the output struct.
153
+ trampoline macro ID
154
+ endbr64
155
+ sub rsp, 120
156
+ .allocstack 120
157
+ .endprolog
158
+ mov qword ptr [rsp+32], rcx
159
+ mov qword ptr [rsp+40], rdx
160
+ mov qword ptr [rsp+48], r8
161
+ mov qword ptr [rsp+56], r9
162
+ mov rcx, ID
163
+ lea rdx, qword ptr [rsp+32]
164
+ lea r8, qword ptr [rsp+128]
165
+ lea r9, qword ptr [rsp+96]
166
+ call RelayCallBack
167
+ mov qword ptr [rsp+96], rax
168
+ add rsp, 120
169
+ ret
170
+ endm
171
+
172
+ ; Same thing, but also forward the XMM argument registers and load the XMM result registers.
173
+ trampoline_xmm macro ID
174
+ endbr64
175
+ sub rsp, 120
176
+ .allocstack 120
177
+ .endprolog
178
+ mov qword ptr [rsp+32], rcx
179
+ mov qword ptr [rsp+40], rdx
180
+ mov qword ptr [rsp+48], r8
181
+ mov qword ptr [rsp+56], r9
182
+ movsd qword ptr [rsp+64], xmm0
183
+ movsd qword ptr [rsp+72], xmm1
184
+ movsd qword ptr [rsp+80], xmm2
185
+ movsd qword ptr [rsp+88], xmm3
186
+ mov rcx, ID
187
+ lea rdx, qword ptr [rsp+32]
188
+ lea r8, qword ptr [rsp+128]
189
+ lea r9, qword ptr [rsp+96]
190
+ call RelayCallBack
191
+ mov qword ptr [rsp+96], rax
192
+ movsd qword ptr [rsp+104], xmm0
193
+ add rsp, 120
194
+ ret
195
+ endm
196
+
197
+ Trampoline0 proc frame
198
+ trampoline 0
199
+ Trampoline0 endp
200
+ Trampoline1 proc frame
201
+ trampoline 1
202
+ Trampoline1 endp
203
+ Trampoline2 proc frame
204
+ trampoline 2
205
+ Trampoline2 endp
206
+ Trampoline3 proc frame
207
+ trampoline 3
208
+ Trampoline3 endp
209
+ Trampoline4 proc frame
210
+ trampoline 4
211
+ Trampoline4 endp
212
+ Trampoline5 proc frame
213
+ trampoline 5
214
+ Trampoline5 endp
215
+ Trampoline6 proc frame
216
+ trampoline 6
217
+ Trampoline6 endp
218
+ Trampoline7 proc frame
219
+ trampoline 7
220
+ Trampoline7 endp
221
+ Trampoline8 proc frame
222
+ trampoline 8
223
+ Trampoline8 endp
224
+ Trampoline9 proc frame
225
+ trampoline 9
226
+ Trampoline9 endp
227
+ Trampoline10 proc frame
228
+ trampoline 10
229
+ Trampoline10 endp
230
+ Trampoline11 proc frame
231
+ trampoline 11
232
+ Trampoline11 endp
233
+ Trampoline12 proc frame
234
+ trampoline 12
235
+ Trampoline12 endp
236
+ Trampoline13 proc frame
237
+ trampoline 13
238
+ Trampoline13 endp
239
+ Trampoline14 proc frame
240
+ trampoline 14
241
+ Trampoline14 endp
242
+ Trampoline15 proc frame
243
+ trampoline 15
244
+ Trampoline15 endp
245
+
246
+ TrampolineX0 proc frame
247
+ trampoline_xmm 0
248
+ TrampolineX0 endp
249
+ TrampolineX1 proc frame
250
+ trampoline_xmm 1
251
+ TrampolineX1 endp
252
+ TrampolineX2 proc frame
253
+ trampoline_xmm 2
254
+ TrampolineX2 endp
255
+ TrampolineX3 proc frame
256
+ trampoline_xmm 3
257
+ TrampolineX3 endp
258
+ TrampolineX4 proc frame
259
+ trampoline_xmm 4
260
+ TrampolineX4 endp
261
+ TrampolineX5 proc frame
262
+ trampoline_xmm 5
263
+ TrampolineX5 endp
264
+ TrampolineX6 proc frame
265
+ trampoline_xmm 6
266
+ TrampolineX6 endp
267
+ TrampolineX7 proc frame
268
+ trampoline_xmm 7
269
+ TrampolineX7 endp
270
+ TrampolineX8 proc frame
271
+ trampoline_xmm 8
272
+ TrampolineX8 endp
273
+ TrampolineX9 proc frame
274
+ trampoline_xmm 9
275
+ TrampolineX9 endp
276
+ TrampolineX10 proc frame
277
+ trampoline_xmm 10
278
+ TrampolineX10 endp
279
+ TrampolineX11 proc frame
280
+ trampoline_xmm 11
281
+ TrampolineX11 endp
282
+ TrampolineX12 proc frame
283
+ trampoline_xmm 12
284
+ TrampolineX12 endp
285
+ TrampolineX13 proc frame
286
+ trampoline_xmm 13
287
+ TrampolineX13 endp
288
+ TrampolineX14 proc frame
289
+ trampoline_xmm 14
290
+ TrampolineX14 endp
291
+ TrampolineX15 proc frame
292
+ trampoline_xmm 15
293
+ TrampolineX15 endp
294
+
295
+ ; When a callback is relayed, Koffi will call into Node.js and V8 to execute Javascript.
296
+ ; The propblem is that we're still running on the separate Koffi stack, and V8 will
297
+ ; preobably misdetect this as a "stack overflow". We have to restore the old
298
+ ; stack pointer, call Node.js/V8 and go back to ours.
299
+ ; The first three parameters (rcx, rdx, r8) are passed through untouched.
300
+ CallSwitchStack proc frame
301
+ endbr64
302
+ push rbx
303
+ .pushreg rbx
304
+ mov rbx, rsp
305
+ .setframe rbx, 0
306
+ .endprolog
307
+ mov rax, qword ptr [rsp+56]
308
+ mov r10, rsp
309
+ mov r11, qword ptr [rsp+48]
310
+ sub r10, qword ptr [r11+0]
311
+ and r10, -16
312
+ mov qword ptr [r11+8], r10
313
+ lea rsp, [r9-32]
314
+ call rax
315
+ mov rsp, rbx
316
+ pop rbx
317
+ ret
318
+ CallSwitchStack endp
319
+
105
320
  end