bytevm: treat blocks and tags as normal local bindings

Previously when unbinding we've skipped blocks and tags and let the frame exit
to collect the frame variable. This commit simplifies managing the environment
in the compiler.
This commit is contained in:
Daniel Kochmański 2025-05-01 12:30:35 +02:00
parent 878fc3441c
commit 16996f8d38
2 changed files with 4 additions and 5 deletions

View file

@ -1113,7 +1113,7 @@ c_undo_bindings(cl_env_ptr the_env, cl_object old_vars, int only_specials)
record = ECL_CONS_CDR(record);
special = ECL_CONS_CAR(record);
if (name == @':block' || name == @':tag') {
(void)0;
if (!only_specials) num_lexical++;
} else if (name == @':function' || Null(special)) {
if (!only_specials) num_lexical++;
} else if (name == @':declare') {
@ -1264,7 +1264,6 @@ c_block(cl_env_ptr env, cl_object body, int old_flags) {
return compile_body(env, body, old_flags);
} else {
c_undo_bindings(env, old_env.variables, 0);
env->c_env->env_size--;
asm_op(env, OP_EXIT_FRAME);
asm_complete(env, 0, labelz);
return flags;
@ -1470,7 +1469,6 @@ c_catch(cl_env_ptr env, cl_object args, int flags) {
compile_body(env, args, FLAG_VALUES);
c_undo_bindings(env, old_env, 0);
env->c_env->env_size--;
asm_op(env, OP_EXIT_FRAME);
asm_complete(env, 0, labelz);
@ -2487,7 +2485,6 @@ c_tagbody(cl_env_ptr env, cl_object args, int flags)
}
asm_op(env, OP_EXIT_TAGBODY);
c_undo_bindings(env, old_env, 0);
env->c_env->env_size--;
return FLAG_REG0;
}

View file

@ -1110,7 +1110,9 @@ ecl_interpret(cl_object frame, cl_object closure, cl_object bytecodes)
if (__ecl_frs_push_result != 0) {
reg0 = the_env->values[0];
vector = (cl_opcode *)ECL_STACK_REF(the_env,-1); /* FIXME! */
/* Unbind locals including the frame, we are leaving the frame. */
unwind_lcl(lcl_env, ECL_STACK_REF(the_env, -2));
unbind_lcl(lcl_env, 1); /* unbind the frame */
goto DO_EXIT_FRAME;
}
THREAD_NEXT;
@ -1140,6 +1142,7 @@ ecl_interpret(cl_object frame, cl_object closure, cl_object bytecodes)
ranges from 0 to ntags-1, depending on the tag. These numbers are
indices into the jump table and are computed at compile time. */
cl_opcode *table = (cl_opcode *)ECL_STACK_REF(the_env,-1);
/* Unbind locals but leave the frame, we are still inside the frame. */
unwind_lcl(lcl_env, ECL_STACK_REF(the_env,-2));
table = table + ecl_fixnum(the_env->values[0]) * OPARG_SIZE;
vector = table + *(cl_oparg *)table;
@ -1153,7 +1156,6 @@ ecl_interpret(cl_object frame, cl_object closure, cl_object bytecodes)
DO_EXIT_FRAME:
ecl_frs_pop(the_env);
ECL_STACK_POP_N_UNSAFE(the_env, 2);
unbind_lcl(lcl_env, 1);
THREAD_NEXT;
}
CASE(OP_NIL); {