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'
|
// See 'splitTryCatchBlocksContainingSuspensionPoint'
|
||||||
val possibleTryCatchBlockStart = suspension.tryCatchBlocksContinuationLabel
|
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) {
|
assert(possibleTryCatchBlockStart.previous.opcode == Opcodes.NOP) {
|
||||||
"NOP expected but ${possibleTryCatchBlockStart.previous.opcode} was found"
|
"NOP expected but ${possibleTryCatchBlockStart.previous.opcode} was found"
|
||||||
}
|
}
|
||||||
remove(possibleTryCatchBlockStart.previous)
|
remove(possibleTryCatchBlockStart.previous)
|
||||||
|
|
||||||
insert(possibleTryCatchBlockStart, withInstructionAdapter {
|
insert(possibleTryCatchBlockStart, withInstructionAdapter {
|
||||||
|
nop()
|
||||||
generateResumeWithExceptionCheck(languageVersionSettings.isReleaseCoroutines(), dataIndex, exceptionIndex)
|
generateResumeWithExceptionCheck(languageVersionSettings.isReleaseCoroutines(), dataIndex, exceptionIndex)
|
||||||
|
|
||||||
// Load continuation argument just like suspending function returns it
|
// 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) }
|
proceed = { c.resume(Unit) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun check(numberOfSuspensions: Int) {
|
fun check(numberOfSuspensions: Int, checkFinished: Boolean = true) {
|
||||||
for (i in 1..numberOfSuspensions) {
|
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)
|
if (counter != i) error("Wrong state-machine generated: suspendHere should be called exactly once in one state. Expected " + i + ", got " + counter)
|
||||||
proceed()
|
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)
|
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")
|
if (finished) error("Wrong state-machine generated: it is finished early")
|
||||||
proceed()
|
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()
|
val StateMachineChecker = StateMachineCheckerClass()
|
||||||
|
|||||||
+5
@@ -4089,6 +4089,11 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxInlineCo
|
|||||||
runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/insideObject.kt", "kotlin.coroutines");
|
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")
|
@TestMetadata("normalInline.kt")
|
||||||
public void testNormalInline_1_2() throws Exception {
|
public void testNormalInline_1_2() throws Exception {
|
||||||
runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/normalInline.kt", "kotlin.coroutines.experimental");
|
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");
|
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")
|
@TestMetadata("normalInline.kt")
|
||||||
public void testNormalInline_1_2() throws Exception {
|
public void testNormalInline_1_2() throws Exception {
|
||||||
runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/normalInline.kt", "kotlin.coroutines.experimental");
|
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");
|
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")
|
@TestMetadata("normalInline.kt")
|
||||||
public void testNormalInline_1_3() throws Exception {
|
public void testNormalInline_1_3() throws Exception {
|
||||||
runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/normalInline.kt", "kotlin.coroutines");
|
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");
|
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")
|
@TestMetadata("normalInline.kt")
|
||||||
public void testNormalInline_1_3() throws Exception {
|
public void testNormalInline_1_3() throws Exception {
|
||||||
runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/normalInline.kt", "kotlin.coroutines");
|
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");
|
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")
|
@TestMetadata("normalInline.kt")
|
||||||
public void testNormalInline_1_3() throws Exception {
|
public void testNormalInline_1_3() throws Exception {
|
||||||
runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/normalInline.kt", "kotlin.coroutines");
|
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");
|
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")
|
@TestMetadata("normalInline.kt")
|
||||||
public void testNormalInline_1_2() throws Exception {
|
public void testNormalInline_1_2() throws Exception {
|
||||||
runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/normalInline.kt", "kotlin.coroutines.experimental");
|
runTestWithPackageReplacement("compiler/testData/codegen/boxInline/suspend/stateMachine/normalInline.kt", "kotlin.coroutines.experimental");
|
||||||
|
|||||||
Reference in New Issue
Block a user