[IR] Add IR support for setting parameters.

Use it in the JVM_IR backend for default values code. The parameter
local has to be overwritten for the inliner to work.
This commit is contained in:
Mads Ager
2020-09-01 14:28:07 +02:00
committed by Alexander Udalov
parent db23460fd5
commit 9a93bb3f09
46 changed files with 107 additions and 144 deletions
@@ -308,7 +308,7 @@ class CallAndReferenceGenerator(
putValueArgument(0, assignedValue)
}
}
is IrVariableSymbol -> IrSetVariableImpl(startOffset, endOffset, type, symbol, assignedValue, origin)
is IrVariableSymbol -> IrSetValueImpl(startOffset, endOffset, type, symbol, assignedValue, origin)
else -> generateErrorCallExpression(startOffset, endOffset, calleeReference)
}
}.applyTypeArguments(variableAssignment).applyReceivers(variableAssignment, explicitReceiverExpression)
@@ -135,8 +135,8 @@ class CheckIrElementVisitor(
expression.ensureTypeIs(expression.symbol.owner.type)
}
override fun visitSetVariable(expression: IrSetVariable) {
super.visitSetVariable(expression)
override fun visitSetValue(expression: IrSetValue) {
super.visitSetValue(expression)
expression.ensureTypeIs(irBuiltIns.unitType)
}
@@ -9,7 +9,7 @@ import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.declarations.IrVariable
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrGetValue
import org.jetbrains.kotlin.ir.expressions.IrSetVariable
import org.jetbrains.kotlin.ir.expressions.IrSetValue
import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol
interface SharedVariablesManager {
@@ -19,5 +19,5 @@ interface SharedVariablesManager {
fun getSharedValue(sharedVariableSymbol: IrVariableSymbol, originalGet: IrGetValue): IrExpression
fun setSharedValue(sharedVariableSymbol: IrVariableSymbol, originalSet: IrSetVariable): IrExpression
fun setSharedValue(sharedVariableSymbol: IrVariableSymbol, originalSet: IrSetValue): IrExpression
}
@@ -148,10 +148,10 @@ abstract class AbstractValueUsageTransformer(
return expression
}
override fun visitSetVariable(expression: IrSetVariable): IrExpression {
override fun visitSetValue(expression: IrSetValue): IrExpression {
expression.transformChildrenVoid(this)
expression.value = expression.value.useForVariable(expression.symbol.owner)
expression.value = expression.value.useAsValue(expression.symbol.owner)
return expression
}
@@ -103,7 +103,7 @@ private class ArrayConstructorTransformer(
putValueArgument(1, value)
}
val inc = index.type.getClass()!!.functions.single { it.name == OperatorNameConventions.INC }
+irSetVar(index.symbol, irCallOp(inc.symbol, index.type, irGet(index)))
+irSet(index.symbol, irCallOp(inc.symbol, index.type, irGet(index)))
}
}
+irGet(result)
@@ -27,7 +27,7 @@ import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrGetFieldImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrSetFieldImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrSetVariableImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrSetValueImpl
import org.jetbrains.kotlin.ir.types.isMarkedNullable
import org.jetbrains.kotlin.ir.types.isPrimitiveType
import org.jetbrains.kotlin.ir.types.makeNullable
@@ -154,11 +154,11 @@ class LateinitUsageLowering(val backendContext: CommonBackendContext) : BodyLowe
}
}
override fun visitSetVariable(expression: IrSetVariable): IrExpression {
override fun visitSetValue(expression: IrSetValue): IrExpression {
expression.transformChildrenVoid(this)
val newVar = nullableVariables[expression.symbol.owner] ?: return expression
return with(expression) {
IrSetVariableImpl(startOffset, endOffset, type, newVar.symbol, value, origin)
IrSetValueImpl(startOffset, endOffset, type, newVar.symbol, value, origin)
}
}
@@ -57,6 +57,13 @@ abstract class AbstractVariableRemapper : IrElementTransformerVoid() {
remapVariable(expression.symbol.owner)?.let {
IrGetValueImpl(expression.startOffset, expression.endOffset, it.type, it.symbol, expression.origin)
} ?: expression
override fun visitSetValue(expression: IrSetValue): IrExpression {
expression.transformChildrenVoid()
return remapVariable(expression.symbol.owner)?.let {
IrSetValueImpl(expression.startOffset, expression.endOffset, it.type, it.symbol, expression.value, expression.origin)
} ?: expression
}
}
open class VariableRemapper(val mapping: Map<IrValueParameter, IrValueDeclaration>) : AbstractVariableRemapper() {
@@ -107,7 +107,7 @@ class ReturnableBlockTransformer(val context: CommonBackendContext, val containe
returnMap[expression.symbol] = { returnExpression ->
hasReturned = true
builder.irComposite(returnExpression) {
+irSetVar(variable.symbol, returnExpression.value)
+irSet(variable.symbol, returnExpression.value)
+irBreak(loop)
}
}
@@ -116,7 +116,7 @@ class ReturnableBlockTransformer(val context: CommonBackendContext, val containe
if (i == expression.statements.lastIndex && s is IrReturn && s.returnTargetSymbol == expression.symbol) {
s.transformChildrenVoid()
if (!hasReturned) s.value else {
builder.irSetVar(variable.symbol, s.value)
builder.irSet(variable.symbol, s.value)
}
} else {
s.transformStatement(this)
@@ -118,11 +118,11 @@ class SharedVariablesLowering(val context: BackendContext) : BodyLoweringPass {
}
}
override fun visitSetVariable(expression: IrSetVariable, data: IrDeclarationParent?) {
super.visitSetVariable(expression, data)
override fun visitSetValue(expression: IrSetValue, data: IrDeclarationParent?) {
super.visitSetValue(expression, data)
val variable = expression.symbol.owner
if (variable.initializer == null && getRealParent(variable) != data && variable in relevantVals) {
if (variable is IrVariable && variable.initializer == null && getRealParent(variable) != data && variable in relevantVals) {
sharedVariables.add(variable)
}
}
@@ -159,7 +159,7 @@ class SharedVariablesLowering(val context: BackendContext) : BodyLoweringPass {
return context.sharedVariablesManager.getSharedValue(newDeclaration, expression)
}
override fun visitSetVariable(expression: IrSetVariable): IrExpression {
override fun visitSetValue(expression: IrSetValue): IrExpression {
expression.transformChildrenVoid(this)
val newDeclaration = getTransformedSymbol(expression.symbol) ?: return expression
@@ -148,7 +148,7 @@ private class BodyTransformer(
at(argument)
// Note that argument can use values of parameters, so it is important that
// references to parameters are mapped using `parameterToNew`, not `parameterToVariable`.
+irSetVar(parameterToVariable[parameter]!!.symbol, argument)
+irSet(parameterToVariable[parameter]!!.symbol, argument)
}
val specifiedParameters = parameterToArgument.map { (parameter, _) -> parameter }.toSet()
@@ -177,7 +177,7 @@ private class BodyTransformer(
}
}, data = null)
+irSetVar(parameterToVariable[parameter]!!.symbol, defaultValue)
+irSet(parameterToVariable[parameter]!!.symbol, defaultValue)
}
// Jump to the entry:
@@ -142,7 +142,7 @@ internal abstract class NumericForLoopHeader<T : NumericHeaderInfo>(
it.valueParameters.size == 1 &&
it.valueParameters[0].type == stepType
}
irSetVar(
irSet(
inductionVariable.symbol, irCallOp(
plusFun.symbol, plusFun.returnType,
irGet(inductionVariable),
@@ -469,7 +469,7 @@ internal class WithIndexLoopHeader(
it.valueParameters[0].type.isInt()
}
incrementIndexStatement =
irSetVar(
irSet(
indexVariable.symbol, irCallOp(
plusFun.symbol, plusFun.returnType,
irGet(indexVariable),
@@ -114,7 +114,7 @@ internal class StepHandler(
stepArgExpression.negate()
} else {
// Step is already stored in a variable, just negate it.
stepNegation = irSetVar(stepArgVar.symbol, irGet(stepArgVar).negate())
stepNegation = irSet(stepArgVar.symbol, irGet(stepArgVar).negate())
irGet(stepArgVar)
}
}
@@ -145,7 +145,7 @@ internal class StepHandler(
stepNegation = irIfThen(
context.irBuiltIns.unitType,
nestedStepNonPositiveCheck,
irSetVar(stepArgVar.symbol, irGet(stepArgVar).negate())
irSet(stepArgVar.symbol, irGet(stepArgVar).negate())
)
irGet(stepArgVar)
}
@@ -11,7 +11,7 @@ import org.jetbrains.kotlin.ir.declarations.IrVariable
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrGetValue
import org.jetbrains.kotlin.ir.expressions.IrSetVariable
import org.jetbrains.kotlin.ir.expressions.IrSetValue
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
@@ -83,7 +83,7 @@ class JsSharedVariablesManager(context: JsIrBackendContext) : SharedVariablesMan
}
}
override fun setSharedValue(sharedVariableSymbol: IrVariableSymbol, originalSet: IrSetVariable): IrExpression {
override fun setSharedValue(sharedVariableSymbol: IrVariableSymbol, originalSet: IrSetValue): IrExpression {
return IrCallImpl(
originalSet.startOffset,
originalSet.endOffset,
@@ -59,7 +59,7 @@ object JsIrBuilder {
IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, symbol.owner.type, symbol, SYNTHESIZED_STATEMENT)
fun buildSetVariable(symbol: IrVariableSymbol, value: IrExpression, type: IrType) =
IrSetVariableImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, symbol, value, SYNTHESIZED_STATEMENT)
IrSetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, type, symbol, value, SYNTHESIZED_STATEMENT)
fun buildGetField(symbol: IrFieldSymbol, receiver: IrExpression?, superQualifierSymbol: IrClassSymbol? = null, type: IrType? = null) =
IrGetFieldImpl(
@@ -271,13 +271,13 @@ class BlockDecomposerTransformer(
}
}
override fun visitSetVariable(expression: IrSetVariable): IrExpression {
override fun visitSetValue(expression: IrSetValue): IrExpression {
expression.transformChildrenVoid(expressionTransformer)
val composite = expression.value as? IrComposite ?: return expression
return materializeLastExpression(composite) {
expression.run { IrSetVariableImpl(startOffset, endOffset, type, symbol, it, origin) }
expression.run { IrSetValueImpl(startOffset, endOffset, type, symbol, it, origin) }
}
}
@@ -474,7 +474,7 @@ class BlockDecomposerTransformer(
override fun visitLoop(loop: IrLoop) = loop.asExpression(unitValue)
override fun visitSetVariable(expression: IrSetVariable) = expression.asExpression(unitValue)
override fun visitSetValue(expression: IrSetValue) = expression.asExpression(unitValue)
override fun visitSetField(expression: IrSetField) = expression.asExpression(unitValue)
@@ -459,7 +459,7 @@ class StateMachineBuilder(
}
}
override fun visitSetVariable(expression: IrSetVariable) {
override fun visitSetValue(expression: IrSetValue) {
if (expression !in suspendableNodes) return addStatement(expression)
expression.acceptChildrenVoid(this)
transformLastExpression { expression.apply { value = it } }
@@ -90,7 +90,7 @@ class LiveLocalsTransformer(
return expression.run { IrGetFieldImpl(startOffset, endOffset, field, type, receiver(), origin) }
}
override fun visitSetVariable(expression: IrSetVariable): IrExpression {
override fun visitSetValue(expression: IrSetValue): IrExpression {
expression.transformChildrenVoid(this)
val field = localMap[expression.symbol] ?: return expression
return expression.run { IrSetFieldImpl(startOffset, endOffset, field, receiver(), value, unitType, origin) }
@@ -116,7 +116,7 @@ class IrElementToJsExpressionTransformer : BaseIrElementToJsNodeTransformer<JsEx
return jsAssignment(dest, source)
}
override fun visitSetVariable(expression: IrSetVariable, context: JsGenerationContext): JsExpression {
override fun visitSetValue(expression: IrSetValue, context: JsGenerationContext): JsExpression {
val ref = JsNameRef(context.getNameForValueDeclaration(expression.symbol.owner))
val value = expression.value.accept(this, context)
return JsBinaryOperation(JsBinaryOperator.ASG, ref, value)
@@ -65,7 +65,7 @@ class IrElementToJsStatementTransformer : BaseIrElementToJsNodeTransformer<JsSta
return expression.value.maybeOptimizeIntoSwitch(context) { jsAssignment(dest, it).makeStmt() }
}
override fun visitSetVariable(expression: IrSetVariable, context: JsGenerationContext): JsStatement {
override fun visitSetValue(expression: IrSetValue, context: JsGenerationContext): JsStatement {
val ref = JsNameRef(context.getNameForValueDeclaration(expression.symbol.owner))
return expression.value.maybeOptimizeIntoSwitch(context) { JsBinaryOperation(JsBinaryOperator.ASG, ref, it).makeStmt() }
}
@@ -525,18 +525,6 @@ class JvmSymbols(
returnType = dst.defaultType
}.symbol
val reassignParameterIntrinsic: IrSimpleFunctionSymbol =
irFactory.buildFun {
name = Name.special("<set-parameter>")
origin = IrDeclarationOrigin.IR_BUILTINS_STUB
}.apply {
parent = kotlinJvmInternalPackage
val type = addTypeParameter("T", irBuiltIns.anyNType)
addValueParameter("parameter", type.defaultType) // must be IrGetValue of an IrValueParameter
addValueParameter("value", type.defaultType)
returnType = irBuiltIns.unitType
}.symbol
private val collectionToArrayClass: IrClassSymbol = createClass(FqName("kotlin.jvm.internal.CollectionToArray")) { klass ->
klass.origin = JvmLoweredDeclarationOrigin.TO_ARRAY
@@ -41,7 +41,7 @@ import org.jetbrains.kotlin.ir.descriptors.toIrBasedKotlinType
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
@@ -685,7 +685,7 @@ class ExpressionCodegen(
throw AssertionError("Non-mapped local declaration: $irSymbol\n in ${irFunction.dump()}")
}
private fun handlePlusMinus(expression: IrSetVariable, value: IrExpression?, isMinus: Boolean): Boolean {
private fun handlePlusMinus(expression: IrSetValue, value: IrExpression?, isMinus: Boolean): Boolean {
if (value is IrConst<*> && value.kind == IrConstKind.Int) {
@Suppress("UNCHECKED_CAST")
val delta = (value as IrConst<Int>).value
@@ -707,7 +707,7 @@ class ExpressionCodegen(
// Be careful to make sure that debugging behavior does not change and
// only perform the optimization if that can be done without losing
// line number information.
private fun handleIntVariableSpecialCases(expression: IrSetVariable): Boolean {
private fun handleIntVariableSpecialCases(expression: IrSetValue): Boolean {
if (expression.symbol.owner.type.isInt()) {
when (expression.origin) {
IrStatementOrigin.PREFIX_INCR, IrStatementOrigin.PREFIX_DECR -> {
@@ -746,22 +746,22 @@ class ExpressionCodegen(
return false
}
override fun visitSetVariable(expression: IrSetVariable, data: BlockInfo): PromisedValue {
override fun visitSetValue(expression: IrSetValue, data: BlockInfo): PromisedValue {
if (!handleIntVariableSpecialCases(expression)) {
expression.value.markLineNumber(startOffset = true)
expression.value.accept(this, data).materializeAt(expression.symbol.owner.type)
expression.markLineNumber(startOffset = true)
// We set the value of parameters only for default values. The inliner accepts only
// a very specific bytecode pattern for default arguments and does not tolerate a
// line number on the store. Therefore, if we are storing to a parameter, we do not
// output a line number for the store.
if (expression.symbol !is IrValueParameterSymbol) {
expression.markLineNumber(startOffset = true)
}
mv.store(findLocalIndex(expression.symbol), expression.symbol.owner.asmType)
}
return unitValue
}
fun setVariable(symbol: IrValueSymbol, value: IrExpression, data: BlockInfo) {
value.markLineNumber(startOffset = true)
value.accept(this, data).materializeAt(symbol.owner.type)
mv.store(findLocalIndex(symbol), symbol.owner.asmType)
}
override fun <T> visitConst(expression: IrConst<T>, data: BlockInfo): PromisedValue {
expression.markLineNumber(startOffset = true)
when (val value = expression.value) {
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.ir.descriptors.WrappedVariableDescriptor
import org.jetbrains.kotlin.ir.expressions.IrConst
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrGetValue
import org.jetbrains.kotlin.ir.expressions.IrSetVariable
import org.jetbrains.kotlin.ir.expressions.IrSetValue
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl
@@ -115,7 +115,7 @@ class JvmSharedVariablesManager(
return sharedVariableDeclaration
}
val initializationStatement = with (originalDeclaration) {
IrSetVariableImpl(startOffset, endOffset, irBuiltIns.unitType, symbol, initializer, null)
IrSetValueImpl(startOffset, endOffset, irBuiltIns.unitType, symbol, initializer, null)
}
val sharedVariableInitialization = setSharedValue(sharedVariableDeclaration.symbol, initializationStatement)
return with(originalDeclaration) {
@@ -142,7 +142,7 @@ class JvmSharedVariablesManager(
unboxedType?.let { unsafeCoerce(unboxedRead, it, symbol.owner.type) } ?: unboxedRead
}
override fun setSharedValue(sharedVariableSymbol: IrVariableSymbol, originalSet: IrSetVariable): IrExpression =
override fun setSharedValue(sharedVariableSymbol: IrVariableSymbol, originalSet: IrSetValue): IrExpression =
with(originalSet) {
val unboxedType = InlineClassAbi.unboxType(symbol.owner.type)
val unboxedValue = unboxedType?.let { unsafeCoerce(value, symbol.owner.type, it) } ?: value
@@ -116,7 +116,6 @@ class IrIntrinsicMethods(val irBuiltIns: IrBuiltIns, val symbols: JvmSymbols) {
irBuiltIns.dataClassArrayMemberToStringSymbol.toKey()!! to IrDataClassArrayMemberToString,
symbols.unsafeCoerceIntrinsic.toKey()!! to UnsafeCoerce,
symbols.signatureStringIntrinsic.toKey()!! to SignatureString,
symbols.reassignParameterIntrinsic.toKey()!! to ReassignParameter,
symbols.throwNullPointerException.toKey()!! to ThrowException(Type.getObjectType("java/lang/NullPointerException")),
symbols.throwTypeCastException.toKey()!! to ThrowException(Type.getObjectType("kotlin/TypeCastException")),
symbols.throwUnsupportedOperationException.toKey()!! to ThrowException(Type.getObjectType("java/lang/UnsupportedOperationException")),
@@ -1,33 +0,0 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.backend.jvm.intrinsics
import org.jetbrains.kotlin.backend.jvm.codegen.*
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
import org.jetbrains.kotlin.ir.expressions.IrGetValue
import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol
// A magic intrinsic that changes the supposedly-immutable parameter referenced by its argument:
//
// fun f(x: Int) {
// <set-parameter>(x, 1)
// return x
// }
// assert(f(2) == 1)
//
// This *only* works for parameters; any other variable should be made mutable instead.
//
// This is used to optimize default method stubs (and, more importantly, produce bytecode that
// the inliner can actually handle) in `JvmDefaultArgumentStubGenerator`.
object ReassignParameter : IntrinsicMethod() {
override fun invoke(expression: IrFunctionAccessExpression, codegen: ExpressionCodegen, data: BlockInfo): PromisedValue {
val parameterGet = expression.getValueArgument(0) as? IrGetValue
val parameter = parameterGet?.symbol as? IrValueParameterSymbol
?: throw AssertionError("${expression.getValueArgument(0)} is not a get of a parameter")
codegen.setVariable(parameter, expression.getValueArgument(1)!!, data)
return codegen.unitValue
}
}
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBodyImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrSetValueImpl
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol
import org.jetbrains.kotlin.ir.types.typeWith
@@ -162,6 +163,13 @@ private class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringP
IrGetValueImpl(expression.startOffset, expression.endOffset, it.type, it.symbol, expression.origin)
} ?: expression
override fun visitSetValue(expression: IrSetValue): IrExpression {
expression.transformChildrenVoid()
return loweredEnumConstructorParameters[expression.symbol]?.let {
IrSetValueImpl(expression.startOffset, expression.endOffset, it.type, it.symbol, expression.value, expression.origin)
} ?: expression
}
override fun visitEnumConstructorCall(expression: IrEnumConstructorCall): IrExpression {
expression.transformChildrenVoid(this)
val scopeOwnerSymbol = currentScope!!.scope.scopeOwnerSymbol
@@ -9,7 +9,6 @@ import org.jetbrains.kotlin.backend.common.ir.isFinalClass
import org.jetbrains.kotlin.backend.common.lower.DefaultArgumentStubGenerator
import org.jetbrains.kotlin.backend.common.lower.irIfThen
import org.jetbrains.kotlin.backend.common.lower.irNot
import org.jetbrains.kotlin.backend.common.lower.irThrow
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.JvmLoweredStatementOrigin
@@ -40,11 +39,7 @@ class JvmDefaultArgumentStubGenerator(override val context: JvmBackendContext) :
//
// 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, irCall(this@JvmDefaultArgumentStubGenerator.context.ir.symbols.reassignParameterIntrinsic).apply {
putTypeArgument(0, parameter.type)
putValueArgument(0, irGet(parameter))
putValueArgument(1, default)
})
+irIfThen(defaultFlag, irSet(parameter.symbol, default))
return parameter
}
@@ -29,9 +29,8 @@ import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionReferenceImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrSetVariableImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrSetValueImpl
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol
import org.jetbrains.kotlin.ir.transformStatement
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.classOrNull
@@ -220,7 +219,7 @@ private class JvmInlineClassLowering(private val context: JvmBackendContext) : F
// This is safe, since the delegating constructor call precedes all references to "this".
override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall): IrExpression {
expression.transformChildrenVoid()
return irSetVar(thisVar.symbol, expression)
return irSet(thisVar.symbol, expression)
}
// A constructor body has type unit and may contain explicit return statements.
@@ -457,16 +456,16 @@ private class JvmInlineClassLowering(private val context: JvmBackendContext) : F
return super.visitGetValue(expression)
}
override fun visitSetVariable(expression: IrSetVariable): IrExpression {
override fun visitSetValue(expression: IrSetValue): IrExpression {
valueMap[expression.symbol]?.let {
return IrSetVariableImpl(
return IrSetValueImpl(
expression.startOffset, expression.endOffset,
it.type, it.symbol as IrVariableSymbol,
it.type, it.symbol,
expression.value.transform(this@JvmInlineClassLowering, null),
expression.origin
)
}
return super.visitSetVariable(expression)
return super.visitSetValue(expression)
}
private fun buildPrimaryInlineClassConstructor(irClass: IrClass, irConstructor: IrConstructor) {
@@ -76,7 +76,7 @@ class ExpressionTransformer : BaseTransformer<WasmInstruction, WasmCodegenContex
return WasmSetGlobal(fieldName, value)
}
override fun visitSetVariable(expression: IrSetVariable, data: WasmCodegenContext): WasmInstruction {
override fun visitSetValue(expression: IrSetValue, data: WasmCodegenContext): WasmInstruction {
val fieldName = data.getLocalName(expression.symbol.owner)
val value = expression.value.accept(this, data)
return WasmSetLocal(fieldName, value)
@@ -162,7 +162,7 @@ class IrCompileTimeChecker(
return visitedStack.contains(parent) || isObject
}
override fun visitSetVariable(expression: IrSetVariable, data: Nothing?): Boolean {
override fun visitSetValue(expression: IrSetValue, data: Nothing?): Boolean {
return expression.value.accept(this, data)
}
@@ -115,7 +115,7 @@ class IrInterpreter(private val irBuiltIns: IrBuiltIns, private val bodyMap: Map
is IrEnumEntry -> interpretEnumEntry(this)
is IrConst<*> -> interpretConst(this)
is IrVariable -> interpretVariable(this)
is IrSetVariable -> interpretSetVariable(this)
is IrSetValue -> interpretSetVariable(this)
is IrTypeOperatorCall -> interpretTypeOperatorCall(this)
is IrBranch -> interpretBranch(this)
is IrWhileLoop -> interpretWhile(this)
@@ -561,7 +561,7 @@ class IrInterpreter(private val irBuiltIns: IrBuiltIns, private val bodyMap: Map
return Next
}
private fun interpretSetVariable(expression: IrSetVariable): ExecutionResult {
private fun interpretSetVariable(expression: IrSetValue): ExecutionResult {
expression.value.interpret().check { return it }
if (stack.contains(expression.symbol)) {
@@ -21,11 +21,10 @@ import org.jetbrains.kotlin.ir.declarations.IrVariable
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrSetVariableImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrSetValueImpl
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.utils.addToStdlib.assertedCast
class VariableLValue(
@@ -46,7 +45,7 @@ class VariableLValue(
IrGetValueImpl(startOffset, endOffset, type, symbol, origin)
override fun store(irExpression: IrExpression): IrExpression =
IrSetVariableImpl(
IrSetValueImpl(
startOffset, endOffset,
context.irBuiltIns.unitType,
symbol.assertedCast<IrVariableSymbol> { "Not a variable: ${symbol.descriptor}" },
@@ -205,7 +205,7 @@ internal class InsertImplicitCasts(
}
}
override fun visitSetVariable(expression: IrSetVariable): IrExpression =
override fun visitSetValue(expression: IrSetValue): IrExpression =
expression.transformPostfix {
value = value.cast(expression.symbol.owner.type)
}
@@ -152,8 +152,8 @@ fun IrBuilderWithScope.irGet(type: IrType, variable: IrValueSymbol) =
fun IrBuilderWithScope.irGet(variable: IrValueDeclaration) = irGet(variable.type, variable.symbol)
fun IrBuilderWithScope.irSetVar(variable: IrVariableSymbol, value: IrExpression) =
IrSetVariableImpl(startOffset, endOffset, context.irBuiltIns.unitType, variable, value, IrStatementOrigin.EQ)
fun IrBuilderWithScope.irSet(variable: IrValueSymbol, value: IrExpression) =
IrSetValueImpl(startOffset, endOffset, context.irBuiltIns.unitType, variable, value, IrStatementOrigin.EQ)
fun IrBuilderWithScope.irGetField(receiver: IrExpression?, field: IrField) =
IrGetFieldImpl(startOffset, endOffset, field.symbol, field.type, receiver)
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.ir.expressions
import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol
@@ -28,7 +29,7 @@ abstract class IrGetValue : IrValueAccessExpression(), IrExpressionWithCopy {
abstract override fun copy(): IrGetValue
}
abstract class IrSetVariable : IrValueAccessExpression() {
abstract override val symbol: IrVariableSymbol
abstract class IrSetValue : IrValueAccessExpression() {
abstract override val symbol: IrValueSymbol
abstract var value: IrExpression
}
@@ -17,23 +17,23 @@
package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrSetVariable
import org.jetbrains.kotlin.ir.expressions.IrSetValue
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
class IrSetVariableImpl(
class IrSetValueImpl(
override val startOffset: Int,
override val endOffset: Int,
override var type: IrType,
override val symbol: IrVariableSymbol,
override val symbol: IrValueSymbol,
override var value: IrExpression,
override val origin: IrStatementOrigin?
) : IrSetVariable() {
) : IrSetValue() {
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
return visitor.visitSetVariable(this, data)
return visitor.visitSetValue(this, data)
}
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
@@ -457,11 +457,11 @@ open class DeepCopyIrTreeWithSymbols(
mapStatementOrigin(expression.origin)
).copyAttributes(expression)
override fun visitSetVariable(expression: IrSetVariable): IrSetVariable =
IrSetVariableImpl(
override fun visitSetValue(expression: IrSetValue): IrSetValue =
IrSetValueImpl(
expression.startOffset, expression.endOffset,
expression.type.remapType(),
symbolRemapper.getReferencedVariable(expression.symbol),
symbolRemapper.getReferencedValue(expression.symbol),
expression.value.transform(),
mapStatementOrigin(expression.origin)
).copyAttributes(expression)
@@ -607,7 +607,7 @@ class RenderIrElementVisitor(private val normalizeNames: Boolean = false) : IrEl
override fun visitGetValue(expression: IrGetValue, data: Nothing?): String =
"GET_VAR '${expression.symbol.renderReference()}' type=${expression.type.render()} origin=${expression.origin}"
override fun visitSetVariable(expression: IrSetVariable, data: Nothing?): String =
override fun visitSetValue(expression: IrSetValue, data: Nothing?): String =
"SET_VAR '${expression.symbol.renderReference()}' type=${expression.type.render()} origin=${expression.origin}"
override fun visitGetField(expression: IrGetField, data: Nothing?): String =
@@ -98,7 +98,7 @@ interface IrElementTransformer<in D> : IrElementVisitor<IrElement, D> {
override fun visitGetEnumValue(expression: IrGetEnumValue, data: D) = visitSingletonReference(expression, data)
override fun visitValueAccess(expression: IrValueAccessExpression, data: D) = visitDeclarationReference(expression, data)
override fun visitGetValue(expression: IrGetValue, data: D) = visitValueAccess(expression, data)
override fun visitSetVariable(expression: IrSetVariable, data: D) = visitValueAccess(expression, data)
override fun visitSetValue(expression: IrSetValue, data: D) = visitValueAccess(expression, data)
override fun visitFieldAccess(expression: IrFieldAccessExpression, data: D) = visitDeclarationReference(expression, data)
override fun visitGetField(expression: IrGetField, data: D) = visitFieldAccess(expression, data)
override fun visitSetField(expression: IrSetField, data: D) = visitFieldAccess(expression, data)
@@ -177,8 +177,8 @@ abstract class IrElementTransformerVoid : IrElementTransformer<Nothing?> {
open fun visitGetValue(expression: IrGetValue) = visitValueAccess(expression)
final override fun visitGetValue(expression: IrGetValue, data: Nothing?) = visitGetValue(expression)
open fun visitSetVariable(expression: IrSetVariable) = visitValueAccess(expression)
final override fun visitSetVariable(expression: IrSetVariable, data: Nothing?) = visitSetVariable(expression)
open fun visitSetValue(expression: IrSetValue) = visitValueAccess(expression)
final override fun visitSetValue(expression: IrSetValue, data: Nothing?) = visitSetValue(expression)
open fun visitFieldAccess(expression: IrFieldAccessExpression) = visitDeclarationReference(expression)
final override fun visitFieldAccess(expression: IrFieldAccessExpression, data: Nothing?) = visitFieldAccess(expression)
@@ -67,7 +67,7 @@ interface IrElementVisitor<out R, in D> {
fun visitGetEnumValue(expression: IrGetEnumValue, data: D) = visitSingletonReference(expression, data)
fun visitValueAccess(expression: IrValueAccessExpression, data: D) = visitDeclarationReference(expression, data)
fun visitGetValue(expression: IrGetValue, data: D) = visitValueAccess(expression, data)
fun visitSetVariable(expression: IrSetVariable, data: D) = visitValueAccess(expression, data)
fun visitSetValue(expression: IrSetValue, data: D) = visitValueAccess(expression, data)
fun visitFieldAccess(expression: IrFieldAccessExpression, data: D) = visitDeclarationReference(expression, data)
fun visitGetField(expression: IrGetField, data: D) = visitFieldAccess(expression, data)
fun visitSetField(expression: IrSetField, data: D) = visitFieldAccess(expression, data)
@@ -143,8 +143,8 @@ interface IrElementVisitorVoid : IrElementVisitor<Unit, Nothing?> {
fun visitGetValue(expression: IrGetValue) = visitVariableAccess(expression)
override fun visitGetValue(expression: IrGetValue, data: Nothing?) = visitGetValue(expression)
fun visitSetVariable(expression: IrSetVariable) = visitVariableAccess(expression)
override fun visitSetVariable(expression: IrSetVariable, data: Nothing?) = visitSetVariable(expression)
fun visitSetValue(expression: IrSetValue) = visitVariableAccess(expression)
override fun visitSetValue(expression: IrSetValue, data: Nothing?) = visitSetValue(expression)
fun visitFieldAccess(expression: IrFieldAccessExpression) = visitDeclarationReference(expression)
override fun visitFieldAccess(expression: IrFieldAccessExpression, data: Nothing?) = visitFieldAccess(expression)
@@ -607,11 +607,11 @@ abstract class IrFileDeserializer(
return IrSetFieldImpl(start, end, symbol, receiver, value, builtIns.unitType, origin, superQualifier)
}
private fun deserializeSetVariable(proto: ProtoSetVariable, start: Int, end: Int): IrSetVariable {
private fun deserializeSetVariable(proto: ProtoSetVariable, start: Int, end: Int): IrSetValue {
val symbol = deserializeIrSymbolAndRemap(proto.symbol) as IrVariableSymbol
val value = deserializeExpression(proto.value)
val origin = if (proto.hasOriginName()) deserializeIrStatementOrigin(proto.originName) else null
return IrSetVariableImpl(start, end, builtIns.unitType, symbol, value, origin)
return IrSetValueImpl(start, end, builtIns.unitType, symbol, value, origin)
}
private fun deserializeSpreadElement(proto: ProtoSpreadElement): IrSpreadElement {
@@ -673,7 +673,7 @@ open class IrFileSerializer(
}
.build()
private fun serializeSetVariable(expression: IrSetVariable): ProtoSetVariable =
private fun serializeSetVariable(expression: IrSetValue): ProtoSetVariable =
ProtoSetVariable.newBuilder()
.setSymbol(serializeIrSymbol(expression.symbol))
.setValue(serializeExpression(expression.value)).apply {
@@ -933,7 +933,7 @@ open class IrFileSerializer(
is IrPropertyReference -> operationProto.propertyReference = serializePropertyReference(expression)
is IrReturn -> operationProto.`return` = serializeReturn(expression)
is IrSetField -> operationProto.setField = serializeSetField(expression)
is IrSetVariable -> operationProto.setVariable = serializeSetVariable(expression)
is IrSetValue -> operationProto.setVariable = serializeSetVariable(expression)
is IrStringConcatenation -> operationProto.stringConcat = serializeStringConcat(expression)
is IrThrow -> operationProto.`throw` = serializeThrow(expression)
is IrTry -> operationProto.`try` = serializeTry(expression)
@@ -299,7 +299,7 @@ class IrSparseArrayParcelSerializer(
}
val dec = context.irBuiltIns.intClass.getSimpleFunction("dec")!!
+irSetVar(remainingSizeTemporary.symbol, irCall(dec).apply {
+irSet(remainingSizeTemporary.symbol, irCall(dec).apply {
dispatchReceiver = irGet(remainingSizeTemporary)
})
}
@@ -131,7 +131,7 @@ inline fun IrBlockBuilder.forUntil(upperBound: IrExpression, loopBody: IrBlockBu
body = irBlock {
loopBody(indexTemporary)
val inc = context.irBuiltIns.intClass.getSimpleFunction("inc")!!
+irSetVar(indexTemporary.symbol, irCall(inc).apply {
+irSet(indexTemporary.symbol, irCall(inc).apply {
dispatchReceiver = irGet(indexTemporary)
})
}
@@ -419,14 +419,14 @@ open class SerializerIrGenerator(val irClass: IrClass, final override val compil
args.add(localProps[index].get())
}
// local$i = localInput.decode...(...)
+irSetVar(
+irSet(
localProps[index].symbol,
irInvoke(localInput.get(), decodeFuncToCall, typeArgs, args, returnTypeHint = property.type.toIrType())
)
// bitMask[i] |= 1 << x
val bitPos = 1 shl (index % 32)
val or = irBinOp(OperatorNameConventions.OR, bitMasks[index / 32].get(), irInt(bitPos))
+irSetVar(bitMasks[index / 32].symbol, or)
+irSet(bitMasks[index / 32].symbol, or)
}
index to body
}
@@ -442,10 +442,10 @@ open class SerializerIrGenerator(val irClass: IrClass, final override val compil
loop.condition = flagVar.get()
loop.body = irBlock {
val readElementF = inputClass.referenceMethod(CallingConventions.decodeElementIndex)
+irSetVar(indexVar.symbol, irInvoke(localInput.get(), readElementF, localSerialDesc.get()))
+irSet(indexVar.symbol, irInvoke(localInput.get(), readElementF, localSerialDesc.get()))
+irWhen {
// if index == -1 (READ_DONE) break loop
+IrBranchImpl(irEquals(indexVar.get(), irInt(-1)), irSetVar(flagVar.symbol, irBoolean(false)))
+IrBranchImpl(irEquals(indexVar.get(), irInt(-1)), irSet(flagVar.symbol, irBoolean(false)))
decoderCalls.forEach { (i, e) -> +IrBranchImpl(irEquals(indexVar.get(), irInt(i)), e) }