Drop result of finally block after interpretation
This change is needed due to using FIR as frontend for tests. In this case finally block doesn't has coercion to unit so it's result must be dropped manually.
This commit is contained in:
committed by
TeamCityServer
parent
61d65436f4
commit
cc169613c1
+6
@@ -331,6 +331,12 @@ public class IrInterpreterAfterFir2IrTestGenerated extends AbstractIrInterpreter
|
||||
runTest("compiler/testData/ir/interpreter/superClass.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("unitResult.kt")
|
||||
public void testUnitResult() throws Exception {
|
||||
runTest("compiler/testData/ir/interpreter/unitResult.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("vararg.kt")
|
||||
public void testVararg() throws Exception {
|
||||
|
||||
+12
-9
@@ -17,9 +17,17 @@ import org.jetbrains.kotlin.ir.interpreter.stack.CallStack
|
||||
import org.jetbrains.kotlin.ir.interpreter.stack.Variable
|
||||
import org.jetbrains.kotlin.ir.interpreter.state.*
|
||||
import org.jetbrains.kotlin.ir.types.classOrNull
|
||||
import org.jetbrains.kotlin.ir.types.classifierOrNull
|
||||
import org.jetbrains.kotlin.ir.types.isUnit
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
|
||||
internal fun IrExpression.handleAndDropResult(callStack: CallStack, dropOnlyUnit: Boolean = false) {
|
||||
val dropResult = fun() {
|
||||
if (!dropOnlyUnit && !this.type.isUnit() || callStack.peekState().isUnit()) callStack.popState()
|
||||
}
|
||||
callStack.addInstruction(CustomInstruction(dropResult))
|
||||
callStack.addInstruction(CompoundInstruction(this))
|
||||
}
|
||||
|
||||
internal fun unfoldInstruction(element: IrElement?, environment: IrInterpreterEnvironment) {
|
||||
val callStack = environment.callStack
|
||||
when (element) {
|
||||
@@ -178,6 +186,7 @@ private fun unfoldField(field: IrField, callStack: CallStack) {
|
||||
}
|
||||
|
||||
private fun unfoldBody(body: IrBody, callStack: CallStack) {
|
||||
callStack.addInstruction(SimpleInstruction(body))
|
||||
unfoldStatements(body.statements, callStack)
|
||||
}
|
||||
|
||||
@@ -188,18 +197,12 @@ private fun unfoldBlock(block: IrBlock, callStack: CallStack) {
|
||||
}
|
||||
|
||||
private fun unfoldStatements(statements: List<IrStatement>, callStack: CallStack) {
|
||||
fun dropUnitResult() {
|
||||
if (callStack.peekState().isUnit()) callStack.popState()
|
||||
}
|
||||
|
||||
for (i in statements.indices.reversed()) {
|
||||
when (val statement = statements[i]) {
|
||||
is IrClass -> if (!statement.isLocal) TODO("Only local classes are supported")
|
||||
is IrFunction -> if (!statement.isLocal) TODO("Only local functions are supported")
|
||||
else -> {
|
||||
callStack.addInstruction(CustomInstruction(::dropUnitResult))
|
||||
callStack.addInstruction(CompoundInstruction(statement))
|
||||
}
|
||||
is IrExpression -> statement.handleAndDropResult(callStack, dropOnlyUnit = true)
|
||||
else -> callStack.addInstruction(CompoundInstruction(statement))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+14
-4
@@ -90,7 +90,6 @@ class IrInterpreter private constructor(
|
||||
incrementAndCheckCommands()
|
||||
}
|
||||
|
||||
if (callStack.peekState() == null) callStack.pushState(getUnitState())
|
||||
callStack.popState().apply { callStack.dropFrame() }
|
||||
}
|
||||
}
|
||||
@@ -106,7 +105,8 @@ class IrInterpreter private constructor(
|
||||
is IrValueParameter -> interpretValueParameter(element)
|
||||
is IrInstanceInitializerCall -> interpretInstanceInitializerCall(element)
|
||||
is IrField -> interpretField(element)
|
||||
is IrBlock -> callStack.dropSubFrame()
|
||||
is IrBody -> interpretBody(element)
|
||||
is IrBlock -> interpretBlock(element)
|
||||
is IrReturn -> interpretReturn(element)
|
||||
is IrSetField -> interpretSetField(element)
|
||||
is IrGetField -> interpretGetField(element)
|
||||
@@ -140,7 +140,6 @@ class IrInterpreter private constructor(
|
||||
|
||||
private fun interpretFunction(function: IrSimpleFunction) {
|
||||
function.tryResetFunctionBody()
|
||||
if (callStack.peekState() == null) callStack.pushState(getUnitState()) // implicit Unit return
|
||||
if (function.checkCast(environment)) callStack.dropFrameAndCopyResult()
|
||||
}
|
||||
|
||||
@@ -237,6 +236,17 @@ class IrInterpreter private constructor(
|
||||
receiverState.setField(Variable(field.correspondingPropertySymbol!!, callStack.popState()))
|
||||
}
|
||||
|
||||
@Suppress("UNUSED_PARAMETER")
|
||||
private fun interpretBody(body: IrBody) {
|
||||
if (callStack.peekState() == null) callStack.pushState(getUnitState()) // implicit Unit result
|
||||
}
|
||||
|
||||
@Suppress("UNUSED_PARAMETER")
|
||||
private fun interpretBlock(block: IrBlock) {
|
||||
callStack.dropSubFrame()
|
||||
if (callStack.peekState() == null) callStack.pushState(getUnitState()) // implicit Unit result
|
||||
}
|
||||
|
||||
@Suppress("UNUSED_PARAMETER")
|
||||
private fun interpretConstructor(constructor: IrConstructor) {
|
||||
callStack.dropFrameAndCopyResult()
|
||||
@@ -533,7 +543,7 @@ class IrInterpreter private constructor(
|
||||
}
|
||||
callStack.addInstruction(CustomInstruction(checkUnhandledException))
|
||||
}
|
||||
callStack.addInstruction(CompoundInstruction(element.finallyExpression))
|
||||
element.finallyExpression?.handleAndDropResult(callStack)
|
||||
}
|
||||
|
||||
private fun interpretThrow(expression: IrThrow) {
|
||||
|
||||
+3
-2
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.interpreter.CompoundInstruction
|
||||
import org.jetbrains.kotlin.ir.interpreter.Instruction
|
||||
import org.jetbrains.kotlin.ir.interpreter.SimpleInstruction
|
||||
import org.jetbrains.kotlin.ir.interpreter.handleAndDropResult
|
||||
import org.jetbrains.kotlin.ir.interpreter.state.State
|
||||
import org.jetbrains.kotlin.ir.interpreter.state.StateWithClosure
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
@@ -61,7 +62,7 @@ internal class CallStack {
|
||||
dropSubFrame()
|
||||
pushState(result)
|
||||
addInstruction(SimpleInstruction(irReturn))
|
||||
addInstruction(CompoundInstruction(frameOwner.finallyExpression))
|
||||
frameOwner.finallyExpression?.handleAndDropResult(this)
|
||||
return
|
||||
}
|
||||
is IrCatch -> {
|
||||
@@ -69,7 +70,7 @@ internal class CallStack {
|
||||
dropSubFrame()
|
||||
pushState(result)
|
||||
addInstruction(SimpleInstruction(irReturn))
|
||||
addInstruction(CompoundInstruction(tryBlock.finallyExpression))
|
||||
tryBlock.finallyExpression?.handleAndDropResult(this)
|
||||
return
|
||||
}
|
||||
else -> {
|
||||
|
||||
+20
-10
@@ -29,6 +29,15 @@ fun outerReturnTryFinally(n: Int): Int {
|
||||
}
|
||||
}
|
||||
|
||||
@CompileTimeCalculation
|
||||
fun outerReturnUnitTryFinally(n: Int): Int {
|
||||
return try {
|
||||
n
|
||||
} finally {
|
||||
Unit
|
||||
}
|
||||
}
|
||||
|
||||
@CompileTimeCalculation
|
||||
fun exceptionInFinally(divideBy: Int): Int {
|
||||
return try {
|
||||
@@ -191,25 +200,26 @@ fun tryTryFinally(): Int {
|
||||
|
||||
const val a1 = <!EVALUATED: `0`!>tryFinally(0)<!>
|
||||
const val a2 = <!EVALUATED: `10`!>tryFinally(10)<!>
|
||||
//const val a3 = outerReturnTryFinally(10) TODO -> `10`
|
||||
const val a3 = <!EVALUATED: `10`!>outerReturnTryFinally(10)<!>
|
||||
const val a4 = <!EVALUATED: `10`!>outerReturnUnitTryFinally(10)<!>
|
||||
const val b1 = <!EVALUATED: `Inside try block; Inside finally; Outside try; `!>tryFinally2()<!>
|
||||
const val c1 = <!WAS_NOT_EVALUATED: `
|
||||
Exception java.lang.IllegalArgumentException: In finally
|
||||
at TryFinallyKt.tryCatchFinally(tryFinally.kt:48)
|
||||
at TryFinallyKt.<clinit>(tryFinally.kt:196)`!>tryCatchFinally()<!>
|
||||
at TryFinallyKt.tryCatchFinally(tryFinally.kt:57)
|
||||
at TryFinallyKt.<clinit>(tryFinally.kt:206)`!>tryCatchFinally()<!>
|
||||
const val c2 = <!EVALUATED: `0`!>exceptionInFinally(10)<!>
|
||||
const val c3 = <!WAS_NOT_EVALUATED: `
|
||||
Exception java.lang.ArithmeticException: / by zero
|
||||
at TryFinallyKt.exceptionInFinally(tryFinally.kt:37)
|
||||
at TryFinallyKt.<clinit>(tryFinally.kt:198)`!>exceptionInFinally(0)<!>
|
||||
//const val d1 = returnTryFinally() TODO -> `OK`
|
||||
at TryFinallyKt.exceptionInFinally(tryFinally.kt:46)
|
||||
at TryFinallyKt.<clinit>(tryFinally.kt:208)`!>exceptionInFinally(0)<!>
|
||||
const val d1 = <!EVALUATED: `OK`!>returnTryFinally()<!>
|
||||
const val d2 = <!EVALUATED: `1`!>tryCatchReturnFinally(10)<!>
|
||||
const val d3 = <!EVALUATED: `0`!>tryCatchReturnFinally(0)<!>
|
||||
const val e1 = <!EVALUATED: `10`!>tryFinallyContinue()<!>
|
||||
const val e2 = <!EVALUATED: `1`!>tryFinallyBreak()<!>
|
||||
const val e3 = <!EVALUATED: `10`!>tryCatchFinallyContinue(0)<!>
|
||||
//const val f1 = innerTryFinally(10) TODO -> `1`
|
||||
const val f1 = <!EVALUATED: `1`!>innerTryFinally(10)<!>
|
||||
const val f2 = <!EVALUATED: `20`!>innerTryFinallyReturn(10)<!>
|
||||
//const val g1 = tryCatch(10) TODO -> `0`
|
||||
//const val g2 = tryCatch(0) TODO -> `-1`
|
||||
//const val h1 = tryTryFinally() TODO -> `-1`
|
||||
const val g1 = <!EVALUATED: `0`!>tryCatch(10)<!>
|
||||
const val g2 = <!EVALUATED: `-1`!>tryCatch(0)<!>
|
||||
const val h1 = <!EVALUATED: `-1`!>tryTryFinally()<!>
|
||||
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
@CompileTimeCalculation fun getUnitImplicit(): Unit {}
|
||||
@CompileTimeCalculation fun getUnitExplicit(): Unit { return Unit }
|
||||
@CompileTimeCalculation fun getUnitImplicitFromExpression(): Unit { if (true) {} else Unit }
|
||||
@CompileTimeCalculation fun getUnitImplicitFromTry1(): Unit { try {} finally { 5 } }
|
||||
@CompileTimeCalculation fun getUnitImplicitFromTry2(): Unit { try {} finally { } }
|
||||
|
||||
const val unit1 = Unit.<!EVALUATED: `kotlin.Unit`!>toString()<!>
|
||||
const val unit2 = getUnitImplicit().<!EVALUATED: `kotlin.Unit`!>toString()<!>
|
||||
const val unit3 = getUnitExplicit().<!EVALUATED: `kotlin.Unit`!>toString()<!>
|
||||
const val unit4 = getUnitImplicitFromExpression().<!EVALUATED: `kotlin.Unit`!>toString()<!>
|
||||
const val unit5 = getUnitImplicitFromTry1().<!EVALUATED: `kotlin.Unit`!>toString()<!>
|
||||
const val unit6 = getUnitImplicitFromTry2().<!EVALUATED: `kotlin.Unit`!>toString()<!>
|
||||
Reference in New Issue
Block a user