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,31 +1,32 @@
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
  .syntax unified
15
15
 
16
- // These three are the same, but they differ (in the C side) by their return type.
17
- // Unlike the three next functions, these ones don't forward XMM argument registers.
16
+ # These three are the same, but they differ (in the C side) by their return type.
17
+ # Unlike the three next functions, these ones don't forward XMM argument registers.
18
18
  .global ForwardCallGG
19
19
  .global ForwardCallF
20
20
  .global ForwardCallDDDD
21
21
 
22
- // The X variants are slightly slower, and are used when XMM arguments must be forwarded.
22
+ # The X variants are slightly slower, and are used when XMM arguments must be forwarded.
23
23
  .global ForwardCallXGG
24
24
  .global ForwardCallXF
25
25
  .global ForwardCallXDDDD
26
26
 
27
- // Copy function pointer to r12, in order to save it through argument forwarding.
28
- // Save RSP in fp (non-volatile), and use carefully assembled stack provided by caller.
27
+ # Copy function pointer to r12, in order to save it through argument forwarding.
28
+ # Also make a copy of the SP to CallData::old_sp because the callback system might need it.
29
+ # Save RSP in fp (non-volatile), and use carefully assembled stack provided by caller.
29
30
  .macro prologue
30
31
  .cfi_startproc
31
32
  push {fp, lr}
@@ -34,14 +35,15 @@
34
35
  .cfi_offset 14, 8
35
36
  mov fp, sp
36
37
  .cfi_def_cfa fp, 8
38
+ str fp, [r2, 0]
37
39
  mov r12, r0
38
40
  mov sp, r1
39
41
  add sp, sp, #80
40
42
  .endm
41
43
 
42
- // Call native function.
43
- // Once done, restore normal stack pointer and return.
44
- // The return value is passed untouched through r0, r1, and or FP registers
44
+ # Call native function.
45
+ # Once done, restore normal stack pointer and return.
46
+ # The return value is passed untouched through r0, r1, and or FP registers
45
47
  .macro epilogue
46
48
  blx r12
47
49
  mov sp, fp
@@ -54,7 +56,7 @@
54
56
  .cfi_endproc
55
57
  .endm
56
58
 
57
- // Prepare general purpose argument registers from array passed by caller.
59
+ # Prepare general purpose argument registers from array passed by caller.
58
60
  .macro forward_int
59
61
  ldr r3, [r1, 76]
60
62
  ldr r2, [r1, 72]
@@ -62,7 +64,7 @@
62
64
  ldr r1, [r1, 68]
63
65
  .endm
64
66
 
65
- // Prepare vector argument registers from array passed by caller.
67
+ # Prepare vector argument registers from array passed by caller.
66
68
  .macro forward_vec
67
69
  vldr d7, [r1, 56]
68
70
  vldr d6, [r1, 48]
@@ -106,3 +108,216 @@ ForwardCallXDDDD:
106
108
  forward_vec
107
109
  forward_int
108
110
  epilogue
