From b8d5712bc03bdd1832f44d7a39fb165a2a95abb2 Mon Sep 17 00:00:00 2001 From: Ilya Goncharov Date: Thu, 4 Mar 2021 16:04:32 +0300 Subject: [PATCH] [JS IR] Not use double slice for external varargs --- .../ir/backend/js/lower/VarargLowering.kt | 27 ++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/VarargLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/VarargLowering.kt index c93d8d1e00e..5481ba71352 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/VarargLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/VarargLowering.kt @@ -16,7 +16,10 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrGetFieldImpl import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl -import org.jetbrains.kotlin.ir.util.* +import org.jetbrains.kotlin.ir.util.constructors +import org.jetbrains.kotlin.ir.util.defaultType +import org.jetbrains.kotlin.ir.util.getInlineClassBackingField +import org.jetbrains.kotlin.ir.util.getInlineClassUnderlyingType import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid @@ -26,12 +29,15 @@ class VarargLowering(val context: JsIrBackendContext) : BodyLoweringPass { irBody.transformChildrenVoid(VarargTransformer(context)) } } + private class VarargTransformer( val context: JsIrBackendContext ) : IrElementTransformerVoid() { fun IrType.getInlinedClass() = context.inlineClassesUtils.getInlinedClass(this) + var externalVarargs = mutableSetOf() + private fun List.toArrayLiteral(type: IrType, varargElementType: IrType): IrExpression { // TODO: Use symbols when builtins symbol table is fixes @@ -138,7 +144,7 @@ private class VarargTransformer( // empty vararg => empty array literal if (segments.isEmpty()) { - with (arrayInfo) { + with(arrayInfo) { return boxArrayIfNeeded(toPrimitiveArrayLiteral(emptyList())) } } @@ -146,6 +152,10 @@ private class VarargTransformer( // vararg with a single segment => no need to concatenate if (segments.size == 1) { val segment = segments.first() + if (expression in externalVarargs) { + externalVarargs.remove(expression) + return segment + } val argument = if (expression.elements.any { it is IrSpreadElement }) { val elementType = arrayInfo.primitiveElementType val copyFunction = @@ -197,6 +207,17 @@ private class VarargTransformer( } private fun transformFunctionAccessExpression(expression: IrFunctionAccessExpression): IrExpression { + if (expression.symbol.owner.isExternal) { + for (i in 0 until expression.valueArgumentsCount) { + val parameter = expression.symbol.owner.valueParameters[i] + val varargElementType = parameter.varargElementType + if (varargElementType != null) { + (expression.getValueArgument(i) as IrVararg?)?.let { + externalVarargs.add(it) + } + } + } + } expression.transformChildrenVoid() val size = expression.valueArgumentsCount @@ -206,7 +227,7 @@ private class VarargTransformer( val varargElementType = parameter.varargElementType if (argument == null && varargElementType != null) { val arrayInfo = InlineClassArrayInfo(varargElementType, parameter.type) - val emptyArray = with (arrayInfo) { + val emptyArray = with(arrayInfo) { boxArrayIfNeeded(toPrimitiveArrayLiteral(emptyList())) }