mirror of
https://gitlab.com/embeddable-common-lisp/ecl.git
synced 2025-12-15 15:21:03 -08:00
bytecmp: compute the locals env size correctly
Previously our calculations were off because: - we've counted special variables - we didn't decrement the env size when unbound One could argue that we need only to increment it, but then we'd end up with the size too big. Consider: (progn (let ((a 1)) (foobar)) (let ((b 1)) (foobar))) In this snippet we have two local variables, but we never look at locals beyond the first element.
This commit is contained in:
parent
6babf49b1c
commit
878fc3441c
1 changed files with 18 additions and 4 deletions
|
|
@ -494,6 +494,13 @@ c_push_record(const cl_compiler_ptr c_env, cl_object type,
|
|||
return cl_list(4, type, arg1, arg2, loc);
|
||||
}
|
||||
|
||||
static cl_object
|
||||
c_make_record(const cl_compiler_ptr c_env, cl_object type,
|
||||
cl_object arg1, cl_object arg2)
|
||||
{
|
||||
return cl_list(3, type, arg1, arg2);
|
||||
}
|
||||
|
||||
static void
|
||||
c_register_block(cl_env_ptr env, cl_object name)
|
||||
{
|
||||
|
|
@ -515,8 +522,9 @@ c_register_var(cl_env_ptr env, cl_object var, bool special, bool bound)
|
|||
{
|
||||
const cl_compiler_ptr c_env = env->c_env;
|
||||
cl_object boundp = bound? ECL_T : ECL_NIL;
|
||||
cl_object specialp = special? ECL_T : ECL_NIL;
|
||||
cl_object entry = c_push_record(c_env, var, specialp, boundp);
|
||||
cl_object entry = (special
|
||||
? c_make_record(c_env, var, ECL_T, boundp)
|
||||
: c_push_record(c_env, var, ECL_NIL, boundp));
|
||||
c_env->variables = CONS(entry, c_env->variables);
|
||||
}
|
||||
|
||||
|
|
@ -533,7 +541,7 @@ static void
|
|||
c_register_symbol_macro(cl_env_ptr env, cl_object name, cl_object exp_fun)
|
||||
{
|
||||
const cl_compiler_ptr c_env = env->c_env;
|
||||
cl_object entry = c_push_record(c_env, name, @'si::symbol-macro', exp_fun);
|
||||
cl_object entry = c_make_record(c_env, name, @'si::symbol-macro', exp_fun);
|
||||
c_env->variables = CONS(entry, c_env->variables);
|
||||
}
|
||||
|
||||
|
|
@ -1121,7 +1129,10 @@ c_undo_bindings(cl_env_ptr the_env, cl_object old_vars, int only_specials)
|
|||
}
|
||||
}
|
||||
c_env->variables = env;
|
||||
if (num_lexical) asm_op2(the_env, OP_UNBIND, num_lexical);
|
||||
if (num_lexical) {
|
||||
c_env->env_size -= num_lexical;
|
||||
asm_op2(the_env, OP_UNBIND, num_lexical);
|
||||
}
|
||||
if (num_special) asm_op2(the_env, OP_UNBINDS, num_special);
|
||||
}
|
||||
|
||||
|
|
@ -1253,6 +1264,7 @@ 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;
|
||||
|
|
@ -1458,6 +1470,7 @@ 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);
|
||||
|
||||
|
|
@ -2474,6 +2487,7 @@ 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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue