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.
@@ -1,15 +1,15 @@
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/.
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
13
 
14
14
  #ifdef __APPLE__
15
15
  #define SYMBOL(Symbol) _ ## Symbol
@@ -17,25 +17,27 @@
17
17
  #define SYMBOL(Symbol) Symbol
18
18
  #endif
19
19
 
20
- // Forward
20
+ # Forward
21
+ # ----------------------------
21
22
 
22
- // These five are the same, but they differ (in the C side) by their return type.
23
- // Unlike the five next functions, these ones don't forward XMM argument registers.
23
+ # These five are the same, but they differ (in the C side) by their return type.
24
+ # Unlike the five next functions, these ones don't forward XMM argument registers.
24
25
  .global SYMBOL(ForwardCallGG)
25
26
  .global SYMBOL(ForwardCallF)
26
27
  .global SYMBOL(ForwardCallDG)
27
28
  .global SYMBOL(ForwardCallGD)
28
29
  .global SYMBOL(ForwardCallDD)
29
30
 
30
- // The X variants are slightly slower, and are used when XMM arguments must be forwarded.
31
+ # The X variants are slightly slower, and are used when XMM arguments must be forwarded.
31
32
  .global SYMBOL(ForwardCallXGG)
32
33
  .global SYMBOL(ForwardCallXF)
33
34
  .global SYMBOL(ForwardCallXDG)
34
35
  .global SYMBOL(ForwardCallXGD)
35
36
  .global SYMBOL(ForwardCallXDD)
36
37
 
37
- // Copy function pointer to R11, in order to save it through argument forwarding.
38
- // Save RSP in RBX (non-volatile), and use carefully assembled stack provided by caller.
38
+ # Copy function pointer to R11, in order to save it through argument forwarding.
39
+ # Also make a copy of the SP to CallData::old_sp because the callback system might need it.
40
+ # Save RSP in RBX (non-volatile), and use carefully assembled stack provided by caller.
39
41
  .macro prologue
40
42
  .cfi_startproc
41
43
  .cfi_def_cfa rsp, 8
@@ -43,14 +45,15 @@
43
45
  movq %rdi, %r11
44
46
  pushq %rbx
45
47
  .cfi_def_cfa rsp, 16
48
+ movq %rsp, (%rdx)
46
49
  movq %rsp, %rbx
47
50
  .cfi_def_cfa rbx, 16
48
51
  leaq 112(%rsi), %rsp
49
52
  .endm
50
53
 
51
- // Call native function.
52
- // Once done, restore normal stack pointer and return.
53
- // The return value is passed untouched through RAX or XMM0.
54
+ # Call native function.
55
+ # Once done, restore normal stack pointer and return.
56
+ # The return value is passed untouched through RAX or XMM0.
54
57
  .macro epilogue
55
58
  call *%r11
56
59
  movq %rbx, %rsp
@@ -60,7 +63,7 @@
60
63
  .cfi_endproc
61
64
  .endm
62
65
 
63
- // Prepare integer argument registers from array passed by caller.
66
+ # Prepare integer argument registers from array passed by caller.
64
67
  .macro forward_int
65
68
  movq 40(%rsi), %r9
66
69
  movq 32(%rsi), %r8
@@ -70,7 +73,7 @@
70
73
  movq 8(%rsi), %rsi
71
74
  .endm
72
75
 
73
- // Prepare XMM argument registers from array passed by caller.
76
+ # Prepare XMM argument registers from array passed by caller.
74
77
  .macro forward_xmm
75
78
  movsd 104(%rsi), %xmm7
76
79
  movsd 96(%rsi), %xmm6
@@ -147,27 +150,50 @@ SYMBOL(ForwardCallXDD):
147
150
  movb $8, %al
148
151
  epilogue
149
152
 
150
- // Callbacks
153
+ # Callback trampolines
154
+ # ----------------------------
151
155
 
