Remove returns unit markers in suspend lambdas

This commit is contained in:
Ilmir Usmanov
2018-01-24 21:43:59 +03:00
parent e169383f76
commit e6a353e590
4 changed files with 39 additions and 2 deletions
@@ -94,6 +94,8 @@ class CoroutineTransformerMethodVisitor(
continuationIndex = methodNode.maxLocals++
prepareMethodNodePreludeForNamedFunction(methodNode)
} else {
ReturnUnitMethodTransformer.cleanUpReturnsUnitMarkers(methodNode, ReturnUnitMethodTransformer.findReturnsUnitMarks(methodNode))
}
for (suspensionPoint in suspensionPoints) {
@@ -124,10 +124,10 @@ object ReturnUnitMethodTransformer : MethodTransformer() {
private fun findReturnUnitSequences(methodNode: MethodNode): Collection<AbstractInsnNode> =
methodNode.instructions.asSequence().filter { it.isUnitInstance() && it.next?.opcode == Opcodes.ARETURN }.toList()
private fun findReturnsUnitMarks(methodNode: MethodNode): Collection<AbstractInsnNode> =
internal fun findReturnsUnitMarks(methodNode: MethodNode): Collection<AbstractInsnNode> =
methodNode.instructions.asSequence().filter(::isReturnsUnitMarker).toList()
private fun cleanUpReturnsUnitMarkers(methodNode: MethodNode, unitMarks: Collection<AbstractInsnNode>) {
internal fun cleanUpReturnsUnitMarkers(methodNode: MethodNode, unitMarks: Collection<AbstractInsnNode>) {
unitMarks.forEach { methodNode.instructions.removeAll(listOf(it.previous, it)) }
}
}
@@ -0,0 +1,29 @@
// WITH_RUNTIME
// WITH_COROUTINES
import helpers.*
import kotlin.coroutines.experimental.*
import kotlin.coroutines.experimental.intrinsics.*
// TREAT_AS_ONE_FILE
var res = "FAIL"
suspend fun suspendHere() = suspendCoroutineOrReturn<Unit> {
res = "OK"
it.resume(Unit)
COROUTINE_SUSPENDED
}
fun builder(c: suspend () -> Unit) {
c.startCoroutine(EmptyContinuation)
}
fun box() : String {
builder {
suspendHere()
}
return res
}
// 0 ICONST_2
// 0 ICONST_3
@@ -1137,6 +1137,12 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
doTest(fileName);
}
@TestMetadata("returnUnitInLambda.kt")
public void testReturnUnitInLambda() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/coroutines/returnUnitInLambda.kt");
doTest(fileName);
}
@TestMetadata("varValueConflictsWithTable.kt")
public void testVarValueConflictsWithTable() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/coroutines/varValueConflictsWithTable.kt");