DIRECTORY AMBridge USING[TVToCardinal, WordSequenceRecord, WordSequence, RemoteRef, RemotePointer, RemoteSED, RemotePD, RemoteFrameHandle, RemoteGlobalFrameHandle, nilRemotePD, nilRemoteSED, TVToLC, TVForGFHReferent], AMTypes USING[Error, Class, TypeClass, UnderType, TVType, TypedVariable, Status, Type, TV], AtomPrivate USING[AtomRec], Basics USING[bitsPerWord], Rope USING[RopeRep], RTSymbolDefs USING[BodyIndex], RTSymbolOps USING[NullBTI], SafeStorage USING[nullType, fhType, gfhType, EquivalentTypes], RTTypesPrivate USING[TypedVariableRec, BitsForType, TypedVariableHead], RTTypesRemotePrivate USING[GetRemoteReferentType, GetRemoteProcedureType, GetRemoteSignalType, AcquireBTIFromRemoteFH, IsRemoteCatchFrame], WorldVM USING[CurrentIncarnation, Long, LocalWorld, World, Address]; RTTypesRemoteImpl: PROGRAM IMPORTS AMBridge, AMTypes, RTSymbolOps, SafeStorage, RTTypesPrivate, RTTypesRemotePrivate, WorldVM EXPORTS AMBridge SHARES Rope = BEGIN OPEN AMBridge, AMTypes, Basics, RTSymbolDefs, SafeStorage, RTTypesPrivate, RTTypesRemotePrivate, WorldVM; checkMutable: BOOL _ TRUE; IsRemote: PUBLIC PROC[tv: TypedVariable] RETURNS[BOOLEAN] = {WITH tv SELECT FROM tvr: REF TypedVariableRec => WITH tvh: tvr.head SELECT FROM remoteReference, remotePointer, remoteGFH, remoteFH, copiedRemoteObject, remoteConstant => IF GetRemoteWorld[tv] = WorldVM.LocalWorld[] THEN ERROR ELSE RETURN[TRUE]; ENDCASE => RETURN[FALSE]; ENDCASE => RETURN[FALSE]}; TVForRemoteReferent: PUBLIC PROC[remoteRef: RemoteRef, status: Status _ mutable] RETURNS[tv: TypedVariable] = { bitsForType: LONG CARDINAL; head: RTTypesPrivate.TypedVariableHead = [remoteReference[remoteRef: remoteRef]]; type: Type _ GetRemoteReferentType[remoteRef]; IF type = nullType THEN RETURN[NIL]; IF EquivalentTypes[type, CODE[AtomPrivate.AtomRec]] OR EquivalentTypes[type, CODE[Rope.RopeRep]] THEN ERROR Error[reason: typeFault, type: type]; bitsForType _ BitsForType[type].bft; IF bitsForType < bitsPerWord THEN tv _ NEW[TypedVariableRec _ [referentType: [type], head: head, status: status, field: embedded[fd: [wordOffset: 0, extent: small[field: [bitFirst: bitsPerWord-bitsForType, bitCount: bitsForType ] ] ] ] ] ] ELSE tv _ NEW[TypedVariableRec _ [referentType: [type], head: head, status: status, field: entire[]]]; }; RemoteRefFromTV: PUBLIC PROC[tv: TypedVariable] RETURNS[RemoteRef] = {WITH tv SELECT FROM tr: REF TypedVariableRec => {IF tr.tag # entire THEN ERROR Error[reason: internalTV] ELSE IF checkMutable AND tr.status # mutable THEN ERROR Error[reason: notMutable] ELSE WITH head: tr.head SELECT FROM remoteReference => RETURN[head.remoteRef]; ENDCASE => ERROR Error[reason: internalTV]}; ENDCASE => ERROR Error[reason: typeFault, type: nullType]}; TVForRemotePointerReferent: PUBLIC PROC[remotePointer: RemotePointer, type: Type, status: Status _ mutable] RETURNS[TypedVariable] = {bitsForType: LONG CARDINAL = BitsForType[type].bft; head: RTTypesPrivate.TypedVariableHead = [remotePointer[remotePointer: remotePointer]]; RETURN[ IF bitsForType < bitsPerWord THEN NEW[TypedVariableRec _ [referentType: [type], head: head, status: status, field: embedded[fd: [wordOffset: 0, extent: small[field: [bitFirst: bitsPerWord - bitsForType, bitCount: bitsForType]]]]]] ELSE NEW[TypedVariableRec _ [referentType: [type], head: head, status: status, field: entire[]]]]}; RemotePointerFromTV: PUBLIC PROC[tv: TypedVariable] RETURNS[RemotePointer] = {WITH tv SELECT FROM tr: REF TypedVariableRec => {IF checkMutable AND tr.status # mutable THEN ERROR Error[reason: notMutable]; WITH etr: tr SELECT FROM embedded => WITH fd: etr.fd SELECT FROM large => {rp: RemotePointer _ GetRemoteHeadPointer[tr]; rp.ptr _ rp.ptr + fd.wordOffset; RETURN[rp]}; small => IF fd.field.bitFirst = 0 THEN {rp: RemotePointer _ GetRemoteHeadPointer[tr]; rp.ptr _ rp.ptr + fd.wordOffset; RETURN[rp]} ELSE ERROR Error[reason: internalTV]; ENDCASE => ERROR; entire => RETURN[GetRemoteHeadPointer[tr]]; --may have been narrowed-- ENDCASE => ERROR} ENDCASE => ERROR Error[reason: typeFault, type: nullType]}; GetRemoteHeadPointer: PROC[tr: REF TypedVariableRec] RETURNS[RemotePointer] = {RETURN[(WITH head: tr.head SELECT FROM remotePointer => head.remotePointer, remoteGFH => [world: head.remoteGlobalFrameHandle.world, worldIncarnation: CurrentIncarnation[head.remoteGlobalFrameHandle.world], ptr: Long[world: head.remoteGlobalFrameHandle.world, addr: head.remoteGlobalFrameHandle.gfh]], remoteFH => [world: head.remoteFrameHandle.world, worldIncarnation: CurrentIncarnation[head.remoteFrameHandle.world], ptr: Long[world: head.remoteFrameHandle.world, addr: head.remoteFrameHandle.fh]] ENDCASE => ERROR Error[reason: typeFault, type: nullType])]}; TVForRemoteProc: PUBLIC PROC[remotePD: RemotePD] RETURNS[TypedVariable--procedure--] = {RETURN[TVForRemotePD[remotePD]]}; TVForRemotePD: PUBLIC PROC[remotePD: RemotePD] RETURNS[TypedVariable--procedure--] = {ws: WordSequence; ws _ NEW[WordSequenceRecord[1]]; ws[0] _ LOOPHOLE[remotePD.pd, CARDINAL]; RETURN[NEW[TypedVariableRec _ [referentType: [GetRemoteProcedureType[remotePD]], head: [remoteConstant [world: remotePD.world, worldIncarnation: CurrentIncarnation[remotePD.world]]], status: const, field: constant[value: ws]]]]}; TVForRemoteSignal: PUBLIC PROC[remoteSED: RemoteSED] RETURNS[TypedVariable--signal, error--] = {RETURN[TVForRemoteSED[remoteSED]]}; TVForRemoteSED: PUBLIC PROC[remoteSED: RemoteSED] RETURNS[TypedVariable--signal, error--] = {ws: WordSequence; ws _ NEW[WordSequenceRecord[1]]; ws[0] _ LOOPHOLE[remoteSED.sed, CARDINAL]; RETURN[NEW[TypedVariableRec _ [referentType: [GetRemoteSignalType[remoteSED]], head: [remoteConstant [world: remoteSED.world, worldIncarnation: CurrentIncarnation[remoteSED.world]]], status: const, field: constant[value: ws]]]]}; TVToRemoteProc: PUBLIC PROC[tv: TypedVariable--procedure, program--] RETURNS[RemotePD] = {RETURN[TVToRemotePD[tv]]}; TVToRemotePD: PUBLIC PROC[tv: TypedVariable--procedure, program--] RETURNS[RemotePD] = { SELECT TypeClass[UnderType[TVType[tv]]] FROM nil => RETURN[nilRemotePD]; program, procedure => NULL; ENDCASE => ERROR Error[reason: typeFault, type: TVType[tv]]; RETURN[[world: GetWorld[tv], worldIncarnation: CurrentIncarnation[GetWorld[tv]], pd: TVToCardinal[tv]]]}; TVToRemoteSignal: PUBLIC PROC[tv: TypedVariable] RETURNS[RemoteSED] = {RETURN[TVToRemoteSED[tv]]}; TVToRemoteSED: PUBLIC PROC[tv: TypedVariable] RETURNS[RemoteSED] = { SELECT TypeClass[UnderType[TVType[tv]]] FROM signal, error => NULL; nil => RETURN[nilRemoteSED]; ENDCASE => ERROR Error[reason: typeFault, type: TVType[tv]]; RETURN[[world: GetWorld[tv], worldIncarnation: CurrentIncarnation[GetWorld[tv]], sed: TVToCardinal[tv]]]}; TVForRemoteFrame: PUBLIC PROC[remoteFrameHandle: RemoteFrameHandle, evalStack: WordSequence _ NIL, return: BOOL _ FALSE, contextPC: BOOL _ FALSE] RETURNS[ans: TV _ NIL] = {bti: BodyIndex; isCatchFrame: BOOLEAN _ FALSE; IF remoteFrameHandle.fh = 0 THEN RETURN[NIL]; bti _ AcquireBTIFromRemoteFH[remoteFrameHandle, contextPC];-- returns BTNull if no symbols IF NOT RTSymbolOps.NullBTI[bti] THEN [isCatchFrame, bti] _ IsRemoteCatchFrame[remoteFrameHandle, bti]; RETURN[NEW[TypedVariableRec _ [referentType: [fhType], head: [remoteFH[remoteFrameHandle: remoteFrameHandle, evalStack: evalStack, bti: bti, isCatchFrame: isCatchFrame, return: return, contextPC: contextPC]], status: mutable, field: entire[]]]]}; RemoteFHFromTV: PUBLIC PROC[tv: TypedVariable] RETURNS[RemoteFrameHandle] = {WITH tv SELECT FROM tvr: REF TypedVariableRec => WITH tvh: tvr.head SELECT FROM remoteFH => RETURN[tvh.remoteFrameHandle]; ENDCASE => ERROR Error[reason: typeFault, type: fhType]; ENDCASE => ERROR Error[reason: typeFault, type: fhType]}; TVForRemoteGFHReferent: PUBLIC PROC[remoteGlobalFrameHandle: RemoteGlobalFrameHandle] RETURNS[TypedVariable] = { IF remoteGlobalFrameHandle.gfh = 0 THEN RETURN[NIL]; IF remoteGlobalFrameHandle.world = WorldVM.LocalWorld[] THEN RETURN[TVForGFHReferent[LOOPHOLE[remoteGlobalFrameHandle.gfh]]]; RETURN[NEW[TypedVariableRec _ [referentType: [gfhType], head: [remoteGFH[remoteGlobalFrameHandle: remoteGlobalFrameHandle]], status: mutable, field: entire[]]]]}; RemoteGFHFromTV: PUBLIC PROC[tv: TypedVariable] RETURNS[RemoteGlobalFrameHandle] = {WITH tv SELECT FROM tvr: REF TypedVariableRec => WITH tvh: tvr.head SELECT FROM remoteGFH => RETURN[tvh.remoteGlobalFrameHandle]; ENDCASE => ERROR Error[reason: typeFault, type: gfhType]; ENDCASE => ERROR Error[reason: typeFault, type: gfhType]}; GetRemoteWorld: PROC[tv: TypedVariable] RETURNS[World] = {WITH tv SELECT FROM tvr: REF TypedVariableRec => WITH tvh: tvr.head SELECT FROM remoteReference => RETURN[tvh.remoteRef.world]; remotePointer => RETURN[tvh.remotePointer.world]; remoteFH => RETURN[tvh.remoteFrameHandle.world]; remoteGFH => RETURN[tvh.remoteGlobalFrameHandle.world]; copiedRemoteObject => RETURN[tvh.world]; remoteConstant => RETURN[tvh.world]; ENDCASE => ERROR; ENDCASE => ERROR; }; GetWorld: PUBLIC PROC[tv: TypedVariable] RETURNS[World] = {IF IsRemote[tv] THEN RETURN[GetRemoteWorld[tv]] ELSE RETURN[LocalWorld[]]; }; GetWorldIncarnation: PUBLIC PROC[tv: TypedVariable] RETURNS[LONG CARDINAL] = {IF IsRemote[tv] THEN WITH tv SELECT FROM tvr: REF TypedVariableRec => WITH tvh: tvr.head SELECT FROM remoteReference => RETURN[tvh.remoteRef.worldIncarnation]; remotePointer => RETURN[tvh.remotePointer.worldIncarnation]; remoteFH => RETURN[tvh.remoteFrameHandle.worldIncarnation]; remoteGFH => RETURN[tvh.remoteGlobalFrameHandle.worldIncarnation]; copiedRemoteObject => RETURN[tvh.worldIncarnation]; remoteConstant => RETURN[tvh.worldIncarnation]; ENDCASE => ERROR; ENDCASE => ERROR ELSE RETURN[CurrentIncarnation[LocalWorld[]]]; }; TVToRemoteRef: PUBLIC PROC[tv: TypedVariable] RETURNS[RemoteRef] = { IF GetWorld[tv] = LocalWorld[] THEN ERROR Error[reason: typeFault, msg: "Can't get a remote REF for a local object"]; SELECT TypeClass[UnderType[TVType[tv]]] FROM atom, rope, list, ref => RETURN[[world: GetWorld[tv], worldIncarnation: GetWorldIncarnation[tv], ref: LOOPHOLE[TVToLC[tv], WorldVM.Address]]]; ENDCASE => ERROR Error[reason: typeFault, type: TVType[tv]]; }; END. ðRTTypesRemoteImpl.Mesa last modified on August 10, 1983 12:30 pm by Paul Rovner P R O C E D U R E S raises notMutable, internalTV, typeFault If possible, this returns the REF which points to the value represented by the specified TypedVariable. Raises InternalTV if tv is embedded, NotVar if TVStatus[tv] # mutable. If possible, RemotePointerFromTV returns the LONG POINTER which points to the value represented by the specified TypedVariable. Raises Error[reason: internalTV] if tv is embedded and not word aligned Raises NotVar if TVStatus[tv] # mutable. raises notMutable, internalTV, typeFault raises typeFault raises typeFault raises typeFault MOVE raises typeFault all such tvs have the same (distinguished) type: gfhType raises typeFault Ê Ý˜J˜Jšœ™Jšœ8™8J˜šÏk ˜ šœ œ;˜IJ˜6J˜;J˜—šœœI˜VJšœ˜—Jšœ œ ˜Jšœœ˜Jšœœ ˜Jšœ œ ˜Jšœ œ ˜Jšœ œ-˜>Jšœœ3˜Gšœœ/˜IJ˜,J˜—Jšœœ7˜DJ˜—šœ˜šœ=˜DJ˜—Jšœ ˜Jšœ˜ J˜—šœœœ6˜BJ˜.J˜—JšÏb œœœ˜J˜Jšœ™š Ïnœœœœœ˜;šœœœ˜šœœ˜šœœ˜J˜*˜,šœœ*˜/Jšœ˜ Jšœœœ˜——Jšœœœ˜——Jšœœœ˜J˜——šŸœœœ0˜PJšœ˜šœœœ˜"J˜QJ˜.J˜Jšœœœœ˜$J˜šœœ˜3Jšœœ˜,Jšœœ&˜0J˜—J˜$J˜šœ˜š˜šœœ˜˜J˜ J˜˜#˜8J˜J˜J˜—J˜J˜——J˜J˜——šœœ*˜7J˜ J˜J˜——J˜J˜——Jšœ(™(šŸœœœœ ˜Dšœœœ˜šœœ˜šœœ˜Jšœœ˜$šœœœ˜,Jšœœ˜$šœœœ˜#Jšœœ˜*Jšœœ˜,————Jšœœ+˜;˜JšœX™XJšœU™UJ˜J˜———šŸœœœ˜EJ˜ J˜Jšœ˜šœœœ˜4J˜Wšœ˜šœ˜š˜šœ˜˜J˜ J˜˜#˜:J˜—————šœœ*˜2J˜ J˜J˜J˜JšœF™FJšœ8™8JšœG™GJšœ(™(—————Jšœ(™(šŸœœœœ˜Lšœœœ˜šœœ˜š œœœœœ˜Nšœ œ˜˜ šœ œ˜˜7J˜ Jšœ˜ —šœ œ˜!šœ/˜3J˜ Jšœ˜ —Jšœœ˜%—Jšœœ˜——Jšœ œÏc˜IJšœœ˜———Jšœœ+˜;J˜——Jšœ™šŸœœœœ˜Mšœœœœ˜'J˜$˜8˜J˜7—˜4J˜)——˜1˜J˜1—˜.J˜!——Jšœœ-˜=J˜——š Ÿœœœœ  œ˜VJšœœ˜"J˜—š Ÿ œœœœ  œ˜T˜Jšœœ˜ šœœœ˜(šœœF˜P˜˜˜J˜%——J˜J˜J˜—————šŸœœœ˜4Jšœ œœ˜NJ˜—šŸœœœ˜1Jšœ œ˜)˜Jšœœ˜ šœœœ˜*šœœD˜N˜˜˜J˜&———J˜J˜J˜J˜————Jšœ™šŸœœœ œ˜DJšœœ˜/J˜—šŸ œœœ œ˜BJšœ ˜šœœ"˜.Jšœœ˜Jšœœ˜Jšœœ,˜<šœ˜J˜3J˜J˜———Jšœ™šŸœœœœ ˜EJšœœ˜J˜—šŸ œœœœ ˜Bšœœ"˜.Jšœœ˜Jšœœ˜Jšœœ,˜<šœ˜J˜3J˜J˜—Jšœ™——šŸœœœ&˜CJšœœ˜Jšœœœ˜Jšœ œœ˜Jšœœœ˜˜Jšœœœ˜Jšœœœœ˜-Jšœ; ˜Zšœœ˜JšœB˜F—šœœ˜˜˜5J˜J˜ J˜J˜J˜—J˜J˜J˜————Jšœ™šŸœœœœ˜Kšœœœ˜šœœ˜šœœ˜Jšœ œ˜*Jšœœ(˜8——Jšœœ)˜9˜Jšœ8™8———šŸœœœ2˜UJšœ˜š œœ!œœœ˜6šœ5˜7Jšœœœ ˜E—šœœ˜˜J˜DJ˜J˜J˜————Jšœ™šŸœœœœ˜Ršœœœ˜šœœ˜šœœ˜Jšœ œ˜1Jšœœ)˜9——Jšœœ*˜:J˜——šŸœœœ ˜8šœœœ˜šœœ˜šœœ˜Jšœœ˜/Jšœœ˜1Jšœ œ˜0Jšœ œ$˜7Jšœœ ˜(Jšœœ ˜$Jšœœ˜——Jšœœ˜——J˜J˜šŸœœœœ ˜9šœœ ˜Jšœœ˜Jšœœ˜J˜J˜——š Ÿœœœœœœ˜Lšœœ ˜š˜šœœ˜šœœ˜šœœ˜Jšœœ!˜:Jšœœ%˜