diff options
author | Kimplul <kimi.h.kuparinen@gmail.com> | 2025-03-15 13:16:54 +0200 |
---|---|---|
committer | Kimplul <kimi.h.kuparinen@gmail.com> | 2025-03-15 13:16:54 +0200 |
commit | 912c07167705613c6db70e542723c7ec2c06c7ea (patch) | |
tree | 119b74c5af8508f663e6fd9cdbdf91b27723b023 /src/interp.c | |
parent | 2a2d096b61262c2059ea022379869b9c4a70eafa (diff) | |
download | ejit-912c07167705613c6db70e542723c7ec2c06c7ea.tar.gz ejit-912c07167705613c6db70e542723c7ec2c06c7ea.zip |
experiment with allocating regs on stack in interp
+ Avoids having to lug around an execution context, arguably simplified
things but now there's no real way to detect when we run out memory
for regs.
Diffstat (limited to 'src/interp.c')
-rw-r--r-- | src/interp.c | 105 |
1 files changed, 28 insertions, 77 deletions
diff --git a/src/interp.c b/src/interp.c index f8ba927..80a9edc 100644 --- a/src/interp.c +++ b/src/interp.c @@ -5,7 +5,7 @@ /* 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], bool run, void ***labels_wb) { static void *labels[OPCODE_COUNT] = { [MOVI] = &&MOVI, @@ -227,40 +227,35 @@ union interp_ret ejit_run(struct ejit_func *f, size_t argc, struct ejit_arg args if (f->arena) { 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->arena)(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->arena)(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->arena)(paramc, params) }; return (union interp_ret){ - .i = ((ejit_escape_i_t)f->arena)(argc, args) + .i = ((ejit_escape_i_t)f->arena)(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)); - 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 = alloca(sizeof(int64_t) * gpr_stats_len(&f->gpr)); + union fpr *fpr = alloca(sizeof(int64_t) * fpr_stats_len(&f->fpr)); + struct ejit_arg *args = alloca(sizeof(struct ejit_arg) * f->max_args); struct ejit_insn *insns = f->insns.buf; /* retval is kind of an unfortunate extra bit of state to keep track of, @@ -978,25 +973,25 @@ union interp_ret ejit_run(struct ejit_func *f, size_t argc, struct ejit_arg args DISPATCH(); DO(PARAM); - gpr[i.r2] = args[i.r0].u64; + gpr[i.r2] = params[i.r0].u64; 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 +1001,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); @@ -1016,95 +1011,55 @@ union interp_ret ejit_run(struct ejit_func *f, size_t argc, struct ejit_arg args else a = ejit_build_arg_f(i.r1, i.f); - 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; - - retval = ejit_run(f, argc, args, state, true, NULL).i; - - gpr = state->gprs.buf + prev_gprs; - fpr = (union fpr *)state->fprs.buf + prev_fprs; - args_shrink(&state->args, prev_argc); + retval = ejit_run(f, argc, args, true, NULL).i; + argc = 0; 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; - - retval = ejit_run(f, argc, args, state, true, NULL).i; - - gpr = state->gprs.buf + prev_gprs; - fpr = (union fpr *)state->fprs.buf + prev_fprs; - args_shrink(&state->args, prev_argc); + retval = ejit_run(f, argc, args, true, NULL).i; + argc = 0; DISPATCH(); 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; - - retval_f = ejit_run(f, argc, args, state, true, NULL).f; - - gpr = state->gprs.buf + prev_gprs; - fpr = (union fpr *)state->fprs.buf + prev_fprs; - args_shrink(&state->args, prev_argc); + retval_f = ejit_run(f, argc, args, true, NULL).f; + 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; - - retval_f = ejit_run(f, argc, args, state, true, NULL).f; - - gpr = state->gprs.buf + prev_gprs; - fpr = (union fpr *)state->fprs.buf + prev_fprs; - args_shrink(&state->args, prev_argc); + retval_f = ejit_run(f, argc, args, true, NULL).f; + 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); + 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); + 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); + 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); + argc = 0; DISPATCH(); /* dispatch is technically unnecessary for returns, but keep it for @@ -1144,13 +1099,9 @@ union interp_ret ejit_run(struct ejit_func *f, size_t argc, struct ejit_arg args #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: |