[JS IR] Correct pureness of expressions for arrayLiteral

This commit is contained in:
Ilya Goncharov
2021-03-09 15:23:08 +03:00
parent f890156dde
commit 47d050c420
3 changed files with 30 additions and 27 deletions
@@ -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<Ir
}
fun IrFactory.createStaticFunctionWithReceivers(
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<IrTypeParameter> = 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<IrTypeParameter> = 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
@@ -525,7 +525,6 @@ class FunctionInlining(
val arguments = buildParameterToArgument(callSite, callee)
val evaluationStatements = mutableListOf<IrStatement>()
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)
@@ -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