Fix linenumbers written to debug metadata
#KT-26848 Fixed
This commit is contained in:
+11
-12
@@ -129,12 +129,17 @@ class CoroutineTransformerMethodVisitor(
|
|||||||
|
|
||||||
val suspendMarkerVarIndex = methodNode.maxLocals++
|
val suspendMarkerVarIndex = methodNode.maxLocals++
|
||||||
|
|
||||||
val suspensionPointLabels = suspensionPoints.withIndex().map {
|
val suspensionPointLineNumbers =
|
||||||
|
suspensionPoints.map { suspensionPoint ->
|
||||||
|
suspensionPoint.suspensionCallBegin.findPreviousOrNull { it is LineNumberNode } as LineNumberNode?
|
||||||
|
}
|
||||||
|
|
||||||
|
val continuationLabels = suspensionPoints.withIndex().map {
|
||||||
transformCallAndReturnContinuationLabel(it.index + 1, it.value, methodNode, suspendMarkerVarIndex)
|
transformCallAndReturnContinuationLabel(it.index + 1, it.value, methodNode, suspendMarkerVarIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
val tableSwitchLabel = LabelNode()
|
|
||||||
methodNode.instructions.apply {
|
methodNode.instructions.apply {
|
||||||
|
val tableSwitchLabel = LabelNode()
|
||||||
val firstStateLabel = LabelNode()
|
val firstStateLabel = LabelNode()
|
||||||
val defaultLabel = LabelNode()
|
val defaultLabel = LabelNode()
|
||||||
|
|
||||||
@@ -153,7 +158,7 @@ class CoroutineTransformerMethodVisitor(
|
|||||||
0,
|
0,
|
||||||
suspensionPoints.size,
|
suspensionPoints.size,
|
||||||
defaultLabel,
|
defaultLabel,
|
||||||
firstStateLabel, *suspensionPointLabels.toTypedArray()
|
firstStateLabel, *continuationLabels.toTypedArray()
|
||||||
),
|
),
|
||||||
firstStateLabel
|
firstStateLabel
|
||||||
)
|
)
|
||||||
@@ -182,11 +187,7 @@ class CoroutineTransformerMethodVisitor(
|
|||||||
fixLvtForParameters(methodNode, startLabel, endLabel)
|
fixLvtForParameters(methodNode, startLabel, endLabel)
|
||||||
|
|
||||||
if (languageVersionSettings.isReleaseCoroutines() && !isCrossinlineLambda) {
|
if (languageVersionSettings.isReleaseCoroutines() && !isCrossinlineLambda) {
|
||||||
val suspensionPointLabelNodes = listOf(tableSwitchLabel) + suspensionPointLabels.map {
|
writeDebugMetadata(methodNode, suspensionPointLineNumbers, spilledToVariableMapping)
|
||||||
it.label.info.safeAs<LabelNode>()
|
|
||||||
.sure { "suspensionPointLabel shall have valid info. Check state-machine generation." }
|
|
||||||
}
|
|
||||||
writeDebugMetadata(methodNode, suspensionPointLabelNodes, spilledToVariableMapping)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -217,12 +218,10 @@ class CoroutineTransformerMethodVisitor(
|
|||||||
|
|
||||||
private fun writeDebugMetadata(
|
private fun writeDebugMetadata(
|
||||||
methodNode: MethodNode,
|
methodNode: MethodNode,
|
||||||
suspensionPointLabels: List<LabelNode>,
|
suspensionPointLineNumbers: List<LineNumberNode?>,
|
||||||
spilledToLocalMapping: List<List<SpilledVariableDescriptor>>
|
spilledToLocalMapping: List<List<SpilledVariableDescriptor>>
|
||||||
) {
|
) {
|
||||||
val lines = suspensionPointLabels.map { label ->
|
val lines = suspensionPointLineNumbers.map { it?.line ?: -1 }
|
||||||
label.safeAs<AbstractInsnNode>()?.findNextOrNull { it is LineNumberNode }.safeAs<LineNumberNode>()?.line ?: -1
|
|
||||||
}
|
|
||||||
val metadata = classBuilderForCoroutineState.newAnnotation(DEBUG_METADATA_ANNOTATION_ASM_TYPE.descriptor, true)
|
val metadata = classBuilderForCoroutineState.newAnnotation(DEBUG_METADATA_ANNOTATION_ASM_TYPE.descriptor, true)
|
||||||
metadata.visit(COROUTINES_METADATA_SOURCE_FILE_JVM_NAME, sourceFile)
|
metadata.visit(COROUTINES_METADATA_SOURCE_FILE_JVM_NAME, sourceFile)
|
||||||
metadata.visit(COROUTINES_METADATA_LINE_NUMBERS_JVM_NAME, lines.toIntArray())
|
metadata.visit(COROUTINES_METADATA_LINE_NUMBERS_JVM_NAME, lines.toIntArray())
|
||||||
|
|||||||
@@ -0,0 +1,62 @@
|
|||||||
|
// !LANGUAGE: +ReleaseCoroutines
|
||||||
|
|
||||||
|
// IGNORE_BACKEND: JVM_IR
|
||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// WITH_RUNTIME
|
||||||
|
// FULL_JDK
|
||||||
|
// WITH_COROUTINES
|
||||||
|
|
||||||
|
import helpers.*
|
||||||
|
import kotlin.coroutines.*
|
||||||
|
import kotlin.coroutines.intrinsics.*
|
||||||
|
|
||||||
|
suspend fun foo() {
|
||||||
|
/*
|
||||||
|
A
|
||||||
|
LOT
|
||||||
|
OF
|
||||||
|
EMPTY
|
||||||
|
LINES
|
||||||
|
*/
|
||||||
|
suspendHere()
|
||||||
|
suspendHere()
|
||||||
|
}
|
||||||
|
|
||||||
|
val lambda: suspend () -> Unit = {
|
||||||
|
/*
|
||||||
|
A
|
||||||
|
LOT
|
||||||
|
OF
|
||||||
|
EMPTY
|
||||||
|
LINES
|
||||||
|
*/
|
||||||
|
suspendHere()
|
||||||
|
suspendHere()
|
||||||
|
}
|
||||||
|
|
||||||
|
var continuation: Continuation<Unit>? = null
|
||||||
|
|
||||||
|
suspend fun suspendHere() = suspendCoroutineUninterceptedOrReturn<Unit> {
|
||||||
|
continuation = it
|
||||||
|
COROUTINE_SUSPENDED
|
||||||
|
}
|
||||||
|
|
||||||
|
fun builder(c: suspend () -> Unit) {
|
||||||
|
c.startCoroutine(EmptyContinuation)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
builder {
|
||||||
|
foo()
|
||||||
|
}
|
||||||
|
if (!"$continuation".contains("21")) return "$continuation"
|
||||||
|
continuation!!.resumeWith(Result.success(Unit))
|
||||||
|
if (!"$continuation".contains("22")) return "$continuation"
|
||||||
|
builder {
|
||||||
|
lambda()
|
||||||
|
}
|
||||||
|
if (!"$continuation".contains("33")) return "$continuation"
|
||||||
|
continuation!!.resumeWith(Result.success(Unit))
|
||||||
|
if (!"$continuation".contains("34")) return "$continuation"
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+5
@@ -6461,6 +6461,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
runTest("compiler/testData/codegen/box/coroutines/debug/debuggerMetadata.kt");
|
runTest("compiler/testData/codegen/box/coroutines/debug/debuggerMetadata.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("firstSuspensionPoint.kt")
|
||||||
|
public void testFirstSuspensionPoint() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/coroutines/debug/firstSuspensionPoint.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("runtimeDebugMetadata.kt")
|
@TestMetadata("runtimeDebugMetadata.kt")
|
||||||
public void testRuntimeDebugMetadata() throws Exception {
|
public void testRuntimeDebugMetadata() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/coroutines/debug/runtimeDebugMetadata.kt");
|
runTest("compiler/testData/codegen/box/coroutines/debug/runtimeDebugMetadata.kt");
|
||||||
|
|||||||
+5
@@ -6461,6 +6461,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
runTest("compiler/testData/codegen/box/coroutines/debug/debuggerMetadata.kt");
|
runTest("compiler/testData/codegen/box/coroutines/debug/debuggerMetadata.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("firstSuspensionPoint.kt")
|
||||||
|
public void testFirstSuspensionPoint() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/coroutines/debug/firstSuspensionPoint.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("runtimeDebugMetadata.kt")
|
@TestMetadata("runtimeDebugMetadata.kt")
|
||||||
public void testRuntimeDebugMetadata() throws Exception {
|
public void testRuntimeDebugMetadata() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/coroutines/debug/runtimeDebugMetadata.kt");
|
runTest("compiler/testData/codegen/box/coroutines/debug/runtimeDebugMetadata.kt");
|
||||||
|
|||||||
+5
@@ -6461,6 +6461,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTest("compiler/testData/codegen/box/coroutines/debug/debuggerMetadata.kt");
|
runTest("compiler/testData/codegen/box/coroutines/debug/debuggerMetadata.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("firstSuspensionPoint.kt")
|
||||||
|
public void testFirstSuspensionPoint() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/coroutines/debug/firstSuspensionPoint.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("runtimeDebugMetadata.kt")
|
@TestMetadata("runtimeDebugMetadata.kt")
|
||||||
public void testRuntimeDebugMetadata() throws Exception {
|
public void testRuntimeDebugMetadata() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/coroutines/debug/runtimeDebugMetadata.kt");
|
runTest("compiler/testData/codegen/box/coroutines/debug/runtimeDebugMetadata.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user