Generate call of throwOnFailure instead of manual check

whether coroutine is resumed with exception.
 #KT-28015 Fixed
This commit is contained in:
Ilmir Usmanov
2019-02-14 14:41:06 +03:00
parent 7c83d5df93
commit 19d2262cf1
4 changed files with 31 additions and 12 deletions
@@ -828,23 +828,20 @@ internal fun InstructionAdapter.generateContinuationConstructorCall(
private fun InstructionAdapter.generateResumeWithExceptionCheck(isReleaseCoroutines: Boolean, dataIndex: Int, exceptionIndex: Int) {
// Check if resumeWithException has been called
load(if (isReleaseCoroutines) dataIndex else exceptionIndex, AsmTypes.OBJECT_TYPE)
dup()
val noExceptionLabel = Label()
if (isReleaseCoroutines) {
instanceOf(AsmTypes.RESULT_FAILURE)
ifeq(noExceptionLabel)
// TODO: do we need this checkcast?
checkcast(AsmTypes.RESULT_FAILURE)
getfield(AsmTypes.RESULT_FAILURE.internalName, "exception", AsmTypes.JAVA_THROWABLE_TYPE.descriptor)
load(dataIndex, AsmTypes.OBJECT_TYPE)
invokestatic("kotlin/ResultKt", "throwOnFailure", "(Ljava/lang/Object;)V", false)
} else {
load(exceptionIndex, AsmTypes.OBJECT_TYPE)
dup()
val noExceptionLabel = Label()
ifnull(noExceptionLabel)
}
athrow()
athrow()
mark(noExceptionLabel)
pop()
mark(noExceptionLabel)
pop()
}
}
private fun Type.fieldNameForVar(index: Int) = descriptor.first() + "$" + index
@@ -0,0 +1,12 @@
// IGNORE_BACKEND: JVM_IR
// WITH_COROUTINES
// TREAT_AS_ONE_FILE
suspend fun foo() {}
suspend fun bar(): Int {
foo()
return 42
}
// 2 INVOKESTATIC kotlin/ResultKt.throwOnFailure \(Ljava/lang/Object;\)V
@@ -1125,6 +1125,11 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
runTestWithPackageReplacement("compiler/testData/codegen/bytecodeText/coroutines/returnUnitInLambda.kt", "kotlin.coroutines");
}
@TestMetadata("throwOnFailure.kt")
public void testThrowOnFailure() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/coroutines/throwOnFailure.kt");
}
@TestMetadata("varValueConflictsWithTable.kt")
public void testVarValueConflictsWithTable() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/coroutines/varValueConflictsWithTable.kt");
@@ -1125,6 +1125,11 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest {
runTestWithPackageReplacement("compiler/testData/codegen/bytecodeText/coroutines/returnUnitInLambda.kt", "kotlin.coroutines");
}
@TestMetadata("throwOnFailure.kt")
public void testThrowOnFailure() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/coroutines/throwOnFailure.kt");
}
@TestMetadata("varValueConflictsWithTable.kt")
public void testVarValueConflictsWithTable() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/coroutines/varValueConflictsWithTable.kt");