diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/DefaultArgumentStubGenerator.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/DefaultArgumentStubGenerator.kt index e0b04af96ee..c4a75a59e6a 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/DefaultArgumentStubGenerator.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/DefaultArgumentStubGenerator.kt @@ -177,8 +177,24 @@ open class DefaultArgumentStubGenerator( parameter: IrValueParameter, default: IrExpression ): IrValueDeclaration { - val value = irIfThenElse(parameter.type, irNotEquals(defaultFlag, irInt(0)), default, irGet(parameter)) - return createTmpVariable(value, nameHint = parameter.name.asString()) + // For the JVM backend, we have to generate precisely this code because that results in the + // bytecode the inliner expects see `expandMaskConditionsAndUpdateVariableNodes`. In short, + // the bytecode sequence should be + // + // -- no loads of the parameter here, as after inlining its value will be uninitialized + // ILOAD + // ICONST + // IAND + // IFEQ Lx + // -- any code inserted here is removed if the call site specifies the parameter + // STORE + // -- no jumps here + // Lx + // + // This control flow limits us to an if-then (without an else), and this together with the + // restriction on loading the parameter in the default case means we cannot create any temporaries. + +irIfThen(defaultFlag, irSet(parameter.symbol, default)) + return parameter } protected open fun getOriginForCallToImplementation(): IrStatementOrigin? = null diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/InlineClassDeclarationLowering.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/InlineClassDeclarationLowering.kt index 160b90b4f12..9a2ad00cd32 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/InlineClassDeclarationLowering.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/InlineClassDeclarationLowering.kt @@ -106,6 +106,12 @@ class InlineClassLowering(val context: CommonBackendContext) { return expression } + override fun visitSetValue(expression: IrSetValue): IrExpression { + expression.transformChildrenVoid() + parameterMapping[expression.symbol]?.let { return irSet(it.symbol, expression.value) } + return expression + } + override fun visitDeclaration(declaration: IrDeclarationBase): IrStatement { declaration.transformChildrenVoid(this) if (declaration.parent == irConstructor) @@ -171,6 +177,21 @@ class InlineClassLowering(val context: CommonBackendContext) { } ) } + + override fun visitSetValue(expression: IrSetValue): IrExpression { + val valueDeclaration = expression.symbol.owner as? IrValueParameter ?: return super.visitSetValue(expression) + expression.transformChildrenVoid() + return context.createIrBuilder(staticMethod.symbol).irSet( + when (valueDeclaration) { + in function.valueParameters -> { + val offset = if (function.extensionReceiverParameter != null) 2 else 1 + staticMethod.valueParameters[valueDeclaration.index + offset].symbol + } + else -> return expression + }, + expression.value + ) + } }) } } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/EnumClassLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/EnumClassLowering.kt index b502f2a3993..d5909f4e0e6 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/EnumClassLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/EnumClassLowering.kt @@ -171,6 +171,14 @@ private fun JsCommonBackendContext.fixReferencesToConstructorParameters(irClass: return super.visitGetValue(expression) } + + override fun visitSetValue(expression: IrSetValue): IrExpression { + expression.transformChildrenVoid() + mapping.enumConstructorOldToNewValueParameters[expression.symbol.owner]?.let { + return builder.irSet(it.symbol, expression.value) + } + return super.visitSetValue(expression) + } }) } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/SecondaryCtorLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/SecondaryCtorLowering.kt index b20f8460c1d..82a21740879 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/SecondaryCtorLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/SecondaryCtorLowering.kt @@ -20,10 +20,7 @@ import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder import org.jetbrains.kotlin.ir.builders.declarations.buildFun import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.* -import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl -import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl -import org.jetbrains.kotlin.ir.expressions.impl.IrRawFunctionReferenceImpl -import org.jetbrains.kotlin.ir.expressions.impl.IrReturnImpl +import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl @@ -159,6 +156,13 @@ class SecondaryConstructorLowering(val context: JsIrBackendContext) : Declaratio override fun visitGetValue(expression: IrGetValue) = symbolMapping[expression.symbol.owner]?.let { expression.run { IrGetValueImpl(startOffset, endOffset, type, it.symbol, origin) } } ?: expression + + override fun visitSetValue(expression: IrSetValue): IrExpression { + expression.transformChildrenVoid() + return symbolMapping[expression.symbol.owner]?.let { + expression.run { IrSetValueImpl(startOffset, endOffset, type, it.symbol, expression.value, origin) } + } ?: expression + } } } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/JvmDefaultArgumentStubGenerator.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/JvmDefaultArgumentStubGenerator.kt index 509c5128c08..7eaa4fb33ca 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/JvmDefaultArgumentStubGenerator.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/JvmDefaultArgumentStubGenerator.kt @@ -19,30 +19,6 @@ import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.util.isTopLevelDeclaration class JvmDefaultArgumentStubGenerator(override val context: JvmBackendContext) : DefaultArgumentStubGenerator(context, false, false) { - override fun IrBlockBodyBuilder.selectArgumentOrDefault( - defaultFlag: IrExpression, - parameter: IrValueParameter, - default: IrExpression - ): IrValueDeclaration { - // We have to generate precisely this code because that results in the bytecode the inliner expects; - // see `expandMaskConditionsAndUpdateVariableNodes`. In short, the bytecode sequence should be - // - // -- no loads of the parameter here, as after inlining its value will be uninitialized - // ILOAD - // ICONST - // IAND - // IFEQ Lx - // -- any code inserted here is removed if the call site specifies the parameter - // STORE - // -- no jumps here - // Lx - // - // This control flow limits us to an if-then (without an else), and this together with the - // restriction on loading the parameter in the default case means we cannot create any temporaries. - +irIfThen(defaultFlag, irSet(parameter.symbol, default)) - return parameter - } - override fun defaultArgumentStubVisibility(function: IrFunction) = function.getJvmVisibilityOfDefaultArgumentStub() override fun useConstructorMarker(function: IrFunction): Boolean = diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DataClassMembersGenerator.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DataClassMembersGenerator.kt index 87f3e4a2ae9..15ff8885722 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DataClassMembersGenerator.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DataClassMembersGenerator.kt @@ -169,7 +169,7 @@ abstract class DataClassMembersGenerator( for (property in properties.drop(1)) { val shiftedResult = irCallOp(intTimesSymbol, irIntType, irGet(irResultVar), irInt(31)) val irRhs = irCallOp(intPlusSymbol, irIntType, shiftedResult, getHashCodeOfProperty(property)) - +irSetVar(irResultVar.symbol, irRhs) + +irSet(irResultVar.symbol, irRhs) } +irReturn(irGet(irResultVar))