From fc6bb4f25d14b99c8d87928bf5fe2bc2bb96dec2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=86=A1=EA=B2=BD=ED=98=B8?= Date: Tue, 4 Feb 2025 12:11:23 +0900 Subject: [PATCH] add step count to debugger --- .../esmeta/interpreter/Interpreter.scala | 40 ++++++++++------- src/main/scala/esmeta/web/Debugger.scala | 44 ++++++++++--------- .../scala/esmeta/web/routes/MetaRoute.scala | 2 +- 3 files changed, 49 insertions(+), 37 deletions(-) diff --git a/src/main/scala/esmeta/interpreter/Interpreter.scala b/src/main/scala/esmeta/interpreter/Interpreter.scala index 10b20c9465..344a05ce32 100644 --- a/src/main/scala/esmeta/interpreter/Interpreter.scala +++ b/src/main/scala/esmeta/interpreter/Interpreter.scala @@ -59,7 +59,7 @@ class Interpreter( try { // text-based logging if (log) - pw.println(st.getCursorString) + pw.println(st.getCursorString + s" StepCnt : $stepCnt") if (detail) pw.println(st.context) pw.flush @@ -104,27 +104,28 @@ class Interpreter( /** transition for nodes */ def eval(node: Node): Unit = + val fid = cfg.funcOf(node).id node match { case bnode @ Block(_, insts, _) => for (inst <- insts) { + countStep(fid, inst.loc) eval(inst) st.context.moveInst } st.context.moveNode case branch: Branch => - countStep(branch.loc) + countStep(fid, branch.loc) eval(branch.cond) match case Bool(bool) => moveBranch(branch, bool) case v => throw NoBoolean(v) case call: Call => - countStep(call.loc) + countStep(fid, call.loc) eval(call) } /** transition for normal instructions */ - def eval(inst: NormalInst): Unit = - countStep(inst.loc) - inst match + def eval(inst: NormalInst): Unit = + inst match case IExpr(expr) => eval(expr) case ILet(lhs, expr) => st.define(lhs, eval(expr)) case IAssign(ref, expr) => st.update(eval(ref), eval(expr)) @@ -148,7 +149,6 @@ class Interpreter( val v = eval(expr) if (!TEST_MODE) println(st.getString(v)) case INop() => /* do nothing */ - /** transition for calls */ def eval(call: Call): Unit = call.callInst match { case ICall(lhs, fexpr, args) => @@ -419,20 +419,30 @@ class Interpreter( /** iteration count */ private var iter = 0 - def getIter = iter - protected def setIter(i: Int) = iter = i /** count of passed instruction */ - private var prevLoc : Option[Loc] = None - private var stepCnt : Int = 0 - private def countStep(curLoc : Option[Loc]) : Unit = + case class StepLocation(fid: Int, loc: Loc) + private var prevLoc: Option[StepLocation] = None + protected var stepCnt: Int = 0 + + private def convertLocation( + fid: Int, + loc: Option[Loc], + ): Option[StepLocation] = loc match + case None => None + case Some(sLoc) => Some(StepLocation(fid, sLoc)) + + protected def countStep(fid: Int, loc: Option[Loc]): Unit = + val curLoc = convertLocation(fid, loc) (prevLoc, curLoc) match - case (None,Some(_)) => stepCnt += 1 + case (None, Some(_)) => stepCnt += 1 case (Some(_), None) => stepCnt += 1 - case (Some(loc1), Some(loc2)) if loc1.steps != loc2.steps => stepCnt += 1 + case (Some(l1), Some(l2)) + if l1.fid != l2.fid || l1.loc.steps != l2.loc.steps => + stepCnt += 1 case _ => prevLoc = curLoc - + def getStepCnt = stepCnt /** logging */ private lazy val pw: PrintWriter = diff --git a/src/main/scala/esmeta/web/Debugger.scala b/src/main/scala/esmeta/web/Debugger.scala index da133fad5f..8d6bd43abf 100644 --- a/src/main/scala/esmeta/web/Debugger.scala +++ b/src/main/scala/esmeta/web/Debugger.scala @@ -13,7 +13,7 @@ import scala.annotation.tailrec import scala.collection.mutable.ListBuffer /** debugger extension of IR interpreter */ -class Debugger(st: State) extends Interpreter(st, log = true) { +class Debugger(st: State) extends Interpreter(st) { // --------------------------------------------------------------------------- // shortcuts // --------------------------------------------------------------------------- @@ -43,7 +43,9 @@ class Debugger(st: State) extends Interpreter(st, log = true) { saveBpCounts // save counter (cursor, node) match case (cursor: NodeCursor, block @ Block(_, insts, next)) => - eval(insts(cursor.idx)) + val targetInst = insts(cursor.idx) + countStep(cfg.funcOf(node).id, targetInst.loc) + eval(targetInst) cursor.idx += 1 if (cursor.idx == insts.length) { cursor.idx -= 1 @@ -57,7 +59,7 @@ class Debugger(st: State) extends Interpreter(st, log = true) { case _: AllocExpr => val addr = super.eval(expr) provenance._2 match { - case Some(provAddr) if provAddr == addr => provenance = (getIter, None) + case Some(provAddr) if provAddr == addr => provenance = (stepCnt, None) case _ => } addr @@ -111,12 +113,12 @@ class Debugger(st: State) extends Interpreter(st, log = true) { ): StepResult = { // XXX should throw exception if count is negative? if count <= 0 then - return if getIter == 0 then StepResult.ReachedFront + return if stepCnt == 0 then StepResult.ReachedFront else StepResult.Succeed stepWhile( { fn.map(_()) - val current = getIter + val current = stepCnt current < count }, ignoreBreak, @@ -145,7 +147,7 @@ class Debugger(st: State) extends Interpreter(st, log = true) { this.st.heap.size = newD.st.heap.size this.st.globals.clear() this.st.globals ++= newD.st.globals - setIter(0) + this.stepCnt = 0 // ir step final def irStep(ignoreBreak: Boolean = false) = { @@ -221,7 +223,7 @@ class Debugger(st: State) extends Interpreter(st, log = true) { // spec step back final def specStepBack(ignoreBreak: Boolean = false) = { - val ((curLoc, curStackSize), curIter) = (getSpecInfo, getIter) + val ((curLoc, curStackSize), curIter) = (getSpecInfo, stepCnt) var target: Int = 0 var breakFlag: Boolean = false @@ -230,7 +232,7 @@ class Debugger(st: State) extends Interpreter(st, log = true) { val (iterLoc, iterStackSize) = getSpecInfo val iterCond = curLoc._2.isDefined && curLoc == iterLoc if (!iterCond) { - target = getIter + target = stepCnt breakpoints.foreach { case SpecBreakpoint(fid, steps, true) if st.context.func.id == fid && iterLoc._2.contains( @@ -250,14 +252,14 @@ class Debugger(st: State) extends Interpreter(st, log = true) { // spec step back over final def specStepBackOver(ignoreBreak: Boolean = false) = { val (curLoc, curStackSize) = getSpecInfo - val currentIter = getIter + val currentIter = stepCnt var target: Int = 0 val calcTarget = () => { val (iterLoc, iterStackSize) = getSpecInfo val cond = (curLoc._2.isDefined && curLoc == iterLoc) || (curStackSize < iterStackSize) - if !cond then target = getIter + if !cond then target = stepCnt } var breakFlag: Boolean = false @@ -272,7 +274,7 @@ class Debugger(st: State) extends Interpreter(st, log = true) { ) ) breakFlag = true - target = getIter + target = stepCnt case _ => } } @@ -292,13 +294,13 @@ class Debugger(st: State) extends Interpreter(st, log = true) { // spec step back out final def specStepBackOut(ignoreBreak: Boolean = false) = { val (curLoc, curStackSize) = getSpecInfo - val currentIter = getIter + val currentIter = stepCnt var target: Int = 0 var breakFlag: Boolean = false val calcTarget = () => { - if !(curStackSize <= getSpecInfo._2) then target = getIter + if !(curStackSize <= getSpecInfo._2) then target = stepCnt } val calcBp = () => { @@ -312,7 +314,7 @@ class Debugger(st: State) extends Interpreter(st, log = true) { ) ) breakFlag = true - target = getIter + target = stepCnt case _ => } } @@ -377,7 +379,7 @@ class Debugger(st: State) extends Interpreter(st, log = true) { // rewind final def rewind: StepResult = { val (curLoc, curStackSize) = getSpecInfo - val currentIter = getIter + val currentIter = stepCnt var target: Int = 0 var breakFlag: Boolean = false @@ -392,7 +394,7 @@ class Debugger(st: State) extends Interpreter(st, log = true) { ) ) breakFlag = true - target = getIter + target = stepCnt case _ => } } @@ -408,23 +410,23 @@ class Debugger(st: State) extends Interpreter(st, log = true) { final def stepBackToProvenance(addr: Addr): StepResult = { provenance = (0, Some(addr)) - stepExactlyFrom(getIter, true) + stepExactlyFrom(stepCnt, true) stepExactlyFrom(provenance._1, true) } final def iterPlus(ignoreBreak: Boolean = false) = { - val targetIter = getIter + 1 + val tarstepCnt = stepCnt + 1 stepUntil( { - getIter == targetIter + stepCnt == tarstepCnt }, ignoreBreak, ) } final def iterMinus(ignoreBreak: Boolean = false) = { - val targetIter = getIter - 1 - stepExactlyFrom(targetIter) + val tarstepCnt = stepCnt - 1 + stepExactlyFrom(tarstepCnt) } // --------------------------------------------------------------------------- diff --git a/src/main/scala/esmeta/web/routes/MetaRoute.scala b/src/main/scala/esmeta/web/routes/MetaRoute.scala index 44106706c3..64d7c93de6 100644 --- a/src/main/scala/esmeta/web/routes/MetaRoute.scala +++ b/src/main/scala/esmeta/web/routes/MetaRoute.scala @@ -26,7 +26,7 @@ object MetaRoute { ContentTypes.`application/json`, _debugger match case None => "null" - case Some(d) => d.getIter.asJson.noSpaces, + case Some(d) => d.getStepCnt.asJson.noSpaces, ), ) }