Skip to content

Commit

Permalink
add step count
Browse files Browse the repository at this point in the history
  • Loading branch information
Goonco committed Feb 4, 2025
1 parent b78ab48 commit b955533
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 106 deletions.
136 changes: 68 additions & 68 deletions src/main/scala/esmeta/constructor/Constructor.scala
Original file line number Diff line number Diff line change
@@ -1,77 +1,77 @@
package esmeta.constructor
// package esmeta.constructor

import esmeta.cfg.*
import esmeta.error.ESMetaError
import esmeta.state.*
import esmeta.web.Debugger
// import esmeta.cfg.*
// import esmeta.error.ESMetaError
// import esmeta.state.*
// import esmeta.web.Debugger

import scala.collection.mutable.Map as MMap
// import scala.collection.mutable.Map as MMap

class Constructor(
st: State,
targetNodeId: Int,
targetFeature: Int,
targetCallPath: String,
nodeToProgId: MMap[Int, MMap[Int, MMap[String, (Int, Int)]]],
) extends Debugger(st) {
private var flag = true
private inline def cfg = st.cfg
// class Constructor(
// st: State,
// targetNodeId: Int,
// targetFeature: Int,
// targetCallPath: String,
// nodeToProgId: MMap[Int, MMap[Int, MMap[String, (Int, Int)]]],
// ) extends Debugger(st) {
// private var flag = true
// private inline def cfg = st.cfg

override def eval(node: Node): Unit =
if (
flag && node.id == targetNodeId && generateCallpathString(
st.context.callPath.toString,
) == targetCallPath
) {
flag = false
val (script, cnt) =
nodeToProgId
.getOrElse(
targetNodeId,
throw new ESMetaError(
s"[Constructor] no corresponding nodeId $targetNodeId for nodeToProgId",
),
)
.getOrElse(
targetFeature,
throw new ESMetaError(
s"[Constructor] no corresponding feature $targetFeature",
),
)
.getOrElse(
targetCallPath,
throw new ESMetaError(
s"[Constructor] no corresponding callpath $targetCallPath",
),
)
// override def eval(node: Node): Unit =
// if (
// flag && node.id == targetNodeId && generateCallpathString(
// st.context.callPath.toString,
// ) == targetCallPath
// ) {
// flag = false
// val (script, cnt) =
// nodeToProgId
// .getOrElse(
// targetNodeId,
// throw new ESMetaError(
// s"[Constructor] no corresponding nodeId $targetNodeId for nodeToProgId",
// ),
// )
// .getOrElse(
// targetFeature,
// throw new ESMetaError(
// s"[Constructor] no corresponding feature $targetFeature",
// ),
// )
// .getOrElse(
// targetCallPath,
// throw new ESMetaError(
// s"[Constructor] no corresponding callpath $targetCallPath",
// ),
// )

nodeToProgId(targetNodeId)(targetFeature) -= targetCallPath
nodeToProgId(targetNodeId)(
targetFeature,
) += targetCallPath -> (script, getIter - 1)
}
super.eval(node)
// nodeToProgId(targetNodeId)(targetFeature) -= targetCallPath
// nodeToProgId(targetNodeId)(
// targetFeature,
// ) += targetCallPath -> (script, getIter - 1)
// }
// super.eval(node)

private def generateCallpathString(rawPath: String): String =
val nodeIdList = "\\d+".r
.findAllIn(rawPath)
.toList
.map { nodeIdStr =>
nodeIdStr.toIntOption.getOrElse(
throw new IllegalArgumentException(
s"Invalid integer value: $nodeIdStr",
),
)
}
// private def generateCallpathString(rawPath: String): String =
// val nodeIdList = "\\d+".r
// .findAllIn(rawPath)
// .toList
// .map { nodeIdStr =>
// nodeIdStr.toIntOption.getOrElse(
// throw new IllegalArgumentException(
// s"Invalid integer value: $nodeIdStr",
// ),
// )
// }

// val funcIdList: List[Int] = nodeIdList.flatMap { nodeId =>
// cfg.nodeMap.get(nodeId).flatMap { node =>
// cfg.funcOf.get(node).map(_.id)
// }
// }
// // val funcIdList: List[Int] = nodeIdList.flatMap { nodeId =>
// // cfg.nodeMap.get(nodeId).flatMap { node =>
// // cfg.funcOf.get(node).map(_.id)
// // }
// // }

val path =
if nodeIdList.isEmpty then "" else nodeIdList.mkString("<")
path
// val path =
// if nodeIdList.isEmpty then "" else nodeIdList.mkString("<")
// path

}
// }
76 changes: 46 additions & 30 deletions src/main/scala/esmeta/interpreter/Interpreter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import java.util.concurrent.TimeoutException
import scala.annotation.tailrec
import scala.collection.mutable.{Map => MMap}
import scala.math.{BigInt => SBigInt}
import esmeta.util.Loc

