From 1333b3837d405c31baaa44d1db89aab0f7d09349 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Thu, 11 Dec 2014 21:30:35 +1000 Subject: Avoid unbounded stack consumption for synchronous control flow Previously, as sequence of state transitions that did not pass through an asynchrous boundary incurred stack frames. The trivial loop in the enclosed test case would then overflow the stack. This commit merges the `resume` and `apply(tr: Try[Any])` methods into a `apply`. It changes the body of this method to be an infinite loop with returns at the terminal points in the state machine (or at a terminal failure.) To allow merging of these previously separate matches, states that contain an await are now allocated two state ids: one for the setup code that calls `onComplete`, and one for the code in the continuation that records the result and advances the state machine. Fixes #93 --- src/main/scala/scala/async/internal/StateAssigner.scala | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'src/main/scala/scala/async/internal/StateAssigner.scala') diff --git a/src/main/scala/scala/async/internal/StateAssigner.scala b/src/main/scala/scala/async/internal/StateAssigner.scala index 8f0d518..55e7a51 100644 --- a/src/main/scala/scala/async/internal/StateAssigner.scala +++ b/src/main/scala/scala/async/internal/StateAssigner.scala @@ -5,10 +5,12 @@ package scala.async.internal private[async] final class StateAssigner { - private var current = -1 + private var current = StateAssigner.Initial - def nextState(): Int = { - current += 1 - current - } + def nextState(): Int = + try current finally current += 1 } + +object StateAssigner { + final val Initial = 0 +} \ No newline at end of file -- cgit v1.2.3