BackStopImpl.mesa
Copyright Ó 1985, 1986, 1987, 1991 by Xerox Corporation. All rights reserved.
Russ Atkinson (RRA) April 7, 1987 2:23:59 pm PST
Last tweaked by Mike Spreitzer on October 5, 1989 2:19:42 pm PDT
Christian Jacobi, July 27, 1990 3:47 pm PDT
DIRECTORY
BackStop,
PreDebug USING [Explain],
Rope USING [ROPE],
RuntimeError USING [SendMsg, UNCAUGHT];
BackStopImpl: CEDAR PROGRAM
IMPORTS PreDebug, RuntimeError
EXPORTS BackStop =
BEGIN
SuspendBackStop: PUBLIC SIGNAL = CODE;
ResumeBackStop: PUBLIC SIGNAL = CODE;
alwaysRejectAny: BOOL ¬ FALSE;
for debugging
OZ: BOOL ¬ FALSE;
used to enter debugger when a signal/error occurs
lastAnyMsg: POINTER ¬ NIL;
lastAnySignal: UNSAFE SIGNAL ANY RETURNS ANY ¬ NIL;
useful for debugging ANY errors
lagMsg: Rope.ROPE ¬ NIL;
used to usually avoid GC of error message
Call: PUBLIC PROC [inner: PROC] RETURNS [Rope.ROPE] = TRUSTED {
msg: Rope.ROPE ¬ NIL;
suspensionCount: NAT ¬ 0;
{{ENABLE {
ABORTED => REJECT;
UNWIND => REJECT;
SuspendBackStop => {
suspensionCount ¬ suspensionCount + 1;
RESUME;
};
ResumeBackStop => {
IF suspensionCount > 0 THEN suspensionCount ¬ suspensionCount - 1;
RESUME;
};
ANY => TRUSTED {
anyMsg: POINTER;
anySignal: UNSAFE SIGNAL ANY RETURNS ANY;
IF suspensionCount > 0 THEN REJECT;
IF alwaysRejectAny THEN REJECT;
[anySignal, anyMsg] ¬ SIGNAL RuntimeError.SendMsg;
lastAnyMsg ¬ anyMsg; lastAnySignal ¬ anySignal;
msg ¬ PreDebug.Explain[anySignal, anyMsg ! RuntimeError.UNCAUGHT => {
msg ¬ "unknown error (explaining error raised error)";
CONTINUE
}];
MaybeLeaveKansas[];
GO TO oops;
}};
inner[];
RETURN [NIL]}
EXITS oops => RETURN [(lagMsg ¬ msg)];
};
};
MaybeLeaveKansas: PROC = TRUSTED {
IF OZ THEN
ERROR <<DebuggerSwap.CallDebugger["Toto, I don't think that we are in Kansas anymore..."L]>>;
};
END.