Skip to content

Instantly share code, notes, and snippets.

@diesalbla
Created June 14, 2023 10:26
Show Gist options
  • Save diesalbla/62677eac3ff10edab745b91b58a48f29 to your computer and use it in GitHub Desktop.
Save diesalbla/62677eac3ff10edab745b91b58a48f29 to your computer and use it in GitHub Desktop.
Scala SIP - Coroutine Proposal - Generated runNextLeg
def runNextLeg(a: Int, b: Int)(completion: Continuation[Int]): Int | Suspended =
var a$1:Int = a
var b$2:Int = b
var z$3:Boolean = null
var m$4:Int = null
var g$5:Int = null
val frame = frame match {
case x$0 @ _:GcdFrame if x$0.state & Int.MinValue != 0 =>
x$0.state = x$0.state - Int.MinValue
x$0
case _ => new GcdFrame(0, a$1, b$2, z$3, m$4, g$5, null, completion)
}
frame.state match {
case 0 => // function entry when runNextLeg has not been suspended
// initialize the variables
frame.a = a$1
frame.b = b$2
frame.z = z$3
frame.m = m$4
frame.g = g$5
frame.state = 1
val safeCoroutine = SafeFrame.init[Boolean](frame)
safeCoroutine.resume(isZero(b$2)(completion))
safeCoroutine.getOrThrow() match {
// isZero returned suspended, so we return Suspended
// and will continue from `case 1`
case Coroutine.State.Suspended =>
return Coroutine.State.Suspended
case intermediateResult =>
frame.z = intermediateResult
z$3 = intermediateResult
return[label1] ()
}
case 1 =>
// isZero suspended, and we have been resumed
// with frame.label == 1
// with something, which could be an error. So we need to
// re-initialize from the Frame's stored values
frame.a = a$1
frame.b = b$2
frame.z = z$3
frame.m = m$4
frame.g = g$5
//is there an error in frame.result? Perhaps a cancellation? Stop here if so.
continuations.checkResult(frame)
// isZero returned a result, so we continue from `case intermediateResult`.
// frame.z is guaranteed to exist here.
// skipping the re-initialization above
label1[Unit]: <empty>
a$1 = frame.a
b$2 = frame.b
z$3 = frame.z
m$4 = frame.m
g$5 = frame.g
// if-then-else is not a coroutine, so we can substitute the isZero intermediate result
if (z$3) {
return a$1
} else {
frame.state = 2
val safeCoroutine = SafeFrame.init[Int](frame)
safeCoroutine.resume(mod(a$1, b$2)(completion))
safeCoroutine.getOrThrow() match {
// mod returned suspended, so we return Suspended
// and will continue from `case 2`
case Coroutine.State.Suspended =>
return Coroutine.State.Suspended
case intermediateResult2 =>
frame.m = intermediateResult2
m$4 = intermediateResult2
return[label2] ()
}
}
case 2 =>
// mod suspended, and we have been resumed
// with frame.label == 2
// with something, which could be an error. So we need to
// re-initialize from the Frame's stored values
frame.a = a$1
frame.b = b$2
frame.z = z$3
frame.m = m$4
frame.g = g$5
//is there an error in frame.result? Perhaps a cancellation? Stop here if so.
continuations.checkResult(frame)
// mod returned a result, so we continue from `case intermediateResult2`.
// frame.z is guaranteed to exist here.
// frame.m is guaranteed to exist here.
// skipping the re-initialization above
label2[Unit]: <empty>
a$1 = frame.a
b$2 = frame.b
z$3 = frame.z
m$4 = frame.m
g$5 = frame.g
frame.state = 3
val safeCoroutine = SafeFrame.init[Int](frame)
safeCoroutine.resume(gcd(b$2, m$4)(completion))
safeCoroutine.getOrThrow() match {
// gcd returned suspended, so we return Suspended
// and will continue from `case 3`
case Coroutine.State.Suspended =>
return Coroutine.State.Suspended
case intermediateResult3 =>
frame.g = intermediateResult3
g$5 = intermediateResult3
return[label3] ()
}
case 3 =>
// gcd suspended, and we have been resumed
// with frame.label == 3
// with something, which could be an error. So we need to
// re-initialize from the Frame's stored values
frame.a = a$1
frame.b = b$2
frame.z = z$3
frame.m = m$4
frame.g = g$5
//is there an error in frame.result? Perhaps a cancellation? Stop here if so.
continuations.checkResult(frame)
// gcd returned a result, so we continue from `case intermediateResult3`.
// frame.z is guaranteed to exist here.
// frame.m is guaranteed to exist here.
// frame.g is guaranteed to exist here.
// skipping the re-initialization above
label3[Unit]: <empty>
a$1 = frame.a
b$2 = frame.b
z$3 = frame.z
m$4 = frame.m
g$5 = frame.g
// we now have z, m, and g, so we can simply return our result + 1:
g$5 + 1
case _ => // a launcher or completion did something illegal and we didn't resume with a valid frame state
throw new IllegalArgumentException("call to \'resume\' before \'invoke\' with coroutine")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment