diff options
Diffstat (limited to 'src/interp.c')
-rw-r--r-- | src/interp.c | 657 |
1 files changed, 333 insertions, 324 deletions
diff --git a/src/interp.c b/src/interp.c index f8ba927..894be30 100644 --- a/src/interp.c +++ b/src/interp.c @@ -5,262 +5,270 @@ /* this is the body of a given ejit_interp function, it assumes there's an * external int64_t retval and double retval_f into which it places the value to * be returned. Included from src/interp.c */ -union interp_ret ejit_run(struct ejit_func *f, size_t argc, struct ejit_arg args[argc], struct interp_state *state, bool run, void ***labels_wb) +union interp_ret ejit_run(struct ejit_func *f, size_t paramc, struct ejit_arg params[paramc], void ***labels_wb) { - static void *labels[OPCODE_COUNT] = { - [MOVI] = &&MOVI, - [MOVI_F] = &&MOVI_F, - [MOVI_D] = &&MOVI_D, - [MOVR] = &&MOVR, - [MOVR_F] = &&MOVR_F, - [MOVR_D] = &&MOVR_D, - - [EXTR8] = &&EXTR8, - [EXTR16] = &&EXTR16, - [EXTR32] = &&EXTR32, - [EXTRU8] = &&EXTRU8, - [EXTRU16] = &&EXTRU16, - [EXTRU32] = &&EXTRU32, - [EXTRF] = &&EXTRF, - [EXTRD] = &&EXTRD, - - [ADDR] = &&ADDR, - [ADDR_F] = &&ADDR_F, - [ADDR_D] = &&ADDR_D, - [ADDI] = &&ADDI, - - [ABSR_F] = &&ABSR_F, - [ABSR_D] = &&ABSR_D, - - [SUBR] = &&SUBR, - [SUBR_F] = &&SUBR_F, - [SUBR_D] = &&SUBR_D, - [SUBI] = &&SUBI, - - [MULR] = &&MULR, - [MULR_F] = &&MULR_F, - [MULR_D] = &&MULR_D, - - [DIVR] = &&DIVR, - [DIVR_U] = &&DIVR_U, - [DIVR_F] = &&DIVR_F, - [DIVR_D] = &&DIVR_D, - - [REMR] = &&REMR, - [REMR_U] = &&REMR_U, - - [LSHI] = &&LSHI, - [LSHR] = &&LSHR, - [RSHI] = &&RSHI, - [RSHR] = &&RSHR, - [RSHI_U] = &&RSHI_U, - [RSHR_U] = &&RSHR_U, - - [ANDR] = &&ANDR, - [ANDI] = &&ANDI, - - [ORR] = &&ORR, - [ORI] = &&ORI, - - [XORR] = &&XORR, - [XORI] = &&XORI, - - [COMR] = &&COMR, - [NEGR] = &&NEGR, - [NEGR_F] = &&NEGR_F, - [NEGR_D] = &&NEGR_D, - - [EQR] = &&EQR, - [EQR_F] = &&EQR_F, - [EQR_D] = &&EQR_D, - - [NER] = &&NER, - [NER_F] = &&NER_F, - [NER_D] = &&NER_D, - - [GTR] = &>R, - [GTR_U] = &>R_U, - [GTR_F] = &>R_F, - [GTR_D] = &>R_D, - - [GER] = &&GER, - [GER_U] = &&GER_U, - [GER_F] = &&GER_F, - [GER_D] = &&GER_D, - - [STI8] = &&STI8, - [STI16] = &&STI16, - [STI32] = &&STI32, - [STI64] = &&STI64, - [STIF] = &&STIF, - [STID] = &&STID, - - [STXI8] = &&STXI8, - [STXI16] = &&STXI16, - [STXI32] = &&STXI32, - [STXI64] = &&STXI64, - [STXIF] = &&STXIF, - [STXID] = &&STXID, - - [STXR8] = &&STXR8, - [STXR16] = &&STXR16, - [STXR32] = &&STXR32, - [STXR64] = &&STXR64, - [STXRF] = &&STXRF, - [STXRD] = &&STXRD, - - [LDI8] = &&LDI8, - [LDI16] = &&LDI16, - [LDI32] = &&LDI32, - [LDI64] = &&LDI64, - [LDIU8] = &&LDIU8, - [LDIU16] = &&LDIU16, - [LDIU32] = &&LDIU32, - [LDIU64] = &&LDIU64, - [LDIF] = &&LDIF, - [LDID] = &&LDID, - - [LDXI8] = &&LDXI8, - [LDXI16] = &&LDXI16, - [LDXI32] = &&LDXI32, - [LDXI64] = &&LDXI64, - [LDXIU8] = &&LDXIU8, - [LDXIU16] = &&LDXIU16, - [LDXIU32] = &&LDXIU32, - [LDXIU64] = &&LDXIU64, - [LDXIF] = &&LDXIF, - [LDXID] = &&LDXID, - - [LDXR8] = &&LDXR8, - [LDXR16] = &&LDXR16, - [LDXR32] = &&LDXR32, - [LDXR64] = &&LDXR64, - [LDXRU8] = &&LDXRU8, - [LDXRU16] = &&LDXRU16, - [LDXRU32] = &&LDXRU32, - [LDXRU64] = &&LDXRU64, - [LDXRF] = &&LDXRF, - [LDXRD] = &&LDXRD, - - [TRUNCR_D_32] = &&TRUNCR_D_32, - [TRUNCR_D_64] = &&TRUNCR_D_64, - [TRUNCR_F_32] = &&TRUNCR_F_32, - [TRUNCR_F_64] = &&TRUNCR_F_64, - - [BNER] = &&BNER, - [BNEI] = &&BNEI, - [BNER_F] = &&BNER_F, - [BNER_D] = &&BNER_D, - - [BEQR] = &&BEQR, - [BEQI] = &&BEQI, - [BEQR_F] = &&BEQR_F, - [BEQR_D] = &&BEQR_D, - - [BGER] = &&BGER, - [BGER_U] = &&BGER_U, - [BGEI] = &&BGEI, - [BGEI_U] = &&BGEI_U, - [BGER_F] = &&BGER_F, - [BGER_D] = &&BGER_D, - - [BLEI] = &&BLEI, - [BLEI_U] = &&BLEI_U, - - [BGTR] = &&BGTR, - [BGTR_U] = &&BGTR_U, - [BGTI] = &&BGTI, - [BGTI_U] = &&BGTI_U, - [BGTR_F] = &&BGTR_F, - [BGTR_D] = &&BGTR_D, - - [BLTI] = &&BLTI, - [BLTI_U] = &&BLTI_U, - - [JMP] = &&JMP, - [JMPR] = &&JMPR, - - [BMCI] = &&BMCI, - [BMCR] = &&BMCR, - [BMSI] = &&BMSI, - [BMSR] = &&BMSR, - - [RETR] = &&RETR, - [RETI] = &&RETI, - [RETR_F] = &&RETR_F, - [RETI_F] = &&RETI_F, - [RETR_D] = &&RETR_D, - [RETI_D] = &&RETI_D, - - [RETVAL] = &&RETVAL, - [RETVAL_F] = &&RETVAL_F, - [RETVAL_D] = &&RETVAL_D, - - [ARG] = &&ARG, - [ARG_I] = &&ARG_I, - [ARG_F] = &&ARG_F, - [ARG_FI] = &&ARG_FI, - - [PARAM] = &&PARAM, - [PARAM_F] = &&PARAM_F, - - [CALLI_I] = &&CALLI_I, - [CALLI_L] = &&CALLI_L, - [CALLI_F] = &&CALLI_F, - [CALLI_D] = &&CALLI_D, - [ESCAPEI_I] = &&ESCAPEI_I, - [ESCAPEI_F] = &&ESCAPEI_F, - [ESCAPEI_L] = &&ESCAPEI_L, - [ESCAPEI_D] = &&ESCAPEI_D, - - [START] = &&START, - [END] = &&END, + static void *labels[EJIT_OPCODE_COUNT] = { + [EJIT_OP_MOVI] = &&MOVI, + [EJIT_OP_MOVI_F] = &&MOVI_F, + [EJIT_OP_MOVI_D] = &&MOVI_D, + [EJIT_OP_MOVR] = &&MOVR, + [EJIT_OP_MOVR_F] = &&MOVR_F, + [EJIT_OP_MOVR_D] = &&MOVR_D, + + [EJIT_OP_EXTR8] = &&EXTR8, + [EJIT_OP_EXTR16] = &&EXTR16, + [EJIT_OP_EXTR32] = &&EXTR32, + [EJIT_OP_EXTRU8] = &&EXTRU8, + [EJIT_OP_EXTRU16] = &&EXTRU16, + [EJIT_OP_EXTRU32] = &&EXTRU32, + [EJIT_OP_EXTRF] = &&EXTRF, + [EJIT_OP_EXTRD] = &&EXTRD, + + [EJIT_OP_ADDR] = &&ADDR, + [EJIT_OP_ADDR_F] = &&ADDR_F, + [EJIT_OP_ADDR_D] = &&ADDR_D, + [EJIT_OP_ADDI] = &&ADDI, + + [EJIT_OP_ABSR_F] = &&ABSR_F, + [EJIT_OP_ABSR_D] = &&ABSR_D, + + [EJIT_OP_SUBR] = &&SUBR, + [EJIT_OP_SUBR_F] = &&SUBR_F, + [EJIT_OP_SUBR_D] = &&SUBR_D, + [EJIT_OP_SUBI] = &&SUBI, + + [EJIT_OP_MULR] = &&MULR, + [EJIT_OP_MULR_F] = &&MULR_F, + [EJIT_OP_MULR_D] = &&MULR_D, + + [EJIT_OP_DIVR] = &&DIVR, + [EJIT_OP_DIVR_U] = &&DIVR_U, + [EJIT_OP_DIVR_F] = &&DIVR_F, + [EJIT_OP_DIVR_D] = &&DIVR_D, + + [EJIT_OP_REMR] = &&REMR, + [EJIT_OP_REMR_U] = &&REMR_U, + + [EJIT_OP_LSHI] = &&LSHI, + [EJIT_OP_LSHR] = &&LSHR, + [EJIT_OP_RSHI] = &&RSHI, + [EJIT_OP_RSHR] = &&RSHR, + [EJIT_OP_RSHI_U] = &&RSHI_U, + [EJIT_OP_RSHR_U] = &&RSHR_U, + + [EJIT_OP_ANDR] = &&ANDR, + [EJIT_OP_ANDI] = &&ANDI, + + [EJIT_OP_ORR] = &&ORR, + [EJIT_OP_ORI] = &&ORI, + + [EJIT_OP_XORR] = &&XORR, + [EJIT_OP_XORI] = &&XORI, + + [EJIT_OP_COMR] = &&COMR, + [EJIT_OP_NEGR] = &&NEGR, + [EJIT_OP_NEGR_F] = &&NEGR_F, + [EJIT_OP_NEGR_D] = &&NEGR_D, + + [EJIT_OP_EQR] = &&EQR, + [EJIT_OP_EQR_F] = &&EQR_F, + [EJIT_OP_EQR_D] = &&EQR_D, + + [EJIT_OP_NER] = &&NER, + [EJIT_OP_NER_F] = &&NER_F, + [EJIT_OP_NER_D] = &&NER_D, + + [EJIT_OP_GTR] = &>R, + [EJIT_OP_GTR_U] = &>R_U, + [EJIT_OP_GTR_F] = &>R_F, + [EJIT_OP_GTR_D] = &>R_D, + + [EJIT_OP_GER] = &&GER, + [EJIT_OP_GER_U] = &&GER_U, + [EJIT_OP_GER_F] = &&GER_F, + [EJIT_OP_GER_D] = &&GER_D, + + [EJIT_OP_STI8] = &&STI8, + [EJIT_OP_STI16] = &&STI16, + [EJIT_OP_STI32] = &&STI32, + [EJIT_OP_STI64] = &&STI64, + [EJIT_OP_STIF] = &&STIF, + [EJIT_OP_STID] = &&STID, + + [EJIT_OP_STXI8] = &&STXI8, + [EJIT_OP_STXI16] = &&STXI16, + [EJIT_OP_STXI32] = &&STXI32, + [EJIT_OP_STXI64] = &&STXI64, + [EJIT_OP_STXIF] = &&STXIF, + [EJIT_OP_STXID] = &&STXID, + + [EJIT_OP_STXR8] = &&STXR8, + [EJIT_OP_STXR16] = &&STXR16, + [EJIT_OP_STXR32] = &&STXR32, + [EJIT_OP_STXR64] = &&STXR64, + [EJIT_OP_STXRF] = &&STXRF, + [EJIT_OP_STXRD] = &&STXRD, + + [EJIT_OP_LDI8] = &&LDI8, + [EJIT_OP_LDI16] = &&LDI16, + [EJIT_OP_LDI32] = &&LDI32, + [EJIT_OP_LDI64] = &&LDI64, + [EJIT_OP_LDIU8] = &&LDIU8, + [EJIT_OP_LDIU16] = &&LDIU16, + [EJIT_OP_LDIU32] = &&LDIU32, + [EJIT_OP_LDIU64] = &&LDIU64, + [EJIT_OP_LDIF] = &&LDIF, + [EJIT_OP_LDID] = &&LDID, + + [EJIT_OP_LDXI8] = &&LDXI8, + [EJIT_OP_LDXI16] = &&LDXI16, + [EJIT_OP_LDXI32] = &&LDXI32, + [EJIT_OP_LDXI64] = &&LDXI64, + [EJIT_OP_LDXIU8] = &&LDXIU8, + [EJIT_OP_LDXIU16] = &&LDXIU16, + [EJIT_OP_LDXIU32] = &&LDXIU32, + [EJIT_OP_LDXIU64] = &&LDXIU64, + [EJIT_OP_LDXIF] = &&LDXIF, + [EJIT_OP_LDXID] = &&LDXID, + + [EJIT_OP_LDXR8] = &&LDXR8, + [EJIT_OP_LDXR16] = &&LDXR16, + [EJIT_OP_LDXR32] = &&LDXR32, + [EJIT_OP_LDXR64] = &&LDXR64, + [EJIT_OP_LDXRU8] = &&LDXRU8, + [EJIT_OP_LDXRU16] = &&LDXRU16, + [EJIT_OP_LDXRU32] = &&LDXRU32, + [EJIT_OP_LDXRU64] = &&LDXRU64, + [EJIT_OP_LDXRF] = &&LDXRF, + [EJIT_OP_LDXRD] = &&LDXRD, + + [EJIT_OP_TRUNCR_D_32] = &&TRUNCR_D_32, + [EJIT_OP_TRUNCR_D_64] = &&TRUNCR_D_64, + [EJIT_OP_TRUNCR_F_32] = &&TRUNCR_F_32, + [EJIT_OP_TRUNCR_F_64] = &&TRUNCR_F_64, + + [EJIT_OP_SQRTR_F] = &&SQRTR_F, + [EJIT_OP_SQRTR_D] = &&SQRTR_D, + + [EJIT_OP_MINR_F] = &&MINR_F, + [EJIT_OP_MINR_D] = &&MINR_D, + + [EJIT_OP_MAXR_F] = &&MAXR_F, + [EJIT_OP_MAXR_D] = &&MAXR_D, + + [EJIT_OP_BNER] = &&BNER, + [EJIT_OP_BNEI] = &&BNEI, + [EJIT_OP_BNER_F] = &&BNER_F, + [EJIT_OP_BNER_D] = &&BNER_D, + + [EJIT_OP_BEQR] = &&BEQR, + [EJIT_OP_BEQI] = &&BEQI, + [EJIT_OP_BEQR_F] = &&BEQR_F, + [EJIT_OP_BEQR_D] = &&BEQR_D, + + [EJIT_OP_BGER] = &&BGER, + [EJIT_OP_BGER_U] = &&BGER_U, + [EJIT_OP_BGEI] = &&BGEI, + [EJIT_OP_BGEI_U] = &&BGEI_U, + [EJIT_OP_BGER_F] = &&BGER_F, + [EJIT_OP_BGER_D] = &&BGER_D, + + [EJIT_OP_BLEI] = &&BLEI, + [EJIT_OP_BLEI_U] = &&BLEI_U, + + [EJIT_OP_BGTR] = &&BGTR, + [EJIT_OP_BGTR_U] = &&BGTR_U, + [EJIT_OP_BGTI] = &&BGTI, + [EJIT_OP_BGTI_U] = &&BGTI_U, + [EJIT_OP_BGTR_F] = &&BGTR_F, + [EJIT_OP_BGTR_D] = &&BGTR_D, + + [EJIT_OP_BLTI] = &&BLTI, + [EJIT_OP_BLTI_U] = &&BLTI_U, + + [EJIT_OP_JMP] = &&JMP, + [EJIT_OP_JMPR] = &&JMPR, + + [EJIT_OP_BMCI] = &&BMCI, + [EJIT_OP_BMCR] = &&BMCR, + [EJIT_OP_BMSI] = &&BMSI, + [EJIT_OP_BMSR] = &&BMSR, + + [EJIT_OP_RETR] = &&RETR, + [EJIT_OP_RETI] = &&RETI, + [EJIT_OP_RETR_F] = &&RETR_F, + [EJIT_OP_RETI_F] = &&RETI_F, + [EJIT_OP_RETR_D] = &&RETR_D, + [EJIT_OP_RETI_D] = &&RETI_D, + + [EJIT_OP_RETVAL] = &&RETVAL, + [EJIT_OP_RETVAL_F] = &&RETVAL_F, + [EJIT_OP_RETVAL_D] = &&RETVAL_D, + + [EJIT_OP_ARG] = &&ARG, + [EJIT_OP_ARG_I] = &&ARG_I, + [EJIT_OP_ARG_F] = &&ARG_F, + [EJIT_OP_ARG_FI] = &&ARG_FI, + + [EJIT_OP_PARAM] = &&PARAM, + [EJIT_OP_PARAM_F] = &&PARAM_F, + + [EJIT_OP_CALLR_I] = &&CALLR_I, + [EJIT_OP_CALLR_L] = &&CALLR_L, + [EJIT_OP_CALLR_F] = &&CALLR_F, + [EJIT_OP_CALLR_D] = &&CALLR_D, + [EJIT_OP_CALLI] = &&CALLI, + + [EJIT_OP_TAILR] = &&TAILR, + [EJIT_OP_TAILI] = &&TAILI, + + [EJIT_OP_ESCAPEI_I] = &&ESCAPEI_I, + [EJIT_OP_ESCAPEI_L] = &&ESCAPEI_L, + [EJIT_OP_ESCAPEI_F] = &&ESCAPEI_F, + [EJIT_OP_ESCAPEI_D] = &&ESCAPEI_D, + + [EJIT_OP_START] = &&START, + [EJIT_OP_END] = &&END, }; - if (!run) { + if (labels_wb) { *labels_wb = labels; - goto zero_out; + return (union interp_ret){.i = 0}; } assert(f->size && "trying to run a function that hasn't been compiled"); - - if (f->arena) { + if (f->extern_call) { if (f->rtype == EJIT_INT64 || f->rtype == EJIT_UINT64) return (union interp_ret){ - .i = ((ejit_escape_l_t)f->arena)(argc, args) + .i = ((ejit_escape_l_t)f->extern_call)(paramc, params) }; if (f->rtype == EJIT_DOUBLE) return (union interp_ret){ - .f = ((ejit_escape_d_t)f->arena)(argc, args) + .f = ((ejit_escape_d_t)f->extern_call)(paramc, params) }; if (f->rtype == EJIT_FLOAT) return (union interp_ret){ - .f = ((ejit_escape_f_t)f->arena)(argc, args) + .f = ((ejit_escape_f_t)f->extern_call)(paramc, params) }; return (union interp_ret){ - .i = ((ejit_escape_i_t)f->arena)(argc, args) + .i = ((ejit_escape_i_t)f->extern_call)(paramc, params) }; } - int64_t retval = 0; double retval_f = 0.0; - - size_t prev_gprs = gprs_len(&state->gprs); - size_t prev_fprs = fprs_len(&state->fprs); - size_t prev_argc = args_len(&state->args); - - gprs_reserve(&state->gprs, prev_gprs + gpr_stats_len(&f->gpr)); - fprs_reserve(&state->fprs, prev_fprs + fpr_stats_len(&f->fpr)); - +top: + union interp_ret retval = {.i = 0}; union fpr { double d; float f; }; - int64_t *gpr = ((int64_t *)state->gprs.buf) + prev_gprs; - union fpr *fpr = ((union fpr *)state->fprs.buf) + prev_fprs; + size_t argc = 0; + int64_t gpr[gpr_stats_len(&f->gpr)]; + union fpr fpr[fpr_stats_len(&f->fpr)]; + struct ejit_arg args[f->max_args]; struct ejit_insn *insns = f->insns.buf; /* retval is kind of an unfortunate extra bit of state to keep track of, @@ -278,7 +286,7 @@ union interp_ret ejit_run(struct ejit_func *f, size_t argc, struct ejit_arg args DISPATCH(); DO(END); - goto zero_out; + return (union interp_ret){.i = 0}; DISPATCH(); DO(MOVI); @@ -789,6 +797,30 @@ union interp_ret ejit_run(struct ejit_func *f, size_t argc, struct ejit_arg args gpr[i.r0] = (int64_t)fpr[i.r1].f; DISPATCH(); + DO(SQRTR_F); + fpr[i.r0].f = sqrt(fpr[i.r1].f); + DISPATCH(); + + DO(MINR_F); + fpr[i.r0].f = fminf(fpr[i.r1].f, fpr[i.r2].f); + DISPATCH(); + + DO(MINR_D); + fpr[i.r0].d = fmin(fpr[i.r1].d, fpr[i.r2].d); + DISPATCH(); + + DO(MAXR_F); + fpr[i.r0].f = fmaxf(fpr[i.r1].f, fpr[i.r2].f); + DISPATCH(); + + DO(MAXR_D); + fpr[i.r0].d = fmax(fpr[i.r1].d, fpr[i.r2].d); + DISPATCH(); + + DO(SQRTR_D); + fpr[i.r0].d = sqrt(fpr[i.r1].d); + DISPATCH(); + DO(BNER); if (gpr[i.r1] != gpr[i.r2]) JUMP(i.r0); @@ -966,37 +998,48 @@ union interp_ret ejit_run(struct ejit_func *f, size_t argc, struct ejit_arg args DISPATCH(); DO(RETVAL); - gpr[i.r0] = retval; + gpr[i.r0] = retval.i; DISPATCH(); DO(RETVAL_F); - fpr[i.r0].f = retval_f; + fpr[i.r0].f = retval.f; DISPATCH(); DO(RETVAL_D); - fpr[i.r0].d = retval_f; + fpr[i.r0].d = retval.f; DISPATCH(); DO(PARAM); - gpr[i.r2] = args[i.r0].u64; + switch (i.r1) { + case EJIT_INT8: gpr[i.r2] = params[i.r0].i8; break; + case EJIT_INT16: gpr[i.r2] = params[i.r0].i16; break; + case EJIT_INT32: gpr[i.r2] = params[i.r0].i32; break; + case EJIT_INT64: gpr[i.r2] = params[i.r0].i64; break; + case EJIT_UINT8: gpr[i.r2] = params[i.r0].u8; break; + case EJIT_UINT16: gpr[i.r2] = params[i.r0].u16; break; + case EJIT_UINT32: gpr[i.r2] = params[i.r0].u32; break; + case EJIT_UINT64: gpr[i.r2] = params[i.r0].u64; break; + case EJIT_POINTER: gpr[i.r2] = (int64_t)params[i.r0].p; break; + default: abort(); + } DISPATCH(); DO(PARAM_F); if (i.r1 == EJIT_FLOAT) - fpr[i.r2].f = args[i.r0].f; + fpr[i.r2].f = params[i.r0].f; else - fpr[i.r2].d = args[i.r0].d; + fpr[i.r2].d = params[i.r0].d; DISPATCH(); DO(ARG); struct ejit_arg a = ejit_build_arg(i.r1, gpr[i.r2]); - args_append(&state->args, a); + args[argc++] = a; DISPATCH(); DO(ARG_I); struct ejit_arg a = ejit_build_arg(i.r1, i.o); - args_append(&state->args, a); + args[argc++] = a; DISPATCH(); DO(ARG_F); @@ -1006,7 +1049,7 @@ union interp_ret ejit_run(struct ejit_func *f, size_t argc, struct ejit_arg args else a = ejit_build_arg_f(i.r1, fpr[i.r2].f); - args_append(&state->args, a); + args[argc++] = a; DISPATCH(); DO(ARG_FI); @@ -1014,145 +1057,111 @@ union interp_ret ejit_run(struct ejit_func *f, size_t argc, struct ejit_arg args if (i.r1 == EJIT_DOUBLE) a = ejit_build_arg_f(i.r1, i.d); else - a = ejit_build_arg_f(i.r1, i.f); + a = ejit_build_arg_f(i.r1, i.d); - args_append(&state->args, a); + args[argc++] = a; DISPATCH(); - DO(CALLI_I); - struct ejit_func *f = i.p; - size_t argc = args_len(&state->args) - prev_argc; - struct ejit_arg *args = state->args.buf + prev_argc; + DO(TAILI); + f = (struct ejit_func *)i.p; + + assert(!f->direct_call && "trying to interpret compiled fun"); - retval = ejit_run(f, argc, args, state, true, NULL).i; + paramc = argc; + for (size_t i = 0; i < argc; ++i) + params[i] = args[i]; - gpr = state->gprs.buf + prev_gprs; - fpr = (union fpr *)state->fprs.buf + prev_fprs; - args_shrink(&state->args, prev_argc); + goto top; DISPATCH(); - DO(CALLI_L); - struct ejit_func *f = i.p; - size_t argc = args_len(&state->args) - prev_argc; - struct ejit_arg *args = state->args.buf + prev_argc; + DO(TAILR); + f = (struct ejit_func *)gpr[i.r1]; - retval = ejit_run(f, argc, args, state, true, NULL).i; + /** @todo we could potentially just interpret the func as a fallback + * instead of aborting here, but this is good enough for now */ + assert(!f->direct_call && "trying to interpret compiled fun"); - gpr = state->gprs.buf + prev_gprs; - fpr = (union fpr *)state->fprs.buf + prev_fprs; - args_shrink(&state->args, prev_argc); - DISPATCH(); + paramc = argc; + for (size_t i = 0; i < argc; ++i) + params[i] = args[i]; - DO(CALLI_F); - struct ejit_func *f = i.p; - size_t argc = args_len(&state->args) - prev_argc; - struct ejit_arg *args = state->args.buf + prev_argc; + goto top; + DISPATCH(); - retval_f = ejit_run(f, argc, args, state, true, NULL).f; + DO(CALLR_I); + retval = ejit_run((struct ejit_func *)gpr[i.r1], argc, args, NULL); + argc = 0; + DISPATCH(); - gpr = state->gprs.buf + prev_gprs; - fpr = (union fpr *)state->fprs.buf + prev_fprs; - args_shrink(&state->args, prev_argc); + DO(CALLR_L); + retval = ejit_run((struct ejit_func *)gpr[i.r1], argc, args, NULL); + argc = 0; DISPATCH(); - DO(CALLI_D); - struct ejit_func *f = i.p; - size_t argc = args_len(&state->args) - prev_argc; - struct ejit_arg *args = state->args.buf + prev_argc; + DO(CALLR_F); + retval = ejit_run((struct ejit_func *)gpr[i.r1], argc, args, NULL); + argc = 0; + DISPATCH(); - retval_f = ejit_run(f, argc, args, state, true, NULL).f; + DO(CALLR_D); + retval = ejit_run((struct ejit_func *)gpr[i.r1], argc, args, NULL); + argc = 0; + DISPATCH(); - gpr = state->gprs.buf + prev_gprs; - fpr = (union fpr *)state->fprs.buf + prev_fprs; - args_shrink(&state->args, prev_argc); + DO(CALLI); + retval = ejit_run((struct ejit_func *)i.p, argc, args, NULL); + argc = 0; DISPATCH(); DO(ESCAPEI_I); - ejit_escape_i_t f = i.p; - size_t argc = args_len(&state->args) - prev_argc; - struct ejit_arg *args = state->args.buf + prev_argc; - - retval = f(argc, args); - - args_shrink(&state->args, prev_argc); + retval.i = ((ejit_escape_i_t)i.p)(argc, args); + argc = 0; DISPATCH(); DO(ESCAPEI_L); - ejit_escape_l_t f = i.p; - size_t argc = args_len(&state->args) - prev_argc; - struct ejit_arg *args = state->args.buf + prev_argc; - - retval = f(argc, args); - - args_shrink(&state->args, prev_argc); + retval.i = ((ejit_escape_l_t)i.p)(argc, args); + argc = 0; DISPATCH(); DO(ESCAPEI_F); - ejit_escape_f_t f = i.p; - size_t argc = args_len(&state->args) - prev_argc; - struct ejit_arg *args = state->args.buf + prev_argc; - - retval_f = f(argc, args); - - args_shrink(&state->args, prev_argc); + retval.f = ((ejit_escape_f_t)i.p)(argc, args); + argc = 0; DISPATCH(); DO(ESCAPEI_D); - ejit_escape_d_t f = i.p; - size_t argc = args_len(&state->args) - prev_argc; - struct ejit_arg *args = state->args.buf + prev_argc; - - retval_f = f(argc, args); - - args_shrink(&state->args, prev_argc); + retval.f = ((ejit_escape_d_t)i.p)(argc, args); + argc = 0; DISPATCH(); /* dispatch is technically unnecessary for returns, but keep it for * symmetry */ DO(RETR); - retval = gpr[i.r1]; - goto out_int; + return (union interp_ret){.i = gpr[i.r1]}; DISPATCH(); DO(RETI); - retval = i.o; - goto out_int; + return (union interp_ret){.i = i.o}; DISPATCH(); DO(RETR_F); - retval_f = fpr[i.r1].f; - goto out_float; + return (union interp_ret){.f = fpr[i.r1].f}; DISPATCH(); DO(RETR_D); - retval_f = fpr[i.r1].d; - goto out_float; + return (union interp_ret){.f = fpr[i.r1].d}; DISPATCH(); DO(RETI_F); - retval_f = i.f; - goto out_float; + return (union interp_ret){.f = i.f}; DISPATCH(); DO(RETI_D); - retval_f = i.d; - goto out_float; + return (union interp_ret){.f = i.d}; DISPATCH(); #undef DISPATCH #undef JUMP #undef DO -out_float: - gprs_shrink(&state->gprs, prev_gprs); - fprs_shrink(&state->fprs, prev_fprs); - return (union interp_ret){.f = retval_f}; - -out_int: - gprs_shrink(&state->gprs, prev_gprs); - fprs_shrink(&state->fprs, prev_fprs); - return (union interp_ret){.i = retval}; - -zero_out: return (union interp_ret){.i = 0}; } |