Skip to content

Commit fb56b95

Browse files
committed
Join logic for unpickling top level and term tasty
1 parent 0f43132 commit fb56b95

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]): 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
@@ -40,14 +40,13 @@ class DottyUnpickler(bytes: Array[Byte]) extends ClassfileParser.Embedded with t
4040
private val posUnpicklerOpt = unpickler.unpickle(new PositionsSectionUnpickler)
4141
private val treeUnpickler = unpickler.unpickle(treeSectionUnpickler(posUnpicklerOpt)).get
4242

43+
protected def mode: TreeUnpickler.UnpickleMode = TreeUnpickler.UnpickleMode.TopLevel
44+
4345
/** Enter all toplevel classes and objects into their scopes
4446
* @param roots a set of SymDenotations that should be overwritten by unpickling
4547
*/
4648
def enter(roots: Set[SymDenotation])(implicit ctx: Context): Unit =
47-
treeUnpickler.enterTopLevel(roots)
48-
49-
def unpickleExpr()(implicit ctx: Context): Tree =
50-
treeUnpickler.unpickleExpr()
49+
treeUnpickler.enter(roots)
5150

5251
def unpickleTypeTree()(implicit ctx: Context): Tree =
5352
treeUnpickler.unpickleTypeTree()
@@ -56,7 +55,7 @@ class DottyUnpickler(bytes: Array[Byte]) extends ClassfileParser.Embedded with t
5655
new TreeSectionUnpickler(posUnpicklerOpt)
5756
}
5857

59-
protected def computeTrees(implicit ctx: Context) = treeUnpickler.unpickle()
58+
protected def computeTrees(implicit ctx: Context) = treeUnpickler.unpickle(mode)
6059

6160
private[this] var ids: Array[String] = null
6261

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

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

8882
def unpickleTypeTree()(implicit ctx: Context): Tree = {
@@ -93,9 +87,14 @@ class TreeUnpickler(reader: TastyReader,
9387
}
9488

9589
/** The unpickled trees */
96-
def unpickle()(implicit ctx: Context): List[Tree] = {
90+
def unpickle(mode: UnpickleMode)(implicit ctx: Context): List[Tree] = {
9791
assert(roots != null, "unpickle without previous enterTopLevel")
98-
new TreeReader(reader).readTopLevel()
92+
val rdr = new TreeReader(reader)
93+
mode match {
94+
case UnpickleMode.TopLevel => rdr.readTopLevel()
95+
case UnpickleMode.Term => rdr.readTerm() :: Nil
96+
case UnpickleMode.TypeTree => rdr.readTpt() :: Nil
97+
}
9998
}
10099

101100
class Completer(owner: Symbol, reader: TastyReader) extends LazyType {
@@ -863,21 +862,22 @@ class TreeUnpickler(reader: TastyReader,
863862
}
864863

865864
def skipToplevel()(implicit ctx: Context): Unit= {
866-
if (!isAtEnd)
867-
nextByte match {
868-
case IMPORT | PACKAGE =>
869-
skipTree()
870-
skipToplevel()
871-
case _ =>
872-
}
865+
if (!isAtEnd && isTopLevel) {
866+
skipTree()
867+
skipToplevel()
868+
}
873869
}
874870

871+
def isTopLevel(implicit ctx: Context): Boolean =
872+
nextByte == IMPORT || nextByte == PACKAGE
873+
875874
def readTopLevel()(implicit ctx: Context): List[Tree] = {
876-
@tailrec def read(acc: ListBuffer[Tree]): List[Tree] = nextByte match {
877-
case IMPORT | PACKAGE =>
875+
@tailrec def read(acc: ListBuffer[Tree]): List[Tree] = {
876+
if (isTopLevel) {
878877
acc += readIndexedStat(NoSymbol)
879878
if (!isAtEnd) read(acc) else acc.toList
880-
case _ => // top-level trees which are not imports or packages are not part of tree
879+
}
880+
else // top-level trees which are not imports or packages are not part of tree
881881
acc.toList
882882
}
883883
read(new ListBuffer[tpd.Tree])
@@ -1273,6 +1273,13 @@ class TreeUnpickler(reader: TastyReader,
12731273

12741274
object TreeUnpickler {
12751275

1276+
sealed trait UnpickleMode
1277+
object UnpickleMode {
1278+
object TopLevel extends UnpickleMode
1279+
object Term extends UnpickleMode
1280+
object TypeTree extends UnpickleMode
1281+
}
1282+
12761283
/** A marker value used to detect cyclic reference while unpickling definitions. */
12771284
@sharable val PoisonTree: tpd.Tree = Thicket(Nil)
12781285

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

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

0 commit comments

Comments
 (0)