Skip to content

Commit 87d364c

Browse files
committed
Pickle quoted constants to ValueExpr
* Avoid const of unpickling * Smaller bytecode
1 parent b5d0fdf commit 87d364c

File tree

6 files changed

+67
-6
lines changed

6 files changed

+67
-6
lines changed

compiler/src/dotty/tools/dotc/core/Definitions.scala

+1
Original file line numberDiff line numberDiff line change
@@ -639,6 +639,7 @@ class Definitions {
639639
def QuotedType_apply(implicit ctx: Context) = QuotedType_applyR.symbol
640640

641641
def Unpickler_unpickleExpr = ctx.requiredMethod("scala.runtime.quoted.Unpickler.unpickleExpr")
642+
def Unpickler_unpickleValueExpr = ctx.requiredMethod("scala.runtime.quoted.Unpickler.unpickleValueExpr")
642643
def Unpickler_unpickleType = ctx.requiredMethod("scala.runtime.quoted.Unpickler.unpickleType")
643644

644645
lazy val EqType = ctx.requiredClassRef("scala.Eq")

compiler/src/dotty/tools/dotc/quoted/Toolbox.scala

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import dotty.tools.dotc.ast.Trees._
44
import dotty.tools.dotc.ast.tpd
55
import dotty.tools.dotc.core.Constants._
66
import dotty.tools.dotc.printing.RefinedPrinter
7+
import dotty.tools.dotc.transform.ReifyQuotes
78

89
import scala.quoted.Expr
910
import scala.runtime.BoxedUnit

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

+31-5
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import tasty.TreePickler.Hole
1212
import MegaPhase.MiniPhase
1313
import SymUtils._
1414
import NameKinds._
15+
import dotty.tools.dotc.ast.tpd.Tree
1516
import typer.Implicits.SearchFailureType
1617

1718
import scala.collection.mutable
@@ -290,12 +291,28 @@ class ReifyQuotes extends MacroTransformWithImplicits {
290291
}
291292
else {
292293
val (body1, splices) = nested(isQuote = true).split(body)
294+
pickledQuote(body1, splices, isType).withPos(quote.pos)
295+
}
296+
}
297+
298+
private def pickledQuote(body: Tree, splices: List[Tree], isType: Boolean)(implicit ctx: Context) = {
299+
def pickleAsValue[T](value: T) = {
300+
ref(defn.Unpickler_unpickleValueExpr)
301+
.appliedToType(body.tpe.widen)
302+
.appliedTo(Literal(Constant(value)))
303+
}
304+
def pickleAsTasty() = {
293305
val meth =
294-
if (isType) ref(defn.Unpickler_unpickleType).appliedToType(body1.tpe)
295-
else ref(defn.Unpickler_unpickleExpr).appliedToType(body1.tpe.widen)
306+
if (isType) ref(defn.Unpickler_unpickleType).appliedToType(body.tpe)
307+
else ref(defn.Unpickler_unpickleExpr).appliedToType(body.tpe.widen)
296308
meth.appliedTo(
297-
liftList(PickledQuotes.pickleQuote(body1).map(x => Literal(Constant(x))), defn.StringType),
298-
liftList(splices, defn.AnyType)).withPos(quote.pos)
309+
liftList(PickledQuotes.pickleQuote(body).map(x => Literal(Constant(x))), defn.StringType),
310+
liftList(splices, defn.AnyType))
311+
}
312+
if (splices.nonEmpty) pickleAsTasty()
313+
else ReifyQuotes.toValue(body) match {
314+
case Some(value) => pickleAsValue(value)
315+
case _ => pickleAsTasty()
299316
}
300317
}
301318

@@ -473,4 +490,13 @@ class ReifyQuotes extends MacroTransformWithImplicits {
473490
}
474491
}
475492
}
476-
}
493+
}
494+
495+
object ReifyQuotes {
496+
def toValue(tree: Tree): Option[Any] = tree match {
497+
case Literal(Constant(c)) => Some(c)
498+
case Block(Nil, e) => toValue(e)
499+
case Inlined(_, Nil, e) => toValue(e)
500+
case _ => None
501+
}
502+
}

library/src/scala/runtime/quoted/Unpickler.scala

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package scala.runtime.quoted
22

33
import scala.quoted.Types.TastyType
4-
import scala.quoted.Exprs.TastyExpr
4+
import scala.quoted.Exprs.{TastyExpr, ValueExpr}
55
import scala.quoted.{Expr, Type}
66

77
/** Provides methods to unpickle `Expr` and `Type` trees. */
@@ -17,6 +17,9 @@ object Unpickler {
1717
*/
1818
def unpickleExpr[T](repr: Pickled, args: Seq[Any]): Expr[T] = new TastyExpr[T](repr, args)
1919

20+
/** Unpickle `value` which represents a pickled `Expr` tree for `value` itself */
21+
def unpickleValueExpr[T](value: T): Expr[T] = new ValueExpr[T](value)
22+
2023
/** Unpickle `repr` which represents a pickled `Type` tree,
2124
* replacing splice nodes with `args`
2225
*/
+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
class scala.quoted.Exprs$ValueExpr
2+
class scala.quoted.Exprs$ValueExpr
3+
class scala.quoted.Exprs$ValueExpr
4+
class scala.quoted.Exprs$ValueExpr
5+
class scala.quoted.Exprs$ValueExpr
6+
class scala.quoted.Exprs$ValueExpr
7+
class scala.quoted.Exprs$ValueExpr
8+
class scala.quoted.Exprs$ValueExpr
9+
class scala.quoted.Exprs$ValueExpr
10+
class scala.quoted.Exprs$ValueExpr
11+
class scala.quoted.Exprs$ValueExpr
12+
class scala.quoted.Exprs$ValueExpr
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import scala.quoted._
2+
3+
object Test {
4+
def main(args: Array[String]): Unit = {
5+
println(('(true)).getClass)
6+
println(('{ 'a' }).getClass)
7+
println(('{ '\n' }).getClass)
8+
println(('{ '"' }).getClass)
9+
println(('{ '\'' }).getClass)
10+
println(('{ '\\' }).getClass)
11+
println(('(1)).getClass)
12+
println(('( { { 2 } } )).getClass)
13+
println(('(3L)).getClass)
14+
println(('(4.0f)).getClass)
15+
println(('(5.0d)).getClass)
16+
println(('("xyz")).getClass)
17+
}
18+
}

0 commit comments

Comments
 (0)