<> <> <> DIRECTORY AMModel USING [CharIndex], AMModelPrivate USING [EPI, FGIndex, FGNull, NullPCOffset, PCOffset], BrandXSymbolDefs USING [ SymbolTableBase, BodyTableEntry, FineGrainTableEntry, rootBodyIndex, BodyIndex, nullBodyIndex], BrandYSymbolDefs USING [ SymbolTableBase, BodyTableEntry, FineGrainTableEntry, rootBodyIndex, BodyIndex, nullBodyIndex], RTSymbolDefs USING [SymbolTableBase]; AMModelPrivateImpl: PROGRAM EXPORTS AMModelPrivate = BEGIN OPEN AMModel, AMModelPrivate, bx: BrandXSymbolDefs, by: BrandYSymbolDefs, RTSymbolDefs; <> XBodyPtr: TYPE = LONG POINTER TO bx.BodyTableEntry; YBodyPtr: TYPE = LONG POINTER TO by.BodyTableEntry; EPIndex: TYPE = AMModelPrivate.EPI; FGCard: TYPE = CARDINAL; XFGPtr: TYPE = LONG POINTER TO bx.FineGrainTableEntry; YFGPtr: TYPE = LONG POINTER TO by.FineGrainTableEntry; <> fudge: INT _ 8; -- number of characters to assume beyond the last fgi in a procedure <> FGIToEPI: PUBLIC PROC [stb: SymbolTableBase, fgi: FGIndex] RETURNS [EPIndex] = { WITH stb SELECT FROM t: SymbolTableBase.x => RETURN[FGIToEPIX[t.e, fgi]]; t: SymbolTableBase.y => RETURN[FGIToEPIY[t.e, fgi]]; ENDCASE => ERROR}; FGIToEPIX: PROC [stb: bx.SymbolTableBase, fgi: FGIndex] RETURNS [epi: EPIndex _ 0] = { <> <<(0 for start proc OR invalid fgi)>> bti: bx.BodyIndex; IF fgi = FGNull THEN RETURN; bti _ FGItoBTIX[stb, fgi]; IF bti # bx.nullBodyIndex THEN { body: XBodyPtr _ @stb.bb[bti]; WITH ext: body^ SELECT FROM Callable => epi _ ext.entryIndex; ENDCASE => RETURN; }; }; FGIToEPIY: PROC [stb: by.SymbolTableBase, fgi: FGIndex] RETURNS [epi: EPIndex _ 0] = { <> <<(0 for start proc OR invalid fgi)>> bti: by.BodyIndex; IF fgi = FGNull THEN RETURN; bti _ FGItoBTIY[stb, fgi]; IF bti # by.nullBodyIndex THEN { body: YBodyPtr _ @stb.bb[bti]; WITH ext: body^ SELECT FROM Callable => epi _ ext.entryIndex; ENDCASE => RETURN; }; }; EPIToFirstFGI: PUBLIC PROC [stb: SymbolTableBase, epi: EPIndex, skipArgs: BOOL] RETURNS [FGIndex] = { WITH stb SELECT FROM t: SymbolTableBase.x => RETURN[EPIToFirstFGIX[t.e, epi, skipArgs]]; t: SymbolTableBase.y => RETURN[EPIToFirstFGIY[t.e, epi, skipArgs]]; ENDCASE => ERROR}; EPIToFirstFGIX: PROC [stb: bx.SymbolTableBase, epi: EPIndex, skipArgs: BOOL] RETURNS [fgi: FGIndex _ FGNull] = { <> bti: bx.BodyIndex _ EPItoBTIX[stb, epi]; IF bti = bx.nullBodyIndex THEN RETURN; WITH info: stb.bb[bti].info SELECT FROM External => fgi _ [fgCard: info.startIndex, fudge: FALSE]; ENDCASE; IF skipArgs AND fgi # FGNull THEN { pc: PCOffset _ FGIToFirstPC[[x[stb]], fgi]; DO nfgi: FGIndex _ NextFGIX[stb, fgi, epi]; npc: PCOffset; IF nfgi = FGNull THEN RETURN [fgi]; npc _ FGIToFirstPCX[stb, nfgi]; IF npc # pc THEN RETURN [nfgi]; fgi _ nfgi; ENDLOOP}; }; EPIToFirstFGIY: PROC [stb: by.SymbolTableBase, epi: EPIndex, skipArgs: BOOL] RETURNS [fgi: FGIndex _ FGNull] = { <> bti: by.BodyIndex _ EPItoBTIY[stb, epi]; IF bti = by.nullBodyIndex THEN RETURN; WITH info: stb.bb[bti].info SELECT FROM External => fgi _ [fgCard: info.startIndex, fudge: FALSE]; ENDCASE; IF skipArgs AND fgi # FGNull THEN { pc: PCOffset _ FGIToFirstPC[[y[stb]], fgi]; DO nfgi: FGIndex _ NextFGIY[stb, fgi, epi]; npc: PCOffset; IF nfgi = FGNull THEN RETURN [fgi]; npc _ FGIToFirstPCY[stb, nfgi]; IF npc # pc THEN RETURN [nfgi]; fgi _ nfgi; ENDLOOP}; }; EPIToLastFGI: PUBLIC PROC [stb: SymbolTableBase, epi: EPIndex] RETURNS [FGIndex] = { WITH stb SELECT FROM t: SymbolTableBase.x => RETURN[EPIToLastFGIX[t.e, epi]]; t: SymbolTableBase.y => RETURN[EPIToLastFGIY[t.e, epi]]; ENDCASE => ERROR}; EPIToLastFGIX: PROC [stb: bx.SymbolTableBase, epi: EPIndex] RETURNS [fgi: FGIndex _ FGNull] = { <> <<(FGNull for invalid epi)>> bti: bx.BodyIndex _ EPItoBTIX[stb, epi]; IF bti = bx.nullBodyIndex THEN RETURN; WITH info: stb.bb[bti].info SELECT FROM External => fgi _ [fgCard: info.startIndex + MAX[info.indexLength, 1] - 1, fudge: TRUE]; ENDCASE; }; EPIToLastFGIY: PROC [stb: by.SymbolTableBase, epi: EPIndex] RETURNS [fgi: FGIndex _ FGNull] = { <> <<(FGNull for invalid epi)>> bti: by.BodyIndex _ EPItoBTIY[stb, epi]; IF bti = by.nullBodyIndex THEN RETURN; WITH info: stb.bb[bti].info SELECT FROM External => fgi _ [fgCard: info.startIndex + MAX[info.indexLength, 1] - 1, fudge: TRUE]; ENDCASE; }; EPIToFirstPC: PUBLIC PROC [stb: SymbolTableBase, epi: EPIndex, skipArgs: BOOL] RETURNS [pc: PCOffset _ NullPCOffset] = { fgi: FGIndex _ EPIToFirstFGI[stb, epi, skipArgs]; IF fgi = FGNull THEN RETURN; pc _ FGIToFirstPC[stb, fgi]; }; EPIToLastPC: PUBLIC PROC [stb: SymbolTableBase, epi: EPIndex] RETURNS [PCOffset] = { WITH stb SELECT FROM t: SymbolTableBase.x => RETURN[EPIToLastPCX[t.e, epi]]; t: SymbolTableBase.y => RETURN[EPIToLastPCY[t.e, epi]]; ENDCASE => ERROR}; EPIToLastPCX: PROC [stb: bx.SymbolTableBase, epi: EPIndex] RETURNS [pc: PCOffset _ NullPCOffset] = { <> bti: bx.BodyIndex _ EPItoBTIX[stb, epi]; IF bti = bx.nullBodyIndex THEN RETURN; WITH info: stb.bb[bti].info SELECT FROM External => {pc _ info.bytes; pc _ pc - 1}; ENDCASE; }; EPIToLastPCY: PROC [stb: by.SymbolTableBase, epi: EPIndex] RETURNS [pc: PCOffset _ NullPCOffset] = { <> bti: by.BodyIndex _ EPItoBTIY[stb, epi]; IF bti = by.nullBodyIndex THEN RETURN; WITH info: stb.bb[bti].info SELECT FROM External => {pc _ info.bytes; pc _ pc - 1}; ENDCASE; }; CharIndexToFGI: PUBLIC PROC [stb: SymbolTableBase, ci: CharIndex] RETURNS [FGIndex] = { WITH stb SELECT FROM t: SymbolTableBase.x => RETURN[CharIndexToFGIX[t.e, ci]]; t: SymbolTableBase.y => RETURN[CharIndexToFGIY[t.e, ci]]; ENDCASE => ERROR}; CharIndexToFGIX: PROC [stb: bx.SymbolTableBase, ci: CharIndex] RETURNS [fgi: FGIndex _ FGNull] = { <> <<(FGNull for invalid position)>> bti: bx.BodyIndex _ bx.nullBodyIndex; usedFudge: BOOL _ FALSE; [bti, usedFudge] _ CItoBTIX[stb, ci]; IF bti # bx.nullBodyIndex THEN { body: XBodyPtr _ @stb.bb[bti]; WITH info: body.info SELECT FROM External => { firstFGI: FGCard _ info.startIndex; lastFGI: FGCard _ firstFGI + MAX[info.indexLength, 1] - 1; thisCI: CharIndex _ body.sourceIndex; fgi _ [fgCard: firstFGI, fudge: FALSE]; FOR tfgi: FGCard IN [firstFGI..lastFGI] DO fp: XFGPtr _ @stb.fgTable[tfgi]; nextCI: CharIndex _ thisCI; fgi.fgCard _ tfgi; <> <> WITH fp^ SELECT FROM normal => nextCI _ nextCI + deltaSource; step => IF which = source THEN { thisCI _ nextCI + delta; LOOP}; ENDCASE; IF nextCI > ci THEN RETURN; thisCI _ nextCI; ENDLOOP; fgi.fudge _ TRUE; }; ENDCASE; }; }; CharIndexToFGIY: PROC [stb: by.SymbolTableBase, ci: CharIndex] RETURNS [fgi: FGIndex _ FGNull] = { <> <<(FGNull for invalid position)>> bti: by.BodyIndex _ by.nullBodyIndex; usedFudge: BOOL _ FALSE; [bti, usedFudge] _ CItoBTIY[stb, ci]; IF bti # by.nullBodyIndex THEN { body: YBodyPtr _ @stb.bb[bti]; WITH info: body.info SELECT FROM External => { firstFGI: FGCard _ info.startIndex; lastFGI: FGCard _ firstFGI + MAX[info.indexLength, 1] - 1; thisCI: CharIndex _ body.sourceIndex; fgi _ [fgCard: firstFGI, fudge: FALSE]; FOR tfgi: FGCard IN [firstFGI..lastFGI] DO fp: YFGPtr _ @stb.fgTable[tfgi]; nextCI: CharIndex _ thisCI; fgi.fgCard _ tfgi; <> <> WITH fp^ SELECT FROM normal => nextCI _ nextCI + deltaSource; step => IF which = source THEN { thisCI _ nextCI + delta; LOOP}; ENDCASE; IF nextCI > ci THEN RETURN; thisCI _ nextCI; ENDLOOP; fgi.fudge _ TRUE; }; ENDCASE; }; }; PCToFGI: PUBLIC PROC [stb: SymbolTableBase, epi: EPIndex, pc: PCOffset] RETURNS [FGIndex] = { WITH stb SELECT FROM t: SymbolTableBase.x => RETURN[PCToFGIX[t.e, epi, pc]]; t: SymbolTableBase.y => RETURN[PCToFGIY[t.e, epi, pc]]; ENDCASE => ERROR}; PCToFGIX: PROC [stb: bx.SymbolTableBase, epi: EPIndex, pc: PCOffset] RETURNS [fgi: FGIndex _ FGNull] = { <> <<(FGNull for invalid epi or invalid pc)>> bti: bx.BodyIndex _ EPItoBTIX[stb, epi]; IF bti # bx.nullBodyIndex THEN { body: XBodyPtr _ @stb.bb[bti]; WITH info: body.info SELECT FROM External => { firstFGI: FGCard _ info.startIndex; lastFGI: FGCard _ firstFGI + MAX[info.indexLength, 1] - 1; rem: INT _ pc; IF pc >= info.bytes THEN RETURN [FGNull]; fgi _ [fgCard: firstFGI, fudge: FALSE]; FOR tfgi: FGCard IN [firstFGI..lastFGI] DO fp: XFGPtr _ @stb.fgTable[tfgi]; fgi.fgCard _ tfgi; IF rem = 0 THEN RETURN; WITH fp^ SELECT FROM normal => rem _ rem - deltaObject; step => IF which = object THEN rem _ rem - delta; ENDCASE; IF rem < 0 THEN RETURN; ENDLOOP; fgi.fudge _ TRUE; }; ENDCASE; }; }; PCToFGIY: PROC [stb: by.SymbolTableBase, epi: EPIndex, pc: PCOffset] RETURNS [fgi: FGIndex _ FGNull] = { <> <<(FGNull for invalid epi or invalid pc)>> bti: by.BodyIndex _ EPItoBTIY[stb, epi]; IF bti # by.nullBodyIndex THEN { body: YBodyPtr _ @stb.bb[bti]; WITH info: body.info SELECT FROM External => { firstFGI: FGCard _ info.startIndex; lastFGI: FGCard _ firstFGI + MAX[info.indexLength, 1] - 1; rem: INT _ pc; IF pc >= info.bytes THEN RETURN [FGNull]; fgi _ [fgCard: firstFGI, fudge: FALSE]; FOR tfgi: FGCard IN [firstFGI..lastFGI] DO fp: YFGPtr _ @stb.fgTable[tfgi]; fgi.fgCard _ tfgi; IF rem = 0 THEN RETURN; WITH fp^ SELECT FROM normal => rem _ rem - deltaObject; step => IF which = object THEN rem _ rem - delta; ENDCASE; IF rem < 0 THEN RETURN; ENDLOOP; fgi.fudge _ TRUE; }; ENDCASE; }; }; NextFGI: PUBLIC PROC [stb: SymbolTableBase, fgi: FGIndex, epi: EPIndex] RETURNS [FGIndex] = { WITH stb SELECT FROM t: SymbolTableBase.x => RETURN[NextFGIX[t.e, fgi, epi]]; t: SymbolTableBase.y => RETURN[NextFGIY[t.e, fgi, epi]]; ENDCASE => ERROR}; NextFGIX: PROC [stb: bx.SymbolTableBase, fgi: FGIndex, epi: EPIndex] RETURNS [nfgi: FGIndex _ FGNull] = { <> <> <> bti: bx.BodyIndex; IF fgi = FGNull THEN RETURN; bti _ EPItoBTIX[stb, epi]; IF bti # bx.nullBodyIndex THEN WITH info: stb.bb[bti].info SELECT FROM External => { firstFGI: FGCard _ info.startIndex; lastFGI: FGCard _ firstFGI + MAX[info.indexLength, 1] - 1; IF fgi.fudge OR fgi.fgCard NOT IN [firstFGI..lastFGI] THEN RETURN; IF fgi.fgCard = lastFGI THEN fgi.fudge _ TRUE ELSE fgi.fgCard _ fgi.fgCard + 1; nfgi _ fgi; }; ENDCASE; }; NextFGIY: PROC [stb: by.SymbolTableBase, fgi: FGIndex, epi: EPIndex] RETURNS [nfgi: FGIndex _ FGNull] = { <> <> <> bti: by.BodyIndex; IF fgi = FGNull THEN RETURN; bti _ EPItoBTIY[stb, epi]; IF bti # by.nullBodyIndex THEN WITH info: stb.bb[bti].info SELECT FROM External => { firstFGI: FGCard _ info.startIndex; lastFGI: FGCard _ firstFGI + MAX[info.indexLength, 1] - 1; IF fgi.fudge OR fgi.fgCard NOT IN [firstFGI..lastFGI] THEN RETURN; IF fgi.fgCard = lastFGI THEN fgi.fudge _ TRUE ELSE fgi.fgCard _ fgi.fgCard + 1; nfgi _ fgi; }; ENDCASE; }; FGIToFirstChar: PUBLIC PROC [stb: SymbolTableBase, fgi: FGIndex] RETURNS [ci: CharIndex] = { WITH stb SELECT FROM t: SymbolTableBase.x => RETURN[FGIToFirstCharX[t.e, fgi]]; t: SymbolTableBase.y => RETURN[FGIToFirstCharY[t.e, fgi]]; ENDCASE => ERROR}; FGIToFirstCharX: PROC [stb: bx.SymbolTableBase, fgi: FGIndex] RETURNS [ci: CharIndex _ -1] = { <> <<-1 for invalid fgi>> bti: bx.BodyIndex _ FGItoBTIX[stb, fgi]; IF bti # bx.nullBodyIndex THEN { body: XBodyPtr _ @stb.bb[bti]; WITH info: body.info SELECT FROM External => { firstFGI: FGCard _ info.startIndex; fgc: FGCard _ fgi.fgCard + (IF fgi.fudge THEN 1 ELSE 0); ci _ body.sourceIndex; FOR tfgc: FGCard IN [firstFGI..fgc) DO fp: XFGPtr _ @stb.fgTable[tfgc]; WITH fp^ SELECT FROM normal => ci _ ci + deltaSource; step => IF which = source THEN ci _ ci + delta; ENDCASE; ENDLOOP; IF fgc > firstFGI THEN { <> <> fp: XFGPtr _ @stb.fgTable[fgc - 1]; WITH fp^ SELECT FROM step => IF which = source THEN ci _ ci - delta; ENDCASE; }; }; ENDCASE; }; }; FGIToFirstCharY: PROC [stb: by.SymbolTableBase, fgi: FGIndex] RETURNS [ci: CharIndex _ -1] = { <> <<-1 for invalid fgi>> bti: by.BodyIndex _ FGItoBTIY[stb, fgi]; IF bti # by.nullBodyIndex THEN { body: YBodyPtr _ @stb.bb[bti]; WITH info: body.info SELECT FROM External => { firstFGI: FGCard _ info.startIndex; fgc: FGCard _ fgi.fgCard + (IF fgi.fudge THEN 1 ELSE 0); ci _ body.sourceIndex; FOR tfgc: FGCard IN [firstFGI..fgc) DO fp: YFGPtr _ @stb.fgTable[tfgc]; WITH fp^ SELECT FROM normal => ci _ ci + deltaSource; step => IF which = source THEN ci _ ci + delta; ENDCASE; ENDLOOP; IF fgc > firstFGI THEN { <> <> fp: YFGPtr _ @stb.fgTable[fgc - 1]; WITH fp^ SELECT FROM step => IF which = source THEN ci _ ci - delta; ENDCASE; }; }; ENDCASE; }; }; FGIToLastChar: PUBLIC PROC [stb: SymbolTableBase, fgi: FGIndex] RETURNS [ci: CharIndex] = { WITH stb SELECT FROM t: SymbolTableBase.x => RETURN[FGIToLastCharX[t.e, fgi]]; t: SymbolTableBase.y => RETURN[FGIToLastCharY[t.e, fgi]]; ENDCASE => ERROR}; FGIToLastCharX: PROC [stb: bx.SymbolTableBase, fgi: FGIndex] RETURNS [ci: CharIndex _ -1] = { <> <<-1 for invalid fgi>> bti: bx.BodyIndex _ FGItoBTIX[stb, fgi]; IF bti # bx.nullBodyIndex THEN { body: XBodyPtr _ @stb.bb[bti]; WITH info: body.info SELECT FROM External => { firstFGI: FGCard _ info.startIndex; lastFGI: FGCard _ firstFGI + MAX[info.indexLength, 1] - 1; ci _ body.sourceIndex; FOR tfgi: FGCard IN [firstFGI..fgi.fgCard] DO fp: XFGPtr _ @stb.fgTable[tfgi]; WITH fp^ SELECT FROM normal => ci _ ci + deltaSource; step => IF which = source THEN ci _ ci + delta; ENDCASE; ENDLOOP; IF fgi.fudge THEN ci _ ci + fudge ELSE ci _ ci - 1; }; ENDCASE; }; }; FGIToLastCharY: PROC [stb: by.SymbolTableBase, fgi: FGIndex] RETURNS [ci: CharIndex _ -1] = { <> <<-1 for invalid fgi>> bti: by.BodyIndex _ FGItoBTIY[stb, fgi]; IF bti # by.nullBodyIndex THEN { body: YBodyPtr _ @stb.bb[bti]; WITH info: body.info SELECT FROM External => { firstFGI: FGCard _ info.startIndex; lastFGI: FGCard _ firstFGI + MAX[info.indexLength, 1] - 1; ci _ body.sourceIndex; FOR tfgi: FGCard IN [firstFGI..fgi.fgCard] DO fp: YFGPtr _ @stb.fgTable[tfgi]; WITH fp^ SELECT FROM normal => ci _ ci + deltaSource; step => IF which = source THEN ci _ ci + delta; ENDCASE; ENDLOOP; IF fgi.fudge THEN ci _ ci + fudge ELSE ci _ ci - 1; }; ENDCASE; }; }; FGIToFirstPC: PUBLIC PROC [stb: SymbolTableBase, fgi: FGIndex] RETURNS [pc: PCOffset] = { WITH stb SELECT FROM t: SymbolTableBase.x => RETURN[FGIToFirstPCX[t.e, fgi]]; t: SymbolTableBase.y => RETURN[FGIToFirstPCY[t.e, fgi]]; ENDCASE => ERROR}; FGIToFirstPCX: PROC [stb: bx.SymbolTableBase, fgi: FGIndex] RETURNS [pc: PCOffset _ NullPCOffset] = { <> <<(NullPCOffset for invalid fgi)>> bti: bx.BodyIndex _ FGItoBTIX[stb, fgi]; IF bti # bx.nullBodyIndex THEN { body: XBodyPtr _ @stb.bb[bti]; WITH info: body.info SELECT FROM External => { firstFGI: FGCard _ info.startIndex; tfgi: FGCard _ fgi.fgCard + (IF fgi.fudge THEN 1 ELSE 0); pc _ 0; FOR tfgi IN [firstFGI..tfgi) DO fp: XFGPtr _ @stb.fgTable[tfgi]; WITH fp^ SELECT FROM normal => pc _ pc + deltaObject; step => IF which = object THEN pc _ pc + delta; ENDCASE; ENDLOOP; }; ENDCASE; }; }; FGIToFirstPCY: PROC [stb: by.SymbolTableBase, fgi: FGIndex] RETURNS [pc: PCOffset _ NullPCOffset] = { <> <<(NullPCOffset for invalid fgi)>> bti: by.BodyIndex _ FGItoBTIY[stb, fgi]; IF bti # by.nullBodyIndex THEN { body: YBodyPtr _ @stb.bb[bti]; WITH info: body.info SELECT FROM External => { firstFGI: FGCard _ info.startIndex; tfgi: FGCard _ fgi.fgCard + (IF fgi.fudge THEN 1 ELSE 0); pc _ 0; FOR tfgi IN [firstFGI..tfgi) DO fp: YFGPtr _ @stb.fgTable[tfgi]; WITH fp^ SELECT FROM normal => pc _ pc + deltaObject; step => IF which = object THEN pc _ pc + delta; ENDCASE; ENDLOOP; }; ENDCASE; }; }; FGIToLastPC: PUBLIC PROC [stb: SymbolTableBase, fgi: FGIndex] RETURNS [pc: PCOffset] = { WITH stb SELECT FROM t: SymbolTableBase.x => RETURN[FGIToLastPCX[t.e, fgi]]; t: SymbolTableBase.y => RETURN[FGIToLastPCY[t.e, fgi]]; ENDCASE => ERROR}; FGIToLastPCX: PROC [stb: bx.SymbolTableBase, fgi: FGIndex] RETURNS [pc: PCOffset _ NullPCOffset] = { <> <<(NullPCOffset for invalid fgi)>> bti: bx.BodyIndex _ FGItoBTIX[stb, fgi]; IF bti # bx.nullBodyIndex THEN { body: XBodyPtr _ @stb.bb[bti]; WITH info: body.info SELECT FROM External => { firstFGI: FGCard _ info.startIndex; IF fgi.fudge THEN { pc _ info.bytes; pc _ pc - 1; RETURN}; pc _ 0; FOR tfgi: FGCard IN [firstFGI..fgi.fgCard] DO fp: XFGPtr _ @stb.fgTable[tfgi]; WITH fp^ SELECT FROM normal => pc _ pc + deltaObject; step => IF which = object THEN pc _ pc + delta; ENDCASE; ENDLOOP; pc _ pc - 1; }; ENDCASE; }; }; FGIToLastPCY: PROC [stb: by.SymbolTableBase, fgi: FGIndex] RETURNS [pc: PCOffset _ NullPCOffset] = { <> <<(NullPCOffset for invalid fgi)>> bti: by.BodyIndex _ FGItoBTIY[stb, fgi]; IF bti # by.nullBodyIndex THEN { body: YBodyPtr _ @stb.bb[bti]; WITH info: body.info SELECT FROM External => { firstFGI: FGCard _ info.startIndex; IF fgi.fudge THEN { pc _ info.bytes; pc _ pc - 1; RETURN}; pc _ 0; FOR tfgi: FGCard IN [firstFGI..fgi.fgCard] DO fp: YFGPtr _ @stb.fgTable[tfgi]; WITH fp^ SELECT FROM normal => pc _ pc + deltaObject; step => IF which = object THEN pc _ pc + delta; ENDCASE; ENDLOOP; pc _ pc - 1; }; ENDCASE; }; }; <> EPItoBTIX: PROC[stb: bx.SymbolTableBase, epi: EPIndex] RETURNS [outerBti: bx.BodyIndex _ bx.nullBodyIndex] = { <> <> <> innerEPItoBTI: PROC [bti: bx.BodyIndex] RETURNS [stop: BOOL _ FALSE] = { body: XBodyPtr _ @stb.bb[bti]; thisEPI: EPIndex _ 0; WITH ext: body^ SELECT FROM Callable => thisEPI _ ext.entryIndex; ENDCASE => RETURN; WITH info: body.info SELECT FROM External => IF epi = thisEPI THEN {outerBti _ bti; stop _ TRUE}; ENDCASE; }; [] _ stb.EnumerateBodies[bx.rootBodyIndex, innerEPItoBTI]; }; EPItoBTIY: PROC[stb: by.SymbolTableBase, epi: EPIndex] RETURNS [outerBti: by.BodyIndex _ by.nullBodyIndex] = { <> <> <> innerEPItoBTI: PROC [bti: by.BodyIndex] RETURNS [stop: BOOL _ FALSE] = { body: YBodyPtr _ @stb.bb[bti]; thisEPI: EPIndex _ 0; WITH ext: body^ SELECT FROM Callable => thisEPI _ ext.entryIndex; ENDCASE => RETURN; WITH info: body.info SELECT FROM External => IF epi = thisEPI THEN {outerBti _ bti; stop _ TRUE}; ENDCASE; }; [] _ stb.EnumerateBodies[by.rootBodyIndex, innerEPItoBTI]; }; FGItoBTIX: PROC[stb: bx.SymbolTableBase, fgi: FGIndex] RETURNS [outerBti: bx.BodyIndex _ bx.nullBodyIndex] = { <> <> <> innerFGItoBTI: PROC [bti: bx.BodyIndex] RETURNS [stop: BOOL _ FALSE] = { body: XBodyPtr _ @stb.bb[bti]; thisEPI: EPIndex _ 0; WITH ext: body^ SELECT FROM Callable => thisEPI _ ext.entryIndex; ENDCASE => RETURN; WITH info: body.info SELECT FROM External => { firstFGI: FGCard _ info.startIndex; lastFGI: FGCard _ firstFGI + MAX[info.indexLength, 1] - 1; IF fgi.fgCard IN [firstFGI..lastFGI] THEN { outerBti _ bti; stop _ TRUE}; }; ENDCASE; }; [] _ stb.EnumerateBodies[bx.rootBodyIndex, innerFGItoBTI]; }; FGItoBTIY: PROC[stb: by.SymbolTableBase, fgi: FGIndex] RETURNS [outerBti: by.BodyIndex _ by.nullBodyIndex] = { <> <> <> innerFGItoBTI: PROC [bti: by.BodyIndex] RETURNS [stop: BOOL _ FALSE] = { body: YBodyPtr _ @stb.bb[bti]; thisEPI: EPIndex _ 0; WITH ext: body^ SELECT FROM Callable => thisEPI _ ext.entryIndex; ENDCASE => RETURN; WITH info: body.info SELECT FROM External => { firstFGI: FGCard _ info.startIndex; lastFGI: FGCard _ firstFGI + MAX[info.indexLength, 1] - 1; IF fgi.fgCard IN [firstFGI..lastFGI] THEN { outerBti _ bti; stop _ TRUE}; }; ENDCASE; }; [] _ stb.EnumerateBodies[by.rootBodyIndex, innerFGItoBTI]; }; CItoBTIX: PROC[stb: bx.SymbolTableBase, ci: CharIndex] RETURNS [bestBTI: bx.BodyIndex _ bx.nullBodyIndex, usedFudge: BOOL _ FALSE] = { <> <> <> innerCItoBTI: PROC [bti: bx.BodyIndex] RETURNS [stop: BOOL _ FALSE] = { <> <> <> body: XBodyPtr _ @stb.bb[bti]; thisEPI: EPIndex _ 0; bestCI: CharIndex _ 0; WITH ext: body^ SELECT FROM Callable => thisEPI _ ext.entryIndex; ENDCASE => RETURN; WITH info: body.info SELECT FROM External => { firstFGI: FGCard _ info.startIndex; lastFGI: FGCard _ firstFGI + MAX[info.indexLength, 1] - 1; thisCI: CharIndex _ body.sourceIndex; IF thisCI <= ci AND bestCI <= thisCI THEN { <> lastCI: CharIndex _ thisCI; FOR tfgi: FGCard IN [firstFGI..lastFGI] DO fp: XFGPtr _ @stb.fgTable[tfgi]; WITH fp^ SELECT FROM normal => lastCI _ lastCI + deltaSource; step => IF which = source THEN lastCI _ lastCI + delta; ENDCASE; IF lastCI >= ci THEN EXIT; -- this index is OK ENDLOOP; IF lastCI < ci THEN { IF lastCI+fudge < ci THEN RETURN; -- no match here usedFudge _ TRUE} ELSE usedFudge _ FALSE; bestBTI _ bti; bestCI _ thisCI; }; }; ENDCASE; }; [] _ stb.EnumerateBodies[bx.rootBodyIndex, innerCItoBTI]; }; CItoBTIY: PROC[stb: by.SymbolTableBase, ci: CharIndex] RETURNS [bestBTI: by.BodyIndex _ by.nullBodyIndex, usedFudge: BOOL _ FALSE] = { <> <> <> innerCItoBTI: PROC [bti: by.BodyIndex] RETURNS [stop: BOOL _ FALSE] = { <> <> <> body: YBodyPtr _ @stb.bb[bti]; thisEPI: EPIndex _ 0; bestCI: CharIndex _ 0; WITH ext: body^ SELECT FROM Callable => thisEPI _ ext.entryIndex; ENDCASE => RETURN; WITH info: body.info SELECT FROM External => { firstFGI: FGCard _ info.startIndex; lastFGI: FGCard _ firstFGI + MAX[info.indexLength, 1] - 1; thisCI: CharIndex _ body.sourceIndex; IF thisCI <= ci AND bestCI <= thisCI THEN { <> lastCI: CharIndex _ thisCI; FOR tfgi: FGCard IN [firstFGI..lastFGI] DO fp: YFGPtr _ @stb.fgTable[tfgi]; WITH fp^ SELECT FROM normal => lastCI _ lastCI + deltaSource; step => IF which = source THEN lastCI _ lastCI + delta; ENDCASE; IF lastCI >= ci THEN EXIT; -- this index is OK ENDLOOP; IF lastCI < ci THEN { IF lastCI+fudge < ci THEN RETURN; -- no match here usedFudge _ TRUE} ELSE usedFudge _ FALSE; bestBTI _ bti; bestCI _ thisCI; }; }; ENDCASE; }; [] _ stb.EnumerateBodies[bx.rootBodyIndex, innerCItoBTI]; }; END.