aboutsummaryrefslogtreecommitdiff
path: root/src/interp.c
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2025-04-09 19:56:33 +0300
committerKimplul <kimi.h.kuparinen@gmail.com>2025-04-09 19:56:33 +0300
commit6824dd4b1ee22184f0e600115db3998924ed39d6 (patch)
tree0afbf35344313bdd17238b4fb570af0d094f758d /src/interp.c
parent9e367e1824d62d3759cb19b7c9a433b67b96bd99 (diff)
downloadejit-6824dd4b1ee22184f0e600115db3998924ed39d6.tar.gz
ejit-6824dd4b1ee22184f0e600115db3998924ed39d6.zip
initial tail call stuff
Diffstat (limited to 'src/interp.c')
-rw-r--r--src/interp.c58
1 files changed, 26 insertions, 32 deletions
diff --git a/src/interp.c b/src/interp.c
index 6ef414d..132ba4a 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 paramc, struct ejit_arg params[paramc], 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[EJIT_OPCODE_COUNT] = {
[EJIT_OP_MOVI] = &&MOVI,
@@ -213,10 +213,9 @@ union interp_ret ejit_run(struct ejit_func *f, size_t paramc, struct ejit_arg pa
[EJIT_OP_PARAM] = &&PARAM,
[EJIT_OP_PARAM_F] = &&PARAM_F,
- [EJIT_OP_CALLI_I] = &&CALLI_I,
- [EJIT_OP_CALLI_L] = &&CALLI_L,
- [EJIT_OP_CALLI_F] = &&CALLI_F,
- [EJIT_OP_CALLI_D] = &&CALLI_D,
+ [EJIT_OP_CALLI] = &&CALLI,
+ [EJIT_OP_TAILR] = &&TAILR,
+
[EJIT_OP_ESCAPEI_I] = &&ESCAPEI_I,
[EJIT_OP_ESCAPEI_F] = &&ESCAPEI_F,
[EJIT_OP_ESCAPEI_L] = &&ESCAPEI_L,
@@ -226,13 +225,12 @@ union interp_ret ejit_run(struct ejit_func *f, size_t paramc, struct ejit_arg pa
[EJIT_OP_END] = &&END,
};
- if (!run) {
+ if (labels_wb) {
*labels_wb = labels;
return (union interp_ret){.i = 0};
}
assert(f->size && "trying to run a function that hasn't been compiled");
-
if (f->extern_call) {
if (f->rtype == EJIT_INT64 || f->rtype == EJIT_UINT64)
return (union interp_ret){
@@ -254,8 +252,8 @@ union interp_ret ejit_run(struct ejit_func *f, size_t paramc, struct ejit_arg pa
};
}
- int64_t retval = 0; double retval_f = 0.0;
-
+top:
+ union interp_ret retval = {.i = 0};
union fpr {
double d;
float f;
@@ -994,15 +992,15 @@ union interp_ret ejit_run(struct ejit_func *f, size_t paramc, struct ejit_arg pa
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);
@@ -1058,51 +1056,47 @@ union interp_ret ejit_run(struct ejit_func *f, size_t paramc, struct ejit_arg pa
args[argc++] = a;
DISPATCH();
- DO(CALLI_I);
- struct ejit_func *f = i.p;
- retval = ejit_run(f, argc, args, true, NULL).i;
- argc = 0;
- DISPATCH();
+ DO(TAILR);
+ f = (struct ejit_func *)gpr[i.r1];
- DO(CALLI_L);
- struct ejit_func *f = i.p;
- retval = ejit_run(f, argc, args, true, NULL).i;
- argc = 0;
- DISPATCH();
+ /** @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");
- DO(CALLI_F);
- struct ejit_func *f = i.p;
- retval_f = ejit_run(f, argc, args, true, NULL).f;
- argc = 0;
+ paramc = argc;
+ for (size_t i = 0; i < argc; ++i)
+ params[i] = args[i];
+
+ goto top;
DISPATCH();
- DO(CALLI_D);
+ DO(CALLI);
struct ejit_func *f = i.p;
- retval_f = ejit_run(f, argc, args, true, NULL).f;
+ retval = ejit_run(f, argc, args, NULL);
argc = 0;
DISPATCH();
DO(ESCAPEI_I);
ejit_escape_i_t f = i.p;
- retval = f(argc, args);
+ retval.i = f(argc, args);
argc = 0;
DISPATCH();
DO(ESCAPEI_L);
ejit_escape_l_t f = i.p;
- retval = f(argc, args);
+ retval.i = f(argc, args);
argc = 0;
DISPATCH();
DO(ESCAPEI_F);
ejit_escape_f_t f = i.p;
- retval_f = f(argc, args);
+ retval.f = f(argc, args);
argc = 0;
DISPATCH();
DO(ESCAPEI_D);
ejit_escape_d_t f = i.p;
- retval_f = f(argc, args);
+ retval.f = f(argc, args);
argc = 0;
DISPATCH();