From fabd3064370b5c64f4b9e7759ff660411102baac Mon Sep 17 00:00:00 2001 From: Roman Artemev Date: Tue, 14 May 2019 18:07:43 +0300 Subject: [PATCH] [JS IR BE] Fix varargs for inline arrays --- .../kotlin/ir/backend/js/JsIntrinsics.kt | 25 ++++++++++++++++++- .../ir/backend/js/lower/VarargLowering.kt | 21 +++++++--------- .../unsignedTypes/varargsOfUnsignedTypes.kt | 1 - .../box/expression/function/varargUInt.kt | 1 - 4 files changed, 33 insertions(+), 15 deletions(-) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIntrinsics.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIntrinsics.kt index b708e35d81e..d2f080d8eb1 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIntrinsics.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIntrinsics.kt @@ -14,6 +14,8 @@ import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction import org.jetbrains.kotlin.ir.declarations.impl.IrExternalPackageFragmentImpl import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.symbols.impl.IrExternalPackageFragmentSymbolImpl +import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeBuilder +import org.jetbrains.kotlin.ir.types.impl.buildSimpleType import org.jetbrains.kotlin.ir.types.isLong import org.jetbrains.kotlin.ir.util.constructors import org.jetbrains.kotlin.ir.util.findDeclaration @@ -244,7 +246,7 @@ class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendC val primitiveArrayConcat = getInternalWithoutPackage("primitiveArrayConcat") - val jsArraySlice = unOp("slice") + val jsArraySlice = defineJsSliceIntrinsic().symbol val jsBind = defineJsBindIntrinsic() @@ -322,6 +324,27 @@ class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendC externalPackageFragment.declarations += it } + private fun defineJsSliceIntrinsic(): IrSimpleFunction { + val typeParameter = JsIrBuilder.buildTypeParameter(Name.identifier("A"), 0, true).apply { + superTypes += irBuiltIns.anyType + } + val type = IrSimpleTypeBuilder().run { + classifier = typeParameter.symbol + buildSimpleType() + } + + return JsIrBuilder.buildFunction( + "slice", + returnType = type, + parent = externalPackageFragment, + origin = JsLoweredDeclarationOrigin.JS_INTRINSICS_STUB + ).also { + it.typeParameters += typeParameter.also { t -> t.parent = it } + it.valueParameters += JsIrBuilder.buildValueParameter("a", 0, type).also { v -> v.parent = it } + externalPackageFragment.declarations += it + } + } + private fun defineSetJSPropertyIntrinsic() = JsIrBuilder.buildFunction( "\$setJSProperty\$", 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 c62c229001c..b61523887a9 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 @@ -58,7 +58,7 @@ private class VarargTransformer( fun IrExpression.unboxInlineClassIfNeeded(): IrExpression { val inlinedClass = type.getInlinedClass() ?: return this val field = getInlineClassBackingField(inlinedClass) - return IrGetFieldImpl(startOffset, endOffset, field.symbol, inlinedClass.defaultType, this) + return IrGetFieldImpl(startOffset, endOffset, field.symbol, field.type, this) } fun IrExpression.boxInlineClassIfNeeded(inlineClass: IrClass?) = @@ -121,28 +121,25 @@ private class VarargTransformer( // vararg with a single segment => no need to concatenate if (segments.size == 1) { - return if (expression.elements.any { it is IrSpreadElement }) { - // Single spread operator => need to copy the array + val segment = segments.first() + val argument = if (expression.elements.any { it is IrSpreadElement }) { IrCallImpl( expression.startOffset, expression.endOffset, expression.type, context.intrinsics.jsArraySlice ).apply { - putValueArgument(0, segments.first()) + putTypeArgument(0, expression.type) + putValueArgument(0, segment) } - } else { - val res = segments.first() - return if (needUnboxing) - res.boxInlineClassIfNeeded(arrayInlineClass!!) - else - res - } + } else segment + + return if (needUnboxing) argument.boxInlineClassIfNeeded(arrayInlineClass!!) else argument } val arrayLiteral = segments.toArrayLiteral( - IrSimpleTypeImpl(context.intrinsics.array, false, emptyList(), emptyList()), + IrSimpleTypeImpl(context.intrinsics.array, false, emptyList(), emptyList()), // TODO: Substitution context.irBuiltIns.anyType ) diff --git a/compiler/testData/codegen/box/unsignedTypes/varargsOfUnsignedTypes.kt b/compiler/testData/codegen/box/unsignedTypes/varargsOfUnsignedTypes.kt index 9fb01db42bf..8d31eece2e8 100644 --- a/compiler/testData/codegen/box/unsignedTypes/varargsOfUnsignedTypes.kt +++ b/compiler/testData/codegen/box/unsignedTypes/varargsOfUnsignedTypes.kt @@ -1,7 +1,6 @@ // IGNORE_BACKEND: JVM_IR // WITH_RUNTIME // KJS_WITH_FULL_RUNTIME -// IGNORE_BACKEND: JS_IR fun uint(vararg us: UInt): UIntArray = us diff --git a/js/js.translator/testData/box/expression/function/varargUInt.kt b/js/js.translator/testData/box/expression/function/varargUInt.kt index 3e84ccc6f4e..67d9828c8db 100644 --- a/js/js.translator/testData/box/expression/function/varargUInt.kt +++ b/js/js.translator/testData/box/expression/function/varargUInt.kt @@ -1,5 +1,4 @@ // LANGUAGE_VERSION: 1.3 -// IGNORE_BACKEND: JS_IR // KJS_WITH_FULL_RUNTIME // EXPECTED_REACHABLE_NODES: 1566 package foo