[LMH]Re: CATCH/THROW?
Paul Fuqua
pf@ti.com
Wed Jul 23 20:58:00 2003
Date: Wed, 23 Jul 2003 23:04:42 -0500
From: Steve Krueger <s-krueger@sbcglobal.net>
I think catch/throw/unwind-protect is an area that changed somewhat in
VM2 because the call frame changed.
A lot, actually. We divorced catch/throw from call/return, though both
use the stack.
A catch is an open (in progress and not yet called) frame on the stack
with the function being a special UCODE-ENTRY.
Um, that's VM1, not VM2. (VM2 doesn't have open frames.)
Catch and throw are described in SSDN in chapter 11, the
function-calling chapter; partly because they're related, and partly
because I wrote them both so I had it all in one document. There are
some terse comments on the unwind-protect ops in chapter 20,
macroinstructions.
An unwind protect is a catch with special handling for throws that don't
match, the unwind clause is executed and then the throwing is continued,
still looking for a matching catch.
Sort of. A normal catch is bounded by %open-catch and %close-catch.
The former sets up a catch-block on the stack, for tracing back when
throwing. %close-catch exists to remove the catch-block on the way out
of the catch; when throwing, execution resumes there, and when not
throwing, execution must reach there.
An unwind-protect starts with %open-catch (with a magic tag; NIL?), but
has %close-catch-unwind-protect between the body and the undo-forms, and
%unwind-protect-continue after the undo-forms. (I can't remember what
%unwind-protect-cleanup is for.)
When not throwing, the latter two ops just clean up the stack from the
catch-block. When throwing, the unwind-protect block acts like a
universal catcher, starting execution at %close-catch-unwind-protect
which drops some information on the stack to indicate whether or not
it's throwing; %unwind-protect-continue retrieves this information and
continues the throw by essentially throwing again with the same tag
after the unwind-protect's catch-block is out of the way.
Come to think of it, it must write the throw-tag into the catch-block,
and %unwind-protect-continue will pick that tag up and throw if it's
non-NIL. But I still can't remember %unwind-protect-cleanup; from the
name, it should be something that cleans up an unwind-protect
catch-block when we know we don't have a throw to deal with, but I can't
immediately think of a context where that's useful. Maybe when throwing
out of the undo-forms?
pf