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