Refine ABI for coroutine lambdas
Make their invoke work in the same way as any other suspend function: it should return SUSPENDED_MARKER iff. it indeed became suspended
This commit is contained in:
@@ -17,7 +17,6 @@
|
|||||||
package org.jetbrains.kotlin.codegen.coroutines
|
package org.jetbrains.kotlin.codegen.coroutines
|
||||||
|
|
||||||
import com.intellij.util.ArrayUtil
|
import com.intellij.util.ArrayUtil
|
||||||
import org.jetbrains.kotlin.backend.common.CONTINUATION_RESUME_METHOD_NAME
|
|
||||||
import org.jetbrains.kotlin.codegen.*
|
import org.jetbrains.kotlin.codegen.*
|
||||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
|
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
|
||||||
import org.jetbrains.kotlin.codegen.context.ClosureContext
|
import org.jetbrains.kotlin.codegen.context.ClosureContext
|
||||||
@@ -184,16 +183,8 @@ class CoroutineCodegen(
|
|||||||
)
|
)
|
||||||
checkcast(Type.getObjectType(v.thisName))
|
checkcast(Type.getObjectType(v.thisName))
|
||||||
|
|
||||||
// .resume(Unit)
|
// .doResume(Unit)
|
||||||
StackValue.putUnitInstance(this)
|
invokeDoResumeWithUnit(v.thisName)
|
||||||
invokevirtual(
|
|
||||||
AsmTypes.COROUTINE_IMPL.internalName,
|
|
||||||
CONTINUATION_RESUME_METHOD_NAME.identifier,
|
|
||||||
Type.getMethodDescriptor(Type.VOID_TYPE, AsmTypes.OBJECT_TYPE),
|
|
||||||
false
|
|
||||||
)
|
|
||||||
|
|
||||||
loadSuspendMarker()
|
|
||||||
areturn(AsmTypes.OBJECT_TYPE)
|
areturn(AsmTypes.OBJECT_TYPE)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
// WITH_COROUTINES
|
// WITH_COROUTINES
|
||||||
// IGNORE_BACKEND: JS
|
|
||||||
import kotlin.coroutines.*
|
import kotlin.coroutines.*
|
||||||
import kotlin.coroutines.intrinsics.*
|
import kotlin.coroutines.intrinsics.*
|
||||||
|
|
||||||
@@ -82,7 +81,7 @@ fun box(): String {
|
|||||||
val k = suspendWithValue("K")
|
val k = suspendWithValue("K")
|
||||||
log += "$o$k;"
|
log += "$o$k;"
|
||||||
}
|
}
|
||||||
if (result != "suspend(O);before 0;suspend(K);before 1;OK;after 1;after 0;") return "fail1: $result"
|
if (result != "before 0;suspend(O);before 1;suspend(K);before 2;OK;after 2;after 1;after 0;") return "fail1: $result"
|
||||||
|
|
||||||
result = test {
|
result = test {
|
||||||
try {
|
try {
|
||||||
@@ -93,7 +92,7 @@ fun box(): String {
|
|||||||
log += "${e.message};"
|
log += "${e.message};"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (result != "error(OK);before 0;OK;after 0;") return "fail2: $result"
|
if (result != "before 0;error(OK);before 1;OK;after 1;after 0;") return "fail2: $result"
|
||||||
|
|
||||||
return "OK"
|
return "OK"
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -100,12 +100,12 @@ fun box(): String {
|
|||||||
var result = test {
|
var result = test {
|
||||||
test1()
|
test1()
|
||||||
}
|
}
|
||||||
if (result != "suspend();before 0;suspend(O);before 1;suspend(K);before 2;OK;after 2;after 1;after 0;") return "fail1: $result"
|
if (result != "before 0;suspend();before 1;suspend(O);before 2;suspend(K);before 3;OK;after 3;after 2;after 1;after 0;") return "fail1: $result"
|
||||||
|
|
||||||
result = test {
|
result = test {
|
||||||
test2()
|
test2()
|
||||||
}
|
}
|
||||||
if (result != "suspend();before 0;suspend(O);before 1;error(OK);before 2;OK;after 2;after 1;after 0;") return "fail2: $result"
|
if (result != "before 0;suspend();before 1;suspend(O);before 2;error(OK);before 3;OK;after 3;after 2;after 1;after 0;") return "fail2: $result"
|
||||||
|
|
||||||
return "OK"
|
return "OK"
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-7
@@ -5355,13 +5355,7 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
@TestMetadata("dispatchResume.kt")
|
@TestMetadata("dispatchResume.kt")
|
||||||
public void testDispatchResume() throws Exception {
|
public void testDispatchResume() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/dispatchResume.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/dispatchResume.kt");
|
||||||
try {
|
doTest(fileName);
|
||||||
doTest(fileName);
|
|
||||||
}
|
|
||||||
catch (Throwable ignore) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("emptyClosure.kt")
|
@TestMetadata("emptyClosure.kt")
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import kotlin.coroutines.intrinsics.*
|
|||||||
public fun <R, T> (suspend R.() -> T).createCoroutine(
|
public fun <R, T> (suspend R.() -> T).createCoroutine(
|
||||||
receiver: R,
|
receiver: R,
|
||||||
completion: Continuation<T>
|
completion: Continuation<T>
|
||||||
): Continuation<Unit> = (this as kotlin.jvm.internal.CoroutineImpl).create(receiver, completion)
|
): Continuation<Unit> = ((this as kotlin.jvm.internal.CoroutineImpl).create(receiver, completion) as kotlin.jvm.internal.CoroutineImpl).facade
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts coroutine with receiver type [R] and result type [T].
|
* Starts coroutine with receiver type [R] and result type [T].
|
||||||
@@ -30,7 +30,7 @@ public fun <R, T> (suspend R.() -> T).startCoroutine(
|
|||||||
receiver: R,
|
receiver: R,
|
||||||
completion: Continuation<T>
|
completion: Continuation<T>
|
||||||
) {
|
) {
|
||||||
(this as Function2<R, Continuation<T>, Any?>).invoke(receiver, completion)
|
createCoroutine(receiver, completion).resume(Unit)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -43,7 +43,7 @@ public fun <R, T> (suspend R.() -> T).startCoroutine(
|
|||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
public fun <T> (suspend () -> T).createCoroutine(
|
public fun <T> (suspend () -> T).createCoroutine(
|
||||||
completion: Continuation<T>
|
completion: Continuation<T>
|
||||||
): Continuation<Unit> = (this as kotlin.jvm.internal.CoroutineImpl).create(completion)
|
): Continuation<Unit> = ((this as kotlin.jvm.internal.CoroutineImpl).create(completion) as kotlin.jvm.internal.CoroutineImpl).facade
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts coroutine without receiver and with result type [T].
|
* Starts coroutine without receiver and with result type [T].
|
||||||
@@ -55,7 +55,7 @@ public fun <T> (suspend () -> T).createCoroutine(
|
|||||||
public fun <T> (suspend () -> T).startCoroutine(
|
public fun <T> (suspend () -> T).startCoroutine(
|
||||||
completion: Continuation<T>
|
completion: Continuation<T>
|
||||||
) {
|
) {
|
||||||
(this as Function1<Continuation<T>, Any?>).invoke(completion)
|
createCoroutine(completion).resume(Unit)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user