111
+
112
+ # Callback trampolines
113
+ # ----------------------------
114
+
115
+ .global Trampoline0
116
+ .global Trampoline1
117
+ .global Trampoline2
118
+ .global Trampoline3
119
+ .global Trampoline4
120
+ .global Trampoline5
121
+ .global Trampoline6
122
+ .global Trampoline7
123
+ .global Trampoline8
124
+ .global Trampoline9
125
+ .global Trampoline10
126
+ .global Trampoline11
127
+ .global Trampoline12
128
+ .global Trampoline13
129
+ .global Trampoline14
130
+ .global Trampoline15
131
+ .global TrampolineX0
132
+ .global TrampolineX1
133
+ .global TrampolineX2
134
+ .global TrampolineX3
135
+ .global TrampolineX4
136
+ .global TrampolineX5
137
+ .global TrampolineX6
138
+ .global TrampolineX7
139
+ .global TrampolineX8
140
+ .global TrampolineX9
141
+ .global TrampolineX10
142
+ .global TrampolineX11
143
+ .global TrampolineX12
144
+ .global TrampolineX13
145
+ .global TrampolineX14
146
+ .global TrampolineX15
147
+ .global RelayCallBack
148
+ .global CallSwitchStack
149
+
150
+ # First, make a copy of the GPR argument registers (r0 to r7).
151
+ # Then call the C function RelayCallBack with the following arguments:
152
+ # static trampoline ID, a pointer to the saved GPR array, a pointer to the stack
153
+ # arguments of this call, and a pointer to a struct that will contain the result registers.
154
+ # After the call, simply load these registers from the output struct.
155
+ .macro trampoline id
156
+ .cfi_startproc
157
+ push {fp, lr}
158
+ .cfi_def_cfa sp, 8
159
+ .cfi_offset 11, 4
160
+ .cfi_offset 14, 8
161
+ sub sp, sp, #120
162
+ .cfi_def_cfa sp, 128
163
+ str r0, [sp, 64]
164
+ str r1, [sp, 68]
165
+ str r2, [sp, 72]
166
+ str r3, [sp, 76]
167
+ mov r0, \id
168
+ mov r1, sp
169
+ add r2, sp, #128
170
+ add r3, sp, #80
171
+ bl RelayCallBack
172
+ ldr r0, [sp, 80]
173
+ ldr r1, [sp, 84]
174
+ add sp, sp, #120
175
+ .cfi_def_cfa sp, 8
176
+ pop {fp, lr}
177
+ .cfi_def_cfa sp, 0
178
+ .cfi_restore 11
179
+ .cfi_restore 14
180
+ bx lr
181
+ .cfi_endproc
182
+ .endm
183
+
184
+ # Same thing, but also forwards the floating-point argument registers and loads them at the end.
185
+ .macro trampoline_vec id
186
+ .cfi_startproc
187
+ push {fp, lr}
188
+ .cfi_def_cfa sp, 8
189
+ .cfi_offset 11, 4
190
+ .cfi_offset 14, 8
191
+ sub sp, sp, #120
192
+ .cfi_def_cfa sp, 128
193
+ str r0, [sp, 64]
194
+ str r1, [sp, 68]
195
+ str r2, [sp, 72]
196
+ str r3, [sp, 76]
197
+ vstr d0, [sp, 0]
198
+ vstr d1, [sp, 8]
199
+ vstr d2, [sp, 16]
200
+ vstr d3, [sp, 24]
201
+ vstr d4, [sp, 32]
202
+ vstr d5, [sp, 40]
203
+ vstr d6, [sp, 48]
204
+ vstr d7, [sp, 56]
205
+ mov r0, \id
206
+ mov r1, sp
207
+ add r2, sp, #128
208
+ add r3, sp, #80
209
+ bl RelayCallBack
210
+ ldr r0, [sp, 80]
211
+ ldr r1, [sp, 84]
212
+ vldr d0, [sp, 88]
213
+ vldr d1, [sp, 96]
214
+ vldr d2, [sp, 104]
215
+ vldr d3, [sp, 112]
216
+ add sp, sp, #120
217
+ .cfi_def_cfa sp, 8
218
+ pop {fp, lr}
219
+ .cfi_def_cfa sp, 0
220
+ .cfi_restore 11
221
+ .cfi_restore 14
222
+ bx lr
223
+ .cfi_endproc
224
+ .endm
225
+
226
+ Trampoline0:
227
+ trampoline 0
228
+ Trampoline1:
229
+ trampoline 1
230
+ Trampoline2:
231
+ trampoline 2
232
+ Trampoline3:
233
+ trampoline 3
234
+ Trampoline4:
235
+ trampoline 4
236
+ Trampoline5:
237
+ trampoline 5
238
+ Trampoline6:
239
+ trampoline 6
240
+ Trampoline7:
241
+ trampoline 7
242
+ Trampoline8:
243
+ trampoline 8
244
+ Trampoline9:
245
+ trampoline 9
246
+ Trampoline10:
247
+ trampoline 10
248
+ Trampoline11:
249
+ trampoline 11
250
+ Trampoline12:
251
+ trampoline 12
252
+ Trampoline13:
253
+ trampoline 13
254
+ Trampoline14:
255
+ trampoline 14
256
+ Trampoline15:
257
+ trampoline 15
258
+
259
+ TrampolineX0:
260
+ trampoline_vec 0
261
+ TrampolineX1:
262
+ trampoline_vec 1
263
+ TrampolineX2:
264
+ trampoline_vec 2
265
+ TrampolineX3:
266
+ trampoline_vec 3
267
+ TrampolineX4:
268
+ trampoline_vec 4
269
+ TrampolineX5:
270
+ trampoline_vec 5
271
+ TrampolineX6:
272
+ trampoline_vec 6
273
+ TrampolineX7:
274
+ trampoline_vec 7
275
+ TrampolineX8:
276
+ trampoline_vec 8
277
+ TrampolineX9:
278
+ trampoline_vec 9
279
+ TrampolineX10:
280
+ trampoline_vec 10
281
+ TrampolineX11:
282
+ trampoline_vec 11
283
+ TrampolineX12:
284
+ trampoline_vec 12
285
+ TrampolineX13:
286
+ trampoline_vec 13
287
+ TrampolineX14:
288
+ trampoline_vec 14
289
+ TrampolineX15:
290
+ trampoline_vec 15
291
+
292
+ # When a callback is relayed, Koffi will call into Node.js and V8 to execute Javascript.
293
+ # The propblem is that we're still running on the separate Koffi stack, and V8 will
294
+ # preobably misdetect this as a "stack overflow". We have to restore the old
295
+ # stack pointer, call Node.js/V8 and go back to ours.
296
+ # The first three parameters (r0, r1, r2) are passed through untouched.
297
+ CallSwitchStack:
298
+ .cfi_startproc
299
+ push {fp, lr}
300
+ .cfi_def_cfa sp, 8
301
+ push {r4, r5}
302
+ .cfi_def_cfa sp, 16
303
+ .cfi_offset 11, 4
304
+ .cfi_offset 14, 8
305
+ mov fp, sp
306
+ ldr r4, [sp, 16]
307
+ ldr r5, [r4, 0]
308
+ sub r5, sp, r5
309
+ and r5, r5, #-16
310
+ str r5, [r4, 4]
311
+ ldr r4, [sp, 20]
312
+ mov sp, r3
313
+ blx r4
314
+ mov sp, fp
315
+ .cfi_def_cfa sp, 16
316
+ pop {r4, r5}
317
+ .cfi_def_cfa sp, 8
318
+ pop {fp, lr}
319
+ .cfi_def_cfa sp, 0
320
+ .cfi_restore 11
321
+ .cfi_restore 14
322
+ bx lr
323
+ .cfi_endproc