[IR] Support try for MFVC

#KT-1179
This commit is contained in:
Evgeniy.Zhelenskiy
2022-10-03 10:02:09 +02:00
committed by teamcity
parent f8aa3612f8
commit e1f886936c
8 changed files with 156 additions and 2 deletions
@@ -50237,6 +50237,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/valueClasses/throwingMFVCReassignments.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
}
@Test
@TestMetadata("tryExpressions.kt")
public void testTryExpressions() throws Exception {
runTest("compiler/testData/codegen/box/valueClasses/tryExpressions.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
}
@Test
@TestMetadata("visibility.kt")
public void testVisibility() throws Exception {
@@ -5824,6 +5824,12 @@ public class FirBytecodeTextTestGenerated extends AbstractFirBytecodeTextTest {
public void testRegularClassWithMFVC() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/valueClasses/regularClassWithMFVC.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
}
@Test
@TestMetadata("tryExpressions.kt")
public void testTryExpressions() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/valueClasses/tryExpressions.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
}
}
@Nested
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.backend.jvm.lower
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
import org.jetbrains.kotlin.backend.common.lower.irCatch
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
import org.jetbrains.kotlin.backend.common.pop
import org.jetbrains.kotlin.backend.common.push
@@ -1002,14 +1003,21 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV
}
if (expression is IrWhen) {
for (branch in expression.branches) {
branch.condition = branch.condition.transform(this@JvmMultiFieldValueClassLowering, null)
branch.condition = branch.condition.transform(lowering, null)
branch.result = irBlock {
flattenExpressionTo(branch.result, instance)
}
}.unwrap()
}
+expression
return
}
if (expression is IrTry) {
expression.tryResult = irBlock { flattenExpressionTo(expression.tryResult, instance) }.unwrap()
expression.catches.replaceAll { irCatch(it.catchParameter, irBlock { flattenExpressionTo(it.result, instance) }.unwrap()) }
expression.finallyExpression = expression.finallyExpression?.transform(lowering, null)
+expression
return
}
if (expression is IrConstructorCall) {
val constructor = expression.symbol.owner
if (constructor.isPrimary && constructor.constructedClass.isMultiFieldValueClass &&
@@ -1084,6 +1092,16 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV
expression.acceptChildren(this, data) // when's are transparent
}
override fun visitCatch(aCatch: IrCatch, data: Boolean) {
aCatch.acceptChildren(this, data) // catches are transparent
}
override fun visitTry(aTry: IrTry, data: Boolean) {
aTry.tryResult.accept(this, data)
aTry.catches.forEach { it.accept(this, data) }
aTry.finallyExpression?.accept(this, false)
}
override fun visitBranch(branch: IrBranch, data: Boolean) {
branch.condition.accept(this, true)
branch.result.accept(this, data)
@@ -0,0 +1,43 @@
// CHECK_BYTECODE_LISTING
// WITH_STDLIB
// TARGET_BACKEND: JVM_IR
// WORKS_WHEN_VALUE_CLASS
// LANGUAGE: +ValueClasses
@JvmInline
value class DPoint(val x: Double, val y: Double) {
init {
require(x != 0.0 && y != 0.0)
}
}
fun tryOk() = try {
DPoint(1.0, 2.0)
} catch(_: Throwable) {
DPoint(0.0, 3.0)
} finally {
DPoint(4.0, 5.0)
}
fun tryFail1() = try {
DPoint(0.0, 1.0)
} catch(_: Throwable) {
DPoint(2.0, 3.0)
} finally {
DPoint(4.0, 5.0)
}
fun tryFail2() = try {
DPoint(1.0, 2.0)
} catch(_: Throwable) {
DPoint(3.0, 4.0)
} finally {
DPoint(5.0, 0.0)
}
fun box(): String {
require(runCatching { tryOk() } == Result.success(DPoint(1.0, 2.0)))
require(runCatching { tryFail1() } == Result.success(DPoint(2.0, 3.0)))
require(runCatching { tryFail2() }.isFailure)
return "OK"
}
@@ -0,0 +1,31 @@
@kotlin.jvm.JvmInline
@kotlin.Metadata
public final class DPoint {
// source: 'tryExpressions.kt'
private final field field-0: double
private final field field-1: double
private synthetic method <init>(p0: double, p1: double): void
public synthetic final static method box-impl(p0: double, p1: double): DPoint
public final static method constructor-impl(p0: double, p1: double): void
public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean
public static method equals-impl(p0: double, p1: double, p2: java.lang.Object): boolean
public final static method equals-impl0(p0: double, p1: double, p2: double, p3: double): boolean
public final static method getX-impl(p0: double, p1: double): double
public final static method getY-impl(p0: double, p1: double): double
public method hashCode(): int
public static method hashCode-impl(p0: double, p1: double): int
public @org.jetbrains.annotations.NotNull method toString(): java.lang.String
public static method toString-impl(p0: double, p1: double): java.lang.String
public synthetic final method unbox-impl-0(): double
public synthetic final method unbox-impl-1(): double
}
@kotlin.Metadata
public final class TryExpressionsKt {
// source: 'tryExpressions.kt'
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
public final static @org.jetbrains.annotations.NotNull method tryFail1(): DPoint
public final static @org.jetbrains.annotations.NotNull method tryFail2(): DPoint
public final static @org.jetbrains.annotations.NotNull method tryOk(): DPoint
public final inner class kotlin/Result$Companion
}
@@ -0,0 +1,38 @@
// CHECK_BYTECODE_LISTING
// WITH_STDLIB
// TARGET_BACKEND: JVM_IR
// WORKS_WHEN_VALUE_CLASS
// LANGUAGE: +ValueClasses
@JvmInline
value class DPoint(val x: Double, val y: Double)
fun tryExpr() = try {
DPoint(0.0, 1.0)
} catch(_: Throwable) {
DPoint(2.0, 3.0)
} finally {
DPoint(4.0, 5.0)
}
fun tryBody() {
try {
DPoint(0.0, 1.0)
} catch(_: Throwable) {
DPoint(2.0, 3.0)
} finally {
DPoint(4.0, 5.0)
}
val x: DPoint = try {
DPoint(0.0, 1.0)
} catch(_: Throwable) {
DPoint(2.0, 3.0)
} finally {
DPoint(4.0, 5.0)
}
}
// 1 tryExpr.*(\n .*)(\n .*)*(\n .*box-impl.*)(\n .*)*(\n .*box-impl.*)
// 0 tryExpr.*(\n .*)(\n .*)*(\n .*box-impl.*)(\n .*)*(\n .*box-impl.*)(\n .*)*(\n .*box-impl.*)
// 0 tryBody.*(\n .*)*(\n .*box-impl.*)
@@ -50237,6 +50237,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/valueClasses/throwingMFVCReassignments.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
}
@Test
@TestMetadata("tryExpressions.kt")
public void testTryExpressions() throws Exception {
runTest("compiler/testData/codegen/box/valueClasses/tryExpressions.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
}
@Test
@TestMetadata("visibility.kt")
public void testVisibility() throws Exception {
@@ -5824,6 +5824,12 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest {
public void testRegularClassWithMFVC() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/valueClasses/regularClassWithMFVC.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
}
@Test
@TestMetadata("tryExpressions.kt")
public void testTryExpressions() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/valueClasses/tryExpressions.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal());
}
}
@Nested