-- AMBridge.Mesa
-- last modified on December 17, 1982 8:34 am by Paul Rovner

DIRECTORY
AMTypes USING[Status],
PrincOps USING[FrameHandle, GlobalFrameHandle, BytePC, StateVector],
Rope USING[ROPE],
RTBasic USING[TV, Type],
WorldVM USING[World, Address, ShortAddress];

AMBridge: DEFINITIONS

= BEGIN OPEN AMTypes, PrincOps, Rope, RTBasic, WorldVM;

-- T Y P E S, C O N S T A N T S

RemoteRef: TYPE = RECORD
[world: World ← ,
worldIncarnation: LONG CARDINAL,
ref: WorldVM.Address];
nilRemoteRef: RemoteRef
= [world: NIL, ref: 0, worldIncarnation: 0];

RemotePointer: TYPE = RECORD
[world: World ← ,
worldIncarnation: LONG CARDINAL,
ptr: WorldVM.Address];
nilRemotePointer: RemotePointer
= [world: NIL, ptr: 0, worldIncarnation: 0];

RemoteFrameHandle: TYPE = RECORD
[world: World ← ,
worldIncarnation: LONG CARDINAL,
fh: WorldVM.ShortAddress];
nilRemoteFrameHandle: RemoteFrameHandle
= [world: NIL, fh: 0, worldIncarnation: 0];

RemoteGlobalFrameHandle: TYPE = RECORD
[world: World ← ,
worldIncarnation: LONG CARDINAL,
gfh: WorldVM.ShortAddress];
nilRemoteGlobalFrameHandle: RemoteGlobalFrameHandle
= [world: NIL, gfh: 0, worldIncarnation: 0];

RemotePD: TYPE = RECORD
[world: World ← ,
worldIncarnation: LONG CARDINAL,
pd: UNSPECIFIED];
nilRemotePD: RemotePD
= [world: NIL, pd: 0, worldIncarnation: 0];

RemoteSED: TYPE = RECORD
[world: World ← ,
worldIncarnation: LONG CARDINAL,
sed: UNSPECIFIED];
nilRemoteSED: RemoteSED
= [world: NIL, sed: 0, worldIncarnation: 0];


-- P R O C E D U R E S

-- (1) Access to World information for a TV.

IsRemote: PROC[tv: TV] RETURNS[BOOLEAN];

GetWorld: PROC[tv: TV] RETURNS[World];

GetWorldIncarnation: PROC[tv: TV] RETURNS[LONG CARDINAL];


-- (2) Mappings between TVs, REFs and RemoteRefs.

TVForReferent: PROC[ref: REF ANY, status: Status ← mutable] RETURNS[TV];

TVForRemoteReferent: PROC[remoteRef: RemoteRef, status: Status ← mutable] RETURNS[TV];

RefFromTV: PROC[tv: TV] RETURNS[REF ANY];
-- If possible, this returns the REF which points to the value represented by the specified
-- TV. Raises InternalTV if tv is embedded, NotVar if TVStatus[tv] # mutable.

RemoteRefFromTV: PROC[tv: TV] RETURNS[RemoteRef];
-- If possible, this returns the REF which points to the value represented
-- by the specified TV. Raises InternalTV if tv is embedded,
-- NotVar if TVStatus[tv] # mutable.

SomeRefFromTV: PROC[tv: TV] RETURNS[REF ANY];
-- Like RefFromTV, but copies instead of raising an error.

TVForReadOnlyReferent: PROC[ref: REF READONLY ANY] RETURNS[TV];

ReadOnlyRefFromTV: PROC[tv: TV -- status: readOnly--] RETURNS[REF READONLY ANY];


-- (3) Mappings between TVs and pointers.

TVForPointerReferent:
PROC[ptr: LONG POINTER, type: Type, status: Status ← mutable] RETURNS[TV];

TVForRemotePointerReferent: PROC[remotePointer: RemotePointer,
type: Type,
status: Status ← mutable]
RETURNS[TV];

PointerFromTV: PROC[tv: TV] RETURNS[LONG POINTER];
-- If possible, this returns the LONG POINTER which points to
-- the value represented by the specified TV.
-- Raises InternalTV if tv is embedded and not word aligned
-- Raises NotVar if TVStatus[tv] # mutable.

RemotePointerFromTV: PROC[tv: TV] RETURNS[RemotePointer];
-- If possible, this returns the LONG POINTER which points to the value
-- represented by the specified TV.
-- Raises MalformedTV if tv is a REF or a REF's component
-- Raises InternalTV if tv is embedded and not word aligned
-- Raises NotVar if TVStatus[tv] # mutable.


-- (4) Mappings between TVs and transfer descriptors.

TVForProc: PROC[proc: PROC ANY RETURNS ANY] RETURNS[TV--procedure--];

TVForRemoteProc: PROC[remotePD: RemotePD] RETURNS[TV--procedure--];

TVToProc: PROC[tv: TV--procedure, program--] RETURNS[PROC ANY RETURNS ANY];

