diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2012-11-26 16:00:13 +0100 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2012-11-26 16:26:55 +0100 |
commit | fe26ed3f0e589c91d3f1099000a83e44814224d9 (patch) | |
tree | c35fa23e2ff9744ae7061f31a5f4c20dfbf6ddcd /src | |
parent | 37de4d569e30f29f854aeeeeb4f1f7f53dcda97f (diff) | |
download | scala-async-fe26ed3f0e589c91d3f1099000a83e44814224d9.tar.gz scala-async-fe26ed3f0e589c91d3f1099000a83e44814224d9.tar.bz2 scala-async-fe26ed3f0e589c91d3f1099000a83e44814224d9.zip |
Fix #26, leaner code gen for `async { <no awaits> }`.
We can then use this as a replacement for `Future { expr }`.
Diffstat (limited to 'src')
-rw-r--r-- | src/main/scala/scala/async/Async.scala | 29 |
1 files changed, 20 insertions, 9 deletions
diff --git a/src/main/scala/scala/async/Async.scala b/src/main/scala/scala/async/Async.scala index 09e002d..4a770ed 100644 --- a/src/main/scala/scala/async/Async.scala +++ b/src/main/scala/scala/async/Async.scala @@ -115,7 +115,7 @@ abstract class AsyncBase { val stateMachineType = utils.applied("scala.async.StateMachine", List(futureSystemOps.promType[T], futureSystemOps.execContextType)) - val stateMachine: ClassDef = { + lazy val stateMachine: ClassDef = { val body: List[Tree] = { val stateVar = ValDef(Modifiers(Flag.MUTABLE), name.state, TypeTree(definitions.IntTpe), Literal(Constant(0))) val result = ValDef(NoMods, name.result, TypeTree(futureSystemOps.promType[T]), futureSystemOps.createProm[T].tree) @@ -142,14 +142,24 @@ abstract class AsyncBase { def selectStateMachine(selection: TermName) = Select(Ident(name.stateMachine), selection) - val code = c.Expr[futureSystem.Fut[T]](Block(List[Tree]( - stateMachine, - ValDef(NoMods, name.stateMachine, stateMachineType, New(Ident(name.stateMachineT), Nil)), - futureSystemOps.future(c.Expr[Unit](Apply(selectStateMachine(name.apply), Nil))) - (c.Expr[futureSystem.ExecContext](selectStateMachine(name.execContext))).tree - ), - futureSystemOps.promiseToFuture(c.Expr[futureSystem.Prom[T]](selectStateMachine(name.result))).tree - )) + def spawn(tree: Tree): Tree = + futureSystemOps.future(c.Expr[Unit](tree))(c.Expr[futureSystem.ExecContext](selectStateMachine(name.execContext))).tree + + val code: c.Expr[futureSystem.Fut[T]] = { + val isSimple = asyncStates.size == 1 + val tree = + if (isSimple) + Block(Nil, spawn(body.tree)) // generate lean code for the simple case of `async { 1 + 1 }` + else { + Block(List[Tree]( + stateMachine, + ValDef(NoMods, name.stateMachine, stateMachineType, New(Ident(name.stateMachineT), Nil)), + spawn(Apply(selectStateMachine(name.apply), Nil)) + ), + futureSystemOps.promiseToFuture(c.Expr[futureSystem.Prom[T]](selectStateMachine(name.result))).tree) + } + c.Expr[futureSystem.Fut[T]](tree) + } AsyncUtils.vprintln(s"async state machine transform expands to:\n ${code.tree}") code @@ -173,5 +183,6 @@ abstract class AsyncBase { /** Internal class used by the `async` macro; should not be manually extended by client code */ abstract class StateMachine[Result, EC] extends (scala.util.Try[Any] => Unit) with (() => Unit) { def result$async: Result + def execContext$async: EC } |