[K/JS] Compile Kotlin coroutines as JS generator ^KT-63038 Fixed

This commit is contained in:
Artem Kobzar
2023-12-18 17:13:07 +00:00
committed by Space Team
parent 4d07fdf97e
commit 2530cba82a
73 changed files with 2240 additions and 144 deletions
@@ -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)
}
}
}
@@ -0,0 +1,5 @@
STEP 0:
modifications:
U : generator.0.kt -> generator.kt
added file: generator.kt
STEP 1:
@@ -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
@@ -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
}
@@ -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"
}
@@ -0,0 +1,5 @@
STEP 0:
dependencies: lib1, lib2
added file: m.kt
STEP 1:
dependencies: lib1, lib2
@@ -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