DIRECTORY AMBridge USING [WordSequence, WordSequenceRecord, RemotePD, RemoteGlobalFrameHandle, RemoteFrameHandle, RemoteRef, RemoteSED, RemotePointer, TVForRemoteFrame, nilRemotePD, nilRemoteFrameHandle, GetWorld], AMProcessBasic USING [ReturnLink], AMTypes USING [Error, TypedVariable, TVType], BcdDefs USING [MTIndex, BCD, FTSelf, SGIndex, SGNull, FTIndex, NameRecord, VersionStamp, BcdBase, MTHandle, NameString, FTHandle], BcdOps USING [ProcessModules, ProcessFiles], BrandXSymbolDefs USING [rootBodyIndex, SymbolTableBase, SymbolIdIndex, SymbolIndex, BodyIndex], BrandYSymbolDefs USING [rootBodyIndex, SymbolTableBase, SymbolIdIndex, SymbolIndex, BodyIndex], ConvertUnsafe USING [SubString, SubStringToRope], LoadState USING [Acquire, ConfigID, local, GlobalFrameToModule, ConfigInfo, Release, Handle, ModuleIndex], PrincOps USING [BytePC, ControlLink, CSegPrefix, EntryVectorItem, EPRange, Frame, FrameCodeBase, FrameHandle, GlobalFrame, GlobalFrameHandle, localbase, NullLink, ProcDesc, SignalDesc, UnboundLink, NullGlobalFrame, wordsPerPage, SD, sSignal], RemotePrincOpsUtils USING [RemoteGlobalFrame, RemoteGlobalFrameAndEntryPoint], Rope USING [ROPE, Concat, Text, Length], RTCommon USING [Field, StoreFieldLong], RTSD USING [sGCState, sMapStiStd], RTSymbolDefs USING [SymbolTableBase, SymbolTableHandle, nullHandle, nullBase, CallableBodyIndex, BodyIndex, rootBodyIndex, SymbolIdIndex, SymbolRecordIndex, SymbolIndex, nullBodyIndex], RTSymbolOps USING [AcquireType, EnumerateRecordIseis, AcquireRope, NullISEI], RTSymbols USING [ReleaseSTB, AcquireSTB, GetSTHForModule], RTSymbolsPrivate USING [AcquireSTHFromSTX], RTTypesBasicPrivate USING [UniqueTypeFinger, STDesc, FindSTI, PSTDesc, RMapStiStd, SymbolTableIndex, MapStiStd, TypeDesc, RMapTiTd, PTypeDesc], RTTypesPrivate USING [TypedVariableRec, GetCBTI, ConvertCbti], RTTypesRemotePrivate USING [RemoteErrorType, EVRange], RuntimeError USING [UNCAUGHT], SafeStorage USING [Type, nullType], Table USING [Base], VM USING [Interval, Allocate, Free, PageNumberForAddress, AddressForPageNumber], WorldVM USING [Address, AddressFault, 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, LoadState, RemotePrincOpsUtils, Rope, RTCommon, RTSymbolOps, RTSymbols, RTSymbolsPrivate, RTTypesBasicPrivate, RTTypesPrivate, RuntimeError, VM, WorldVM EXPORTS RTTypesPrivate, RTTypesRemotePrivate SHARES Rope = BEGIN OPEN AMBridge, AMTypes, bx: BrandXSymbolDefs, by: BrandYSymbolDefs, RemotePrincOpsUtils, RTSymbolDefs, RTSymbolOps, RTSymbols, RTTypesPrivate, RTTypesRemotePrivate, RuntimeError, SafeStorage, WorldVM; RemoteBCDCache: TYPE = LIST OF BCDCacheRec; BCDCacheRec: TYPE = RECORD[world: World _ , incarnation: Incarnation _ , remoteBCD: Address _ , localBCD: BcdDefs.BcdBase _ , useCount: INT _ ]; remoteBCDCache: RemoteBCDCache _ NIL; remoteBCDCacheLength: NAT _ 0; maxRemoteBCDCacheLength: NAT _ 1; SignallerFrameMessageOffset: NAT = 9; SignallerFrameSignalOffset: NAT = 7; RemoteError: PUBLIC ERROR[type: RemoteErrorType, message: LONG POINTER TO TEXT _ NIL] = CODE; AcquireSTBFromRemoteGFH: PUBLIC PROC [gfh: RemoteGlobalFrameHandle] RETURNS [SymbolTableBase] = { mappedBCD: BcdDefs.BcdBase; module: LoadState.ModuleIndex; std: RTTypesBasicPrivate.STDesc; sth: SymbolTableHandle _ nullHandle; mth: BcdDefs.MTHandle; ftb: Table.Base; sti: RTTypesBasicPrivate.SymbolTableIndex; moduleName: Rope.ROPE = RemoteGFHToName[gfh: gfh]; FindModule: PROC [mth: BcdDefs.MTHandle, mti: BcdDefs.MTIndex] RETURNS [BOOL] = { RETURN[module IN [mth.gfi .. mth.gfi + mth.ngfi)]}; [mappedBCD, module] _ AcquireRemoteBCDAndModule[gfh]; ftb _ LOOPHOLE[mappedBCD + mappedBCD.ftOffset, Table.Base]; [mth, ] _ BcdOps.ProcessModules[mappedBCD, FindModule ! UNWIND => ReleaseRemoteBCD[mappedBCD]]; IF mth = NIL THEN {ReleaseRemoteBCD[mappedBCD]; 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 ! AMTypes.Error => CONTINUE].sth; IF sth = nullHandle THEN { sth _ 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]]; }; OuterFromRemoteGFH: PUBLIC PROC [gfh: RemoteGlobalFrameHandle, inner: PROC [stb: SymbolTableBase] ] = { stb: SymbolTableBase _ AcquireSTBFromRemoteGFH[gfh]; inner[stb ! UNWIND => ReleaseSTB[stb] ]; ReleaseSTB[stb]; }; AcquireRemoteBCDAndModule: PUBLIC PROC [gfh: RemoteGlobalFrameHandle] RETURNS [BcdDefs.BcdBase, LoadState.ModuleIndex] = { bcd: BcdDefs.BcdBase; -- remote bcd module: LoadState.ModuleIndex; mappedBCD: BcdDefs.BcdBase; IF gfh.gfh = 0 THEN ERROR AMTypes.Error[reason: noSymbols]; Lock[gfh.world]; { ENABLE UNWIND => Unlock[gfh.world]; loadState: LoadState.Handle _ WorldVM.Loadstate[gfh.world]; config: LoadState.ConfigID; loadState.Acquire[]; { ENABLE UNWIND => loadState.Release[]; [config, module] _ loadState.GlobalFrameToModule[LOOPHOLE[gfh.gfh, PrincOps.GlobalFrameHandle]]; bcd _ loadState.ConfigInfo[config].bcd; }; -- end ENABLE UNWIND loadState.Release[]; mappedBCD _ AcquireRemoteBCD[ world: gfh.world, incarnation: gfh.worldIncarnation, bcd: bcd]; }; -- end ENABLE UNWIND Unlock[gfh.world]; RETURN[mappedBCD, module]; }; -- end AcquireRemoteBCDAndModule ReleaseRemoteBCD: PUBLIC ENTRY PROC [bcd: BcdDefs.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 { bcdP: BcdDefs.BcdBase = s.first.localBCD; pages: NAT _ IF bcdP.extended THEN bcdP.nPages - bcdP.rtPages.pages ELSE bcdP.nPages; VM.Free[[page: VM.PageNumberForAddress[bcdP], count: pages]]; 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: BcdDefs.BcdBase _ NIL] = { ENABLE UNWIND => NULL; prev: RemoteBCDCache _ NIL; incarnation: Incarnation = CurrentIncarnation[world]; FOR l: RemoteBCDCache _ remoteBCDCache, l.rest UNTIL l = NIL DO IF l.first.world = world AND l.first.remoteBCD = remoteBCD AND l.first.incarnation = incarnation 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: BcdDefs.BcdBase] = { ENABLE UNWIND => NULL; incarnation: Incarnation = CurrentIncarnation[world]; FOR l: RemoteBCDCache _ remoteBCDCache, l.rest UNTIL l = NIL DO IF l.rest = NIL THEN { l.rest _ CONS[ [world: world, incarnation: incarnation, remoteBCD: remoteBCD, localBCD: localBCD, useCount: 1], NIL]; RETURN; }; ENDLOOP; remoteBCDCache _ CONS[ [world: world, incarnation: incarnation, remoteBCD: remoteBCD, localBCD: localBCD, useCount: 1], NIL]; }; AcquireRemoteBCD: PUBLIC PROC [world: World, incarnation: Incarnation, bcd: BcdDefs.BcdBase] RETURNS [mappedBCD: BcdDefs.BcdBase _ NIL] ={ pages: NAT; interval: VM.Interval; mappedBCD _ FindCachedRemoteBCD[world, LOOPHOLE[bcd, Address]]; IF mappedBCD # NIL THEN RETURN[mappedBCD]; interval _ VM.Allocate[count: 1]; mappedBCD _ VM.AddressForPageNumber[interval.page]; CopyRead[world: world, from: LOOPHOLE[bcd, Address], nwords: SIZE[BcdDefs.BCD], to: LOOPHOLE[mappedBCD, LONG POINTER] ! UNWIND => VM.Free[interval]]; IF mappedBCD.extended THEN pages _ mappedBCD.nPages - mappedBCD.rtPages.pages ELSE pages _ mappedBCD.nPages; VM.Free[interval]; interval _ VM.Allocate[count: pages]; mappedBCD _ VM.AddressForPageNumber[interval.page]; CopyRead[world: world, from: LOOPHOLE[bcd, Address], nwords: pages*PrincOps.wordsPerPage, to: LOOPHOLE[mappedBCD, LONG POINTER] ! UNWIND => VM.Free[interval]]; EnterRemoteBCDInCache[ world: world, remoteBCD: LOOPHOLE[bcd, Address], localBCD: mappedBCD ]; }; GFHToName: PUBLIC PROC [f: PrincOps.GlobalFrameHandle] RETURNS [name: Rope.ROPE] = { moduleIndex: LoadState.ModuleIndex; config: LoadState.ConfigID; ssb: BcdDefs.NameString; bcd: BcdDefs.BcdBase; FindModuleString: PROC [mth: BcdDefs.MTHandle, mti: BcdDefs.MTIndex] RETURNS [ans: BOOL _ FALSE] = { ssd: ConvertUnsafe.SubString; IF moduleIndex IN [mth.gfi..mth.gfi + mth.ngfi) THEN { ssd _ [base: @ssb.string, offset: mth.name, length: ssb.size[mth.name]]; name _ ConvertUnsafe.SubStringToRope[ssd]; RETURN [TRUE]; }; }; IF f = PrincOps.NullGlobalFrame THEN RETURN[NIL]; LoadState.local.Acquire[]; { ENABLE UNWIND => LoadState.local.Release[]; [config, moduleIndex] _ LoadState.local.GlobalFrameToModule[f]; bcd _ LoadState.local.ConfigInfo[config].bcd; }; -- end ENABLE UNWIND LoadState.local.Release[]; ssb _ LOOPHOLE[bcd + bcd.ssOffset]; [] _ BcdOps.ProcessModules[bcd, FindModuleString]; }; RemoteGFHToName: PUBLIC PROC [gfh: RemoteGlobalFrameHandle] RETURNS [ans: Rope.ROPE _ NIL] = { bcd: BcdDefs.BcdBase; module: LoadState.ModuleIndex; ssb: BcdDefs.NameString; FindModuleString: PROC [mth: BcdDefs.MTHandle, mti: BcdDefs.MTIndex] RETURNS [stop: BOOL] = { ssd: ConvertUnsafe.SubString; IF module IN [mth.gfi..mth.gfi + mth.ngfi) THEN { ssd _ [base: @ssb.string, offset: mth.name, length: ssb.size[mth.name]]; ans _ ConvertUnsafe.SubStringToRope[ssd]; RETURN[TRUE]} ELSE RETURN[FALSE]; }; [bcd, module] _ AcquireRemoteBCDAndModule[gfh]; ssb _ LOOPHOLE[bcd + bcd.ssOffset, BcdDefs.NameString]; [] _ BcdOps.ProcessModules[bcd, FindModuleString ! UNCAUGHT => CONTINUE]; ReleaseRemoteBCD[bcd]; }; RemoteTypeToLocal: PUBLIC PROC [world: World, remoteType: CARDINAL] RETURNS [type: Type] = { stb: SymbolTableBase; td: RTTypesBasicPrivate.TypeDesc; -- copied from the remote world. NO REFS. sth: SymbolTableHandle _ nullHandle; seIndex: SymbolIndex; CopyRead[ world: world, from: LongRead[ world: world, addr: RemoteMapTiTd[world] -- WorldRoot[world].GCStateBasic.mapTiTd + SIZE[RTTypesBasicPrivate.RMapTiTd[0]] + LOOPHOLE[remoteType, CARDINAL] * SIZE[RTTypesBasicPrivate.PTypeDesc] ], nwords: SIZE[RTTypesBasicPrivate.TypeDesc], to: @td]; 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 THEN { remoteBCD: BcdDefs.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: BcdDefs.BcdBase _ AcquireRemoteBCD[world: world, incarnation: CurrentIncarnation[world], bcd: remoteBCD]; { ENABLE UNWIND => ReleaseRemoteBCD[mappedBCD]; ssb: BcdDefs.NameString = LOOPHOLE[mappedBCD + mappedBCD.ssOffset, BcdDefs.NameString]; IF remoteSGI = BcdDefs.SGNull THEN { findSymbolFTI: PROC [ffth: BcdDefs.FTHandle, ffti: BcdDefs.FTIndex] RETURNS [stop: BOOL] = { 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 { 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] ELSE moduleName _ GetModuleName[ssb, ftb[fti].name]}; }; -- end ENABLE UNWIND ReleaseRemoteBCD[mappedBCD]; sth _ 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: BcdDefs.NameString, n: BcdDefs.NameRecord] RETURNS [name: Rope.Text] = { ssd: ConvertUnsafe.SubString _ [base: @ssb.string, offset: n, length: ssb.size[n]]; name _ ConvertUnsafe.SubStringToRope[ssd]; FOR i: INT IN [0..Rope.Length[name]) DO IF name[i] = '. THEN {name.length _ i; EXIT}; ENDLOOP; }; 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: remoteFH.worldIncarnation, gfh: LOOPHOLE[GetRemoteFrameHeader[remoteFH].accesslink, WorldVM.ShortAddress] ]] THEN ERROR RemoteError[invalidFrame]; }; ValidRemoteGlobalFrame: PROC [gfh: RemoteGlobalFrameHandle] RETURNS [ans: BOOL _ FALSE] = { h: rep PrincOps.ControlLink = LOOPHOLE[gfh.gfh, rep PrincOps.ControlLink]; ans _ NOT h.proc AND NOT h.indirect; }; -- AND InRemoteGFT[gfh ! ANY => CONTINUE]}; Kludge: TYPE = RECORD [ignore1, ignore2, ignore3, ignore4, ignore5, mapTiTd: LONG POINTER]; RemoteMapTiTd: PROC [world: World] RETURNS [LONG CARDINAL] = { RETURN[ LongRead[ -- gets the remote address of an RTTypesBasicPrivate.RMapTiTd world: world, addr: -- the remote address of a cell containing the remote address of an RMapTiTd LongRead[ -- gets the remote address of a Kludge world: world, addr: --the remote address of a cell containing the remote address of a Kludge Long[world: world, addr: LOOPHOLE[PrincOps.SD + RTSD.sGCState, ShortAddress]] ] + 5 * SIZE[LONG POINTER] ] ]; }; WorldMapStiStdEntry: PROC [world: World, remoteSTI: RTTypesBasicPrivate.SymbolTableIndex] RETURNS [BcdDefs.BcdBase, BcdDefs.SGIndex, BcdDefs.VersionStamp] = { ans: RTTypesBasicPrivate.STDesc; CopyRead[-- gets an STDesc world: world, from: LongRead[-- gets the remote address of an STDesc world: world, addr:-- the remote address of a cell containing the remote address of an STDesc LongRead[ -- gets the remote address of an RMapStiStd world: world, addr:-- the remote address of a cell containing the remote address of an RMapStiStd Long[ world: world, addr: LOOPHOLE[PrincOps.SD + RTSD.sMapStiStd, ShortAddress] ] ] + SIZE[RTTypesBasicPrivate.RMapStiStd[0]] + SIZE[RTTypesBasicPrivate.PSTDesc] * remoteSTI ], 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 = 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: gfh.worldIncarnation, ptr: LOOPHOLE[c, Address]]]; }; 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]; Lock[world]; { ENABLE UNWIND => Unlock[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; }; -- end ENABLE UNWIND Unlock[world]; RETURN[[world: world, worldIncarnation: pd.worldIncarnation, pd: LOOPHOLE[icl]]]}; AcquireCBTHandleFromRemotePD: PUBLIC PROC [pd: RemotePD] RETURNS [stb: SymbolTableBase, cbti: CallableBodyIndex] = { world: World = pd.world; Lock[world]; { ENABLE UNWIND => Unlock[world]; gfh: RemoteGlobalFrameHandle _ [world: world, worldIncarnation: pd.worldIncarnation, gfh: LOOPHOLE[RemoteGlobalFrame[world, pd.pd], WorldVM.ShortAddress]]; stb _ AcquireSTBFromRemoteGFH[gfh]; cbti _ RTTypesPrivate.GetCBTI[stb, RemoteGlobalFrameAndEntryPoint[world, pd.pd].ep]; }; Unlock[world]; }; GetRemoteGFHeader: PUBLIC PROC [gfh: RemoteGlobalFrameHandle] RETURNS [ans: REF PrincOps.GlobalFrame] = { world: World = gfh.world; ans _ NEW[PrincOps.GlobalFrame]; Lock[world]; { ENABLE UNWIND => Unlock[world]; CopyRead[ world: world, from: Long[world: world, addr: LOOPHOLE[gfh.gfh, ShortAddress]], nwords: SIZE[PrincOps.GlobalFrame], to: LOOPHOLE[ans, LONG POINTER] ]; }; -- end ENABLE UNWIND Unlock[world]; }; GetRemoteFrameHeader: PUBLIC PROC [fh: RemoteFrameHandle] RETURNS [ans: REF PrincOps.Frame] = { world: World = fh.world; ans _ NEW[PrincOps.Frame]; Lock[world]; { ENABLE UNWIND => Unlock[world]; CopyRead[ world: world, from: Long[world: world, addr: LOOPHOLE[fh.fh, ShortAddress]], nwords: SIZE[PrincOps.Frame], to: LOOPHOLE[ans, LONG POINTER] ]; }; -- end ENABLE UNWIND Unlock[world]; }; GetRemoteReferentType: PUBLIC PROC [remoteRef: RemoteRef] RETURNS [type: Type--valid locally--] = { world: World = remoteRef.world; IF remoteRef.ref = 0 THEN RETURN[nullType]; Lock[world]; type _ GetRemotePrefixedType[remoteRef ! UNWIND => Unlock[world]]; Unlock[world]; }; GetRemotePrefixedType: PROC [remoteRef: RemoteRef] RETURNS [Type--valid locally--] = { remoteType: CARDINAL = WorldVM.Read[world: remoteRef.world, addr: remoteRef.ref - 1]; RETURN[RemoteTypeToLocal[world: remoteRef.world, remoteType: remoteType]]; }; 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]}; GetRemoteSignalType: PUBLIC PROC [remoteSED: RemoteSED] RETURNS [type: Type _ nullType--valid locally--] = { ep: CARDINAL; stb: SymbolTableBase; world: World = remoteSED.world; proc: PROC [stb: SymbolTableBase, isei: SymbolIdIndex] RETURNS [stop: BOOL] = { 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: BOOL] = { 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 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: BOOL] = { 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 ep = STInfoToEPN[LOOPHOLE[stb.seb[isei].idValue, PrincOps.SignalDesc]] THEN {type _ AcquireType[[y[stb]], [y[stb.seb[isei].idType]]]; RETURN[TRUE]} ELSE RETURN[FALSE]}; 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]]; Lock[world]; { ENABLE UNWIND => Unlock[world]; gfh: PrincOps.GlobalFrameHandle; [gfh, ep] _ RemoteGlobalFrameAndEntryPoint[world, remoteSED.sed]; stb _ AcquireSTBFromRemoteGFH[[world, remoteSED.worldIncarnation, LOOPHOLE[gfh]]]; [] _ 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]; }; -- end ENABLE UNWIND Unlock[world]; }; IsRemoteCatchFrame: PUBLIC PROC [remoteFrameHandle: RemoteFrameHandle, bti: BodyIndex] RETURNS [isCatchFrame: BOOL _ TRUE, revBti: BodyIndex] = { world: World = remoteFrameHandle.world; Lock[world]; { ENABLE UNWIND => Unlock[world]; revBti _ bti; ValidateRemoteFrame[remoteFrameHandle ! RuntimeError.UNCAUGHT, RemoteError, WorldVM.AddressFault => GOTO notCatch]; { -- return FALSE if input invalid nextFrame: RemoteFrameHandle _ [world: remoteFrameHandle.world, worldIncarnation: remoteFrameHandle.worldIncarnation, fh: LOOPHOLE[AMProcessBasic.ReturnLink [world, LOOPHOLE[remoteFrameHandle.fh, PrincOps.FrameHandle]], ShortAddress]]; nextFHdr: REF PrincOps.Frame; ValidateRemoteFrame[nextFrame ! RuntimeError.UNCAUGHT, RemoteError, WorldVM.AddressFault => GOTO notCatch]; 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: remoteFrameHandle.worldIncarnation, fh: 0]; IF sl = 0 THEN GOTO notCatch; L0Frame _ [ world: remoteFrameHandle.world, worldIncarnation: remoteFrameHandle.worldIncarnation, fh: LOOPHOLE[sl - PrincOps.localbase, ShortAddress] ]; ValidateRemoteFrame[L0Frame ! RuntimeError.UNCAUGHT, RemoteError, WorldVM.AddressFault => GOTO notCatch]; 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 }; -- end detect situation where ... }; -- end return FALSE if caller not signaller }; -- end return FALSE if input invalid }; -- end ENABLE UNWIND Unlock[world]; EXITS notCatch => {Unlock[remoteFrameHandle.world]; isCatchFrame _ FALSE}; }; -- end IsRemoteCatchFrame RemoteSigGF: PROC [world: World] RETURNS [PrincOps.GlobalFrameHandle] = { pd: PrincOps.ProcDesc = LOOPHOLE[Read[world: world, addr: Long[world: world, addr: LOOPHOLE[PrincOps.SD + PrincOps.sSignal, ShortAddress]]], PrincOps.ProcDesc]; RETURN[RemoteGlobalFrame[world, LOOPHOLE[pd]]]; }; AcquireBTIFromRemoteFH: PUBLIC PROC [remoteFrameHandle: RemoteFrameHandle, contextPC: BOOL] RETURNS [bti: BodyIndex _ nullBodyIndex] = { stb: SymbolTableBase _ nullBase; world: World = remoteFrameHandle.world; Lock[world]; { ENABLE UNWIND => Unlock[world]; [stb, bti] _ AcquireBTHandleFromRemoteFH[remoteFrameHandle, contextPC ! RuntimeError.UNCAUGHT, RemoteError, WorldVM.AddressFault, AMTypes.Error => CONTINUE ]; }; -- end ENABLE UNWIND Unlock[world]; IF stb # nullBase THEN ReleaseSTB[stb]; }; 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: fh.worldIncarnation, gfh: LOOPHOLE[remoteFrame.accesslink, ShortAddress]]]; [epn, start] _ GetRemoteEp[pc: framePC, gf: [world: fh.world, worldIncarnation: fh.worldIncarnation, 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}; 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: BOOL] = { 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: BOOL] = { 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}; diff: CARDINAL _ LAST[CARDINAL]; anyProcedure: BOOL _ 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}; 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] = { ep: CARDINAL; stb: SymbolTableBase; world: World = sed.world; proc: PROC [stb: SymbolTableBase, isei: SymbolIdIndex] RETURNS [stop: BOOL] = { 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: BOOL] = { 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 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: BOOL] = { 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 ep = STInfoToEPN[LOOPHOLE[stb.seb[isei].idValue, PrincOps.SignalDesc]] THEN {ans _ AcquireRope[[y[stb]], [y[stb.seb[isei].hash]]]; RETURN[TRUE]} ELSE RETURN[FALSE]}; SELECT LOOPHOLE[sed.sed, CARDINAL] FROM LOOPHOLE[PrincOps.NullLink, CARDINAL] => RETURN[NIL]; LOOPHOLE[PrincOps.UnboundLink, CARDINAL] => RETURN[NIL]; 177777B => RETURN["ERROR"]; LOOPHOLE[UNWIND, CARDINAL] => RETURN["UNWIND"]; LOOPHOLE[ABORTED, CARDINAL] => RETURN["ABORTED"]; ENDCASE; Lock[world]; { ENABLE UNWIND => Unlock[world]; sei: SymbolRecordIndex; gfh: PrincOps.GlobalFrameHandle; [gfh, ep] _ RemoteGlobalFrameAndEntryPoint[world, sed.sed]; stb _ AcquireSTBFromRemoteGFH[[world, sed.worldIncarnation, LOOPHOLE[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]; }; -- end ENABLE UNWIND Unlock[world]; }; RemoteStoreWords: PUBLIC PROC [from: LONG POINTER, to: RemotePointer, nWords: NAT] = { Lock[to.world]; CopyWrite[world: to.world, from: from, nwords: nWords, to: to.ptr ! UNWIND => Unlock[to.world]]; Unlock[to.world]; }; RemoteStoreWord: PUBLIC PROC [to: RemotePointer, value: CARDINAL] = { Lock[to.world]; Write[world: to.world, addr: to.ptr, value: value ! UNWIND => Unlock[to.world]]; Unlock[to.world]; }; RemoteStoreDoubleWord: PUBLIC PROC [to: RemotePointer, value: LONG CARDINAL] = { Lock[to.world]; LongWrite[world: to.world, addr: to.ptr, value: value ! UNWIND => Unlock[to.world]]; Unlock[to.world]; }; RemoteStoreFieldLong: PUBLIC PROC [ptr: RemotePointer, field: RTCommon.Field, value: LONG CARDINAL] = { val: LONG CARDINAL; Lock[ptr.world]; {ENABLE UNWIND => Unlock[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]; }; -- end ENABLE UNWIND Unlock[ptr.world]; }; GetRemoteWord: PUBLIC PROC [remotePointer: RemotePointer] RETURNS [ans: WORD] = { Lock[remotePointer.world]; ans _ Read[world: remotePointer.world, addr: remotePointer.ptr ! UNWIND => Unlock[remotePointer.world]]; Unlock[remotePointer.world]; }; GetRemoteLC: PUBLIC PROC [remotePointer: RemotePointer] RETURNS [ans: LONG CARDINAL] = { Lock[remotePointer.world]; ans _ LongRead[world: remotePointer.world, addr: remotePointer.ptr ! UNWIND => Unlock[remotePointer.world]]; Unlock[remotePointer.world]; }; GetRemoteWords: PUBLIC PROC [remotePointer: RemotePointer, nWords: NAT] RETURNS [ans: WordSequence] = { Lock[remotePointer.world]; {ENABLE UNWIND => Unlock[remotePointer.world]; ans _ NEW[WordSequenceRecord[nWords]]; CopyRead[ world: remotePointer.world, from: remotePointer.ptr, nwords: nWords, to: LOOPHOLE[@ans[0], LONG POINTER]]; }; -- end ENABLE UNWIND Unlock[remotePointer.world]; }; 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; 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 { remoteSignallerFrameHandle: RemoteFrameHandle _ nilRemoteFrameHandle; Lock[world]; { ENABLE UNWIND => Unlock[world]; ValidateRemoteFrame[th.remoteFrameHandle]; remoteSignallerFrameHandle _ [world: world, worldIncarnation: th.remoteFrameHandle.worldIncarnation, 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]; }; -- end ENABLE UNWIND 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. RTTypesRemotePrivateImpl.Mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Rovner, January 16, 1984 2:39 pm Russ Atkinson (RRA) March 22, 1985 10:00:30 am PST TYPES VARIABLES CONSTANTS S I G N A L S P R O C E D U R E S 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[PrincOps.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]}}; here with the copied remote BCD. Now poke around in the remote bcd to find the version stamp, then get the symboltable now find the bcd and module of interest UnsafeStorage.GetSystemUZone[].FREE[@nBCD]; assumes world is locked UnsafeStorage.NewUObject [size: PrincOps.wordsPerPage, zone: UnsafeStorage.GetSystemUZone[]]; UnsafeStorage.GetSystemUZone[].FREE[@mappedBCD]]; UnsafeStorage.GetSystemUZone[].FREE[@mappedBCD]; UnsafeStorage.NewUObject[ size: pages*PrincOps.wordsPerPage, zone: UnsafeStorage.GetSystemUZone[]]; UnsafeStorage.GetSystemUZone[].FREE[@mappedBCD]]; seIndex must be consistent with sth: either symbols from the UTF or from the Typs's symbol access info first try for the original defining module not easy. Try harder using symbol access info for the remote type. go again for the defining module, this time with its name (search the BCD's file table) go for the module specified by the SGI NOTE module name vs file name raises RemoteError InRemoteGFT: PROC[gfh: RemoteGlobalFrameHandle] RETURNS[BOOL] = {gftLength: CARDINAL; world: World = gfh.world; Lock[world]; { ENABLE UNWIND => Unlock[world]; gftLength _ Read[world: world, addr: Long[world: world, addr: LOOPHOLE[PrincOps.SD + PrincOps.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]; }; LONG POINTER TO PrincOps.CSegPrefix raises typeFault 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]]]}; }; START GetRemoteSignalType HERE return FALSE if no valid calling frame L0Frame is the frame that encloses the catch frame return FALSE if static frame not valid (??) body of GetEp begins here Κ#P˜codešœ™Kšœ Οmœ1™Kšœžœ˜6Kšœ žœžœ˜Kšœ žœ˜#Kšœžœ˜KšžœžœH˜Pšœžœ₯˜²K˜——šœžœΟc$˜GKšžœΘžœ ˜ΪKšžœ%˜,Kšžœ˜ KšœžœžœΔ˜ΠK˜—šœ™Kšœžœžœžœ ˜+šœ žœžœ˜+K˜K˜K˜Kšœ žœ˜——šœ ™ Kšœ!žœ˜%Kšœžœ˜Kšœžœ˜!K˜—šœ ™ Kšœžœ˜%Kšœžœ˜$K˜—šœ ™ K˜šœ žœžœ!žœžœžœžœžœžœ˜]K˜——Kšœ™K˜Kšœ™Kšœ0™0KšœU™UKšœ™K˜KšœH™HKšœ%™%Kšœ"™"Kšœ"™"Kšœ™Kšœ™K˜Kšœ6™6Kšœ#™#Kšœ™Kšœ#™#Kšœ™K˜Kšœ!™!Kšœ ™ Kšœ™Kšœ™Kšœ/™/Kšœ™Kšœ$™$Kšœ™Kšœ"™"Kšœ™Kšœ™Kšœ"™"Kšœ$™$Kšœ™Kšœ&™&Kšœ ™ Kšœ'™'Kšœ<™Kšžœžœžœ˜šžœ,žœž˜?šžœžœ˜ Kšœ(˜(šžœ/žœ˜8Kšœžœ˜šžœ,žœž˜?šžœžœ˜Kšœ)˜)šœžœ˜ Kšžœžœ!žœ ˜H—šžœ žœ,˜=Kšœ+™+—Kšžœžœžœ˜CKšžœ˜Kšœ˜—K˜ Kšž˜—Kšœ˜—Kšž˜Kšœ˜—Kšžœ˜—Kšžœ˜K˜K˜—š  œžœžœ#žœžœ˜pKšžœžœžœ˜Kšœžœ˜Kšœ5˜5šžœ,žœž˜?šžœžœžœ"žœ˜gKšœ(˜(Kš žœžœžœžœŸ ˜OKšœŸ*˜DK˜Kšžœ˜K˜—K˜ Kšžœ˜—K˜K˜—š œžœžœB˜cKšžœžœžœ˜Kšœ5˜5šžœ,žœž˜?šžœ žœ˜šœ žœ˜Kšœ˜K˜K˜K˜K˜Kšžœ˜—Kšžœ˜K˜—Kšžœ˜—šœžœ˜Kšœ˜K˜K˜K˜K˜Kšžœ˜—K˜K˜—š  œžœžœ?žœžœ˜ŠKšœ™Kšœžœ˜ Kšœ žœ ˜Kšœ'žœ˜?Kšžœ žœžœžœ ˜*Kšœ žœ˜!šœ žœ%˜3šœ™K™D——˜Kšœžœ˜Kšœžœ žœ˜šœžœ žœžœ˜%Kšœžœ˜Kšœžœ™1—K˜—šžœ˜Kšžœ3˜7Kšžœ˜K˜—šœ˜Kšœžœ ™0—Kšœ žœ˜%šœ žœ%˜3™K™"K™&——˜Kšœžœ˜K˜$šœžœ žœžœ˜%Kšœžœ˜Kšœžœ™1——˜K˜ Kšœ žœ˜"K˜K˜—K˜K˜—š   œžœžœ!žœ žœ˜TK˜$K˜K˜K˜š œž˜Kšœ.žœžœžœ˜MK˜šžœ žœžœ˜6K˜IK˜+Kšžœžœ˜K˜—K˜—Kšžœžœžœžœ˜1K˜šœžœžœ˜-K˜?K˜.KšœŸ˜—K˜Kšœžœ˜$K˜3K˜—K˜š  œžœžœžœ žœžœ˜^Kšœ˜K˜K˜š œžœ.žœžœ˜]Kšœ˜šžœžœ˜*šžœ˜KšœI˜IK˜*Kšžœžœ˜—Kšžœžœžœ˜—Kšœ˜—K˜/Kšœžœ*˜8Kšœ3žœžœ˜IK˜K˜K˜—š  œžœžœžœžœ˜\Kšœ˜Kšœ#Ÿ*˜MK˜$˜Kšœ$™$KšœA™A—˜ K˜ K˜˜ K˜ šœ˜šœŸ(˜>Kšœžœ!˜'Kšœžœ žœžœ˜F——K˜—Kšœžœ˜+K˜ —Kšœ*™*KšœŸ>˜Y˜gK˜—šžœ˜šžœ˜KšœB™BKšœ˜K˜K˜)˜*K˜D—šžœ žœžœ˜Kšœžœžœ˜˜˜ K˜'K˜——šœžœžœ ˜/˜Kšœžœ5˜?K˜—šžœ˜šž˜šœ9™9Kšœ™—šœžœ0žœžœ˜\Kšžœ#žœžœžœ˜8Kšœ+˜+Kšžœžœ˜—K˜!K˜3Kšžœžœžœžœ˜K˜—šžœ˜Kšœ&™&Kšœžœ-˜GKšœžœ-˜GK˜+K˜šžœ˜šžœ2˜6Kšœ™—Kšžœ1˜5———KšœŸ˜—K˜K˜K˜uKšœŸ˜—KšœŸ˜K˜——Kšžœžœžœ"˜@K˜Kšœ0žœ˜KK˜KšœŸ˜K˜—š  œžœ2žœ˜bK˜SK˜+šžœžœžœž˜'Kšžœžœžœ˜-Kšžœ˜—šœ˜K˜——š œžœžœ"˜BKšœ™Kšœ"žœ(˜Ršžœ ˜ Kšžœ˜šžœ˜Kšœ˜Kšœ-˜-KšœžœA˜OKšœ˜—Kšžœžœ˜%—šœ˜K˜——š  œžœžœžœžœ˜[Kšœžœ$˜JKšœžœžœžœ ˜$šœŸ,˜0K˜——Kšœ?™?Kšœ™Kšœ™Kšœ ™ Kšœ!™!Kšœ™Kšœ™Kšœ1™1Kšœ™Kšœ$™$Kšœ0™0Kšœ"™"Kšœ#™#Kšœ™Kšœ™Kšœ™Kšœ™Kšœ™˜Kš œžœžœ8žœžœ˜[—š Πbn œžœžœžœžœ˜>šžœ˜šœ Ÿ=˜HK˜ šœŸL˜Sšœ Ÿ&˜1Kšœ ˜ šœŸH˜OKšœžœ žœžœ˜M—Kšœžœžœžœ˜——K˜—K˜—K˜K˜—š œžœ@žœ=˜žK˜ šœ Ÿ˜K˜ šœ˜šœ Ÿ'˜0K˜ šœŸJ˜Ošœ Ÿ+˜6Kšœ ˜ šœŸN˜Sšœ˜Kšœ ˜ Kšœžœ žœžœ˜;Kšœ˜——Kšœ˜—Kšœžœ#˜)Kšœžœ)˜/—Kšœ˜——Kšœžœ˜)K˜K˜—Kšžœ$˜*K˜K˜—š  œžœžœ*žœ˜`šœ6˜6Kšœ#™#—šœžœ˜%šœžœ˜%Kšœžœ˜Kšœžœ˜$——Kšžœžœ˜+K˜—š œžœžœ˜XKšœ8˜8Kšœžœ˜KšžœAžœ˜^K˜K˜—š œžœžœžœ˜OKšœ™Kšœžœ˜BK˜Kšžœžœžœžœ˜RK˜ šœžœžœ˜!šžœ ž˜šžœ ˜šž˜šœžœ˜šœ˜Kšœ žœ˜C—K˜——Kšžœžœ)˜3—Kšžœ˜—KšœŸ˜—K˜šžœ;žœ ˜RK˜——š œžœžœžœ4˜tK˜K˜K˜ šœžœžœ˜!˜˜Kšœ&˜&Kšœžœ9˜F——K˜#K˜TK˜—K˜K˜K˜—KšœD™DKšœ"™"Kšœ™K˜Kšœ!™!Kšœ ™ K˜Kšœ™Kšœ™Kšœ"™"Kšœ&™&Kšœ™Kšœ&™&Kšœ ™ Kšœ™Kšœ™Kšœ™Kšœ,™,Kšœ?™?Kšœ™K˜š œžœžœ˜=Kšžœžœ˜+K˜Kšœžœ˜ K˜ šœžœžœ˜!˜ K˜ Kšœžœ˜@Kšœžœ˜#Kšœžœžœžœ˜Kšœ˜—KšœŸ˜—K˜šœ˜K˜——š œžœžœ˜9Kšžœžœ˜%K˜Kšœžœ˜K˜ šœžœžœ˜!˜ K˜ Kšœžœ˜>Kšœžœ˜Kšœžœžœžœ˜Kšœ˜—KšœŸ˜—K˜˜K˜——š  œžœžœžœ Ÿœ˜cK˜Kšžœžœžœ ˜+K˜ Kšœ)žœ˜BK˜K˜K˜—š œžœžœŸœ˜VKšœ žœA˜UKšžœD˜JK˜K˜—š  œžœžœžœ Ÿœ˜bKšœ˜K˜K˜5˜˜šžœžœž˜Kšœ"žœ(˜PKšœ"žœ(˜PKšžœžœ˜——Kšœžœ˜—K˜K˜—š  œžœžœžœŸœ˜lKšœžœ˜ K˜K˜K˜šœžœ,žœžœ˜Ošžœžœž˜Kšœžœ žœ˜LKšœžœ žœ˜LKšžœžœ˜——šœžœ2žœžœ˜VKšœ˜šžœ˜KšžœG˜Jšžœžœž˜#Kšœžœ˜Kšžœžœ˜—Kšžœžœ-˜JKšžœ;žœžœ˜LKšžœžœžœ˜——šœžœ2žœžœ˜VKšœ˜šžœ˜KšžœG˜Jšžœžœž˜#Kšœžœ˜Kšžœžœ˜—Kšžœžœ-˜JKšžœ;žœžœ˜LKšžœžœžœ˜K˜——Kšœ™K˜šžœžœžœ Ÿ˜8Kš žœžœžœžœžœžœ˜AKš žœžœžœžœžœžœ˜BKšžœžœžœžœ˜K˜—K˜ šœžœžœ˜!K˜ K˜AKšœBžœ˜R˜K˜šžœžœž˜K˜;K˜;Kšžœžœ˜—K˜Kšœžœ˜—K˜KšœŸ˜—K˜˜K˜——š  œžœžœ7žœžœžœ˜‘K˜'K˜ šœžœžœ˜!K˜ šœ%˜%Kšœžœ'žœ ˜M—šœŸ ˜$˜˜"Kšœ6˜6šœžœ˜'˜Kšžœ.˜6—K˜———Kšœ žœ˜šœ˜Kšœžœ'žœ ˜MKšœ&™&—K˜+šžœ;˜=Kšžœžœ ˜—šœŸ'˜+Kšœžœžœ5˜L˜˜"Kšœ6˜6K˜——Kšžœžœžœ ˜˜ K˜Kšœ5˜5Kšœžœ'˜3Kšœ˜Kšœ2™2—šœ˜Kšœžœ'žœ ˜MKšœ+™+—šžœ3˜5K˜*Kšžœžœ ˜—Kšžœžœžœ Ÿ"˜IšœŸH˜Jšœžœ˜Kšœžœžœ˜:—šžœ žœž˜Kšœ žœžœ˜8Kšžœž˜—KšœŸ!˜%—KšœŸ+˜/—KšœŸ$˜(—KšœŸ˜—K˜Kšžœ>žœ˜JKšœŸ˜—K˜š  œžœžœ!˜IKšœžœ3žœ žœ9˜ Kšžœžœ˜/Kšœ˜K˜—š Οbœžœžœ3žœžœ%˜ˆKšœ ˜ K˜'K˜ šœžœžœ˜!˜ ˜:šœžœ2˜IKšœž˜ —Kšœ˜——KšœŸ˜—K˜Kšžœžœ˜'šœ˜K˜——š œžœ$žœžœ+˜}Kšœ˜Kšœžœ˜Kšœ žœ+˜;Kšœ/žœ žœžœ˜MK˜˜/Kšœ&˜&Kšœžœ)˜6K˜—˜'˜Kšœ&˜&Kšœžœ(˜5—K˜Kšœžœ˜—˜+K˜ K˜ šœ žœ"˜3Kšœžœ˜——Kšžœžœ˜1K˜—š  œžœžœIžœ*˜“šœ  œžœžœ˜+š œ œžœžœžœ˜;šžœžœž˜˜šžœ žœž˜Kšœ žœ žœžœ˜7Kšžœ˜——Kšžœžœ˜Kšžœžœ˜——š œžœžœžœ˜:šžœžœž˜˜šžœ žœž˜Kšœ žœ žœžœ˜7Kšžœ˜——Kšžœžœ˜Kšžœžœ˜——K˜šžœžœž˜K˜LK˜LKšžœžœ˜—K˜—Kšœ™Kšœžœžœžœ˜ Kšœžœžœ˜šžœ žœž˜%K˜+Kšžœžœžœ˜#Kšžœžœžœ˜*K˜K˜Kšœžœ˜Kšžœ˜—KšžœžœžœŸ˜:Kšžœ˜K˜—š  œžœžœžœ žœ˜GKšœ˜K˜K˜&Kšžœ žœžœžœ˜K˜/˜šžœžœž˜˜Kšœžœ*˜B—˜Kšœžœ*˜B—Kšžœž˜—Kšœžœ˜—K˜Kšžœ˜ K˜—š  œžœžœžœ žœžœ˜PKšœžœ˜ K˜K˜K˜šœžœ,žœžœ˜Ošžœžœž˜Kšœžœ žœ˜LKšœžœ žœ˜LKšžœžœ˜——šœžœ2žœžœ˜VKšœ˜šžœ˜KšžœG˜Jšžœžœž˜#Kšœžœ˜Kšžœžœ˜—Kšžœžœ-˜JKšžœ8žœžœ˜IKšžœžœžœ˜——šœžœ2žœžœ˜VKšœ˜šžœ˜KšžœG˜Jšžœžœž˜#Kšœžœ˜Kšžœžœ˜—Kšžœžœ-˜JKšžœ8žœžœ˜IKšžœžœžœ˜K˜——šžœžœ žœž˜'Kšžœžœžœžœ˜5Kšžœžœžœžœ˜8Kšœ žœ ˜Kšžœžœžœžœ ˜/Kšžœžœžœžœ ˜1Kšžœ˜K˜—K˜ šœžœžœ˜!K˜K˜ K˜;Kšœ<žœ˜Lšœžœžœž˜K˜;K˜;Kšžœžœ˜—šžœžœ žœž˜#Kšœ+žœ˜F—K˜KšœŸ˜—K˜šœ˜K˜——š  œžœžœžœžœžœ˜VK˜šœA˜AKšœžœ˜—K˜˜K˜——š œžœžœžœ˜EK˜Kšœ4žœ˜PK˜˜K˜——š  œžœžœžœžœ˜PK˜Kšœ8žœ˜TK˜˜K˜——š ’œžœžœ4žœžœ˜gKšœžœžœ˜K˜šœžœžœ˜$Kšœ'žœ˜CK˜BKšœ"žœ ˜JKšœŸ˜—K˜K˜K˜—š   œžœžœ žœžœ˜QK˜šœ>˜>Kšœžœ!˜)—K˜K˜K˜—š   œžœžœ žœžœžœ˜XK˜šœB˜BKšœžœ!˜)—K˜K˜K˜—š  œžœžœ(žœžœ˜gK˜šœžœžœ ˜.Kšœžœ˜&˜ K˜K˜K˜Kšœžœ žœžœ˜%—KšœŸ˜—K˜K˜K˜—š  œžœžœŸœžœ žœ0˜Kšœžœžœ˜(K˜šžœžœž˜˜šžœ˜šžœ-˜1K˜Ešœ žœ4˜FKšžœžœž œ˜—šœ žœ3˜GKšžœžœ˜!—Kšžœ˜Kšžœžœ,˜6———˜ šžœ˜šžœ˜K˜EK˜ šœžœžœ˜!K˜*˜˜Kšœ9˜9šœžœ˜šœ˜Kšœž œ1˜A—K˜———˜K˜˜ K˜ K˜D——šœ ž˜˜˜ K˜ K˜C——K˜—KšœŸ˜—K˜Kšž˜Kšœ˜Kšžœžœ,˜6———Kšžœžœ-˜=K˜——š  œžœžœžœ˜BKšžœ+˜1K˜—š œžœžœžœ˜7Kšžœžœžœ˜ K˜—Kšžœ˜K˜K˜—…—}Ά°