On 1-Jul-08, at 1:16 PM, Martin Cracauer wrote:
> For a project I need to track which special variables are being
> accessed while they are locally bound somewhere up in the call stack.
> Since the value lookup goes through a stack anyway, I think it would
> be pretty straightforward to have a switch that changes the code to
> raise a condition on any access to a shadowed special.
No, value lookups do not go through a stack, since we use shallow
binding. It's still simple enough on threaded platforms, since local
bindings are read via thread-local slots, while global ones are still
stored in the symbol object (a really shallow stack, as nyef pointed
out ;). On unthreaded platforms, I don't see how to avoid walking the
binding stack to make sure no binding information is stored for the
symbol. A file implementing GLOBAL-BINDING-P, a predicate that returns
T if the argument symbol's binding is the global one, NIL otherwise is
attached. It was only lightly tested on threaded x86-64, but should
work everywhere else.
After that, it's a simple matter of modifying the way references to
global (special) variables are translated during IR1 translation. The
relevant function is ir1-convert-var, in src/compiler/ir1tran.lisp.
(cond ((and (global-var-p var) specials-introspect:*insert-global-
binding-checks*) ; misplaced symbol...
(ir1-convert start next result `(progn
((and (global-var-p var) (not result))
;; KLUDGE: If the reference is dead, convert using SYMBOL-
;; which is not flushable, so that unbound dead variables
;; an error (bug 412).
(ir1-convert start next result `(symbol-value ',name)))
(etypecase var ...)))
should do it. Obviously, this won't catch direct uses of SYMBOL-VALUE.
All: Does it seem like a good idea to implement real global lexical
variables as an sb-extension? There would be some friction with
specials (a global lexical variable shouldn't also be declared special
somewhere else), but that seems reasonable and similar to constants VS
specials (and to current implementations of globals via define-symbol-
macro and defparameter).