TestRecursivelyNILImpl.Mesa
last edited On September 25, 1984 9:06:20 am PDT by Bob Hagmann
DIRECTORY
Allocator,
AllocatorOps,
Process,
RecursivelyNIL USING[NILRef, CheckProc],
SafeStorage;
TestRecursivelyNILImpl: PROGRAM
IMPORTS AllocatorOps, Process, RecursivelyNIL, SafeStorage
= BEGIN
root: REF1 ← NIL;
lastREF: CARDINAL = 19;
REF1Rec: TYPE = RECORD [
I1: INT ← 33,
C1: CARDINAL ← 2323,
next: REF1 ← NIL,
other: REF ANY,
refs: ARRAY [0..lastREF] OF REF ANYALL[NIL]
];
REF1: TYPE = REF REF1Rec;
REF2Rec: TYPE = RECORD [
I2: REAL ← 33.33,
C2: CARDINAL ← 2323,
next: REF1 ← NIL,
other: REF ANY
];
REF2: TYPE = REF REF2Rec;
REF3Rec: TYPE = RECORD [
I2: REAL ← 33.33,
C2: INT ← 2323
];
REF3: TYPE = REF REF3Rec;
REF4Rec: TYPE = RECORD [
rr: REF3 ← NIL
];
REF4: TYPE = REF REF4Rec;
fiveTypeField: TYPE = {foo1, foo2};
REF5Rec: TYPE = RECORD [
varPart: SELECT tag: * FROM
foo1 => [one: REF ANYNIL],
foo2 => [
two: REF3 ← NIL,
anINT: INT ← 3
],
ENDCASE
];
REF5: TYPE = REF REF5Rec;
oneREF5: TYPE = foo1 REF5Rec;
twoREF5: TYPE = foo2 REF5Rec;
REF6Rec: TYPE = RECORD [
nRuns: CARDINAL ← 4,
runs: SEQUENCE length: CARDINAL OF REF4];
REF6: TYPE = REF REF6Rec;
REF7Rec: TYPE = RECORD [
the8: REF8
];
REF7: TYPE = REF REF7Rec;
REF8Rec: TYPE = RECORD [
the7: REF7
];
REF8: TYPE = REF REF8Rec;
REF7Type: SafeStorage.Type = CODE[REF7];
REF8Type: SafeStorage.Type = CODE[REF8];
BuildTest: PROC = {
lastNext: CARDINAL = 249;
current: REF1;
current2: REF1;
refIndex: CARDINAL ← 0;
phase: BOOLFALSE;
runSize: CARDINAL ← 2;
root ← NEW[REF1Rec];
current ← root;
FOR I:INT IN [0..lastNext] DO
new: REF1 ← NEW[REF1Rec];
current.next ← new;
current ← new;
ENDLOOP;
current ← root;
FOR I:INT IN [0..lastNext] DO
new: REF ANYNEW[REF3Rec];
IF phase THEN {
new4: REF4 ← NEW[REF4Rec];
new4.rr ← NARROW[new];
new ← new4;
};
current.other ← new;
current ← current.next;
phase ← ~phase;
ENDLOOP;
current ← root;
current2 ← root;
FOR I:INT IN [0..lastNext] DO
nhp: Allocator.NHeaderP;
i:INT ← 0 ;
new: REF2NEW[REF2Rec];
new5: REF5 ← NIL;
new6: REF6 ← NIL;
new7: REF7 ← NIL;
new8: REF8 ← NIL;
current.refs[refIndex] ← new;
new7 ← NEW[REF7Rec];
new8 ← NEW[REF8Rec];
new.other ← new7;
new8.the7 ← new7;
new7.the8 ← new8;
nhp ← AllocatorOps.REFToNHP[new7];
IF nhp.refCount # 2 THEN {i ← i + 1 };
SafeStorage.EnableFinalization[new7];
IF nhp.refCount # 1 THEN {i ← i + 1 };
refIndex ← refIndex + 1;
IF refIndex > lastREF THEN refIndex ← 0 ;
IF current2 = NIL THEN current2 ← root ELSE current2 ← current2.next;
IF current2 = NIL THEN current2 ← root ELSE current2 ← current2.next;
current.refs[refIndex] ← current2;
refIndex ← refIndex + 1;
IF refIndex > lastREF THEN refIndex ← 0 ;
IF phase THEN {
aNew3: REF3 ← NEW[REF3Rec];
new5 ← NEW[oneREF5 ← [foo1[one: aNew3]]];
}
ELSE {
aNew3: REF3 ← NEW[REF3Rec];
new5 ← NEW[twoREF5 ← [foo2[two: aNew3]]];
};
current.refs[refIndex] ← new5 ;
refIndex ← refIndex + 1;
IF refIndex > lastREF THEN refIndex ← 0 ;
runSize ← runSize + 3;
IF runSize > 14 THEN runSize ← 3 ;
new6 ← NEW[REF6Rec[runSize]];
FOR i: CARDINAL IN [0..runSize) DO
new6[i] ← NEW[REF4Rec ← [ rr: NEW[REF3Rec]]];
ENDLOOP;
current.refs[refIndex] ← new6;
refIndex ← refIndex + 1;
IF refIndex > lastREF THEN refIndex ← 0 ;
current ← current.next;
phase ← ~phase;
ENDLOOP;
};
DestroyTest: PROC = {
RecursivelyNIL.NILRef[root, checkIt];
root ← NIL ;
};
AREFANY: REF ANY ← NIL;
OneREF7Test: PROC = {
i:INT ← 0 ;
nhp: Allocator.NHeaderP;
new7: REF7 ← NIL;
new8: REF8 ← NIL;
new7 ← NEW[REF7Rec];
new8 ← NEW[REF8Rec];
AREFANY ← new7;
new8.the7 ← new7;
new7.the8 ← new8;
nhp ← AllocatorOps.REFToNHP[new7];
IF nhp.refCount # 2 THEN {i ← i + 1 };
SafeStorage.EnableFinalization[new7];
IF nhp.refCount # 1 THEN {i ← i + 1 };
};
checkIt: RecursivelyNIL.CheckProc = {
PROC [objectREF: REF ANY, objectREFType: SafeStorage.Type, referredREF: REF ANY, referredREFType: SafeStorage.Type] RETURNS [OKToNIL: BOOL ← TRUE]
IF objectREFType = REF7Type OR objectREFType = REF8Type THEN ERROR;
IF referredREFType = REF7Type OR referredREFType = REF8Type THEN ERROR;
};
fQ: SafeStorage.FinalizationQueue;
Finalize: PROC = {
ref7: REF7 ← NIL;
DO
ref7 ← NARROW[SafeStorage.FQNext[fQ] ];
ref7.the8 ← NIL;
ref7 ← NIL;
ENDLOOP;
};
fQ ← SafeStorage.NewFQ[];
SafeStorage.EstablishFinalization[CODE[REF7Rec], 1, fQ];
TRUSTED { Process.Detach[FORK Finalize[]] };
END.