// SwatStack.bcpl - code for stack manipulation // Copyright Xerox Corporation 1979, 1981, 1982 // Last modified March 21, 1982 1:55 PM by Boggs // All you do is just...08/10/73 (ALB) get "Swat.decl" external [ // outgoing procedures StackSwapIn; StackSysIn; StackSysOut MapStack; Frame; PrintFrame; GetRetPC // incoming procedures from Swat VMFetch; ReportFail; AddrToSym; OpenCell // incoming procedures from OS Endofs; Gets; Puts; Wss; PutTemplate // outgoing statics openFrame // incoming statics dsp; stackDubious; xmFlag ] static [ openFrame // currently open frame opfnum fnp ] //---------------------------------------------------------------------------- let StackSwapIn() be openFrame = VMFetch(userAC2) //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- and StackSysOut(sysOut) be Puts(sysOut, openFrame) //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- and StackSysIn(sysIn) be //---------------------------------------------------------------------------- openFrame = Endofs(sysIn)? VMFetch(userAC2), Gets(sysIn) //---------------------------------------------------------------------------- and Frame(n) be //---------------------------------------------------------------------------- // Dump the parameters in the nth frame, and set $ [ MapStack(n, Frame1, nil, VMFetch(userAC2)) if opfnum ne n then ReportFail("Frame not found") for i = 1 to fnp do PutTemplate(dsp, "$UO: $UO*N", openFrame+3+i, VMFetch(openFrame+3+i)) OpenCell(openFrame+3+fnp) ] //---------------------------------------------------------------------------- and GetRetPC(n) = valof //---------------------------------------------------------------------------- // Get the pc at which we jump back into the nth frame. // Used by the "index$↑P" command. [ MapStack(n, Frame1, nil, VMFetch(userAC2)) if opfnum ne n then ReportFail("Frame not found") resultis VMFetch(openFrame+1) +1 ] //---------------------------------------------------------------------------- and Frame1(level, frame, numArgs, nil) be //---------------------------------------------------------------------------- [ openFrame, opfnum, fnp = frame, level, numArgs ] //---------------------------------------------------------------------------- and PrintFrame(level, frame, numArgs, stream) be //---------------------------------------------------------------------------- [ let bank = 0 let retAddr = VMFetch(frame eq VMFetch(userAC2)? userPC, frame+1) if xmFlag then [ let retInst = VMFetch(retAddr+1) if (retInst & xJmpInstMask) eq xJmp0 & retAddr eq (frame+xJmp-1) then [ retAddr = VMFetch(retAddr+2) //i.e. xPC in extended frame bank = retInst & xJmpBankMask ] ] if level ge 1 then stackDubious = false // used in SwatResident.bcpl PutTemplate(stream, "$2O $6UO $5UO $1O ", level, frame, VMFetch(frame)-frame, bank) AddrToSym(stream, retAddr, bank) Wss(stream, "--(") for i = 1 to numArgs do PutTemplate(stream, "$UO$S", VMFetch(frame+3+i), (numArgs eq i? "", ", ")) Wss(stream, ")*N") ] //---------------------------------------------------------------------------- and MapStack(lastLevel, proc, arg, root) be //---------------------------------------------------------------------------- [ let thisLevel, thisFrame = 0, root until thisLevel gr lastLevel do [ let prevFrame = VMFetch(thisFrame) let retAddr = VMFetch(prevFrame+1) let numArgs = VMFetch(retAddr) let prevFrameValid = valof [ if (numArgs & 177700B) ne 0 then [ numArgs = 0; resultis false ] if prevFrame eq 0 % prevFrame eq thisFrame % prevFrame ugr 176777b % retAddr eq 0 resultis false resultis true ] proc(thisLevel, thisFrame, numArgs, arg) unless prevFrameValid return thisFrame = prevFrame thisLevel = thisLevel +1 ] ]