DIRECTORY IO USING [PutFR], LupineDeclare USING [ ParameterName, WriteParameterName, WriteTypeName ], LupineManagerPrivate USING [ Indent, Nest, Options, ParamPassingMethod, String, StringNIL, WF1, WFS, WFS1, WFSL, WFL, WFL1, WFLL ], LupineMarshal USING [ FieldInfo, ParamIndex, ParamInfo, ParamProcedure, ParamRecordKind, OverlayHandling, OverlayParamType, VariableNames, Version ], LupineMarshalPrivate USING [ ContainsEmbeddedPtrs, CopyCharacters, CopyOne, CopyTwo, CopyType, CopyUninterpreted, Direction, EnumerateFrameParams, EnumerateOverlayParams, Error, IsExplicitHandle, IsShortString, MarshalInfo, MarshalInfoObject, MarshalArray, MarshalDescriptor, MarshalList, MarshalPointer, MarshalRecord, MarshalRef, MarshalSequence, MarshalTransfer,MarshalVariantPart, OperationProc, ParentInfo, ParentInfoNull, Passing, SubStrings, WriteNEW ], LupineSymbolTable USING [GetTypeInfo, TypeHandle, TypeInfo, Types], Rope USING [ROPE]; LupineMarshalTypeManagerImpl: PROGRAM IMPORTS IO, Declare: LupineDeclare, LupineManagerPrivate, Private: LupineMarshalPrivate, ST: LupineSymbolTable EXPORTS LupineMarshal, LupineMarshalPrivate SHARES LupineManagerPrivate = BEGIN OPEN LupineManagerPrivate, LupineMarshal; ParentInfo: TYPE = Private.ParentInfo; MarshalInfo: TYPE = Private.MarshalInfo; ParameterProtocolVersions: PUBLIC PROCEDURE RETURNS [oldestSupported, newestSupported: Version] = {RETURN [ oldestSupported: 1, newestSupported: 1 ]}; ToPacket: PUBLIC PROCEDURE [ paramInfo: ParamInfo, overlayHandling: OverlayHandling, varNames: VariableNames, nest: Nest, options: Options ] = BEGIN overlayNeedsMoving: BOOLEAN _ FALSE; construct: BOOLEAN _ TRUE; -- Assign, not construct, when FALSE. FOR overlayType: OverlayParamType IN [FIRST[OverlayParamType]..PRED[LAST[OverlayParamType]]] DO IF paramInfo.hasOverlayParamType[overlayType] THEN SELECT overlayHandling[overlayType] FROM copyToPkt => overlayNeedsMoving _ TRUE; ENDCASE => construct _ FALSE; ENDLOOP; IF overlayNeedsMoving THEN BEGIN -- Move some overlay params from local frame to pkt. printedOne: BOOLEAN _ FALSE; MoveOverlayParam: ParamProcedure = BEGIN SELECT overlayHandling[paramFieldInfo.overlayParamType] FROM alreadyInPkt => NULL; copyToPkt => BEGIN IF construct THEN {IF printedOne THEN WFS1[", "--L--] ELSE printedOne _ TRUE} ELSE WFS[Indent[nest], varNames.overlayPtr, "."--L--]; Declare.WriteParameterName[paramName, paramIndex]; WFS1[IF construct THEN ": "--L-- ELSE " _ "--L--]; Declare.WriteParameterName[paramName, paramIndex]; IF ~construct THEN WFS1[";\n"--L--]; END; ENDCASE => ERROR; END; -- MoveOverlayParam. IF construct THEN WFS[Indent[nest], varNames.overlayPtr, "^ _ ["--L--]; Private.EnumerateOverlayParams[paramInfo, MoveOverlayParam]; IF construct THEN WFS1["];\n"--L--]; END; -- Move the overlay params. BEGIN -- Move remaining nonoverlay params from local frame to pkt. marshalInfoObject: Private.MarshalInfoObject _ [ paramInfo: paramInfo, paramFieldInfo: NULL, varNames: varNames, direction: toPkt ]; marshalInfo: MarshalInfo = @marshalInfoObject; MarshalFrameParam: ParamProcedure = BEGIN marshalInfo.paramFieldInfo _ paramFieldInfo; MarshalType[ nest: nest, name: Declare.ParameterName[paramName, paramIndex], type: paramType, parentInfo: Private.ParentInfoNull, marshalInfo: marshalInfo, options: options ]; END; -- MarshalFrameParam. Private.EnumerateFrameParams[paramInfo, MarshalFrameParam]; END; -- Move the remaining nonoverlay params. END; FromPacket: PUBLIC PROCEDURE [ paramInfo: ParamInfo, overlayHandling: OverlayHandling, varNames: VariableNames, nest: Nest, options: Options ] = BEGIN overlayNeedsMoving: BOOLEAN _ FALSE; FOR overlayType: OverlayParamType IN OverlayParamType DO IF paramInfo.hasOverlayParamType[overlayType] AND overlayHandling[overlayType] IN [copyToFrame..justCopyToFrame] THEN {overlayNeedsMoving _ TRUE; EXIT}; ENDLOOP; IF overlayNeedsMoving THEN BEGIN -- Move some overlay params from pkt to local frame. printedOne: BOOLEAN _ FALSE; ExtractOverlayParam: ParamProcedure = BEGIN SELECT overlayHandling[paramFieldInfo.overlayParamType] FROM leaveInPkt => NULL; copyToFrame, justCopyToFrame => BEGIN IF printedOne THEN WFS1[", "--L--] ELSE printedOne _ TRUE; Declare.WriteParameterName[paramName, paramIndex]; WFS1[": "--L--]; Declare.WriteParameterName[paramName, paramIndex]; END; ENDCASE => ERROR; END; -- ExtractOverlayParam. WFS[Indent[nest], "["--L--]; Private.EnumerateOverlayParams[paramInfo, ExtractOverlayParam]; WFS["] _ "--L--, varNames.overlayPtr, "^;\n"--L--]; END; -- Move the overlay params. FOR overlayType: OverlayParamType IN OverlayParamType DO IF overlayHandling[overlayType] = justCopyToFrame THEN RETURN; ENDLOOP; BEGIN -- Move remaining nonoverlay params from local frame to pkt. marshalInfoObject: Private.MarshalInfoObject _ [ paramInfo: paramInfo, paramFieldInfo: NULL, varNames: varNames, direction: fromPkt ]; marshalInfo: MarshalInfo = @marshalInfoObject; MarshalFrameParam: ParamProcedure = BEGIN marshalInfo.paramFieldInfo _ paramFieldInfo; MarshalType[ nest: nest, name: Declare.ParameterName[paramName, paramIndex], type: paramType, parentInfo: Private.ParentInfoNull, marshalInfo: marshalInfo, options: options ]; END; -- MarshalFrameParam. Private.EnumerateFrameParams[paramInfo, MarshalFrameParam]; END; -- Move the remaining nonoverlay params. BEGIN -- Check that the correct amount of pkt.data was unmarshaled. HasInFrameParams: PROC [paramInfo: ParamInfo] RETURNS [BOOLEAN] = INLINE {RETURN[ paramInfo.adrInfo.hasAddresses OR paramInfo.adrInfo.hasDynamics OR ~paramInfo.alwaysOnePkt ]}; WFSL[Indent[nest], "Lupine.CheckPktLength[pkt: ", varNames.pkt, ", pktLength: "]; IF HasInFrameParams[paramInfo] THEN WFS1[varNames.pktLength] ELSE WF1["%g", [integer[paramInfo.sizeOf.overlayParamRecord]]]; WFS1["];\n"]; END; END; OperationInfo: TYPE = RECORD [ canMarshal: BOOLEAN _ TRUE, newBlock: BOOLEAN _ TRUE] _ []; MarshalOpInfo: PACKED ARRAY ST.Types OF OperationInfo = [ Pointer: [newBlock: TRUE], Ref: [newBlock: TRUE], List: [newBlock: TRUE], Descriptor: [newBlock: TRUE], Null: [newBlock: FALSE], Basic: [newBlock: FALSE], Transfer: [newBlock: FALSE], VariantPart: [newBlock: FALSE], RelativePtr: [newBlock: FALSE], Zone: [newBlock: FALSE], Opaque: [newBlock: FALSE], Definition: [canMarshal: FALSE, newBlock: FALSE], Any: [canMarshal: FALSE, newBlock: FALSE], Other: [canMarshal: FALSE, newBlock: FALSE] ]; MarshalType: PUBLIC Private.OperationProc = { Explain: ARRAY {verb, adverb} OF ARRAY Private.Direction OF String = [ verb: [toPkt: "Marshal"--L--, fromPkt: "Unmarshal"--L--], adverb: [toPkt: "to"--L--, fromPkt: "from"--L--] ]; typeInfo: ST.TypeInfo = ST.GetTypeInfo[type: type]; passingMethod: ParamPassingMethod = marshalInfo.paramFieldInfo.passingMethod; newBlock: BOOL _ MarshalOpInfo[typeInfo.type].newBlock; marshalInfo.depth _ marshalInfo.depth + 1; IF newBlock THEN { WFSL[ Indent[nest], "BEGIN -- "--L--, Explain[verb][marshalInfo.direction], " "--L--, name, ": "--L-- ]; Declare.WriteTypeName[type]; WFSL[ " "--L--, Explain[adverb][marshalInfo.direction], " "--L--, marshalInfo.varNames.pkt, ".data["--L--, marshalInfo.varNames.pktLength, "].\n"--L-- ]; nest _ nest + 1; }; IF MarshalOpInfo[typeInfo.type].canMarshal THEN SELECT passingMethod FROM Handle, InterMds => { IF marshalInfo.depth # 1 THEN ERROR; Private.CopyUninterpreted[ nest: nest, variableName: name, variableInfo: typeInfo, parentInfo: parentInfo, marshalInfo: marshalInfo ]; }; Var, Value, Result => SELECT TRUE FROM (passingMethod = Result OR passingMethod = Var) AND Private.ContainsEmbeddedPtrs[type] => Private.Error[code: EmbeddedRESULT, type: type]; Private.IsExplicitHandle[typeInfo] => Private.CopyUninterpreted[ nest: nest, variableName: name, variableInfo: typeInfo, parentInfo: parentInfo, marshalInfo: marshalInfo ]; ENDCASE => { marshalName: String = StartReadonly[ nest: nest, name: name, typeInfo: typeInfo, marshalInfo: marshalInfo ]; WITH typeInfo: typeInfo SELECT FROM Null, Basic, RelativePtr, Opaque => Private.CopyType[ nest: nest, variableName: marshalName, variableInfo: typeInfo, parentInfo: parentInfo, marshalInfo: marshalInfo ]; Transfer => Private.MarshalTransfer[ marshalName, typeInfo, parentInfo, marshalInfo, nest, options]; Record => Private.MarshalRecord[ marshalName, typeInfo, parentInfo, marshalInfo, nest, options]; VariantPart => Private.MarshalVariantPart[ marshalName, typeInfo, parentInfo, marshalInfo, nest, options]; Pointer => Private.MarshalPointer[ marshalName, typeInfo, parentInfo, marshalInfo, nest, options]; Ref => Private.MarshalRef[ marshalName, typeInfo, parentInfo, marshalInfo, nest, options]; List => Private.MarshalList[ marshalName, typeInfo, parentInfo, marshalInfo, nest, options]; String => MarshalString[ marshalName, typeInfo, parentInfo, marshalInfo, nest, options]; Rope => MarshalRope[ marshalName, typeInfo, parentInfo, marshalInfo, nest]; Atom => MarshalAtom[ marshalName, typeInfo, parentInfo, marshalInfo, nest]; StringBody => MarshalStringBody[ marshalName, typeInfo, parentInfo, marshalInfo, nest, options]; Text => MarshalText[ marshalName, typeInfo, parentInfo, marshalInfo, nest, options]; Array => Private.MarshalArray[ marshalName, typeInfo, parentInfo, marshalInfo, nest, options]; Descriptor => Private.MarshalDescriptor[ marshalName, typeInfo, parentInfo, marshalInfo, nest, options]; Sequence => Private.MarshalSequence[ marshalName, typeInfo, parentInfo, marshalInfo, nest, options]; Zone => -- Zones must be handles. Private.Error[code: ImproperPassingMethod, type: type]; Definition, Any, Other => ERROR; -- Unimplemented marshalings should be caught above. ENDCASE => ERROR; StopReadonly[ nest: nest, name: name, typeInfo: typeInfo, marshalName: marshalName, marshalInfo: marshalInfo ]; }; ENDCASE => ERROR ELSE Private.Error[code: UnimplementedMarshaling, type: type]; IF newBlock THEN WFLL[nest, "END; -- "--L--, Explain[verb][marshalInfo.direction], " "--L--, name, "."--L-- ]; marshalInfo.depth _ marshalInfo.depth - 1; }; MarshalString: PROCEDURE [ name: String, stringInfo: String ST.TypeInfo, parentInfo: ParentInfo, marshalInfo: MarshalInfo, nest: Nest, options: Options ] = INLINE BEGIN MarshalStringTypes[ nest: nest, stringInfo: stringInfo, parentInfo: [name, stringInfo], marshalInfo: marshalInfo, options: options ]; END; MarshalStringBody: PROCEDURE [ name: String, stringBodyInfo: StringBody ST.TypeInfo, parentInfo: ParentInfo, marshalInfo: MarshalInfo, nest: Nest, options: Options ] = INLINE BEGIN MarshalStringTypes[ nest: nest, stringInfo: stringBodyInfo, parentInfo: parentInfo, marshalInfo: marshalInfo, options: options ]; END; MarshalText: PROCEDURE [ name: String, textInfo: Text ST.TypeInfo, parentInfo: ParentInfo, marshalInfo: MarshalInfo, nest: Nest, options: Options ] = INLINE BEGIN MarshalStringTypes[ nest: nest, stringInfo: textInfo, parentInfo: parentInfo, marshalInfo: marshalInfo, options: options ]; END; MarshalStringTypes: PROCEDURE [ stringInfo: ST.TypeInfo, parentInfo: ParentInfo, marshalInfo: MarshalInfo, options: Options, nest: Nest ] = BEGIN DotMaxLength: String = SELECT stringInfo.type FROM String, StringBody => ".maxlength", Text => ".maxLength", ENDCASE => ERROR; TextBase: Private.SubStrings = SELECT stringInfo.type FROM String, StringBody => ["BASE[", parentInfo.name, ".text]"], Text => ["BASE[DESCRIPTOR[", parentInfo.name, ".text]]"], ENDCASE => ERROR; VerifyPassingMethods[all: TRUE, marshalInfo: marshalInfo]; SELECT parentInfo.typeInfo.type FROM String, Pointer, Ref => NULL; ENDCASE => ERROR; SELECT marshalInfo.direction FROM toPkt => BEGIN Private.CopyOne[ nest: nest, wordsNeeded: 3, value: [parentInfo.name, "=NIL"], marshalInfo: marshalInfo ]; WFL[nest, "IF ", parentInfo.name, " # NIL"]; WFL1[nest+1, "THEN BEGIN"]; WFL1[nest+2, "stringHeader: Lupine.StringHeader = ["]; WFLL[nest+3, "Lengths[length: ", parentInfo.name, ".length, maxLength: ", parentInfo.name, DotMaxLength, "]];" ]; IF Private.IsShortString[stringInfo.self] THEN BEGIN WFL[nest+2, "IF stringHeader.length > RpcPrivate.maxShortStringLength"]; WFL1[nest+3, "THEN Lupine.MarshalingError;"]; END; Private.CopyTwo[ nest: nest+2, wordsNeeded: 0, value: ["stringHeader.all"], marshalInfo: marshalInfo ]; IF Private.Passing[Result, argument, marshalInfo] THEN WFL1[nest+2, "NULL; -- Call by result, send header only."] ELSE Private.CopyCharacters[ nest: nest+2, textName: TextBase, numCharsName: "stringHeader.length", marshalInfo: marshalInfo ]; WFL[nest+2, "END; -- IF ", parentInfo.name, " # NIL."]; END; fromPkt => BEGIN WFL1[nest, "stringIsNIL: Lupine.NilHeader;"]; Private.CopyOne[ nest: nest, wordsNeeded: 3, value: ["stringIsNIL"], marshalInfo: marshalInfo ]; IF Private.Passing[Result, result, marshalInfo] OR Private.Passing[Var,result,marshalInfo] THEN WFL[nest, "IF stringIsNIL # (", parentInfo.name, "=NIL) THEN Lupine.UnmarshalingError;"]; WFL1[nest, "IF stringIsNIL"]; WFL[nest+1, "THEN ", parentInfo.name, " _ NIL"]; WFL1[nest+1, "ELSE BEGIN"]; WFL1[nest+2, "stringHeader: Lupine.StringHeader;"]; Private.CopyTwo[ nest: nest+2, wordsNeeded: 0, value: ["stringHeader.all"], marshalInfo: marshalInfo ]; IF Private.IsShortString[stringInfo.self] THEN BEGIN WFL[nest+2, "IF stringHeader.length > RpcPrivate.maxShortStringLength"]; WFL1[nest+3, "THEN Lupine.UnmarshalingError;"]; END; IF Private.Passing[Result, result, marshalInfo] OR Private.Passing[Var,result,marshalInfo] THEN BEGIN WFLL[nest+2, "IF stringHeader.maxLength # ", parentInfo.name, DotMaxLength, " THEN Lupine.UnmarshalingError;" ]; WFL1[nest+2, "NULL; -- Call by var or result, use existing string."]; END ELSE BEGIN WFS[Indent[nest+2], parentInfo.name, " _ ("]; [] _ Private.WriteNEW[ptrInfo: parentInfo.typeInfo, marshalInfo: marshalInfo, options: options]; WFS1["["]; SELECT stringInfo.type FROM String => WFS1["StringBody"]; ENDCASE => Declare.WriteTypeName[stringInfo.self]; WFS1["[stringHeader.maxLength]]);\n"]; END; IF Private.Passing[Result, argument, marshalInfo] THEN WFL1[nest+2, "NULL; -- Call by result, use uninitialized body."] ELSE BEGIN WFL[nest+2, parentInfo.name, ".length _ stringHeader.length;"]; Private.CopyCharacters[ nest: nest+2, textName: TextBase, numCharsName: "stringHeader.length", marshalInfo: marshalInfo ]; END; WFL[nest+2, "END; -- IF stringIsNIL."]; END; ENDCASE => ERROR; END; MarshalRope: PROCEDURE [ name: String, ropeInfo: Rope ST.TypeInfo, parentInfo: ParentInfo, marshalInfo: MarshalInfo, nest: Nest ] = BEGIN inlineRopeMarshal: BOOL=marshalInfo.paramInfo.options.inlineRopeMarshal; VerifyPassingMethods[value: TRUE, handle: TRUE, marshalInfo: marshalInfo]; SELECT marshalInfo.direction FROM toPkt => IF ~inlineRopeMarshal THEN WFLL[nest, "pktLength _ Lupine.MarshalRope[", name, ", pkt, pktLength, ", (IF Private.IsShortString[ropeInfo.self] THEN "TRUE" ELSE "FALSE"), "];"] ELSE BEGIN Private.CopyOne[ nest: nest, wordsNeeded: 2, value: [name, "=NIL"], marshalInfo: marshalInfo ]; WFL[nest, "IF ", name, " # NIL"]; WFL1[nest+1, "THEN BEGIN"]; WFL[nest+2, "textRope: Rope.Text = Rope.InlineFlatten[r: ", name, "];"]; IF Private.IsShortString[ropeInfo.self] THEN BEGIN WFL1[nest+2, "IF textRope.length > RpcPrivate.maxShortStringLength"]; WFL1[nest+3, "THEN Lupine.MarshalingError;"]; END; Private.CopyOne[ nest: nest+2, wordsNeeded: 0, value: ["textRope.length"], marshalInfo: marshalInfo ]; Private.CopyCharacters[ nest: nest+2, textName: ["BASE[DESCRIPTOR[textRope.text]]"], numCharsName: "textRope.length", marshalInfo: marshalInfo ]; WFL[nest+2, "END; -- IF ", name, " # NIL."]; END; fromPkt => IF ~inlineRopeMarshal THEN WFLL[nest, "[", name, ", pktLength] _ Lupine.UnmarshalRope[pkt, pktLength, ", (IF Private.IsShortString[ropeInfo.self] THEN "TRUE" ELSE "FALSE"), "];"] ELSE BEGIN WFL1[nest, "ropeIsNIL: Lupine.NilHeader;"]; Private.CopyOne[ nest: nest, wordsNeeded: 2, value: ["ropeIsNIL"], marshalInfo: marshalInfo ]; WFL1[nest, "IF ropeIsNIL"]; WFL[nest+1, "THEN ", name, " _ NIL"]; WFL1[nest+1, "ELSE BEGIN"]; WFL1[nest+2, "ropeLength: Lupine.RopeHeader;"]; WFL1[nest+2, "textRope: Rope.Text;"]; Private.CopyOne[ nest: nest+2, wordsNeeded: 0, value: ["ropeLength"], marshalInfo: marshalInfo ]; WFL[nest+2, "IF ropeLength > ", (IF Private.IsShortString[ropeInfo.self] THEN "RpcPrivate.maxShortStringLength" ELSE "LAST[NAT]") ]; WFL1[nest+3, "THEN Lupine.UnmarshalingError;"]; WFL[nest+2, name, " _ textRope _ Rope.NewText[size: ropeLength];"]; Private.CopyCharacters[ nest: nest+2, textName: ["BASE[DESCRIPTOR[textRope.text]]"], numCharsName: "ropeLength", marshalInfo: marshalInfo ]; WFL[nest+2, "END; -- IF ropeIsNIL."]; END; ENDCASE => ERROR; END; MarshalAtom: PROCEDURE [ name: String, atomInfo: Atom ST.TypeInfo, parentInfo: ParentInfo, marshalInfo: MarshalInfo, nest: Nest ] = BEGIN inlineRopeMarshal: BOOL=marshalInfo.paramInfo.options.inlineRopeMarshal; VerifyPassingMethods[value: TRUE, handle: TRUE, marshalInfo: marshalInfo]; SELECT marshalInfo.direction FROM toPkt => IF ~inlineRopeMarshal THEN WFL[nest, "pktLength _ Lupine.MarshalAtom[", name, ", pkt, pktLength];"] ELSE BEGIN WFL[nest, "pNameOfAtom: Rope.Text = Atom.GetPName[atom: ", name, "];"]; MarshalRope[ nest: nest, name: "pNameOfAtom", ropeInfo: ST.TypeInfo[self: atomInfo.self, info: Rope[]], parentInfo: parentInfo, marshalInfo: marshalInfo ]; END; fromPkt => IF ~inlineRopeMarshal THEN WFL[nest, "[", name, ", pktLength] _ Lupine.UnmarshalAtom[pkt, pktLength];"] ELSE BEGIN WFL1[nest, "pNameOfAtom: Rope.ROPE;"]; MarshalRope[ nest: nest, name: "pNameOfAtom", ropeInfo: ST.TypeInfo[self: atomInfo.self, info: Rope[]], parentInfo: parentInfo, marshalInfo: marshalInfo ]; WFL[nest, name, " _ Atom.MakeAtom[--pName:-- pNameOfAtom];"]; END; ENDCASE => ERROR; END; VerifyPassingMethods: PUBLIC PROCEDURE [ var, value, result, handle, all: BOOLEAN _ FALSE, marshalInfo: MarshalInfo ] = BEGIN IF marshalInfo.depth = 1 AND NOT (all OR (SELECT marshalInfo.paramFieldInfo.passingMethod FROM Var => var, Value => value, Result => result, Handle => handle, InterMds => TRUE, ENDCASE => ERROR) ) THEN ERROR; END; UniqueName: PUBLIC PROCEDURE [ root: String, suffix: String _ StringNIL, marshalInfo: MarshalInfo ] RETURNS [nameString: String] = BEGIN nameString _ IO.PutFR["%g%g%g", [rope[root]], [integer[marshalInfo.depth]], [rope[suffix]]]; END; StartReadonly: PROCEDURE [ name: String, typeInfo: ST.TypeInfo, marshalInfo: MarshalInfo, nest: Nest ] RETURNS [marshalName: String] = BEGIN marshalName _ name; -- Usually no new name is needed. SELECT typeInfo.type FROM Pointer, Ref, List, Descriptor => IF typeInfo.readonly THEN BEGIN marshalName _ UniqueName[ root: "writeOk", marshalInfo: marshalInfo ]; WFL1[nest, "-- Declare readwrite pointer for marshaling readonly pointer."]; SELECT marshalInfo.direction FROM toPkt => BEGIN WFS[Indent[nest], marshalName, ": "]; Declare.WriteTypeName[type: typeInfo.self, includeReadonly: FALSE]; WFS[" = LOOPHOLE[", name, "];\n"]; END; fromPkt => BEGIN WFS[Indent[nest], marshalName, ": "]; Declare.WriteTypeName[type: typeInfo.self, includeReadonly: FALSE]; WFS1[";\n"]; END; ENDCASE => ERROR; END; ENDCASE => IF typeInfo.readonly THEN ERROR; END; StopReadonly: PROCEDURE [ name: String, typeInfo: ST.TypeInfo, marshalName: String, marshalInfo: MarshalInfo, nest: Nest ] = BEGIN SELECT typeInfo.type FROM Pointer, Ref, List, Descriptor => IF typeInfo.readonly THEN SELECT marshalInfo.direction FROM toPkt => NULL; fromPkt => WFLL[nest, name, " _ ", marshalName, ";"]; ENDCASE => ERROR; ENDCASE => IF typeInfo.readonly THEN ERROR; END; END. -- LupineMarshalTypeManagerImpl. ΦLupineMarshalTypeManagerImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Last edited by BZM on 11-May-82 16:20:51. Birrell, September 12, 1983 3:41 pm Swinehart, February 8, 1985 8:45:00 am PST Bob Hagmann March 15, 1985 9:47:36 am PST This module cooperates with LupineMarshal*Impl to export LupineMarshal. Types from the internal LupineManagerPrivate interface. Parameter protocol versions: These routines generate marshaling code for top-level parameters. Must use assignment when whole record can't be constructed. This routine is used to perform constant folding on "pktLength". See LupineDeclareStubsImpl.PacketLength. General type marshaling routine. These four must have a block because of Start/StopReadonly. These are simple and don't need a block. These guys cannot be marshaled. Each marshaling routine for which MarshalOpInfo.newBlock is TRUE can generate multiple statements because BEGIN-END is written here. Otherwise the routine must generate exactly one statement. Handle and InterMds should only happen at the top (param) level. Exactly one pointer depth is permitted in VAR and RESULT. A handle embedded in something else still a handle. These basic types just need copying. Marshaling routines for nontrivial builtin types (e.g., strings). Marshaling utility routines. VerifyPassingMethods double checks that Lupine's type checker (LupineMarshalInfoImpl.DeterminePassingMethod) and code generators (the Marshal routines) are in agreement. Κ˜headšœ!™!Icodešœ Οmœ1™<—šœ™Jšœ™L™#L™*L™)—J˜JšœG™GJ˜šΟk ˜ Jšžœžœ ˜šœžœ˜J˜3—šœžœ˜J˜=Jš œžœžœžœžœ˜(—šœžœ˜J˜!J˜1J˜+—šœžœ˜J˜J˜>J˜?J˜ J˜J˜-J˜*J˜4J˜J˜$J˜—Jšœžœ,˜CJšœžœžœ˜J˜J˜—šœž˜%šž˜J˜1Jšœžœ˜4—Jšžœ$˜+Jšžœ˜Jšœžœžœ%˜1J˜J˜J˜Jšœ7™7˜Jšœ žœ˜&Jšœ žœ˜(J˜J˜Jšœ™J˜šΟnœžœž ˜+Jšžœ.˜5šœžœ˜ J˜J˜J˜J˜J˜——J˜J˜——J˜JšœA™A˜šŸœžœž œ˜J˜J˜!J˜J˜ J˜Jšž˜Jšœžœžœ˜$Jšœ žœžœΟc%˜Ašžœ˜!š žœžœžœžœž˜=šžœ+˜-šžœžœž˜-Jšœ"žœ˜'šžœžœ˜Jšœ;™;————Jšžœ˜—šžœ˜šžœžœ 4˜@Jšœ žœžœ˜˜"Jšž˜šžœ2ž˜Jšžœžœžœ˜'—Jšžœ˜—šžœ˜šžœžœ 4˜@Jšœ žœžœ˜˜%Jšž˜šžœ2ž˜Jšžœ˜—Jšžœ <˜C˜0J˜Jšœžœ˜J˜J˜—J˜.˜#Jšž˜J˜,˜J˜3J˜J˜#J˜J˜—Jšžœ ˜—J˜;Jšžœ (˜.Jšžœ =˜DJšŸœžœžœžœ˜AJšœ@™@šœ(™(šžœžœ˜Jšœž˜!Jšœž˜ J˜——šžœ;˜?J˜—šžœ˜Jšžœ˜Jšžœ;˜?—J˜ Jšžœ˜Jšžœ˜J˜——J˜Jšœ ™ J˜˜šœžœžœ˜Jšœ žœžœ˜Jšœ žœžœ˜J˜—š œžœžœžœžœ˜9šœ;™;Jšœžœ˜Jšœžœ˜Jšœžœ˜Jšœžœ˜—šœ(™(Jšœžœ˜Jšœžœ˜Jšœžœ˜Jšœžœ˜Jšœžœ˜Jšœžœ˜Jšœžœ˜—šœ™Jšœžœ žœ˜1Jšœžœ žœ˜*Jšœžœ žœ˜.J˜J˜——šœ žœ˜-JšœD™DJšœ?™?Jšœ:™:š œ žœžœžœžœ ˜FJšœ œ œ˜;Jšœ œ œ˜3—Jšœ žœ žœ˜3J˜MJšœ žœ)˜7J˜*šžœ žœ˜šžœ œ˜&Jšœ) œ  œ˜BJ˜šžœ œ- œ˜Ašœ" œ!˜HJšœ œ˜——J˜—Jšœ˜—šžœ(˜*šžœžœž˜˜Jšœ@™@Jšžœžœžœ˜$˜&J˜,J˜4—Jšœ˜—˜šžœžœž˜šœžœž˜3J˜%Jšœ9™9J˜0—˜%Jšœ3™3˜&J˜,J˜4——šžœ˜ ˜0J˜J˜—šžœžœž˜#˜#Jšœ$™$˜J˜3J˜4——˜$J˜?—˜ J˜?—˜*J˜?—˜"J˜?—˜J˜?—˜J˜?—˜J˜?—˜J˜6—˜J˜6—˜ J˜?—˜J˜?—˜J˜?—˜(J˜?—˜$J˜?—šœ  ˜"J˜7—˜Jšžœ 4˜<—Jšžœžœ˜—˜J˜J˜6—Jšœ˜———Jšžœž˜—Jšžœ:˜>—šžœ ž œ œ'˜SJšœ œ  œ˜—J˜*Jšœ˜—J˜—J˜JšœA™A˜šŸ œž œ˜J˜ Jšœžœ ˜J˜J˜J˜ J˜Jšžœž˜ ˜J˜J˜J˜J˜—Jšžœ˜J˜—šŸœž œ˜J˜ Jšœžœ ˜'J˜J˜J˜ J˜Jšžœž˜ ˜J˜J˜J˜J˜—Jšžœ˜J˜—šŸ œž œ˜J˜ Jšœžœ ˜J˜J˜J˜ J˜Jšžœž˜ ˜J˜J˜J˜J˜—Jšžœ˜J˜—šŸœž œ˜Jšœ žœ ˜J˜J˜J˜J˜Jšž˜šœžœž˜2J˜#J˜Jšžœžœ˜—šœžœž˜:J˜;J˜9Jšžœžœ˜—Jšœžœ˜:šžœž˜$Jšœžœžœžœ˜/—šžœž˜!˜Jšž˜˜J˜J˜!J˜—Jšžœ)˜,J˜J˜6šžœ˜ J˜J˜$—˜ J˜9—Jšž˜—šžœž˜ Jšžœ*˜-J˜`J˜ šžœž˜J˜Jšžœ+˜2—J˜&Jšžœ˜——šžœ/˜1JšžœB˜Fšžœž˜ Jšžœ<˜?˜%J˜J˜$J˜—Jšžœ˜——Jšžœ%˜(Jšžœ˜—Jšžœžœ˜—Jšžœ˜J˜—šŸ œž œ˜J˜ Jšœžœ ˜J˜J˜J˜Jšž˜Jšœžœ1˜HJšœžœ žœ˜Jšžœž˜!˜šžœžœžœ˜%Jšœˆ˜ˆ—šž ˜ ˜J˜J˜J˜—Jšžœ˜!J˜šžœ˜ J˜<—šžœ&žœž˜2J˜EJ˜-Jšžœ˜—˜J˜J˜J˜—˜%J˜.J˜ J˜—Jšžœ*˜-Jšžœ˜——˜ šžœžœžœ˜%JšœŒ˜Œ—šžœž˜ J˜+˜J˜J˜J˜—J˜Jšžœ"˜%˜J˜/—J˜%˜J˜J˜J˜—šžœ˜ J˜šœžœ%˜(Jšžœ#žœ˜;——J˜/Jšžœ@˜C˜%J˜.J˜J˜—Jšžœ#˜&Jšžœ˜——Jšžœžœ˜—Jšžœ˜J˜—šŸ œž œ˜J˜ Jšœžœ ˜J˜J˜J˜Jšž˜Jšœžœ1˜HJšœžœ žœ˜Jšžœž˜!˜šžœžœžœ˜$J˜>—šžœž˜ JšžœD˜G˜J˜Jšœ žœ-˜9J˜4—Jšžœ˜——˜ šžœžœžœ˜$J˜B—šžœž˜ J˜&˜J˜Jšœ žœ-˜9J˜4—Jšžœ:˜=Jšžœ˜——Jšžœžœ˜—Jšžœ˜J˜——J˜Jšœ™˜šŸœžœž œ˜(Jšœ!žœžœ˜1J˜Jšž˜Jšœ0™0Jšœ;™;JšœB™Bšžœž˜šžœžœžœ*ž˜AJ˜?Jšœ žœžœžœ˜%—Jšžœžœ˜ —Jšžœ˜J˜—šŸ œžœž œ˜J˜ J˜J˜Jšžœ˜Jšž˜Jšœ\˜\Jšžœ˜J˜J˜—šŸ œž œ˜J˜ Jšœ žœ ˜J˜J˜ Jšžœ˜Jšž˜Jšœ !˜6šžœž˜˜!šžœžœž˜˜J˜J˜—˜ J˜A—šžœž˜!˜Jšž˜Jšžœ"˜%Jšœ<žœ˜CJšžœ˜"Jšžœ˜—˜ Jšž˜Jšžœ"˜%Jšœ<žœ˜CJ˜ Jšžœ˜—Jšžœžœ˜—Jšžœ˜——Jšžœžœžœžœ˜/—Jšžœ˜J˜—šŸ œž œ˜J˜ Jšœ žœ ˜J˜J˜J˜Jšž˜šžœž˜˜!šžœž˜šžœž˜!Jšœ žœ˜Jšœ žœ&˜5Jšžœžœ˜———Jšžœžœžœžœ˜+—Jšžœ˜J˜J˜——Jšžœ  ˜&J˜—…—Lje@