[JS IR] arrayConcat not use additional slice
This commit is contained in:
+37
-24
@@ -152,30 +152,11 @@ private class VarargTransformer(
|
|||||||
// vararg with a single segment => no need to concatenate
|
// vararg with a single segment => no need to concatenate
|
||||||
if (segments.size == 1) {
|
if (segments.size == 1) {
|
||||||
val segment = segments.first()
|
val segment = segments.first()
|
||||||
if (expression in externalVarargs) {
|
val argument = getArgumentFromSingleSegment(
|
||||||
externalVarargs.remove(expression)
|
expression,
|
||||||
return segment
|
segment,
|
||||||
}
|
arrayInfo
|
||||||
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
|
|
||||||
|
|
||||||
return arrayInfo.boxArrayIfNeeded(argument)
|
return arrayInfo.boxArrayIfNeeded(argument)
|
||||||
}
|
}
|
||||||
@@ -206,6 +187,38 @@ private class VarargTransformer(
|
|||||||
return arrayInfo.boxArrayIfNeeded(res)
|
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 {
|
private fun transformFunctionAccessExpression(expression: IrFunctionAccessExpression): IrExpression {
|
||||||
if (expression.symbol.owner.isExternal) {
|
if (expression.symbol.owner.isExternal) {
|
||||||
for (i in 0 until expression.valueArgumentsCount) {
|
for (i in 0 until expression.valueArgumentsCount) {
|
||||||
|
|||||||
+2
@@ -170,6 +170,8 @@ class IrElementToJsExpressionTransformer : BaseIrElementToJsNodeTransformer<JsEx
|
|||||||
JsNew(refForExternalClass, arguments)
|
JsNew(refForExternalClass, arguments)
|
||||||
} else {
|
} else {
|
||||||
val argumentsAsSingleArray = argumentsWithVarargAsSingleArray(
|
val argumentsAsSingleArray = argumentsWithVarargAsSingleArray(
|
||||||
|
expression,
|
||||||
|
context,
|
||||||
JsNullLiteral(),
|
JsNullLiteral(),
|
||||||
arguments,
|
arguments,
|
||||||
varargParameterIndex
|
varargParameterIndex
|
||||||
|
|||||||
+10
-1
@@ -156,6 +156,8 @@ fun translateCall(
|
|||||||
// TODO: Don't use `Function.prototype.apply` when number of arguments is known at compile time (e.g. there are no spread operators)
|
// TODO: Don't use `Function.prototype.apply` when number of arguments is known at compile time (e.g. there are no spread operators)
|
||||||
|
|
||||||
val argumentsAsSingleArray = argumentsWithVarargAsSingleArray(
|
val argumentsAsSingleArray = argumentsWithVarargAsSingleArray(
|
||||||
|
expression,
|
||||||
|
context,
|
||||||
jsExtensionReceiver,
|
jsExtensionReceiver,
|
||||||
arguments,
|
arguments,
|
||||||
varargParameterIndex
|
varargParameterIndex
|
||||||
@@ -223,6 +225,8 @@ fun translateCall(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun argumentsWithVarargAsSingleArray(
|
fun argumentsWithVarargAsSingleArray(
|
||||||
|
expression: IrFunctionAccessExpression,
|
||||||
|
context: JsGenerationContext,
|
||||||
additionalReceiver: JsExpression?,
|
additionalReceiver: JsExpression?,
|
||||||
arguments: List<JsExpression>,
|
arguments: List<JsExpression>,
|
||||||
varargParameterIndex: Int,
|
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
|
// Call `Array.prototype.slice` on vararg arguments in order to convert array-like objects into proper arrays
|
||||||
varargParameterIndex -> {
|
varargParameterIndex -> {
|
||||||
|
val valueArgument = expression.getValueArgument(varargParameterIndex)
|
||||||
|
|
||||||
if (arraysForConcat.isNotEmpty()) {
|
if (arraysForConcat.isNotEmpty()) {
|
||||||
concatElements.add(JsArrayLiteral(arraysForConcat))
|
concatElements.add(JsArrayLiteral(arraysForConcat))
|
||||||
}
|
}
|
||||||
@@ -250,7 +256,10 @@ fun argumentsWithVarargAsSingleArray(
|
|||||||
is JsArrayLiteral -> argument
|
is JsArrayLiteral -> argument
|
||||||
is JsNew -> argument.arguments.firstOrNull() as? JsArrayLiteral
|
is JsNew -> argument.arguments.firstOrNull() as? JsArrayLiteral
|
||||||
else -> null
|
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)
|
concatElements.add(varargArgument)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user