[bytevm][wip] new opcode CALLW, don't use lcl frame when no locals

CALLW calls a word from the data stack. The word differs from normal functions
in that it takes no arguments (so the call does not modify the data stack).

To allow words using the stack across calls (like in "real" forth) don't unwind
the stack on exit if there are no locals.
This commit is contained in:
Daniel Kochmański 2025-06-03 09:59:54 +02:00
parent aa6600cea3
commit 2e1d336581
3 changed files with 21 additions and 4 deletions

View file

@ -204,12 +204,19 @@ disassemble(cl_object bytecodes, cl_opcode *vector) {
goto OPARG;
/* OP_QUOTE
Sets VALUES(0) to an immediate value.
Sets REG0 to an immediate value.
*/
case OP_QUOTE: string = "QUOTE\t";
GET_DATA(o, vector, data);
goto ARG;
/* OP_CALLW
Sets REG0 to a result of calling an immediate value.
*/
case OP_CALLW: string = "CALLW\t";
GET_DATA(o, vector, data);
goto ARG;
/* OP_CSET n{arg}
Replace constant with a computed value
*/

View file

@ -410,7 +410,7 @@ ecl_interpret(cl_object frame, cl_object closure, cl_object bytecodes)
lcl_env = ecl_cast_ptr(cl_object, &frame_lcl);
ecl_cs_check(the_env, ihs);
ecl_ihs_push(the_env, &ihs, bytecodes, closure, lcl_env);
ecl_stack_frame_open(the_env, lcl_env, nlcl);
if(nlcl) ecl_stack_frame_open(the_env, lcl_env, nlcl);
frame_aux.t = t_frame;
frame_aux.opened = 0;
frame_aux.base = 0;
@ -423,13 +423,21 @@ ecl_interpret(cl_object frame, cl_object closure, cl_object bytecodes)
the_env->nvalues = 0;
THREAD_NEXT;
}
/* OP_QUOTE
/* OP_QUOTE n{dat}
Sets REG0 to an immediate value.
*/
CASE(OP_QUOTE); {
GET_DATA(reg0, vector, data);
THREAD_NEXT;
}
/* OP_CALLW n{dat}
Calls the immediate value and sets REG0 to the result.
*/
CASE(OP_CALLW); {
GET_DATA(reg0, vector, data);
ecl_apply_from_stack_frame(frame, reg0);
THREAD_NEXT;
}
/* OP_VAR n{lcl}
OP_VARC n{lex}
OP_VARS n{dat}
@ -747,7 +755,7 @@ ecl_interpret(cl_object frame, cl_object closure, cl_object bytecodes)
*/
CASE(OP_EXIT); {
ecl_ihs_pop(the_env);
ecl_stack_frame_close(lcl_env);
if(nlcl) ecl_stack_frame_close(lcl_env);
return reg0;
}
/* OP_FLET nfun{arg}, fun1{object}

View file

@ -13,6 +13,7 @@
enum {
OP_NOP,
OP_QUOTE,
OP_CALLW,
OP_ENDP,
OP_CONS,
OP_CAR,
@ -176,6 +177,7 @@ typedef int16_t cl_opcode;
static const int offsets[] = {\
&&LBL_OP_NOP - &&LBL_OP_NOP,\
&&LBL_OP_QUOTE - &&LBL_OP_NOP,\
&&LBL_OP_CALLW - &&LBL_OP_NOP,\
&&LBL_OP_ENDP - &&LBL_OP_NOP,\
&&LBL_OP_CONS - &&LBL_OP_NOP,\
&&LBL_OP_CAR - &&LBL_OP_NOP,\