diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/IrInterpreter.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/IrInterpreter.kt index 4316f9ec338..1920cf8a406 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/IrInterpreter.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/IrInterpreter.kt @@ -319,11 +319,7 @@ class IrInterpreter(internal val environment: IrInterpreterEnvironment, internal } private fun interpretReturn(expression: IrReturn) { - val function = expression.returnTargetSymbol.owner as? IrFunction - function?.tryResetFunctionBody() - if (function.checkCast(environment)) { - callStack.returnFromFrameWithResult(expression) - } + callStack.returnFromFrameWithResult(expression) } private fun interpretWhile(loop: IrWhileLoop) { diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/stack/CallStack.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/stack/CallStack.kt index d9cc2bad7a2..f63a575220d 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/stack/CallStack.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/stack/CallStack.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.ir.interpreter.stack import org.jetbrains.kotlin.ir.IrElement +import org.jetbrains.kotlin.ir.declarations.IrConstructor import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.expressions.* @@ -55,8 +56,9 @@ internal class CallStack { fun returnFromFrameWithResult(irReturn: IrReturn) { val result = popState() + val returnTarget = irReturn.returnTargetSymbol.owner var frameOwner = currentFrameOwner - while (frameOwner != irReturn.returnTargetSymbol.owner) { + while (frameOwner != returnTarget) { when (frameOwner) { is IrTry -> { dropSubFrame() @@ -75,16 +77,15 @@ internal class CallStack { } else -> { dropSubFrame() - if (currentFrame.hasNoSubFrames() && frameOwner != irReturn.returnTargetSymbol.owner) dropFrame() + if (currentFrame.hasNoSubFrames() && frameOwner != returnTarget) dropFrame() frameOwner = currentFrameOwner } } } - dropFrame() - // check that last frame is not a function itself; use case for proxyInterpret - if (frames.size == 0) newFrame(irReturn) // just stub frame - pushState(result) + currentFrame.dropInstructions() + addInstruction(SimpleInstruction(returnTarget)) + if (returnTarget !is IrConstructor) pushState(result) } fun unrollInstructionsForBreakContinue(breakOrContinue: IrBreakContinue) { diff --git a/compiler/testData/ir/interpreter/exceptions/classCastException.kt b/compiler/testData/ir/interpreter/exceptions/classCastException.kt index 0a25ba5c7d8..fbb00b4c5fa 100644 --- a/compiler/testData/ir/interpreter/exceptions/classCastException.kt +++ b/compiler/testData/ir/interpreter/exceptions/classCastException.kt @@ -47,13 +47,13 @@ const val b2 = safeClassCast("10") const val c1 = unsafeClassCast() const val c2 = (classCastException.kt:48)`!>unsafeClassCast() const val d1 = A().unsafeCast() const val d2 = A().(classCastException.kt:51)`!>unsafeCast() const val stringList = getIntList>(). `!>wholeName const val d1 = Person("Ivan", 20).age const val d2 = Person("Ivan", 20).`!>wholeName + +@CompileTimeCalculation +class A { + val prop: Int + constructor(arg: Boolean) { + if (arg) { + prop = 1 + return + } + prop = 2 + } +} + +const val e1 = A(true).prop +const val e2 = A(false).prop