-- RTTypesRemotePrivateImpl.Mesa -- last modified on May 25, 1983 10:06 am by Paul Rovner DIRECTORY AMBridge USING[WordSequence, WordSequenceRecord, RemotePD, RemoteGlobalFrameHandle, RemoteFrameHandle, RemoteRef, RemoteSED, RemotePointer, TVForRemoteFrame, nilRemotePD, nilRemoteGlobalFrameHandle, nilRemoteFrameHandle, GetWorld], AMProcessBasic USING[ReturnLink], AMTypes USING[Error, TypedVariable, TVType], BcdDefs USING[MTIndex, BCD, FTSelf, SGIndex, SGNull, FTIndex, NameRecord, VersionStamp], BcdOps USING[BcdBase, MTHandle, ProcessModules, NameString, FTHandle, ProcessFiles], BrandXSymbolDefs USING [rootBodyIndex, SymbolTableBase, SymbolIdIndex, SymbolIndex, BodyIndex], BrandYSymbolDefs USING [rootBodyIndex, SymbolTableBase, SymbolIdIndex, SymbolIndex, BodyIndex], ConvertUnsafe USING[ToRope], Environment USING[wordsPerPage], LongString USING[AppendChar, AppendOctal, SubStringDescriptor, AppendSubString], PilotLoadStateOps USING[InputLoadState, ReleaseLoadState, GetModule, AcquireBcd], PilotLoadStateFormat USING[LoadState, LoadStateObject, ModuleInfo], PilotLoadStatePrivate USING[InstallLoadState], PrincOps USING[BytePC, ControlLink, CSegPrefix, EntryVectorItem, EPRange, Frame, FrameCodeBase, FrameHandle, GFTIndex, GlobalFrame, GlobalFrameHandle, localbase, NullLink, ProcDesc, SignalDesc, UnboundLink, NullGlobalFrame], PrincOpsRuntime USING[GFT, GFTItem, GetFrame], Rope USING[ROPE, Concat], RTBasic USING[Type, nullType], RTCommon USING[Field, StoreFieldLong], RTQuanta USING[QuantumIndex], RTRefCounts USING[AGCState], RTSD USING[sRTState, sMapStiStd], RTSymbolDefs USING[SymbolTableBase, SymbolTableHandle, nullHandle, CallableBodyIndex, BodyIndex, rootBodyIndex, SymbolIdIndex, SymbolRecordIndex, SymbolIndex, nullBodyIndex], RTSymbolOps USING[AcquireType, EnumerateRecordIseis, AcquireRope, NullISEI], RTSymbols USING[ReleaseSTB, AcquireSTB], RTSymbolsPrivate USING[AcquireSTHFromSTX, GetSTHForModule], RTTypesBasicPrivate USING[TypeDesc, UniqueTypeFinger, STDesc, RMapTiTd, PTypeDesc, FindSTI, PSTDesc, RMapStiStd, SymbolTableIndex, MapStiStd], RTTypesPrivate USING[TypedVariableRec, GetCBTI, ConvertCbti], RTTypesRemotePrivate USING[RemoteErrorType, EVRange], RTZones USING[ZoneFinger, SubZone, SubZoneIndex, TMapQZf, MapPtrQ, NodeHeader, sizeNd, SubZoneRec, RMapQZf, RMapSziSz], Runtime USING[ValidateFrame], SDDefs USING[SD, sSignal, sGFTLength], SafeStorage USING[NewZone], Strings USING[SubStringDescriptor, AppendSubString], Table USING[Base], UnsafeStorage USING[NewUObject, GetSystemUZone], WorldVM USING[Address, CopyRead, CopyWrite, Long, LongRead, LongWrite, Read, ShortAddress, World, Write, Loadstate, Lock, Unlock, CurrentIncarnation]; RTTypesRemotePrivateImpl: MONITOR -- protects the cache of remote BCDs IMPORTS AMBridge, AMProcessBasic, AMTypes, BcdOps, ConvertUnsafe, LongString, PilotLoadStateOps, PilotLoadStatePrivate, PrincOpsRuntime, Rope, RTCommon, RTSymbolOps, RTSymbols, RTSymbolsPrivate, RTTypesBasicPrivate, RTTypesPrivate, RTZones, Runtime, SafeStorage, Strings, UnsafeStorage, WorldVM EXPORTS RTTypesRemotePrivate = BEGIN OPEN AMBridge, AMTypes, bx: BrandXSymbolDefs, by: BrandYSymbolDefs, RTBasic, RTSymbolDefs, RTSymbolOps, RTSymbols, RTTypesPrivate, RTTypesRemotePrivate, WorldVM; z: ZONE = SafeStorage.NewZone[prefixed]; -- TYPES RemoteBCDCache: TYPE = LIST OF BCDCacheRec; BCDCacheRec: TYPE = RECORD[world: World _ , remoteBCD: Address _ , localBCD: BcdOps.BcdBase _ , useCount: INT _ ]; -- VARIABLES remoteBCDCache: RemoteBCDCache _ NIL; remoteBCDCacheLength: NAT _ 0; maxRemoteBCDCacheLength: NAT _ 1; -- CONSTANTS SignallerFrameMessageOffset: NAT = 9; SignallerFrameSignalOffset: NAT = 7; -- S I G N A L S RemoteError: PUBLIC ERROR[type: RemoteErrorType, message: LONG POINTER TO TEXT _ NIL] = CODE; -- P R O C E D U R E S --XXX -- raises notImplemented ValidateRemoteRef: PUBLIC PROC[ref: RemoteRef] = {IF FALSE THEN ERROR AMTypes.Error[reason: notImplemented, msg: "ValidateRemoteRef"]; }; SameCode: PUBLIC PROC [f1, f2: RemoteGlobalFrameHandle] RETURNS [BOOL] = { fcb1, fcb2: PrincOps.FrameCodeBase; fcb1 _ GetRemoteGFHeader[f1].code; fcb2 _ GetRemoteGFHeader[f2].code; fcb1.out _ fcb2.out _ FALSE; RETURN[fcb1 = fcb2]}; EnumerateRemoteGlobalFrames: PUBLIC PROC[world: World, proc: PROC[RemoteGlobalFrameHandle] RETURNS[BOOLEAN]] RETURNS[RemoteGlobalFrameHandle] = { gftLength: CARDINAL; { ENABLE UNWIND => Unlock[world]; Lock[world]; gftLength _ Read[world: world, addr: Long[world: world, addr: LOOPHOLE[SDDefs.SD + SDDefs.sGFTLength, ShortAddress]]]; FOR i: CARDINAL IN [1..gftLength) DO item: PrincOpsRuntime.GFTItem; frame: PrincOps.GlobalFrameHandle; CopyRead[world: world, from: Long[world: world, addr: LOOPHOLE[PrincOpsRuntime.GFT + i * SIZE[PrincOpsRuntime.GFTItem], ShortAddress]], nwords: SIZE[PrincOpsRuntime.GFTItem], to: @item]; frame _ PrincOpsRuntime.GetFrame[item]; IF frame # PrincOps.NullGlobalFrame AND item.epbias = 0 THEN {IF proc[[world: world, worldIncarnation: CurrentIncarnation[world], gfh: LOOPHOLE[frame, ShortAddress]]] THEN {Unlock[world]; RETURN[[world: world, worldIncarnation: CurrentIncarnation[world], gfh: LOOPHOLE[frame, ShortAddress]]]}}; ENDLOOP; Unlock[world]; RETURN[nilRemoteGlobalFrameHandle]}}; -- MOVE NOTE PROBLEM! AcquireSTBFromRemoteGFH: PUBLIC PROC[gfh: RemoteGlobalFrameHandle] RETURNS[SymbolTableBase] = { mappedBCD: BcdOps.BcdBase; module: PilotLoadStateFormat.ModuleInfo; -- a loadstate.gft entry std: RTTypesBasicPrivate.STDesc; sth: SymbolTableHandle; mth: BcdOps.MTHandle; ftb: Table.Base; sti: RTTypesBasicPrivate.SymbolTableIndex; FindModule: PROC [mth: BcdOps.MTHandle, mti: BcdDefs.MTIndex] RETURNS [BOOLEAN] = {RETURN[module.gfi IN [mth.gfi .. mth.gfi + mth.ngfi)]}; [mappedBCD, module] _ AcquireRemoteBCDAndModule[gfh]; -- here with the copied remote BCD. Now poke around in the remote bcd to find -- the version stamp, then get the symboltable ftb _ LOOPHOLE[LOOPHOLE[mappedBCD, LONG POINTER] + mappedBCD.ftOffset, Table.Base]; [mth, ] _ BcdOps.ProcessModules[LOOPHOLE[mappedBCD], FindModule ! UNWIND => ReleaseRemoteBCD[mappedBCD]]; IF mth = NIL THEN ERROR; std _ [symbolsStamp: IF mth.file = BcdDefs.FTSelf THEN mappedBCD.version ELSE ftb[mth.file].version]; ReleaseRemoteBCD[mappedBCD]; sti _ RTTypesBasicPrivate.FindSTI[std]; sth _ RTSymbolsPrivate.AcquireSTHFromSTX[sti].sth; IF sth = nullHandle THEN {moduleName: Rope.ROPE = RemoteGFHToName[gfh: gfh, moduleNameOnly: TRUE]; sth _ RTSymbolsPrivate.GetSTHForModule[stamp: std.symbolsStamp, moduleName: moduleName, fileName: Rope.Concat[moduleName, ".bcd"]]; IF sth # nullHandle THEN RTTypesBasicPrivate.MapStiStd[sti].sth _ sth; }; IF sth = nullHandle THEN ERROR AMTypes.Error[reason: noSymbols, msg: RemoteGFHToName[gfh]] ELSE RETURN[AcquireSTB[sth]]; }; -- raises Error AcquireRemoteBCDAndModule: PUBLIC PROC[gfh: RemoteGlobalFrameHandle] RETURNS[BcdOps.BcdBase, PilotLoadStateFormat.ModuleInfo] = { bcd: BcdOps.BcdBase; -- remote bcd module: PilotLoadStateFormat.ModuleInfo; -- a loadstate.gft entry world: World = gfh.world; mappedBCD: BcdOps.BcdBase; FindOriginal: PROCEDURE [f: RemoteGlobalFrameHandle] RETURNS [BOOLEAN] = {RETURN[(f.gfh # gfh.gfh) AND (SameCode[gfh, f]) AND (~GetRemoteGFHeader[f].copied)]}; IF gfh.gfh = 0 THEN ERROR AMTypes.Error[reason: noSymbols]; { ENABLE UNWIND => Unlock[world]; loadStateHeld: BOOLEAN _ FALSE; oldState: PilotLoadStateFormat.LoadState; newState: REF PilotLoadStateFormat.LoadStateObject; Lock[world]; { ENABLE ANY => IF loadStateHeld THEN {PilotLoadStateOps.ReleaseLoadState[]; loadStateHeld _ FALSE}; IF GetRemoteGFHeader[gfh].copied THEN gfh _ EnumerateRemoteGlobalFrames[world, FindOriginal]; newState _ Loadstate[gfh.world]; loadStateHeld _ TRUE; [] _ PilotLoadStateOps.InputLoadState[]; oldState _ PilotLoadStatePrivate.InstallLoadState[LOOPHOLE[newState]]; -- no error raised -- now find the bcd and module of interest module _ PilotLoadStateOps.GetModule[GetRemoteGFHeader[gfh].gfi]; IF NOT loadStateHeld THEN {loadStateHeld _ TRUE; [] _ PilotLoadStateOps.InputLoadState[]; [] _ PilotLoadStatePrivate.InstallLoadState[LOOPHOLE[newState]];-- no error raised--}; bcd _ PilotLoadStateOps.AcquireBcd -- NOTE assume that it doesn't need to be released [config: module.config]; IF NOT loadStateHeld THEN {loadStateHeld _ TRUE; [] _ PilotLoadStateOps.InputLoadState[]; [] _ PilotLoadStatePrivate.InstallLoadState[LOOPHOLE[newState]];-- no error raised--}; [] _ PilotLoadStatePrivate.InstallLoadState[oldState]; PilotLoadStateOps.ReleaseLoadState[]; loadStateHeld _ FALSE}; -- end ENABLE ANY mappedBCD _ AcquireRemoteBCD[world: gfh.world, bcd: bcd]; Unlock[world]; }; -- end ENABLE UNWIND RETURN[mappedBCD, module]; }; -- end AcquireRemoteBCDAndModule ReleaseRemoteBCD: PUBLIC ENTRY PROC[bcd: BcdOps.BcdBase] = {ENABLE UNWIND => NULL; FOR l: RemoteBCDCache _ remoteBCDCache, l.rest UNTIL l = NIL DO IF l.first.localBCD = bcd THEN {l.first.useCount _ l.first.useCount - 1; IF remoteBCDCacheLength > maxRemoteBCDCacheLength THEN {prev: RemoteBCDCache _ NIL; FOR s: RemoteBCDCache _ remoteBCDCache, s.rest UNTIL s = NIL DO IF s.first.useCount = 0 THEN {nBCD: BcdOps.BcdBase _ s.first.localBCD; UnsafeStorage.GetSystemUZone[].FREE[@nBCD]; IF prev = NIL THEN remoteBCDCache _ s.rest ELSE prev.rest _ s.rest; EXIT}; prev _ s; ENDLOOP}; RETURN}; ENDLOOP; ERROR; }; FindCachedRemoteBCD: ENTRY PROC[world: World, remoteBCD: Address] RETURNS[localBCD: BcdOps.BcdBase _ NIL] = {ENABLE UNWIND => NULL; prev: RemoteBCDCache _ NIL; FOR l: RemoteBCDCache _ remoteBCDCache, l.rest UNTIL l = NIL DO IF l.first.world = world AND l.first.remoteBCD = remoteBCD THEN {l.first.useCount _ l.first.useCount + 1; IF prev = NIL THEN remoteBCDCache _ l.rest ELSE prev.rest _ l.rest; -- unhook it l.rest _ remoteBCDCache; -- stick it at the beginning (most recent) remoteBCDCache _ l; RETURN[l.first.localBCD]; }; prev _ l; ENDLOOP; }; EnterRemoteBCDInCache: ENTRY PROC[world: World, remoteBCD: Address, localBCD: BcdOps.BcdBase] = {ENABLE UNWIND => NULL; FOR l: RemoteBCDCache _ remoteBCDCache, l.rest UNTIL l = NIL DO IF l.rest = NIL THEN {l.rest _ CONS[[world: world, remoteBCD: remoteBCD, localBCD: localBCD, useCount: 1], NIL]; RETURN; }; ENDLOOP; remoteBCDCache _ CONS[[world: world, remoteBCD: remoteBCD, localBCD: localBCD, useCount: 1], NIL]; }; -- assumes world is locked AcquireRemoteBCD: PUBLIC PROC[world: World, bcd: BcdOps.BcdBase--remote--] RETURNS[mappedBCD: BcdOps.BcdBase _ NIL--local--] = { pages: NAT; mappedBCD _ FindCachedRemoteBCD[world, LOOPHOLE[bcd, Address]]; IF mappedBCD # NIL THEN RETURN[mappedBCD]; mappedBCD _ UnsafeStorage.NewUObject [size: Environment.wordsPerPage, zone: UnsafeStorage.GetSystemUZone[]]; CopyRead[world: world, from: LOOPHOLE[bcd, Address], nwords: SIZE[BcdDefs.BCD], to: LOOPHOLE[mappedBCD, LONG POINTER] ! UNWIND => UnsafeStorage.GetSystemUZone[].FREE[@mappedBCD]]; IF mappedBCD.extended THEN pages _ mappedBCD.nPages - mappedBCD.rtPages.pages ELSE pages _ mappedBCD.nPages; UnsafeStorage.GetSystemUZone[].FREE[@mappedBCD]; mappedBCD _ UnsafeStorage.NewUObject[size: pages*Environment.wordsPerPage, zone: UnsafeStorage.GetSystemUZone[]]; CopyRead[world: world, from: LOOPHOLE[bcd, Address], nwords: pages*Environment.wordsPerPage, to: LOOPHOLE[mappedBCD, LONG POINTER] ! UNWIND => UnsafeStorage.GetSystemUZone[].FREE[@mappedBCD]]; EnterRemoteBCDInCache[world: world, remoteBCD: LOOPHOLE[bcd, Address], localBCD: mappedBCD]; }; RemoteGFHToName: PUBLIC PROC[gfh: RemoteGlobalFrameHandle, moduleNameOnly: BOOL _ FALSE] RETURNS[ans: Rope.ROPE _ NIL] = { s: STRING _ [80]; bcd: BcdOps.BcdBase; module: PilotLoadStateFormat.ModuleInfo; ssb: BcdOps.NameString; AppendBracketed: PROC [s: STRING, value: CARDINAL] = INLINE {IF moduleNameOnly THEN RETURN; LongString.AppendChar[s, '[]; LongString.AppendOctal[s, value]; LongString.AppendChar[s, ']]}; FindModuleString: PROC[mth: BcdOps.MTHandle, mti: BcdDefs.MTIndex] RETURNS [stop: BOOLEAN] = { ssd: LongString.SubStringDescriptor; IF module.gfi IN [mth.gfi..mth.gfi + mth.ngfi) THEN {ssd _ [base: @ssb.string, offset: mth.name, length: ssb.size[mth.name]]; s.length _ 0; LongString.AppendSubString[s, @ssd]; IF GetRemoteGFHeader[gfh].copied THEN AppendBracketed[s, GetRemoteGFHeader[gfh].gfi]; RETURN[TRUE]} ELSE RETURN[FALSE]}; [bcd, module] _ AcquireRemoteBCDAndModule[gfh]; ssb _ LOOPHOLE[bcd + bcd.ssOffset, BcdOps.NameString]; [] _ BcdOps.ProcessModules[bcd, FindModuleString ! ANY => {s.length _ 0; AppendBracketed[s, GetRemoteGFHeader[gfh].gfi]; CONTINUE}]; ReleaseRemoteBCD[bcd]; RETURN[ConvertUnsafe.ToRope[LONG[s]]] }; RemoteTypeToLocal: PUBLIC PROC[world: World, remoteType: CARDINAL] RETURNS[type: Type] = {stb: SymbolTableBase; td: RTTypesBasicPrivate.TypeDesc; -- copied from the remote world. NO REFS. sth: SymbolTableHandle; seIndex: SymbolIndex; -- seIndex must be consistent with sth: -- either symbols from the UTF or from the Typs's symbol access info CopyRead[world: world, from: LongRead[world: world, addr: LOOPHOLE[WorldRoot[world].GCStateBasic.mapTiTd + SIZE[RTTypesBasicPrivate.RMapTiTd[0]] + LOOPHOLE[remoteType, CARDINAL] *SIZE[RTTypesBasicPrivate.PTypeDesc], Address]], nwords: SIZE[RTTypesBasicPrivate.TypeDesc], to: @td]; -- first try for the original defining module seIndex _ td.utf.seIndex; -- utf: (umid: original defining module, seIndex: sei therein) sth _ RTSymbolsPrivate.AcquireSTHFromSTX [RTTypesBasicPrivate.FindSTI[[symbolsStamp: td.utf.umid]]].sth; IF sth = nullHandle -- not easy. Try harder using symbol access info for the remote type. THEN {remoteBCD: BcdOps.BcdBase; remoteSGI: BcdDefs.SGIndex; remoteSymbolsStamp: BcdDefs.VersionStamp; [remoteBCD, remoteSGI, remoteSymbolsStamp] _ WorldMapStiStdEntry[world: world, remoteSTI: td.symbolAccess.sti]; IF remoteBCD # NIL THEN {moduleName: Rope.ROPE _ NIL; mappedBCD: BcdOps.BcdBase _ AcquireRemoteBCD[world: world, bcd: remoteBCD]; { ENABLE UNWIND => ReleaseRemoteBCD[mappedBCD]; ssb: BcdOps.NameString = LOOPHOLE[mappedBCD + mappedBCD.ssOffset, BcdOps.NameString]; IF remoteSGI = BcdDefs.SGNull THEN -- go again for the defining module, this time with its name -- (search the BCD's file table) { findSymbolFTI: PROC[ffth: BcdOps.FTHandle, ffti: BcdDefs.FTIndex] RETURNS[stop: BOOLEAN] = { IF ffth.version # remoteSymbolsStamp THEN RETURN[FALSE]; moduleName _ GetModuleName[ssb, ffth.name]; RETURN[TRUE]}; remoteSymbolsStamp _ td.utf.umid; [] _ BcdOps.ProcessFiles[mappedBCD, findSymbolFTI]; IF moduleName = NIL THEN ERROR; } ELSE -- go for the module specified by the SGI {sgb: Table.Base = LOOPHOLE[mappedBCD + mappedBCD.sgOffset, Table.Base]; ftb: Table.Base = LOOPHOLE[mappedBCD + mappedBCD.ftOffset, Table.Base]; fti: BcdDefs.FTIndex _ sgb[remoteSGI].file; seIndex _ td.symbolAccess.sei; IF fti = BcdDefs.FTSelf THEN moduleName _ GetModuleName[ssb, mappedBCD.source] -- NOTE module name vs file name ELSE moduleName _ GetModuleName[ssb, ftb[fti].name]}; }; -- end ENABLE UNWIND ReleaseRemoteBCD[mappedBCD]; sth _ RTSymbolsPrivate.GetSTHForModule [stamp: remoteSymbolsStamp, moduleName: moduleName, fileName: Rope.Concat[moduleName, ".bcd"]]; }; -- end remoteBCD # NIL }; -- end sth = nullHandle IF sth = nullHandle THEN ERROR AMTypes.Error[reason: noSymbols]; stb _ AcquireSTB[sth]; type _ AcquireType[stb: stb, seIndex: seIndex ! UNWIND => ReleaseSTB[stb]]; ReleaseSTB[stb]; }; -- end RemoteTypeToLocal GetModuleName: PROC[ssb: BcdOps.NameString, n: BcdDefs.NameRecord] RETURNS[Rope.ROPE] = {nameString: STRING = [100]; ssd: Strings.SubStringDescriptor _ [base: @ssb.string, offset: n, length: MIN[ssb.size[n], 100]]; nameString.length _ 0; Strings.AppendSubString[nameString, @ssd]; FOR i: CARDINAL IN [0..nameString.length) DO IF nameString[i] = '. THEN {nameString.length _ i; EXIT}; ENDLOOP; RETURN[ConvertUnsafe.ToRope[LONG[nameString]]]}; -- raises RemoteError ValidateRemoteFrame: PUBLIC PROC[remoteFH: RemoteFrameHandle] = {frame: rep PrincOps.ControlLink = LOOPHOLE[remoteFH.fh, rep PrincOps.ControlLink]; IF frame.proc OR frame.indirect OR ~ValidRemoteGlobalFrame[[world: remoteFH.world, worldIncarnation: CurrentIncarnation[remoteFH.world], gfh: LOOPHOLE[GetRemoteFrameHeader[remoteFH].accesslink, WorldVM.ShortAddress]]] THEN ERROR RemoteError[invalidFrame]}; ValidRemoteGlobalFrame: PROC[gfh: RemoteGlobalFrameHandle] RETURNS[ans: BOOLEAN _ FALSE] = {h: rep PrincOps.ControlLink = LOOPHOLE[gfh.gfh, rep PrincOps.ControlLink]; ans _ NOT h.proc AND NOT h.indirect AND InRemoteGFT[gfh ! ANY => CONTINUE]}; InRemoteGFT: PROC[gfh: RemoteGlobalFrameHandle] RETURNS[BOOLEAN] = {gftLength: CARDINAL; world: World = gfh.world; { ENABLE UNWIND => Unlock[world]; Lock[world]; gftLength _ Read[world: world, addr: Long[world: world, addr: LOOPHOLE[SDDefs.SD + SDDefs.sGFTLength, ShortAddress]]]; FOR k: CARDINAL IN [1..gftLength) DO IF GetRemoteGFHandle[world: world, gfi: k] = gfh AND GetRemoteGFHeader[gfh].gfi = k THEN {Unlock[world]; RETURN[TRUE]}; ENDLOOP; Unlock[world]; RETURN[FALSE]; }}; -- NOTE copies the AGCState (but not MapPiRce and MapOiOe) WorldRoot: PROC[world: World] RETURNS[ans: REF RTRefCounts.AGCState] = {ans _ z.NEW[RTRefCounts.AGCState]; CopyRead[world: world, from: LOOPHOLE[LongRead[world: world, addr: Long[world: world, addr: LOOPHOLE[SDDefs.SD + RTSD.sRTState, ShortAddress]]], Address], nwords: SIZE[RTRefCounts.AGCState], to: LOOPHOLE[ans, LONG POINTER] ]; }; WorldMapStiStdEntry: PROC[world: World, remoteSTI: RTTypesBasicPrivate.SymbolTableIndex] RETURNS[BcdOps.BcdBase, BcdDefs.SGIndex, BcdDefs.VersionStamp] = {ans: RTTypesBasicPrivate.STDesc; CopyRead[ world: world, from: LOOPHOLE [LongRead [world: world, addr: LOOPHOLE[LongRead[world: world, addr: Long[world: world, addr: LOOPHOLE [SDDefs.SD + RTSD.sMapStiStd, ShortAddress]]], Address] -- MapStiStd + SIZE[RTTypesBasicPrivate.RMapStiStd[0]] + SIZE[RTTypesBasicPrivate.PSTDesc] * remoteSTI], Address], nwords: SIZE[RTTypesBasicPrivate.STDesc], to: @ans ]; RETURN[ans.bcd, ans.sgi, ans.symbolsStamp] }; GetRemotePc: PUBLIC PROC[gf: RemoteGlobalFrameHandle, i: EVRange] RETURNS [PrincOps.BytePC] = {codeBase: RemotePointer -- LONG POINTER TO PrincOps.CSegPrefix = GetRemoteEntryTableBase[gf]; wpc: CARDINAL _ Read[world: gf.world, addr: LOOPHOLE[codeBase.ptr, Address] + SIZE[PrincOps.CSegPrefix] + i*SIZE[PrincOps.EntryVectorItem]]; RETURN[LOOPHOLE[wpc*2, PrincOps.BytePC]]}; GetRemoteEntryTableBase: PROC [gfh: RemoteGlobalFrameHandle] RETURNS [RemotePointer] = {c: PrincOps.FrameCodeBase _ GetRemoteGFHeader[gfh].code; c.out _ FALSE; RETURN[[world: gfh.world, worldIncarnation: CurrentIncarnation[gfh.world], ptr: LOOPHOLE[c, Address]]]; }; -- raises typeFault UnwindRemoteIndirectProcDesc: PUBLIC PROC[pd: RemotePD] RETURNS[RemotePD] = {icl: PrincOps.ControlLink _ LOOPHOLE[pd.pd, PrincOps.ControlLink]; world: World = pd.world; IF icl = PrincOps.NullLink OR icl = PrincOps.UnboundLink THEN RETURN[nilRemotePD]; { ENABLE UNWIND => Unlock[world]; Lock[world]; UNTIL icl.proc DO IF icl.indirect THEN icl _ LOOPHOLE[Read[world: world, addr: Long[world: world, addr: LOOPHOLE[icl.link, ShortAddress]]], PrincOps.ControlLink] ELSE ERROR Error[reason: typeFault, type: nullType] ENDLOOP; Unlock[world]; RETURN[[world: world, worldIncarnation: CurrentIncarnation[world], pd: icl]]}}; -- break up and MOVE AcquireCBTHandleFromRemotePD: PUBLIC PROC[pd: RemotePD] RETURNS[stb: SymbolTableBase, cbti: CallableBodyIndex] = { item: PrincOpsRuntime.GFTItem; world: World = pd.world; { ENABLE UNWIND => Unlock[world]; Lock[world]; pd _ UnwindRemoteIndirectProcDesc[pd]; CopyRead[world: world, from: Long[world: world, addr: LOOPHOLE[PrincOpsRuntime.GFT + (LOOPHOLE[pd.pd, PrincOps.ProcDesc].gfi * SIZE[PrincOpsRuntime.GFTItem]), ShortAddress]], nwords: SIZE[PrincOpsRuntime.GFTItem], to: @item ]; stb _ AcquireSTBFromRemoteGFH [GetRemoteGFHandle[world: world, gfi: LOOPHOLE[pd.pd, PrincOps.ProcDesc].gfi]]; cbti _ RTTypesPrivate.GetCBTI [stb, item.epbias * PrincOps.EPRange + LOOPHOLE[pd.pd, PrincOps.ProcDesc].ep]; Unlock[world]}}; GetRemoteGFHandle: PUBLIC PROC[world: World, gfi: PrincOps.GFTIndex] RETURNS[RemoteGlobalFrameHandle] = {item: PrincOpsRuntime.GFTItem; { ENABLE UNWIND => Unlock[world]; Lock[world]; CopyRead[world: world, from: Long[world: world, addr: LOOPHOLE[PrincOpsRuntime.GFT + gfi * SIZE[PrincOpsRuntime.GFTItem], ShortAddress]], nwords: SIZE[PrincOpsRuntime.GFTItem], to: @item ]; Unlock[world]; RETURN[[world: world, worldIncarnation: CurrentIncarnation[world], gfh: LOOPHOLE[PrincOpsRuntime.GetFrame[item], ShortAddress]]]}; }; GetRemoteGFHeader: PUBLIC PROC[gfh: RemoteGlobalFrameHandle] RETURNS[ans: REF PrincOps.GlobalFrame] = {world: World = gfh.world; ans _ z.NEW[PrincOps.GlobalFrame]; { ENABLE UNWIND => Unlock[world]; Lock[world]; CopyRead[world: world, from: Long[world: world, addr: LOOPHOLE[gfh.gfh, ShortAddress]], nwords: SIZE[PrincOps.GlobalFrame], to: LOOPHOLE[ans, LONG POINTER]]; Unlock[world]; }}; GetRemoteFrameHeader: PUBLIC PROC[fh: RemoteFrameHandle] RETURNS[ans: REF PrincOps.Frame] = {world: World = fh.world; ans _ z.NEW[PrincOps.Frame]; { ENABLE UNWIND => Unlock[world]; Lock[world]; CopyRead[world: world, from: Long[world: world, addr: LOOPHOLE[fh.fh, ShortAddress]], nwords: SIZE[PrincOps.Frame], to: LOOPHOLE[ans, LONG POINTER]]; Unlock[world]; }}; GetRemoteReferentType: PUBLIC PROC[remoteRef: RemoteRef] RETURNS[type: Type--valid locally--] = { mz: RTZones.ZoneFinger; world: World = remoteRef.world; IF remoteRef.ref = 0 THEN RETURN[nullType]; { ENABLE UNWIND => Unlock[world]; Lock[world]; mz _ RemoteMapRefZf[remoteRef]; WITH mz: mz SELECT FROM prefixed => type _ GetRemotePrefixedType[remoteRef]; sub => type _ GetRemoteSzType[world: world, szi: mz.szi]; ENDCASE => ERROR; Unlock[world]}}; RemoteMapRefZf: PROC[remoteRef: RemoteRef] RETURNS[zf: RTZones.ZoneFinger] = {qi: RTQuanta.QuantumIndex = RTZones.MapPtrQ[LOOPHOLE[remoteRef.ref, LONG POINTER]]; remoteMapQZf: RTZones.TMapQZf = WorldRoot[remoteRef.world].GCStateBasic.mapQZf; CopyRead[world: remoteRef.world, from: LOOPHOLE[remoteMapQZf + SIZE[RTZones.RMapQZf[0]] + qi*SIZE[RTZones.ZoneFinger], Address], nwords: SIZE[RTZones.ZoneFinger], to: @zf]; }; GetRemotePrefixedType: PROC[remoteRef: RemoteRef] RETURNS[Type--valid locally--] = {remoteType: CARDINAL; NHdr: inuse RTZones.NodeHeader; CopyRead[world: remoteRef.world, from: remoteRef.ref - RTZones.sizeNd, nwords: SIZE[inuse RTZones.NodeHeader], to: @NHdr]; remoteType _ NHdr.type; RETURN[RemoteTypeToLocal[world: remoteRef.world, remoteType: remoteType]]; }; GetRemoteSzType: PROC[world: World, szi: RTZones.SubZoneIndex] RETURNS[Type--valid locally--] = {remoteType: CARDINAL; szrp: Address; -- SubZone szRec: RTZones.SubZoneRec; szrp _ LongRead [world: world, addr: LOOPHOLE[WorldRoot[world].GCStateBasic.mapSziSz + SIZE[RTZones.RMapSziSz[0]] + szi*SIZE[RTZones.SubZone], Address]]; CopyRead[world: world, from: szrp, nwords: SIZE[RTZones.SubZoneRec], to: @szRec]; remoteType _ szRec.type; RETURN[RemoteTypeToLocal[world: world, remoteType: remoteType]]; }; -- MOVE GetRemoteProcedureType: PUBLIC PROC[remotePD: RemotePD] RETURNS[type: Type--valid locally--] = { stb: SymbolTableBase; cbti: CallableBodyIndex; [stb, cbti] _ AcquireCBTHandleFromRemotePD[remotePD]; type _ AcquireType [stb, WITH stb SELECT FROM t: SymbolTableBase.x => [x[t.e.bb[NARROW[cbti, CallableBodyIndex.x].e].ioType]], t: SymbolTableBase.y => [y[t.e.bb[NARROW[cbti, CallableBodyIndex.y].e].ioType]], ENDCASE => ERROR, ! UNWIND => ReleaseSTB[stb]]; ReleaseSTB[stb]}; -- break up and MOVE GetRemoteSignalType: PUBLIC PROC[remoteSED: RemoteSED] RETURNS[type: Type--valid locally--] = { gfh: RemoteGlobalFrameHandle _ nilRemoteGlobalFrameHandle; item: PrincOpsRuntime.GFTItem; stb: SymbolTableBase; world: World = remoteSED.world; proc: PROC[stb: SymbolTableBase, isei: SymbolIdIndex] RETURNS[stop: BOOLEAN] = {WITH stb SELECT FROM t: SymbolTableBase.x => RETURN[procX[t.e, NARROW[isei, SymbolIdIndex.x].e]]; t: SymbolTableBase.y => RETURN[procY[t.e, NARROW[isei, SymbolIdIndex.y].e]]; ENDCASE => ERROR}; procX: PROC[stb: bx.SymbolTableBase, isei: bx.SymbolIdIndex] RETURNS[stop: BOOLEAN] = { tsei: bx.SymbolIndex; IF stb.seb[isei].constant AND stb.seb[tsei _ stb.UnderType[stb.seb[isei].idType]].typeTag = transfer AND (SELECT stb.XferMode[tsei] FROM error, signal => TRUE, ENDCASE => FALSE) AND CARDINAL[item.epbias * PrincOps.EPRange + LOOPHOLE[remoteSED.sed, PrincOps.SignalDesc].ep] = STInfoToEPN[LOOPHOLE[stb.seb[isei].idValue, PrincOps.SignalDesc]] THEN {type _ AcquireType[[x[stb]], [x[stb.seb[isei].idType]]]; RETURN[TRUE]} ELSE RETURN[FALSE]}; procY: PROC[stb: by.SymbolTableBase, isei: by.SymbolIdIndex] RETURNS[stop: BOOLEAN] = { tsei: by.SymbolIndex; IF stb.seb[isei].constant AND stb.seb[tsei _ stb.UnderType[stb.seb[isei].idType]].typeTag = transfer AND (SELECT stb.XferMode[tsei] FROM error, signal => TRUE, ENDCASE => FALSE) AND CARDINAL[item.epbias * PrincOps.EPRange + LOOPHOLE[remoteSED.sed, PrincOps.SignalDesc].ep] = STInfoToEPN[LOOPHOLE[stb.seb[isei].idValue, PrincOps.SignalDesc]] THEN {type _ AcquireType[[y[stb]], [y[stb.seb[isei].idType]]]; RETURN[TRUE]} ELSE RETURN[FALSE]}; -- START GetRemoteSignalType HERE IF LOOPHOLE[remoteSED.sed, CARDINAL] = 177777B -- ERROR OR LOOPHOLE[remoteSED.sed, CARDINAL] = LOOPHOLE[UNWIND, CARDINAL] OR LOOPHOLE[remoteSED.sed, CARDINAL] = LOOPHOLE[ABORTED, CARDINAL] THEN RETURN[CODE[ERROR]]; { ENABLE UNWIND => Unlock[world]; Lock[world]; gfh _ GetRemoteGFHandle[world: world, gfi: LOOPHOLE[remoteSED.sed, PrincOps.SignalDesc].gfi]; stb _ AcquireSTBFromRemoteGFH[gfh]; CopyRead[world: world, from: Long[world: world, addr: LOOPHOLE[PrincOpsRuntime.GFT + LOOPHOLE[remoteSED.sed, PrincOps.SignalDesc].gfi * SIZE[PrincOpsRuntime.GFTItem], ShortAddress]], nwords: SIZE[PrincOpsRuntime.GFTItem], to: @item ]; type _ nullType; [] _ EnumerateRecordIseis [stb, WITH stb SELECT FROM t: SymbolTableBase.x => [x[t.e.bb[bx.rootBodyIndex].type]], t: SymbolTableBase.y => [y[t.e.bb[by.rootBodyIndex].type]], ENDCASE => ERROR, proc ! UNWIND => ReleaseSTB[stb]]; ReleaseSTB[stb]; Unlock[world]}}; -- break up and MOVE IsRemoteCatchFrame: PUBLIC PROC[remoteFrameHandle: RemoteFrameHandle, bti: BodyIndex] RETURNS [isCatchFrame: BOOLEAN _ TRUE, revBti: BodyIndex] = {world: World = remoteFrameHandle.world; { ENABLE UNWIND => Unlock[world]; Lock[world]; revBti _ bti; ValidateRemoteFrame[remoteFrameHandle ! ANY => GOTO notCatch]; { -- return FALSE if input invalid nextFrame: RemoteFrameHandle _ [world: remoteFrameHandle.world, worldIncarnation: CurrentIncarnation[remoteFrameHandle.world], fh: LOOPHOLE[AMProcessBasic.ReturnLink [world, LOOPHOLE[remoteFrameHandle.fh, PrincOps.FrameHandle]], ShortAddress]]; nextFHdr: REF PrincOps.Frame; ValidateRemoteFrame[nextFrame ! ANY => GOTO notCatch]; -- return FALSE if no valid calling frame nextFHdr _ GetRemoteFrameHeader[nextFrame]; IF nextFHdr.accesslink # RemoteSigGF[remoteFrameHandle.world] THEN GOTO notCatch; { -- return FALSE if caller not signaller sl: CARDINAL = LOOPHOLE[GetRemoteFrameHeader[remoteFrameHandle].staticlink]; L0Frame: RemoteFrameHandle _ [world: remoteFrameHandle.world, worldIncarnation: CurrentIncarnation[remoteFrameHandle.world], fh: 0]; IF sl = 0 THEN GOTO notCatch; L0Frame _ [world: remoteFrameHandle.world, worldIncarnation: CurrentIncarnation[remoteFrameHandle.world], fh: LOOPHOLE[sl - PrincOps.localbase, ShortAddress]]; -- L0Frame is the frame that encloses the catch frame ValidateRemoteFrame[L0Frame ! ANY => GOTO notCatch]; -- return FALSE if static frame not valid (??) IF GetRemoteFrameHeader[remoteFrameHandle].accesslink # GetRemoteFrameHeader[L0Frame].accesslink THEN GOTO notCatch; IF ~nextFHdr.mark THEN GOTO notCatch; -- calling frame not the signaller { -- detect situation where catch frame has no locals, thus no body table. tr: REF TypedVariableRec = NARROW[TVForRemoteFrame[L0Frame], REF TypedVariableRec]; WITH hd: tr.head SELECT FROM remoteFH => IF bti = hd.bti THEN revBti _ nullBodyIndex; ENDCASE => ERROR }; Unlock[world]; } }; EXITS notCatch => {Unlock[world]; isCatchFrame _ FALSE}}}; RemoteSigGF: PROC[world: World] RETURNS[PrincOps.GlobalFrameHandle] = { item: PrincOpsRuntime.GFTItem; pd: PrincOps.ProcDesc = LOOPHOLE[Read[world: world, addr: Long[world: world, addr: LOOPHOLE[SDDefs.SD + SDDefs.sSignal, ShortAddress]]], PrincOps.ProcDesc]; CopyRead[world: world, from: Long[world: world, addr: LOOPHOLE[PrincOpsRuntime.GFT + pd.gfi * SIZE[PrincOpsRuntime.GFTItem], ShortAddress]], nwords: SIZE[PrincOpsRuntime.GFTItem], to: @item ]; RETURN[PrincOpsRuntime.GetFrame[item]]}; -- MOVE AcquireBTIFromRemoteFH: PUBLIC PROC[remoteFrameHandle: RemoteFrameHandle, contextPC: BOOL] RETURNS[bti: BodyIndex] = {stb: SymbolTableBase; world: World = remoteFrameHandle.world; Lock[world]; [stb, bti] _ AcquireBTHandleFromRemoteFH[remoteFrameHandle, contextPC ! ANY => GOTO nope]; Unlock[world]; ReleaseSTB[stb]; EXITS nope => {Unlock[remoteFrameHandle.world]; RETURN[nullBodyIndex]}}; -- MOVE AcquireBTHandleFromRemoteFH: PROC[fh: RemoteFrameHandle, contextPC: BOOL] RETURNS[stb: SymbolTableBase, bti: BodyIndex] = { start: PrincOps.BytePC; epn: CARDINAL; remoteFrame: REF PrincOps.Frame = GetRemoteFrameHeader[fh]; framePC: PrincOps.BytePC = [(remoteFrame.pc - (IF contextPC THEN 0 ELSE 1))]; stb _ AcquireSTBFromRemoteGFH[[world: fh.world, worldIncarnation: CurrentIncarnation[fh.world], gfh: LOOPHOLE[remoteFrame.accesslink, ShortAddress]]]; [epn, start] _ GetRemoteEp[pc: framePC, gf: [world: fh.world, worldIncarnation: CurrentIncarnation[fh.world], gfh: LOOPHOLE[remoteFrame.accesslink, ShortAddress]], stb: stb ! UNWIND => ReleaseSTB[stb]]; bti _ RTTypesPrivate.ConvertCbti[base: stb, pc: framePC, start: start, lastBti: LOOPHOLE[RTTypesPrivate.GetCBTI[stb, epn]] ! UNWIND => ReleaseSTB[stb]]; IF bti = rootBodyIndex THEN bti _ nullBodyIndex}; -- MOVE GetRemoteEp: PUBLIC PROC [pc: PrincOps.BytePC, gf: RemoteGlobalFrameHandle, stb: SymbolTableBase] RETURNS [ep: EVRange, start: PrincOps.BytePC] = { FindMaxEI: PROC RETURNS [max: EVRange] = { GetMaxX: PROC [bti: bx.BodyIndex] RETURNS [stop: BOOLEAN] = {WITH stb SELECT FROM t: SymbolTableBase.x => WITH t.e.bb[bti] SELECT FROM Callable => IF ~inline THEN max _ MAX[max, entryIndex]; ENDCASE; ENDCASE => ERROR; RETURN[FALSE]}; GetMaxY: PROC [bti: by.BodyIndex] RETURNS [stop: BOOLEAN] = {WITH stb SELECT FROM t: SymbolTableBase.y => WITH t.e.bb[bti] SELECT FROM Callable => IF ~inline THEN max _ MAX[max, entryIndex]; ENDCASE; ENDCASE => ERROR; RETURN[FALSE]}; max _ 0; WITH stb SELECT FROM t: SymbolTableBase.x => [] _ t.e.EnumerateBodies[bx.rootBodyIndex, GetMaxX]; t: SymbolTableBase.y => [] _ t.e.EnumerateBodies[by.rootBodyIndex, GetMaxY]; ENDCASE => ERROR}; -- body of GetEp begins here diff: CARDINAL _ LAST[CARDINAL]; anyProcedure: BOOLEAN _ FALSE; FOR i: EVRange IN [0..FindMaxEI[]] DO last: PrincOps.BytePC _ GetRemotePc[gf, i]; IF Card[last] > Card[pc] THEN LOOP; IF Card[pc] - Card[last] > diff THEN LOOP; diff _ Card[pc] - Card[last]; ep _ i; start _ last; anyProcedure _ TRUE; ENDLOOP; IF ~anyProcedure THEN ERROR; -- SIGNAL NotInAnyProcedure; RETURN}; -- MOVE RemotePDToName: PUBLIC PROC[pd: RemotePD] RETURNS[ans: Rope.ROPE] = { stb: SymbolTableBase; cbti: CallableBodyIndex; pd _ UnwindRemoteIndirectProcDesc[pd]; IF pd.pd = 0 THEN RETURN[NIL]; [stb, cbti] _ AcquireCBTHandleFromRemotePD[pd]; ans _ AcquireRope[stb, WITH stb SELECT FROM t: SymbolTableBase.x => [x[t.e.seb[t.e.bb[NARROW[cbti, CallableBodyIndex.x].e].id].hash]], t: SymbolTableBase.y => [y[t.e.seb[t.e.bb[NARROW[cbti, CallableBodyIndex.y].e].id].hash]], ENDCASE => ERROR ! UNWIND => ReleaseSTB[stb]]; ReleaseSTB[stb]; RETURN[ans]}; RemoteSEDToName: PUBLIC PROC[sed: RemoteSED] RETURNS[ans: Rope.ROPE _ NIL] = { item: PrincOpsRuntime.GFTItem; gfh: RemoteGlobalFrameHandle _ nilRemoteGlobalFrameHandle; stb: SymbolTableBase; world: World = sed.world; proc: PROC[stb: SymbolTableBase, isei: SymbolIdIndex] RETURNS[stop: BOOLEAN] = {WITH stb SELECT FROM t: SymbolTableBase.x => RETURN[procX[t.e, NARROW[isei, SymbolIdIndex.x].e]]; t: SymbolTableBase.y => RETURN[procY[t.e, NARROW[isei, SymbolIdIndex.y].e]]; ENDCASE => ERROR}; procX: PROC[stb: bx.SymbolTableBase, isei: bx.SymbolIdIndex] RETURNS[stop: BOOLEAN] = { tsei: bx.SymbolIndex; IF stb.seb[isei].constant AND stb.seb[tsei _ stb.UnderType[stb.seb[isei].idType]].typeTag = transfer AND (SELECT stb.XferMode[tsei] FROM error, signal => TRUE, ENDCASE => FALSE) AND CARDINAL[item.epbias * PrincOps.EPRange + LOOPHOLE[sed.sed, PrincOps.SignalDesc].ep] = STInfoToEPN[LOOPHOLE[stb.seb[isei].idValue, PrincOps.SignalDesc]] THEN {ans _ AcquireRope[[x[stb]], [x[stb.seb[isei].hash]]]; RETURN[TRUE]} ELSE RETURN[FALSE]}; procY: PROC[stb: by.SymbolTableBase, isei: by.SymbolIdIndex] RETURNS[stop: BOOLEAN] = { tsei: by.SymbolIndex; IF stb.seb[isei].constant AND stb.seb[tsei _ stb.UnderType[stb.seb[isei].idType]].typeTag = transfer AND (SELECT stb.XferMode[tsei] FROM error, signal => TRUE, ENDCASE => FALSE) AND CARDINAL[item.epbias * PrincOps.EPRange + LOOPHOLE[sed.sed, PrincOps.SignalDesc].ep] = STInfoToEPN[LOOPHOLE[stb.seb[isei].idValue, PrincOps.SignalDesc]] THEN {ans _ AcquireRope[[y[stb]], [y[stb.seb[isei].hash]]]; RETURN[TRUE]} ELSE RETURN[FALSE]}; IF sed.sed = PrincOps.NullLink OR sed.sed = PrincOps.UnboundLink THEN RETURN[NIL]; IF LOOPHOLE[sed.sed, CARDINAL] = 177777B THEN RETURN["ERROR"]; IF LOOPHOLE[sed.sed, CARDINAL] = LOOPHOLE[UNWIND, CARDINAL] THEN RETURN["UNWIND"]; IF LOOPHOLE[sed.sed, CARDINAL] = LOOPHOLE[ABORTED, CARDINAL] THEN RETURN["ABORTED"]; { ENABLE UNWIND => Unlock[world]; sei: SymbolRecordIndex; Lock[world]; gfh _ GetRemoteGFHandle[world: world, gfi: LOOPHOLE[sed.sed, PrincOps.SignalDesc].gfi]; CopyRead[world: world, from: Long[world: world, addr: LOOPHOLE[PrincOpsRuntime.GFT + LOOPHOLE[sed.sed, PrincOps.SignalDesc].gfi * SIZE[PrincOpsRuntime.GFTItem], ShortAddress]], nwords: SIZE[PrincOpsRuntime.GFTItem], to: @item]; stb _ AcquireSTBFromRemoteGFH[gfh]; sei _ WITH stb SELECT FROM t: SymbolTableBase.x => [x[t.e.bb[bx.rootBodyIndex].type]], t: SymbolTableBase.y => [y[t.e.bb[by.rootBodyIndex].type]], ENDCASE => ERROR; IF NOT NullISEI[LOOPHOLE[sei]] THEN [] _ EnumerateRecordIseis[stb, sei, proc ! UNWIND => ReleaseSTB[stb]]; ReleaseSTB[stb]; Unlock[world]}}; RemoteStoreWords: PUBLIC PROC[from: LONG POINTER, to: RemotePointer, nWords: NAT] = {ENABLE UNWIND => Unlock[to.world]; Lock[to.world]; CopyWrite[world: to.world, from: from, nwords: nWords, to: to.ptr]; Unlock[to.world]}; RemoteStoreWord: PUBLIC PROC[to: RemotePointer, value: CARDINAL] = {ENABLE UNWIND => Unlock[to.world]; Lock[to.world]; Write[world: to.world, addr: to.ptr, value: value]; Unlock[to.world]}; RemoteStoreDoubleWord: PUBLIC PROC[to: RemotePointer, value: LONG CARDINAL] = {ENABLE UNWIND => Unlock[to.world]; Lock[to.world]; LongWrite[world: to.world, addr: to.ptr, value: value]; Unlock[to.world]}; RemoteStoreFieldLong: PUBLIC PROC[ptr: RemotePointer, field: RTCommon.Field, value: LONG CARDINAL] = {ENABLE UNWIND => Unlock[ptr.world]; val: LONG CARDINAL; Lock[ptr.world]; val _ LongRead[world: ptr.world, addr: LOOPHOLE[ptr.ptr, Address]]; RTCommon.StoreFieldLong[ptr: @val, field: field, newValue: value]; LongWrite[world: ptr.world, addr: LOOPHOLE[ptr.ptr, Address], value: val]; Unlock[ptr.world]; }; GetRemoteWord: PUBLIC PROC[remotePointer: RemotePointer] RETURNS[ans: WORD] = {ENABLE UNWIND => Unlock[remotePointer.world]; Lock[remotePointer.world]; ans _ Read[world: remotePointer.world, addr: remotePointer.ptr]; Unlock[remotePointer.world]; }; GetRemoteLC: PUBLIC PROC[remotePointer: RemotePointer] RETURNS[ans: LONG CARDINAL] = {ENABLE UNWIND => Unlock[remotePointer.world]; Lock[remotePointer.world]; ans _ LongRead[world: remotePointer.world, addr: remotePointer.ptr]; Unlock[remotePointer.world]; }; GetRemoteWords: PUBLIC PROC[remotePointer: RemotePointer, nWords: NAT] RETURNS[ans: WordSequence] = {ENABLE UNWIND => Unlock[remotePointer.world]; Lock[remotePointer.world]; ans _ z.NEW[WordSequenceRecord[nWords]]; CopyRead[world: remotePointer.world, from: remotePointer.ptr, nwords: nWords, to: LOOPHOLE[@ans[0], LONG POINTER]]; Unlock[remotePointer.world]; }; -- NOTE RemoteSignalValues: PUBLIC PROC[tv: TypedVariable--catch Frame--] RETURNS [message: CARDINAL, signal: PrincOps.SignalDesc, world: World] = {rtr: REF TypedVariableRec _ NARROW[tv]; world _ GetWorld[tv]; WITH th: rtr.head SELECT FROM fh => IF th.isCatchFrame THEN {signallerFrameHandle: PrincOps.FrameHandle; Runtime.ValidateFrame[th.fh]; signallerFrameHandle _ AMProcessBasic.ReturnLink[world, th.fh].frame; message _ LOOPHOLE[signallerFrameHandle + SignallerFrameMessageOffset, POINTER TO UNSPECIFIED]^; signal _ LOOPHOLE[signallerFrameHandle + SignallerFrameSignalOffset, POINTER TO PrincOps.SignalDesc]^; RETURN} ELSE ERROR Error[reason: typeFault, type: TVType[tv]]; remoteFH => IF th.isCatchFrame THEN {ENABLE UNWIND => Unlock[world]; remoteSignallerFrameHandle: RemoteFrameHandle _ nilRemoteFrameHandle; Lock[world]; ValidateRemoteFrame[th.remoteFrameHandle]; remoteSignallerFrameHandle _ [world: world, worldIncarnation: CurrentIncarnation[world], fh: LOOPHOLE[AMProcessBasic.ReturnLink [world, LOOPHOLE[th.remoteFrameHandle.fh, PrincOps.FrameHandle]], ShortAddress]]; message _ Read[world: world, addr: Long[world: world, addr: remoteSignallerFrameHandle.fh + SignallerFrameMessageOffset]]; signal _ LOOPHOLE [Read[world: world, addr: Long[world: world, addr: remoteSignallerFrameHandle.fh + SignallerFrameSignalOffset]], PrincOps.SignalDesc]; Unlock[world]; RETURN} ELSE ERROR Error[reason: typeFault, type: TVType[tv]]; ENDCASE => ERROR Error[reason: typeFault, type: TVType[tv]]}; STInfoToEPN: PROC[cl: PrincOps.SignalDesc] RETURNS[CARDINAL] = {RETURN[(cl.gfi - 1) * PrincOps.EPRange + cl.ep]}; Card: PROC[pc: PrincOps.BytePC] RETURNS[CARDINAL] = {RETURN[LOOPHOLE[pc, CARDINAL]]}; END. Κ– "Mesa" style˜IprocšΒΟcZœΟk œžœΈžœžœ,žœ žœJžœtžœŠžœ‡žœžœžœWžœTžœDžœ!žœ—žœžœžœžœžœžœ&žœ žœžœžœ)žœηžœJžœ/žœ>žœΥžœCžœ(žœŽžœžœžœ(žœžœ2žœžœ*žœΧžœ%œžœΡžœžœžœΔžœ# œžœžœžœžœžœΏžœ œ!žœžœžœ œžœ"žœœžœžœBžœžœžœžœžœžœœΟnœžœžœžœžœžœžœHŸœžœžœ#žœžœœžœžœŸœžœžœLžœ[žœžœ žœ.žœ žœžœ΄žœžœnžœžœžœžœΜžœžœAžœ€žœxžœ"žœžœžœwžœ&žœžœ¬žœ#žœžœ!Ÿœžœžœ%žœgœ€Ÿ œžœ.žœžœžœ žœiNœ /œ žœžœ žœžœJžœ8žœ&žœžœžœžœžœ;žœ3žœ’žœžœžœ-žœύžœ!žœCžœžœžœjžœžœŸœžœžœ%žœNœ4œKŸ œž œžœžœ žœ%žœ&žœ(žœ žœžœ,žœžœ&žœžœ>žœBžœžœžœ+žœ]žœ žœ%žœsžœežœœ +œPžœžœžœžœsžœ œ,3œ2žœžœžœžœsžœ œ}žœœ]œžœ!œŸœžœžœžœžœžœžœžœ,žœžœžœžœ#žœ?žœEžœžœ žœ,žœžœ!žœžœ;žœxžœ7žœžœ0žœHžœCžœQžœžœžœžœŸœžœžœ)žœžœžœžœžœžœžœ,žœžœžœžœžœ*žœ?žœžœžœžœ œ.+œ<žœCžœ Ÿœžœžœ¦žœžœžœžœ,žœžœžœžœ žœ žœ žœΫžœžœžœžœΦžœŸœžœžœ" œžœž œžœ.žœžœ žœžœžœλžœ)žœ žœžœ žœžœžœ#žœžœžœ:žœFžœοžœ`žœ žœžœžœ#žœežœPŸœžœžœYžœžœžœ žœžœ žœtŸœžœžœ žœžœžœžœžœƒŸœžœ7žœžœ9žœ žœ(žœΆžœ3žœDžœžœ žœžœžœCžœvžœ…žœ#žœžœŸœžœžœžœžœN+œ<vœnžœažœ\žœ žœDžœzžœ<-œ@œ‰žœFœžœšžœ žœžœž œΟžœžœmžœMžœœž•œ/žœ‘žœžœ,žœ#žœžœžœžœžœΊžœžœžœžœ:žœ*œVžœ…žœΩžœ7žœW!œ!žœJœιΟi œœžœžœžœpžœ0œŸ œžœ0žœžœžœVžœ]žœžœžœžœžœžœžœžœžœžœŸœžœžœFžœ-žœžœžœΐžœ†žœžœŸœžœ%žœžœžœ'žœ1žœžœžœ žœžœžœ Ÿ œžœžœžœžœ#žœžœ©žœžœhžœžœžœžœžœ7žœ'žœžœžœ žœžœžœ;Ÿ œžœžœžœ&žœNžœͺžœžœžœΌžœ/žœžœžœŸœžœFžœ‘žœxžœΕžœ_žœ[žœ³ œ'žœKžœkžœŸ œžœžœ0žœ3'œ4žœBžœEžœEžœ"žœžœŸœžœ&žœ_žœžœnžœŸœžœžœžœ,žœ?žœžœ žœžœžœžœ'žœ žœžœžœžœ“žœ[žœžœ.žœžœOŸœžœžœžœ}žœžœΔžœžœ;žœ]žœ}žœΡžœΘžœ8Ÿœžœžœ-žœBžœžœ‰žœžœ<žœtžœ\žœbžœ9Ÿœžœžœ%žœžœCžœžœžœžœ2žœ,žœžœžœ Ÿœžœžœžœžœ;žœžœžœ‹žœ0žœ&žœžœžœŸœžœžœžœ œFžœžœžœžœžœJžœžœžœ†žœžœŸœžœžœLžœžœžœ—žœ8žœBžœažœ@Ÿœžœžœœžœ£žœ_žœSŸœžœ0žœœžœ œmžœRžœEžœ›žœ[žœKŸœžœžœžœ œ½žœžœžœ7žœ_žœ<žœžœžœ1Ÿœžœžœžœ œΉžœ8žœžœžœžœžœ&žœ žœBžœ žœ)žœžœžœ>žœžœ.žœ%žœUžœžœžœ&žœžœžœžœžœEžœLžœ9žœOžœžœžœžœžœžœ>žœžœ.žœ%žœUžœžœžœ&žœžœžœžœžœEžœLžœ9žœOžœžœžœžœžœ "œ žœžœžœ  œžœžœžœžœžœžœ žœžœžœžœžœžœ žœžœžœžœ žœžœ~žœώžœžœ;žœ³žœ}žœ¬žœžœžœ΄žœžœ)žœGŸœžœžœižœžœžœWžœžœ]žœžœ!œ³žœpžœnžœ:žœžœ*œ4žœEžœžœ(œ žœžœπžœžœžœ©žœ26œ$žœžœ/œžœržœžœžœžœžœ #œIœ žœžœQžœžœ žœžœžœžœ"žœžœ,žœDžœŸ œžœžœsžœžœžœ‘žœžœDžœ|žœRžœ'ŸœžœžœfžœžœΚžœžœ1žœ+žœŸœžœ#žœžœRžœžœažœ žœžœΧžœ žœtžœφžœ[žœžœžœŸ œžœžœ”žœ/Ÿ œžœžœŸœžœžœžœžœžœžœ@žœ žœžœ'žœ žœžœ,žœžœžœžœžœ Ÿœžœžœžœžœžœžœ@žœ žœžœ'žœ žœžœ,žœžœžœžœžœžœžœžœΎžœžœ œ žœžœžœžœžœžœ žœžœ=žœžœžœ žœžœžœ]žœ žœžœžœžœœžœŸœžœžœžœ žœržœ žœžœžœsžœžœžœmžœ—žœIžœžœžœ3žœ Ÿœžœžœžœ žœžœ³žœ8žœžœžœžœžœ&žœ žœBžœ žœ)žœžœžœ>žœžœ.žœ%žœUžœžœžœ(žœžœžœžœžœEžœFžœ:žœ8žœžœžœžœžœžœ>žœžœ.žœ%žœUžœžœžœ(žœžœžœžœžœEžœFžœ:žœ8žœžœžœžœžœ žœžœ'žœžœ žœžœ žœžœžœžœžœ žœžœžœžœ žœžœžœžœ žœžœžœžœ žœžœžœžœ›žœ•žœžœ;žœcžœ|žœpžœžœžœ₯žœžœžœžœ žœžœ4žœEŸœžœžœžœžœkžœžœžœ‡ŸœžœžœžœžœžœwŸœžœžœžœžœžœžœ{Ÿœžœžœžœžœžœžœ žœžœBžœ‚žœ>Ÿ œžœžœžœžœžœžœ©Ÿ œžœžœžœžœžœžœžœ­Ÿœžœžœ'žœžœžœžœJžœ£žœ žœžœ*Ÿœžœžœœžœ žœ7žœžœ žœžœžœžœžœΥžœbžœžœž œ#žœažœžœ+žœ žœžœFžœžœžœžœŸžœ”žœύžœ¦žœ žœžœ1žœžœ/Ÿ œžœžœžœ žœ-Ÿœžœžœžœ žœžœžœžœ˜Ε’—…—ΡHγd