Skip to content

Commit 8f5a8ab

Browse files
committed
Join logic for unpickling top level and term tasty
1 parent 385082b commit 8f5a8ab

File tree

5 files changed

+40
-32
lines changed

5 files changed

+40
-32
lines changed

compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,15 +99,14 @@ object PickledQuotes {
9999

100100
/** Unpickle TASTY bytes into it's tree */
101101
private def unpickle(bytes: Array[Byte], splices: Seq[Any], isType: Boolean)(implicit ctx: Context): Tree = {
102-
val unpickler = new TastyUnpickler(bytes, splices)
103102
if (pickling ne noPrinter) {
104103
println(i"**** unpickling quote from TASTY")
105104
new TastyPrinter(bytes).printContents()
106105
}
107106

108-
val tree =
109-
if (isType) unpickler.unpickleTypeTree()
110-
else unpickler.unpickleExpr()
107+
val unpickler = new TastyUnpickler(bytes, splices, isType)
108+
unpickler.enter(Set.empty)
109+
val tree = unpickler.tree
111110

112111
if (pickling ne noPrinter)
113112
println(i"**** unpickle quote ${tree.show}")

compiler/src/dotty/tools/dotc/core/quoted/TastyUnpickler.scala

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,13 @@ object TastyUnpickler {
1515
* @param bytes the bytearray containing the Tasty file from which we unpickle
1616
* @param splices splices that will fill the holes in the quote
1717
*/
18-
class TastyUnpickler(bytes: Array[Byte], splices: Seq[Any]) extends DottyUnpickler(bytes) {
18+
class TastyUnpickler(bytes: Array[Byte], splices: Seq[Any], isTypeTree: Boolean) extends DottyUnpickler(bytes) {
1919
import DottyUnpickler._
2020
import TastyUnpickler._
2121

22+
override protected def mode: TreeUnpickler.UnpickleMode =
23+
if (isTypeTree) TreeUnpickler.UnpickleMode.TypeTree else TreeUnpickler.UnpickleMode.Term
24+
2225
protected override def treeSectionUnpickler(posUnpicklerOpt: Option[PositionUnpickler], commentUnpicklerOpt: Option[CommentUnpickler]): TreeSectionUnpickler =
2326
new QuotedTreeSectionUnpickler(posUnpicklerOpt, splices)
2427
}

compiler/src/dotty/tools/dotc/core/tasty/DottyUnpickler.scala

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,13 @@ class DottyUnpickler(bytes: Array[Byte]) extends ClassfileParser.Embedded with t
4646
private val commentUnpicklerOpt = unpickler.unpickle(new CommentsSectionUnpickler)
4747
private val treeUnpickler = unpickler.unpickle(treeSectionUnpickler(posUnpicklerOpt, commentUnpicklerOpt)).get
4848

49+
protected def mode: TreeUnpickler.UnpickleMode = TreeUnpickler.UnpickleMode.TopLevel
50+
4951
/** Enter all toplevel classes and objects into their scopes
5052
* @param roots a set of SymDenotations that should be overwritten by unpickling
5153
*/
5254
def enter(roots: Set[SymDenotation])(implicit ctx: Context): Unit =
53-
treeUnpickler.enterTopLevel(roots)
54-
55-
def unpickleExpr()(implicit ctx: Context): Tree =
56-
treeUnpickler.unpickleExpr()
55+
treeUnpickler.enter(roots)
5756

5857
def unpickleTypeTree()(implicit ctx: Context): Tree =
5958
treeUnpickler.unpickleTypeTree()
@@ -62,7 +61,7 @@ class DottyUnpickler(bytes: Array[Byte]) extends ClassfileParser.Embedded with t
6261
new TreeSectionUnpickler(posUnpicklerOpt, commentUnpicklerOpt)
6362
}
6463

65-
protected def computeTrees(implicit ctx: Context) = treeUnpickler.unpickle()
64+
protected def computeTrees(implicit ctx: Context) = treeUnpickler.unpickle(mode)
6665

6766
private[this] var ids: Array[String] = null
6867

compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -74,18 +74,12 @@ class TreeUnpickler(reader: TastyReader,
7474
/** Enter all toplevel classes and objects into their scopes
7575
* @param roots a set of SymDenotations that should be overwritten by unpickling
7676
*/
77-
def enterTopLevel(roots: Set[SymDenotation])(implicit ctx: Context): Unit = {
77+
def enter(roots: Set[SymDenotation])(implicit ctx: Context): Unit = {
7878
this.roots = roots
7979
val rdr = new TreeReader(reader).fork
8080
ownerTree = new OwnerTree(NoAddr, 0, rdr.fork, reader.endAddr)
81-
rdr.indexStats(reader.endAddr)
82-
}
83-
84-
def unpickleExpr()(implicit ctx: Context): Tree = {
85-
this.roots = Set(ctx.owner)
86-
val rdr = new TreeReader(reader).fork
87-
ownerTree = new OwnerTree(NoAddr, 0, rdr.fork, reader.endAddr)
88-
rdr.readTerm()
81+
if (rdr.isTopLevel)
82+
rdr.indexStats(reader.endAddr)
8983
}
9084

9185
def unpickleTypeTree()(implicit ctx: Context): Tree = {
@@ -96,9 +90,14 @@ class TreeUnpickler(reader: TastyReader,
9690
}
9791

9892
/** The unpickled trees */
99-
def unpickle()(implicit ctx: Context): List[Tree] = {
93+
def unpickle(mode: UnpickleMode)(implicit ctx: Context): List[Tree] = {
10094
assert(roots != null, "unpickle without previous enterTopLevel")
101-
new TreeReader(reader).readTopLevel()
95+
val rdr = new TreeReader(reader)
96+
mode match {
97+
case UnpickleMode.TopLevel => rdr.readTopLevel()
98+
case UnpickleMode.Term => rdr.readTerm() :: Nil
99+
case UnpickleMode.TypeTree => rdr.readTpt() :: Nil
100+
}
102101
}
103102

104103
class Completer(owner: Symbol, reader: TastyReader) extends LazyType {
@@ -885,21 +884,22 @@ class TreeUnpickler(reader: TastyReader,
885884
}
886885

887886
def skipToplevel()(implicit ctx: Context): Unit= {
888-
if (!isAtEnd)
889-
nextByte match {
890-
case IMPORT | PACKAGE =>
891-
skipTree()
892-
skipToplevel()
893-
case _ =>
894-
}
887+
if (!isAtEnd && isTopLevel) {
888+
skipTree()
889+
skipToplevel()
890+
}
895891
}
896892

893+
def isTopLevel(implicit ctx: Context): Boolean =
894+
nextByte == IMPORT || nextByte == PACKAGE
895+
897896
def readTopLevel()(implicit ctx: Context): List[Tree] = {
898-
@tailrec def read(acc: ListBuffer[Tree]): List[Tree] = nextByte match {
899-
case IMPORT | PACKAGE =>
897+
@tailrec def read(acc: ListBuffer[Tree]): List[Tree] = {
898+
if (isTopLevel) {
900899
acc += readIndexedStat(NoSymbol)
901900
if (!isAtEnd) read(acc) else acc.toList
902-
case _ => // top-level trees which are not imports or packages are not part of tree
901+
}
902+
else // top-level trees which are not imports or packages are not part of tree
903903
acc.toList
904904
}
905905
read(new ListBuffer[tpd.Tree])
@@ -1298,6 +1298,13 @@ class TreeUnpickler(reader: TastyReader,
12981298

12991299
object TreeUnpickler {
13001300

1301+
sealed trait UnpickleMode
1302+
object UnpickleMode {
1303+
object TopLevel extends UnpickleMode
1304+
object Term extends UnpickleMode
1305+
object TypeTree extends UnpickleMode
1306+
}
1307+
13011308
/** A marker value used to detect cyclic reference while unpickling definitions. */
13021309
@sharable val PoisonTree: tpd.Tree = Thicket(Nil)
13031310

compiler/src/dotty/tools/dotc/transform/Pickler.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ class Pickler extends Phase {
9898
val unpicklers =
9999
for ((cls, pickler) <- picklers) yield {
100100
val unpickler = new DottyUnpickler(pickler.assembleParts())
101-
unpickler.enter(roots = Set())
101+
unpickler.enter(roots = Set.empty)
102102
cls -> unpickler
103103
}
104104
pickling.println("************* entered toplevel ***********")

0 commit comments

Comments
 (0)