From 53a15264124dd606e4515865e69959b383984c56 Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov Date: Tue, 4 Sep 2018 18:44:03 +0300 Subject: [PATCH] Add version to DebugMetadata #KT-26580 Fixed --- .../CoroutineTransformerMethodVisitor.kt | 7 +++++ .../coroutines/jvm/internal/DebugMetadata.kt | 30 ++++++++++++------- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformerMethodVisitor.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformerMethodVisitor.kt index e0eba14a53c..7b20fe7ed55 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformerMethodVisitor.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformerMethodVisitor.kt @@ -34,6 +34,8 @@ import org.jetbrains.org.objectweb.asm.tree.analysis.Frame import org.jetbrains.org.objectweb.asm.tree.analysis.SourceInterpreter import org.jetbrains.org.objectweb.asm.tree.analysis.SourceValue +private const val COROUTINES_DEBUG_METADATA_VERSION = 1 + private const val COROUTINES_METADATA_SOURCE_FILE_JVM_NAME = "f" private const val COROUTINES_METADATA_LINE_NUMBERS_JVM_NAME = "l" private const val COROUTINES_METADATA_LOCAL_NAMES_JVM_NAME = "n" @@ -41,6 +43,7 @@ private const val COROUTINES_METADATA_SPILLED_JVM_NAME = "s" private const val COROUTINES_METADATA_INDEX_TO_LABEL_JVM_NAME = "i" private const val COROUTINES_METADATA_METHOD_NAME_JVM_NAME = "m" private const val COROUTINES_METADATA_CLASS_NAME_JVM_NAME = "c" +private const val COROUTINES_METADATA_VERSION_JVM_NAME = "v" class CoroutineTransformerMethodVisitor( delegate: MethodVisitor, @@ -210,6 +213,10 @@ class CoroutineTransformerMethodVisitor( }.visitEnd() metadata.visit(COROUTINES_METADATA_METHOD_NAME_JVM_NAME, methodNode.name) metadata.visit(COROUTINES_METADATA_CLASS_NAME_JVM_NAME, containingClassInternalName) + @Suppress("ConstantConditionIf") + if (COROUTINES_DEBUG_METADATA_VERSION != 1) { + metadata.visit(COROUTINES_METADATA_VERSION_JVM_NAME, COROUTINES_DEBUG_METADATA_VERSION) + } metadata.visitEnd() } diff --git a/libraries/stdlib/coroutines/jvm/src/kotlin/coroutines/jvm/internal/DebugMetadata.kt b/libraries/stdlib/coroutines/jvm/src/kotlin/coroutines/jvm/internal/DebugMetadata.kt index 67e53b7212e..8202404cb64 100644 --- a/libraries/stdlib/coroutines/jvm/src/kotlin/coroutines/jvm/internal/DebugMetadata.kt +++ b/libraries/stdlib/coroutines/jvm/src/kotlin/coroutines/jvm/internal/DebugMetadata.kt @@ -5,25 +5,25 @@ package kotlin.coroutines.jvm.internal -import kotlin.coroutines.Continuation - @Target(AnnotationTarget.CLASS) @SinceKotlin("1.3") internal annotation class DebugMetadata( + @get:JvmName("v") + val version: Int = 1, @get:JvmName("f") - val sourceFile: String, + val sourceFile: String = "", @get:JvmName("l") - val lineNumbers: IntArray, + val lineNumbers: IntArray = [], @get:JvmName("n") - val localNames: Array, + val localNames: Array = [], @get:JvmName("s") - val spilled: Array, + val spilled: Array = [], @get:JvmName("i") - val indexToLabel: IntArray, + val indexToLabel: IntArray = [], @get:JvmName("m") - val methodName: String, + val methodName: String = "", @get:JvmName("c") - val className: String + val className: String = "" ) /** @@ -38,6 +38,7 @@ internal annotation class DebugMetadata( @JvmName("getStackTraceElement") internal fun BaseContinuationImpl.getStackTraceElementImpl(): StackTraceElement? { val debugMetadata = getDebugMetadataAnnotation() ?: return null + checkDebugMetadataVersion(COROUTINES_DEBUG_METADATA_VERSION, debugMetadata.version) val label = getLabel() val lineNumber = if (label < 0) -1 else debugMetadata.lineNumbers[label] return StackTraceElement(debugMetadata.className, debugMetadata.methodName, debugMetadata.sourceFile, lineNumber) @@ -55,6 +56,12 @@ private fun BaseContinuationImpl.getLabel(): Int = -1 } +private fun checkDebugMetadataVersion(expected: Int, actual: Int) { + if (actual > expected) { + error("Debug metadata version mismatch. Expected: $expected, got $actual. Please update the Kotlin standard library.") + } +} + /** * Returns an array of spilled variable names and continuation's field names where the variable has been spilled. * The structure is the following: @@ -70,6 +77,7 @@ private fun BaseContinuationImpl.getLabel(): Int = @JvmName("getSpilledVariableFieldMapping") internal fun BaseContinuationImpl.getSpilledVariableFieldMapping(): Array? { val debugMetadata = getDebugMetadataAnnotation() ?: return null + checkDebugMetadataVersion(COROUTINES_DEBUG_METADATA_VERSION, debugMetadata.version) val res = arrayListOf() val label = getLabel() for ((i, labelOfIndex) in debugMetadata.indexToLabel.withIndex()) { @@ -79,4 +87,6 @@ internal fun BaseContinuationImpl.getSpilledVariableFieldMapping(): Array