From: Bruno H. <br...@cl...> - 2005-01-18 18:50:32
|
Sam wrote: > funcall_iclosure() is called when the values of the bindings are already > known (arguments are evaluated before the function is called) > while make_variable_frame() is called _before_ the values are known and > must create _inactive_ bindings, which it does not: Yes. I think you're on the right track. Recall the general work pattern of make_variable_frame: - A pre-pass to collect the SPECIAL declarations, - A loop through the binding list that for each variable, tests whether it is among the SPECIAL declared ones, and prepare the binding in the stack. Whereas the evaluation of the initforms happens later, in a caller's loop. Looking at these examples: (LET ((X 5)) (PROGV '(X) '(20) (LET* ((X (1+ X)) (Z (1+ X))) (DECLARE (SPECIAL X)) Z))) => 7 (LET ((X 5)) (PROGV '(X) '(20) (LET* ((Y (1+ X)) (Z (1+ X))) (DECLARE (SPECIAL X)) Z))) => 6 it is clear that - If X is bound but neither specdecled nor a globally special variable, the binding of X must be activated in the caller's loop, after its initform has been evaluated. - If X is bound and is specdecled or a globally special variable, the X <--> #<SPECDECL> binding must be activated in the loop, not before. - If X is not bound, just specdecled, the X <--> #<SPECDECL> binding must be activated after the loop. So I think > control.d:make_variable_frame(): > > 460: pushSTACK_symbolwithflags(declsym,wbit(active_bit_o)); /* Symbol active */ here the binding should not be made active. > why doesn't deactivation of the bindings: > > --- control.d 17 Jan 2005 22:24:12 -0500 1.117 > +++ control.d 18 Jan 2005 11:55:42 -0500 > @@ -560,9 +560,9 @@ > if (specdecled || special_var_p(TheSymbol(symbol))) { > /* bind dynamically */ > #if (varframe_binding_mark == varframe_binding_sym) > ... & ~wbit(active_bit_o)); > #endif > } else { > /* bind statically */ > > fix the problem? That's because (as_oint(symbol) | wbit(dynam_bit_o) has the active_bit_o bit set to 0, therefore masking it out has no effect. Also here you are operating on the part of the stack frame that corresponds to the bindinglist, and this part is correct. So 1) before the loop, collect the SPECDECL bindings but don't make them active, 2) outside make_variable_frame, in LET, LET*, MULTIPLE-VALUE-BIND, after the loop that evaluates the initforms but before the implicit_progn, add a small loop that activates the SPECDECL bindings. Bruno |