From a9abf3b9b618250ed582e44852c95f57ffb78423 Mon Sep 17 00:00:00 2001 From: Ivan Kylchik Date: Thu, 24 Jun 2021 15:03:07 +0300 Subject: [PATCH] Drop redundant frames after some of exceptions in interpreter Drop only last frame because it is pointing on function itself. --- .../jetbrains/kotlin/ir/interpreter/InstructionsUnfolder.kt | 4 +++- .../src/org/jetbrains/kotlin/ir/interpreter/Utils.kt | 1 + .../testData/ir/interpreter/exceptions/classCastException.kt | 2 -- compiler/testData/ir/interpreter/exceptions/stackOverflow.kt | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/InstructionsUnfolder.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/InstructionsUnfolder.kt index 864ba331430..3dae8c6e421 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/InstructionsUnfolder.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/InstructionsUnfolder.kt @@ -77,8 +77,10 @@ internal fun unfoldInstruction(element: IrElement?, environment: IrInterpreterEn } private fun unfoldFunction(function: IrSimpleFunction, environment: IrInterpreterEnvironment) { - if (environment.callStack.getStackCount() >= environment.configuration.maxStack) + if (environment.callStack.getStackCount() >= environment.configuration.maxStack) { + environment.callStack.dropFrame() // current frame is pointing on function and is redundant return StackOverflowError().handleUserException(environment) + } // SimpleInstruction with function is added in IrCall // It will serve as endpoint for all possible calls, there we drop frame and copy result to new one function.body?.let { environment.callStack.addInstruction(CompoundInstruction(it)) } diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/Utils.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/Utils.kt index 9aa9508a513..610411da349 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/Utils.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/Utils.kt @@ -180,6 +180,7 @@ internal fun IrFunction?.checkCast(environment: IrInterpreterEnvironment): Boole if (!actualState.isSubtypeOf(expectedType)) { val convertibleClassName = environment.callStack.popState().irClass.fqNameWhenAvailable + environment.callStack.dropFrame() // current frame is pointing on function and is redundant ClassCastException("$convertibleClassName cannot be cast to ${expectedType.render()}").handleUserException(environment) return false } diff --git a/compiler/testData/ir/interpreter/exceptions/classCastException.kt b/compiler/testData/ir/interpreter/exceptions/classCastException.kt index fbb00b4c5fa..3edab5d8aa9 100644 --- a/compiler/testData/ir/interpreter/exceptions/classCastException.kt +++ b/compiler/testData/ir/interpreter/exceptions/classCastException.kt @@ -47,13 +47,11 @@ 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>().