Body:
PROC [bti: CBTIndex] = {
saved: P3S.BodyData = current^;
saveIndex: CARDINAL = dataPtr.textIndex;
saveBodyIndex: CBTIndex = dataPtr.bodyIndex;
saveScope: BTIndex = currentScope;
saveSafety: Safety = safety;
node: Tree.Index;
lockVar: ISEIndex;
lockBit: BOOL;
inRecord, outRecord: RecordSEIndex;
argLevel: ContextLevel;
dataPtr.bodyIndex ← currentScope ← bti;
dataPtr.textIndex ← bb[bti].sourceIndex;
current.bodyNode ← node ←
WITH bb[bti].info
SELECT
FROM
Internal => bodyTree,
ENDCASE => ERROR;
current.level ← bb[bti].level; current.entry ← bb[bti].entry;
SetSafety[SafetyAttr[node]];
bb[bti].resident ← FALSE;
current.lockHeld ← bb[bti].entry OR bb[bti].internal;
argLevel ← IF bti = RootBti THEN lG ELSE current.level;
IF bb[bti].ioType # typeANY THEN seb[bb[bti].ioType].mark4 ← FALSE;
[inRecord, outRecord] ← TransferTypes[bb[bti].ioType];
IF inRecord = SENull THEN current.argCtx ← CTXNull
ELSE {
current.argCtx ← seb[inRecord].fieldCtx;
ctxb[current.argCtx].level ← argLevel;
IF argLevel = lG THEN EnterTypes[current.argCtx]};
IF outRecord # SENull THEN ctxb[seb[outRecord].fieldCtx].level ← argLevel;
PushArgCtx[current.inputRecord ← inRecord]; SetArgRefs[inRecord, 1];
PushArgCtx[current.returnRecord ← outRecord]; SetArgRefs[outRecord, 0];
ClearRefStack[];
initialize computed attributes
current.labelList ← Tree.Null; current.loopDepth ← 0;
current.catchDepth ← 0; current.unwindEnabled ← FALSE;
current.resumeRecord ← RecordSENull; current.resumeFlag ← FALSE;
IF ~current.entry THEN pathNP ← none
ELSE {
IF (lockVar ← FindLockParams[].actual) # SENull
THEN {
lockBit ← seb[lockVar].immutable; seb[lockVar].immutable ← TRUE};
tb[node].son[4] ← CopyLock[]; pathNP ← phraseNP};
BEGIN
ENABLE
InsertCatchLabel => {Log.Error[catchLabel]; RESUME};
outInit: Tree.Link ← Tree.Null;
ScanList[tb[node].son[1], OpenItem];
current.noXfers ← TRUE;
IF inRecord # SENull THEN CheckDisjoint[current.argCtx, bb[bti].localCtx];
IF outRecord # SENull
THEN {
CheckDisjoint[seb[outRecord].fieldCtx, bb[bti].localCtx];
outInit ← AssignDefaults[seb[outRecord].fieldCtx, bb[bti].inline]};
PushCtx[bb[bti].localCtx];
IF bti = RootBti
AND dataPtr.monitored
THEN {
PushCtx[tb[passPtr.lockNode].info];
DeclList[tb[passPtr.lockNode].son[1]];
IF (lockVar ← FirstCtxSe[tb[passPtr.lockNode].info]) # SENull THEN BumpCount[lockVar];
tb[passPtr.lockNode].son[2] ← LockVar[tb[passPtr.lockNode].son[2]];
PopCtx[]; ClearRefStack[]};
DeclList[tb[node].son[2]];
IF outInit # Tree.Null
THEN {
PushTree[outInit]; PushTree[tb[node].son[2]];
PushNode[initlist, 2]; SetInfo[dataPtr.textIndex];
tb[node].son[2] ← PopTree[]};
END;
IF bb[bti].type # RecordSENull
THEN {
IF bti = RootBti THEN SetBodyAttrs[bb[bti].type];
seb[bb[bti].type].mark3 ← TRUE};
current.reachable ← TRUE;
tb[node].son[3] ← UpdateList[tb[node].son[3], Stmt
! InsertCatchLabel => {IF ~catchSeen THEN Log.Error[catchLabel]; RESUME}];
IF current.reachable THEN tb[node].son[3] ← ImpliedReturn[tb[node].son[3]];
BodyList[bb[bti].firstSon];
PopCtx[];
ReverseScanList[tb[node].son[1], CloseItem];
bb[bti].noXfers ← current.noXfers;
bb[bti].hints ← [
safe: pathNP <= ref,
argUpdated: inRecord # SENull AND ctxb[seb[inRecord].fieldCtx].varUpdated,
nameSafe: pathNP # unsafe,
noStrings: ];
PopArgCtx[outRecord]; PopArgCtx[inRecord];
IF bti = RootBti
AND SymLiteralOps.DescribeRefLits[].length # 0
THEN {
rSei: RecordSEIndex = bb[bti].type;
seb[rSei].hints.refField ← TRUE; EnterType[rSei]};
IF current.entry AND lockVar # SENull THEN seb[lockVar].immutable ← lockBit;
current^ ← saved; currentScope ← saveScope;
SetSafety[saveSafety];
dataPtr.bodyIndex ← saveBodyIndex; dataPtr.textIndex ← saveIndex};
Scope:
PUBLIC
PROC [node: Tree.Index, body: Tree.Map] = {
bti: BTIndex = tb[node].info;
saveIndex: CARDINAL = dataPtr.textIndex;
saveScope: BTIndex = currentScope;
dataPtr.textIndex ← bb[bti].sourceIndex;
currentScope ← bti;
PushCtx[bb[bti].localCtx];
DeclList[tb[node].son[1] ! InsertCatchLabel => {Log.Error[catchLabel]; RESUME}];
IF bb[bti].type # RecordSENull THEN seb[bb[bti].type].mark3 ← TRUE;
tb[node].son[2] ← body[tb[node].son[2]];
BodyList[bb[bti].firstSon];
PopCtx[];
currentScope ← saveScope; dataPtr.textIndex ← saveIndex};