[K/JS] Compile Kotlin coroutines as JS generator ^KT-63038 Fixed
This commit is contained in:
+57
@@ -0,0 +1,57 @@
|
||||
import kotlin.coroutines.*
|
||||
|
||||
abstract class Generator<T> {
|
||||
private var generatorContinuation: Continuation<Unit>? = null
|
||||
private var callerContinuation: Continuation<T>? = null
|
||||
|
||||
fun resetGenerator() {
|
||||
this::initGenerator.startCoroutine(object: Continuation<Unit> {
|
||||
override val context = EmptyCoroutineContext
|
||||
override fun resumeWith(result: Result<Unit>) {
|
||||
result.getOrThrow()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
suspend fun yieldValue(x: T) {
|
||||
suspendCoroutine { continuation ->
|
||||
generatorContinuation = continuation
|
||||
callerContinuation?.resume(x)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun initGenerator() {
|
||||
suspendCoroutine { continuation ->
|
||||
generatorContinuation = continuation
|
||||
}
|
||||
|
||||
generatorBody()
|
||||
|
||||
generatorContinuation = null
|
||||
}
|
||||
|
||||
protected abstract suspend fun generatorBody()
|
||||
|
||||
fun hasNext(): Boolean {
|
||||
return generatorContinuation != null
|
||||
}
|
||||
|
||||
suspend fun nextValue(): T {
|
||||
return suspendCoroutine { continuation ->
|
||||
callerContinuation = continuation
|
||||
generatorContinuation?.resume(Unit)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ClosedRangeGenerator(
|
||||
private val rangeStart: Int,
|
||||
private val rangeEnd: Int,
|
||||
private val step: Int
|
||||
) : Generator<Int>() {
|
||||
override suspend fun generatorBody() {
|
||||
for (i in IntProgression.fromClosedRange(rangeStart, rangeEnd, step)) {
|
||||
yieldValue(i)
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
STEP 0:
|
||||
modifications:
|
||||
U : generator.0.kt -> generator.kt
|
||||
added file: generator.kt
|
||||
STEP 1:
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
STEP 0:
|
||||
dependencies: lib1
|
||||
modifications:
|
||||
U : test.0.kt -> test.kt
|
||||
added file: test.kt
|
||||
STEP 1:
|
||||
dependencies: lib1
|
||||
modifications:
|
||||
U : test.1.kt -> test.kt
|
||||
modified ir: test.kt
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
import kotlin.coroutines.*
|
||||
|
||||
private fun runCoroutine(c: suspend () -> Unit) {
|
||||
c.startCoroutine(object: Continuation<Unit> {
|
||||
override val context = EmptyCoroutineContext
|
||||
override fun resumeWith(result: Result<Unit>) {
|
||||
result.getOrThrow()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun test(): Int {
|
||||
val generator = ClosedRangeGenerator(0, 0, 1)
|
||||
generator.resetGenerator()
|
||||
var s = 0
|
||||
runCoroutine {
|
||||
while(generator.hasNext()) {
|
||||
s += generator.nextValue()
|
||||
}
|
||||
}
|
||||
return s
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
import kotlin.coroutines.*
|
||||
|
||||
private fun runCoroutine(c: suspend () -> Unit) {
|
||||
c.startCoroutine(object: Continuation<Unit> {
|
||||
override val context = EmptyCoroutineContext
|
||||
override fun resumeWith(result: Result<Unit>) {
|
||||
result.getOrThrow()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun test(): Int {
|
||||
val generator = ClosedRangeGenerator(0, 1, 1)
|
||||
generator.resetGenerator()
|
||||
var s = 0
|
||||
runCoroutine {
|
||||
while(generator.hasNext()) {
|
||||
s += generator.nextValue()
|
||||
}
|
||||
}
|
||||
return s
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fun box(stepId: Int): String {
|
||||
val got = test()
|
||||
if (got != stepId) {
|
||||
return "Fail: $got != $stepId"
|
||||
}
|
||||
return "OK"
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
STEP 0:
|
||||
dependencies: lib1, lib2
|
||||
added file: m.kt
|
||||
STEP 1:
|
||||
dependencies: lib1, lib2
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
MODULES: lib1, lib2, main
|
||||
|
||||
STEP 0:
|
||||
libs: lib1, lib2, main
|
||||
dirty js modules: lib1, lib2, main
|
||||
dirty js files: lib1/generator, lib2/test, main/m, main/m.export, main
|
||||
STEP 1:
|
||||
libs: lib1, lib2, main
|
||||
dirty js modules: lib2
|
||||
dirty js files: lib2/test
|
||||
Reference in New Issue
Block a user