-- AMModelPrivate.Mesa
-- Russ Atkinson, October 21, 1982 3:41 pm
-- last modified on November 12, 1982 10:29 am by Paul Rovner

DIRECTORY
AMModel USING[CharIndex, Class],
BcdDefs USING[VersionStamp],
BcdOps USING[BcdBase],
PilotLoadStateFormat USING[NullConfig, ConfigIndex],
PrincOps USING[EPRange, MaxNGfi, BytePC, GFTIndex],
Rope USING[ROPE],
RTBasic USING[TV],
RTSymbols USING[SymbolTableBase],
RTTypesPrivate USING[TypedVariableRec],
WorldVM USING[World];

AMModelPrivate: DEFINITIONS
= BEGIN OPEN PilotLoadStateFormat, Rope, AMModel, WorldVM;

FGIndex: TYPE = RECORD[fgCard: CARDINAL, fudge: BOOL];
-- fgCard is used to index the fine grain table
-- fudge is used to indicate that this index indicates the "missing" index for the last statement in the procedure. This kludge should be resolved when the compiler actually puts out an FGI for the last statement. Until then, if fudge is true, we will try to compensate for the missing FGI in a transparent manner. Fudge should only be true if fgCard is the last fgi for a procedure.
FGNull: FGIndex = [LAST[CARDINAL], FALSE];

EPI: TYPE = [0..PrincOps.EPRange*PrincOps.MaxNGfi);

PCOffset: TYPE = INT; -- # of bytes from start of procedure
NullPCOffset: PCOffset = -1; -- indicates no such PCOffset available

RefTVRec: TYPE = REF RTTypesPrivate.TypedVariableRec;

-- either binder output bundle for a config, or compiler output bundle
-- for a prog module, DEFs module, proc, or statement
SectionRec: TYPE =
RECORD[ SELECT class: Class FROM
model => [configName: ROPE ← , -- require specification
versionStamp: BcdDefs.VersionStamp ← ,
configContext: ConfigContext ← NIL
-- useful if it's loaded, but not required
],
prog => [moduleName: ROPE ← ,
versionStamp: BcdDefs.VersionStamp ← ,
someGFHTV: RefTVRec ← NIL -- useful if it's loaded, not required
],
interface =>
[moduleName: ROPE ← ,
versionStamp: BcdDefs.VersionStamp ←
],
proc => [prog: REF prog SectionRec ← ,
entryPointIndex: EPI,
procTV: RefTVRec ← NIL -- useful if it's loaded, but not required
],
statement =>
[prog: REF prog SectionRec ← ,
fgtIndex: FGIndex
]
ENDCASE
];

-- A Context is either a ConfigContext, a StatementContext, or a TV for a
-- global frame, local frame or IR instance.
ConfigContext: TYPE = REF ConfigContextObj;
ConfigContextObj: TYPE =
RECORD[world: World ← ,
worldIncarnation: LONG CARDINAL,
configIndex: ConfigIndex ← NullConfig -- NullConfig represents rootContext
];

StatementContext: TYPE = REF StatementContextObj;
StatementContextObj: TYPE = RECORD[localFrameTV: RefTVRec];

z: ZONE;

-- The procedures below are implemented in AMModelPrivateImpl (Russ Atkinson). They deal with the fine grain table, entry points, and character indexes. BEWARE: there is currently no FGI for the last statement in a procedure. This will probably effect character position to fgi translation, and produce other unfortunate effects until this bug is fixed. The use of fudge is an attempt to get around this problem.

FGIToEPI: PROC [stb: RTSymbols.SymbolTableBase, fgi: FGIndex] RETURNS [EPI];
-- returns first fine grain index for the given procedure
-- (0 for start proc OR invalid fgi)

EPIToFirstFGI: PROC [stb: RTSymbols.SymbolTableBase, epi: EPI] RETURNS [FGIndex];
-- returns first fine grain index for the given procedure
-- (FGNull for invalid epi)

EPIToLastFGI: PROC [stb: RTSymbols.SymbolTableBase, epi: EPI] RETURNS [FGIndex];
-- returns last fine grain index for the given procedure
-- (FGNull for invalid epi)

EPIToFirstPC: PROC [stb: RTSymbols.SymbolTableBase, epi: EPI] RETURNS [PCOffset];
-- returns offset (usually 0) of first byte in the procedure

EPIToLastPC: PROC [stb: RTSymbols.SymbolTableBase, epi: EPI] RETURNS [PCOffset];
-- returns offset of last byte in the procedure (may be padding byte)

CharIndexToFGI: PROC [stb: RTSymbols.SymbolTableBase, ci: CharIndex] RETURNS [FGIndex];
-- returns the "best" fine grain index for the given character position
-- (FGNull for invalid position)

PCToFGI: PROC
[stb: RTSymbols.SymbolTableBase, epi: EPI, pc: PCOffset] RETURNS [FGIndex];
-- returns the "best" fine grain index for the given pc offset in the given procedure
-- (FGNull for invalid epi or invalid pc)

NextFGI: PROC [stb: RTSymbols.SymbolTableBase, fgi: FGIndex, epi: EPI] RETURNS [FGIndex];
-- returns FGNull if next fgi is in a different proc than entryPointIndex

FGIToFirstChar: PROC [stb: RTSymbols.SymbolTableBase, fgi: FGIndex] RETURNS [CharIndex];
-- returns character position of first byte in the fine grain entry
-- (-1 for invalid fgi)

FGIToLastChar: PROC [stb: RTSymbols.SymbolTableBase, fgi: FGIndex] RETURNS [CharIndex];
-- returns character position of last byte in the fine grain entry
-- (-1 for invalid fgi)

FGIToFirstPC: PROC [stb: RTSymbols.SymbolTableBase, fgi: FGIndex] RETURNS [PCOffset];
-- returns offset of first byte in the fine grain entry
-- (NullPCOffset for invalid fgi)

FGIToLastPC: PROC [stb: RTSymbols.SymbolTableBase, fgi: FGIndex] RETURNS [PCOffset];
-- returns offset (usually 0) of first byte in the fine grain entry
-- (NullPCOffset for invalid fgi)

ProgPCToFGI: PROC[prog: RTBasic.TV, pc: PrincOps.BytePC] RETURNS[FGIndex];

-- A BCD acquired from the local loadstate does not need to be released
GetLocalBCD: PROC[rgfi: PrincOps.GFTIndex] RETURNS[bcd: BcdOps.BcdBase ← NIL];

-- This guy uses RTTypesRemotePrivate.AcquireRemoteBCD.
-- BEWARE. Don't forget to release it via RTTypesRemotePrivate.
ReleaseRemoteBCD
GetRemoteBCD: PROC[world: World, rgfi: PrincOps.GFTIndex]
RETURNS[bcd: BcdOps.BcdBase ← NIL];

GetModuleSTB: PROC[bcd: BcdOps.BcdBase, versionStamp: BcdDefs.VersionStamp]
RETURNS[RTSymbols.SymbolTableBase];

END
.