Fix default value generation after suspension point
Replace coercion from VOID with call 'pushDefaultValueOnStack' It's necessary because coercion of VOID to java/lang/Object ends with Unit instance on stack that makes variables spilling algorithm thinking that variable is Unit #KT-13409 Fixed
This commit is contained in:
@@ -2875,7 +2875,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
callGenerator.genCall(callableMethod, resolvedCall, defaultMaskWasGenerated, this);
|
callGenerator.genCall(callableMethod, resolvedCall, defaultMaskWasGenerated, this);
|
||||||
|
|
||||||
if (isSuspensionPoint) {
|
if (isSuspensionPoint) {
|
||||||
StackValue.coerce(Type.VOID_TYPE, getSuspensionReturnTypeByResolvedCall(resolvedCall), v);
|
AsmUtil.pushDefaultValueOnStack(getSuspensionReturnTypeByResolvedCall(resolvedCall), v);
|
||||||
v.invokestatic(
|
v.invokestatic(
|
||||||
CoroutineCodegenUtilKt.COROUTINE_MARKER_OWNER,
|
CoroutineCodegenUtilKt.COROUTINE_MARKER_OWNER,
|
||||||
CoroutineCodegenUtilKt.AFTER_SUSPENSION_POINT_MARKER_NAME, "()V", false);
|
CoroutineCodegenUtilKt.AFTER_SUSPENSION_POINT_MARKER_NAME, "()V", false);
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
class Controller {
|
||||||
|
suspend fun <T> suspendHere(v: T, x: Continuation<T>) {
|
||||||
|
x.resume(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun builder(coroutine c: Controller.() -> Continuation<Unit>) {
|
||||||
|
c(Controller()).resume(Unit)
|
||||||
|
}
|
||||||
|
|
||||||
|
var result: Any = ""
|
||||||
|
|
||||||
|
fun <T : Any> foo(v: T) {
|
||||||
|
builder {
|
||||||
|
val r = suspendHere(v)
|
||||||
|
suspendHere("")
|
||||||
|
result = r
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
foo("OK")
|
||||||
|
return result as String
|
||||||
|
}
|
||||||
@@ -4348,6 +4348,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("falseUnitCoercion.kt")
|
||||||
|
public void testFalseUnitCoercion() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/falseUnitCoercion.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("generate.kt")
|
@TestMetadata("generate.kt")
|
||||||
public void testGenerate() throws Exception {
|
public void testGenerate() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/generate.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/coroutines/generate.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user