diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/UnitMaterializationLowering.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/UnitMaterializationLowering.kt index ea57817b071..e2b7cbb292e 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/UnitMaterializationLowering.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/UnitMaterializationLowering.kt @@ -19,10 +19,16 @@ import org.jetbrains.kotlin.ir.types.isUnit import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid -class UnitMaterializationLowering(context: BackendContext): FileLoweringPass { +class UnitMaterializationLowering(context: BackendContext) : FileLoweringPass { private val unitType = context.irBuiltIns.unitType - private val unitValue = IrGetObjectValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, unitType, unitType.classifierOrFail as IrClassSymbol) + private val unitValue + get() = IrGetObjectValueImpl( + UNDEFINED_OFFSET, + UNDEFINED_OFFSET, + unitType, + unitType.classifierOrFail as IrClassSymbol + ) override fun lower(irFile: IrFile) { irFile.transformChildrenVoid(object : IrElementTransformerVoid() { diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/BlockDecomposerLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/BlockDecomposerLowering.kt index 6682f8a029d..92b07a9b3c4 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/BlockDecomposerLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/BlockDecomposerLowering.kt @@ -79,19 +79,19 @@ class BlockDecomposerLowering(context: JsIrBackendContext) : DeclarationContaine } } -class BlockDecomposerTransformer(context: JsIrBackendContext) : IrElementTransformerVoid() { +class BlockDecomposerTransformer(private val context: JsIrBackendContext) : IrElementTransformerVoid() { private lateinit var function: IrFunction private var tmpVarCounter: Int = 0 private val statementTransformer = StatementTransformer() private val expressionTransformer = ExpressionTransformer() - private val constTrue = JsIrBuilder.buildBoolean(context.irBuiltIns.booleanType, true) - private val constFalse = JsIrBuilder.buildBoolean(context.irBuiltIns.booleanType, false) + private val constTrue get() = JsIrBuilder.buildBoolean(context.irBuiltIns.booleanType, true) + private val constFalse get() = JsIrBuilder.buildBoolean(context.irBuiltIns.booleanType, false) private val nothingType = context.irBuiltIns.nothingNType private val unitType = context.irBuiltIns.unitType - private val unitValue = JsIrBuilder.buildGetObjectValue(unitType, context.symbolTable.referenceClass(context.builtIns.unit)) + private val unitValue get() = JsIrBuilder.buildGetObjectValue(unitType, context.symbolTable.referenceClass(context.builtIns.unit)) private val unreachableFunction = context.intrinsics.unreachable private val booleanNotSymbol = context.irBuiltIns.booleanNotSymbol diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/CallableReferenceLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/CallableReferenceLowering.kt index c9a13031820..000d7dcdd40 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/CallableReferenceLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/CallableReferenceLowering.kt @@ -43,9 +43,9 @@ data class CallableReferenceKey( // TODO: generate $metadata$ property and fill it with corresponding KFunction/KProperty interface class CallableReferenceLowering(val context: JsIrBackendContext) : FileLoweringPass { - private val callableNameConst = JsIrBuilder.buildString(context.irBuiltIns.stringType, Namer.KCALLABLE_NAME) - private val getterConst = JsIrBuilder.buildString(context.irBuiltIns.stringType, Namer.KPROPERTY_GET) - private val setterConst = JsIrBuilder.buildString(context.irBuiltIns.stringType, Namer.KPROPERTY_SET) + private val callableNameConst get() = JsIrBuilder.buildString(context.irBuiltIns.stringType, Namer.KCALLABLE_NAME) + private val getterConst get() = JsIrBuilder.buildString(context.irBuiltIns.stringType, Namer.KPROPERTY_GET) + private val setterConst get() = JsIrBuilder.buildString(context.irBuiltIns.stringType, Namer.KPROPERTY_SET) private val callableToFactoryFunction = context.callableReferencesCache private val newDeclarations = mutableListOf() @@ -327,13 +327,13 @@ class CallableReferenceLowering(val context: JsIrBackendContext) : FileLoweringP // val cacheName = "${factoryFunction.name}_${Namer.KCALLABLE_CACHE_SUFFIX}" val type = factoryFunction.returnType - val irNull = JsIrBuilder.buildNull(context.irBuiltIns.nothingNType) - val cacheVar = JsIrBuilder.buildVar(type, factoryFunction.parent, cacheName, true, initializer = irNull) + val irNull = { JsIrBuilder.buildNull(context.irBuiltIns.nothingNType) } + val cacheVar = JsIrBuilder.buildVar(type, factoryFunction.parent, cacheName, true, initializer = irNull()) - val irCacheValue = JsIrBuilder.buildGetValue(cacheVar.symbol) + val irCacheValue = { JsIrBuilder.buildGetValue(cacheVar.symbol) } val irIfCondition = JsIrBuilder.buildCall(context.irBuiltIns.eqeqSymbol).apply { - putValueArgument(0, irCacheValue) - putValueArgument(1, irNull) + putValueArgument(0, irCacheValue()) + putValueArgument(1, irNull()) } val irSetCache = JsIrBuilder.buildSetVariable(cacheVar.symbol, JsIrBuilder.buildGetValue(varSymbol), context.irBuiltIns.unitType) @@ -344,7 +344,7 @@ class CallableReferenceLowering(val context: JsIrBackendContext) : FileLoweringP val irThenBranch = JsIrBuilder.buildBlock(context.irBuiltIns.unitType, thenStatements) val irIfNode = JsIrBuilder.buildIfElse(context.irBuiltIns.unitType, irIfCondition, irThenBranch) statements += irIfNode - returnValue = irCacheValue + returnValue = irCacheValue() returnStatements = listOf(cacheVar) } else { statements += bodyStatements diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/MultipleCatchesLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/MultipleCatchesLowering.kt index 90ef41fabc2..9118eeed440 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/MultipleCatchesLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/MultipleCatchesLowering.kt @@ -51,7 +51,7 @@ import org.jetbrains.kotlin.ir.visitors.IrElementTransformer */ class MultipleCatchesLowering(val context: JsIrBackendContext) : FileLoweringPass { - val litTrue = JsIrBuilder.buildBoolean(context.irBuiltIns.booleanType, true) + val litTrue get() = JsIrBuilder.buildBoolean(context.irBuiltIns.booleanType, true) val unitType = context.irBuiltIns.unitType val nothingType = context.irBuiltIns.nothingType @@ -70,7 +70,7 @@ class MultipleCatchesLowering(val context: JsIrBackendContext) : FileLoweringPas val commonType = mergeTypes(aTry.catches.map { it.catchParameter.type }) val pendingExceptionDeclaration = JsIrBuilder.buildVar(commonType, data, "\$p") - val pendingException = JsIrBuilder.buildGetValue(pendingExceptionDeclaration.symbol) + val pendingException = { JsIrBuilder.buildGetValue(pendingExceptionDeclaration.symbol) } val branches = mutableListOf() @@ -81,9 +81,9 @@ class MultipleCatchesLowering(val context: JsIrBackendContext) : FileLoweringPas val typeSymbol = type.classifierOrNull val castedPendingException = { if (type !is IrDynamicType) - buildImplicitCast(pendingException, type, typeSymbol!!) + buildImplicitCast(pendingException(), type, typeSymbol!!) else - pendingException + pendingException() } val catchBody = catch.result.transform(object : IrElementTransformer { @@ -98,14 +98,14 @@ class MultipleCatchesLowering(val context: JsIrBackendContext) : FileLoweringPas branches += IrElseBranchImpl(catch.startOffset, catch.endOffset, litTrue, catchBody) break } else { - val typeCheck = buildIsCheck(pendingException, type, typeSymbol!!) + val typeCheck = buildIsCheck(pendingException(), type, typeSymbol!!) branches += IrBranchImpl(catch.startOffset, catch.endOffset, typeCheck, catchBody) } } if (commonType !is IrDynamicType) { - val throwStatement = JsIrBuilder.buildThrow(nothingType, pendingException) + val throwStatement = JsIrBuilder.buildThrow(nothingType, pendingException()) branches += IrElseBranchImpl(litTrue, JsIrBuilder.buildBlock(nothingType, listOf(throwStatement))) } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ThrowableSuccessorsLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ThrowableSuccessorsLowering.kt index d06f4e3e626..2c91f3ef8d2 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ThrowableSuccessorsLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ThrowableSuccessorsLowering.kt @@ -40,9 +40,9 @@ class ThrowableSuccessorsLowering(context: JsIrBackendContext) : FileLoweringPas private val propertySetter = context.intrinsics.jsSetJSField.symbol private val eqeqeqSymbol = context.irBuiltIns.eqeqSymbol - private val messageName = JsIrBuilder.buildString(stringType, "message") - private val causeName = JsIrBuilder.buildString(stringType, "cause") - private val nameName = JsIrBuilder.buildString(stringType, "name") + private val messageName get() = JsIrBuilder.buildString(stringType, "message") + private val causeName get() = JsIrBuilder.buildString(stringType, "cause") + private val nameName get() = JsIrBuilder.buildString(stringType, "name") private val throwableClass = context.symbolTable.referenceClass( context.getClass(JsIrBackendContext.KOTLIN_PACKAGE_FQN.child(Name.identifier("Throwable"))) @@ -121,15 +121,15 @@ class ThrowableSuccessorsLowering(context: JsIrBackendContext) : FileLoweringPas } private fun extractConstructorParameters(expression: IrFunctionAccessExpression): Pair { - val nullValue = IrConstImpl.constNull(expression.startOffset, expression.endOffset, nothingNType) + val nullValue = { IrConstImpl.constNull(expression.startOffset, expression.endOffset, nothingNType) } return when { - expression.valueArgumentsCount == 0 -> Pair(nullValue, nullValue) + expression.valueArgumentsCount == 0 -> Pair(nullValue(), nullValue()) expression.valueArgumentsCount == 2 -> expression.run { Pair(getValueArgument(0)!!, getValueArgument(1)!!) } else -> { val arg = expression.getValueArgument(0)!! when { - arg.type.makeNotNull().isThrowable() -> Pair(nullValue, arg) - else -> Pair(arg, nullValue) + arg.type.makeNotNull().isThrowable() -> Pair(nullValue(), arg) + else -> Pair(arg, nullValue()) } } } @@ -229,7 +229,7 @@ class ThrowableSuccessorsLowering(context: JsIrBackendContext) : FileLoweringPas } val klass = successor.klass - val receiver = IrGetValueImpl(expression.startOffset, expression.endOffset, klass.thisReceiver!!.symbol) + val receiver = { IrGetValueImpl(expression.startOffset, expression.endOffset, klass.thisReceiver!!.symbol) } val fillStatements = fillThrowableInstance(expression, receiver, messageArg, causeArg) @@ -240,21 +240,21 @@ class ThrowableSuccessorsLowering(context: JsIrBackendContext) : FileLoweringPas private fun fillThrowableInstance( expression: IrFunctionAccessExpression, - receiver: IrExpression, + receiver: () -> IrExpression, messageArg: IrExpression, causeArg: IrExpression ): List { val setMessage = expression.run { - IrSetFieldImpl(startOffset, endOffset, successor.message.symbol, receiver, messageArg, unitType) + IrSetFieldImpl(startOffset, endOffset, successor.message.symbol, receiver(), messageArg, unitType) } val setCause = expression.run { - IrSetFieldImpl(startOffset, endOffset, successor.cause.symbol, receiver, causeArg, unitType) + IrSetFieldImpl(startOffset, endOffset, successor.cause.symbol, receiver(), causeArg, unitType) } val setStackTrace = IrCallImpl(expression.startOffset, expression.endOffset, unitType, captureStackFunction).apply { - putValueArgument(0, receiver) + putValueArgument(0, receiver()) } return listOf(setMessage, setCause, setStackTrace) @@ -264,10 +264,10 @@ class ThrowableSuccessorsLowering(context: JsIrBackendContext) : FileLoweringPas expression: IrFunctionAccessExpression, parent: IrDeclarationParent ): Triple> { - val nullValue = IrConstImpl.constNull(expression.startOffset, expression.endOffset, nothingNType) + val nullValue = { IrConstImpl.constNull(expression.startOffset, expression.endOffset, nothingNType) } // Wrap parameters into variables to keep original evaluation order return when { - expression.valueArgumentsCount == 0 -> Triple(nullValue, nullValue, emptyList()) + expression.valueArgumentsCount == 0 -> Triple(nullValue(), nullValue(), emptyList()) expression.valueArgumentsCount == 2 -> { val msg = expression.getValueArgument(0)!! val cus = expression.getValueArgument(1)!! @@ -276,7 +276,7 @@ class ThrowableSuccessorsLowering(context: JsIrBackendContext) : FileLoweringPas val check = JsIrBuilder.buildCall(eqeqeqSymbol, booleanType).apply { putValueArgument(0, JsIrBuilder.buildGetValue(irValM.symbol)) - putValueArgument(1, nullValue) + putValueArgument(1, nullValue()) } val msgElvis = JsIrBuilder.buildIfElse( @@ -292,7 +292,7 @@ class ThrowableSuccessorsLowering(context: JsIrBackendContext) : FileLoweringPas val argValue = JsIrBuilder.buildGetValue(irVal.symbol) when { arg.type.makeNotNull().isThrowable() -> Triple(safeCallToString(irVal), argValue, listOf(irVal)) - else -> Triple(argValue, nullValue, listOf(irVal)) + else -> Triple(argValue, nullValue(), listOf(irVal)) } } } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/TypeOperatorLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/TypeOperatorLowering.kt index f767205dc09..e467261d8e4 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/TypeOperatorLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/TypeOperatorLowering.kt @@ -17,6 +17,7 @@ import org.jetbrains.kotlin.ir.declarations.IrDeclarationParent import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.expressions.IrExpression +import org.jetbrains.kotlin.ir.expressions.IrExpressionWithCopy import org.jetbrains.kotlin.ir.expressions.IrTypeOperator import org.jetbrains.kotlin.ir.expressions.IrTypeOperatorCall import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl @@ -31,13 +32,13 @@ import org.jetbrains.kotlin.ir.visitors.IrElementTransformer class TypeOperatorLowering(val context: JsIrBackendContext) : FileLoweringPass { private val unit = context.irBuiltIns.unitType - private val unitValue = JsIrBuilder.buildGetObjectValue(unit, unit.classifierOrFail as IrClassSymbol) + private val unitValue get() = JsIrBuilder.buildGetObjectValue(unit, unit.classifierOrFail as IrClassSymbol) - private val lit24 = JsIrBuilder.buildInt(context.irBuiltIns.intType, 24) - private val lit16 = JsIrBuilder.buildInt(context.irBuiltIns.intType, 16) + private val lit24 get() = JsIrBuilder.buildInt(context.irBuiltIns.intType, 24) + private val lit16 get() = JsIrBuilder.buildInt(context.irBuiltIns.intType, 16) - private val byteMask = JsIrBuilder.buildInt(context.irBuiltIns.intType, 0xFF) - private val shortMask = JsIrBuilder.buildInt(context.irBuiltIns.intType, 0xFFFF) + private val byteMask get() = JsIrBuilder.buildInt(context.irBuiltIns.intType, 0xFF) + private val shortMask get() = JsIrBuilder.buildInt(context.irBuiltIns.intType, 0xFFFF) private val calculator = JsIrArithBuilder(context) @@ -56,14 +57,14 @@ class TypeOperatorLowering(val context: JsIrBackendContext) : FileLoweringPass { private val typeOfIntrinsicSymbol = context.intrinsics.jsTypeOf.symbol private val jsClassIntrinsicSymbol = context.intrinsics.jsClass - private val stringMarker = JsIrBuilder.buildString(context.irBuiltIns.stringType, "string") - private val booleanMarker = JsIrBuilder.buildString(context.irBuiltIns.stringType, "boolean") - private val functionMarker = JsIrBuilder.buildString(context.irBuiltIns.stringType, "function") - private val numberMarker = JsIrBuilder.buildString(context.irBuiltIns.stringType, "number") + private val stringMarker get() = JsIrBuilder.buildString(context.irBuiltIns.stringType, "string") + private val booleanMarker get() = JsIrBuilder.buildString(context.irBuiltIns.stringType, "boolean") + private val functionMarker get() = JsIrBuilder.buildString(context.irBuiltIns.stringType, "function") + private val numberMarker get() = JsIrBuilder.buildString(context.irBuiltIns.stringType, "number") - private val litTrue: IrExpression = JsIrBuilder.buildBoolean(context.irBuiltIns.booleanType, true) - private val litFalse: IrExpression = JsIrBuilder.buildBoolean(context.irBuiltIns.booleanType, false) - private val litNull: IrExpression = JsIrBuilder.buildNull(context.irBuiltIns.nothingNType) + private val litTrue: IrExpression get() = JsIrBuilder.buildBoolean(context.irBuiltIns.booleanType, true) + private val litFalse: IrExpression get() = JsIrBuilder.buildBoolean(context.irBuiltIns.booleanType, false) + private val litNull: IrExpression get() = JsIrBuilder.buildNull(context.irBuiltIns.nothingNType) override fun lower(irFile: IrFile) { irFile.transformChildren(object : IrElementTransformer { @@ -96,9 +97,9 @@ class TypeOperatorLowering(val context: JsIrBackendContext) : FileLoweringPass { val newStatements = mutableListOf() val argument = cacheValue(expression.argument, newStatements, declaration) - val irNullCheck = nullCheck(argument) + val irNullCheck = nullCheck(argument()) - newStatements += JsIrBuilder.buildIfElse(expression.typeOperand, irNullCheck, JsIrBuilder.buildCall(throwNPE), argument) + newStatements += JsIrBuilder.buildIfElse(expression.typeOperand, irNullCheck, JsIrBuilder.buildCall(throwNPE), argument()) return expression.run { IrCompositeImpl(startOffset, endOffset, typeOperand, null, newStatements) } } @@ -117,12 +118,13 @@ class TypeOperatorLowering(val context: JsIrBackendContext) : FileLoweringPass { val newStatements = mutableListOf() val argument = cacheValue(expression.argument, newStatements, declaration) - val check = generateTypeCheck(argument, toType) - newStatements += JsIrBuilder.buildIfElse(toType, check, argument, failResult) + newStatements += JsIrBuilder.buildIfElse(toType, check, argument(), failResult) - return expression.run { IrCompositeImpl(startOffset, endOffset, toType, null, newStatements) } + return expression.run { + IrCompositeImpl(startOffset, endOffset, toType, null, newStatements) + } } private fun lowerImplicitCast(expression: IrTypeOperatorCall) = expression.run { @@ -155,18 +157,19 @@ class TypeOperatorLowering(val context: JsIrBackendContext) : FileLoweringPass { assert((expression.operator == IrTypeOperator.NOT_INSTANCEOF) == inverted) val toType = expression.typeOperand - val isCopyRequired = expression.argument.type.isNullable() && advancedCheckRequired(toType.makeNotNull()) val newStatements = mutableListOf() - val argument = - if (isCopyRequired) cacheValue(expression.argument, newStatements, declaration) else expression.argument + val argument = cacheValue(expression.argument, newStatements, declaration) val check = generateTypeCheck(argument, toType) val result = if (inverted) calculator.not(check) else check - - return if (isCopyRequired) { - newStatements += result - IrCompositeImpl(expression.startOffset, expression.endOffset, toType, null, newStatements) - } else result + newStatements += result + return IrCompositeImpl( + expression.startOffset, + expression.endOffset, + context.irBuiltIns.booleanType, + null, + newStatements + ) } private fun nullCheck(value: IrExpression) = JsIrBuilder.buildCall(eqeq).apply { @@ -178,40 +181,41 @@ class TypeOperatorLowering(val context: JsIrBackendContext) : FileLoweringPass { value: IrExpression, newStatements: MutableList, declaration: IrDeclarationParent - ): IrExpression { + ): () -> IrExpressionWithCopy { val varDeclaration = JsIrBuilder.buildVar(value.type, declaration, initializer = value) newStatements += varDeclaration - return JsIrBuilder.buildGetValue(varDeclaration.symbol) + return { JsIrBuilder.buildGetValue(varDeclaration.symbol) } } - private fun generateTypeCheck(argument: IrExpression, toType: IrType): IrExpression { + private fun generateTypeCheck(argument: () -> IrExpressionWithCopy, toType: IrType): IrExpression { // TODO: Fix unbound symbols (in inline) toType.classifierOrNull?.apply { if (!isBound) { - return argument + return argument() } } val toNotNullable = toType.makeNotNull() - val instanceCheck = generateTypeCheckNonNull(argument, toNotNullable) - val isFromNullable = argument.type.isNullable() + val argumentInstance = argument() + val instanceCheck = generateTypeCheckNonNull(argumentInstance, toNotNullable) + val isFromNullable = argumentInstance.type.isNullable() val isToNullable = toType.isNullable() val isNativeCheck = !advancedCheckRequired(toNotNullable) return when { !isFromNullable -> instanceCheck // ! -> * - isToNullable -> calculator.run { oror(nullCheck(argument), instanceCheck) } // * -> ? + isToNullable -> calculator.run { oror(nullCheck(argument()), instanceCheck) } // * -> ? else -> if (isNativeCheck) instanceCheck else calculator.run { andand( - not(nullCheck(argument)), + not(nullCheck(argument())), instanceCheck ) } // ? -> ! } } - private fun generateTypeCheckNonNull(argument: IrExpression, toType: IrType): IrExpression { + private fun generateTypeCheckNonNull(argument: IrExpressionWithCopy, toType: IrType): IrExpression { assert(!toType.isMarkedNullable()) return when { toType.isAny() -> generateIsObjectCheck(argument) @@ -232,7 +236,7 @@ class TypeOperatorLowering(val context: JsIrBackendContext) : FileLoweringPass { putValueArgument(0, argument) } - private fun generateTypeCheckWithTypeParameter(argument: IrExpression, toType: IrType): IrExpression { + private fun generateTypeCheckWithTypeParameter(argument: IrExpressionWithCopy, toType: IrType): IrExpression { val typeParameterSymbol = (toType.classifierOrNull as? IrTypeParameterSymbol) ?: error("expected type parameter, but $toType") @@ -244,9 +248,8 @@ class TypeOperatorLowering(val context: JsIrBackendContext) : FileLoweringPass { val typeParameter = typeParameterSymbol.owner assert(!typeParameter.isReified) { "reified parameters have to be lowered before" } - return typeParameter.superTypes.fold(litTrue) { r, t -> - val check = generateTypeCheckNonNull(argument, t.makeNotNull()) + val check = generateTypeCheckNonNull(argument.copy(), t.makeNotNull()) calculator.and(r, check) } } @@ -314,25 +317,23 @@ class TypeOperatorLowering(val context: JsIrBackendContext) : FileLoweringPass { val isNullable = expression.argument.type.isNullable() val toType = expression.typeOperand - fun maskOp(arg: IrExpression, mask: IrExpression, shift: IrExpression) = calculator.run { - shr(shl(and(arg, mask), shift), shift) + fun maskOp(arg: IrExpression, mask: IrExpression, shift: IrExpressionWithCopy) = calculator.run { + shr(shl(and(arg, mask), shift), shift.copy()) } val newStatements = mutableListOf() - - val argument = - if (isNullable) cacheValue(expression.argument, newStatements, declaration) else expression.argument + val argument = cacheValue(expression.argument, newStatements, declaration) val casted = when { - toType.isByte() -> maskOp(argument, byteMask, lit24) - toType.isShort() -> maskOp(argument, shortMask, lit16) + toType.isByte() -> maskOp(argument(), byteMask, lit24) + toType.isShort() -> maskOp(argument(), shortMask, lit16) toType.isLong() -> JsIrBuilder.buildCall(context.intrinsics.jsToLong).apply { - putValueArgument(0, argument) + putValueArgument(0, argument()) } else -> error("Unreachable execution (coercion to non-Integer type") } - newStatements += if (isNullable) JsIrBuilder.buildIfElse(toType, nullCheck(argument), litNull, casted) else casted + newStatements += if (isNullable) JsIrBuilder.buildIfElse(toType, nullCheck(argument()), litNull, casted) else casted return expression.run { IrCompositeImpl(startOffset, endOffset, toType, null, newStatements) } } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/coroutines/SuspendFunctionsLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/coroutines/SuspendFunctionsLowering.kt index 1ff9e3f9e09..7b6429c0453 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/coroutines/SuspendFunctionsLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/coroutines/SuspendFunctionsLowering.kt @@ -943,7 +943,7 @@ internal class SuspendFunctionsLowering(val context: JsIrBackendContext): FileLo } } - function.transform(LiveLocalsTransformer(localToPropertyMap, JsIrBuilder.buildGetValue(thisReceiver), unit), null) + function.transform(LiveLocalsTransformer(localToPropertyMap, { JsIrBuilder.buildGetValue(thisReceiver) } , unit), null) } private fun computeLivenessAtSuspensionPoints(body: IrBody): Map> { diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/coroutines/SuspendLoweringUtils.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/coroutines/SuspendLoweringUtils.kt index 007232a56f2..7951e888ef3 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/coroutines/SuspendLoweringUtils.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/coroutines/SuspendLoweringUtils.kt @@ -147,19 +147,19 @@ class SuspendedTerminatorsCollector(suspendableNodes: MutableSet) : S class LiveLocalsTransformer( private val localMap: Map, - private val receiver: IrExpression, + private val receiver: () -> IrExpression, private val unitType: IrType ) : IrElementTransformerVoid() { override fun visitGetValue(expression: IrGetValue): IrExpression { val field = localMap[expression.symbol] ?: return expression - return expression.run { IrGetFieldImpl(startOffset, endOffset, field, type, receiver, origin) } + return expression.run { IrGetFieldImpl(startOffset, endOffset, field, type, receiver(), origin) } } override fun visitSetVariable(expression: IrSetVariable): IrExpression { expression.transformChildrenVoid(this) val field = localMap[expression.symbol] ?: return expression - return expression.run { IrSetFieldImpl(startOffset, endOffset, field, receiver, value, unitType, origin) } + return expression.run { IrSetFieldImpl(startOffset, endOffset, field, receiver(), value, unitType, origin) } } override fun visitVariable(declaration: IrVariable): IrStatement { @@ -167,7 +167,7 @@ class LiveLocalsTransformer( val field = localMap[declaration.symbol] ?: return declaration val initializer = declaration.initializer return if (initializer != null) { - declaration.run { IrSetFieldImpl(startOffset, endOffset, field, receiver, initializer, unitType) } + declaration.run { IrSetFieldImpl(startOffset, endOffset, field, receiver(), initializer, unitType) } } else { JsIrBuilder.buildComposite(declaration.type) } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/inline/ReturnableBlockLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/inline/ReturnableBlockLowering.kt index 0435cd85969..51b8c09b38b 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/inline/ReturnableBlockLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/inline/ReturnableBlockLowering.kt @@ -96,7 +96,7 @@ private class ReturnableBlockTransformer( return super.visitDeclaration(declaration, data) } - private val constFalse = JsIrBuilder.buildBoolean(context.irBuiltIns.booleanType, false) + private val constFalse get() = JsIrBuilder.buildBoolean(context.irBuiltIns.booleanType, false) override fun visitContainerExpression(expression: IrContainerExpression, data: ReturnableBlockLoweringContext): IrExpression { if (expression !is IrReturnableBlock) return super.visitContainerExpression(expression, data) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrExpression.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrExpression.kt index 2b590267a76..939be128235 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrExpression.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/IrExpression.kt @@ -28,6 +28,6 @@ interface IrExpression : IrStatement, IrVarargElement { } interface IrExpressionWithCopy : IrExpression { - fun copy(): IrExpression + fun copy(): IrExpressionWithCopy }