[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