-- file GLList.mesa
-- last edited by Satterthwaite, September 16, 1982 8:36 am
DIRECTORY
BcdDefs: TYPE USING [Base, Link, MTIndex, MTRecord, MTNull],
BcdOps: TYPE USING [BcdBase, NameString],
CharIO: TYPE USING [PutChar, PutDecimal, PutString, PutSubString],
FileSegment: TYPE USING [Pages, nullPages],
ListerOps: TYPE USING [],
ListerUtil: TYPE USING [
CreateStream, LoadBcd, LoadModule, MapPages, Message, PutFileID,
SetFileName, SetRoutineSymbols, TTYStream, UnknownModule],
PrincOps: TYPE USING [globalbase],
Space: TYPE USING [Handle, Delete, LongPointer, nullHandle],
Stream: TYPE USING [Delete, Handle],
Strings: TYPE USING [
String, SubStringDescriptor, AppendString, AppendSubString],
Symbols: TYPE USING [
HTIndex, ISEIndex, CSEIndex, CTXIndex, CBTIndex, BitAddress,
HTNull, ISENull, CSENull, CTXNull, RootBti, WordLength],
SymbolTable: TYPE USING [Acquire, Base, Release, SetCacheSize];
GLList: PROGRAM
IMPORTS CharIO, ListerUtil, Space, Stream, Strings, SymbolTable
EXPORTS ListerOps = {
OPEN Symbols;
-- output streams
out: Stream.Handle ← NIL;
OpenOutput: PROC [root: Strings.String, tty: BOOL] = {
IF tty THEN out ← ListerUtil.TTYStream[]
ELSE {
outName: STRING ← [40];
ListerUtil.SetFileName[outName, root, "gl"L];
out ← ListerUtil.CreateStream[outName]}};
CloseOutput: PROC = {Stream.Delete[out]; out ← NIL};
-- symbol printing
symbols: SymbolTable.Base ← NIL;
DoSymbol: PROC [sei: ISEIndex] RETURNS [span: CARDINAL] = {
addr: BitAddress = symbols.seb[sei].idValue;
size: CARDINAL = symbols.seb[sei].idInfo/WordLength;
hti: HTIndex = symbols.HashForSe[sei];
d: Strings.SubStringDescriptor;
n: NAT;
CharIO.PutString[out," "L];
IF hti = HTNull THEN {
CharIO.PutString[out, "(anon)"L];
n ← ("(anon)"L).length}
ELSE {
symbols.SubStringForHash[@d, hti];
CharIO.PutSubString[out, @d];
n ← d.length};
WHILE n < 16 DO CharIO.PutChar[out, ' ]; n ← n + 1 ENDLOOP;
CharIO.PutChar[out, '\t]; CharIO.PutDecimal[out, size];
CharIO.PutChar[out, '\n];
RETURN [addr.wd + size]};
DoContext: PROC [ctx: CTXIndex] RETURNS [maxSpan: CARDINAL ← 0] = {
FOR sei: ISEIndex ← symbols.FirstCtxSe[ctx], symbols.NextSe[sei]
UNTIL sei = ISENull DO
IF ~symbols.seb[sei].constant THEN
maxSpan ← MAX[DoSymbol[sei], maxSpan];
ENDLOOP};
DoFields: PROC [rSei: CSEIndex] RETURNS [maxSpan: CARDINAL] = {
RETURN [WITH t: symbols.seb[rSei] SELECT FROM
record => DoContext[t.fieldCtx],
ENDCASE => 0]};
DoBody: PROC [bti: Symbols.CBTIndex, frameSize: CARDINAL] = {
frameOverhead: CARDINAL = PrincOps.globalbase+1; -- for start trap pointer
maxSpan: CARDINAL ← PrincOps.globalbase;
typeIn, typeOut: CSEIndex;
[typeIn, typeOut] ← symbols.TransferTypes[symbols.bb[bti].ioType];
IF typeIn # CSENull THEN {
CharIO.PutString[out, " Global arguments:\n"L];
maxSpan ← MAX[DoFields[typeIn], maxSpan]};
IF typeOut # CSENull THEN {
CharIO.PutString[out, " Global results:\n"L];
maxSpan ← MAX[DoFields[typeOut], maxSpan]};
IF symbols.bb[bti].localCtx # CTXNull THEN {
CharIO.PutString[out, " Global variables:\n"L];
maxSpan ← MAX[DoContext[symbols.bb[bti].localCtx], maxSpan]};
IF ~symbols.bb[bti].hints.noStrings THEN
CharIO.PutString[out, " Global string literals or string bodies\n"L];
IF maxSpan # frameSize AND frameSize > frameOverhead THEN {
CharIO.PutString[out, " "L];
CharIO.PutDecimal[out, frameSize - maxSpan];
CharIO.PutString[out, " words not in listed variables or overhead\n"L]};
CharIO.PutChar[out, '\n]};
-- module enumeration
DoGlobals: PROC [root: Strings.String] = {
bcdFile: Strings.String ← [100];
bcdSeg: FileSegment.Pages ← FileSegment.nullPages;
bcdSpace: Space.Handle;
bcd: BcdOps.BcdBase ← NIL;
mtb: BcdDefs.Base ← NIL;
ssb: BcdOps.NameString;
EnumerateModules: PROC [proc: PROC [BcdDefs.MTIndex] RETURNS [BOOL]]
RETURNS [BcdDefs.MTIndex] = {
mti: BcdDefs.MTIndex ← BcdDefs.MTIndex.FIRST;
UNTIL mti = bcd.mtLimit DO
IF proc[mti] THEN RETURN [mti];
mti ← mti + (WITH m: mtb[mti] SELECT FROM
direct => BcdDefs.MTRecord.direct.SIZE + m.length*BcdDefs.Link.SIZE,
indirect => BcdDefs.MTRecord.indirect.SIZE,
multiple => BcdDefs.MTRecord.multiple.SIZE,
ENDCASE => ERROR)
ENDLOOP;
RETURN [BcdDefs.MTNull]};
DoModule: PROC [mti: BcdDefs.MTIndex] RETURNS [BOOL←FALSE] = {
d: Strings.SubStringDescriptor ← [
base: @ssb.string, offset: mtb[mti].name, length: ssb.size[mtb[mti].name]];
name: Strings.String ← [100];
sSeg: FileSegment.Pages;
CharIO.PutString[out, "Module: "L]; CharIO.PutSubString[out, @d];
IF mtb[mti].tableCompiled THEN GO TO Table;
Strings.AppendSubString[name, @d];
[symbols: sSeg] ← ListerUtil.LoadModule[bcdSeg, name
! ListerUtil.UnknownModule => {GOTO NoModule}];
IF ~bcd.definitions THEN {
CharIO.PutString[out, ", frame size: "L];
CharIO.PutDecimal[out, mtb[mti].framesize]};
IF mtb[mti].ngfi > 1 THEN {
CharIO.PutString[out, ", gfi slots: "L];
CharIO.PutDecimal[out, mtb[mti].ngfi]};
CharIO.PutChar[out, '\n];
IF sSeg = FileSegment.nullPages THEN GO TO NoSymbols;
SymbolTable.SetCacheSize[0]; -- flush cache
symbols ← SymbolTable.Acquire[sSeg];
ListerUtil.SetRoutineSymbols[symbols];
IF symbols.stHandle.definitionsFile THEN
CharIO.PutString[out, " No global frame\n\n"L]
ELSE DoBody[Symbols.RootBti, mtb[mti].framesize];
SymbolTable.Release[symbols]; symbols ← NIL;
EXITS
Table => CharIO.PutString[out, " -- table compiled\n\n"L];
NoModule => CharIO.PutString[out, " -- not found in file\n\n"L];
NoSymbols => CharIO.PutString[out, " symbols not available\n\n"L]};
MakeBcdFilename[bcdFile, root];
bcdSeg ← ListerUtil.LoadBcd[bcdFile];
bcdSpace ← ListerUtil.MapPages[bcdSeg];
IF bcdSpace # Space.nullHandle THEN {
ListerUtil.PutFileID[out];
bcd ← bcdSpace.LongPointer;
mtb ← LOOPHOLE[bcd, BcdDefs.Base] + bcd.mtOffset;
ssb ← LOOPHOLE[bcd + bcd.ssOffset];
[] ← EnumerateModules[DoModule];
ssb ← NIL; mtb ← NIL; bcd ← NIL;
Space.Delete[bcdSpace]}
ELSE ListerUtil.Message["File could not be opened"L]};
-- overall control
MakeBcdFilename: PROC [bcd, root: Strings.String] = {
Strings.AppendString[bcd, root];
FOR i: CARDINAL IN [0..bcd.length) DO IF bcd[i] = '. THEN RETURN ENDLOOP;
Strings.AppendString[bcd, ".bcd"L]};
ListGlobals: PUBLIC PROC [root: Strings.String, ttyOut: BOOL] = {
OpenOutput[root, ttyOut];
DoGlobals[root];
CloseOutput[]};
}.