diff options
author | Kimplul <kimi.h.kuparinen@gmail.com> | 2025-04-09 19:56:33 +0300 |
---|---|---|
committer | Kimplul <kimi.h.kuparinen@gmail.com> | 2025-04-09 19:56:33 +0300 |
commit | 6824dd4b1ee22184f0e600115db3998924ed39d6 (patch) | |
tree | 0afbf35344313bdd17238b4fb570af0d094f758d /src/interp.c | |
parent | 9e367e1824d62d3759cb19b7c9a433b67b96bd99 (diff) | |
download | ejit-6824dd4b1ee22184f0e600115db3998924ed39d6.tar.gz ejit-6824dd4b1ee22184f0e600115db3998924ed39d6.zip |
initial tail call stuff
Diffstat (limited to 'src/interp.c')
-rw-r--r-- | src/interp.c | 58 |
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(); |