From 16996f8d38f3f656afd90f2be5e0008d522ee90c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Kochma=C5=84ski?= Date: Thu, 1 May 2025 12:30:35 +0200 Subject: [PATCH] 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. --- src/c/compiler.d | 5 +---- src/c/interpreter.d | 4 +++- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/c/compiler.d b/src/c/compiler.d index ad4b7fc59..f33eaa82c 100644 --- a/src/c/compiler.d +++ b/src/c/compiler.d @@ -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; } diff --git a/src/c/interpreter.d b/src/c/interpreter.d index e2861bea2..8704f41da 100644 --- a/src/c/interpreter.d +++ b/src/c/interpreter.d @@ -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); {