[JVM_IR] Give temporary variable loads meaningful offsets.
Temporary variable loads in when expressions had the offsets of the variable declaration. That leads to hacks during codegen for line number generation. Instead of those hacks, give the variable loads the offsets of the context in which they occur. That avoids the codegen hacks and fixes stepping behavior for more when expressions.
This commit is contained in:
+2
-4
@@ -532,10 +532,7 @@ class ExpressionCodegen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitGetValue(expression: IrGetValue, data: BlockInfo): PromisedValue {
|
override fun visitGetValue(expression: IrGetValue, data: BlockInfo): PromisedValue {
|
||||||
// Do not generate line number information for loads from compiler-generated
|
expression.markLineNumber(startOffset = true)
|
||||||
// temporary variables. They do not correspond to variable loads in user code.
|
|
||||||
if (expression.symbol.owner.origin != IrDeclarationOrigin.IR_TEMPORARY_VARIABLE)
|
|
||||||
expression.markLineNumber(startOffset = true)
|
|
||||||
val type = frameMap.typeOf(expression.symbol)
|
val type = frameMap.typeOf(expression.symbol)
|
||||||
mv.load(findLocalIndex(expression.symbol), type)
|
mv.load(findLocalIndex(expression.symbol), type)
|
||||||
return MaterialValue(this, type, expression.type)
|
return MaterialValue(this, type, expression.type)
|
||||||
@@ -858,6 +855,7 @@ class ExpressionCodegen(
|
|||||||
IrTypeOperator.INSTANCEOF -> {
|
IrTypeOperator.INSTANCEOF -> {
|
||||||
expression.argument.accept(this, data).materializeAt(context.irBuiltIns.anyNType)
|
expression.argument.accept(this, data).materializeAt(context.irBuiltIns.anyNType)
|
||||||
val type = typeMapper.boxType(typeOperand)
|
val type = typeMapper.boxType(typeOperand)
|
||||||
|
|
||||||
if (typeOperand.isReifiedTypeParameter) {
|
if (typeOperand.isReifiedTypeParameter) {
|
||||||
putReifiedOperationMarkerIfTypeIsReifiedParameter(typeOperand, ReifiedTypeInliner.OperationKind.IS)
|
putReifiedOperationMarkerIfTypeIsReifiedParameter(typeOperand, ReifiedTypeInliner.OperationKind.IS)
|
||||||
v.instanceOf(type)
|
v.instanceOf(type)
|
||||||
|
|||||||
+13
-7
@@ -30,7 +30,7 @@ import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
|||||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.startOffsetSkippingComments
|
import org.jetbrains.kotlin.psi.psiUtil.startOffsetSkippingComments
|
||||||
import org.jetbrains.kotlin.psi2ir.deparenthesize
|
import org.jetbrains.kotlin.psi2ir.deparenthesize
|
||||||
import org.jetbrains.kotlin.psi2ir.intermediate.defaultLoad
|
import org.jetbrains.kotlin.psi2ir.intermediate.loadAt
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.utils.SmartList
|
import org.jetbrains.kotlin.utils.SmartList
|
||||||
|
|
||||||
@@ -206,12 +206,14 @@ class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : Sta
|
|||||||
private fun generateIsPatternCondition(irSubject: IrVariable, ktCondition: KtWhenConditionIsPattern): IrExpression {
|
private fun generateIsPatternCondition(irSubject: IrVariable, ktCondition: KtWhenConditionIsPattern): IrExpression {
|
||||||
val typeOperand = getOrFail(BindingContext.TYPE, ktCondition.typeReference)
|
val typeOperand = getOrFail(BindingContext.TYPE, ktCondition.typeReference)
|
||||||
val irTypeOperand = typeOperand.toIrType()
|
val irTypeOperand = typeOperand.toIrType()
|
||||||
|
val startOffset = ktCondition.startOffsetSkippingComments
|
||||||
|
val endOffset = ktCondition.endOffset
|
||||||
val irInstanceOf = IrTypeOperatorCallImpl(
|
val irInstanceOf = IrTypeOperatorCallImpl(
|
||||||
ktCondition.startOffsetSkippingComments, ktCondition.endOffset,
|
startOffset, endOffset,
|
||||||
context.irBuiltIns.booleanType,
|
context.irBuiltIns.booleanType,
|
||||||
IrTypeOperator.INSTANCEOF,
|
IrTypeOperator.INSTANCEOF,
|
||||||
irTypeOperand,
|
irTypeOperand,
|
||||||
irSubject.defaultLoad()
|
irSubject.loadAt(startOffset, startOffset)
|
||||||
)
|
)
|
||||||
return if (ktCondition.isNegated)
|
return if (ktCondition.isNegated)
|
||||||
primitiveOp1(
|
primitiveOp1(
|
||||||
@@ -227,7 +229,9 @@ class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : Sta
|
|||||||
|
|
||||||
private fun generateInRangeCondition(irSubject: IrVariable, ktCondition: KtWhenConditionInRange): IrExpression {
|
private fun generateInRangeCondition(irSubject: IrVariable, ktCondition: KtWhenConditionInRange): IrExpression {
|
||||||
val inCall = statementGenerator.pregenerateCall(getResolvedCall(ktCondition.operationReference)!!)
|
val inCall = statementGenerator.pregenerateCall(getResolvedCall(ktCondition.operationReference)!!)
|
||||||
inCall.irValueArgumentsByIndex[0] = irSubject.defaultLoad()
|
val startOffset = ktCondition.startOffsetSkippingComments
|
||||||
|
val endOffset = ktCondition.endOffset
|
||||||
|
inCall.irValueArgumentsByIndex[0] = irSubject.loadAt(startOffset, startOffset)
|
||||||
val inOperator = getInfixOperator(ktCondition.operationReference.getReferencedNameElementType())
|
val inOperator = getInfixOperator(ktCondition.operationReference.getReferencedNameElementType())
|
||||||
val irInCall = CallGenerator(statementGenerator).generateCall(ktCondition, inCall, inOperator)
|
val irInCall = CallGenerator(statementGenerator).generateCall(ktCondition, inCall, inOperator)
|
||||||
return when (inOperator) {
|
return when (inOperator) {
|
||||||
@@ -235,7 +239,7 @@ class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : Sta
|
|||||||
irInCall
|
irInCall
|
||||||
IrStatementOrigin.NOT_IN ->
|
IrStatementOrigin.NOT_IN ->
|
||||||
primitiveOp1(
|
primitiveOp1(
|
||||||
ktCondition.startOffsetSkippingComments, ktCondition.endOffset,
|
startOffset, endOffset,
|
||||||
context.irBuiltIns.booleanNotSymbol,
|
context.irBuiltIns.booleanNotSymbol,
|
||||||
context.irBuiltIns.booleanType,
|
context.irBuiltIns.booleanType,
|
||||||
IrStatementOrigin.EXCL,
|
IrStatementOrigin.EXCL,
|
||||||
@@ -248,9 +252,11 @@ class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : Sta
|
|||||||
private fun generateEqualsCondition(irSubject: IrVariable, ktCondition: KtWhenConditionWithExpression): IrExpression {
|
private fun generateEqualsCondition(irSubject: IrVariable, ktCondition: KtWhenConditionWithExpression): IrExpression {
|
||||||
val ktExpression = ktCondition.expression
|
val ktExpression = ktCondition.expression
|
||||||
val irExpression = ktExpression!!.genExpr()
|
val irExpression = ktExpression!!.genExpr()
|
||||||
|
val startOffset = ktCondition.startOffsetSkippingComments
|
||||||
|
val endOffset = ktCondition.endOffset
|
||||||
return OperatorExpressionGenerator(statementGenerator).generateEquality(
|
return OperatorExpressionGenerator(statementGenerator).generateEquality(
|
||||||
ktCondition.startOffsetSkippingComments, ktCondition.endOffset, IrStatementOrigin.EQEQ,
|
startOffset, endOffset, IrStatementOrigin.EQEQ,
|
||||||
irSubject.defaultLoad(), irExpression,
|
irSubject.loadAt(startOffset, startOffset), irExpression,
|
||||||
context.bindingContext[BindingContext.PRIMITIVE_NUMERIC_COMPARISON_INFO, ktExpression]
|
context.bindingContext[BindingContext.PRIMITIVE_NUMERIC_COMPARISON_INFO, ktExpression]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.ir.declarations.IrVariable
|
|||||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
||||||
|
|
||||||
fun IrVariable.defaultLoad(): IrExpression =
|
fun IrVariable.loadAt(startOffset: Int, endOffset: Int): IrExpression =
|
||||||
IrGetValueImpl(startOffset, endOffset, type, symbol)
|
IrGetValueImpl(startOffset, endOffset, type, symbol)
|
||||||
|
|
||||||
fun CallReceiver.adjustForCallee(callee: CallableMemberDescriptor): CallReceiver =
|
fun CallReceiver.adjustForCallee(callee: CallableMemberDescriptor): CallReceiver =
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
// FILE: test.kt
|
||||||
|
|
||||||
|
fun foo(x: Any) {
|
||||||
|
when (x) {
|
||||||
|
is Float ->
|
||||||
|
1
|
||||||
|
is Double ->
|
||||||
|
2
|
||||||
|
else ->
|
||||||
|
3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box() {
|
||||||
|
foo(1.2f)
|
||||||
|
foo(1.2)
|
||||||
|
foo(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// LINENUMBERS
|
||||||
|
// test.kt:15 box
|
||||||
|
// test.kt:4 foo
|
||||||
|
// test.kt:5 foo
|
||||||
|
// test.kt:6 foo
|
||||||
|
// test.kt:12 foo
|
||||||
|
// test.kt:16 box
|
||||||
|
// test.kt:4 foo
|
||||||
|
// test.kt:5 foo
|
||||||
|
// test.kt:7 foo
|
||||||
|
// test.kt:8 foo
|
||||||
|
// test.kt:12 foo
|
||||||
|
// test.kt:17 box
|
||||||
|
// test.kt:4 foo
|
||||||
|
// test.kt:5 foo
|
||||||
|
// test.kt:7 foo
|
||||||
|
// test.kt:10 foo
|
||||||
|
// test.kt:12 foo
|
||||||
|
// test.kt:18 box
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
// FILE: test.kt
|
||||||
|
|
||||||
|
fun box() {
|
||||||
|
val a: Int? = 0
|
||||||
|
when (a) {
|
||||||
|
1 -> {
|
||||||
|
1 + 1
|
||||||
|
}
|
||||||
|
2 -> {
|
||||||
|
2 + 1
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
0 + 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// LINENUMBERS
|
||||||
|
// test.kt:4 box
|
||||||
|
// test.kt:5 box
|
||||||
|
// test.kt:6 box
|
||||||
|
// test.kt:9 box
|
||||||
|
// test.kt:13 box
|
||||||
|
// test.kt:16 box
|
||||||
+12
@@ -427,6 +427,12 @@ public class IrSteppingTestGenerated extends AbstractIrSteppingTest {
|
|||||||
runTest("compiler/testData/debug/stepping/whenComplicatedSubject.kt");
|
runTest("compiler/testData/debug/stepping/whenComplicatedSubject.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("whenIsChecks.kt")
|
||||||
|
public void testWhenIsChecks() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/stepping/whenIsChecks.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("whenMultiLine.kt")
|
@TestMetadata("whenMultiLine.kt")
|
||||||
public void testWhenMultiLine() throws Exception {
|
public void testWhenMultiLine() throws Exception {
|
||||||
@@ -439,6 +445,12 @@ public class IrSteppingTestGenerated extends AbstractIrSteppingTest {
|
|||||||
runTest("compiler/testData/debug/stepping/whenMultiLineSubject.kt");
|
runTest("compiler/testData/debug/stepping/whenMultiLineSubject.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("whenNullalbeSubject.kt")
|
||||||
|
public void testWhenNullalbeSubject() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/stepping/whenNullalbeSubject.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("whenSubject.kt")
|
@TestMetadata("whenSubject.kt")
|
||||||
public void testWhenSubject() throws Exception {
|
public void testWhenSubject() throws Exception {
|
||||||
|
|||||||
+12
@@ -427,6 +427,12 @@ public class SteppingTestGenerated extends AbstractSteppingTest {
|
|||||||
runTest("compiler/testData/debug/stepping/whenComplicatedSubject.kt");
|
runTest("compiler/testData/debug/stepping/whenComplicatedSubject.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("whenIsChecks.kt")
|
||||||
|
public void testWhenIsChecks() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/stepping/whenIsChecks.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("whenMultiLine.kt")
|
@TestMetadata("whenMultiLine.kt")
|
||||||
public void testWhenMultiLine() throws Exception {
|
public void testWhenMultiLine() throws Exception {
|
||||||
@@ -439,6 +445,12 @@ public class SteppingTestGenerated extends AbstractSteppingTest {
|
|||||||
runTest("compiler/testData/debug/stepping/whenMultiLineSubject.kt");
|
runTest("compiler/testData/debug/stepping/whenMultiLineSubject.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("whenNullalbeSubject.kt")
|
||||||
|
public void testWhenNullalbeSubject() throws Exception {
|
||||||
|
runTest("compiler/testData/debug/stepping/whenNullalbeSubject.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("whenSubject.kt")
|
@TestMetadata("whenSubject.kt")
|
||||||
public void testWhenSubject() throws Exception {
|
public void testWhenSubject() throws Exception {
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
LineBreakpoint created at whenExpr.kt:5
|
LineBreakpoint created at whenExpr.kt:5
|
||||||
Run Java
|
Run Java
|
||||||
Connected to the target VM
|
Connected to the target VM
|
||||||
|
|||||||
Reference in New Issue
Block a user