From 47d050c420487cdd9d3c35e4c65706ff1c74721e Mon Sep 17 00:00:00 2001 From: Ilya Goncharov Date: Tue, 9 Mar 2021 15:23:08 +0300 Subject: [PATCH] [JS IR] Correct pureness of expressions for arrayLiteral --- .../kotlin/backend/common/ir/IrUtils.kt | 49 ++++++++++--------- .../common/lower/inline/FunctionInlining.kt | 5 +- .../ir/backend/js/JsIrBackendContext.kt | 3 +- 3 files changed, 30 insertions(+), 27 deletions(-) diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/IrUtils.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/IrUtils.kt index c3348ff020a..3baabba0989 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/IrUtils.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/IrUtils.kt @@ -200,8 +200,8 @@ fun IrTypeParametersContainer.copyTypeParameters( // Therefore, we first copy the parameters themselves, then set up their supertypes. val newTypeParameters = srcTypeParameters.mapIndexed { i, sourceParameter -> sourceParameter.copyToWithoutSuperTypes(this, index = i + shift, origin = origin ?: sourceParameter.origin).also { - oldToNewParameterMap[sourceParameter] = it - } + oldToNewParameterMap[sourceParameter] = it + } } typeParameters += newTypeParameters srcTypeParameters.zip(newTypeParameters).forEach { (srcParameter, dstParameter) -> @@ -323,8 +323,7 @@ fun IrType.remapTypeParameters( when { classifier is IrTypeParameter -> { val newClassifier = - srcToDstParameterMap?.get(classifier) ?: - if (classifier.parent == source) + srcToDstParameterMap?.get(classifier) ?: if (classifier.parent == source) target.typeParameters[classifier.index] else classifier @@ -485,16 +484,16 @@ fun IrClass.addFakeOverrides(irBuiltIns: IrBuiltIns, implementedMembers: List = listOf() + irParent: IrDeclarationParent, + name: Name, + oldFunction: IrFunction, + dispatchReceiverType: IrType? = oldFunction.dispatchReceiverParameter?.type, + origin: IrDeclarationOrigin = oldFunction.origin, + modality: Modality = Modality.FINAL, + visibility: DescriptorVisibility = oldFunction.visibility, + isFakeOverride: Boolean = oldFunction.isFakeOverride, + copyMetadata: Boolean = true, + typeParametersFromContext: List = listOf() ): IrSimpleFunction { return createFunction( oldFunction.startOffset, oldFunction.endOffset, @@ -548,13 +547,13 @@ fun IrFactory.createStaticFunctionWithReceivers( remapTypeMap = typeParameterMap ) valueParameters = listOfNotNull(dispatchReceiver, extensionReceiver) + - oldFunction.valueParameters.map { - it.copyTo( - this, - index = it.index + offset, - remapTypeMap = typeParameterMap - ) - } + oldFunction.valueParameters.map { + it.copyTo( + this, + index = it.index + offset, + remapTypeMap = typeParameterMap + ) + } if (copyMetadata) metadata = oldFunction.metadata @@ -662,7 +661,13 @@ fun IrExpression?.isPure( if (valueDeclaration is IrVariable) !valueDeclaration.isVar else true } - is IrCall -> context?.isSideEffectFree(this) ?: false + is IrCall -> if (context?.isSideEffectFree(this) == true) { + for (i in 0 until valueArgumentsCount) { + val valueArgument = getValueArgument(i) + if (!valueArgument.isPure(anyVariable, checkFields, context)) return false + } + true + } else false is IrGetObjectValue -> type.isUnit() is IrVararg -> elements.all { (it as? IrExpression)?.isPure(anyVariable, checkFields, context) == true } else -> false diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/inline/FunctionInlining.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/inline/FunctionInlining.kt index a4290f8d416..19608239f3d 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/inline/FunctionInlining.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/inline/FunctionInlining.kt @@ -525,7 +525,6 @@ class FunctionInlining( val arguments = buildParameterToArgument(callSite, callee) val evaluationStatements = mutableListOf() val substitutor = ParameterSubstitutor() - var argumentExtracted = false arguments.forEach { argument -> /* * We need to create temporary variable for each argument except inlinable lambda arguments. @@ -533,14 +532,12 @@ class FunctionInlining( * not only for those referring to inlinable lambdas. */ if (argument.isInlinableLambdaArgument) { - argumentExtracted = true substituteMap[argument.parameter] = argument.argumentExpression (argument.argumentExpression as? IrFunctionReference)?.let { evaluationStatements += evaluateArguments(it) } return@forEach } if (argument.isImmutableVariableLoad) { - argumentExtracted = true substituteMap[argument.parameter] = argument.argumentExpression.transform( // Arguments may reference the previous ones - substitute them. substitutor, @@ -549,7 +546,7 @@ class FunctionInlining( return@forEach } - argumentExtracted = argumentExtracted || !argument.argumentExpression.isPure(false) + val argumentExtracted = !argument.argumentExpression.isPure(false) // Arguments may reference the previous ones - substitute them. val variableInitializer = argument.argumentExpression.transform(substitutor, data = null) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIrBackendContext.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIrBackendContext.kt index 82526557d9d..e71a172659f 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIrBackendContext.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIrBackendContext.kt @@ -60,7 +60,8 @@ class JsIrBackendContext( override var inVerbosePhase: Boolean = false override fun isSideEffectFree(call: IrCall): Boolean = - call.symbol in intrinsics.primitiveToLiteralConstructor.values + call.symbol in intrinsics.primitiveToLiteralConstructor.values || + call.symbol == intrinsics.arrayLiteral val devMode = configuration[JSConfigurationKeys.DEVELOPER_MODE] ?: false val errorPolicy = configuration[JSConfigurationKeys.ERROR_TOLERANCE_POLICY] ?: ErrorTolerancePolicy.DEFAULT