CalledStubBody:
PROCEDURE [
transferName, blockName: String,
transferInfo: TransferInfo,
inlineBody: BOOLEAN,
argInfo, resultInfo: ParamInfo,
nest: Nest ] =
BEGIN
CallPkt: String = "pkt"; -- Must be identical to Dispatcher's pkt.
ReturnPkt: String = CallPkt; -- ... pkt.
CallLength: String = "pktLength";
ReturnLength: String --must equal-- = CallLength;
CallLimit: String = "callLimit"; -- Not used at this time.
LastPkt: String = "lastPkt"; -- Must be identical to Dispatcher's lastPkt.
ArgPtr: String = "argPkt";
ResultPtr: String = "resPkt";
CallVars: Marshal.VariableNames = [
pkt: CallPkt, overlayPtr: ArgPtr,
pktLength: CallLength, pktLimit: CallLimit,
lastPkt: LastPkt ];
ReturnVars: Marshal.VariableNames = [
pkt: ReturnPkt, overlayPtr: ResultPtr,
pktLength: ReturnLength, pktLimit: "",
lastPkt: LastPkt ];
WFL[nest, (IF inlineBody THEN "INLINE " ELSE ""), "BEGIN"];
ParamsAsLocalVars[nest: nest, paramInfo: argInfo];
ParamsAsLocalVars[nest: nest, paramInfo: resultInfo];
OverlayRecord[paramInfo: argInfo, nest: nest];
OverlayRecord[paramInfo: resultInfo, nest: nest];
IF ~Rope.Equal[CallPkt, Private.GetString[dispatcherPkt]] THEN ERROR;
IF ~Rope.Equal[CallPkt, ReturnPkt] THEN ERROR;
OverlayPointer[ nest: nest,
paramInfo: argInfo,
pktName: CallPkt, overlayPtrName: ArgPtr,
do: both ];
OverlayPointer[ nest: nest,
paramInfo: resultInfo,
pktName: ReturnPkt, overlayPtrName: ResultPtr,
do: IF argInfo.alwaysOnePkt THEN both ELSE declare ];
PacketLength[ nest: nest,
paramInfo: argInfo,
pktLengthName: CallLength,
declare: IF argInfo.transferType=Error THEN ifNeeded ELSE yes,
assign: ifNeeded ];
nest ← Marshal.BeginAllocation[paramInfo: argInfo, nest: nest];
SELECT
TRUE
FROM
argInfo.alwaysOnePkt =>
BEGIN
Marshal.FromPacket[ nest: nest,
paramInfo: argInfo,
overlayHandling: [static: leaveInPkt],
varNames: CallVars ];
OverlayPointer[ nest: nest,
paramInfo: resultInfo,
pktName: ReturnPkt, overlayPtrName: ResultPtr,
do: argInfo.alwaysOnePkt => assigned above ];
CallStmt[ nest: nest,
transferName: transferName,
type: transferInfo.kind,
argInfo: argInfo, resultInfo: resultInfo,
staticArgs: inPktOverlay, staticResults: inPktOverlay,
argOverlayPtr: ArgPtr, resultOverlayPtr: ResultPtr ];
END; -- alwaysOnePkt.
argInfo.alwaysMultiplePkts =>
BEGIN
Marshal.FromPacket[ nest: nest,
paramInfo: argInfo,
overlayHandling: [static: copyToFrame],
varNames: CallVars ];
OverlayPointer[ nest: nest,
paramInfo: resultInfo,
pktName: ReturnPkt, overlayPtrName: ResultPtr,
do: assign ];
CallStmt[ nest: nest,
transferName: transferName,
type: transferInfo.kind,
argInfo: argInfo, resultInfo: resultInfo,
staticArgs: inFrame, staticResults: inPktOverlay,
argOverlayPtr: ArgPtr, resultOverlayPtr: ResultPtr ];
END; -- alwaysMultiplePkt.
~argInfo.hasOverlayParamType[static] =>
BEGIN
Could be multiple packets, no statics.
Marshal.FromPacket[ nest: nest,
paramInfo: argInfo,
overlayHandling: [static: leaveInPkt],
varNames: CallVars ];
OverlayPointer[ nest: nest,
paramInfo: resultInfo,
pktName: ReturnPkt, overlayPtrName: ResultPtr,
do: assign ];
CallStmt[ nest: nest,
transferName: transferName,
type: transferInfo.kind,
argInfo: argInfo, resultInfo: resultInfo,
staticArgs: inFrame, staticResults: inPktOverlay,
argOverlayPtr: ArgPtr, resultOverlayPtr: ResultPtr ];
END; -- One or more packets, no statics.
ENDCASE =>
-- Could be one or more packets, some statics.
BEGIN
WFL1[nest, "BEGIN -- OnePkt."];
WFL[nest, "onePkt: BOOLEAN = ", LastPkt, ";"];
WFL1[nest, "IF ~onePkt THEN BEGIN -- Must move statics from pkt now."];
Marshal.FromPacket[ nest: nest+1,
paramInfo: argInfo,
overlayHandling: [static: justCopyToFrame],
varNames: CallVars ];
WFL1[nest+1, "END;"];
Marshal.FromPacket[ nest: nest,
paramInfo: argInfo,
overlayHandling: [static: leaveInPkt],
varNames: CallVars ];
OverlayPointer[ nest: nest,
paramInfo: resultInfo,
pktName: ReturnPkt, overlayPtrName: ResultPtr,
do: assign ];
WFL1[nest, "IF onePkt"];
WFS[Indent[nest+1], "THEN "];
Call[ nest: nest+2,
transferName: transferName,
type: transferInfo.kind,
argInfo: argInfo, resultInfo: resultInfo,
staticArgs: inPktOverlay, staticResults: inPktOverlay,
argOverlayPtr: ArgPtr, resultOverlayPtr: ResultPtr ];
WFS["\n", Indent[nest+1], "ELSE "];
Call[ nest: nest+2,
transferName: transferName,
type: transferInfo.kind,
argInfo: argInfo, resultInfo: resultInfo,
staticArgs: inFrame, staticResults: inPktOverlay,
argOverlayPtr: ArgPtr, resultOverlayPtr: ResultPtr ];
WFS1[";\n"];
WFL1[nest, "END; -- OnePkt."];
END; -- One or more packets.
PacketLength[ nest: nest,
paramInfo: resultInfo,
pktLengthName: ReturnLength,
declare: no,
assign: IF argInfo.transferType=Error THEN no ELSE yes ];
Marshal.ToPacket[ nest: nest,
paramInfo: resultInfo,
overlayHandling: [static: alreadyInPkt],
varNames: ReturnVars ];
nest ← Marshal.EndAllocation[ nest: nest,
paramInfo: argInfo,
justCloseBlocks: argInfo.transferType=Error ];
IF argInfo.transferType # Error
-- Nothing can follow an ERROR.
THEN
BEGIN
WFSL[Indent[nest],
"RETURN[", Private.GetString[dispatcherReturnLength],
": ", ReturnLength, "];\n" ];
END;
WFL[nest, "END; -- ", blockName, "."];
END; -- CalledStubBody.