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 5481ba71352..62a49146aa5 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 @@ -152,30 +152,11 @@ 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 = - if (elementType.isChar() || elementType.isBoolean() || elementType.isLong()) - context.intrinsics.taggedArrayCopy - else - context.intrinsics.jsArraySlice - - IrCallImpl( - expression.startOffset, - expression.endOffset, - arrayInfo.primitiveArrayType, - copyFunction, - typeArgumentsCount = 1, - valueArgumentsCount = 1 - ).apply { - putTypeArgument(0, arrayInfo.primitiveArrayType) - putValueArgument(0, segment) - } - } else segment + val argument = getArgumentFromSingleSegment( + expression, + segment, + arrayInfo + ) return arrayInfo.boxArrayIfNeeded(argument) } @@ -206,6 +187,38 @@ private class VarargTransformer( return arrayInfo.boxArrayIfNeeded(res) } + private fun getArgumentFromSingleSegment( + expression: IrVararg, + segment: IrExpression, + arrayInfo: InlineClassArrayInfo + ): IrExpression { + if (expression in externalVarargs) { + externalVarargs.remove(expression) + return segment + } + + return if (expression.elements.any { it is IrSpreadElement }) { + val elementType = arrayInfo.primitiveElementType + val copyFunction = + if (elementType.isChar() || elementType.isBoolean() || elementType.isLong()) + context.intrinsics.taggedArrayCopy + else + context.intrinsics.jsArraySlice + + IrCallImpl( + expression.startOffset, + expression.endOffset, + arrayInfo.primitiveArrayType, + copyFunction, + typeArgumentsCount = 1, + valueArgumentsCount = 1 + ).apply { + putTypeArgument(0, arrayInfo.primitiveArrayType) + putValueArgument(0, segment) + } + } else segment + } + private fun transformFunctionAccessExpression(expression: IrFunctionAccessExpression): IrExpression { if (expression.symbol.owner.isExternal) { for (i in 0 until expression.valueArgumentsCount) { diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrElementToJsExpressionTransformer.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrElementToJsExpressionTransformer.kt index 9020c2c2138..23b11138606 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrElementToJsExpressionTransformer.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrElementToJsExpressionTransformer.kt @@ -170,6 +170,8 @@ class IrElementToJsExpressionTransformer : BaseIrElementToJsNodeTransformer, varargParameterIndex: Int, @@ -241,6 +245,8 @@ fun argumentsWithVarargAsSingleArray( // Call `Array.prototype.slice` on vararg arguments in order to convert array-like objects into proper arrays varargParameterIndex -> { + val valueArgument = expression.getValueArgument(varargParameterIndex) + if (arraysForConcat.isNotEmpty()) { concatElements.add(JsArrayLiteral(arraysForConcat)) } @@ -250,7 +256,10 @@ fun argumentsWithVarargAsSingleArray( is JsArrayLiteral -> argument is JsNew -> argument.arguments.firstOrNull() as? JsArrayLiteral else -> null - } ?: JsInvocation(JsNameRef("call", JsNameRef("slice", JsArrayLiteral())), argument) + } ?: if (valueArgument is IrCall && valueArgument.symbol == context.staticContext.backendContext.intrinsics.arrayConcat) + argument + else + JsInvocation(JsNameRef("call", JsNameRef("slice", JsArrayLiteral())), argument) concatElements.add(varargArgument) }