Skip to content

Commit ff70a12

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

File tree

6 files changed

+67
-5
lines changed

6 files changed

+67
-5
lines changed

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

+6
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,12 @@ class Definitions {
628628
lazy val QuotedExpr_runR = QuotedExprClass.requiredMethodRef(nme.run)
629629
def QuotedExpr_run(implicit ctx: Context) = QuotedExpr_runR.symbol
630630

631+
lazy val QuotedExprsModule = ctx.requiredModule("scala.quoted.Exprs")
632+
def QuotedExprsClass(implicit ctx: Context) = QuotedExprsModule.symbol.asClass
633+
634+
lazy val QuotedExprs_valueExprR = QuotedExprsModule.requiredMethod("valueExpr")
635+
def QuotedExprs_valueExpr(implicit ctx: Context) = QuotedExprs_valueExprR.symbol
636+
631637
lazy val QuotedTypeType = ctx.requiredClassRef("scala.quoted.Type")
632638
def QuotedTypeClass(implicit ctx: Context) = QuotedTypeType.symbol.asClass
633639

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

+28-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,25 @@ 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.QuotedExprs_valueExpr).appliedToType(body.tpe.widen).appliedTo(Literal(Constant(value)))
301+
def pickleAsTasty() = {
293302
val meth =
294-
if (isType) ref(defn.Unpickler_unpickleType).appliedToType(body1.tpe)
295-
else ref(defn.Unpickler_unpickleExpr).appliedToType(body1.tpe.widen)
303+
if (isType) ref(defn.Unpickler_unpickleType).appliedToType(body.tpe)
304+
else ref(defn.Unpickler_unpickleExpr).appliedToType(body.tpe.widen)
296305
meth.appliedTo(
297-
liftList(PickledQuotes.pickleQuote(body1).map(x => Literal(Constant(x))), defn.StringType),
298-
liftList(splices, defn.AnyType)).withPos(quote.pos)
306+
liftList(PickledQuotes.pickleQuote(body).map(x => Literal(Constant(x))), defn.StringType),
307+
liftList(splices, defn.AnyType))
308+
}
309+
if (splices.nonEmpty) pickleAsTasty()
310+
else ReifyQuotes.toValue(body) match {
311+
case Some(value) => pickleAsValue(value)
312+
case _ => pickleAsTasty()
299313
}
300314
}
301315

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

library/src/scala/quoted/Expr.scala

+2
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ object Exprs {
3535
override def toString: String = s"Expr($value)"
3636
}
3737

38+
def valueExpr[T](value: T): ValueExpr[T] = new ValueExpr[T](value)
39+
3840
/** An Expr backed by a tree. Only the current compiler trees are allowed. */
3941
final class TreeExpr[Tree](val tree: Tree) extends quoted.Expr[Any] {
4042
override def toString: String = s"Expr(<raw>)"
+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)