TVToRemoteProc: PROC[tv: TV--procedure, program--] RETURNS[RemotePD];

TVForSignal: PROC[signal: ERROR ANY RETURNS ANY] RETURNS[TV--signal, error--];

TVForRemoteSignal: PROC[remoteSED: RemoteSED] RETURNS[TV--signal, error--];

TVToSignal: PROC[tv: TV] RETURNS[ERROR ANY RETURNS ANY];

TVToRemoteSignal: PROC[tv: TV] RETURNS[RemoteSED];


-- (5) Mappings between TVs and frame goodies.

-- "return" is TRUE iff the next instruction would be RET
-- ContextPC will subtract one from the fh.pc if NOT contextPC
-- ContinuationPC will ignore contextPC and always return fh.pc
TVForFrame: PROC[fh: FrameHandle,
evalStack: POINTER TO PrincOps.StateVector ← NIL,
return: BOOLFALSE,
contextPC: BOOLFALSE]
RETURNS[TV];
-- all such tvs have the same (distinguished) type: fhType

TVForRemoteFrame: PROC[remoteFrameHandle: RemoteFrameHandle,
evalStack: WordSequence ← NIL,
return: BOOLFALSE,
contextPC: BOOLFALSE]
RETURNS[TV];
-- all such tvs have the same (distinguished) type: fhType

FHFromTV: PROC[tv: TV] RETURNS[FrameHandle];

RemoteFHFromTV: PROC[tv: TV] RETURNS[RemoteFrameHandle];

ContextPC: PROC[tv: TV--localFrame--] RETURNS[PrincOps.BytePC];

TVForGFHReferent: PROC[gfh: GlobalFrameHandle] RETURNS[TV];
-- all such tvs have the same (distinguished) type: gfhType

TVForRemoteGFHReferent: PROC[remoteGlobalFrameHandle: RemoteGlobalFrameHandle]
RETURNS[TV];
-- all such tvs have the same (distinguished) type: gfhType

GFHFromTV: PROC[tv: TV] RETURNS[GlobalFrameHandle];

RemoteGFHFromTV: PROC[tv: TV] RETURNS[RemoteGlobalFrameHandle];

IsStarted: PROC[tv: TV--globalFrame--] RETURNS[BOOL];

IsCopied: PROC[tv: TV--globalFrame--] RETURNS[BOOL];


-- (6) Mappings between TVs and ATOMs, ROPEs.

TVForATOM: PROC[atom: ATOM] RETURNS[TV--atom--];

TVToATOM: PROC[tv: TV--atom--] RETURNS[ATOM];

TVForROPE: PROC[rope: ROPE] RETURNS[TV--rope--];
-- use TVToName to get the ROPE back


-- (7) ENGINE ROOM PROPER procs. See me (Paul Rovner) if you use this stuff.

TVToLC: PROC[tv: TV] RETURNS[LONG CARDINAL];
-- Raises TypeFault if the field is bigger than 32 bits, else PUNs its value
-- (right justified, zero filled) into a LONG CARDINAL.
TVToInteger: PROC[tv: TV] RETURNS[INTEGER]; -- raises RangeFault
TVToLI: PROC[tv: TV] RETURNS[LONG INTEGER];
TVToCardinal: PROC[tv: TV] RETURNS[CARDINAL]; -- raises RangeFault
TVToCharacter: PROC[tv: TV] RETURNS[CHARACTER]; -- raises RangeFault
TVToReal: PROC[tv: TV] RETURNS[REAL];
TVToRef: PROC[tv: TV] RETURNS[REF ANY];
TVToRemoteRef: PROC[tv: TV] RETURNS[RemoteRef];

-- For use by Wizards. BEWARE.
SetTVFromLC: PROC[tv: TV, lc: LONG CARDINAL];
-- Raises TypeFault if the tv type is not basic, enumeration or subrange
-- else PUNs lc into TVType[tv] and assigns it to the field specified by tv.
SetTVFromLI: PROC[tv: TV, li: LONG INTEGER];

Loophole: PROC[tv: TV, type: Type, tag: TVNIL] RETURNS[TV]; -- Shudder.

OctalRead: PROC[tv: TV, offset: INT] RETURNS[CARDINAL];

-- escape hatch. If you need this, chances are good you're doing something wrong
TVToWordSequence: PROC[tv: TV] RETURNS [s: WordSequence];
-- TVToWordSequence copies the tv
WordSequence: TYPE = REF WordSequenceRecord;
WordSequenceRecord: TYPE = RECORD[s: SEQUENCE size: NAT OF WORD];

-- escape hatch. If you need this, chances are good you're doing something wrong
TVHead: PROC[tv: TV] RETURNS[TVHeadType];
TVHeadType: TYPE = {constant, remoteConstant, reference, remoteReference,
copiedRemoteObject, pointer, remotePointer, gfh,
remoteGFH, fh, remoteFH, notTVRecord};

END.