152
- .global SYMBOL(CallBack0)
153
- .global SYMBOL(CallBack1)
154
- .global SYMBOL(CallBack2)
155
- .global SYMBOL(CallBack3)
156
- .global SYMBOL(CallBack4)
157
- .global SYMBOL(CallBack5)
158
- .global SYMBOL(CallBack6)
159
- .global SYMBOL(CallBack7)
160
- .global SYMBOL(CallBackX0)
161
- .global SYMBOL(CallBackX1)
162
- .global SYMBOL(CallBackX2)
163
- .global SYMBOL(CallBackX3)
164
- .global SYMBOL(CallBackX4)
165
- .global SYMBOL(CallBackX5)
166
- .global SYMBOL(CallBackX6)
167
- .global SYMBOL(CallBackX7)
156
+ .global SYMBOL(Trampoline0)
157
+ .global SYMBOL(Trampoline1)
158
+ .global SYMBOL(Trampoline2)
159
+ .global SYMBOL(Trampoline3)
160
+ .global SYMBOL(Trampoline4)
161
+ .global SYMBOL(Trampoline5)
162
+ .global SYMBOL(Trampoline6)
163
+ .global SYMBOL(Trampoline7)
164
+ .global SYMBOL(Trampoline8)
165
+ .global SYMBOL(Trampoline9)
166
+ .global SYMBOL(Trampoline10)
167
+ .global SYMBOL(Trampoline11)
168
+ .global SYMBOL(Trampoline12)
169
+ .global SYMBOL(Trampoline13)
170
+ .global SYMBOL(Trampoline14)
171
+ .global SYMBOL(Trampoline15)
172
+ .global SYMBOL(TrampolineX0)
173
+ .global SYMBOL(TrampolineX1)
174
+ .global SYMBOL(TrampolineX2)
175
+ .global SYMBOL(TrampolineX3)
176
+ .global SYMBOL(TrampolineX4)
177
+ .global SYMBOL(TrampolineX5)
178
+ .global SYMBOL(TrampolineX6)
179
+ .global SYMBOL(TrampolineX7)
180
+ .global SYMBOL(TrampolineX8)
181
+ .global SYMBOL(TrampolineX9)
182
+ .global SYMBOL(TrampolineX10)
183
+ .global SYMBOL(TrampolineX11)
184
+ .global SYMBOL(TrampolineX12)
185
+ .global SYMBOL(TrampolineX13)
186
+ .global SYMBOL(TrampolineX14)
187
+ .global SYMBOL(TrampolineX15)
168
188
  .global SYMBOL(RelayCallBack)
189
+ .global SYMBOL(CallSwitchStack)
169
190
 
170
- .macro jumper id
191
+ # First, make a copy of the GPR argument registers (rdi, rsi, rdx, rcx, r8, r9).
192
+ # Then call the C function RelayCallBack with the following arguments:
193
+ # static trampoline ID, a pointer to the saved GPR array, a pointer to the stack
194
+ # arguments of this call, and a pointer to a struct that will contain the result registers.
195
+ # After the call, simply load these registers from the output struct.
196
+ .macro trampoline id
171
197
  .cfi_startproc
172
198
  .cfi_def_cfa rsp, 8
173
199
  endbr64
@@ -179,18 +205,21 @@ SYMBOL(ForwardCallXDD):
179
205
  movq %rcx, 24(%rsp)
180
206
  movq %r8, 32(%rsp)
181
207
  movq %r9, 40(%rsp)
182
- leaq 112(%rsp), %rdi
183
- movq $\id, %rsi
184
- movq %rsp, %rdx
208
+ movq $\id, %rdi
209
+ movq %rsp, %rsi
210
+ leaq 160(%rsp), %rdx
211
+ leaq 112(%rsp), %rcx
185
212
  call SYMBOL(RelayCallBack)
186
- movq 8(%rax), %rdx
187
- movq 0(%rax), %rax
213
+ movq 112(%rsp), %rax
214
+ movq 120(%rsp), %rdx
188
215
  addq $152, %rsp
216
+ .cfi_def_cfa rsp, 8
189
217
  ret
190
218
  .cfi_endproc
191
219
  .endm
192
220
 
193
- .macro jumperx id
221
+ # Same thing, but also forward the XMM argument registers and load the XMM result registers.
222
+ .macro trampoline_xmm id
194
223
  .cfi_startproc
195
224
  .cfi_def_cfa rsp, 8
196
225
  endbr64
@@ -210,49 +239,109 @@ SYMBOL(ForwardCallXDD):
210
239
  movsd %xmm5, 88(%rsp)
211
240
  movsd %xmm6, 96(%rsp)
212
241
  movsd %xmm7, 104(%rsp)
213
- leaq 112(%rsp), %rdi
214
- movq $\id, %rsi
215
- movq %rsp, %rdx
242
+ movq $\id, %rdi
243
+ movq %rsp, %rsi
244
+ leaq 160(%rsp), %rdx
245
+ leaq 112(%rsp), %rcx
216
246
  call SYMBOL(RelayCallBack)
217
- movsd 16(%rax), %xmm0
218
- movsd 24(%rax), %xmm1
219
- movq 8(%rax), %rdx
220
- movq 0(%rax), %rax
247
+ movq 112(%rsp), %rax
248
+ movq 120(%rsp), %rdx
249
+ movsd 128(%rsp), %xmm0
250
+ movsd 136(%rsp), %xmm1
221
251
  addq $152, %rsp
252
+ .cfi_def_cfa rsp, 8
222
253
  ret
223
254
  .cfi_endproc
224
255
  .endm
225
256
 
