DIRECTORY IO USING [PutFR], LupineDeclare USING [WriteSymbolName, WriteTypeName], LupineManagerPrivate USING [ Indent, Nest, ParamPassingMethod, String, StringNIL, WFS, WFS1, WFSL, WFL, WFL1, WFLL ], LupineMarshal USING [FieldInfo, ParamInfo, ParamRecordKind], LupineMarshalPrivate USING [ ContainsRefs, ContainsSequences, ContainsStatics, CopyOne, CopyTwo, CopyType, Direction, Error, HasEmptyIndex, MarshalInfo, MarshalType, MaxPointerDepth, NeedsMarshaling, NeedsOperationProc, OperationProc, ParentInfo, Passing, SubStrings, UniqueName, VerifyPassingMethods, WriteNEW ], LupineSymbolTable USING [ ComponentProcedure, EnumerateRecord, EnumerateVariants, GetTypeInfo, IsAnonymous, SymbolHandle, SymbolName, TypeHandle, TypeInfo, Types, VariantProcedure ], Rope USING [Cat]; LupineMarshalTypeConstructorImpl: PROGRAM IMPORTS IO, Declare: LupineDeclare, LupineManagerPrivate, Private: LupineMarshalPrivate, ST: LupineSymbolTable, Rope EXPORTS LupineMarshalPrivate = BEGIN OPEN LupineManagerPrivate, LupineMarshal; ParentInfo: TYPE = Private.ParentInfo; MarshalInfo: TYPE = Private.MarshalInfo; NeedsOperationProc: TYPE = Private.NeedsOperationProc; OperationProc: TYPE = Private.OperationProc; SubStrings: TYPE = Private.SubStrings; MarshalTransfer: PUBLIC PROCEDURE [ name: String, transferInfo: Transfer ST.TypeInfo, parentInfo: ParentInfo, marshalInfo: MarshalInfo, nest: Nest ] = BEGIN Private.VerifyPassingMethods[value: TRUE, handle: TRUE, marshalInfo: marshalInfo]; Private.Error[code: TransferParameter, type: transferInfo.self]; END; MarshalRecord: PUBLIC PROCEDURE [ name: String, recInfo: Record ST.TypeInfo, parentInfo: ParentInfo, marshalInfo: MarshalInfo, nest: Nest ] = BEGIN Private.VerifyPassingMethods[value: TRUE, marshalInfo: marshalInfo]; IF recInfo.hasSequences THEN MarshalSequenceRecord[ nest: nest, recName: name, recInfo: recInfo, parentInfo: parentInfo, marshalInfo: marshalInfo ] ELSE MarshalFixedRecord[ nest: nest, recName: name, recInfo: recInfo, parentInfo: parentInfo, marshalInfo: marshalInfo ]; END; MarshalFixedRecord: PROCEDURE [ recName: String, recInfo: Record ST.TypeInfo, parentInfo: ParentInfo, marshalInfo: MarshalInfo, nest: Nest ] = BEGIN IF (SELECT parentInfo.typeInfo.type FROM Record, VariantPart => FALSE, ENDCASE => TRUE) AND Private.ContainsStatics[recInfo.self] THEN BEGIN Private.CopyType[ nest: nest, variableName: recName, variableInfo: recInfo, parentInfo: parentInfo, marshalInfo: marshalInfo ]; MakeRefsNil[ nest: nest, name: recName, type: recInfo.self, parentInfo: parentInfo, marshalInfo: marshalInfo ]; END; DoRecordOperation[ nest: nest, opProc: Private.MarshalType, needsOpProc: Private.NeedsMarshaling, recName: recName, recInfo: recInfo, marshalInfo: marshalInfo ]; END; MarshalSequenceRecord: PROCEDURE [ recName: String, recInfo: Record ST.TypeInfo, parentInfo: ParentInfo, marshalInfo: MarshalInfo, nest: Nest ] = BEGIN IF ~recInfo.hasSequences OR (SELECT parentInfo.typeInfo.type FROM Pointer, Ref => FALSE, ENDCASE => TRUE) THEN ERROR; SELECT marshalInfo.direction FROM toPkt => BEGIN Private.CopyOne[ nest: nest, wordsNeeded: 3, value: [parentInfo.name, "=NIL"--L--], marshalInfo: marshalInfo ]; WFL[nest, "IF "--L--, parentInfo.name, " # NIL THEN BEGIN"--L--]; WFL1[nest+1, "-- Record has a sequence, put its length up front."--L--]; Private.CopyTwo[ nest: nest+1, wordsNeeded: 0, value: SubStrings["LENGTH[DESCRIPTOR["--L--, recName, "]]"--L--], marshalInfo: marshalInfo ]; IF Private.Passing[Result, argument, marshalInfo] THEN WFL1[nest+1, "NULL; -- Call by result, don't send record."--L--] ELSE MarshalFixedRecord[ nest: nest+1, recName: recName, recInfo: recInfo, parentInfo: parentInfo, marshalInfo: marshalInfo ]; WFL[nest+1, "END; -- IF "--L--, parentInfo.name, " # NIL."--L--]; END; fromPkt => BEGIN WFL1[nest, "recordIsNIL: Lupine.NilHeader;"--L--]; Private.CopyOne[ nest: nest, wordsNeeded: 3, value: ["recordIsNIL"--L--], marshalInfo: marshalInfo ]; IF Private.Passing[Result, result, marshalInfo] OR Private.Passing[Var, result, marshalInfo] THEN WFL[nest, "IF recordIsNIL # ("--L--, parentInfo.name, "=NIL) THEN Lupine.UnmarshalingError;"--L--]; WFL1[nest, "IF recordIsNIL"--L--]; WFL[nest+1, "THEN "--L--, parentInfo.name, " _ NIL"--L--]; WFL1[nest+1, "ELSE BEGIN"--L--]; WFL1[nest+2, "seqLength: Lupine.SequenceHeader;"--L--]; Private.CopyTwo[ nest: nest+2, wordsNeeded: 0, value: ["seqLength"--L--], marshalInfo: marshalInfo ]; IF Private.Passing[Result, result, marshalInfo] OR Private.Passing[Var, result, marshalInfo] THEN BEGIN WFL[nest+2, "IF seqLength # LENGTH[DESCRIPTOR["--L--, recName, "]] THEN Lupine.UnmarshalingError;"--L-- ]; WFL1[nest+2, "NULL; -- Call by var or result, use existing record."--L--]; END ELSE BEGIN WFS[Indent[nest+2], parentInfo.name, " _ ("--L--]; Private.WriteNEW[ ptrInfo: parentInfo.typeInfo, marshalInfo: marshalInfo ]; WFS1["["--L--]; Declare.WriteTypeName[recInfo.self]; WFS1["[Lupine.SHORT[seqLength]]]);\n"--L--]; END; IF Private.Passing[Result, argument, marshalInfo] THEN WFL1[nest+2, "NULL; -- Call by result, use uninitialized record."--L--] ELSE MarshalFixedRecord[ nest: nest+2, recName: recName, recInfo: recInfo, parentInfo: parentInfo, marshalInfo: marshalInfo ]; WFL[nest+2, "END; -- IF recordIsNIL."--L--]; END; ENDCASE => ERROR; END; DoRecordOperation: PROCEDURE [ opProc: OperationProc, needsOpProc: NeedsOperationProc, recName: String, recInfo: Record ST.TypeInfo, marshalInfo: MarshalInfo, nest: Nest ] = BEGIN MarshalField: ST.ComponentProcedure = BEGIN IF ~needsOpProc[componentType] THEN RETURN; opProc[ nest: nest, name: FieldName[ fieldSymbol: component, recordType: recInfo.self, anonOk: -- Single component variant records don't need names. componentIndex = 1 AND recInfo.hasVariants AND ST.GetTypeInfo[componentType].type = VariantPart ], type: componentType, parentInfo: [recName, recInfo], marshalInfo: marshalInfo ]; END; IF needsOpProc[recInfo.self] THEN BEGIN WFL[nest, "BEGIN OPEN record: "--L--, recName, ";"--L--]; [] _ ST.EnumerateRecord[recordType: recInfo.self, proc: MarshalField]; WFL[nest, "END; -- OPEN record: "--L--, recName, "."--L--]; END; END; MarshalVariantPart: PUBLIC PROCEDURE [ name: String, varInfo: VariantPart ST.TypeInfo, parentInfo: ParentInfo, marshalInfo: MarshalInfo, nest: Nest ] = BEGIN Private.VerifyPassingMethods[value: TRUE, marshalInfo: marshalInfo]; IF Private.ContainsSequences[varInfo.self] THEN Private.Error[code: SequenceInsideVariant, type: varInfo.self] ELSE DoVariantOperation[ nest: nest, opProc: Private.MarshalType, needsOpProc: Private.NeedsMarshaling, varName: name, varInfo: varInfo, marshalInfo: marshalInfo ]; END; DoVariantOperation: PROCEDURE [ opProc: OperationProc, needsOpProc: NeedsOperationProc, varName: String, varInfo: VariantPart ST.TypeInfo, marshalInfo: MarshalInfo, nest: Nest ] = BEGIN MarshalVariant: ST.VariantProcedure = BEGIN IF ~needsOpProc[variantRecordType] THEN RETURN; WFS1[Indent[nest+1]]; Declare.WriteSymbolName[variantTag]; WFS1[" =>\n"--L--]; opProc[ nest: nest+2, name: "variant"--L--, type: variantRecordType, parentInfo: [varName, varInfo], marshalInfo: marshalInfo ]; END; -- MarshalVariant. SELECT TRUE FROM ~needsOpProc[varInfo.self] => NULL; varInfo.kind = Computed => Private.Error[code: ComputedVariant, type: varInfo.self]; ENDCASE => BEGIN WFL1[nest, "WITH variant: record SELECT FROM"--L--]; [] _ ST.EnumerateVariants[ variantPartType: varInfo.self, proc: MarshalVariant]; WFL1[nest+1, "ENDCASE => NULL; -- WITH variant: record."--L--]; END; END; MarshalPointer: PUBLIC PROCEDURE [ name: String, pointerInfo: Pointer ST.TypeInfo, parentInfo: ParentInfo, marshalInfo: MarshalInfo, nest: Nest ] = BEGIN MarshalPointerTypes[ nest: nest, ptrName: name, ptrInfo: pointerInfo, referentType: pointerInfo.referentType, parentInfo: parentInfo, marshalInfo: marshalInfo ]; END; MarshalRef: PUBLIC PROCEDURE [ name: String, refInfo: Ref ST.TypeInfo, parentInfo: ParentInfo, marshalInfo: MarshalInfo, nest: Nest ] = BEGIN MarshalPointerTypes[ nest: nest, ptrName: name, ptrInfo: refInfo, referentType: refInfo.referentType, parentInfo: parentInfo, marshalInfo: marshalInfo ]; END; MarshalPointerTypes: PROCEDURE [ ptrName: String, ptrInfo: ST.TypeInfo, referentType: ST.TypeHandle, parentInfo: ParentInfo, marshalInfo: MarshalInfo, nest: Nest ] = BEGIN referentInfo: ST.TypeInfo = ST.GetTypeInfo[referentType]; referentName: String = ptrName.Cat["^"]; Private.VerifyPassingMethods[all: TRUE, marshalInfo: marshalInfo]; marshalInfo.ptrDepth _ marshalInfo.ptrDepth + 1; SELECT TRUE FROM marshalInfo.ptrDepth > Private.MaxPointerDepth => Private.Error[code: ProbablePointerRecursion, type: ptrInfo.self]; (WITH refInfo: referentInfo SELECT FROM Basic => SELECT refInfo.kind FROM Unspecified, Other => TRUE, ENDCASE => FALSE, Any => TRUE, Opaque => ~refInfo.lengthKnown, ENDCASE => FALSE) => Private.Error[code: InvalidHandle, type: ptrInfo.self]; (WITH refInfo: referentInfo SELECT FROM Text, StringBody => TRUE, Record => refInfo.hasSequences, ENDCASE => FALSE) => Private.MarshalType[ nest: nest, name: referentName, type: referentType, parentInfo: [ptrName, ptrInfo], marshalInfo: marshalInfo ]; ENDCASE => MarshalFixedReferent[ nest: nest, ptrName: ptrName, ptrInfo: ptrInfo, referentName: referentName, referentInfo: referentInfo, parentInfo: parentInfo, marshalInfo: marshalInfo ]; marshalInfo.ptrDepth _ marshalInfo.ptrDepth - 1; END; MarshalFixedReferent: PROCEDURE [ ptrName: String, ptrInfo: ST.TypeInfo, referentName: String, referentInfo: ST.TypeInfo, parentInfo: ParentInfo, marshalInfo: MarshalInfo, nest: Nest ] = BEGIN SELECT marshalInfo.direction FROM toPkt => BEGIN Private.CopyOne[ nest: nest, wordsNeeded: 1, value: [ptrName, "=NIL"--L--], marshalInfo: marshalInfo ]; WFL[nest, "IF "--L--, ptrName, " # NIL THEN"--L--]; IF Private.Passing[Result, argument, marshalInfo] THEN WFL1[nest+1, "NULL; -- Call by result, send nothing."--L--] ELSE Private.MarshalType[ nest: nest+1, name: referentName, type: referentInfo.self, parentInfo: [ptrName, ptrInfo], marshalInfo: marshalInfo ]; END; fromPkt => BEGIN WFL1[nest, "isNIL: Lupine.NilHeader;"--L--]; Private.CopyOne[ nest: nest, wordsNeeded: 1, value: ["isNIL"--L--], marshalInfo: marshalInfo ]; IF Private.Passing[Result, result, marshalInfo] OR Private.Passing[Var,result,marshalInfo] THEN BEGIN WFL[nest, "IF isNIL # ("--L--, ptrName, "=NIL) THEN Lupine.UnmarshalingError;"--L--]; WFL1[nest, "IF ~isNIL THEN"--L--]; WFL1[nest+1, "-- Call by var or result, use existing referent."--L--]; Private.MarshalType[ nest: nest+1, name: referentName, type: referentInfo.self, parentInfo: [ptrName, ptrInfo], marshalInfo: marshalInfo ]; END ELSE BEGIN WFL1[nest, "IF isNIL"--L--]; WFL[nest+1, "THEN "--L--, ptrName, " _ NIL"--L--]; WFL1[nest+1, "ELSE BEGIN"--L--]; WFS[Indent[nest+2], ptrName, " _ ("--L--]; Private.WriteNEW[ptrInfo: ptrInfo, marshalInfo: marshalInfo]; WFS1["["--L--]; Declare.WriteTypeName[referentInfo.self]; WFS1["]);\n"--L--]; IF Private.Passing[Result, argument, marshalInfo] THEN WFL1[nest+2, "NULL; -- Call by result, use uninitialized referent."--L--] ELSE Private.MarshalType[ nest: nest+2, name: referentName, type: referentInfo.self, parentInfo: [ptrName, ptrInfo], marshalInfo: marshalInfo ]; WFL1[nest+2, "END; -- IF isNIL."--L--]; END; END; ENDCASE => ERROR; END; MarshalList: PUBLIC PROCEDURE [ name: String, listInfo: List ST.TypeInfo, parentInfo: ParentInfo, marshalInfo: MarshalInfo, nest: Nest ] = BEGIN Private.VerifyPassingMethods[value: TRUE, handle: TRUE, marshalInfo: marshalInfo]; DoListOperation[ nest: nest, opProc: Private.MarshalType, needsOpProc: Private.NeedsMarshaling, listName: name, listInfo: listInfo, marshalInfo: marshalInfo ]; END; DoListOperation: PROCEDURE [ opProc: OperationProc, needsOpProc: NeedsOperationProc, listName: String, listInfo: List ST.TypeInfo, marshalInfo: MarshalInfo, nest: Nest ] = BEGIN thisNode: String = Private.UniqueName[ root: "thisNode"--L--, marshalInfo: marshalInfo ]; thisNodeFirst: String = Private.UniqueName[ root: "thisNode"--L--, suffix: ".first"--L--, marshalInfo: marshalInfo ]; IF opProc # Private.MarshalType THEN ERROR; SELECT marshalInfo.direction FROM toPkt => BEGIN WFS[Indent[nest], thisNode, ": "--L--]; Declare.WriteTypeName[type: listInfo.self, includeReadonly: FALSE]; WFS1[";\n"--L--]; WFL1[nest, "listLength: Lupine.ListHeader _ 0;"--L--]; WFSL[ Indent[nest], "FOR "--L--, thisNode, " _ "--L--, listName, ", "--L--, thisNode, ".rest UNTIL "--L--, thisNode, " = NIL DO\n"--L--]; WFL1[nest+1, "listLength _ listLength + 1; ENDLOOP;"--L--]; Private.CopyTwo[ nest: nest, wordsNeeded: 2, value: SubStrings["listLength"--L--], marshalInfo: marshalInfo ]; WFSL[ Indent[nest], "FOR "--L--, thisNode, " _ "--L--, listName, ", "--L--, thisNode, ".rest UNTIL "--L--, thisNode, " = NIL DO\n"--L--]; opProc[ nest: nest+1, name: thisNodeFirst, type: listInfo.firstType, parentInfo: [listName, listInfo], marshalInfo: marshalInfo ]; WFL[nest+1, "ENDLOOP; -- FOR "--L--, thisNode, "."--L--]; END; fromPkt => BEGIN WFS[Indent[nest], "lastNode: "--L--]; Declare.WriteTypeName[type: listInfo.self, includeReadonly: FALSE]; WFS[" _ ("--L--, listName, " _ NIL);\n"--L--]; WFL1[nest, "listLength: Lupine.ListHeader;"--L--]; Private.CopyTwo[ nest: nest, wordsNeeded: 2, value: SubStrings["listLength"--L--], marshalInfo: marshalInfo ]; WFL1[nest, "WHILE listLength > 0 DO"--L--]; WFS[Indent[nest+1], thisNode, ": "--L--]; Declare.WriteTypeName[type: listInfo.self, includeReadonly: FALSE]; WFS1[" = "--L--]; Private.WriteNEW[ allocOp: cons, ptrInfo: listInfo, marshalInfo: marshalInfo]; WFS1["[--DefaultValue--,NIL];\n"--L--]; opProc[ nest: nest+1, name: thisNodeFirst, type: listInfo.firstType, parentInfo: [listName, listInfo], marshalInfo: marshalInfo ]; WFL1[nest+1, "IF lastNode # NIL"--L--]; WFSL[ Indent[nest+2], "THEN lastNode _ (lastNode.rest _ "--L--, thisNode, ")\n"--L--, Indent[nest+2], "ELSE lastNode _ ("--L--, listName, " _ "--L--, thisNode, ");\n"--L-- ]; WFL1[nest+1, "listLength _ listLength - 1;"--L--]; WFL1[nest+1, "ENDLOOP; -- WHILE listLength > 0."--L--]; END; ENDCASE => ERROR; END; MarshalArray: PUBLIC PROCEDURE [ name: String, arrayInfo: Array ST.TypeInfo, parentInfo: ParentInfo, marshalInfo: MarshalInfo, nest: Nest ] = BEGIN Private.VerifyPassingMethods[value: TRUE, marshalInfo: marshalInfo]; IF Private.HasEmptyIndex[index: arrayInfo.indexType] THEN Private.Error[code: EmptyArray, type: arrayInfo.self] ELSE MarshalVector[ nest: nest, vectorName: name, vectorInfo: arrayInfo, indexType: arrayInfo.indexType, elementType: arrayInfo.elementType, parentInfo: parentInfo, marshalInfo: marshalInfo ]; END; MarshalDescriptor: PUBLIC PROCEDURE [ name: String, descInfo: Descriptor ST.TypeInfo, parentInfo: ParentInfo, marshalInfo: MarshalInfo, nest: Nest ] = BEGIN lengthString: String = IO.PutFR["(IF BASE[%g]=NIL THEN 0 ELSE LENGTH[%g])", [rope[name]], [rope[name]] ]; Private.VerifyPassingMethods[all: TRUE, marshalInfo: marshalInfo]; SELECT marshalInfo.direction FROM toPkt => BEGIN Private.CopyTwo[ nest: nest, wordsNeeded: 2, value: [lengthString], marshalInfo: marshalInfo ]; WFL[nest, "IF BASE["--L--, name, "] # NIL THEN"--L--]; IF Private.Passing[Result, argument, marshalInfo] THEN WFL1[nest+1, "NULL; -- Call by result, send length only."--L--] ELSE BEGIN MarshalVector[ nest: nest+1, vectorName: name, vectorInfo: descInfo, indexType: descInfo.indexType, elementType: descInfo.elementType, parentInfo: parentInfo, marshalInfo: marshalInfo ]; END; END; fromPkt => BEGIN WFSL[Indent[nest], "DescriptorType: TYPE = RECORD ["--L--, (IF descInfo.packed THEN "PACKED "--L-- ELSE ""--L--), "SEQUENCE COMPUTED CARDINAL OF "--L--]; Declare.WriteTypeName[descInfo.elementType]; WFS1["];\n"--L--]; WFL1[nest, "descLength: Lupine.SequenceHeader;"--L--]; Private.CopyTwo[ nest: nest, wordsNeeded: 2, value: ["descLength"--L--], marshalInfo: marshalInfo]; IF Private.Passing[Result, result, marshalInfo] OR Private.Passing[Var,result,marshalInfo] THEN BEGIN WFL[nest, "IF descLength # "--L--, lengthString]; WFL[nest+1, "THEN Lupine.UnmarshalingError;"--L--]; WFL1[nest, "NULL; -- Call by var or result, use existing descriptor."--L--]; END ELSE BEGIN WFSL[Indent[nest], name, " _ DESCRIPTOR[\n"--L--, Indent[nest+1], "("--L--]; Private.WriteNEW[ptrInfo: descInfo, marshalInfo: marshalInfo]; WFS["[DescriptorType[Lupine.SHORT[descLength]]]),\n"--L--, Indent[nest+1], "Lupine.SHORT[descLength]];\n"--L--]; END; IF Private.Passing[Result, argument, marshalInfo] THEN WFL1[nest, "NULL; -- Call by result, use uninitialized descriptor."--L--] ELSE BEGIN MarshalVector[ nest: nest, vectorName: name, vectorInfo: descInfo, indexType: descInfo.indexType, elementType: descInfo.elementType, parentInfo: parentInfo, marshalInfo: marshalInfo ] END; END; ENDCASE => ERROR; END; MarshalSequence: PUBLIC PROCEDURE [ name: String, seqInfo: Sequence ST.TypeInfo, parentInfo: ParentInfo, marshalInfo: MarshalInfo, nest: Nest ] = BEGIN Private.VerifyPassingMethods[value: TRUE, marshalInfo: marshalInfo]; WITH tagName: seqInfo SELECT FROM Computed => Private.Error[code: ComputedSequence, type: seqInfo.self]; Named => BEGIN WFL1[nest, "-- The sequence's length was carried by its record."--L--]; IF ~Private.NeedsMarshaling[seqInfo.elementType] THEN ERROR; MarshalVector[ nest: nest, vectorName: name, vectorInfo: seqInfo, indexType: seqInfo.indexType, elementType: seqInfo.elementType, parentInfo: parentInfo, marshalInfo: marshalInfo ]; END; ENDCASE => ERROR; END; MarshalVector: PROCEDURE [ vectorName: String, vectorInfo: ST.TypeInfo, indexType, elementType: ST.TypeHandle, parentInfo: ParentInfo, marshalInfo: MarshalInfo, nest: Nest ] = BEGIN IF ~Private.NeedsMarshaling[elementType] THEN Private.CopyType[ nest: nest, variableName: vectorName, variableInfo: vectorInfo, parentInfo: parentInfo, marshalInfo: marshalInfo ] ELSE DoVectorOperation[ nest: nest, opProc: Private.MarshalType, needsOpProc: Private.NeedsMarshaling, vectorName: vectorName, vectorInfo: vectorInfo, indexType: indexType, elementType: elementType, marshalInfo: marshalInfo ]; END; DoVectorOperation: PROCEDURE [ opProc: OperationProc, needsOpProc: NeedsOperationProc, vectorName: String, vectorInfo: ST.TypeInfo, indexType, elementType: ST.TypeHandle, marshalInfo: MarshalInfo, nest: Nest ] = BEGIN IF needsOpProc[elementType] THEN BEGIN indexName: String = Private.UniqueName[ root: "element", marshalInfo: marshalInfo]; elementName: String = IO.PutFR["%g[%g]", [rope[vectorName]], [rope[indexName]]]; WFSL[Indent[nest], "FOR "--L--, indexName, ": "--L--]; Declare.WriteTypeName[indexType]; WFS1[" IN "--L--]; SELECT vectorInfo.type FROM Array => Declare.WriteTypeName[indexType]; Descriptor, Sequence => BEGIN WFS1["[FIRST["--L--]; Declare.WriteTypeName[indexType]; WFS1["]..FIRST["--L--]; Declare.WriteTypeName[indexType]; WFSL["]+LENGTH["--L--, (IF vectorInfo.type=Sequence THEN "DESCRIPTOR["--L-- ELSE ""--L--), vectorName, (IF vectorInfo.type=Sequence THEN "]"--L-- ELSE ""--L--), "])"--L--]; END; ENDCASE => ERROR; WFS1[" DO\n"--L--]; opProc[ nest: nest+1, name: elementName, type: elementType, parentInfo: [vectorName, vectorInfo], marshalInfo: marshalInfo ]; WFL[nest+1, "ENDLOOP; -- FOR "--L--, indexName, "."--L--]; END; END; MakeRefsNil: OperationProc = BEGIN IF marshalInfo.direction=fromPkt AND Private.ContainsRefs[type: type] THEN BEGIN WFL1[nest, "-- Restore garbled REFs to NIL following copy."--L--]; AssignNilToRefs[ nest: nest, name: name, type: type, parentInfo: parentInfo, marshalInfo: marshalInfo ]; END; END; AssignNilToRefs: OperationProc = BEGIN typeInfo: ST.TypeInfo = ST.GetTypeInfo[type: type]; SELECT marshalInfo.paramFieldInfo.passingMethod FROM Handle => NULL; InterMds => ERROR; Var, Value, Result => WITH typeInfo: typeInfo SELECT FROM Null, Definition, Basic, Pointer, RelativePtr, String, StringBody, Text, Any, Opaque, Zone, Other => NULL; Ref, List, Rope, Atom, Transfer => WFLL[nest, "LOOPHOLE["--L--, name, ", "--L--, (IF typeInfo.type#Transfer THEN "LONG "--L-- ELSE ""--L--), "POINTER] _ NIL;"--L-- ]; Record => DoRecordOperation[ nest: nest, opProc: AssignNilToRefs, needsOpProc: Private.ContainsRefs, recName: name, recInfo: typeInfo, marshalInfo: marshalInfo ]; VariantPart => DoVariantOperation[ nest: nest, opProc: AssignNilToRefs, needsOpProc: Private.ContainsRefs, varName: name, varInfo: typeInfo, marshalInfo: marshalInfo ]; Array => DoVectorOperation[ nest: nest, opProc: AssignNilToRefs, needsOpProc: Private.ContainsRefs, vectorName: name, vectorInfo: typeInfo, indexType: typeInfo.indexType, elementType: typeInfo.elementType, marshalInfo: marshalInfo ]; Descriptor => DoVectorOperation[ nest: nest, opProc: AssignNilToRefs, needsOpProc: Private.ContainsRefs, vectorName: name, vectorInfo: typeInfo, indexType: typeInfo.indexType, elementType: typeInfo.elementType, marshalInfo: marshalInfo ]; Sequence => DoVectorOperation[ nest: nest, opProc: AssignNilToRefs, needsOpProc: Private.ContainsRefs, vectorName: name, vectorInfo: typeInfo, indexType: typeInfo.indexType, elementType: typeInfo.elementType, marshalInfo: marshalInfo ]; ENDCASE => ERROR; ENDCASE => ERROR; END; FieldName: PROCEDURE [ recordName: String _ "record", recordType: ST.TypeHandle, fieldSymbol: ST.SymbolHandle, anonOk: BOOLEAN _ FALSE ] RETURNS [recordDotField: String _ NIL] = BEGIN IF anonOk OR ~ST.IsAnonymous[symbol: fieldSymbol] THEN recordDotField _ recordName.Cat[".", ST.SymbolName[fieldSymbol]] ELSE BEGIN Private.Error[code: AnonymousIdentifier, type: recordType]; recordDotField _ "record.unnamedField"; END; END; END. -- LupineMarshalTypeConstructorImpl. ^File [Ivy]Lupine>LupineMarshalTypeConstructorImpl.mesa. Last edited by BZM on March 18, 1982 11:18 AM. This module cooperates with LupineMarshal*Impl to export LupineMarshal. Last Edited by: Birrell, September 8, 1983 4:38 pm Types from the internal LupineManagerPrivate interface. Marshaling routines for type constructors (i.e., nonbuiltin types). MarshalFixedRecord needs storage for the record to already be allocated. Thus, sequence containing records are separately handled by MarshalSequenceRecord, which calls us to do some work. After a blind copy, always reset any Refs to NIL immediately. This consistency-making must be done atomically, ie, there must be no possibility of a fault (UNWIND) between the copying and the NIL-making. Monitored records will be caught because of the LOCK field. This routine expects that the referentType has a fixed, nondynamic length. MarshalPointerTypes should have screened this. DoListOperation does only marshaling correctly for now. lastNode: String = UniqueName[ root: "lastNode", marshalInfo: marshalInfo ]; MarshalVector must generate exactly one statement. Caller guarantees that the vector has >= 0 elements in it, and that any header information for sequences and descriptors has been sent. Must generate one statement. Marshaling utility routines. Make only refs in safe storage NIL, not those in pkts. ʘJšœ?™?Jšœ/™/J˜JšœG™GJšÏk2™2J˜š ˜ Jšœœ ˜Jšœœ"˜5šœœ˜J˜J˜,Jšœœœœ˜#—Jšœœ)˜<šœœ˜J˜1J˜™>Jšœ™˜J˜J˜J˜J˜—Jšœ˜———˜J˜CJ˜$J˜—Jšœ˜J˜—šžœ œ˜"J˜Jšœœ ˜J˜J˜J˜Jš˜šœ˜šœœ˜%Jšœœœœ˜'—Jšœœ˜ —šœ˜!˜Jš˜˜J˜JšœÏcœ˜&J˜—Jšœ Ÿœ&Ÿœ˜AJšœAŸœ˜H˜J˜Jšœ&ŸœŸœ˜AJ˜—šœ/˜1Jšœ<Ÿœ˜Fšœ"˜&J˜#J˜3——JšœŸœŸœ˜BJšœ˜—˜ Jš˜Jšœ+Ÿœ˜2˜J˜JšœŸœ˜J˜—šœ-˜/Jšœ*˜,šœœ˜JšœŸœ˜+Jšœ&Ÿœ˜-——JšœŸœ˜"JšœŸœŸœ˜:JšœŸœ˜ Jšœ0Ÿœ˜7˜J˜JšœŸœ˜J˜—šœ-˜/Jšœ*˜,šœ˜ šœ˜ Jšœ#Ÿœ ˜2Jšœ#Ÿœ˜+—˜ Jšœ7Ÿœ˜>—Jš˜—šœ˜ Jšœ(Ÿœ˜2˜J˜9—JšœŸœ˜J˜$Jšœ%Ÿœ˜,Jšœ˜——šœ/˜1šœ ˜Jšœ5Ÿœ˜;—šœ"˜&J˜#J˜3——Jšœ#Ÿœ˜-Jšœ˜—Jšœœ˜—Jšœ˜J˜—šžœ œ˜J˜J˜ J˜Jšœœ ˜J˜J˜Jš˜šœœ˜%Jš˜Jšœœœ˜+Jšœ;™;˜˜J˜J˜šœ Ÿ5˜>Jšœ˜Jšœ˜Jšœ1˜3——J˜J˜J˜—Jšœ˜—šœœ˜'JšœŸœŸœ˜9Jšœœ?˜FJšœŸœŸœ˜šœ1Ÿœ˜:Jšœ.Ÿœ˜5—Jšœ˜——šœ/˜1šœ ˜Jšœ9Ÿœ˜?—šœ˜ ˜J˜(J˜AJ˜2—Jšœ˜——Jšœ˜—Jšœœ˜—Jšœ˜J˜—šžœœ œ˜#J˜ Jšœœ ˜J˜J˜J˜Jš˜Jšœ$œ˜Dšœœ˜!J˜F˜Jš˜Jšœ@Ÿœ˜GJšœ/œœ˜<˜J˜'J˜?J˜3—Jšœ˜—Jšœœ˜—Jšœ˜J˜—šž œ œ˜J˜Jšœ œ ˜Jšœœ ˜&J˜J˜J˜Jš˜Jšœ2™2JšœC™CJšœC™Cšœ&˜(šœ˜"J˜4J˜3—šœ˜#J˜CJ˜0J˜0J˜——Jšœ˜J˜—šžœ œ˜J˜J˜ J˜Jšœ œ ˜Jšœœ ˜&J˜J˜Jš˜Jšœ™šœ˜šœ˜ ˜'Jšœ+˜+—JšœP˜PJšœŸœŸœ˜6J˜!Jšœ Ÿœ˜šœ˜J˜*˜Jš˜JšœŸœ$˜7JšœŸœ$˜9šœ Ÿœ˜Jš œœœŸœœŸœ˜CJ˜ Jš œœœŸœœŸœ˜9JšœŸœ˜ —Jšœ˜—Jšœœ˜—Jšœ Ÿœ˜˜J˜%J˜%J˜—JšœŸœŸœ˜;Jšœ˜——Jšœ˜J˜——J˜Jšœ™˜˜Jš˜Jšœ6™6šœœ!˜Ešœ˜ Jšœ;Ÿœ˜B˜J˜J˜4—Jšœ˜——Jšœ˜J˜—˜ Jš˜Jšœ œ œ˜3šœ*˜4Jšœ œ˜Jšœ œ˜˜šœœ˜#˜J˜/Jšœœ˜!—˜"šœ˜ Jšœ Ÿœ Ÿœ˜"Jš œœœŸœœŸœ˜;JšœŸœ˜——˜ ˜J˜