[JS_IR] Use IrSetValue for default argument handling for JS backend.
Fix a couple of parameter remappings that now have to take IrSetValue into account as well as IrGetValue.
This commit is contained in:
committed by
Alexander Udalov
parent
9a93bb3f09
commit
87f17dec4a
+18
-2
@@ -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 <mask>
|
||||
// ICONST <bit>
|
||||
// IAND
|
||||
// IFEQ Lx
|
||||
// -- any code inserted here is removed if the call site specifies the parameter
|
||||
// STORE <n>
|
||||
// -- 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
|
||||
|
||||
+21
@@ -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
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
+8
@@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
+8
-4
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-24
@@ -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 <mask>
|
||||
// ICONST <bit>
|
||||
// IAND
|
||||
// IFEQ Lx
|
||||
// -- any code inserted here is removed if the call site specifies the parameter
|
||||
// STORE <n>
|
||||
// -- 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 =
|
||||
|
||||
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user