On Sun, Mar 28, 2010 at 1:55 PM, Nikodemus Siivola <firstname.lastname@example.org>
Something terribly wrong:
On 24 March 2010 15:16, Nikodemus Siivola <email@example.com
> Attached is my first cut, which makes
> (defun baz (x) (unwind-protect (setf x (quux x)) (setf x (quux x))))
> non-consing. Unless I discover something terribly wrong about this, I
> will commit this as 1.0.37.something-small.
(defun quux (x) (list :quux x))
(defun cleanup (x) (list :cleanup x))
(defun baz (x) (setf x (cleanup x)))
(unwind-protect (setf x (quux x))
(baz t) ; => (:QUUX T) should be (:cleanup (:quux t))
Cleanups are not in the same frame as the protected forms.
So, it turns out that what's happening here is that the compiler is generating a KNOWN-CALL-LOCAL, which does, in fact, spawn a new stack frame. At the same time, the UNWIND assembler-routine is preserving the frame pointer (the current-cont slot of the catch-block structure), which allows the backtrace to show the cleanup-fun being called by the frame containing the UWP. Nikodemus: The smoking gun is in my annotation to your paste 96988.