Fix statement order in LocalDeclarationsLowering
Previously, the order of IrSetField statements in this lowering was non-deterministic. This broke the inliner in the JVM backend which expects statements to be in argument order.
This commit is contained in:
committed by
max-kammerer
parent
c38fb27676
commit
173f1fc7d1
+19
-17
@@ -87,7 +87,7 @@ class LocalDeclarationsLowering(
|
||||
abstract val declaration: IrFunction
|
||||
abstract val transformedDeclaration: IrFunction
|
||||
|
||||
val capturedValueToParameter: MutableMap<IrValueDeclaration, IrValueParameter> = HashMap()
|
||||
val capturedValueToParameter: MutableMap<IrValueDeclaration, IrValueParameter> = mutableMapOf()
|
||||
|
||||
override fun irGet(startOffset: Int, endOffset: Int, valueDeclaration: IrValueDeclaration): IrExpression? {
|
||||
val parameter = capturedValueToParameter[valueDeclaration] ?: return null
|
||||
@@ -114,7 +114,9 @@ class LocalDeclarationsLowering(
|
||||
private class LocalClassContext(val declaration: IrClass) : LocalContext() {
|
||||
lateinit var closure: Closure
|
||||
|
||||
val capturedValueToField: MutableMap<IrValueDeclaration, IrField> = HashMap()
|
||||
// NOTE: This map is iterated over in `rewriteClassMembers` and we're relying on
|
||||
// the deterministic iteration order that `mutableMapOf` provides.
|
||||
val capturedValueToField: MutableMap<IrValueDeclaration, IrField> = mutableMapOf()
|
||||
|
||||
override fun irGet(startOffset: Int, endOffset: Int, valueDeclaration: IrValueDeclaration): IrExpression? {
|
||||
val field = capturedValueToField[valueDeclaration] ?: return null
|
||||
@@ -380,26 +382,26 @@ class LocalDeclarationsLowering(
|
||||
|
||||
assert(constructorsCallingSuper.any()) { "Expected at least one constructor calling super; class: $irClass" }
|
||||
|
||||
localClassContext.capturedValueToField.forEach { (capturedValue, field) ->
|
||||
val startOffset = irClass.startOffset
|
||||
val endOffset = irClass.endOffset
|
||||
irClass.declarations.add(field)
|
||||
irClass.declarations += localClassContext.capturedValueToField.values
|
||||
|
||||
for (constructorContext in constructorsCallingSuper) {
|
||||
val blockBody = constructorContext.declaration.body as? IrBlockBody
|
||||
?: throw AssertionError("Unexpected constructor body: ${constructorContext.declaration.body}")
|
||||
val capturedValueExpression = constructorContext.irGet(startOffset, endOffset, capturedValue)!!
|
||||
blockBody.statements.add(
|
||||
0,
|
||||
for (constructorContext in constructorsCallingSuper) {
|
||||
val blockBody = constructorContext.declaration.body as? IrBlockBody
|
||||
?: throw AssertionError("Unexpected constructor body: ${constructorContext.declaration.body}")
|
||||
|
||||
// NOTE: It's important to set the fields for captured values in the same order as the arguments,
|
||||
// since `AnonymousObjectTransformer` relies on this ordering.
|
||||
blockBody.statements.addAll(
|
||||
0,
|
||||
localClassContext.capturedValueToField.map { (capturedValue, field) ->
|
||||
IrSetFieldImpl(
|
||||
startOffset, endOffset, field.symbol,
|
||||
IrGetValueImpl(startOffset, endOffset, irClass.thisReceiver!!.symbol),
|
||||
capturedValueExpression,
|
||||
irClass.startOffset, irClass.endOffset, field.symbol,
|
||||
IrGetValueImpl(irClass.startOffset, irClass.endOffset, irClass.thisReceiver!!.symbol),
|
||||
constructorContext.irGet(irClass.startOffset, irClass.endOffset, capturedValue)!!,
|
||||
context.irBuiltIns.unitType,
|
||||
STATEMENT_ORIGIN_INITIALIZER_OF_FIELD_FOR_CAPTURED_VALUE
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user