226
- SYMBOL(CallBack0):
227
- jumper 0
228
- SYMBOL(CallBack1):
229
- jumper 1
230
- SYMBOL(CallBack2):
231
- jumper 2
232
- SYMBOL(CallBack3):
233
- jumper 3
234
- SYMBOL(CallBack4):
235
- jumper 4
236
- SYMBOL(CallBack5):
237
- jumper 5
238
- SYMBOL(CallBack6):
239
- jumper 6
240
- SYMBOL(CallBack7):
241
- jumper 7
257
+ SYMBOL(Trampoline0):
258
+ trampoline 0
259
+ SYMBOL(Trampoline1):
260
+ trampoline 1
261
+ SYMBOL(Trampoline2):
262
+ trampoline 2
263
+ SYMBOL(Trampoline3):
264
+ trampoline 3
265
+ SYMBOL(Trampoline4):
266
+ trampoline 4
267
+ SYMBOL(Trampoline5):
268
+ trampoline 5
269
+ SYMBOL(Trampoline6):
270
+ trampoline 6
271
+ SYMBOL(Trampoline7):
272
+ trampoline 7
273
+ SYMBOL(Trampoline8):
274
+ trampoline 8
275
+ SYMBOL(Trampoline9):
276
+ trampoline 9
277
+ SYMBOL(Trampoline10):
278
+ trampoline 10
279
+ SYMBOL(Trampoline11):
280
+ trampoline 11
281
+ SYMBOL(Trampoline12):
282
+ trampoline 12
283
+ SYMBOL(Trampoline13):
284
+ trampoline 13
285
+ SYMBOL(Trampoline14):
286
+ trampoline 14
287
+ SYMBOL(Trampoline15):
288
+ trampoline 15
242
289
 
243
- SYMBOL(CallBackX0):
244
- jumperx 0
245
- SYMBOL(CallBackX1):
246
- jumperx 1
247
- SYMBOL(CallBackX2):
248
- jumperx 2
249
- SYMBOL(CallBackX3):
250
- jumperx 3
251
- SYMBOL(CallBackX4):
252
- jumperx 4
253
- SYMBOL(CallBackX5):
254
- jumperx 5
255
- SYMBOL(CallBackX6):
256
- jumperx 6
257
- SYMBOL(CallBackX7):
258
- jumperx 7
290
+ SYMBOL(TrampolineX0):
291
+ trampoline_xmm 0
292
+ SYMBOL(TrampolineX1):
293
+ trampoline_xmm 1
294
+ SYMBOL(TrampolineX2):
295
+ trampoline_xmm 2
296
+ SYMBOL(TrampolineX3):
297
+ trampoline_xmm 3
298
+ SYMBOL(TrampolineX4):
299
+ trampoline_xmm 4
300
+ SYMBOL(TrampolineX5):
301
+ trampoline_xmm 5
302
+ SYMBOL(TrampolineX6):
303
+ trampoline_xmm 6
304
+ SYMBOL(TrampolineX7):
305
+ trampoline_xmm 7
306
+ SYMBOL(TrampolineX8):
307
+ trampoline_xmm 8
308
+ SYMBOL(TrampolineX9):
309
+ trampoline_xmm 9
310
+ SYMBOL(TrampolineX10):
311
+ trampoline_xmm 10
312
+ SYMBOL(TrampolineX11):
313
+ trampoline_xmm 11
314
+ SYMBOL(TrampolineX12):
315
+ trampoline_xmm 12
316
+ SYMBOL(TrampolineX13):
317
+ trampoline_xmm 13
318
+ SYMBOL(TrampolineX14):
319
+ trampoline_xmm 14
320
+ SYMBOL(TrampolineX15):
321
+ trampoline_xmm 15
322
+
323
+ # When a callback is relayed, Koffi will call into Node.js and V8 to execute Javascript.
324
+ # The propblem is that we're still running on the separate Koffi stack, and V8 will
325
+ # preobably misdetect this as a "stack overflow". We have to restore the old
326
+ # stack pointer, call Node.js/V8 and go back to ours.
327
+ # The first three parameters (rdi, rsi, rdx) are passed through untouched.
328
+ SYMBOL(CallSwitchStack):
329
+ .cfi_startproc
330
+ .cfi_def_cfa rsp, 8
331
+ endbr64
332
+ push %rbx
333
+ .cfi_def_cfa rsp, 16
334
+ movq %rsp, %rbx
335
+ movq %rsp, %r10
336
+ subq 0(%r8), %r10
337
+ andq $-16, %r10
338
+ movq %r10, 8(%r8)
339
+ movq %rcx, %rsp
340
+ .cfi_def_cfa rsp, 16
341
+ call *%r9
342
+ mov %rbx, %rsp
343
+ .cfi_def_cfa rsp, 16
344
+ pop %rbx
345
+ .cfi_def_cfa rsp, 8
346
+ ret
347
+ .cfi_endproc