Skip to content

Enable optimisations in Expr.run #3830

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jan 15, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions compiler/src/dotty/tools/dotc/quoted/ExprCompiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ package quoted

import dotty.tools.backend.jvm.GenBCode
import dotty.tools.dotc.ast.tpd

import dotty.tools.dotc.core.Contexts.Context
import dotty.tools.dotc.core.Flags.{EmptyFlags, Method}
import dotty.tools.dotc.core.{Mode, Phases}
import dotty.tools.dotc.core.Decorators._
import dotty.tools.dotc.core.Flags._
import dotty.tools.dotc.core.Mode
import dotty.tools.dotc.core.Names.TypeName
import dotty.tools.dotc.core.Phases.Phase
import dotty.tools.dotc.core.Scopes.{EmptyScope, newScope}
import dotty.tools.dotc.core.StdNames.nme
Expand All @@ -17,14 +18,14 @@ import dotty.tools.dotc.transform.ReifyQuotes
import dotty.tools.dotc.typer.FrontEnd
import dotty.tools.dotc.util.Positions.Position
import dotty.tools.dotc.util.SourceFile
import dotty.tools.io.{Path, PlainFile, VirtualDirectory}
import dotty.tools.io.{AbstractFile, Path, PlainFile}

import scala.quoted.Expr

/** Compiler that takes the contents of a quoted expression `expr` and produces
* a class file with `class ' { def apply: Object = expr }`.
*/
class ExprCompiler(directory: VirtualDirectory) extends Compiler {
class ExprCompiler(directory: AbstractFile) extends Compiler {
import tpd._

/** A GenBCode phase that outputs to a virtual directory */
Expand All @@ -47,6 +48,8 @@ class ExprCompiler(directory: VirtualDirectory) extends Compiler {
new ExprRun(this, ctx.addMode(Mode.ReadPositions))
}

def outputClassName: TypeName = "Quoted".toTypeName

/** Frontend that receives scala.quoted.Expr as input */
class ExprFrontend(putInClass: Boolean) extends FrontEnd {
import tpd._
Expand All @@ -72,7 +75,7 @@ class ExprCompiler(directory: VirtualDirectory) extends Compiler {
val pos = Position(0)
val assocFile = new PlainFile(Path("<quote>"))

val cls = ctx.newCompleteClassSymbol(defn.RootClass, nme.QUOTE.toTypeName, EmptyFlags,
val cls = ctx.newCompleteClassSymbol(defn.RootClass, outputClassName, EmptyFlags,
defn.ObjectType :: Nil, newScope, coord = pos, assocFile = assocFile).entered.asClass
cls.enter(ctx.newDefaultConstructor(cls), EmptyScope)
val meth = ctx.newSymbol(cls, nme.apply, Method, ExprType(defn.AnyType), coord = pos).entered
Expand Down
25 changes: 16 additions & 9 deletions compiler/src/dotty/tools/dotc/quoted/QuoteDriver.scala
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package dotty.tools.dotc.quoted

import dotty.tools.dotc.Driver
import dotty.tools.dotc.core.Contexts.{Context, FreshContext}
import dotty.tools.dotc.core.Contexts.Context
import dotty.tools.dotc.core.StdNames._
import dotty.tools.io.VirtualDirectory
import dotty.tools.io.{AbstractFile, Directory, PlainDirectory, VirtualDirectory}
import dotty.tools.repl.AbstractFileClassLoader

import scala.quoted.Expr
Expand All @@ -13,18 +13,25 @@ import java.nio.charset.StandardCharsets

class QuoteDriver extends Driver {

def run[T](expr: Expr[T]): T = {
def run[T](expr: Expr[T], settings: Runners.RunSettings): T = {
val ctx: Context = initCtx.fresh
// TODO enable optimisation?
// ctx.settings.optimise.update(true)(ctx)

val outDir = new VirtualDirectory("(memory)", None)
ctx.settings.optimise.update(settings.optimise)(ctx)

val outDir: AbstractFile = settings.outDir match {
case Some(out) =>
val dir = Directory(out)
dir.createDirectory()
new PlainDirectory(Directory(out))
case None =>
new VirtualDirectory("(memory)", None)
}

new ExprCompiler(outDir).newRun(ctx).compileExpr(expr)
val driver = new ExprCompiler(outDir)
driver.newRun(ctx).compileExpr(expr)

val classLoader = new AbstractFileClassLoader(outDir, this.getClass.getClassLoader)

val clazz = classLoader.loadClass(nme.QUOTE.toString)
val clazz = classLoader.loadClass(driver.outputClassName.toString)
val method = clazz.getMethod("apply")
val instance = clazz.newInstance()

Expand Down
17 changes: 13 additions & 4 deletions compiler/src/dotty/tools/dotc/quoted/Runners.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,7 @@ object Runners {

implicit def runner[T]: Runner[T] = new Runner[T] {

def run(expr: Expr[T]): T = expr match {
case expr: ConstantExpr[T] => expr.value
case _ => new QuoteDriver().run(expr)
}
def run(expr: Expr[T]): T = Runners.run(expr, RunSettings())

def show(expr: Expr[T]): String = expr match {
case expr: ConstantExpr[T] =>
Expand All @@ -27,4 +24,16 @@ object Runners {
case _ => new QuoteDriver().show(expr)
}
}

def run[T](expr: Expr[T], settings: RunSettings): T = expr match {
case expr: ConstantExpr[T] => expr.value
case _ => new QuoteDriver().run(expr, settings)
}

case class RunSettings(
/** Enable optimisation when compiling the quoted code */
optimise: Boolean = false,
/** Output directory for the copiled quote. If set to None the output will be in memory */
outDir: Option[String] = None
)
}
10 changes: 10 additions & 0 deletions tests/run-with-compiler/quote-run-with-settings.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
val a: Int = 3
println("foo")
2.+(a)
}
foo
5

foo
5
29 changes: 29 additions & 0 deletions tests/run-with-compiler/quote-run-with-settings.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@

import java.nio.file.{Files, Paths}

import dotty.tools.dotc.quoted.Runners._

import scala.quoted._

object Test {
def main(args: Array[String]): Unit = {
val expr = '{
val a = 3
println("foo")
2 + a
}
println(expr.show)
println(expr.run)
println()

val outDir = Paths.get("../out/out-quoted-1")
val classFile = outDir.resolve("Quoted.class")

Files.deleteIfExists(classFile)

val settings = RunSettings(optimise = true, outDir = Some(outDir.toString))

println(run(expr, settings))
assert(Files.exists(classFile))
}
}
2 changes: 1 addition & 1 deletion tests/run-with-compiler/quote-run.check
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ lambda(5)
Foo
false
Bar
class '$A$1
class Quoted$A$1