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 86ac488828f..3a3ce33934d 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 @@ -496,13 +496,9 @@ class IrInterpreter(val irBuiltIns: IrBuiltIns, private val bodyMap: Map.withUnitIfNoResult(): ExecutionResult { return stack.newFrame(asSubFrame = true) { - val executionResult = interpretStatements(body.statements).check { return@newFrame it } + val executionResult = interpretStatements(this).check { return@newFrame it } when { !stack.hasReturnValue() -> getOrCreateObjectValue(irBuiltIns.unitClass.owner) else -> executionResult @@ -510,6 +506,14 @@ class IrInterpreter(val irBuiltIns: IrBuiltIns, private val bodyMap: Map stack.popReturnValue() + IrTypeOperator.IMPLICIT_COERCION_TO_UNIT -> { + stack.popReturnValue() + getOrCreateObjectValue(irBuiltIns.unitClass.owner).check { return it } + } IrTypeOperator.CAST, IrTypeOperator.IMPLICIT_CAST -> { if (!isErased && !stack.peekReturnValue().isSubtypeOf(typeOperand)) { val convertibleClassName = stack.popReturnValue().irClass.fqNameWhenAvailable @@ -802,7 +808,8 @@ class IrInterpreter(val irBuiltIns: IrBuiltIns, private val bodyMap: Map this } ReturnLabel.BREAK_LOOP -> when (irElement) { - is IrWhileLoop -> if (owner == irElement) Next else this + is IrWhileLoop, is IrDoWhileLoop -> if (owner == irElement) Next else this else -> this } ReturnLabel.CONTINUE -> when (irElement) { is IrWhileLoop -> if (owner == irElement) irElement.interpret() else this + is IrDoWhileLoop -> { + if (owner != irElement) return this + error("Continue must be handled inside DoWhile interpreter function") + } else -> this } ReturnLabel.EXCEPTION -> Exception @@ -55,8 +56,10 @@ open class ExecutionResult(val returnLabel: ReturnLabel, private val owner: IrEl } } -inline fun ExecutionResult.check(toCheckLabel: ReturnLabel = ReturnLabel.REGULAR, returnBlock: (ExecutionResult) -> Unit): ExecutionResult { - if (this.returnLabel != toCheckLabel) returnBlock(this) +inline fun ExecutionResult.check( + vararg toCheckLabel: ReturnLabel = arrayOf(ReturnLabel.REGULAR), returnBlock: (ExecutionResult) -> Unit +): ExecutionResult { + if (this.returnLabel !in toCheckLabel) returnBlock(this) return this } diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/ExceptionState.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/ExceptionState.kt index 59dea4ab95c..5ac4270d47b 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/ExceptionState.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/ExceptionState.kt @@ -43,6 +43,7 @@ internal class ExceptionState private constructor( } constructor(common: Common, stackTrace: List) : this(common.irClass, common.fields, stackTrace) { + (common.superWrapperClass?.value as? Throwable)?.let { setMessage(it.message) } setUpCauseIfNeeded(common.superWrapperClass) }