SignalsImpl.mesa
Copyright Ó 1987, 1989, 1991 by Xerox Corporation. All rights reserved.
Carl Hauser, July 24, 1989 12:51:53 pm PDT
Russ Atkinson (RRA) July 27, 1989 9:05:46 pm PDT
Christian Jacobi, January 5, 1990 5:24:28 pm PST
Chauser, February 22, 1991 10:51 am PST
Foote, May 31, 1991 2:44 pm PDT
Willie-s, August 5, 1991 5:34 pm PDT
Michael Plass, December 13, 1991 3:22 pm PST
DIRECTORY
PortableCedarRuntimeSupport,
RuntimeError,
SignalStatistics;
SignalsImpl: CEDAR PROGRAM -- MONITOR
IMPORTS RuntimeError
EXPORTS PortableCedarRuntimeSupport, RuntimeError, SignalStatistics
~ BEGIN
OPEN PCRS: PortableCedarRuntimeSupport;
Options
checking: BOOL = TRUE;
Global Variables (protected by monitor)
ucsHandler: RuntimeError.UCSProc ¬ InitialUCSHandler;
SigInfo: TYPE ~ RECORD [
sig: ExceptAny,
arg: POINTER,
rtns: POINTER,
informational: BOOL
];
InformationalSignal: PUBLIC SAFE PROC [signal: SIGNAL] = TRUSTED {
Who makes informational signals? What language feature? According to Dan Swinehart, this kind of signalling is done in code written by wizards and not produced by any Mesa language feature. The idea is to signal in such a way that if the signal is not caught, you don't end up in the debugger.
SignalHandler[signal, NIL, NIL, TRUE];
};
RegisterUncaughtSignalHandler: PUBLIC -- ENTRY -- PROC [proc: RuntimeError.UCSProc] RETURNS [old: RuntimeError.UCSProc] = {
old ¬ ucsHandler;
ucsHandler ¬ proc;
};
InitialUCSHandler: RuntimeError.UCSProc ~ {
CallDebugger[];
};
CatchProc: TYPE ~ PCRS.Handler;
HandlerAction: TYPE = PCRS.HandlerAction;
NoHandler: CatchPhrase = NIL;
SignalHandler
signalSpy: PROC ¬ NIL;
RegisterSignalSpy: PUBLIC -- ENTRY -- PROC [new: PROC] RETURNS [old: PROC] ~ {
old ¬ signalSpy;
signalSpy ¬ new;
};
SignalHandler: PROC
[sig: ExceptAny, arg: POINTER, rtns: POINTER, informational: BOOL ¬ FALSE] ~ TRUSTED {
action: PCRS.HandlerAction;
catchProc: PCRS.Handler;
warmestHandler: CatchPhrase ¬ NIL;
selfObj: SignallerStateObject ¬ [];
self: SignallerState ¬ LOOPHOLE[@selfObj];
exitTo: INT;
spy: PROC ~ signalSpy;
IF spy # NIL THEN spy[];
self.signal ¬ sig;
TRUSTED {
OPEN self;
unwinding ¬ FALSE;
warmestHandler ¬ WarmestHandler[]; -- in the current thread
First pass: find catch phrases, looking for GOTO out of one
unwinding = FALSE
start ¬ warmestHandler;
nextCatchPhrase ¬ start;
UNTIL (nextCatchPhrase = target) OR unwinding DO
thisSignaller: SignallerState;
walk from nextFrame toward "cool" end of stack, looking for target
currentCatchPhrase ¬ nextCatchPhrase;
thisSignaller ¬ currentCatchPhrase.signallerState;
IF thisSignaller # NIL THEN {
catchPhrase is for another instance of this (SignalHandler) procedure.
choose our nextFrame
IF signal ~= thisSignaller.signal
THEN {
nextCatchPhrase ¬ Parent[currentCatchPhrase];
}
ELSE {
nextCatchPhrase ¬ thisSignaller.nextCatchPhrase;
};
different signals propagate through intervening frames
from the Mesa 11.0 manual: "all of the routines whose frames lie beyond thisSignaller, up to the frame containing the catch phrase called by thisSignaller, have already had a chance to handle signal, so they are not given it again."
I claim that all signals should propagate through intervening frames, or none. I lean to the side of none, but I'll leave this as-is for the time being.
}
ELSE -- currentCatchPhrase.signallerState = NIL --
frame is NOT for another SignalHandler - just walk the stack to nextFrame
{
nextCatchPhrase ¬ Parent[currentCatchPhrase];
};
Will this frame catch any signals? It may, depending on the body of the catch phrase (it may also raise signals!)
IF (catchProc ¬ currentCatchPhrase.catchProc) # NIL THEN {
call the catch phrase
ENABLE {
RuntimeError.SendMsg => RESUME[self.signal, arg, rtns]; -- GetSignal is SIGNALled by an ANY-catcher to request the details of the signal it is processing --
};
now WarmestHandler will give us the catchPhrase just pushed for the above ENABLE
hotHandler: CatchPhrase ¬ WarmestHandler[];
stuff our "self" record in the catchPhrase so later instances of the SignalHandler can find it.
hotHandler.signallerState ¬ self;
[action, exitTo] ¬
catchProc[context: currentCatchPhrase.catchContext, except: signal, rtnPtr: rtns, argPtr: arg ! RuntimeError.Resume => TRUSTED { action ¬ resume; CONTINUE }];
SELECT action FROM
reject => NULL;
resume => {
the handler has filled rtns^ with the results for signal's raiser
RETURN
};
exit =>
IF ~informational THEN {
target ¬ currentCatchPhrase;
unwinding ¬ TRUE;
arg ¬ NIL;
};
ELSE
Apparently, non-local GOTOs from a handlers for signals originated as informational are ignored and treated as REJECTs.
ENDCASE;
};
ENDLOOP;
What happened?
SELECT TRUE FROM
unwinding => NULL;
informational OR signal = LOOPHOLE[UNCAUGHT] => NULL;
does an implicit RESUME
Informational signals are resumed either by an explicit resume in a catch phrase or when the signal has propagated to the top of the stack. IF signal = LOOPHOLE[UNCAUGHT] at this point, it was raised in the following ENDCASE (in a different invocation of SignalHandler), so upon resumption, that SignalHandler calls ucsHandler.
ENDCASE => {
We want to be able to RESUME UNCAUGHT, but we don't want a random catch phrase to do so. So, we declare it to be an ERROR in the interface, but raise it as a SIGNAL here. When (if) UNCAUGHT percolates to the top of the stack, it is implicitly resumed (see the preceding line of code). Control then passes to the statement following the invocation of UNCAUGHT, which calls the debugger (or whatever).
Uncaught: TYPE = SIGNAL [SIGNAL ANY RETURNS ANY, WORD];
LOOPHOLE[UNCAUGHT, Uncaught][signal, LOOPHOLE[arg]];
for now dummy msg parameter because the PrincOps world is so different.
frame: NIL because I think that's what happens in PrincOps world.
TRUSTED {ucsHandler[msg: LOOPHOLE[arg], signal: signal, frame: NIL]};
};
IF unwinding THEN {
disable ordinary handlers in the stack to be unwound
nextCatchPhrase ← start;
UNTIL (nextCatchPhrase = target) DO
nextCatchPhrase.dynamicFrame.key ← DisabledMesaHandlerKey;
nextCatchPhrase ← Parent[nextCatchPhrase];
ENDLOOP;
target.dynamicFrame.key ← DisabledMesaHandlerKey;
propagate an UNWIND
UnwindTo[LOOPHOLE[target]];
RestartHandlee[GetNextHandlee[NIL], target.jmpBufPtr, exitTo]
};
};
};
Parent: PROC [catchPhrase: CatchPhrase] RETURNS [parent: CatchPhrase]
~ TRUSTED {
follows the caller pointer of frame
env: DynamicFrame ~ LOOPHOLE[catchPhrase];
RETURN[LOOPHOLE[LookupInDynamicEnvironment[MesaHandlerKey, env.next]]];
};
WarmestHandler: PROC [] RETURNS [CatchPhrase] ~ {
env: DynamicFrame ~ GetDynamicEnvironment[];
RETURN[LOOPHOLE[LookupInDynamicEnvironment[MesaHandlerKey, env]]];
};
MesaUnwinderProc: TYPE ~ POINTER TO MesaUnwinderProcBody;
MesaUnwinderProcBody: TYPE ~ RECORD [
codeBody: WORD,
catchPhrase: CatchPhrase
];
MesaUnwinder: PROC [self: MesaUnwinderProc] ~ TRUSTED { -- XR¬MesaUnwinder
cp: CatchPhrase ¬ self.catchPhrase;
catchProc: PCRS.Handler;
action: PCRS.HandlerAction;
IF (catchProc ¬ cp.catchProc) # NIL THEN TRUSTED {
ENABLE {
RuntimeError.SendMsg => RESUME[LOOPHOLE[UNWIND], NIL, NIL]; -- GetSignal is SIGNALled by an ANY-catcher to request the details of the signal it is processing --
};
call the catch phrase -- this is old-style, with UNWIND handling buried in normal catch phrases.
[action, ] ¬
catchProc[context: cp.catchContext, except: LOOPHOLE[UNWIND], rtnPtr: NIL, argPtr: NIL ! RuntimeError.Resume => {action ¬ resume; CONTINUE }];
SELECT action FROM
reject => NULL;
resume => ERROR RuntimeError.ResumeFault;
exit => ERROR RuntimeError.UnwindFault;
ENDCASE;
};
};
Signalling types
Maintain correspondence with declaration in DefSetSignalEnvironment below
SignalEnvironment: TYPE = REF SignalEnvironmentObject;
SignalEnvironmentObject: TYPE = MACHINE DEPENDENT RECORD [
unixTrapHandler: PROC,
aborted: ERROR,
abstractionFault: ERROR,
arithmeticFault: ERROR,
assignRefCompositeFault: ERROR,
boundsFault: ERROR,
divideCheck: SAFE SIGNAL,
invalidProcess: ERROR [process: PROCESS],
linkageFault: ERROR,
narrowFault: ERROR,
narrowRefFault: ERROR [ref: REF, type: RuntimeError.Type],
nestedProcFault: ERROR [proc: RuntimeError.ProcAny],
nilFault: ERROR,
resumeFault: ERROR,
sendMsg: SIGNAL RETURNS [signal: SIGNAL ANY RETURNS ANY, args, results: POINTER],
stackFault: ERROR,
startFault: SIGNAL [dest: PROGRAM],
unboundProcedureFault: SIGNAL [dest: PROC ANY RETURNS ANY] RETURNS [PROC ANY RETURNS ANY],
uncaught: ERROR [signal: SIGNAL ANY RETURNS ANY, parameters: WORD],
unnamedError: ERROR,
unnamedSignal: SIGNAL,
unwind: ERROR,
unwindFault: ERROR,
zeroDivisor: SAFE SIGNAL
];
formerly from SignalSupport.c and SignalSupport.h:
DefSetSignalEnvironment: PROC [] = TRUSTED MACHINE CODE {
"+";
"typedef struct {\n";
" int *unixTrapHandler;\n";
" unsigned aborted;\n";
" unsigned abstractionFault;\n";
" unsigned arithmeticFault;\n";
" unsigned assignRefCompositeFault;\n";
" unsigned boundsFault;\n";
" unsigned divideCheck;\n";
" unsigned invalidProcess;\n";
" unsigned linkageFault;\n";
" unsigned narrowFault;\n";
" unsigned narrowRefFault;\n";
" unsigned nestedProcFault;\n";
" unsigned nilFault;\n";
" unsigned resumeFault;\n";
" unsigned sendMsg;\n";
" unsigned stackFault;\n";
" unsigned startFault;\n";
" unsigned unboundProcedureFault;\n";
" unsigned uncaught;\n";
" unsigned unnamedError;\n";
" unsigned unnamedSignal;\n";
" unsigned Unwind;\n";
" unsigned unwindFault;\n";
" unsigned zeroDivisor;\n";
" } SignalEnvironmentObject;\n";
"typedef SignalEnvironmentObject *SignalEnvironment;\n";
"unsigned XR←UnnamedSignal;\n";
"unsigned XR←UnnamedError;\n";
"unsigned XR←Unwind;\n";
"unsigned XR�orted;\n";
"unsigned XR←Uncaught;\n";
"unsigned XR←NarrowFault;\n";
"unsigned XR←NarrowRefFault;\n";
"unsigned XR←InvalidProcess;\n";
"SignalEnvironment XR←SigEnv;\n";
"static void XR←SetSignalEnvironment(env)\n";
" SignalEnvironment env;\n";
" {\n";
" XR←SigEnv = env;\n";
" XR←UnnamedError = env-> unnamedError;\n";
" XR←UnnamedSignal = env->unnamedSignal;\n";
" XR←Unwind = env->Unwind;\n";
" XR�orted = env->aborted;\n";
" XR←Uncaught = env->uncaught;\n";
" XR←NarrowFault = env->narrowFault;\n";
" XR←NarrowRefFault = env->narrowRefFault;\n";
" XR←InvalidProcess = env->invalidProcess;\n";
" };\n";
".";
};
ExceptAny: TYPE ~ SIGNAL ANY RETURNS ANY;
noCP: CatchPhrase ~ NIL;
MesaHandlerKey: WORD ~ CODE;
DisabledMesaHandlerKey: WORD ~ CODE;
UnwindFrameKey: WORD ¬ GetUnwindFrameKey[];
DynamicFrame: TYPE ~ POINTER TO DynamicFrameObject;
DynamicFrameObject: TYPE ~ RECORD [
next: DynamicFrame,
key: WORD,
data: WORD
];
UnwindFrame: TYPE ~ POINTER TO UnwindFrameObject;
UnwindFrameObject: TYPE ~ RECORD [
next: DynamicFrame,
key: WORD,
unwinder: PROC,
rewinder: PROC
];
assertUnwindFrameObjectSize: [0..4] = WORDS[UnwindFrameObject];
If this fails to compile, change the number in "unwindSpace[4]" in XR𡤎nable
CatchPhrase: TYPE ~ POINTER TO CatchPhraseObject;
CatchPhraseObject: TYPE ~ RECORD [
dynamicFrame: DynamicFrameObject, 
jmpBufPtr: POINTER,
catchProc: PCRS.Handler,
catchContext: POINTER,
signallerState: REF SignallerStateObject
];
assertCatchPhraseObjectSize: [0..7] = WORDS[CatchPhraseObject];
If this fails to compile, change the number in "catchSpace[7]" in XR𡤎nable
SignallerState: TYPE = REF SignallerStateObject;
SignallerStateObject: TYPE ~ RECORD [
startMark: CARD32 ¬ 0FF00FF00H,
start: CatchPhrase ¬ noCP,
signal: ExceptAny ¬ NIL,
currentCatchPhrase: CatchPhrase ¬ noCP,
nextCatchPhrase: CatchPhrase ¬ noCP,
target, nextTarget: CatchPhrase ¬ noCP,
unwinding: BOOL ¬ FALSE,
endMark: CARD32 ¬ 0FF11FF11H
];
RaiseErrorProc: TYPE = PROC [which: ExceptAny, args: POINTER];
RaiseSignalProc: TYPE = PROC [which: ExceptAny, rtns: POINTER, args: POINTER];
XR routines
CallDebugger: PROC [] RETURNS [] ~ TRUSTED MACHINE CODE {
"XR�llDebugger"
};
SetSignalEnvironment: PROC [env: SignalEnvironment] ~ TRUSTED MACHINE CODE {
"XR←SetSignalEnvironment"
};
RaiseError: PUBLIC RaiseErrorProc = TRUSTED { -- XR¬RaiseError
stats.errorsRaised ¬ stats.errorsRaised + 1;
SignalHandler[which, args, NIL];
ERROR RuntimeError.ResumeFault
};
RaiseSignal: PUBLIC RaiseSignalProc = TRUSTED { -- XR¬RaiseSignal
stats.signalsRaised ¬ stats.signalsRaised + 1;
SignalHandler[which, args, rtns];
};
RaiseUnnamedError: PROC [] RETURNS [CARD ¬ 0] ~ { -- XR¬RaiseUnnamedError
--make this procedure PUBLIC when interface changes for any other reason
RaiseError[LOOPHOLE[RuntimeError.UnnamedError], NIL]
};
RaiseArithmeticFault: PUBLIC PROC [] RETURNS [CARD ¬ 0] ~ { -- XR¬RaiseArithmeticFault
RaiseError[LOOPHOLE[RuntimeError.ArithmeticFault], NIL]
};
RaiseBoundsFault: PUBLIC PROC [] RETURNS [CARD ¬ 0] ~ { -- XR¬RaiseBoundsFault
RaiseError[LOOPHOLE[RuntimeError.BoundsFault], NIL]
};
RaiseAbstractionFault: PUBLIC PROC [] RETURNS [] ~ { -- XR¬RaiseAbstractionFault
RaiseError[LOOPHOLE[RuntimeError.AbstractionFault], NIL]
};
SetupPushHandler: PROC
[context: POINTER, proc: PCRS.Handler, catchPhrase: CatchPhrase, unwindFrame: UnwindFrame, unwinder: PROC, jmpBufPtr: POINTER ]
~ TRUSTED { -- XR¬SetupPushHandler
prevEnv: DynamicFrame ¬ GetDynamicEnvironment[];
catchPhrase.dynamicFrame.next ¬ LOOPHOLE[unwindFrame];
catchPhrase.dynamicFrame.key ¬ MesaHandlerKey;
catchPhrase.catchProc ¬ proc;
catchPhrase.catchContext ¬ context;
catchPhrase.signallerState ¬ NIL;
catchPhrase.jmpBufPtr ¬ jmpBufPtr;
unwindFrame.next ¬ prevEnv;
unwindFrame.key ¬ UnwindFrameKey;
unwindFrame.unwinder ¬ unwinder;
unwindFrame.rewinder ¬ NIL;
SetDynamicEnvironment[LOOPHOLE[catchPhrase]];
stats.newPushCount ¬ stats.newPushCount+1;
};
PushAllocedHandler: PUBLIC PROC
[context: POINTER, handler: PCRS.Handler, jmpBuf: POINTER] RETURNS [INT]
~ TRUSTED { -- XR¬PushAllocedHandler
the jmpBuf^ should be dynamically allocated (not on the stack)
unwindFrame: UnwindFrame ¬ LOOPHOLE[NEW[UnwindFrameObject]];
catchPhrase: CatchPhrase ¬ LOOPHOLE[NEW[CatchPhraseObject]];
MesaProcObject: TYPE ~ RECORD [
codePointer: WORD,
context: WORD
];
MesaProc: TYPE ~ POINTER TO MesaProcObject;
prevEnv: DynamicFrame ¬ GetDynamicEnvironment[];
catchPhrase.dynamicFrame.next ¬ LOOPHOLE[unwindFrame];
catchPhrase.dynamicFrame.key ¬ MesaHandlerKey;
catchPhrase.catchProc ¬ handler;
catchPhrase.catchContext ¬ context;
catchPhrase.signallerState ¬ NIL;
catchPhrase.jmpBufPtr ¬ jmpBuf;
unwindFrame.rewinder ¬ NIL;
unwindFrame.next ¬ prevEnv;
unwindFrame.key ¬ UnwindFrameKey;
unwindFrame.unwinder ¬ LOOPHOLE[NEW[MesaProcObject ¬ [LOOPHOLE[MesaUnwinder, MesaProc].codePointer, LOOPHOLE[catchPhrase]]]];
SetDynamicEnvironment[LOOPHOLE[catchPhrase]];
stats.pushCount ¬ stats.pushCount+1;
RETURN[0];
dead, but it keeps the compiler happy
};
PopHandler: PUBLIC PROC [] RETURNS [] ~ TRUSTED { -- XR¬PopHandler
env: DynamicFrame ¬ GetDynamicEnvironment[];
IF (env.key = MesaHandlerKey OR env.key = DisabledMesaHandlerKey) AND env.next.key=UnwindFrameKey THEN {
SetDynamicEnvironment[env.next.next]
}
ELSE ERROR;
};
Thread state manipulation
XRThread: TYPE ~ POINTER;
GetDynamicEnvironment: PROC [] RETURNS [DynamicFrame] ~ TRUSTED MACHINE CODE {
"XR←GetDynamicEnvironment"
};
GetDynamicEnvironmentOf: PROC [XRThread] RETURNS [DynamicFrame] ~ TRUSTED MACHINE CODE {
"XR←GetDynamicEnvironmentOf"
};
SetDynamicEnvironment: PROC [DynamicFrame] RETURNS [] ~ TRUSTED MACHINE CODE {
"XR←SetDynamicEnvironment"
};
LookupInDynamicEnvironment: PROC [key: WORD, de: DynamicFrame] RETURNS [DynamicFrame] ~ TRUSTED MACHINE CODE {
"XR←LookupInDynamicEnvironment"
};
UnwindTo: PROC [DynamicFrame] RETURNS [] ~ TRUSTED MACHINE CODE {
"XR←UnwindTo"
};
GetNextHandlee: PROC[thread: XRThread] RETURNS [XRThread]~ TRUSTED MACHINE CODE {
"XR←GetNextHandlee"
};
GetUnwindFrameKey: PROC[] RETURNS [WORD] ~ TRUSTED MACHINE CODE {
"XR←GetUnwindFrameKey"
};
RestartHandlee: PROC[thread: XRThread, jmpBuf: POINTER, exitTo: INT] ~ TRUSTED MACHINE CODE {
"XR←RestartHandlee"
};
Statistics
stats: SignalStatistics.Stats ¬ [];
GetStatistics: PUBLIC PROC [] RETURNS [SignalStatistics.Stats] ~ {
RETURN [stats];
};
Embedded C procedure (for XR𡤎nable)
DefEnable: PROC [] = TRUSTED MACHINE CODE {
"+";
"#include <xr/Threads.h>\n";
"typedef struct {fPt p; word c;} ProcDescBody;\n";
"extern word XR𡤎nable(body, handler, context)\n";
" fPt body;\n";
" fPt handler;\n";
" ptr context;\n";
" {\n";
" word rtnCode;\n";
" ptr beforeCall;\n";
" ProcDescBody pdDescBody;\n";
" ProcDescBody unwindDescBody;\n";
" word catchSpace[7];\n";
" struct XR←JmpBufRep jmpBuf;\n";
" word unwindSpace[4];\n";
" pdDescBody.p = handler;\n";
" pdDescBody.c = 1;\n";
" unwindDescBody.p = (fPt) XR←MesaUnwinder;\n";
n.b. the context for the unwinder is the catchPhrase, not the unwindFrame
" unwindDescBody.c = (word) catchSpace;\n";
" beforeCall = (ptr) XR←GetDynamicEnvironment();\n";
" XR←SetupPushHandler(context, &pdDescBody, catchSpace, unwindSpace, &unwindDescBody, &jmpBuf);\n";
" rtnCode = XR←setjmp(&jmpBuf);\n";
" if (rtnCode == 0) rtnCode = body(context);\n";
" { /* INLINE version of XR←PopHandler, no stats */ \n";
" ptr curr = (ptr) XR←GetDynamicEnvironment();\n";
" ptr prev = (ptr) *((ptr) *curr);\n";
" if (beforeCall != prev) XR←RaiseError(0,0);\n";
" XR←SetDynamicEnvironment(prev);\n";
" };\n";
" return (rtnCode);\n";
" };\n";
"extern word XR←UnwindFrameKey;\n";
"static word XR←GetUnwindFrameKey()\n";
" {\n";
" return( XR←UnwindFrameKey );\n";
" };\n";
".";
};
External names
ExternalNames: PROC [] = TRUSTED MACHINE CODE {
"^ExternalNames\n";
"RaiseError XR←RaiseError\n";
"RaiseSignal XR←RaiseSignal\n";
"RaiseUnnamedError XR←RaiseUnnamedError\n";
"RaiseArithmeticFault XR←RaiseArithmeticFault\n";
"RaiseBoundsFault XR←RaiseBoundsFault\n";
"RaiseAbstractionFault XR←RaiseAbstractionFault\n";
"SetupPushHandler XR←SetupPushHandler\n";
"PushAllocedHandler XR←PushAllocedHandler\n";
"PopHandler XR←PopHandler\n";
"PushUnwinder XR←PushUnwinder\n";
"PopUnwinder XR←PopUnwinder\n";
"GetUnwinderContext XR←GetUnwinderContext\n";
"MesaUnwinder XR←MesaUnwinder\n";
};
Initialization
Initialize: PROC = {
SetSignalEnvironment[ NEW[SignalEnvironmentObject ¬ [
aborted ~ RuntimeError.Aborted,
abstractionFault ~ RuntimeError.AbstractionFault,
arithmeticFault ~ RuntimeError.ArithmeticFault,
assignRefCompositeFault ~ RuntimeError.AssignRefCompositeFault,
boundsFault ~ RuntimeError.BoundsFault,
divideCheck ~ RuntimeError.DivideCheck,
invalidProcess ~ RuntimeError.InvalidProcess,
linkageFault ~ RuntimeError.LinkageFault,
narrowFault ~ RuntimeError.NarrowFault,
narrowRefFault ~ RuntimeError.NarrowRefFault,
nestedProcFault ~ RuntimeError.NestedProcFault,
nilFault ~ RuntimeError.NilFault,
resumeFault ~ RuntimeError.ResumeFault,
sendMsg ~ RuntimeError.SendMsg,
stackFault ~ RuntimeError.StackFault,
startFault ~ RuntimeError.StartFault,
unboundProcedureFault ~ RuntimeError.UnboundProcedureFault,
uncaught ~ RuntimeError.Uncaught,
unnamedError ~ RuntimeError.UnnamedError,
unnamedSignal ~ RuntimeError.UnnamedSignal,
unwind ~ RuntimeError.Unwind,
unwindFault ~ RuntimeError.UnwindFault,
zeroDivisor ~ RuntimeError.ZeroDivisor
]]];
DefEnable[];
DefSetSignalEnvironment[];
};
ExternalNames[];
Initialize[];
END.