From 15b6c636e28cd13aa49c7c5e0b1a271a3790e1a5 Mon Sep 17 00:00:00 2001 From: Yongwook Choi Date: Wed, 13 Mar 2024 23:34:15 +0900 Subject: [PATCH] Implement TargetSelector --- .../es/util/fuzzer/TargetSelector.scala | 58 +++++++++++++++++++ src/main/scala/esmeta/util/BaseUtils.scala | 7 ++- 2 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 src/main/scala/esmeta/es/util/fuzzer/TargetSelector.scala diff --git a/src/main/scala/esmeta/es/util/fuzzer/TargetSelector.scala b/src/main/scala/esmeta/es/util/fuzzer/TargetSelector.scala new file mode 100644 index 0000000000..ef6eab7efc --- /dev/null +++ b/src/main/scala/esmeta/es/util/fuzzer/TargetSelector.scala @@ -0,0 +1,58 @@ +package esmeta.es.util.fuzzer + +import esmeta.es.* +import esmeta.es.util.* +import esmeta.es.util.Coverage.* +import esmeta.spec.Grammar +import esmeta.util.* +import esmeta.util.BaseUtils.* + +/** mutation target selector for fuzzer */ +trait TargetSelector { + + /** target selection */ + def apply( + pool: Iterable[Script], + cov: Coverage, + ): (String, Script, Option[CondView]) + + /** Possible names of underlying selectors */ + val names: List[String] +} + +/** weighted mutation target selector */ +class WeightedSelector(pairs: (TargetSelector, Int)*) extends TargetSelector { + def apply( + pool: Iterable[Script], + cov: Coverage, + ): (String, Script, Option[CondView]) = weightedChoose(pairs)(pool, cov) + + val names = pairs.toList.flatMap(_._1.names) +} + +/** branch coverage-based mutation target selector */ +object BranchSelector extends TargetSelector { + def apply( + pool: Iterable[Script], + cov: Coverage, + ): (String, Script, Option[CondView]) = if (!cov.targetCondViews.isEmpty) { + val cond = choose(cov.targetCondViews.keys) + val view = choose(cov.targetCondViews(cond))._1 + val condView = CondView(cond, view) + cov.getScript(condView).fold(RandomSelector(pool, cov)) { + (names.head, _, Some(condView)) + } + } else RandomSelector(pool, cov) + + val names = List("BranchTarget") +} + +/** random mutation target selector */ +object RandomSelector extends TargetSelector { + def apply( + pool: Iterable[Script], + cov: Coverage, + ): (String, Script, Option[CondView]) = (names.head, choose(pool), None) + + val names = List("RandomTarget") +} diff --git a/src/main/scala/esmeta/util/BaseUtils.scala b/src/main/scala/esmeta/util/BaseUtils.scala index 77cd4b0fb9..9255bb3b20 100644 --- a/src/main/scala/esmeta/util/BaseUtils.scala +++ b/src/main/scala/esmeta/util/BaseUtils.scala @@ -120,7 +120,9 @@ object BaseUtils { private def rand = Random() /** randomly choose an element in a list */ - def choose[T](seq: Seq[T]): T = seq(rand.nextInt(seq.length)) + def choose[T](vec: Vector[T]): T = vec(rand.nextInt(vec.length)) + def choose[T](iter: Iterable[T]): T = choose(iter.toVector) + def choose[T](x: => T, y: => T): T = if randBool then x else y /** randomly choose an element in a list and return it with its index */ def chooseWithIndex[T](seq: Seq[T]): (T, Int) = @@ -133,6 +135,9 @@ object BaseUtils { def randInt(n: Int): Int = rand.nextInt(n) /** randomly choose an element in a list with different weights */ + def weightedChoose[T](seq: (T, Int)*): T = weightedChoose(seq) + def weightedChoose[T](iter: Iterable[(T, Int)]): T = + weightedChoose(iter.toArray) def weightedChoose[T](arr: Array[(T, Int)]): T = { val _arr = arr.filter(_._2 != 0) val n = rand.nextInt(_arr.map(_._2).sum) + 1