Previous: Simple Special Forms, Up: Evaluation; Stack Frames; Bindings [Contents][Index]
struct catchtag { Lisp_Object tag; Lisp_Object val; struct catchtag *next; struct gcpro *gcpro; jmp_buf jmp; struct backtrace *backlist; int lisp_eval_depth; int pdlcount; };
catch
is a Lisp function that places a catch around a body of
code. A catch is a means of non-local exit from the code. When a catch
is created, a tag is specified, and executing a throw
to this tag
will exit from the body of code caught with this tag, and its value will
be the value given in the call to throw
. If there is no such
call, the code will be executed normally.
Information pertaining to a catch is held in a struct catchtag
,
which is placed at the head of a linked list pointed to by
catchlist
. internal_catch()
is passed a C function to
call (Fprogn()
when Lisp catch
is called) and arguments to
give it, and places a catch around the function. Each struct
catchtag
is held in the stack frame of the internal_catch()
instance that created the catch.
internal_catch()
is fairly straightforward. It stores into the
struct catchtag
the tag name and the current values of
backtrace_list
, lisp_eval_depth
, gcprolist
, and the
offset into the specpdl
array, sets a jump point with _setjmp()
(storing the jump point into the struct catchtag
), and calls the
function. Control will return to internal_catch()
either when
the function exits normally or through a _longjmp()
to this jump
point. In the latter case, throw
will store the value to be
returned into the struct catchtag
before jumping. When it’s
done, internal_catch()
removes the struct catchtag
from
the catchlist and returns the proper value.
Fthrow()
goes up through the catchlist until it finds one with
a matching tag. It then calls unbind_catch()
to restore
everything to what it was when the appropriate catch was set, stores the
return value in the struct catchtag
, and jumps (with
_longjmp()
) to its jump point.
unbind_catch()
removes all catches from the catchlist until it
finds the correct one. Some of the catches might have been placed for
error-trapping, and if so, the appropriate entries on the handlerlist
must be removed (see “errors”). unbind_catch()
also restores
the values of gcprolist
, backtrace_list
, and
lisp_eval
, and calls unbind_to()
to undo any specbindings
created since the catch.
Previous: Simple Special Forms, Up: Evaluation; Stack Frames; Bindings [Contents][Index]