1 | | /* |
2 | | * ex: set ro: |
3 | | * DO NOT EDIT THIS FILE |
4 | | * Generated by Parrot::Configure::Compiler from config/gen/libjit/frame_builder_libjit_c.in |
5 | | */ |
6 | | |
7 | | /* |
8 | | Copyright (C) 2008-2009, Parrot Foundation. |
9 | | $Id$ |
10 | | */ |
11 | | |
12 | | /* HEADERIZER HFILE: none */ |
13 | | /* HEADERIZER STOP */ |
14 | | |
15 | | #include "parrot/parrot.h" |
16 | | #include "pmc/pmc_integer.h" |
17 | | #include "pmc/pmc_unmanagedstruct.h" |
18 | | #include "pmc/pmc_managedstruct.h" |
19 | | #include "frame_builder.h" |
20 | | #include "frame_builder_libjit.h" |
21 | | |
22 | | #ifdef PARROT_HAS_LIBJIT |
23 | | |
24 | | /* |
25 | | |
26 | | =over 4 |
27 | | |
28 | | =item C<void *Parrot_jit_build_call_func(PARROT_INTERP, PMC *nci, STRING *sig, void **priv)> |
29 | | |
30 | | Public interface to NCI function interface builder. |
31 | | |
32 | | =cut |
33 | | |
34 | | */ |
35 | | |
36 | | void * |
37 | | Parrot_jit_build_call_func(PARROT_INTERP, PMC *pmc, STRING *sig, void **priv) { |
38 | | void *thunk; |
39 | | char *sig_cstr; |
40 | | |
41 | | sig_cstr = Parrot_str_to_cstring(interp, sig); |
42 | | *priv = mem_sys_allocate(sizeof (struct jit_buffer_private_data)); |
43 | | |
44 | | thunk = Parrot_jit_create_thunk(interp, sig_cstr, *priv); |
45 | | |
46 | | Parrot_str_free_cstring(sig_cstr); |
47 | | |
48 | | return thunk; |
49 | | } |
50 | | |
51 | | /* |
52 | | |
53 | | =item C<void Parrot_jit_free_buffer(PARROT_INTERP, void *ptr, void *priv)> |
54 | | |
55 | | This is a callback to implement the proper freeing semantics. It is called by |
56 | | the ManagedStruct PMC as it is garbage collected. |
57 | | |
58 | | =cut |
59 | | |
60 | | */ |
61 | | |
62 | | void |
63 | | Parrot_jit_free_buffer(PARROT_INTERP, void *ptr, void *priv) |
64 | | { |
65 | | struct jit_buffer_private_data *jit = (struct jit_buffer_private_data*)priv; |
66 | | jit_context_destroy(jit->ctx); |
67 | | mem_sys_free(jit->sig); |
68 | | mem_sys_free(priv); |
69 | | } |
70 | | |
71 | | /* |
72 | | |
73 | | =item C<PMC *Parrot_jit_clone_buffer(PARROT_INTERP, PMC *pmc, void *priv)> |
74 | | |
75 | | This is a callback to implement the proper cloning semantics for jit buffers. |
76 | | It is called by the ManagedStruct PMC's clone() function. |
77 | | |
78 | | =back |
79 | | |
80 | | =cut |
81 | | |
82 | | */ |
83 | | |
84 | | PMC * |
85 | | Parrot_jit_clone_buffer(PARROT_INTERP, PMC *pmc, void *priv) |
86 | | { |
87 | | PMC * const rv = pmc_new(interp, pmc->vtable->base_type); |
88 | | |
89 | | VTABLE_init(interp, rv); |
90 | | /* copy the attributes */ |
91 | | { |
92 | | void (*tmpfreefunc)(PARROT_INTERP, void*, void*); |
93 | | GETATTR_ManagedStruct_custom_free_func(interp, pmc, tmpfreefunc); |
94 | | SETATTR_ManagedStruct_custom_free_func(interp, rv , tmpfreefunc); |
95 | | } |
96 | | { |
97 | | PMC* (*tmpclonefunc)(PARROT_INTERP, PMC*, void*); |
98 | | GETATTR_ManagedStruct_custom_clone_func(interp, pmc, tmpclonefunc); |
99 | | SETATTR_ManagedStruct_custom_clone_func(interp, rv , tmpclonefunc); |
100 | | } |
101 | | |
102 | | /* compile a clone of the function */ |
103 | | if (PARROT_MANAGEDSTRUCT(pmc)->ptr) { |
104 | | void *rv_priv; |
105 | | struct jit_buffer_private_data *jit = (struct jit_buffer_private_data*)priv; |
106 | | STRING *sig = Parrot_str_new(interp, jit->sig, 0); |
107 | | PARROT_MANAGEDSTRUCT(rv)->ptr = Parrot_jit_build_call_func(interp, rv, sig, &rv_priv); |
108 | | } |
109 | | |
110 | | return rv; |
111 | | } |
112 | | |
113 | | /* |
114 | | * JIT functions |
115 | | */ |
116 | | |
117 | | void * |
118 | | Parrot_jit_create_thunk(PARROT_INTERP, char *sig, void *priv) { |
119 | | struct jit_buffer_private_data *p; |
120 | | jit_function_t f; |
121 | | jit_value_t jit_interp, jit_func; |
122 | | jit_type_t *jit_args_t; |
123 | | jit_value_t *jit_args_v, *jit_regs; |
124 | | |
125 | | /* populate private data */ |
126 | | p = (struct jit_buffer_private_data*)priv; |
127 | | p->ctx = jit_context_create(); |
128 | | p->sig = mem_sys_strdup(sig); |
129 | | |
130 | | /* start compiling */ |
131 | | jit_context_build_start(p->ctx); |
132 | | |
133 | | /* start JIT function */ |
134 | | { |
135 | | jit_type_t arg_types[] = { |
136 | | jit_type_void_ptr, /* interp */ |
137 | | jit_type_void_ptr /* nci_info */ |
138 | | }; |
139 | | jit_type_t f_sig = jit_type_create_signature(jit_abi_cdecl, jit_type_void, arg_types, 2, 1); |
140 | | f = jit_function_create(p->ctx, f_sig); |
141 | | } |
142 | | |
143 | | /* get the incomming args */ |
144 | | jit_interp = jit_value_get_param(f, 0); |
145 | | jit_func = jit__vtable_get_pointer(f, jit_interp, jit_value_get_param(f, 1)); |
146 | | |
147 | | /* get the outgoing args */ |
148 | | { |
149 | | jit_value_t st; |
150 | | int nargs; |
151 | | |
152 | | { |
153 | | jit_value_t sizeof_call_state |
154 | | = jit_value_create_nint_constant(f, jit_type_sys_int, sizeof (call_state)); |
155 | | st = jit_insn_alloca(f, sizeof_call_state); |
156 | | } |
157 | | |
158 | | nargs = Parrot_jit_parse_sig_args_pre(interp, sig, f, jit_interp, st, |
159 | | &jit_args_t, &jit_args_v, &jit_regs); |
160 | | |
161 | | /* get the return type */ |
162 | | { |
163 | | jit_type_t ret_t; |
164 | | jit_value_t ret_v; |
165 | | |
166 | | ret_t = Parrot_jit_parse_sig_ret_pre(interp, sig); |
167 | | |
168 | | /* make the call */ |
169 | | { |
170 | | jit_type_t jit_sig |
171 | | = jit_type_create_signature(jit_abi_cdecl, ret_t, jit_args_t, nargs, 1); |
172 | | ret_v = jit_insn_call_indirect(f, jit_func, jit_sig, jit_args_v, nargs, 0); |
173 | | } |
174 | | |
175 | | /* get the incomming return */ |
176 | | Parrot_jit_parse_sig_ret_post(interp, sig, f, jit_interp, st, ret_v); |
177 | | } |
178 | | |
179 | | /* clean up args */ |
180 | | Parrot_jit_parse_sig_args_post(interp, sig, nargs, f, jit_interp, jit_args_v, jit_regs); |
181 | | } |
182 | | |
183 | | /* end JIT function */ |
184 | | jit_insn_return(f, NULL); |
185 | | |
186 | | /* compile to native callable func poitner */ |
187 | | jit_function_compile(f); |
188 | | jit_context_build_end(p->ctx); |
189 | | |
190 | | mem_sys_free(jit_args_t); |
191 | | mem_sys_free(jit_args_v); |
192 | | mem_sys_free(jit_regs); |
193 | | |
194 | | return jit_function_to_closure(f); |
195 | | } |
196 | | |
197 | | int |
198 | | Parrot_jit_parse_sig_args_pre(PARROT_INTERP, char *sig, jit_function_t f, |
199 | | jit_value_t jinterp, jit_value_t st, |
200 | | jit_type_t **arg_types, |
201 | | jit_value_t **arg_vals, jit_value_t **arg_regs) { |
202 | | int nargs, nregs, i, j; |
203 | | |
204 | | sig += 1; /* ignore return character */ |
205 | | |
206 | | nargs = strlen(sig); |
207 | | nregs = Parrot_jit_init_pcc(sig, nargs, f, jinterp, st); |
208 | | |
209 | | *arg_types = (jit_type_t *)mem_sys_allocate(nargs * sizeof (jit_type_t)); |
210 | | *arg_vals = (jit_value_t *)mem_sys_allocate(nargs * sizeof (jit_value_t)); |
211 | | *arg_regs = (jit_value_t *)mem_sys_allocate(nregs * sizeof (jit_value_t)); |
212 | | |
213 | | for (i = 0, j = 0; i < nargs; i++) { |
214 | | char c; |
215 | | jit_type_t t1; |
216 | | jit_value_t v1, v2, v3, v4; |
217 | | switch (c = sig[i]) { |
218 | | case 'I': |
219 | | t1 = JIT_TYPE_INTVAL; |
220 | | read_int_reg: |
221 | | (*arg_types)[i] = t1; |
222 | | v1 = jit_value_create_nint_constant(f, jit_type_sys_int, j); |
223 | | v2 = jit__get_nci_I(f, jinterp, st, v1); |
224 | | (*arg_regs)[j++] = (*arg_vals)[i] = v2; |
225 | | break; |
226 | | case 'c': |
227 | | t1 = jit_type_sys_char; |
228 | | goto read_int_reg; |
229 | | case 's': |
230 | | t1 = jit_type_sys_short; |
231 | | goto read_int_reg; |
232 | | case 'i': |
233 | | t1 = jit_type_sys_int; |
234 | | goto read_int_reg; |
235 | | case 'l': |
236 | | t1 = jit_type_sys_long; |
237 | | goto read_int_reg; |
238 | | |
239 | | case 'N': |
240 | | t1 = JIT_TYPE_FLOATVAL; |
241 | | read_float_reg: |
242 | | (*arg_types)[i] = t1; |
243 | | v1 = jit_value_create_nint_constant(f, jit_type_sys_int, j); |
244 | | v2 = jit__get_nci_N(f, jinterp, st, v1); |
245 | | (*arg_regs)[j++] = (*arg_vals)[i] = v2; |
246 | | break; |
247 | | case 'f': |
248 | | t1 = jit_type_sys_float; |
249 | | goto read_float_reg; |
250 | | case 'd': |
251 | | t1 = jit_type_sys_double; |
252 | | goto read_float_reg; |
253 | | |
254 | | case 'S': |
255 | | (*arg_types)[i] = jit_type_void_ptr; |
256 | | v1 = jit_value_create_nint_constant(f, jit_type_sys_int, j); |
257 | | v2 = jit__get_nci_S(f, jinterp, st, v1); |
258 | | (*arg_regs)[j++] = (*arg_vals)[i] = v2; |
259 | | break; |
260 | | |
261 | | case 't': |
262 | | (*arg_types)[i] = jit_type_void_ptr; |
263 | | v1 = jit_value_create_nint_constant(f, jit_type_sys_int, j); |
264 | | v2 = jit__get_nci_S(f, jinterp, st, v1); |
265 | | (*arg_regs)[j++] = v2; |
266 | | (*arg_vals)[i] = jit__Parrot_str_to_cstring(f, jinterp, v2); |
267 | | break; |
268 | | |
269 | | case 'b': |
270 | | (*arg_types)[i] = jit_type_void_ptr; |
271 | | v1 = jit_value_create_nint_constant(f, jit_type_sys_int, j); |
272 | | v2 = jit__get_nci_S(f, jinterp, st, v1); |
273 | | (*arg_regs)[j++] = v2; |
274 | | (*arg_vals)[i] = jit__Buffer_bufstart(f, v2); |
275 | | break; |
276 | | case 'B': |
277 | | (*arg_types)[i] = jit_type_void_ptr; |
278 | | v1 = jit_value_create_nint_constant(f, jit_type_sys_int, j); |
279 | | v2 = jit__get_nci_S(f, jinterp, st, v1); |
280 | | (*arg_regs)[j++] = v2; |
281 | | v3 = jit__Parrot_str_to_cstring(f, jinterp, v2); |
282 | | jit_value_set_addressable(v3); |
283 | | (*arg_vals)[i] = jit_insn_address_of(f, v3); |
284 | | break; |
285 | | |
286 | | case 'p': |
287 | | (*arg_types)[i] = jit_type_void_ptr; |
288 | | v1 = jit_value_create_nint_constant(f, jit_type_sys_int, j); |
289 | | v2 = jit__get_nci_p(f, jinterp, st, v1); |
290 | | (*arg_regs)[j++] = (*arg_vals)[i] = v2; |
291 | | break; |
292 | | case 'P': |
293 | | case 'O': |
294 | | case '@': |
295 | | (*arg_types)[i] = jit_type_void_ptr; |
296 | | v1 = jit_value_create_nint_constant(f, jit_type_sys_int, j); |
297 | | v2 = jit__get_nci_P(f, jinterp, st, v1); |
298 | | (*arg_regs)[j++] = (*arg_vals)[i] = v2; |
299 | | break; |
300 | | case '2': |
301 | | t1 = jit_type_sys_short; |
302 | | goto call_get_integer; |
303 | | case '3': |
304 | | t1 = jit_type_sys_int; |
305 | | goto call_get_integer; |
306 | | case '4': |
307 | | t1 = jit_type_sys_long; |
308 | | call_get_integer: |
309 | | (*arg_types)[i] = jit_type_void_ptr; |
310 | | v1 = jit_value_create_nint_constant(f, jit_type_sys_int, j); |
311 | | v2 = jit__get_nci_P(f, jinterp, st, v1); |
312 | | (*arg_regs)[j++] = v2; |
313 | | v3 = jit__vtable_get_integer(f, jinterp, v2); |
314 | | v4 = jit_value_create(f, t1); |
315 | | jit_value_set_addressable(v4); |
316 | | jit_insn_store(f, v4, v3); |
317 | | (*arg_vals)[i] = jit_insn_address_of(f, v4); |
318 | | break; |
319 | | |
320 | | case 'V': |
321 | | (*arg_types)[i] = jit_type_void_ptr; |
322 | | v1 = jit_value_create_nint_constant(f, jit_type_sys_int, j); |
323 | | v2 = jit__get_nci_P(f, jinterp, st, v1); |
324 | | (*arg_regs)[j++] = v2; |
325 | | v3 = jit__vtable_get_pointer(f, jinterp, v2); |
326 | | v4 = jit_value_create(f, jit_type_void_ptr); |
327 | | jit_value_set_addressable(v4); |
328 | | jit_insn_store(f, v4, v3); |
329 | | (*arg_vals)[i] = jit_insn_address_of(f, v4); |
330 | | break; |
331 | | |
332 | | case '0': |
333 | | (*arg_types)[i] = jit_type_void_ptr; |
334 | | (*arg_vals)[i] = jit_value_create_nint_constant(f, jit_type_void_ptr, (jit_nint)NULL); |
335 | | break; |
336 | | |
337 | | case 'J': |
338 | | (*arg_types)[i] = jit_type_void_ptr; |
339 | | (*arg_vals)[i] = jinterp; |
340 | | break; |
341 | | |
342 | | case 'U': |
343 | | /* TODO */ |
344 | | Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR, |
345 | | "arg type 'U' not yet implemented"); |
346 | | return -1; |
347 | | |
348 | | default: |
349 | | Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR, |
350 | | "unkown arg type '%c'", c); |
351 | | return -1; |
352 | | } |
353 | | } |
354 | | |
355 | | return nargs; |
356 | | } |
357 | | |
358 | | int |
359 | | Parrot_jit_init_pcc(char *sig, int nargs, jit_function_t f, jit_value_t interp, jit_value_t st) { |
360 | | int i, j; |
361 | | char pcc_sig[nargs]; |
362 | | |
363 | | for (i = 0, j = 0; i < nargs; i++) { |
364 | | switch (sig[i]) { |
365 | | case 'I': |
366 | | case 'c': |
367 | | case 's': |
368 | | case 'i': |
369 | | case 'l': |
370 | | pcc_sig[j++] = 'I'; |
371 | | break; |
372 | | |
373 | | case 'N': |
374 | | case 'f': |
375 | | case 'd': |
376 | | pcc_sig[j++] = 'N'; |
377 | | break; |
378 | | |
379 | | case 'S': |
380 | | case 't': |
381 | | case 'b': |
382 | | case 'B': |
383 | | pcc_sig[j++] = 'S'; |
384 | | break; |
385 | | |
386 | | case 'p': |
387 | | case 'P': |
388 | | case 'O': |
389 | | case 'V': |
390 | | case '2': |
391 | | case '3': |
392 | | case '4': |
393 | | pcc_sig[j++] = 'P'; |
394 | | break; |
395 | | |
396 | | case '@': |
397 | | pcc_sig[j++] = '@'; |
398 | | break; |
399 | | |
400 | | default: |
401 | | break; |
402 | | } |
403 | | } |
404 | | pcc_sig[j] = '\0'; |
405 | | |
406 | | jit__Parrot_init_arg_nci(f, interp, st, |
407 | | jit_value_create_string_constant(f, pcc_sig, j+1)); |
408 | | |
409 | | return j; |
410 | | } |
411 | | |
412 | | jit_type_t |
413 | | Parrot_jit_parse_sig_ret_pre(PARROT_INTERP, char *sig) { |
414 | | char c; |
415 | | switch (c = sig[0]) { |
416 | | case 'v': |
417 | | return jit_type_void; |
418 | | |
419 | | case 'I': |
420 | | return JIT_TYPE_INTVAL; |
421 | | case 'c': |
422 | | return jit_type_sys_char; |
423 | | case 's': |
424 | | return jit_type_sys_short; |
425 | | case 'i': |
426 | | return jit_type_sys_int; |
427 | | case 'l': |
428 | | return jit_type_sys_long; |
429 | | |
430 | | case 'N': |
431 | | return JIT_TYPE_FLOATVAL; |
432 | | case 'f': |
433 | | return jit_type_sys_float; |
434 | | case 'd': |
435 | | return jit_type_sys_double; |
436 | | |
437 | | case 'S': |
438 | | case 't': |
439 | | return jit_type_void_ptr; |
440 | | |
441 | | case 'p': |
442 | | case 'P': |
443 | | return jit_type_void_ptr; |
444 | | |
445 | | case 'U': |
446 | | /* TODO */ |
447 | | Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR, |
448 | | "return type 'U' not yet implemented"); |
449 | | return NULL; |
450 | | default: |
451 | | /* FAIL */ |
452 | | Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_JIT_ERROR, |
453 | | "unknown return type '%c'", c); |
454 | | return NULL; |
455 | | } |
456 | | } |
457 | | |
458 | | void |
459 | | Parrot_jit_parse_sig_ret_post(PARROT_INTERP, char *sig, |
460 | | jit_function_t f, jit_value_t jinterp, jit_value_t st, |
461 | | jit_value_t retval) { |
462 | | jit_type_t t1; |
463 | | jit_value_t v1, v2, v3; |
464 | | switch (sig[0]) { |
465 | | case 'v': |
466 | | break; |
467 | | |
468 | | case 'I': |
469 | | case 'c': |
470 | | case 's': |
471 | | case 'i': |
472 | | case 'l': |
473 | | jit__set_nci_I(f, jinterp, st, retval); |
474 | | break; |
475 | | |
476 | | case 'N': |
477 | | case 'f': |
478 | | case 'd': |
479 | | jit__set_nci_N(f, jinterp, st, retval); |
480 | | break; |
481 | | |
482 | | case 'S': |
483 | | jit__set_nci_S(f, jinterp, st, retval); |
484 | | break; |
485 | | case 't': |
486 | | v1 = jit_value_create_nint_constant(f, jit_type_sys_int, 0); |
487 | | v2 = jit__Parrot_str_new(f, jinterp, retval, v1); |
488 | | jit__set_nci_S(f, jinterp, st, v2); |
489 | | break; |
490 | | |
491 | | case 'P': |
492 | | jit__set_nci_P(f, jinterp, st, retval); |
493 | | break; |
494 | | case 'p': |
495 | | v1 = jit_value_create_intval_constant(f, enum_class_UnManagedStruct); |
496 | | v2 = jit__pmc_new_noinit(f, jinterp, v1); |
497 | | jit__vtable_set_pointer(f, jinterp, v2, retval); |
498 | | jit__set_nci_P(f, jinterp, st, v2); |
499 | | break; |
500 | | case '2': |
501 | | t1 = jit_type_sys_short; |
502 | | goto create_int_pmc; |
503 | | case '3': |
504 | | t1 = jit_type_sys_int; |
505 | | goto create_int_pmc; |
506 | | case '4': |
507 | | t1 = jit_type_sys_long; |
508 | | create_int_pmc: |
509 | | v1 = jit_insn_load_relative(f, retval, 0, t1); |
510 | | v2 = jit_value_create_intval_constant(f, enum_class_Integer); |
511 | | v3 = jit__pmc_new_noinit(f, jinterp, v2); |
512 | | jit__vtable_set_integer_native(f, jinterp, v3, v1); |
513 | | jit__set_nci_P(f, jinterp, st, v3); |
514 | | break; |
515 | | |
516 | | case 'U': |
517 | | /* ignore (failed elsewhere) */ |
518 | | break; |
519 | | |
520 | | default: |
521 | | /* ignore (failed elsewhere) */ |
522 | | break; |
523 | | } |
524 | | } |
525 | | |
526 | | void |
527 | | Parrot_jit_parse_sig_args_post(PARROT_INTERP, char *sig, int nargs, |
528 | | jit_function_t f, jit_value_t jinterp, |
529 | | jit_value_t *args, jit_value_t *regs) { |
530 | | int i, j; |
531 | | |
532 | | sig += 1; |
533 | | |
534 | | for (i = 0, j = 0; i < nargs; i++) { |
535 | | jit_type_t t1; |
536 | | jit_value_t v1; |
537 | | switch (sig[i]) { |
538 | | case 't': |
539 | | jit__Parrot_str_free_cstring(f, args[i]); |
540 | | j++; |
541 | | break; |
542 | | |
543 | | case 'B': |
544 | | v1 = jit_insn_load_relative(f, args[i], 0, jit_type_void_ptr); |
545 | | jit__Parrot_str_free_cstring(f, v1); |
546 | | j++; |
547 | | break; |
548 | | |
549 | | case '2': |
550 | | t1 = jit_type_sys_short; |
551 | | goto set_integer; |
552 | | case '3': |
553 | | t1 = jit_type_sys_int; |
554 | | goto set_integer; |
555 | | case '4': |
556 | | t1 = jit_type_sys_long; |
557 | | set_integer: |
558 | | v1 = jit_insn_load_relative(f, args[i], 0, t1); |
559 | | jit__vtable_set_integer_native(f, jinterp, regs[j], v1); |
560 | | j++; |
561 | | break; |
562 | | |
563 | | case 'V': |
564 | | v1 = jit_insn_load_relative(f, args[i], 0, jit_type_void_ptr); |
565 | | jit__vtable_set_pointer(f, jinterp, regs[j], v1); |
566 | | j++; |
567 | | break; |
568 | | |
569 | | case 'I': |
570 | | case 'c': |
571 | | case 'i': |
572 | | case 'l': |
573 | | case 'N': |
574 | | case 'f': |
575 | | case 'd': |
576 | | case 'S': |
577 | | case 'b': |
578 | | case 'p': |
579 | | case 'P': |
580 | | case 'O': |
581 | | case '@': |
582 | | j++; |
583 | | break; |
584 | | |
585 | | case 'U': |
586 | | /* TODO */ |
587 | | break; |
588 | | default: |
589 | | /* ignore */ |
590 | | break; |
591 | | } |
592 | | } |
593 | | } |
594 | | |
595 | | jit_value_t |
596 | | jit_value_create_intval_constant(jit_function_t f, INTVAL i) { |
597 | | return jit_value_create_nint_constant(f, JIT_TYPE_INTVAL, i); |
598 | | } |
599 | | |
600 | | jit_value_t |
601 | | jit_value_create_string_constant(jit_function_t f, char *str, int len) { |
602 | | jit_value_t jit_len, jit_str; |
603 | | int i; |
604 | | |
605 | | if (len < 1) { |
606 | | len = strlen(str); |
607 | | } |
608 | | |
609 | | jit_len = jit_value_create_nint_constant(f, jit_type_sys_int, len); |
610 | | jit_str = jit_insn_alloca(f, jit_len); |
611 | | |
612 | | for (i = 0; i < len; i++) { |
613 | | jit_value_t c = jit_value_create_nint_constant(f, jit_type_sys_char, str[i]); |
614 | | jit_insn_store_relative(f, jit_str, i, c); |
615 | | } |
616 | | |
617 | | return jit_str; |
618 | | } |
619 | | |
620 | | /* |
621 | | * JIT wrappers |
622 | | */ |
623 | | |
624 | | /* custom wrappers */ |
625 | | jit_value_t |
626 | | jit__Buffer_bufstart(jit_function_t f, jit_value_t buf) { |
627 | | return jit_insn_load_relative(f, buf, offsetof(Buffer, _bufstart), jit_type_void_ptr); |
628 | | } |
629 | | |
630 | | /* vtable wrappers */ |
631 | | jit_value_t |
632 | | jit__vtable_get_pointer(jit_function_t f, jit_value_t interp, jit_value_t self ) { |
633 | | jit_type_t sig; |
634 | | jit_value_t vtable, method; |
635 | | jit_type_t arg_t[] = { jit_type_void_ptr, jit_type_void_ptr }; |
636 | | jit_value_t arg_v[] = { interp, self }; |
637 | | |
638 | | sig = jit_type_create_signature(jit_abi_cdecl, jit_type_void_ptr, arg_t, 0 + 2, 1); |
639 | | |
640 | | vtable = jit_insn_load_relative(f, self, offsetof(PMC, vtable), jit_type_void_ptr); |
641 | | method = jit_insn_load_relative(f, vtable, offsetof(VTABLE, get_pointer), jit_type_void_ptr); |
642 | | |
643 | | return jit_insn_call_indirect(f, method, sig, arg_v, 0 + 2, 0); |
644 | | } |
645 | | |
646 | | jit_value_t |
647 | | jit__vtable_set_pointer(jit_function_t f, jit_value_t interp, jit_value_t self , jit_value_t v1) { |
648 | | jit_type_t sig; |
649 | | jit_value_t vtable, method; |
650 | | jit_type_t arg_t[] = { jit_type_void_ptr, jit_type_void_ptr , jit_type_void_ptr }; |
651 | | jit_value_t arg_v[] = { interp, self , v1 }; |
652 | | |
653 | | sig = jit_type_create_signature(jit_abi_cdecl, jit_type_void, arg_t, 1 + 2, 1); |
654 | | |
655 | | vtable = jit_insn_load_relative(f, self, offsetof(PMC, vtable), jit_type_void_ptr); |
656 | | method = jit_insn_load_relative(f, vtable, offsetof(VTABLE, set_pointer), jit_type_void_ptr); |
657 | | |
658 | | return jit_insn_call_indirect(f, method, sig, arg_v, 1 + 2, 0); |
659 | | } |
660 | | |
661 | | jit_value_t |
662 | | jit__vtable_set_integer_native(jit_function_t f, jit_value_t interp, jit_value_t self , jit_value_t v1) { |
663 | | jit_type_t sig; |
664 | | jit_value_t vtable, method; |
665 | | jit_type_t arg_t[] = { jit_type_void_ptr, jit_type_void_ptr , JIT_TYPE_INTVAL }; |
666 | | jit_value_t arg_v[] = { interp, self , v1 }; |
667 | | |
668 | | sig = jit_type_create_signature(jit_abi_cdecl, jit_type_void, arg_t, 1 + 2, 1); |
669 | | |
670 | | vtable = jit_insn_load_relative(f, self, offsetof(PMC, vtable), jit_type_void_ptr); |
671 | | method = jit_insn_load_relative(f, vtable, offsetof(VTABLE, set_integer_native), jit_type_void_ptr); |
672 | | |
673 | | return jit_insn_call_indirect(f, method, sig, arg_v, 1 + 2, 0); |
674 | | } |
675 | | |
676 | | jit_value_t |
677 | | jit__vtable_get_integer(jit_function_t f, jit_value_t interp, jit_value_t self ) { |
678 | | jit_type_t sig; |
679 | | jit_value_t vtable, method; |
680 | | jit_type_t arg_t[] = { jit_type_void_ptr, jit_type_void_ptr }; |
681 | | jit_value_t arg_v[] = { interp, self }; |
682 | | |
683 | | sig = jit_type_create_signature(jit_abi_cdecl, JIT_TYPE_INTVAL, arg_t, 0 + 2, 1); |
684 | | |
685 | | vtable = jit_insn_load_relative(f, self, offsetof(PMC, vtable), jit_type_void_ptr); |
686 | | method = jit_insn_load_relative(f, vtable, offsetof(VTABLE, get_integer), jit_type_void_ptr); |
687 | | |
688 | | return jit_insn_call_indirect(f, method, sig, arg_v, 0 + 2, 0); |
689 | | } |
690 | | |
691 | | |
692 | | /* function wrappers */ |
693 | | jit_value_t |
694 | | jit__Parrot_str_free_cstring(jit_function_t f, jit_value_t v1) { |
695 | | jit_type_t sig; |
696 | | jit_type_t arg_t[] = { jit_type_void_ptr }; |
697 | | jit_value_t arg_v[] = { v1 }; |
698 | | |
699 | | sig = jit_type_create_signature(jit_abi_cdecl, jit_type_void, arg_t, 1, 1); |
700 | | |
701 | | return jit_insn_call_native(f, "Parrot_str_free_cstring", (void *)&Parrot_str_free_cstring, sig, arg_v, 1, 0); |
702 | | } |
703 | | |
704 | | jit_value_t |
705 | | jit__get_nci_N(jit_function_t f, jit_value_t v1, jit_value_t v2, jit_value_t v3) { |
706 | | jit_type_t sig; |
707 | | jit_type_t arg_t[] = { jit_type_void_ptr, jit_type_void_ptr, jit_type_sys_int }; |
708 | | jit_value_t arg_v[] = { v1, v2, v3 }; |
709 | | |
710 | | sig = jit_type_create_signature(jit_abi_cdecl, JIT_TYPE_FLOATVAL, arg_t, 3, 1); |
711 | | |
712 | | return jit_insn_call_native(f, "get_nci_N", (void *)&get_nci_N, sig, arg_v, 3, 0); |
713 | | } |
714 | | |
715 | | jit_value_t |
716 | | jit__Parrot_str_to_cstring(jit_function_t f, jit_value_t v1, jit_value_t v2) { |
717 | | jit_type_t sig; |
718 | | jit_type_t arg_t[] = { jit_type_void_ptr, jit_type_void_ptr }; |
719 | | jit_value_t arg_v[] = { v1, v2 }; |
720 | | |
721 | | sig = jit_type_create_signature(jit_abi_cdecl, jit_type_void_ptr, arg_t, 2, 1); |
722 | | |
723 | | return jit_insn_call_native(f, "Parrot_str_to_cstring", (void *)&Parrot_str_to_cstring, sig, arg_v, 2, 0); |
724 | | } |
725 | | |
726 | | jit_value_t |
727 | | jit__get_nci_S(jit_function_t f, jit_value_t v1, jit_value_t v2, jit_value_t v3) { |
728 | | jit_type_t sig; |
729 | | jit_type_t arg_t[] = { jit_type_void_ptr, jit_type_void_ptr, jit_type_sys_int }; |
730 | | jit_value_t arg_v[] = { v1, v2, v3 }; |
731 | | |
732 | | sig = jit_type_create_signature(jit_abi_cdecl, jit_type_void_ptr, arg_t, 3, 1); |
733 | | |
734 | | return jit_insn_call_native(f, "get_nci_S", (void *)&get_nci_S, sig, arg_v, 3, 0); |
735 | | } |
736 | | |
737 | | jit_value_t |
738 | | jit__set_nci_S(jit_function_t f, jit_value_t v1, jit_value_t v2, jit_value_t v3) { |
739 | | jit_type_t sig; |
740 | | jit_type_t arg_t[] = { jit_type_void_ptr, jit_type_void_ptr, jit_type_void_ptr }; |
741 | | jit_value_t arg_v[] = { v1, v2, v3 }; |
742 | | |
743 | | sig = jit_type_create_signature(jit_abi_cdecl, jit_type_void, arg_t, 3, 1); |
744 | | |
745 | | return jit_insn_call_native(f, "set_nci_S", (void *)&set_nci_S, sig, arg_v, 3, 0); |
746 | | } |
747 | | |
748 | | jit_value_t |
749 | | jit__set_nci_N(jit_function_t f, jit_value_t v1, jit_value_t v2, jit_value_t v3) { |
750 | | jit_type_t sig; |
751 | | jit_type_t arg_t[] = { jit_type_void_ptr, jit_type_void_ptr, JIT_TYPE_FLOATVAL }; |
752 | | jit_value_t arg_v[] = { v1, v2, v3 }; |
753 | | |
754 | | sig = jit_type_create_signature(jit_abi_cdecl, jit_type_void, arg_t, 3, 1); |
755 | | |
756 | | return jit_insn_call_native(f, "set_nci_N", (void *)&set_nci_N, sig, arg_v, 3, 0); |
757 | | } |
758 | | |
759 | | jit_value_t |
760 | | jit__Parrot_init_arg_nci(jit_function_t f, jit_value_t v1, jit_value_t v2, jit_value_t v3) { |
761 | | jit_type_t sig; |
762 | | jit_type_t arg_t[] = { jit_type_void_ptr, jit_type_void_ptr, jit_type_void_ptr }; |
763 | | jit_value_t arg_v[] = { v1, v2, v3 }; |
764 | | |
765 | | sig = jit_type_create_signature(jit_abi_cdecl, jit_type_void_ptr, arg_t, 3, 1); |
766 | | |
767 | | return jit_insn_call_native(f, "Parrot_init_arg_nci", (void *)&Parrot_init_arg_nci, sig, arg_v, 3, 0); |
768 | | } |
769 | | |
770 | | jit_value_t |
771 | | jit__get_nci_I(jit_function_t f, jit_value_t v1, jit_value_t v2, jit_value_t v3) { |
772 | | jit_type_t sig; |
773 | | jit_type_t arg_t[] = { jit_type_void_ptr, jit_type_void_ptr, jit_type_sys_int }; |
774 | | jit_value_t arg_v[] = { v1, v2, v3 }; |
775 | | |
776 | | sig = jit_type_create_signature(jit_abi_cdecl, JIT_TYPE_INTVAL, arg_t, 3, 1); |
777 | | |
778 | | return jit_insn_call_native(f, "get_nci_I", (void *)&get_nci_I, sig, arg_v, 3, 0); |
779 | | } |
780 | | |
781 | | jit_value_t |
782 | | jit__set_nci_I(jit_function_t f, jit_value_t v1, jit_value_t v2, jit_value_t v3) { |
783 | | jit_type_t sig; |
784 | | jit_type_t arg_t[] = { jit_type_void_ptr, jit_type_void_ptr, JIT_TYPE_INTVAL }; |
785 | | jit_value_t arg_v[] = { v1, v2, v3 }; |
786 | | |
787 | | sig = jit_type_create_signature(jit_abi_cdecl, jit_type_void, arg_t, 3, 1); |
788 | | |
789 | | return jit_insn_call_native(f, "set_nci_I", (void *)&set_nci_I, sig, arg_v, 3, 0); |
790 | | } |
791 | | |
792 | | jit_value_t |
793 | | jit__Parrot_str_new(jit_function_t f, jit_value_t v1, jit_value_t v2, jit_value_t v3) { |
794 | | jit_type_t sig; |
795 | | jit_type_t arg_t[] = { jit_type_void_ptr, jit_type_void_ptr, JIT_TYPE_UINTVAL }; |
796 | | jit_value_t arg_v[] = { v1, v2, v3 }; |
797 | | |
798 | | sig = jit_type_create_signature(jit_abi_cdecl, jit_type_void_ptr, arg_t, 3, 1); |
799 | | |
800 | | return jit_insn_call_native(f, "Parrot_str_new", (void *)&Parrot_str_new, sig, arg_v, 3, 0); |
801 | | } |
802 | | |
803 | | jit_value_t |
804 | | jit__set_nci_P(jit_function_t f, jit_value_t v1, jit_value_t v2, jit_value_t v3) { |
805 | | jit_type_t sig; |
806 | | jit_type_t arg_t[] = { jit_type_void_ptr, jit_type_void_ptr, jit_type_void_ptr }; |
807 | | jit_value_t arg_v[] = { v1, v2, v3 }; |
808 | | |
809 | | sig = jit_type_create_signature(jit_abi_cdecl, jit_type_void, arg_t, 3, 1); |
810 | | |
811 | | return jit_insn_call_native(f, "set_nci_P", (void *)&set_nci_P, sig, arg_v, 3, 0); |
812 | | } |
813 | | |
814 | | jit_value_t |
815 | | jit__get_nci_p(jit_function_t f, jit_value_t v1, jit_value_t v2, jit_value_t v3) { |
816 | | jit_type_t sig; |
817 | | jit_type_t arg_t[] = { jit_type_void_ptr, jit_type_void_ptr, jit_type_sys_int }; |
818 | | jit_value_t arg_v[] = { v1, v2, v3 }; |
819 | | |
820 | | sig = jit_type_create_signature(jit_abi_cdecl, jit_type_void_ptr, arg_t, 3, 1); |
821 | | |
822 | | return jit_insn_call_native(f, "get_nci_p", (void *)&get_nci_p, sig, arg_v, 3, 0); |
823 | | } |
824 | | |
825 | | jit_value_t |
826 | | jit__get_nci_P(jit_function_t f, jit_value_t v1, jit_value_t v2, jit_value_t v3) { |
827 | | jit_type_t sig; |
828 | | jit_type_t arg_t[] = { jit_type_void_ptr, jit_type_void_ptr, jit_type_sys_int }; |
829 | | jit_value_t arg_v[] = { v1, v2, v3 }; |
830 | | |
831 | | sig = jit_type_create_signature(jit_abi_cdecl, jit_type_void_ptr, arg_t, 3, 1); |
832 | | |
833 | | return jit_insn_call_native(f, "get_nci_P", (void *)&get_nci_P, sig, arg_v, 3, 0); |
834 | | } |
835 | | |
836 | | jit_value_t |
837 | | jit__pmc_new_noinit(jit_function_t f, jit_value_t v1, jit_value_t v2) { |
838 | | jit_type_t sig; |
839 | | jit_type_t arg_t[] = { jit_type_void_ptr, JIT_TYPE_INTVAL }; |
840 | | jit_value_t arg_v[] = { v1, v2 }; |
841 | | |
842 | | sig = jit_type_create_signature(jit_abi_cdecl, jit_type_void_ptr, arg_t, 2, 1); |
843 | | |
844 | | return jit_insn_call_native(f, "pmc_new_noinit", (void *)&pmc_new_noinit, sig, arg_v, 2, 0); |
845 | | } |
846 | | |
847 | | |
848 | | #endif /* PARROT_HAS_LIBJIT */ |
849 | | |
850 | | /* |
851 | | * Local variables: |
852 | | * c-file-style: "parrot" |
853 | | * End: |
854 | | * vim: expandtab shiftwidth=4: |
855 | | */ |