[JVM_IR] Generate line numbers in synthetic bridges.
The current backend does that for some bridges. We do it consistently for all bridges. The line number used differs. For the JVM_IR backend, we use the line number of the class to which the bridge is added. For the JVM backend, that does not appear to be the case for bridges in lambdas. I prefer the line number for a lambda invoke bridge to be the line for the lambda instead os some surrounding class.
This commit is contained in:
+6
-2
@@ -385,6 +385,8 @@ internal class BridgeLowering(val context: JvmBackendContext) : FileLoweringPass
|
||||
|
||||
private fun IrClass.addBridge(bridge: Bridge, target: IrSimpleFunction): IrSimpleFunction =
|
||||
addFunction {
|
||||
startOffset = this@addBridge.startOffset
|
||||
endOffset = this@addBridge.startOffset
|
||||
modality = Modality.OPEN
|
||||
origin = IrDeclarationOrigin.BRIDGE
|
||||
// Internal functions can be overridden by non-internal functions, which changes their names since the names of internal
|
||||
@@ -396,7 +398,7 @@ internal class BridgeLowering(val context: JvmBackendContext) : FileLoweringPass
|
||||
isSuspend = bridge.overridden.isSuspend
|
||||
}.apply {
|
||||
copyParametersWithErasure(this@addBridge, bridge.overridden)
|
||||
body = context.createIrBuilder(symbol).run { irExprBody(delegatingCall(this@apply, target)) }
|
||||
body = context.createIrBuilder(symbol, startOffset, endOffset).run { irExprBody(delegatingCall(this@apply, target)) }
|
||||
|
||||
// The generated bridge method overrides all of the symbols which were overridden by its overrides.
|
||||
// This is technically wrong, but it's necessary to generate a method which maps to the same signature.
|
||||
@@ -411,6 +413,8 @@ internal class BridgeLowering(val context: JvmBackendContext) : FileLoweringPass
|
||||
|
||||
private fun IrClass.addSpecialBridge(specialBridge: SpecialBridge, target: IrSimpleFunction): IrSimpleFunction =
|
||||
addFunction {
|
||||
startOffset = this@addSpecialBridge.startOffset
|
||||
endOffset = this@addSpecialBridge.startOffset
|
||||
modality = if (specialBridge.isFinal) Modality.FINAL else Modality.OPEN
|
||||
origin = if (specialBridge.isSynthetic) IrDeclarationOrigin.BRIDGE else IrDeclarationOrigin.BRIDGE_SPECIAL
|
||||
name = Name.identifier(specialBridge.signature.name)
|
||||
@@ -423,7 +427,7 @@ internal class BridgeLowering(val context: JvmBackendContext) : FileLoweringPass
|
||||
specialBridge.substitutedParameterTypes
|
||||
)
|
||||
|
||||
body = context.createIrBuilder(symbol).irBlockBody {
|
||||
body = context.createIrBuilder(symbol, startOffset, endOffset).irBlockBody {
|
||||
specialBridge.methodInfo?.let { info ->
|
||||
valueParameters.take(info.argumentsToCheck).forEach {
|
||||
+parameterTypeCheck(it, target.valueParameters[it.index].type, info.defaultValueGenerator(this@apply))
|
||||
|
||||
+16
-10
@@ -15,7 +15,6 @@ import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
|
||||
import org.jetbrains.kotlin.backend.jvm.intrinsics.receiverAndArgs
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.IrInlineReferenceLocator
|
||||
import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.hasMangledParameters
|
||||
import org.jetbrains.kotlin.codegen.syntheticAccessorToSuperSuffix
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
@@ -292,6 +291,8 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle
|
||||
val source = this
|
||||
|
||||
return factory.buildFun {
|
||||
startOffset = parent.startOffset
|
||||
endOffset = parent.startOffset
|
||||
origin = JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR
|
||||
name = source.accessorName(expression.superQualifierSymbol)
|
||||
visibility = DescriptorVisibilities.PUBLIC
|
||||
@@ -306,7 +307,7 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle
|
||||
accessor.returnType = source.returnType.remapTypeParameters(source, accessor)
|
||||
|
||||
accessor.body = IrExpressionBodyImpl(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||
accessor.startOffset, accessor.startOffset,
|
||||
createSimpleFunctionCall(accessor, source.symbol, expression.superQualifierSymbol)
|
||||
)
|
||||
}
|
||||
@@ -314,7 +315,8 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle
|
||||
|
||||
private fun createSimpleFunctionCall(accessor: IrFunction, targetSymbol: IrSimpleFunctionSymbol, superQualifierSymbol: IrClassSymbol?) =
|
||||
IrCallImpl(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||
accessor.startOffset,
|
||||
accessor.endOffset,
|
||||
accessor.returnType,
|
||||
targetSymbol, targetSymbol.owner.typeParameters.size,
|
||||
superQualifierSymbol = superQualifierSymbol
|
||||
@@ -324,6 +326,8 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle
|
||||
|
||||
private fun makeGetterAccessorSymbol(fieldSymbol: IrFieldSymbol, parent: IrClass): IrSimpleFunctionSymbol =
|
||||
context.irFactory.buildFun {
|
||||
startOffset = parent.startOffset
|
||||
endOffset = parent.startOffset
|
||||
origin = JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR
|
||||
name = fieldSymbol.owner.accessorNameForGetter()
|
||||
visibility = DescriptorVisibilities.PUBLIC
|
||||
@@ -346,11 +350,11 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle
|
||||
private fun createAccessorBodyForGetter(targetField: IrField, accessor: IrSimpleFunction): IrBody {
|
||||
val maybeDispatchReceiver =
|
||||
if (targetField.isStatic) null
|
||||
else IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, accessor.valueParameters[0].symbol)
|
||||
else IrGetValueImpl(accessor.startOffset, accessor.endOffset, accessor.valueParameters[0].symbol)
|
||||
return IrExpressionBodyImpl(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||
accessor.startOffset, accessor.endOffset,
|
||||
IrGetFieldImpl(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||
accessor.startOffset, accessor.endOffset,
|
||||
targetField.symbol,
|
||||
targetField.type,
|
||||
maybeDispatchReceiver
|
||||
@@ -360,6 +364,8 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle
|
||||
|
||||
private fun makeSetterAccessorSymbol(fieldSymbol: IrFieldSymbol, parent: IrClass): IrSimpleFunctionSymbol =
|
||||
context.irFactory.buildFun {
|
||||
startOffset = parent.startOffset
|
||||
endOffset = parent.startOffset
|
||||
origin = JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR
|
||||
name = fieldSymbol.owner.accessorNameForSetter()
|
||||
visibility = DescriptorVisibilities.PUBLIC
|
||||
@@ -384,15 +390,15 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle
|
||||
private fun createAccessorBodyForSetter(targetField: IrField, accessor: IrSimpleFunction): IrBody {
|
||||
val maybeDispatchReceiver =
|
||||
if (targetField.isStatic) null
|
||||
else IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, accessor.valueParameters[0].symbol)
|
||||
else IrGetValueImpl(accessor.startOffset, accessor.endOffset, accessor.valueParameters[0].symbol)
|
||||
val value = IrGetValueImpl(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||
accessor.startOffset, accessor.endOffset,
|
||||
accessor.valueParameters[if (targetField.isStatic) 0 else 1].symbol
|
||||
)
|
||||
return IrExpressionBodyImpl(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||
accessor.startOffset, accessor.endOffset,
|
||||
IrSetFieldImpl(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||
accessor.startOffset, accessor.endOffset,
|
||||
targetField.symbol,
|
||||
maybeDispatchReceiver,
|
||||
value,
|
||||
|
||||
-13
@@ -16,37 +16,24 @@ fun box() {
|
||||
A.foo()
|
||||
}
|
||||
|
||||
// The JVM version hits get getProp line numbers twice. That appears
|
||||
// to be because the synthetic accessibility bridges (access$getProp0$cp)
|
||||
// have line numbers (of the start of the surrounding class) in the JVM
|
||||
// version and they do not have line numbers in the JVM_IR version.
|
||||
|
||||
// LINENUMBERS
|
||||
// test.kt:14 box
|
||||
// test.kt:5 <clinit>
|
||||
// test.kt:6 <clinit>
|
||||
// test.kt:5 getProp0
|
||||
// LINENUMBERS JVM
|
||||
// test.kt:5 getProp0
|
||||
// LINENUMBERS
|
||||
// test.kt:14 box
|
||||
// test.kt:15 box
|
||||
// test.kt:6 getProp1
|
||||
// LINENUMBERS JVM
|
||||
// test.kt:6 getProp1
|
||||
// LINENUMBERS
|
||||
// test.kt:15 box
|
||||
// test.kt:16 box
|
||||
// test.kt:8 foo
|
||||
// test.kt:5 getProp0
|
||||
// LINENUMBERS JVM
|
||||
// test.kt:5 getProp0
|
||||
// LINENUMBERS
|
||||
// test.kt:8 foo
|
||||
// test.kt:6 getProp1
|
||||
// LINENUMBERS JVM
|
||||
// test.kt:6 getProp1
|
||||
// LINENUMBERS
|
||||
// test.kt:8 foo
|
||||
// test.kt:16 box
|
||||
// test.kt:17 box
|
||||
|
||||
@@ -30,8 +30,6 @@ fun box() {
|
||||
A.s
|
||||
}
|
||||
|
||||
// JVM backend has extra steps for getX and getS.
|
||||
|
||||
// LINENUMBERS
|
||||
// test.kt:29 box
|
||||
// test.kt:7 <clinit>
|
||||
@@ -46,14 +44,10 @@ fun box() {
|
||||
// test.kt:21 <clinit>
|
||||
// test.kt:22 <clinit>
|
||||
// test.kt:11 getX
|
||||
// LINENUMBERS JVM
|
||||
// test.kt:11 getX
|
||||
// LINENUMBERS
|
||||
// test.kt:29 box
|
||||
// test.kt:30 box
|
||||
// test.kt:5 getS
|
||||
// LINENUMBERS JVM
|
||||
// test.kt:5 getS
|
||||
// LINENUMBERS
|
||||
// test.kt:30 box
|
||||
// test.kt:31 box
|
||||
|
||||
@@ -10,10 +10,19 @@ fun f(block: () -> Unit) {
|
||||
|
||||
fun g() {}
|
||||
|
||||
// The synthetic invoke bridge method generated for in the callable reference has line numbers
|
||||
// in the JVM_IR backend (as all bridges). In the JVM backend, only some bridges have line numbers.
|
||||
// For some reason, when the bridge does not have line numbers, there is no method entry event
|
||||
// for the invoke method bridged to. Therefore, the entry line number for invoke only shows
|
||||
// up for JVM_IR.
|
||||
|
||||
// LINENUMBERS
|
||||
// test.kt:3 box
|
||||
// test.kt:4 box
|
||||
// test.kt:8 f
|
||||
// LINENUMBERS JVM_IR
|
||||
// test.kt:4 invoke
|
||||
// LINENUMBERS
|
||||
// test.kt:11 g
|
||||
// test.kt:4 invoke
|
||||
// test.kt:8 f
|
||||
|
||||
Vendored
+21
@@ -0,0 +1,21 @@
|
||||
LineBreakpoint created at functionCallStoredToVariable.kt:7
|
||||
LineBreakpoint created at functionCallStoredToVariable.kt:14
|
||||
LineBreakpoint created at functionCallStoredToVariable.kt:21
|
||||
LineBreakpoint created at functionCallStoredToVariable.kt:28
|
||||
Run Java
|
||||
Connected to the target VM
|
||||
functionCallStoredToVariable.kt:7
|
||||
functionCallStoredToVariable.kt:4
|
||||
functionCallStoredToVariable.kt:14
|
||||
functionCallStoredToVariable.kt:11
|
||||
functionCallStoredToVariable.kt:43
|
||||
functionCallStoredToVariable.kt:21
|
||||
functionCallStoredToVariable.kt:22
|
||||
functionCallStoredToVariable.kt:25
|
||||
functionCallStoredToVariable.kt:28
|
||||
functionCallStoredToVariable.kt:29
|
||||
functionCallStoredToVariable.kt:25
|
||||
functionCallStoredToVariable.kt:47
|
||||
Disconnected from the target VM
|
||||
|
||||
Process finished with exit code 0
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
LineBreakpoint created at accessors.kt:10
|
||||
Run Java
|
||||
Connected to the target VM
|
||||
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
LineBreakpoint created at syntheticMethods.kt:6
|
||||
Run Java
|
||||
Connected to the target VM
|
||||
syntheticMethods.kt:6
|
||||
syntheticMethods.kt:17
|
||||
syntheticMethods.kt:19
|
||||
syntheticMethods.kt:20
|
||||
syntheticMethods.kt:17
|
||||
syntheticMethods.kt:7
|
||||
syntheticMethods.kt:-1
|
||||
syntheticMethods.kt:7
|
||||
syntheticMethods.kt:25
|
||||
syntheticMethods.kt:31
|
||||
syntheticMethods.kt:25
|
||||
syntheticMethods.kt:26
|
||||
syntheticMethods.kt:25
|
||||
syntheticMethods.kt:31
|
||||
syntheticMethods.kt:25
|
||||
syntheticMethods.kt:28
|
||||
syntheticMethods.kt:8
|
||||
syntheticMethods.kt:36
|
||||
syntheticMethods.kt:42
|
||||
syntheticMethods.kt:36
|
||||
syntheticMethods.kt:37
|
||||
syntheticMethods.kt:36
|
||||
syntheticMethods.kt:42
|
||||
syntheticMethods.kt:36
|
||||
syntheticMethods.kt:39
|
||||
syntheticMethods.kt:9
|
||||
Disconnected from the target VM
|
||||
|
||||
Process finished with exit code 0
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
LineBreakpoint created at syntheticMethods.kt:6
|
||||
Run Java
|
||||
Connected to the target VM
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
KotlinFieldBreakpoint created at fwBackingField.kt:5
|
||||
KotlinFieldBreakpoint created at fwBackingField.kt:8
|
||||
KotlinFieldBreakpoint created at fwBackingField.kt:18
|
||||
|
||||
Reference in New Issue
Block a user