From ad7055b8a077a73799b6da9238ac70f68f842935 Mon Sep 17 00:00:00 2001 From: Ivan Kylchik Date: Fri, 27 Mar 2020 15:31:49 +0300 Subject: [PATCH] Move additional stack filling in ExceptionState class --- .../common/interpreter/IrInterpreter.kt | 30 ++---------------- .../backend/common/interpreter/stack/State.kt | 31 +++++++++++++++++-- 2 files changed, 32 insertions(+), 29 deletions(-) diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/interpreter/IrInterpreter.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/interpreter/IrInterpreter.kt index e6ee2f10a6b..a145d9ecdc9 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/interpreter/IrInterpreter.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/interpreter/IrInterpreter.kt @@ -123,7 +123,7 @@ class IrInterpreter(irModule: IrModuleFragment) { else -> TODO("${this.javaClass} not supported") } - return when (code) { + return when (code) { // TODO move to label class Code.RETURN -> when (this) { is IrCall -> if (code.info == this.symbol.descriptor.toString()) Code.NEXT else code is IrReturnableBlock -> if (code.info == this.symbol.descriptor.toString()) Code.NEXT else code @@ -150,36 +150,12 @@ class IrInterpreter(irModule: IrModuleFragment) { val exceptionName = e::class.java.simpleName val irExceptionClass = irExceptions.firstOrNull { it.name.asString() == exceptionName } ?: irBuiltIns.throwableClass.owner - // TODO do we really need this?... It will point to JVM stdlib - val additionalStack = mutableListOf() - if (e.stackTrace.any { it.className == "java.lang.invoke.MethodHandle" }) { - for ((index, stackTraceElement) in e.stackTrace.withIndex()) { - if (stackTraceElement.methodName == "invokeWithArguments") { - additionalStack.addAll(e.stackTrace.slice(0 until index).reversed().map { "at $it" }) - break - } - } - - var cause = e.cause - val lastNeededValue = e.stackTrace.first().className + "." + e.stackTrace.first().methodName - while (cause != null) { - for ((causeStackIndex, causeStackTraceElement) in cause.stackTrace.withIndex()) { - val currentStackTraceValue = causeStackTraceElement.className + "." + causeStackTraceElement.methodName - if (currentStackTraceValue == lastNeededValue) { - cause.stackTrace = cause.stackTrace.sliceArray(0 until causeStackIndex).reversedArray() - break - } - } - cause = cause.cause - } - } - val exceptionState = when { // this block is used to replace jvm null pointer exception with common one // TODO figure something better irExceptionClass == irBuiltIns.throwableClass.owner && exceptionName == "KotlinNullPointerException" -> - ExceptionState(e, irExceptions.first { it.name.asString() == "NullPointerException" }, stackTrace + additionalStack) - else -> ExceptionState(e, irExceptionClass, stackTrace + additionalStack) + ExceptionState(e, irExceptions.first { it.name.asString() == "NullPointerException" }, stackTrace) + else -> ExceptionState(e, irExceptionClass, stackTrace) } data.pushReturnValue(exceptionState) diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/interpreter/stack/State.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/interpreter/stack/State.kt index a5ca28e9e39..363372bec10 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/interpreter/stack/State.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/interpreter/stack/State.kt @@ -322,7 +322,7 @@ class ExceptionState private constructor( init { instance = this this.stackTrace = stackTrace.reversed() - if (!this::exceptionFqName.isInitialized) this.exceptionFqName = irClass.fqNameForIrSerialization.asString() + if (!this::exceptionFqName.isInitialized) this.exceptionFqName = irClassFqName() if (fields.none { it.descriptor.equalTo(messageProperty.descriptor) }) { setMessage() @@ -341,7 +341,7 @@ class ExceptionState private constructor( constructor( exception: Throwable, irClass: IrClass, stackTrace: List - ) : this(irClass, evaluateFields(exception, irClass, stackTrace), stackTrace) { + ) : this(irClass, evaluateFields(exception, irClass, stackTrace), stackTrace + evaluateAdditionalStackTrace(exception)) { if (irClass.name.asString() != exception::class.java.simpleName) { // ir class wasn't found in classpath, a stub was passed => need to save java class hierarchy this.exceptionFqName = exception::class.java.name @@ -414,6 +414,33 @@ class ExceptionState private constructor( } return listOfNotNull(messageVar, causeVar).toMutableList() } + + private fun evaluateAdditionalStackTrace(e: Throwable): List { + // TODO do we really need this?... It will point to JVM stdlib + val additionalStack = mutableListOf() + if (e.stackTrace.any { it.className == "java.lang.invoke.MethodHandle" }) { + for ((index, stackTraceElement) in e.stackTrace.withIndex()) { + if (stackTraceElement.methodName == "invokeWithArguments") { + additionalStack.addAll(e.stackTrace.slice(0 until index).reversed().map { "at $it" }) + break + } + } + + var cause = e.cause + val lastNeededValue = e.stackTrace.first().let { it.className + "." + it.methodName } + while (cause != null) { + for ((causeStackIndex, causeStackTraceElement) in cause.stackTrace.withIndex()) { + val currentStackTraceValue = causeStackTraceElement.let { it.className + "." + it.methodName } + if (currentStackTraceValue == lastNeededValue) { + cause.stackTrace = cause.stackTrace.sliceArray(0 until causeStackIndex).reversedArray() + break + } + } + cause = cause.cause + } + } + return additionalStack + } } }