diff options
| author | kr.angelov <kr.angelov@gmail.com> | 2014-09-05 10:09:43 +0000 |
|---|---|---|
| committer | kr.angelov <kr.angelov@gmail.com> | 2014-09-05 10:09:43 +0000 |
| commit | 86b5f78c579ce5fcc9c96370644c41c35a421070 (patch) | |
| tree | 8a3034c3e366c901f8bb06ee3733d096fdb8b95a /src/runtime/c | |
| parent | a21ffc194185165ab487e0553cd5c4d0a36a8a9d (diff) | |
full support for recursive def rules in the C runtime
Diffstat (limited to 'src/runtime/c')
| -rw-r--r-- | src/runtime/c/pgf/data.h | 11 | ||||
| -rw-r--r-- | src/runtime/c/pgf/jit.c | 528 |
2 files changed, 304 insertions, 235 deletions
diff --git a/src/runtime/c/pgf/data.h b/src/runtime/c/pgf/data.h index bbf3351cb..f2e646a50 100644 --- a/src/runtime/c/pgf/data.h +++ b/src/runtime/c/pgf/data.h @@ -104,21 +104,26 @@ typedef struct { } PgfAbstr; typedef enum { - PGF_INSTR_EVAL, + PGF_INSTR_ENTER, + PGF_INSTR_EVAL_ARG_VAR, + PGF_INSTR_EVAL_FREE_VAR, PGF_INSTR_CASE, PGF_INSTR_CASE_INT, PGF_INSTR_CASE_STR, PGF_INSTR_CASE_FLT, PGF_INSTR_ALLOC, PGF_INSTR_PUT_CONSTR, + PGF_INSTR_PUT_FUN, PGF_INSTR_PUT_CLOSURE, PGF_INSTR_PUT_INT, PGF_INSTR_PUT_STR, PGF_INSTR_PUT_FLT, PGF_INSTR_SET_VALUE, - PGF_INSTR_SET_VARIABLE, + PGF_INSTR_SET_ARG_VAR, + PGF_INSTR_SET_FREE_VAR, PGF_INSTR_PUSH_VALUE, - PGF_INSTR_PUSH_VARIABLE, + PGF_INSTR_PUSH_ARG_VAR, + PGF_INSTR_PUSH_FREE_VAR, PGF_INSTR_TAIL_CALL, PGF_INSTR_FAIL, PGF_INSTR_RET diff --git a/src/runtime/c/pgf/jit.c b/src/runtime/c/pgf/jit.c index 0efaa7fd2..24e9ee0d8 100644 --- a/src/runtime/c/pgf/jit.c +++ b/src/runtime/c/pgf/jit.c @@ -14,7 +14,7 @@ struct PgfJitState { jit_insn *buf; char *save_ip_ptr; GuBuf* call_patches; - GuBuf* label_patches; + GuBuf* segment_patches; }; #define _jit (rdr->jit_state->jit) @@ -25,9 +25,10 @@ typedef struct { } PgfCallPatch; typedef struct { - size_t label; + size_t segment; jit_insn *ref; -} PgfLabelPatch; + bool is_abs; +} PgfSegmentPatch; // Between two calls to pgf_jit_make_space we are not allowed // to emit more that JIT_CODE_WINDOW bytes. This is not quite @@ -78,7 +79,7 @@ pgf_new_jit(PgfReader* rdr) { PgfJitState* state = gu_new(PgfJitState, rdr->tmp_pool); state->call_patches = gu_new_buf(PgfCallPatch, rdr->tmp_pool); - state->label_patches = gu_new_buf(PgfLabelPatch, rdr->tmp_pool); + state->segment_patches = gu_new_buf(PgfSegmentPatch, rdr->tmp_pool); state->buf = NULL; state->save_ip_ptr = NULL; return state; @@ -333,282 +334,345 @@ pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr, absfun->function = jit_get_ip().ptr; - jit_prolog(2); - - int es_arg = jit_arg_p(); - int closure_arg = jit_arg_p(); - - size_t n_instrs = pgf_read_len(rdr); + size_t n_segments = pgf_read_len(rdr); gu_return_on_exn(rdr->err, ); - - size_t curr_offset = 0; - size_t curr_label = 0; - - gu_buf_flush(rdr->jit_state->label_patches); - - for (size_t i = 0; i < n_instrs; i++) { - size_t labels_count = gu_buf_length(rdr->jit_state->label_patches); - if (labels_count > 0) { - PgfLabelPatch* patch = - gu_buf_index(rdr->jit_state->label_patches, PgfLabelPatch, labels_count-1); - if (patch->label == curr_label) { - jit_patch(patch->ref); - gu_buf_trim_n(rdr->jit_state->label_patches, 1); + + gu_buf_flush(rdr->jit_state->segment_patches); + + int es_arg = 0; + int closure_arg = 0; + + for (size_t segment = 0; segment < n_segments; segment++) { + size_t n_instrs = pgf_read_len(rdr); + gu_return_on_exn(rdr->err, ); + + size_t curr_offset = 0; + + size_t n_patches = gu_buf_length(rdr->jit_state->segment_patches); + if (n_patches > 0) { + PgfSegmentPatch* patch = + gu_buf_index(rdr->jit_state->segment_patches, PgfSegmentPatch, n_patches-1); + if (patch->segment == segment) { + if (patch->is_abs) + jit_patch_movi(patch->ref,jit_get_ip().ptr); + else + jit_patch(patch->ref); + gu_buf_trim_n(rdr->jit_state->segment_patches, 1); } } #ifdef PGF_JIT_DEBUG - gu_printf(out, err, "%04d ", curr_label); + gu_printf(out, err, "%03d ", segment); #endif - curr_label++; - uint8_t opcode = pgf_read_tag(rdr); - switch (opcode) { - case PGF_INSTR_EVAL: { - size_t index = pgf_read_int(rdr); + for (size_t label = 0; label < n_instrs; label++) { #ifdef PGF_JIT_DEBUG - gu_printf(out, err, "EVAL %d\n", index); + if (label > 0) + gu_printf(out, err, " "); #endif - jit_getarg_p(JIT_V0, es_arg); - jit_ldxi_p(JIT_V0, JIT_V0, offsetof(PgfEvalState,stack)); - jit_prepare(1); - jit_pusharg_p(JIT_V0); - jit_finish(gu_buf_last); - jit_ldxi_p(JIT_V0, JIT_RET, -index*sizeof(PgfClosure*)); - jit_prepare(2); - jit_pusharg_p(JIT_V0); - jit_getarg_p(JIT_V2, es_arg); - jit_pusharg_p(JIT_V2); - jit_ldr_p(JIT_V0, JIT_V0); - jit_finishr(JIT_V0); - jit_retval_p(JIT_V1); - jit_ldxi_p(JIT_V0, JIT_V1, offsetof(PgfValue, absfun)); - break; - } - case PGF_INSTR_CASE: { - PgfCId id = pgf_read_cid(rdr, rdr->opool); - int offset = pgf_read_int(rdr); -#ifdef PGF_JIT_DEBUG - gu_printf(out, err, "CASE %s %04d\n", id, curr_label+offset); -#endif - jit_insn *jump= - jit_bnei_i(jit_forward(), JIT_V0, (int) jit_forward()); - - PgfLabelPatch label_patch; - label_patch.label = curr_label+offset; - label_patch.ref = jump; - gu_buf_push(rdr->jit_state->label_patches, PgfLabelPatch, label_patch); - - PgfCallPatch call_patch; - call_patch.cid = id; - call_patch.ref = jump-6; - gu_buf_push(rdr->jit_state->call_patches, PgfCallPatch, call_patch); - - jit_prepare(2); - jit_pusharg_p(JIT_V1); - jit_getarg_p(JIT_V2, es_arg); - jit_pusharg_p(JIT_V2); - jit_finish(pgf_evaluate_save_variables); - break; - } - case PGF_INSTR_CASE_INT: { - int n = pgf_read_int(rdr); - int offset = pgf_read_int(rdr); + uint8_t opcode = pgf_read_tag(rdr); + switch (opcode) { + case PGF_INSTR_ENTER: { #ifdef PGF_JIT_DEBUG - gu_printf(out, err, "CASE_INT %d %04d\n", n, curr_label+offset); + gu_printf(out, err, "ENTER\n"); #endif - break; - } - case PGF_INSTR_CASE_STR: { - GuString s = pgf_read_string(rdr); - int offset = pgf_read_int(rdr); + + jit_prolog(2); + es_arg = jit_arg_p(); + closure_arg = jit_arg_p(); + break; + } + case PGF_INSTR_EVAL_ARG_VAR: { + size_t index = pgf_read_int(rdr); #ifdef PGF_JIT_DEBUG - gu_printf(out, err, "CASE_STR %s %04d\n", s, curr_label+offset); + gu_printf(out, err, "EVAL_ARG_VAR %d\n", index); #endif - break; - } - case PGF_INSTR_CASE_FLT: { - double d = pgf_read_double(rdr); - int offset = pgf_read_int(rdr); + + jit_getarg_p(JIT_V0, es_arg); + jit_ldxi_p(JIT_V0, JIT_V0, offsetof(PgfEvalState,stack)); + jit_prepare(1); + jit_pusharg_p(JIT_V0); + jit_finish(gu_buf_last); + jit_ldxi_p(JIT_V0, JIT_RET, -index*sizeof(PgfClosure*)); + jit_prepare(2); + jit_pusharg_p(JIT_V0); + jit_getarg_p(JIT_V2, es_arg); + jit_pusharg_p(JIT_V2); + jit_ldr_p(JIT_V0, JIT_V0); + jit_finishr(JIT_V0); + jit_retval_p(JIT_V1); + jit_ldxi_p(JIT_V0, JIT_V1, offsetof(PgfValue, absfun)); + break; + } + case PGF_INSTR_CASE: { + PgfCId id = pgf_read_cid(rdr, rdr->opool); + int target = pgf_read_int(rdr); #ifdef PGF_JIT_DEBUG - gu_printf(out, err, "CASE_FLT %f %04d\n", d, curr_label+offset); + gu_printf(out, err, "CASE %s %03d\n", id, target); #endif - break; - } - case PGF_INSTR_ALLOC: { - size_t size = pgf_read_int(rdr); -#ifdef PGF_JIT_DEBUG - gu_printf(out, err, "ALLOC %d\n", size); -#endif - jit_prepare(2); - jit_movi_ui(JIT_V0, size*sizeof(void*)); - jit_pusharg_ui(JIT_V0); - jit_getarg_p(JIT_V0, es_arg); - jit_ldxi_p(JIT_V0, JIT_V0, offsetof(PgfEvalState,pool)); - jit_pusharg_p(JIT_V0); - jit_finish(gu_malloc); - jit_retval_p(JIT_V1); - - curr_offset = 0; - break; - } - case PGF_INSTR_PUT_CONSTR: { - PgfCId id = pgf_read_cid(rdr, rdr->tmp_pool); + jit_insn *jump= + jit_bnei_i(jit_forward(), JIT_V0, (int) jit_forward()); + + PgfSegmentPatch label_patch; + label_patch.segment = target; + label_patch.ref = jump; + label_patch.is_abs = false; + gu_buf_push(rdr->jit_state->segment_patches, PgfSegmentPatch, label_patch); + + PgfCallPatch call_patch; + call_patch.cid = id; + call_patch.ref = jump-6; + gu_buf_push(rdr->jit_state->call_patches, PgfCallPatch, call_patch); + + jit_prepare(2); + jit_pusharg_p(JIT_V1); + jit_getarg_p(JIT_V2, es_arg); + jit_pusharg_p(JIT_V2); + jit_finish(pgf_evaluate_save_variables); + break; + } + case PGF_INSTR_CASE_INT: { + int n = pgf_read_int(rdr); + int target = pgf_read_int(rdr); #ifdef PGF_JIT_DEBUG - gu_printf(out, err, "PUT_CONSTR %s\n", id); + gu_printf(out, err, "CASE_INT %d %03d\n", n, target); +#endif + break; + } + case PGF_INSTR_CASE_STR: { + GuString s = pgf_read_string(rdr); + int target = pgf_read_int(rdr); +#ifdef PGF_JIT_DEBUG + gu_printf(out, err, "CASE_STR %s %03d\n", s, target); +#endif + break; + } + case PGF_INSTR_CASE_FLT: { + double d = pgf_read_double(rdr); + int target = pgf_read_int(rdr); +#ifdef PGF_JIT_DEBUG + gu_printf(out, err, "CASE_FLT %f %03d\n", d, target); +#endif + break; + } + case PGF_INSTR_ALLOC: { + size_t size = pgf_read_int(rdr); +#ifdef PGF_JIT_DEBUG + gu_printf(out, err, "ALLOC %d\n", size); +#endif + jit_prepare(2); + jit_movi_ui(JIT_V0, size*sizeof(void*)); + jit_pusharg_ui(JIT_V0); + jit_getarg_p(JIT_V0, es_arg); + jit_ldxi_p(JIT_V0, JIT_V0, offsetof(PgfEvalState,pool)); + jit_pusharg_p(JIT_V0); + jit_finish(gu_malloc); + jit_retval_p(JIT_V1); + + curr_offset = 0; + break; + } + case PGF_INSTR_PUT_CONSTR: { + PgfCId id = pgf_read_cid(rdr, rdr->tmp_pool); +#ifdef PGF_JIT_DEBUG + gu_printf(out, err, "PUT_CONSTR %s\n", id); #endif - jit_movi_p(JIT_V0, pgf_evaluate_value); - jit_stxi_p(curr_offset*sizeof(void*), JIT_V1, JIT_V0); - curr_offset++; - - PgfCallPatch patch; - patch.cid = id; - patch.ref = jit_movi_p(JIT_V0, jit_forward()); - jit_stxi_p(curr_offset*sizeof(void*), JIT_V1, JIT_V0); - curr_offset++; + jit_movi_p(JIT_V0, pgf_evaluate_value); + jit_stxi_p(curr_offset*sizeof(void*), JIT_V1, JIT_V0); + curr_offset++; + + PgfCallPatch patch; + patch.cid = id; + patch.ref = jit_movi_p(JIT_V0, jit_forward()); + jit_stxi_p(curr_offset*sizeof(void*), JIT_V1, JIT_V0); + curr_offset++; - gu_buf_push(rdr->jit_state->call_patches, PgfCallPatch, patch); - break; - } - case PGF_INSTR_PUT_CLOSURE: { - size_t addr = pgf_read_int(rdr); + gu_buf_push(rdr->jit_state->call_patches, PgfCallPatch, patch); + break; + } + case PGF_INSTR_PUT_FUN: { + PgfCId id = pgf_read_cid(rdr, rdr->tmp_pool); #ifdef PGF_JIT_DEBUG - gu_printf(out, err, "PUT_CLOSURE %d\n", addr); + gu_printf(out, err, "PUT_FUN %s\n", id); #endif - break; - } - case PGF_INSTR_PUT_INT: { - size_t n = pgf_read_int(rdr); + + PgfCallPatch patch; + patch.cid = id; + patch.ref = jit_movi_p(JIT_V0, jit_forward()); + jit_ldxi_p(JIT_V0, JIT_V0, offsetof(PgfAbsFun,function)); + jit_stxi_p(curr_offset*sizeof(void*), JIT_V1, JIT_V0); + curr_offset++; + + gu_buf_push(rdr->jit_state->call_patches, PgfCallPatch, patch); + break; + } + case PGF_INSTR_PUT_CLOSURE: { + size_t target = pgf_read_int(rdr); #ifdef PGF_JIT_DEBUG - gu_printf(out, err, "PUT_INT %d\n", n); + gu_printf(out, err, "PUT_CLOSURE %03d\n", target); #endif - break; - } - case PGF_INSTR_PUT_STR: { - size_t addr = pgf_read_int(rdr); + + PgfSegmentPatch patch; + patch.segment = target; + patch.ref = jit_movi_p(JIT_V0, jit_forward()); + patch.is_abs = true; + jit_stxi_p(curr_offset*sizeof(void*), JIT_V1, JIT_V0); + curr_offset++; + + gu_buf_push(rdr->jit_state->segment_patches, PgfSegmentPatch, patch); + break; + } + case PGF_INSTR_PUT_INT: { + size_t n = pgf_read_int(rdr); #ifdef PGF_JIT_DEBUG - gu_printf(out, err, "PUT_STR %d\n", addr); + gu_printf(out, err, "PUT_INT %d\n", n); #endif - break; - } - case PGF_INSTR_PUT_FLT: { - size_t addr = pgf_read_int(rdr); + break; + } + case PGF_INSTR_PUT_STR: { + size_t addr = pgf_read_int(rdr); #ifdef PGF_JIT_DEBUG - gu_printf(out, err, "PUT_FLT %d\n", addr); + gu_printf(out, err, "PUT_STR %d\n", addr); #endif - - break; - } - case PGF_INSTR_SET_VALUE: { - size_t offset = pgf_read_int(rdr); + break; + } + case PGF_INSTR_PUT_FLT: { + size_t addr = pgf_read_int(rdr); #ifdef PGF_JIT_DEBUG - gu_printf(out, err, "SET_VALUE %d\n", offset); + gu_printf(out, err, "PUT_FLT %d\n", addr); #endif - jit_addi_p(JIT_V0, JIT_V1, offset*sizeof(void*)); - jit_stxi_p(curr_offset*sizeof(void*), JIT_V1, JIT_V0); - curr_offset++; - break; - } - case PGF_INSTR_SET_VARIABLE: { - size_t index = pgf_read_int(rdr); + + break; + } + case PGF_INSTR_SET_VALUE: { + size_t offset = pgf_read_int(rdr); +#ifdef PGF_JIT_DEBUG + gu_printf(out, err, "SET_VALUE %d\n", offset); +#endif + jit_addi_p(JIT_V0, JIT_V1, offset*sizeof(void*)); + jit_stxi_p(curr_offset*sizeof(void*), JIT_V1, JIT_V0); + curr_offset++; + break; + } + case PGF_INSTR_SET_ARG_VAR: { + size_t index = pgf_read_int(rdr); #ifdef PGF_JIT_DEBUG - gu_printf(out, err, "SET_VARIABLE %d\n", index); + gu_printf(out, err, "SET_ARG_VAR %d\n", index); #endif - jit_getarg_p(JIT_V0, es_arg); - jit_ldxi_p(JIT_V0, JIT_V0, offsetof(PgfEvalState,stack)); - jit_prepare(1); - jit_pusharg_p(JIT_V0); - jit_finish(gu_buf_last); - jit_ldxi_p(JIT_V0, JIT_RET, -index*sizeof(PgfClosure*)); - jit_stxi_p(curr_offset*sizeof(void*), JIT_V1, JIT_V0); - curr_offset++; - break; - } - case PGF_INSTR_PUSH_VALUE: { - size_t offset = pgf_read_int(rdr); + jit_getarg_p(JIT_V0, es_arg); + jit_ldxi_p(JIT_V0, JIT_V0, offsetof(PgfEvalState,stack)); + jit_prepare(1); + jit_pusharg_p(JIT_V0); + jit_finish(gu_buf_last); + jit_ldxi_p(JIT_V0, JIT_RET, -index*sizeof(PgfClosure*)); + jit_stxi_p(curr_offset*sizeof(void*), JIT_V1, JIT_V0); + curr_offset++; + break; + } + case PGF_INSTR_PUSH_VALUE: { + size_t offset = pgf_read_int(rdr); #ifdef PGF_JIT_DEBUG - gu_printf(out, err, "PUSH_VALUE %d\n", offset); + gu_printf(out, err, "PUSH_VALUE %d\n", offset); #endif - jit_getarg_p(JIT_V0, es_arg); - jit_ldxi_p(JIT_V0, JIT_V0, offsetof(PgfEvalState,stack)); - jit_prepare(1); - jit_pusharg_p(JIT_V0); - jit_finish(gu_buf_extend); - if (offset == 0) { - jit_str_p(JIT_RET, JIT_V1); - } else { - jit_addi_p(JIT_V0, JIT_V1, offset*sizeof(void*)); + jit_getarg_p(JIT_V0, es_arg); + jit_ldxi_p(JIT_V0, JIT_V0, offsetof(PgfEvalState,stack)); + jit_prepare(1); + jit_pusharg_p(JIT_V0); + jit_finish(gu_buf_extend); + if (offset == 0) { + jit_str_p(JIT_RET, JIT_V1); + } else { + jit_addi_p(JIT_V0, JIT_V1, offset*sizeof(void*)); + jit_str_p(JIT_RET, JIT_V0); + } + break; + } + case PGF_INSTR_PUSH_ARG_VAR: { + size_t index = pgf_read_int(rdr); +#ifdef PGF_JIT_DEBUG + gu_printf(out, err, "PUSH_ARG_VAR %d\n", index); +#endif + + jit_getarg_p(JIT_V0, es_arg); + jit_ldxi_p(JIT_V0, JIT_V0, offsetof(PgfEvalState,stack)); + jit_prepare(1); + jit_pusharg_p(JIT_V0); + jit_finish(gu_buf_extend); + jit_ldxi_p(JIT_V0, JIT_RET, -(index+1)*sizeof(PgfClosure*)); jit_str_p(JIT_RET, JIT_V0); + break; } - break; - } - case PGF_INSTR_PUSH_VARIABLE: { - size_t index = pgf_read_int(rdr); + case PGF_INSTR_PUSH_FREE_VAR: { + size_t index = pgf_read_int(rdr); #ifdef PGF_JIT_DEBUG - gu_printf(out, err, "PUSH_VARIABLE %d\n", index); + gu_printf(out, err, "PUSH_FREE_VAR %d\n", index); #endif - jit_getarg_p(JIT_V0, es_arg); - jit_ldxi_p(JIT_V0, JIT_V0, offsetof(PgfEvalState,stack)); - jit_prepare(1); - jit_pusharg_p(JIT_V0); - jit_finish(gu_buf_extend); - jit_ldxi_p(JIT_V0, JIT_RET, -(index+1)*sizeof(PgfClosure*)); - jit_str_p(JIT_RET, JIT_V0); - break; - } - case PGF_INSTR_TAIL_CALL: { - PgfCId id = pgf_read_cid(rdr, rdr->tmp_pool); -#ifdef PGF_JIT_DEBUG - gu_printf(out, err, "TAIL_CALL %s\n", id); -#endif - - jit_getarg_p(JIT_V0, es_arg); - jit_getarg_p(JIT_V1, closure_arg); - jit_prepare(2); - jit_pusharg_p(JIT_V1); - jit_pusharg_p(JIT_V0); - - PgfCallPatch patch; - patch.cid = id; - patch.ref = jit_movi_p(JIT_V0, jit_forward()); - gu_buf_push(rdr->jit_state->call_patches, PgfCallPatch, patch); - jit_ldxi_p(JIT_V0, JIT_V0, offsetof(PgfAbsFun,function)); - - jit_finishr(JIT_V0); - jit_retval_p(JIT_V1); - break; - } - case PGF_INSTR_FAIL: + jit_getarg_p(JIT_V0, es_arg); + jit_ldxi_p(JIT_V0, JIT_V0, offsetof(PgfEvalState,stack)); + jit_prepare(1); + jit_pusharg_p(JIT_V0); + jit_finish(gu_buf_extend); + jit_getarg_p(JIT_V0, closure_arg); + jit_ldxi_p(JIT_V0, JIT_V0, sizeof(PgfClosure)+index*sizeof(PgfClosure*)); + jit_str_p(JIT_RET, JIT_V0); + break; + } + case PGF_INSTR_TAIL_CALL: { + PgfCId id = pgf_read_cid(rdr, rdr->tmp_pool); #ifdef PGF_JIT_DEBUG - gu_printf(out, err, "FAIL\n"); + gu_printf(out, err, "TAIL_CALL %s\n", id); #endif - break; - case PGF_INSTR_RET: { - size_t count = pgf_read_int(rdr); + + jit_getarg_p(JIT_V0, es_arg); + jit_getarg_p(JIT_V1, closure_arg); + jit_prepare(2); + jit_pusharg_p(JIT_V1); + jit_pusharg_p(JIT_V0); + PgfCallPatch patch; + patch.cid = id; + patch.ref = jit_movi_p(JIT_V0, jit_forward()); + gu_buf_push(rdr->jit_state->call_patches, PgfCallPatch, patch); + jit_ldxi_p(JIT_V0, JIT_V0, offsetof(PgfAbsFun,function)); + + jit_finishr(JIT_V0); + jit_retval_p(JIT_V1); + break; + } + case PGF_INSTR_FAIL: #ifdef PGF_JIT_DEBUG - gu_printf(out, err, "RET %d\n", count); + gu_printf(out, err, "FAIL\n"); #endif + break; + case PGF_INSTR_RET: { + size_t count = pgf_read_int(rdr); - jit_prepare(2); - jit_movi_ui(JIT_V0, count); - jit_pusharg_p(JIT_V0); - jit_getarg_p(JIT_V0, es_arg); - jit_ldxi_p(JIT_V0, JIT_V0, offsetof(PgfEvalState,stack)); - jit_pusharg_p(JIT_V0); - jit_finish(gu_buf_trim_n); +#ifdef PGF_JIT_DEBUG + gu_printf(out, err, "RET %d\n", count); +#endif - jit_movr_p(JIT_RET, JIT_V1); - jit_ret(); - break; - } - default: - gu_impossible(); + if (count > 0) { + jit_prepare(2); + jit_movi_ui(JIT_V0, count); + jit_pusharg_p(JIT_V0); + jit_getarg_p(JIT_V0, es_arg); + jit_ldxi_p(JIT_V0, JIT_V0, offsetof(PgfEvalState,stack)); + jit_pusharg_p(JIT_V0); + jit_finish(gu_buf_trim_n); + } + + jit_movr_p(JIT_RET, JIT_V1); + jit_ret(); + break; + } + default: + gu_impossible(); + } } } } |
