From a753ad723dec2de14ee96f90ba84ef5d29d4698b Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Sun, 22 Oct 2017 12:30:41 +0200 Subject: [PATCH 1/7] Cleanup LabelDefs --- .../src/dotty/tools/backend/jvm/LabelDefs.scala | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/LabelDefs.scala b/compiler/src/dotty/tools/backend/jvm/LabelDefs.scala index a70953ab478f..5b8b0deb91c4 100644 --- a/compiler/src/dotty/tools/backend/jvm/LabelDefs.scala +++ b/compiler/src/dotty/tools/backend/jvm/LabelDefs.scala @@ -84,14 +84,10 @@ import StdNames.nme class LabelDefs extends MiniPhase { def phaseName: String = "labelDef" - val queue = new ArrayBuffer[Tree]() - val beingAppended = new mutable.HashSet[Symbol]() - var labelLevel = 0 - override def transformDefDef(tree: tpd.DefDef)(implicit ctx: Context): tpd.Tree = { - if (tree.symbol is Flags.Label) tree + if (tree.symbol is Label) tree else { - collectLabelDefs.clear + collectLabelDefs.clear() val newRhs = collectLabelDefs.transform(tree.rhs) var labelDefs = collectLabelDefs.labelDefs @@ -117,12 +113,12 @@ class LabelDefs extends MiniPhase { } } - object collectLabelDefs extends TreeMap() { + private object collectLabelDefs extends TreeMap() { // labelSymbol -> Defining tree val labelDefs = new mutable.HashMap[Symbol, Tree]() - def clear = { + def clear(): Unit = { labelDefs.clear() } @@ -135,13 +131,10 @@ class LabelDefs extends MiniPhase { case _ => r } case t: DefDef => - assert(t.symbol is Flags.Label) + assert(t.symbol is Label) val r = super.transform(tree) labelDefs(r.symbol) = r EmptyTree - case t: Apply if t.symbol is Flags.Label => - val sym = t.symbol - super.transform(tree) case _ => super.transform(tree) } From 09816bfa2c639823bd02d6d29a83f4a7b7ce7049 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Sun, 22 Oct 2017 15:58:30 +0200 Subject: [PATCH 2/7] Reimplement LabelDefs using one TreeMap less Replaces one of the TreeMap by a TreeTraverser and implements transformation in the remaining TreeMap. --- .../dotty/tools/backend/jvm/LabelDefs.scala | 54 +++++++------------ 1 file changed, 20 insertions(+), 34 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/LabelDefs.scala b/compiler/src/dotty/tools/backend/jvm/LabelDefs.scala index 5b8b0deb91c4..f91a5bc825c0 100644 --- a/compiler/src/dotty/tools/backend/jvm/LabelDefs.scala +++ b/compiler/src/dotty/tools/backend/jvm/LabelDefs.scala @@ -87,56 +87,42 @@ class LabelDefs extends MiniPhase { override def transformDefDef(tree: tpd.DefDef)(implicit ctx: Context): tpd.Tree = { if (tree.symbol is Label) tree else { - collectLabelDefs.clear() - val newRhs = collectLabelDefs.transform(tree.rhs) - var labelDefs = collectLabelDefs.labelDefs + val labelDefs = collectLabelDefs(tree.rhs) def putLabelDefsNearCallees = new TreeMap() { - override def transform(tree: tpd.Tree)(implicit ctx: Context): tpd.Tree = { tree match { + case t: Template => t case t: Apply if labelDefs.contains(t.symbol) => val labelDef = labelDefs(t.symbol) labelDefs -= t.symbol - - val labelDef2 = transform(labelDef) + val labelDef2 = cpy.DefDef(labelDef)(rhs = transform(labelDef.rhs)) Block(labelDef2:: Nil, t) - + case t: DefDef => + assert(t.symbol is Label) + EmptyTree case _ => if (labelDefs.nonEmpty) super.transform(tree) else tree } } } - val res = cpy.DefDef(tree)(rhs = putLabelDefsNearCallees.transform(newRhs)) - - res + cpy.DefDef(tree)(rhs = putLabelDefsNearCallees.transform(tree.rhs)) } } - private object collectLabelDefs extends TreeMap() { - + private def collectLabelDefs(tree: Tree)(implicit ctx: Context): mutable.HashMap[Symbol, DefDef] = { // labelSymbol -> Defining tree - val labelDefs = new mutable.HashMap[Symbol, Tree]() - - def clear(): Unit = { - labelDefs.clear() - } - - override def transform(tree: tpd.Tree)(implicit ctx: Context): tpd.Tree = tree match { - case t: Template => t - case t: Block => - val r = super.transform(t) - r match { - case t: Block if t.stats.isEmpty => t.expr - case _ => r - } - case t: DefDef => - assert(t.symbol is Label) - val r = super.transform(tree) - labelDefs(r.symbol) = r - EmptyTree - case _ => - super.transform(tree) - } + val labelDefs = new mutable.HashMap[Symbol, DefDef]() + new TreeTraverser { + override def traverse(tree: tpd.Tree)(implicit ctx: Context): Unit = tree match { + case _: Template => + case t: DefDef => + assert(t.symbol is Label) + labelDefs(t.symbol) = t + traverseChildren(t) + case _ => traverseChildren(tree) + } + }.traverse(tree) + labelDefs } } From b0747b07aa0861cc570cd2f02ab085fd90c8dd77 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 24 Oct 2017 07:31:40 +0200 Subject: [PATCH 3/7] Check that there are no Templates --- compiler/src/dotty/tools/backend/jvm/LabelDefs.scala | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/LabelDefs.scala b/compiler/src/dotty/tools/backend/jvm/LabelDefs.scala index f91a5bc825c0..666ce9e8feef 100644 --- a/compiler/src/dotty/tools/backend/jvm/LabelDefs.scala +++ b/compiler/src/dotty/tools/backend/jvm/LabelDefs.scala @@ -92,7 +92,9 @@ class LabelDefs extends MiniPhase { def putLabelDefsNearCallees = new TreeMap() { override def transform(tree: tpd.Tree)(implicit ctx: Context): tpd.Tree = { tree match { - case t: Template => t + case t: Template => + assert(false) + t case t: Apply if labelDefs.contains(t.symbol) => val labelDef = labelDefs(t.symbol) labelDefs -= t.symbol @@ -115,7 +117,7 @@ class LabelDefs extends MiniPhase { val labelDefs = new mutable.HashMap[Symbol, DefDef]() new TreeTraverser { override def traverse(tree: tpd.Tree)(implicit ctx: Context): Unit = tree match { - case _: Template => + case _: Template => assert(false) case t: DefDef => assert(t.symbol is Label) labelDefs(t.symbol) = t From 8c773d079aae81dbb88c602180ae46581561740b Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 24 Oct 2017 08:15:20 +0200 Subject: [PATCH 4/7] Remove Template from pattern match --- compiler/src/dotty/tools/backend/jvm/LabelDefs.scala | 4 ---- 1 file changed, 4 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/LabelDefs.scala b/compiler/src/dotty/tools/backend/jvm/LabelDefs.scala index 666ce9e8feef..e4abe1fbf3fe 100644 --- a/compiler/src/dotty/tools/backend/jvm/LabelDefs.scala +++ b/compiler/src/dotty/tools/backend/jvm/LabelDefs.scala @@ -92,9 +92,6 @@ class LabelDefs extends MiniPhase { def putLabelDefsNearCallees = new TreeMap() { override def transform(tree: tpd.Tree)(implicit ctx: Context): tpd.Tree = { tree match { - case t: Template => - assert(false) - t case t: Apply if labelDefs.contains(t.symbol) => val labelDef = labelDefs(t.symbol) labelDefs -= t.symbol @@ -117,7 +114,6 @@ class LabelDefs extends MiniPhase { val labelDefs = new mutable.HashMap[Symbol, DefDef]() new TreeTraverser { override def traverse(tree: tpd.Tree)(implicit ctx: Context): Unit = tree match { - case _: Template => assert(false) case t: DefDef => assert(t.symbol is Label) labelDefs(t.symbol) = t From 0995c60de0f5250d5c57354bc309d390d29a7600 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 24 Oct 2017 09:39:48 +0200 Subject: [PATCH 5/7] Remove tpd. prefixes --- compiler/src/dotty/tools/backend/jvm/LabelDefs.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/LabelDefs.scala b/compiler/src/dotty/tools/backend/jvm/LabelDefs.scala index e4abe1fbf3fe..c5c4e0b280de 100644 --- a/compiler/src/dotty/tools/backend/jvm/LabelDefs.scala +++ b/compiler/src/dotty/tools/backend/jvm/LabelDefs.scala @@ -84,13 +84,13 @@ import StdNames.nme class LabelDefs extends MiniPhase { def phaseName: String = "labelDef" - override def transformDefDef(tree: tpd.DefDef)(implicit ctx: Context): tpd.Tree = { + override def transformDefDef(tree: DefDef)(implicit ctx: Context): Tree = { if (tree.symbol is Label) tree else { val labelDefs = collectLabelDefs(tree.rhs) def putLabelDefsNearCallees = new TreeMap() { - override def transform(tree: tpd.Tree)(implicit ctx: Context): tpd.Tree = { + override def transform(tree: Tree)(implicit ctx: Context): Tree = { tree match { case t: Apply if labelDefs.contains(t.symbol) => val labelDef = labelDefs(t.symbol) @@ -113,7 +113,7 @@ class LabelDefs extends MiniPhase { // labelSymbol -> Defining tree val labelDefs = new mutable.HashMap[Symbol, DefDef]() new TreeTraverser { - override def traverse(tree: tpd.Tree)(implicit ctx: Context): Unit = tree match { + override def traverse(tree: Tree)(implicit ctx: Context): Unit = tree match { case t: DefDef => assert(t.symbol is Label) labelDefs(t.symbol) = t From 7d850ad7918df19990a0d3307cbae9fe6e4dfd90 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 24 Oct 2017 09:41:59 +0200 Subject: [PATCH 6/7] Cleanup imports --- .../dotty/tools/backend/jvm/LabelDefs.scala | 34 +++---------------- 1 file changed, 5 insertions(+), 29 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/LabelDefs.scala b/compiler/src/dotty/tools/backend/jvm/LabelDefs.scala index c5c4e0b280de..e60727e4b2ca 100644 --- a/compiler/src/dotty/tools/backend/jvm/LabelDefs.scala +++ b/compiler/src/dotty/tools/backend/jvm/LabelDefs.scala @@ -1,38 +1,12 @@ package dotty.tools.backend.jvm -import dotty.tools.dotc.ast.Trees.Thicket -import dotty.tools.dotc.ast.{Trees, tpd} +import dotty.tools.dotc.ast.tpd import dotty.tools.dotc.core.Contexts.Context -import dotty.tools.dotc.core.Types +import dotty.tools.dotc.core.Flags._ +import dotty.tools.dotc.core.Symbols._ import dotty.tools.dotc.transform.MegaPhase._ -import dotty.tools.dotc -import dotty.tools.dotc.backend.jvm.DottyPrimitives -import dotty.tools.dotc.core.Flags.FlagSet -import dotty.tools.dotc.transform.Erasure -import dotty.tools.dotc.transform.SymUtils._ -import java.io.{File => JFile} -import scala.collection.generic.Clearable import scala.collection.mutable -import scala.collection.mutable.{ListBuffer, ArrayBuffer} -import scala.reflect.ClassTag -import dotty.tools.io.{Directory, PlainDirectory, AbstractFile} -import scala.tools.asm.{ClassVisitor, FieldVisitor, MethodVisitor} -import scala.tools.nsc.backend.jvm.{BCodeHelpers, BackendInterface} -import dotty.tools.dotc.core._ -import Periods._ -import SymDenotations._ -import Contexts._ -import Types._ -import Symbols._ -import Denotations._ -import Phases._ -import java.lang.AssertionError -import dotty.tools.dotc.util.Positions.Position -import Decorators._ -import tpd._ -import Flags._ -import StdNames.nme /** * Verifies that each Label DefDef has only a single address to jump back and @@ -82,6 +56,8 @@ import StdNames.nme * @author Dmitry Petrashko */ class LabelDefs extends MiniPhase { + import tpd._ + def phaseName: String = "labelDef" override def transformDefDef(tree: DefDef)(implicit ctx: Context): Tree = { From e5dcf8ea066094ad30a3e423f88e57939e389efa Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Fri, 27 Oct 2017 14:21:36 +0200 Subject: [PATCH 7/7] Do not try to transform method if it has no labels --- compiler/src/dotty/tools/backend/jvm/LabelDefs.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/compiler/src/dotty/tools/backend/jvm/LabelDefs.scala b/compiler/src/dotty/tools/backend/jvm/LabelDefs.scala index e60727e4b2ca..26efb7257a5f 100644 --- a/compiler/src/dotty/tools/backend/jvm/LabelDefs.scala +++ b/compiler/src/dotty/tools/backend/jvm/LabelDefs.scala @@ -81,7 +81,8 @@ class LabelDefs extends MiniPhase { } } - cpy.DefDef(tree)(rhs = putLabelDefsNearCallees.transform(tree.rhs)) + if (labelDefs.isEmpty) tree + else cpy.DefDef(tree)(rhs = putLabelDefsNearCallees.transform(tree.rhs)) } }