-- File [Ivy]<Nelson>Lupine>LupineMarshal.mesa.
-- Last edited by BZM on 10-Mar-82 16:56:13.

-- LupineMarshal is exported by LupineMarshal*Impl.


DIRECTORY
  LupineDeclare USING [
	PktSite, TransferDeclaration, TransferSite ],
  LupineManagerPrivate USING [
	Nest, Options, ParamPassingMethod, String ],
  LupineSymbolTable USING [
	Index, SymbolHandle, TransferTypes, TypeHandle, Types ];


LupineMarshal: DEFINITIONS =
  BEGIN OPEN Declare: LupineDeclare, LupineManagerPrivate, ST: LupineSymbolTable;


-- Word and character counts.

  Words: TYPE = LONG INTEGER;
  Chars: TYPE = --LONG INTEGER-- CARDINAL;


-- These parameter protocol versions are checked during remote binding:

  Version: TYPE = CARDINAL;

  ParameterProtocolVersions: PROCEDURE
    RETURNS [oldestSupported, newestSupported: Version];


-- These routines pull together information needed for marshaling:

  ParamInfo: TYPE = LONG POINTER TO --READONLY-- ParamInfoObject;
  ParamInfoNIL: ParamInfo = NIL;

  TransferDeclaration: TYPE = Declare.TransferDeclaration;
  TransferSite: TYPE = Declare.TransferSite;
  PktSite: TYPE = Declare.PktSite;

  ParamIndex: TYPE = ST.Index[0..256);  -- Origin is 1.
  ParamRecordKind: TYPE = {argument, result};
  ParamLocation: TYPE = {
    inFrame, inPktOverlay, inFrameAndOverlay, inConversation, inStream };
  OverlayParamType: TYPE = {static, address, other --must be last--};
  
  ParamInfoObject: TYPE = RECORD [
	paramRecord: ST.TypeHandle,
	paramRecordKind: ParamRecordKind,
	pktSite: PktSite, 
	transferType: ST.TransferTypes,
	transferDeclaration: TransferDeclaration,
	transferSite: TransferSite,
	options: Options, 
	alwaysOnePkt, alwaysMultiplePkts: BOOLEAN,
	hasOverlayParams, hasConversation: BOOLEAN,
	hasOverlayParamType: PACKED ARRAY OverlayParamType OF BOOLEAN,
	adrInfo: AddressInfo,
	allocInfo: AllocInfo,
	sizeOf: SizeInfo,
	paramCount: ParamIndex,  -- Of explicit parameters only.
	RESULTCount: ParamIndex,  -- Already included in paramCount.
	RESULTsParamInfo: PRIVATE ParamInfo,
	fields: PRIVATE SEQUENCE boundsCheck: ParamIndex OF FieldInfo ];

  AddressInfo: TYPE = RECORD [
	isStatic, isAddress, isDynamic, isTransfer: BOOLEAN←FALSE,
	hasStatics, hasAddresses, hasDynamics, hasTransfers: BOOLEAN←FALSE,
	hasGC, hasHeap, hasMds: BOOLEAN←FALSE,
	hasShortPtrs: BOOLEAN←FALSE ];

  FalseAddressInfo: AddressInfo = [];

  SizeInfo: TYPE = RECORD [
	overlayHeader: Words←0,
	overlayParamRecord: Words←0,
	pktToAllocate: Words←0 ];

  ZeroSizeInfo: SizeInfo = [];

  AllocZone: TYPE = {gc, heap, mds};
  AllocDetails: TYPE = RECORD [
	number: INTEGER ← 0,
	isDynamic: BOOLEAN ← FALSE ];
  AllocInfo: TYPE = PACKED ARRAY AllocZone OF AllocDetails;

  NoAllocations: AllocInfo = [];

  FieldInfo: TYPE = RECORD [
	type: ST.Types,
	passingMethod: ParamPassingMethod,
	location: ParamLocation,
	overlayParamType: OverlayParamType,
	adrInfo: AddressInfo,
	allocInfo: AllocInfo,
	size: Words,
	minFlatSize, maxFlatSize: Words ];


  MakeParamInfo: PROCEDURE [
	paramRecord: ST.TypeHandle,
	paramRecordKind: ParamRecordKind,
	pktSite: PktSite,
	RESULTsParamInfo: ParamInfo←ParamInfoNIL,
	  -- Must be NIL for argument records, nonNIL for results.
	transferType: ST.TransferTypes,
	transferDeclaration: TransferDeclaration,
	transferSite: TransferSite,
	options: Options ] 
    RETURNS[paramInfo: ParamInfo];

  FreeParamInfo: PROCEDURE [paramInfo: ParamInfo];


  ParamProcedure: TYPE = PROCEDURE [
	paramName: ST.SymbolHandle,
	paramType: ST.TypeHandle,
	paramIndex: ParamIndex,
	paramFieldInfo: FieldInfo ] 
    RETURNS[stop: BOOLEAN←FALSE];

  EnumerateParams: PROCEDURE [
	paramInfo: ParamInfo,
	paramProc: ParamProcedure,
	includeRESULTs: BOOLEAN←FALSE ]; 


-- These routines actually generate marshaling code:


  OverlayHandling: TYPE = PACKED ARRAY OverlayParamType OF OverlayOperation;

  OverlayOperation: TYPE = {
   -- Marshal.ToPacket operations:
	alreadyInPkt, copyToPkt,
   -- Marshal.FromPacket operations:
	leaveInPkt, copyToFrame, justCopyToFrame,
   -- Illegal operation:
	error } ← error;

  VariableNames: TYPE = RECORD [
	pkt, overlayPtr, pktLength, pktLimit, lastPkt: String ];


  ToPacket: PROCEDURE [
	paramInfo: ParamInfo,
	overlayHandling: OverlayHandling,
	varNames: VariableNames,
	nest: Nest ];

  FromPacket: PROCEDURE [
	paramInfo: ParamInfo,
	overlayHandling: OverlayHandling,
	varNames: VariableNames,
	nest: Nest ];

 
  BeginAllocation: PROCEDURE [
	paramInfo: ParamInfo,
	nest: Nest ]
    RETURNS [newNest: Nest];

  EndAllocation: PROCEDURE [
	paramInfo: ParamInfo,
	justCloseBlocks: BOOLEAN←FALSE,
	nest: Nest ]
    RETURNS [newNest: Nest];


  END.  -- LupineMarshal.