aboutsummaryrefslogtreecommitdiff
path: root/src/interp.c
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2025-03-15 13:16:54 +0200
committerKimplul <kimi.h.kuparinen@gmail.com>2025-03-15 13:16:54 +0200
commit912c07167705613c6db70e542723c7ec2c06c7ea (patch)
tree119b74c5af8508f663e6fd9cdbdf91b27723b023 /src/interp.c
parent2a2d096b61262c2059ea022379869b9c4a70eafa (diff)
downloadejit-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.c105
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: