-- RTTSupportImpl.mesa -- Last Modified On March 15, 1983 4:03 pm by Paul Rovner DIRECTORY AMTypes USING[Error], AtomsPrivate USING[UnsafeMakeAtom], BrandXSymbolDefs USING[SymbolTableBase, SymbolIndex, SymbolContextIndex, nullHandle, StandardSymbolContextIndex, contextLevelZero, PreDefinedSEI], BrandYSymbolDefs USING[SymbolTableBase, SymbolIndex, SymbolContextIndex, nullHandle, StandardSymbolContextIndex, contextLevelZero, PreDefinedSEI], ConvertUnsafe USING[ToRope], FileSegment USING[Pages], RCMap USING[Index], NewRCMapOps USING[Acquire], Rope USING[ROPE], RTBasic USING[TypeIndex], RTOS USING[UnRavelUSUs], RTMiniModel USING[], -- EXPORTS only RTSymbolDefs USING[SymbolTableHandle, nullHandle, SymbolTableBase, SymbolIndex, SymbolRecordIndex, SymbolNameIndex, nullBase, SymbolConstructorIndex, nullSymbolIndex, SymbolIdIndex, symbolIndexForANY], RTSymbolOps USING[EnumerateCtxIseis, PeelAllButLast, SEUnderType, SETagIDP, NullISEI, SubStringForHash, IsSequence, NullStb, NullSth, ISEName], RTSymbols USING[Outer, AcquireSTBFromMDI, AcquireSTB, ReleaseSTB], RTSymbolsPrivate USING[AcquireSTHFromSTX, GetSTHForModule], RTTypesBasic USING[Type, nullType, unspecType, listOfRefAnyType, refAnyType, anyType], RTTypesBasicPrivate USING[PTypeDesc, TypeStructure, UniqueTypeFinger, SymbolAccess, MapStiStd, STDesc, MakeNewType, MapTiTd, GetLastTypeIndex, FindCanonicalPTD, Enter, FindPTD, SymbolTableIndex, FindSTI], Space USING[Handle, GetHandle, WindowOrigin, GetWindow, GetAttributes, PageFromLongPointer], Strings USING[SubString, EqualSubStrings, SubStringDescriptor, AppendSubString], TimeStamp USING[Null, Stamp], TypeStrings USING[Create], UnsafeStorage USING[NewUZone]; RTTSupportImpl: PROGRAM IMPORTS AMTypes, AtomsPrivate, ConvertUnsafe, NewRCMapOps, RTOS, RTSymbolOps, RTSymbols, RTSymbolsPrivate, RTTypesBasicPrivate, Space, Strings, TypeStrings, UnsafeStorage EXPORTS RTSymbolOps, RTSymbols = BEGIN OPEN bx: BrandXSymbolDefs, by: BrandYSymbolDefs, XRCMapOps: NewRCMapOps, YRCMapOps: NewRCMapOps, XTypeStrings: TypeStrings, YTypeStrings: TypeStrings, Rope, RTSymbolDefs, RTSymbolOps, RTSymbols, RTSymbolsPrivate, RTBasic, RTTypesBasic, RTTypesBasicPrivate; standardXSTH: SymbolTableHandle _ [x[bx.nullHandle]]; standardYSTH: SymbolTableHandle _ [y[by.nullHandle]]; typeStringZone: UNCOUNTED ZONE = UnsafeStorage.NewUZone[]; -- ***************************** -- S U P P O R T F O R T H E D E B U G G E R AcquireType: PUBLIC PROC[stb: SymbolTableBase, seIndex: SymbolIndex, canonicalize: BOOL _ FALSE, rcmi: RCMap.Index _ LAST[RCMap.Index]] RETURNS[type: Type] = {inner: PROC = { ptd: PTypeDesc; utf: UniqueTypeFinger; ustb: SymbolTableBase; usei: SymbolIndex; csei: SymbolConstructorIndex = SEUnderType[stb, seIndex]; isConsType: BOOL = NOT SETagIDP[stb, seIndex]; MakePredefinedType: PROC[preType: Type] = INLINE{utf: UniqueTypeFinger; ustb: SymbolTableBase; usei: SymbolIndex; std: STDesc; [utf, ustb, usei] _ ComputeUTF[stb, seIndex]; std _ STDescFromSTB[ustb]; IF stb # ustb THEN ReleaseSTB[ustb]; IF rcmi = LAST[RCMap.Index] THEN {rcmi _ WITH stb SELECT FROM t: SymbolTableBase.x => XRCMapOps.Acquire [t.e, NARROW[csei, SymbolConstructorIndex.x].e ! ANY => GOTO rcMapAcquisitionError], t: SymbolTableBase.y => YRCMapOps.Acquire [t.e, NARROW[csei, SymbolConstructorIndex.y].e ! ANY => GOTO rcMapAcquisitionError], ENDCASE => ERROR; EXITS rcMapAcquisitionError => ERROR AMTypes.Error[reason: notImplemented, msg: "RCMaps for this type"]}; [] _ MakeNewType [utf, std, usei, WITH stb SELECT FROM t: SymbolTableBase.x => XTypeStrings.Create [t.e, NARROW[csei, SymbolConstructorIndex.x].e, typeStringZone], t: SymbolTableBase.y => YTypeStrings.Create [t.e, NARROW[csei, SymbolConstructorIndex.y].e, typeStringZone], ENDCASE => ERROR, rcmi, FALSE, preType]}; IF NullISEI[LOOPHOLE[seIndex]] THEN ERROR; IF csei = symbolIndexForANY THEN {IF MapTiTd[unspecType] = NIL THEN MakePredefinedType[unspecType]; type _ unspecType; RETURN}; IF isConsType THEN { isListOfRefAny: BOOL _ FALSE; isRefAny: BOOL _ FALSE; isAny: BOOL _ FALSE; WITH stb SELECT FROM t: SymbolTableBase.x => WITH ser: t.e.seb[NARROW[csei, SymbolConstructorIndex.x].e] SELECT FROM -- long => WITH rse: t.e.seb[t.e.UnderType[ser.rangeType]] SELECT FROM -- ref => IF rse.counted -- THEN IF rse.list -- THEN NULL --someday figure out whether this is a LORA -- ELSE IF t.e.seb[t.e.UnderType[rse.refType]].typeTag = any -- THEN isRefAny _ TRUE; -- ENDCASE; any => isAny _ TRUE; ENDCASE; t: SymbolTableBase.y => WITH ser: t.e.seb[NARROW[csei, SymbolConstructorIndex.y].e] SELECT FROM -- long => WITH rse: t.e.seb[t.e.UnderType[ser.rangeType]] SELECT FROM -- ref => IF rse.counted -- THEN IF rse.list -- THEN NULL --someday figure out whether this is a LORA -- ELSE IF t.e.seb[t.e.UnderType[rse.refType]].typeTag = any -- THEN isRefAny _ TRUE; -- ENDCASE; any => isAny _ TRUE; ENDCASE; ENDCASE => ERROR; IF isListOfRefAny THEN {IF MapTiTd[listOfRefAnyType] = NIL THEN MakePredefinedType[listOfRefAnyType]; type _ listOfRefAnyType; RETURN}; IF isRefAny THEN {IF MapTiTd[refAnyType] = NIL THEN MakePredefinedType[refAnyType]; type _ refAnyType; RETURN}; IF isAny THEN {IF MapTiTd[anyType] = NIL THEN MakePredefinedType[anyType]; type _ anyType; RETURN}}; IF canonicalize THEN {ts: TypeStructure; [ptd, ts, utf] _ FindCanonicalType[stb, csei]; -- ts new storage only if ptd = NIL IF ptd # NIL THEN {type _ ptd.equivalentType; RETURN} ELSE {std: STDesc = STDescFromSTB[stb]; IF rcmi = LAST[RCMap.Index] THEN {rcmi _ WITH stb SELECT FROM t: SymbolTableBase.x => XRCMapOps.Acquire [t.e, NARROW[csei, SymbolConstructorIndex.x].e ! ANY => GOTO rcMapAcquisitionError], t: SymbolTableBase.y => YRCMapOps.Acquire [t.e, NARROW[csei, SymbolConstructorIndex.y].e ! ANY => GOTO rcMapAcquisitionError], ENDCASE => ERROR; EXITS rcMapAcquisitionError => ERROR AMTypes.Error[reason: notImplemented, msg: "RCMaps for this type"]}; type _ MakeNewType[utf, std, LOOPHOLE[csei, SymbolIndex], ts, rcmi, TRUE]; RETURN}} ELSE { IF NOT isConsType THEN seIndex _ LOOPHOLE[PeelAllButLast[stb, LOOPHOLE[seIndex, SymbolIdIndex]], SymbolIndex]; [ptd, utf, ustb, usei] _ FindUTF[stb, seIndex]; IF ptd # NIL THEN {IF stb # ustb THEN ReleaseSTB[ustb]; type _ ptd.myType; RETURN} ELSE {std: STDesc = STDescFromSTB[ustb]; IF stb # ustb THEN ReleaseSTB[ustb]; IF rcmi = LAST[RCMap.Index] THEN {rcmi _ WITH stb SELECT FROM t: SymbolTableBase.x => XRCMapOps.Acquire [t.e, NARROW[csei, SymbolConstructorIndex.x].e ! ANY => GOTO rcMapAcquisitionError], t: SymbolTableBase.y => YRCMapOps.Acquire [t.e, NARROW[csei, SymbolConstructorIndex.y].e ! ANY => GOTO rcMapAcquisitionError], ENDCASE => ERROR; EXITS rcMapAcquisitionError => ERROR AMTypes.Error[reason: notImplemented, msg: "RCMaps for this type"]}; type _ MakeNewType [utf, std, usei, WITH stb SELECT FROM t: SymbolTableBase.x => XTypeStrings.Create [t.e, NARROW[csei, SymbolConstructorIndex.x].e, typeStringZone], t: SymbolTableBase.y => YTypeStrings.Create [t.e, NARROW[csei, SymbolConstructorIndex.y].e, typeStringZone], ENDCASE => ERROR, rcmi]; RETURN}}}; Enter[inner ! ANY => GOTO unwind]; EXITS unwind => ERROR}; AcquireSequenceType: PUBLIC PROC[stb: SymbolTableBase, sei: SymbolIndex, -- of sequence part recordSTB: SymbolTableBase, recordSEIndex: SymbolRecordIndex] RETURNS[type: Type] = {inner: PROC = { ptd: PTypeDesc; utf: UniqueTypeFinger; ustb: SymbolTableBase; usei: SymbolIndex; csei: SymbolConstructorIndex = SEUnderType[stb, sei]; IF NOT IsSequence[stb, sei] THEN ERROR; IF SETagIDP[stb, sei] THEN sei _ LOOPHOLE[PeelAllButLast[stb, LOOPHOLE[sei, SymbolIdIndex]], SymbolIndex]; [ptd, utf, ustb, usei] _ FindUTF[stb, sei]; IF ptd # NIL THEN {IF stb # ustb THEN ReleaseSTB[ustb]; type _ ptd.myType} ELSE {rcmi: RCMap.Index; std: STDesc = STDescFromSTB[ustb]; {rcmi _ WITH recordSTB SELECT FROM t: SymbolTableBase.x => XRCMapOps.Acquire [t.e, NARROW[recordSEIndex, SymbolRecordIndex.x].e ! ANY => GOTO rcMapAcquisitionError], t: SymbolTableBase.y => YRCMapOps.Acquire [t.e, NARROW[recordSEIndex, SymbolRecordIndex.y].e ! ANY => GOTO rcMapAcquisitionError], ENDCASE => ERROR; EXITS rcMapAcquisitionError => ERROR AMTypes.Error[reason: notImplemented, msg: "RCMaps for this type"]}; IF stb # ustb THEN ReleaseSTB[ustb]; type _ MakeNewType [utf, std, usei, WITH recordSTB SELECT FROM t: SymbolTableBase.x => XTypeStrings.Create [t.e, NARROW[recordSEIndex, SymbolRecordIndex.x].e, typeStringZone], t: SymbolTableBase.y => YTypeStrings.Create [t.e, NARROW[recordSEIndex, SymbolRecordIndex.y].e, typeStringZone], ENDCASE => ERROR, rcmi]}}; Enter[inner ! ANY => GOTO unwind]; EXITS unwind => ERROR}; AcquireRope: PUBLIC PROC[stb: SymbolTableBase, hti: SymbolNameIndex] RETURNS[ROPE] = { a: Strings.SubStringDescriptor; s: STRING = [100]; SubStringForHash[stb, @a, hti]; s.length _ 0; Strings.AppendSubString[s, @a]; RETURN[ConvertUnsafe.ToRope[LONG[s]]]}; AcquireAtom: PUBLIC PROC[stb: SymbolTableBase, hti: SymbolNameIndex] RETURNS[atom: ATOM] = { a: Strings.SubStringDescriptor; s: STRING = [100]; SubStringForHash[stb, @a, hti]; s.length _ 0; Strings.AppendSubString[s, @a]; RETURN[AtomsPrivate.UnsafeMakeAtom[LOOPHOLE[LONG[s]]]]}; EnumerateTypes: PROC[p: PROC[Type] RETURNS[stop: BOOL]] RETURNS[stopped: BOOL _ FALSE] = {FOR t: TypeIndex IN [FIRST[TypeIndex]..GetLastTypeIndex[]] DO IF p[[t]] THEN RETURN[TRUE] ENDLOOP}; GetTypeSymbols: PUBLIC PROC[type: Type] RETURNS[stb: SymbolTableBase, sei: SymbolIndex] = { moduleName: ROPE; IF type = nullType THEN ERROR AMTypes.Error[reason: typeFault, type: type]; [stb, sei, moduleName] _ DoGetTypeSymbols[type]; IF NullStb[stb] THEN ERROR AMTypes.Error[reason: noSymbols, msg: moduleName]}; GetOriginalTypeSymbols: PUBLIC PROC[type: Type] RETURNS[stb: SymbolTableBase, sei: SymbolIndex] = { IF type = nullType THEN ERROR AMTypes.Error[reason: typeFault, type: type]; [stb, sei,] _ DoGetTypeSymbols[type, TRUE]; IF NullStb[stb] THEN ERROR AMTypes.Error[reason: noSymbols]}; IsPreDefinedSEI: PROC[sei: SymbolIndex] RETURNS[BOOL] = {RETURN[WITH sei SELECT FROM t: SymbolIndex.x => LOOPHOLE[t.e, CARDINAL] IN bx.PreDefinedSEI, t: SymbolIndex.y => LOOPHOLE[t.e, CARDINAL] IN by.PreDefinedSEI, ENDCASE => ERROR]}; DoGetTypeSymbols: PROC[type: Type, originalOnly: BOOL _ FALSE] RETURNS[stb: SymbolTableBase, sei: SymbolIndex, moduleName: ROPE _ NIL] = {stInfo: SymbolAccess = MapTiTd[type].symbolAccess; sth: SymbolTableHandle _ IF originalOnly THEN nullHandle ELSE MapStiStd[stInfo.sti].sth; sei _ IF originalOnly THEN MapTiTd[type].utf.seIndex ELSE stInfo.sei; IF NullSth[sth] THEN IF IsPreDefinedSEI[sei] THEN -- standard symbol; any table will do {IF NOT (IF sei.brand = x THEN NullSth[standardXSTH] ELSE NullSth[standardYSTH]) THEN sth _ (IF sei.brand = x THEN standardXSTH ELSE standardYSTH) ELSE FOR i: SymbolTableIndex IN [1..MapStiStd.length) DO IF MapStiStd[i] = NIL THEN LOOP ELSE IF NOT NullSth[MapStiStd[i].sth] THEN {sth _ MapStiStd[i].sth; EXIT} ELSE { -- go find the symbol table bits [sth: sth, moduleName: moduleName] _ AcquireSTHFromSTX[i]; MapStiStd[i].sth _ sth; IF NOT NullSth[sth] THEN EXIT}; -- found one. ENDLOOP; } ELSE -- go find the symbol table bits {IF originalOnly THEN sth _ GetSTHForModule [MapTiTd[type].utf.umid, NIL, NIL ! AMTypes.Error => CONTINUE] ELSE {[sth: sth, moduleName: moduleName] _ AcquireSTHFromSTX[stInfo.sti]; MapStiStd[stInfo.sti].sth _ sth; IF NullSth[sth] THEN -- try for the original defining module { std: STDesc = [symbolsStamp: MapTiTd[type].utf.umid, bcd: MapStiStd[stInfo.sti].bcd]; sei _ MapTiTd[type].utf.seIndex; IF IsPreDefinedSEI[sei] THEN {IF NOT (IF sei.brand = x THEN NullSth[standardXSTH] ELSE NullSth[standardYSTH]) THEN sth _ (IF sei.brand = x THEN standardXSTH ELSE standardYSTH) ELSE FOR i: SymbolTableIndex IN [1..MapStiStd.length) DO IF MapStiStd[i] = NIL THEN LOOP ELSE IF NOT NullSth[MapStiStd[i].sth] THEN {sth _ MapStiStd[i].sth; EXIT} ELSE { -- go find the symbol table bits [sth: sth, moduleName: moduleName] _ AcquireSTHFromSTX[i]; MapStiStd[i].sth _ sth; IF NOT NullSth[sth] THEN EXIT}; -- found one. ENDLOOP; } ELSE [sth: sth, moduleName: moduleName] _ AcquireSTHFromSTX[FindSTI[std]]; }}; }; IF NullSth[sth] THEN stb _ nullBase ELSE {WITH sth SELECT FROM t: SymbolTableHandle.x => IF NullSth[standardXSTH] THEN standardXSTH _ sth; t: SymbolTableHandle.y => IF NullSth[standardYSTH] THEN standardYSTH _ sth; ENDCASE => ERROR; stb _ AcquireSTB[sth]}; }; -- Creation of new runtime Type descriptors -- ts new storage only if ptd = NIL FindCanonicalType: PROC[stb: SymbolTableBase, csei: SymbolConstructorIndex] RETURNS[ptd: PTypeDesc, ts: TypeStructure, utf: UniqueTypeFinger] = { ts _ WITH stb SELECT FROM t: SymbolTableBase.x => XTypeStrings.Create [t.e, NARROW[csei, SymbolConstructorIndex.x].e, typeStringZone], t: SymbolTableBase.y => YTypeStrings.Create [t.e, NARROW[csei, SymbolConstructorIndex.y].e, typeStringZone], ENDCASE => ERROR; ptd _ FindCanonicalPTD[ts]; IF ptd # NIL THEN {typeStringZone.FREE[@ts]; RETURN[ptd, ptd.typeStructure, ptd.utf]} ELSE {[utf,,] _ ComputeUTF[stb, LOOPHOLE[csei, SymbolIndex]]; RETURN[NIL, ts, utf]}}; -- Recognize identical type previously entered -- hash map: UniqueTypeFinger -> TypeIndex FindUTF: PROC [stb: SymbolTableBase, sei: SymbolIndex] RETURNS[ptd: PTypeDesc, utf: UniqueTypeFinger, ustb: SymbolTableBase, usei: SymbolIndex] = { [utf, ustb, usei] _ ComputeUTF[stb, sei]; RETURN[FindPTD[utf], utf, ustb, usei]}; -- ComputeUTF might return a new (ustb, usei) only if sei is a SymbolIdIndex ComputeUTF: PROC [outerSTB: SymbolTableBase, sei: SymbolIndex] RETURNS[utf: UniqueTypeFinger, ustb: SymbolTableBase, usei: SymbolIndex] = { WITH outerSTB SELECT FROM t: SymbolTableBase.x => [utf, ustb, usei] _ ComputeUTFX[t.e, NARROW[sei, SymbolIndex.x].e]; t: SymbolTableBase.y => [utf, ustb, usei] _ ComputeUTFY[t.e, NARROW[sei, SymbolIndex.y].e]; ENDCASE => ERROR}; ComputeUTFX: PROC [outerSTB: bx.SymbolTableBase, sei: bx.SymbolIndex] RETURNS[utf: UniqueTypeFinger, ustb: SymbolTableBase, usei: SymbolIndex] = { ustb _ [x[outerSTB]]; usei _ [x[sei]]; WITH ser: outerSTB.seb[sei] SELECT FROM id => IF ser.idCtx IN bx.StandardSymbolContextIndex THEN utf _ [umid: TimeStamp.Null, seIndex: usei] -- a primitive type ELSE WITH ctxr: outerSTB.ctxb[ser.idCtx] SELECT FROM included => IF ctxr.level # bx.contextLevelZero THEN utf _ [umid: outerSTB.mdb[ctxr.module].stamp, seIndex: [x[LOOPHOLE[ser.idValue, bx.SymbolIndex]]]] ELSE { inner: PROC[stb: SymbolTableBase] = { p: PROC[stb: SymbolTableBase, isei: SymbolIdIndex] RETURNS[stop: BOOL] = { ssd1: Strings.SubStringDescriptor; ssd2: Strings.SubStringDescriptor; ss1: Strings.SubString = @ssd1; ss2: Strings.SubString = @ssd2; SubStringForHash[[x[outerSTB]], ss1, [x[ser.hash]]]; SubStringForHash[stb, ss2, ISEName[stb, isei]]; IF Strings.EqualSubStrings[ss1, ss2] THEN {utf _ [umid: NARROW[stb, SymbolTableBase.x].e.stHandle.version, seIndex: LOOPHOLE[isei, SymbolIndex]]; usei _ LOOPHOLE[isei, SymbolIndex]; RETURN[TRUE]} ELSE RETURN[FALSE]; }; IF NOT EnumerateCtxIseis[stb: stb, ctx: [x[ctxr.map]], proc: p] THEN ERROR; }; Outer[stb: [x[outerSTB]], mdi: [x[ctxr.module]], inner: inner]; ustb _ AcquireSTBFromMDI[[x[outerSTB]], [x[ctxr.module]]]; RETURN }; ENDCASE => utf _ [umid: outerSTB.stHandle.version, seIndex: [x[sei]]]; cons => utf _ [umid: (IF IsPreDefinedSEI[[x[sei]]] THEN TimeStamp.Null ELSE outerSTB.stHandle.version), -- NOTE seIndex: [x[sei]]]; ENDCASE => ERROR}; ComputeUTFY: PROC [outerSTB: by.SymbolTableBase, sei: by.SymbolIndex] RETURNS[utf: UniqueTypeFinger, ustb: SymbolTableBase, usei: SymbolIndex] = { ustb _ [y[outerSTB]]; usei _ [y[sei]]; WITH ser: outerSTB.seb[sei] SELECT FROM id => IF ser.idCtx IN by.StandardSymbolContextIndex THEN utf _ [umid: TimeStamp.Null, seIndex: usei] -- a primitive type ELSE WITH ctxr: outerSTB.ctxb[ser.idCtx] SELECT FROM included => IF ctxr.level # by.contextLevelZero THEN utf _ [umid: outerSTB.mdb[ctxr.module].stamp, seIndex: [y[LOOPHOLE[ser.idValue, by.SymbolIndex]]]] ELSE { inner: PROC[stb: SymbolTableBase] = { p: PROC[stb: SymbolTableBase, isei: SymbolIdIndex] RETURNS[stop: BOOL] = { ssd1: Strings.SubStringDescriptor; ssd2: Strings.SubStringDescriptor; ss1: Strings.SubString = @ssd1; ss2: Strings.SubString = @ssd2; SubStringForHash[[y[outerSTB]], ss1, [y[ser.hash]]]; SubStringForHash[stb, ss2, ISEName[stb, isei]]; IF Strings.EqualSubStrings[ss1, ss2] THEN {utf _ [umid: NARROW[stb, SymbolTableBase.y].e.stHandle.version, seIndex: LOOPHOLE[isei, SymbolIndex]]; usei _ LOOPHOLE[isei, SymbolIndex]; RETURN[TRUE]} ELSE RETURN[FALSE]; }; IF NOT EnumerateCtxIseis[stb: stb, ctx: [y[ctxr.map]], proc: p] THEN ERROR; }; Outer[stb: [y[outerSTB]], mdi: [y[ctxr.module]], inner: inner]; ustb _ AcquireSTBFromMDI[[y[outerSTB]], [y[ctxr.module]]]; RETURN }; ENDCASE => utf _ [umid: outerSTB.stHandle.version, seIndex: [y[sei]]]; cons => utf _ [umid: (IF IsPreDefinedSEI[[y[sei]]] THEN TimeStamp.Null ELSE outerSTB.stHandle.version), -- NOTE seIndex: [y[sei]]]; ENDCASE => ERROR}; STDescFromSTB: PROC[stb: SymbolTableBase] RETURNS[STDesc] = { version: TimeStamp.Stamp; space: Space.Handle; window: Space.WindowOrigin; sth: SymbolTableHandle; p: LONG POINTER; fsp: FileSegment.Pages; WITH stb SELECT FROM t: SymbolTableBase.x => {version _ t.e.stHandle.version; p _ t.e.stHandle}; t: SymbolTableBase.y => {version _ t.e.stHandle.version; p _ t.e.stHandle}; ENDCASE; space _ RTOS.UnRavelUSUs[Space.GetHandle[Space.PageFromLongPointer[p]]]; window _ Space.GetWindow[space]; fsp _ [file: window.file, span: [base: window.base, pages: Space.GetAttributes[space].size]]; sth _ WITH stb SELECT FROM t: SymbolTableBase.x => [x[fsp]], t: SymbolTableBase.y => [y[fsp]], ENDCASE => ERROR; RETURN[[symbolsStamp: version, sth: sth]]}; END.