-- RTTypesRemotePrivateImpl.Mesa -- last modified on July 6, 1983 6:30 pm 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], 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[NodeHeader, sizeNd], 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, Incarnation]; 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, 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 _ , incarnation: Incarnation _ , 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 AND l.first.incarnation = CurrentIncarnation[world] 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, incarnation: CurrentIncarnation[world], remoteBCD: remoteBCD, localBCD: localBCD, useCount: 1], NIL]; RETURN; }; ENDLOOP; remoteBCDCache _ CONS[[world: world, incarnation: CurrentIncarnation[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--] = { world: World = remoteRef.world; IF remoteRef.ref = 0 THEN RETURN[nullType]; { ENABLE UNWIND => Unlock[world]; Lock[world]; type _ GetRemotePrefixedType[remoteRef]; Unlock[world]}}; 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]]; }; -- 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.