On Sun, Sep 27, 2009 at 11:37 PM, Erik Huelsmann ehuels@gmail.com wrote:
On IRC, we had a discussion some days ago where it was found that ABCL doesn't use unique tag-identifications in tagbody, leading to somewhat dynamically scoped tagbodies, instead of perfectly lexically scoped.
BLOCK also uses non-unique names (think NIL), leading to the same issue. Both the compiler and the interpreter exhibit the problem.
Actually, to be specific: BLOCK is a compiler issue (as it turns out BLOCK does do the right thing in the interpreter), TAGBODY is an interpreter and compiler issue.
Consider the following code:
(labels ((p (b) (tagbody (if (not b) (p #'(lambda () (go :foo))) (funcall b)) (return-from p :bar) :foo (return-from p :foo)))) (p nil))
Or, for BLOCK, consider the following:
(labels ((p (b) (block nil (if (not b) (p #'(lambda () (return :foo))) (funcall b)) (return-from p :bar)))) (p nil))
It should return :foo, but return :bar on ABCL's interpreter instead. (The fact that the compiler works, means there's probably a bug in it somewhere, because there's no explanation why it would.)
The BLOCK code returns :BAR on 0.16.0.
I'm now thinking of ways to make the tags/blocknames unique. The one way I could come up with for the interpreter is this:
[ snip ]
I committed a change for BLOCK which replaces a static symbol with the content of a closure variable. This variable is set up upon entry of the block form and contains a unique identifier by allocating a specific LispObject, but *only* if the block contains non-local RETURN-FROMs.
I'm thinking of the right way to do the same with TAGBODY.
Bye,
Erik.