Add NOP as first instruction in coroutine's try blocks
#KT-35035 Fixed
This commit is contained in:
+3
-1
@@ -783,13 +783,15 @@ class CoroutineTransformerMethodVisitor(
|
||||
// See 'splitTryCatchBlocksContainingSuspensionPoint'
|
||||
val possibleTryCatchBlockStart = suspension.tryCatchBlocksContinuationLabel
|
||||
|
||||
// Remove NOP as it's unnecessary anymore
|
||||
// Move NOP, which is inserted in `splitTryCatchBlocksContainingSuspentionPoint`, inside the try catch block,
|
||||
// so the inliner can transform suspend lambdas during inlining
|
||||
assert(possibleTryCatchBlockStart.previous.opcode == Opcodes.NOP) {
|
||||
"NOP expected but ${possibleTryCatchBlockStart.previous.opcode} was found"
|
||||
}
|
||||
remove(possibleTryCatchBlockStart.previous)
|
||||
|
||||
insert(possibleTryCatchBlockStart, withInstructionAdapter {
|
||||
nop()
|
||||
generateResumeWithExceptionCheck(languageVersionSettings.isReleaseCoroutines(), dataIndex, exceptionIndex)
|
||||
|
||||
// Load continuation argument just like suspending function returns it
|
||||
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
// FILE: test.kt
|
||||
// WITH_RUNTIME
|
||||
// WITH_COROUTINES
|
||||
// CHECK_STATE_MACHINE
|
||||
// NO_CHECK_LAMBDA_INLINING
|
||||
|
||||
import helpers.*
|
||||
import kotlin.coroutines.*
|
||||
|
||||
const val DEBUG = false
|
||||
inline fun inlineFun(b: () -> Unit) {
|
||||
if (DEBUG) {
|
||||
inlineFunReal(b)
|
||||
}
|
||||
}
|
||||
|
||||
inline fun inlineFunReal(b: () -> Unit) {
|
||||
try {
|
||||
b()
|
||||
} finally {
|
||||
}
|
||||
}
|
||||
|
||||
fun builder(c: suspend () -> Unit) {
|
||||
c.startCoroutine(CheckStateMachineContinuation)
|
||||
}
|
||||
|
||||
// FILE: box.kt
|
||||
import helpers.*
|
||||
|
||||
class Sample {
|
||||
fun test() {
|
||||
inlineFun {
|
||||
builder {
|
||||
inlineFun {
|
||||
suspendFun()
|
||||
suspendFun()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun suspendFun() = StateMachineChecker.suspendHere()
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
Sample().test()
|
||||
StateMachineChecker.check(0, checkFinished = false)
|
||||
return "OK"
|
||||
}
|
||||
@@ -94,7 +94,7 @@ fun createTextForHelpers(isReleaseCoroutines: Boolean, checkStateMachine: Boolea
|
||||
proceed = { c.resume(Unit) }
|
||||
}
|
||||
|
||||
fun check(numberOfSuspensions: Int) {
|
||||
fun check(numberOfSuspensions: Int, checkFinished: Boolean = true) {
|
||||
for (i in 1..numberOfSuspensions) {
|
||||
if (counter != i) error("Wrong state-machine generated: suspendHere should be called exactly once in one state. Expected " + i + ", got " + counter)
|
||||
proceed()
|
||||
@@ -103,7 +103,7 @@ fun createTextForHelpers(isReleaseCoroutines: Boolean, checkStateMachine: Boolea
|
||||
error("Wrong state-machine generated: wrong number of overall suspensions. Expected " + numberOfSuspensions + ", got " + counter)
|
||||
if (finished) error("Wrong state-machine generated: it is finished early")
|
||||
proceed()
|
||||
if (!finished) error("Wrong state-machine generated: it is not finished yet")
|
||||
if (checkFinished && !finished) error("Wrong state-machine generated: it is not finished yet")
|
||||
}
|
||||
}
|
||||
val StateMachineChecker = StateMachineCheckerClass()
|
||||
|
||||
+5
@@ -4089,6 +4089,11 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxInlineCo
|
||||
runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/insideObject.kt", "kotlin.coroutines");
|
||||
}
|
||||
|
||||
@TestMetadata("lambdaTransformation.kt")
|
||||
public void testLambdaTransformation() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/suspend/stateMachine/lambdaTransformation.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("normalInline.kt")
|
||||
public void testNormalInline_1_2() throws Exception {
|
||||
runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/normalInline.kt", "kotlin.coroutines.experimental");
|
||||
|
||||
Generated
+5
@@ -4089,6 +4089,11 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi
|
||||
runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/insideObject.kt", "kotlin.coroutines");
|
||||
}
|
||||
|
||||
@TestMetadata("lambdaTransformation.kt")
|
||||
public void testLambdaTransformation() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/suspend/stateMachine/lambdaTransformation.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("normalInline.kt")
|
||||
public void testNormalInline_1_2() throws Exception {
|
||||
runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/normalInline.kt", "kotlin.coroutines.experimental");
|
||||
|
||||
+5
@@ -3879,6 +3879,11 @@ public class IrBlackBoxInlineCodegenTestGenerated extends AbstractIrBlackBoxInli
|
||||
runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/insideObject.kt", "kotlin.coroutines");
|
||||
}
|
||||
|
||||
@TestMetadata("lambdaTransformation.kt")
|
||||
public void testLambdaTransformation() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/suspend/stateMachine/lambdaTransformation.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("normalInline.kt")
|
||||
public void testNormalInline_1_3() throws Exception {
|
||||
runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/normalInline.kt", "kotlin.coroutines");
|
||||
|
||||
Generated
+5
@@ -3879,6 +3879,11 @@ public class IrCompileKotlinAgainstInlineKotlinTestGenerated extends AbstractIrC
|
||||
runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/insideObject.kt", "kotlin.coroutines");
|
||||
}
|
||||
|
||||
@TestMetadata("lambdaTransformation.kt")
|
||||
public void testLambdaTransformation() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/suspend/stateMachine/lambdaTransformation.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("normalInline.kt")
|
||||
public void testNormalInline_1_3() throws Exception {
|
||||
runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/normalInline.kt", "kotlin.coroutines");
|
||||
|
||||
Generated
+5
@@ -329,6 +329,11 @@ public class IrInlineSuspendTestsGenerated extends AbstractIrInlineSuspendTests
|
||||
runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/insideObject.kt", "kotlin.coroutines");
|
||||
}
|
||||
|
||||
@TestMetadata("lambdaTransformation.kt")
|
||||
public void testLambdaTransformation() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/suspend/stateMachine/lambdaTransformation.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("normalInline.kt")
|
||||
public void testNormalInline_1_3() throws Exception {
|
||||
runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/normalInline.kt", "kotlin.coroutines");
|
||||
|
||||
+5
@@ -529,6 +529,11 @@ public class InlineSuspendTestsGenerated extends AbstractInlineSuspendTests {
|
||||
runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/insideObject.kt", "kotlin.coroutines");
|
||||
}
|
||||
|
||||
@TestMetadata("lambdaTransformation.kt")
|
||||
public void testLambdaTransformation() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/suspend/stateMachine/lambdaTransformation.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("normalInline.kt")
|
||||
public void testNormalInline_1_2() throws Exception {
|
||||
runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/normalInline.kt", "kotlin.coroutines.experimental");
|
||||
|
||||
Reference in New Issue
Block a user