Start:
PROC [instr, data: WrapRESIUtil.CacheIndex ← 1, traceOps:
BOOL ←
FALSE, countOps:
BOOL ←
FALSE, recordXferOut:
BOOL ←
TRUE, modelCache:
BOOL ←
TRUE, flushOnCall:
BOOL ←
FALSE]
RETURNS [handle: Handle] = {
cpl: Atom.PropList ← ProcessProps.GetPropList[];
wd: ROPE ← NARROW[List.Assoc[$WorkingDirectory, cpl]];
handle ← NEW [HandleRec ← [modelCache: modelCache]];
handle.parent ← NARROW[List.Assoc[$CommanderHandle, cpl]];
handle.workingDir ← Atom.PutPropOnList[propList: NIL, prop: $WorkingDirectory, val: wd];
handle.m ←
NEW[RESInterpreter.MachineStateRec ← [
cacheData: NEW [WrapRESIUtil.CacheInfoRec ← [iCaches: instr, dCaches: data]],
history: NEW [RESInterpreter.OpHistoryRec],
traceOps: traceOps,
flushOnCall: flushOnCall,
countOps: countOps,
recordXferOut: recordXferOut,
opCount: NEW [ARRAY Basics.Byte OF INT ← ALL[0]],
interestingGfi: NEW [RESInterpreter.BitVector ← ALL[FALSE]]]];
[handle.tsIn, handle.tsOut] ← ViewerIO.CreateViewerStreams [
name: "WrapDragoman.ts", viewer: NIL, backingFile: "WrapDragoman.ts", editedStream: FALSE];
};
SetInstructionCache:
PROC [handle: Handle, number: WrapRESIUtil.CacheIndex, cache: CacheModels.Cache] = {
cacheInfo: WrapRESIUtil.CacheInfo ← NARROW[handle.m.cacheData];
cacheInfo.iCache[number] ← cache;
};
SetDataCache:
PROC [handle: Handle, number: WrapRESIUtil.CacheIndex, cache: CacheModels.Cache] = {
cacheInfo: WrapRESIUtil.CacheInfo ← NARROW[handle.m.cacheData];
cacheInfo.dCache[number] ← cache;
};
MarkGFI:
PROC [handle: Handle, name1, name2, name3, name4, name5, name6:
ROPE ←
NIL] = {
MarkGFIInternal:
PROC [name:
ROPE] = {
wc, cc: AMModel.Context;
NoteMod:
PROC [cx: AMModel.Context]
RETURNS [stop:
BOOL ←
FALSE] =
TRUSTED {
SELECT AMModel.ContextClass[cx]
FROM
model => [] ← AMModel.ContextChildren[cx, NoteMod];
prog => {
tx: AMTypes.TV = AMModelBridge.FrameFromContext[cx];
gf: PrincOps.GlobalFrameHandle = AMBridge.GFHFromTV[tx];
first, last: CARDINAL;
[first, last] ← GfiRange[gf.gfi];
min ← MIN[min, first];
max ← MAX[max, last]};
ENDCASE;
};
min: CARDINAL ← CARDINAL.LAST;
max: CARDINAL ← CARDINAL.FIRST;
TRUSTED {wc ← AMModel.RootContext[WorldVM.LocalWorld[]]};
IF name = NIL THEN RETURN;
TRUSTED {cc ← AMModel.MostRecentNamedContext[name, wc]};
IF cc = NIL THEN {Output[handle, "MarkGFI: ", name, " not found\n"]; RETURN};
[] ← NoteMod[cc];
Output[handle, "MarkGFI: ", name, " gfi's are marked (", Convert.RopeFromInt[min], "-", Convert.RopeFromInt[max], ")\n"];
FOR i:
CARDINAL
IN [min..max]
DO
handle.m.interestingGfi[i] ← TRUE;
ENDLOOP;
};
MarkGFIInternal[name1]; MarkGFIInternal[name2]; MarkGFIInternal[name3]; MarkGFIInternal[name4]; MarkGFIInternal[name5]; MarkGFIInternal[name6];
};
Run:
PROC [handle: Handle, name:
ROPE, recordXferOut:
BOOL ←
TRUE] = {
commandToolGfi: CARDINAL;
Init:
PROC [h: Handle, topProc:
PROC] =
TRUSTED {
link: PrincOps.ControlLink = LOOPHOLE[topProc];
MarkInteresting[h.m, link.gfi];
RESIXfer.Xfer[
m: h.m, dst: link, src: RESInterpreter.MagicReturn, push: FALSE];
};
MarkInteresting:
PROC [m: Machine, gfi: PrincOps.GFTIndex] = {
first, last: CARDINAL;
[first, last] ← GfiRange[gfi];
FOR i: CARDINAL IN [first..last] DO m.interestingGfi[i] ← TRUE; ENDLOOP;
};
RunInContext: SAFE PROC = TRUSTED {RESIDisp.Execute[handle.m]};
gf: PrincOps.GlobalFrameHandle;
gf ← PrincOpsUtils.GlobalFrame[CommandTool.DoCommand];
TRUSTED {commandToolGfi ← gf.gfi};
Output[handle, "Initializing to run command tool\n"];
Atom.PutProp[$HACK, $HACKPROP, name];
Init[handle, LOOPHOLE[CallCommandTool]]; -- we're going to push parameters
WrapRESIUtil.Push2[handle.m, LOOPHOLE[handle]];
MarkInteresting[handle.m, commandToolGfi];
BEGIN
ENABLE {
UNWIND => {};
RESInterpreter.FinishedExecution => {GO TO done};
ABORTED => {Output[handle, " aborted"]; GO TO done}};
handle.m.breakPC ← 0;
handle.m.breakGF ← LOOPHOLE[0];
handle.m.recordXferOut ← recordXferOut;
WrapRESIUtil.EnableCaches[m: handle.m, state: handle.modelCache];
handle.m.singleStep ← FALSE;
handle.m.startOps ← handle.m.iCount;
handle.m.startPulses ← BasicTime.GetClockPulses[];
ProcessProps.AddPropList[handle.workingDir, RunInContext];
GO TO done;
EXITS
done => {
et: REAL;
et ← BasicTime.PulsesToSeconds[BasicTime.GetClockPulses[] - handle.m.startPulses];
Output[handle, IO.PutFR["Executed %g instr in %g secs (%g/sec)\n", [cardinal[handle.m.iCount - handle.m.startOps]], [real[et]], [real[(handle.m.iCount - handle.m.startOps)/et]]]];
IF recordXferOut THEN RESIStats.PrintProcCounts[handle.tsOut, handle.m];
WrapRESIUtil.PrintCacheStats[handle.tsOut, handle.m];
};
END;
};