/** extensible helper of IR interpreter with a CFG */
class Interpreter(
Expand Down Expand Up @@ -104,45 +105,49 @@ class Interpreter(
/** transition for nodes */
def eval(node: Node): Unit =
node match {
case Block(_, insts, _) =>
case bnode @ Block(_, insts, _) =>
for (inst <- insts) {
eval(inst)
st.context.moveInst
}
st.context.moveNode
case branch: Branch =>
countStep(branch.loc)
eval(branch.cond) match
case Bool(bool) => moveBranch(branch, bool)
case v => throw NoBoolean(v)
case call: Call => eval(call)
case call: Call =>
countStep(call.loc)
eval(call)
}

/** transition for normal instructions */
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))
case IExpand(base, expr) => st.expand(st(eval(base)), eval(expr))
case IDelete(base, expr) => st.delete(st(eval(base)), eval(expr))
case IPush(elem, list, front) =>
val value = eval(elem)
val addr = eval(list).asAddr
st.push(addr, value, front)
case IPop(lhs, list, front) =>
val addr = eval(list).asAddr
st.context.locals += lhs -> st.pop(addr, front)
case ret @ IReturn(expr) =>
st.context.retVal = Some(ret, eval(expr))
case IAssert(expr) =>
optional(eval(expr)) match
case None => /* skip not yet compiled assertions */
case Some(Bool(true)) =>
case v => throw AssertionFail(expr)
case IPrint(expr) =>
val v = eval(expr)
if (!TEST_MODE) println(st.getString(v))
case INop() => /* do nothing */
}
def eval(inst: NormalInst): Unit =
countStep(inst.loc)
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))
case IExpand(base, expr) => st.expand(st(eval(base)), eval(expr))
case IDelete(base, expr) => st.delete(st(eval(base)), eval(expr))
case IPush(elem, list, front) =>
val value = eval(elem)
val addr = eval(list).asAddr
st.push(addr, value, front)
case IPop(lhs, list, front) =>
val addr = eval(list).asAddr
st.context.locals += lhs -> st.pop(addr, front)
case ret @ IReturn(expr) =>
st.context.retVal = Some(ret, eval(expr))
case IAssert(expr) =>
optional(eval(expr)) match
case None => /* skip not yet compiled assertions */
case Some(Bool(true)) =>
case v => throw AssertionFail(expr)
case IPrint(expr) =>
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 {
Expand Down Expand Up @@ -400,9 +405,6 @@ class Interpreter(
def moveExit: Unit =
st.context.cursor = ExitCursor(st.func)

def getIter = iter
protected def setIter(i: Int) = iter = i

// ---------------------------------------------------------------------------
// private helpers
// ---------------------------------------------------------------------------
Expand All @@ -417,6 +419,20 @@ 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 =
(prevLoc, curLoc) match
case (None,Some(_)) => stepCnt += 1
case (Some(_), None) => stepCnt += 1
case (Some(loc1), Some(loc2)) if loc1.steps != loc2.steps => stepCnt += 1
case _ =>
prevLoc = curLoc


/** logging */
private lazy val pw: PrintWriter =
Expand Down
16 changes: 8 additions & 8 deletions src/main/scala/esmeta/phase/Construct.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import esmeta.*
import esmeta.cfg.{CFG, Func}
import esmeta.util.*
import esmeta.util.SystemUtils.*
import esmeta.constructor.{Builder, Constructor}
import esmeta.constructor.{Builder}

import scala.collection.mutable.{Map as MMap, Set as MSet}
import java.nio.file.{Files, Paths}
Expand Down Expand Up @@ -64,13 +64,13 @@ case object Construct extends Phase[CFG, Unit] {
)) =>
println(s"$iter/$total : $MINIMAL_DIR/$filename running")
iter += 1
new Constructor(
cfg.init.fromFile(s"$MINIMAL_DIR/$filename.js"),
node,
feature,
callPath,
NodeIdToProgId,
).result
// new Constructor(
// cfg.init.fromFile(s"$MINIMAL_DIR/$filename.js"),
// node,
// feature,
// callPath,
// NodeIdToProgId,
// ).result
}

println("=========== Dump =========")
Expand Down

0 comments on commit b955533

Please sign in to comment.