WASM: Implement spread operator
This commit is contained in:
committed by
teamcityserver
parent
f5e59194b5
commit
d835b3c164
Generated
+7
@@ -0,0 +1,7 @@
|
|||||||
|
<component name="ProjectDictionaryState">
|
||||||
|
<dictionary name="igor">
|
||||||
|
<words>
|
||||||
|
<w>descr</w>
|
||||||
|
</words>
|
||||||
|
</dictionary>
|
||||||
|
</component>
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.backend.wasm
|
package org.jetbrains.kotlin.backend.wasm
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.ir.Symbols
|
import org.jetbrains.kotlin.backend.common.ir.Symbols
|
||||||
|
import org.jetbrains.kotlin.builtins.StandardNames
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.PackageViewDescriptor
|
import org.jetbrains.kotlin.descriptors.PackageViewDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||||
@@ -29,6 +30,8 @@ class WasmSymbols(
|
|||||||
|
|
||||||
private val wasmInternalPackage: PackageViewDescriptor =
|
private val wasmInternalPackage: PackageViewDescriptor =
|
||||||
context.module.getPackage(FqName("kotlin.wasm.internal"))
|
context.module.getPackage(FqName("kotlin.wasm.internal"))
|
||||||
|
private val collectionsPackage: PackageViewDescriptor =
|
||||||
|
context.module.getPackage(StandardNames.COLLECTIONS_PACKAGE_FQ_NAME)
|
||||||
|
|
||||||
override val throwNullPointerException = getInternalFunction("THROW_NPE")
|
override val throwNullPointerException = getInternalFunction("THROW_NPE")
|
||||||
override val throwISE = getInternalFunction("THROW_ISE")
|
override val throwISE = getInternalFunction("THROW_ISE")
|
||||||
@@ -152,6 +155,9 @@ class WasmSymbols(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val arraysCopyInto = findFunctions(collectionsPackage.memberScope, Name.identifier("copyInto"))
|
||||||
|
.map { symbolTable.referenceSimpleFunction(it) }
|
||||||
|
|
||||||
override fun functionN(n: Int): IrClassSymbol =
|
override fun functionN(n: Int): IrClassSymbol =
|
||||||
functionNInterfaces[n]
|
functionNInterfaces[n]
|
||||||
|
|
||||||
|
|||||||
+195
-37
@@ -7,23 +7,20 @@ package org.jetbrains.kotlin.backend.wasm.lower
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||||
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
|
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
|
||||||
|
import org.jetbrains.kotlin.backend.common.ir.ir2string
|
||||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||||
import org.jetbrains.kotlin.backend.common.lower.irComposite
|
import org.jetbrains.kotlin.backend.common.lower.irComposite
|
||||||
import org.jetbrains.kotlin.backend.wasm.WasmBackendContext
|
import org.jetbrains.kotlin.backend.wasm.WasmBackendContext
|
||||||
import org.jetbrains.kotlin.ir.builders.irCall
|
import org.jetbrains.kotlin.ir.builders.*
|
||||||
import org.jetbrains.kotlin.ir.builders.irGet
|
|
||||||
import org.jetbrains.kotlin.ir.builders.irInt
|
|
||||||
import org.jetbrains.kotlin.ir.builders.irTemporary
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrVararg
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrVarargElement
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
import org.jetbrains.kotlin.ir.types.classOrNull
|
|
||||||
import org.jetbrains.kotlin.ir.util.primaryConstructor
|
|
||||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
|
import java.lang.IllegalArgumentException
|
||||||
|
|
||||||
internal class WasmVarargExpressionLowering(
|
internal class WasmVarargExpressionLowering(
|
||||||
private val context: WasmBackendContext
|
private val context: WasmBackendContext
|
||||||
@@ -34,36 +31,183 @@ internal class WasmVarargExpressionLowering(
|
|||||||
irFile.transformChildrenVoid(this)
|
irFile.transformChildrenVoid(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitVararg(expression: IrVararg): IrExpression {
|
// Helper which wraps an array class and allows to access it's commonly used methods.
|
||||||
val irVararg = super.visitVararg(expression) as IrVararg
|
private class ArrayDescr(val arrayType: IrType, val context: WasmBackendContext) {
|
||||||
val builder = context.createIrBuilder(currentScope!!.scope.scopeOwnerSymbol)
|
val arrayClass =
|
||||||
val arrayClass = irVararg.type.classOrNull!!.owner
|
arrayType.getClass() ?: throw IllegalArgumentException("Argument ${arrayType.render()} must have a class")
|
||||||
val primaryConstructor = arrayClass.primaryConstructor!!
|
|
||||||
val setMethod = arrayClass.declarations.filterIsInstance<IrSimpleFunction>().find {
|
init {
|
||||||
it.name == Name.identifier("set")
|
check(arrayClass.symbol in context.wasmSymbols.arrays) { "Argument ${ir2string(arrayClass)} must be an array" }
|
||||||
}!!
|
}
|
||||||
return builder.irComposite(irVararg) {
|
|
||||||
val arrayTempVariable = irTemporary(
|
val primaryConstructor
|
||||||
value = irCall(primaryConstructor).apply {
|
get() = arrayClass.primaryConstructor!!
|
||||||
putValueArgument(0, irInt(irVararg.elements.size))
|
|
||||||
if (primaryConstructor.typeParameters.isNotEmpty()) {
|
val setMethod
|
||||||
check(primaryConstructor.typeParameters.size == 1)
|
get() = arrayClass.getSimpleFunction("set")!!.owner
|
||||||
putTypeArgument(0, irVararg.varargElementType)
|
val getMethod
|
||||||
}
|
get() = arrayClass.getSimpleFunction("get")!!.owner
|
||||||
},
|
val sizeMethod
|
||||||
nameHint = "array_tmp"
|
get() = arrayClass.getPropertyGetter("size")!!.owner
|
||||||
)
|
val elementType: IrType
|
||||||
for ((index: Int, element: IrVarargElement) in irVararg.elements.withIndex()) {
|
get() {
|
||||||
check(element is IrExpression) {
|
if (arrayType.isBoxedArray)
|
||||||
"TODO: Support $element as vararg elements"
|
return arrayType.getArrayElementType(context.irBuiltIns)
|
||||||
|
// getArrayElementType doesn't work on unsigned arrays, use workaround instead
|
||||||
|
return getMethod.returnType
|
||||||
|
}
|
||||||
|
|
||||||
|
val copyInto: IrSimpleFunction
|
||||||
|
get() {
|
||||||
|
val func = context.wasmSymbols.arraysCopyInto.find {
|
||||||
|
it.owner.extensionReceiverParameter?.type?.classOrNull?.owner == arrayClass
|
||||||
}
|
}
|
||||||
|
|
||||||
+irCall(setMethod).apply {
|
return func?.owner ?: throw IllegalArgumentException("copyInto is not found for ${arrayType.render()}")
|
||||||
dispatchReceiver = irGet(arrayTempVariable)
|
}
|
||||||
putValueArgument(0, irInt(index))
|
}
|
||||||
putValueArgument(1, element)
|
|
||||||
|
private fun IrBlockBuilder.irCreateArray(size: IrExpression, arrDescr: ArrayDescr) =
|
||||||
|
irCall(arrDescr.primaryConstructor).apply {
|
||||||
|
putValueArgument(0, size)
|
||||||
|
if (typeArgumentsCount >= 1) {
|
||||||
|
check(typeArgumentsCount == 1 && arrDescr.arrayClass.typeParameters.size == 1)
|
||||||
|
putTypeArgument(0, arrDescr.elementType)
|
||||||
|
}
|
||||||
|
type = arrDescr.arrayType
|
||||||
|
}
|
||||||
|
|
||||||
|
// Represents single contiguous sequence of vararg arguments. It can generate IR for various operations on this
|
||||||
|
// segments. It's used to handle spreads and normal vararg arguments in a uniform manner.
|
||||||
|
private sealed class VarargSegmentBuilder(val wasmContext: WasmBackendContext) {
|
||||||
|
// Returns an expression which calculates size of this spread.
|
||||||
|
abstract fun IrBlockBuilder.irSize(): IrExpression
|
||||||
|
|
||||||
|
// Adds code into the current block which copies this spread into destArr. Returns nothing.
|
||||||
|
// If indexVar is present uses it as a start index in the destination array.
|
||||||
|
abstract fun IrBlockBuilder.irCopyInto(destArr: IrVariable, indexVar: IrVariable?)
|
||||||
|
|
||||||
|
class Plain(val exprs: List<IrVariable>, wasmContext: WasmBackendContext) :
|
||||||
|
VarargSegmentBuilder(wasmContext) {
|
||||||
|
|
||||||
|
override fun IrBlockBuilder.irSize() = irInt(exprs.size)
|
||||||
|
|
||||||
|
override fun IrBlockBuilder.irCopyInto(destArr: IrVariable, indexVar: IrVariable?) {
|
||||||
|
val destArrDescr = ArrayDescr(destArr.type, wasmContext)
|
||||||
|
|
||||||
|
// An infinite sequence of natural numbers possibly shifted by the indexVar when it's available
|
||||||
|
val indexes = generateSequence(0) { it + 1 }
|
||||||
|
.map { irInt(it) }
|
||||||
|
.let { seq ->
|
||||||
|
if (indexVar != null) seq.map { irIntPlus(irGet(indexVar), it, wasmContext) }
|
||||||
|
else seq
|
||||||
|
}
|
||||||
|
|
||||||
|
for ((element, index) in exprs.asSequence().zip(indexes)) {
|
||||||
|
+irCall(destArrDescr.setMethod).apply {
|
||||||
|
dispatchReceiver = irGet(destArr)
|
||||||
|
putValueArgument(0, index)
|
||||||
|
putValueArgument(1, irGet(element))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Spread(val exprVar: IrVariable, wasmContext: WasmBackendContext) :
|
||||||
|
VarargSegmentBuilder(wasmContext) {
|
||||||
|
|
||||||
|
val srcArrDescr = ArrayDescr(exprVar.type, wasmContext) // will check that exprVar is an array
|
||||||
|
|
||||||
|
override fun IrBlockBuilder.irSize(): IrExpression =
|
||||||
|
irCall(srcArrDescr.sizeMethod).apply {
|
||||||
|
dispatchReceiver = irGet(exprVar)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun IrBlockBuilder.irCopyInto(destArr: IrVariable, indexVar: IrVariable?) {
|
||||||
|
assert(srcArrDescr.arrayClass == destArr.type.getClass()) { "type checker failure?" }
|
||||||
|
|
||||||
|
val destIdx = indexVar?.let { irGet(it) } ?: irInt(0)
|
||||||
|
|
||||||
|
+irCall(srcArrDescr.copyInto).apply {
|
||||||
|
if (typeArgumentsCount >= 1) {
|
||||||
|
check(typeArgumentsCount == 1 && srcArrDescr.arrayClass.typeParameters.size == 1)
|
||||||
|
putTypeArgument(0, srcArrDescr.elementType)
|
||||||
|
}
|
||||||
|
extensionReceiver = irGet(exprVar) // source
|
||||||
|
putValueArgument(0, irGet(destArr)) // destination
|
||||||
|
putValueArgument(1, destIdx) // destinationOffset
|
||||||
|
putValueArgument(2, irInt(0)) // startIndex
|
||||||
|
putValueArgument(3, irSize()) // endIndex
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is needed to setup proper extension and dispatch receivers for the VarargSegmentBuilder.
|
||||||
|
private fun IrBlockBuilder.irCopyInto(destArr: IrVariable, indexVar: IrVariable?, segment: VarargSegmentBuilder) =
|
||||||
|
with(segment) {
|
||||||
|
this@irCopyInto.irCopyInto(destArr, indexVar)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun IrBlockBuilder.irSize(segment: VarargSegmentBuilder) =
|
||||||
|
with(segment) {
|
||||||
|
this@irSize.irSize()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitVararg(expression: IrVararg): IrExpression {
|
||||||
|
val irVararg = super.visitVararg(expression) as IrVararg
|
||||||
|
|
||||||
|
// Create temporary variable for each element and emit them all at once to preserve
|
||||||
|
// argument evaluation order as per kotlin language spec.
|
||||||
|
val elementVars = irVararg.elements
|
||||||
|
.map {
|
||||||
|
val exp = if (it is IrSpreadElement) it.expression else (it as IrExpression)
|
||||||
|
currentScope!!.scope.createTemporaryVariable(exp, "vararg_temp")
|
||||||
|
}
|
||||||
|
|
||||||
|
val segments: List<VarargSegmentBuilder> = sequence {
|
||||||
|
val currentElements = mutableListOf<IrVariable>()
|
||||||
|
|
||||||
|
for ((el, tempVar) in irVararg.elements.zip(elementVars)) {
|
||||||
|
when (el) {
|
||||||
|
is IrExpression -> currentElements.add(tempVar)
|
||||||
|
is IrSpreadElement -> {
|
||||||
|
if (currentElements.isNotEmpty()) {
|
||||||
|
yield(VarargSegmentBuilder.Plain(currentElements.toList(), context))
|
||||||
|
currentElements.clear()
|
||||||
|
}
|
||||||
|
yield(VarargSegmentBuilder.Spread(tempVar, context))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (currentElements.isNotEmpty())
|
||||||
|
yield(VarargSegmentBuilder.Plain(currentElements.toList(), context))
|
||||||
|
}.toList()
|
||||||
|
|
||||||
|
val builder = context.createIrBuilder(currentScope!!.scope.scopeOwnerSymbol)
|
||||||
|
val destArrayDescr = ArrayDescr(irVararg.type, context)
|
||||||
|
|
||||||
|
return builder.irComposite(irVararg) {
|
||||||
|
// Emit all of the variables first so that all vararg expressions
|
||||||
|
// are evaluated only once and in order of their appearance.
|
||||||
|
elementVars.forEach { +it }
|
||||||
|
|
||||||
|
val arrayLength = segments
|
||||||
|
.map { irSize(it) }
|
||||||
|
.reduceOrNull { acc, exp -> irIntPlus(acc, exp) }
|
||||||
|
?: irInt(0)
|
||||||
|
val arrayTempVariable = irTemporary(
|
||||||
|
value = irCreateArray(arrayLength, destArrayDescr),
|
||||||
|
nameHint = "vararg_array")
|
||||||
|
val indexVar = if (segments.size >= 2) irTemporary(irInt(0), "vararg_idx") else null
|
||||||
|
|
||||||
|
segments.forEach {
|
||||||
|
irCopyInto(arrayTempVariable, indexVar, it)
|
||||||
|
|
||||||
|
if (indexVar != null)
|
||||||
|
+irSet(indexVar, irIntPlus(irGet(indexVar), irSize(it)))
|
||||||
|
}
|
||||||
|
|
||||||
+irGet(arrayTempVariable)
|
+irGet(arrayTempVariable)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -97,4 +241,18 @@ internal class WasmVarargExpressionLowering(
|
|||||||
}
|
}
|
||||||
return expression
|
return expression
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun IrBlockBuilder.irIntPlus(rhs: IrExpression, lhs: IrExpression): IrExpression =
|
||||||
|
irIntPlus(rhs, lhs, this@WasmVarargExpressionLowering.context)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun IrBlockBuilder.irIntPlus(rhs: IrExpression, lhs: IrExpression, wasmContext: WasmBackendContext): IrExpression {
|
||||||
|
val plusOp = wasmContext.wasmSymbols.getBinaryOperator(
|
||||||
|
OperatorNameConventions.PLUS, context.irBuiltIns.intType, context.irBuiltIns.intType
|
||||||
|
).owner
|
||||||
|
|
||||||
|
return irCall(plusOp).apply {
|
||||||
|
dispatchReceiver = rhs
|
||||||
|
putValueArgument(0, lhs)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -135,6 +135,9 @@ fun IrBuilderWithScope.irGet(variable: IrValueDeclaration) = irGet(variable.type
|
|||||||
fun IrBuilderWithScope.irSet(variable: IrValueSymbol, value: IrExpression, origin: IrStatementOrigin = IrStatementOrigin.EQ) =
|
fun IrBuilderWithScope.irSet(variable: IrValueSymbol, value: IrExpression, origin: IrStatementOrigin = IrStatementOrigin.EQ) =
|
||||||
IrSetValueImpl(startOffset, endOffset, context.irBuiltIns.unitType, variable, value, origin)
|
IrSetValueImpl(startOffset, endOffset, context.irBuiltIns.unitType, variable, value, origin)
|
||||||
|
|
||||||
|
fun IrBuilderWithScope.irSet(variable: IrValueDeclaration, value: IrExpression, origin: IrStatementOrigin = IrStatementOrigin.EQ) =
|
||||||
|
irSet(variable.symbol, value, origin)
|
||||||
|
|
||||||
fun IrBuilderWithScope.irGetField(receiver: IrExpression?, field: IrField) =
|
fun IrBuilderWithScope.irGetField(receiver: IrExpression?, field: IrField) =
|
||||||
IrGetFieldImpl(startOffset, endOffset, field.symbol, field.type, receiver)
|
IrGetFieldImpl(startOffset, endOffset, field.symbol, field.type, receiver)
|
||||||
|
|
||||||
|
|||||||
@@ -233,7 +233,7 @@ private fun IrClass.getPropertyDeclaration(name: String): IrProperty? {
|
|||||||
return properties.firstOrNull()
|
return properties.firstOrNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun IrClass.getSimpleFunction(name: String): IrSimpleFunctionSymbol? =
|
fun IrClass.getSimpleFunction(name: String): IrSimpleFunctionSymbol? =
|
||||||
findDeclaration<IrSimpleFunction> { it.name.asString() == name }?.symbol
|
findDeclaration<IrSimpleFunction> { it.name.asString() == name }?.symbol
|
||||||
|
|
||||||
fun IrClass.getPropertyGetter(name: String): IrSimpleFunctionSymbol? =
|
fun IrClass.getPropertyGetter(name: String): IrSimpleFunctionSymbol? =
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
// DONT_TARGET_EXACT_BACKEND: WASM
|
// DONT_TARGET_EXACT_BACKEND: WASM
|
||||||
// WASM_MUTE_REASON: SPREAD_OPERATOR
|
// Doesn't fail on WASM backend if lambdas return Int. Need to investigate futher.
|
||||||
|
// WASM_MUTE_REASON: UNIT_ISSUES
|
||||||
// !LANGUAGE: +UseCorrectExecutionOrderForVarargArguments
|
// !LANGUAGE: +UseCorrectExecutionOrderForVarargArguments
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
// KJS_WITH_FULL_RUNTIME
|
// KJS_WITH_FULL_RUNTIME
|
||||||
|
|||||||
Vendored
-2
@@ -1,5 +1,3 @@
|
|||||||
// DONT_TARGET_EXACT_BACKEND: WASM
|
|
||||||
// WASM_MUTE_REASON: SPREAD_OPERATOR
|
|
||||||
var result = "fail"
|
var result = "fail"
|
||||||
|
|
||||||
fun foo(vararg xs: Int, s1: String = "", s2: String = "OK") {
|
fun foo(vararg xs: Int, s1: String = "", s2: String = "OK") {
|
||||||
|
|||||||
-2
@@ -1,5 +1,3 @@
|
|||||||
// DONT_TARGET_EXACT_BACKEND: WASM
|
|
||||||
// WASM_MUTE_REASON: SPREAD_OPERATOR
|
|
||||||
// !LANGUAGE: +NewInference +FunctionReferenceWithDefaultValueAsOtherType
|
// !LANGUAGE: +NewInference +FunctionReferenceWithDefaultValueAsOtherType
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
|||||||
Vendored
-2
@@ -1,5 +1,3 @@
|
|||||||
// DONT_TARGET_EXACT_BACKEND: WASM
|
|
||||||
// WASM_MUTE_REASON: SPREAD_OPERATOR
|
|
||||||
// !LANGUAGE: +NewInference
|
// !LANGUAGE: +NewInference
|
||||||
|
|
||||||
fun sum(vararg args: Int): Int {
|
fun sum(vararg args: Int): Int {
|
||||||
|
|||||||
-2
@@ -1,5 +1,3 @@
|
|||||||
// DONT_TARGET_EXACT_BACKEND: WASM
|
|
||||||
// WASM_MUTE_REASON: SPREAD_OPERATOR
|
|
||||||
// !LANGUAGE: +InlineClasses
|
// !LANGUAGE: +InlineClasses
|
||||||
|
|
||||||
inline class UInt(val value: Int)
|
inline class UInt(val value: Int)
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
// DONT_TARGET_EXACT_BACKEND: WASM
|
|
||||||
// WASM_MUTE_REASON: SPREAD_OPERATOR
|
|
||||||
// !LANGUAGE: +NewInference +MixedNamedArgumentsInTheirOwnPosition
|
// !LANGUAGE: +NewInference +MixedNamedArgumentsInTheirOwnPosition
|
||||||
|
|
||||||
fun foo1(
|
fun foo1(
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
// DONT_TARGET_EXACT_BACKEND: WASM
|
|
||||||
// WASM_MUTE_REASON: SPREAD_OPERATOR
|
|
||||||
// !LANGUAGE: +NewInference +MixedNamedArgumentsInTheirOwnPosition
|
// !LANGUAGE: +NewInference +MixedNamedArgumentsInTheirOwnPosition
|
||||||
// See KT-17691: Wrong argument order in resolved call with varargs. (fixed in JVM_IR)
|
// See KT-17691: Wrong argument order in resolved call with varargs. (fixed in JVM_IR)
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
// DONT_TARGET_EXACT_BACKEND: WASM
|
// DONT_TARGET_EXACT_BACKEND: WASM
|
||||||
// WASM_MUTE_REASON: SPREAD_OPERATOR
|
// WASM_MUTE_REASON: STDLIB_STRING_BUILDER
|
||||||
// KJS_WITH_FULL_RUNTIME
|
// KJS_WITH_FULL_RUNTIME
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
// DONT_TARGET_EXACT_BACKEND: WASM
|
|
||||||
// WASM_MUTE_REASON: SPREAD_OPERATOR
|
|
||||||
fun join(x: Array<out String>): String {
|
fun join(x: Array<out String>): String {
|
||||||
var result = ""
|
var result = ""
|
||||||
for (i in x) {
|
for (i in x) {
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
// DONT_TARGET_EXACT_BACKEND: WASM
|
|
||||||
// WASM_MUTE_REASON: SPREAD_OPERATOR
|
|
||||||
abstract class Base(val s: String, vararg ints: Int)
|
abstract class Base(val s: String, vararg ints: Int)
|
||||||
|
|
||||||
fun foo(s: String, ints: IntArray) = object : Base(ints = *ints, s = s) {}
|
fun foo(s: String, ints: IntArray) = object : Base(ints = *ints, s = s) {}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// DONT_TARGET_EXACT_BACKEND: WASM
|
// DONT_TARGET_EXACT_BACKEND: WASM
|
||||||
// WASM_MUTE_REASON: SPREAD_OPERATOR
|
// WASM_MUTE_REASON: UNSIGNED_ARRAYS
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
// KJS_WITH_FULL_RUNTIME
|
// KJS_WITH_FULL_RUNTIME
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
// DONT_TARGET_EXACT_BACKEND: WASM
|
|
||||||
// WASM_MUTE_REASON: SPREAD_OPERATOR
|
|
||||||
fun booleanVararg(vararg xs: Boolean) {
|
fun booleanVararg(vararg xs: Boolean) {
|
||||||
if (xs.size != 1 && xs[0] != true) throw AssertionError()
|
if (xs.size != 1 && xs[0] != true) throw AssertionError()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
// DONT_TARGET_EXACT_BACKEND: WASM
|
|
||||||
// WASM_MUTE_REASON: SPREAD_OPERATOR
|
|
||||||
// !LANGUAGE: +AllowAssigningArrayElementsToVarargsInNamedFormForFunctions
|
// !LANGUAGE: +AllowAssigningArrayElementsToVarargsInNamedFormForFunctions
|
||||||
|
|
||||||
fun test(vararg s: String) = s[1] + s.size
|
fun test(vararg s: String) = s[1] + s.size
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
// DONT_TARGET_EXACT_BACKEND: WASM
|
|
||||||
// WASM_MUTE_REASON: SPREAD_OPERATOR
|
|
||||||
fun barB(vararg args: Byte) = args
|
fun barB(vararg args: Byte) = args
|
||||||
fun barC(vararg args: Char) = args
|
fun barC(vararg args: Char) = args
|
||||||
fun barD(vararg args: Double) = args
|
fun barD(vararg args: Double) = args
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
// DONT_TARGET_EXACT_BACKEND: WASM
|
|
||||||
// WASM_MUTE_REASON: SPREAD_OPERATOR
|
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|
||||||
import kotlin.test.*
|
import kotlin.test.*
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
// DONT_TARGET_EXACT_BACKEND: WASM
|
|
||||||
// WASM_MUTE_REASON: SPREAD_OPERATOR
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
if (test1() != "") return "fail 1"
|
if (test1() != "") return "fail 1"
|
||||||
if (test1(1) != "1") return "fail 2"
|
if (test1(1) != "1") return "fail 2"
|
||||||
|
|||||||
js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java
Generated
+65
@@ -1342,6 +1342,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
|
|||||||
runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/manyDefaultsAndVararg.kt");
|
runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/manyDefaultsAndVararg.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("referenceToVarargWithDefaults.kt")
|
||||||
|
public void testReferenceToVarargWithDefaults() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/referenceToVarargWithDefaults.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("simpleDefaultArgument.kt")
|
@TestMetadata("simpleDefaultArgument.kt")
|
||||||
public void testSimpleDefaultArgument() throws Exception {
|
public void testSimpleDefaultArgument() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/simpleDefaultArgument.kt");
|
runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/simpleDefaultArgument.kt");
|
||||||
@@ -1352,11 +1357,21 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
|
|||||||
runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/simpleEmptyVararg.kt");
|
runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/simpleEmptyVararg.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("unboundReferences.kt")
|
||||||
|
public void testUnboundReferences() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/unboundReferences.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("varargViewedAsArray.kt")
|
@TestMetadata("varargViewedAsArray.kt")
|
||||||
public void testVarargViewedAsArray() throws Exception {
|
public void testVarargViewedAsArray() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/varargViewedAsArray.kt");
|
runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/varargViewedAsArray.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("varargViewedAsPrimitiveArray.kt")
|
||||||
|
public void testVarargViewedAsPrimitiveArray() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/varargViewedAsPrimitiveArray.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("varargWithDefaultValue.kt")
|
@TestMetadata("varargWithDefaultValue.kt")
|
||||||
public void testVarargWithDefaultValue() throws Exception {
|
public void testVarargWithDefaultValue() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/varargWithDefaultValue.kt");
|
runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/varargWithDefaultValue.kt");
|
||||||
@@ -7135,6 +7150,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
|
|||||||
runTest("compiler/testData/codegen/box/inlineClasses/passInlineClassAsVararg.kt");
|
runTest("compiler/testData/codegen/box/inlineClasses/passInlineClassAsVararg.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("passInlineClassWithSpreadOperatorToVarargs.kt")
|
||||||
|
public void testPassInlineClassWithSpreadOperatorToVarargs() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/inlineClasses/passInlineClassWithSpreadOperatorToVarargs.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("propertyLoweringOrder.kt")
|
@TestMetadata("propertyLoweringOrder.kt")
|
||||||
public void testPropertyLoweringOrder() throws Exception {
|
public void testPropertyLoweringOrder() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/inlineClasses/propertyLoweringOrder.kt");
|
runTest("compiler/testData/codegen/box/inlineClasses/propertyLoweringOrder.kt");
|
||||||
@@ -9853,6 +9873,16 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
|
|||||||
public void testSimple() throws Exception {
|
public void testSimple() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/mixedNamedPosition/simple.kt");
|
runTest("compiler/testData/codegen/box/mixedNamedPosition/simple.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("varargs.kt")
|
||||||
|
public void testVarargs() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/mixedNamedPosition/varargs.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("varargsEvaluationOrder.kt")
|
||||||
|
public void testVarargsEvaluationOrder() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/mixedNamedPosition/varargsEvaluationOrder.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/box/multiDecl")
|
@TestMetadata("compiler/testData/codegen/box/multiDecl")
|
||||||
@@ -14341,6 +14371,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
|
|||||||
runTest("compiler/testData/codegen/box/secondaryConstructors/superCallSecondary.kt");
|
runTest("compiler/testData/codegen/box/secondaryConstructors/superCallSecondary.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("varargs.kt")
|
||||||
|
public void testVarargs() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/secondaryConstructors/varargs.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("withoutPrimarySimple.kt")
|
@TestMetadata("withoutPrimarySimple.kt")
|
||||||
public void testWithoutPrimarySimple() throws Exception {
|
public void testWithoutPrimarySimple() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/secondaryConstructors/withoutPrimarySimple.kt");
|
runTest("compiler/testData/codegen/box/secondaryConstructors/withoutPrimarySimple.kt");
|
||||||
@@ -14919,6 +14954,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
|
|||||||
runTest("compiler/testData/codegen/box/super/superConstructor/kt18356.kt");
|
runTest("compiler/testData/codegen/box/super/superConstructor/kt18356.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt18356_2.kt")
|
||||||
|
public void testKt18356_2() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/super/superConstructor/kt18356_2.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("objectExtendsInner.kt")
|
@TestMetadata("objectExtendsInner.kt")
|
||||||
public void testObjectExtendsInner() throws Exception {
|
public void testObjectExtendsInner() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/super/superConstructor/objectExtendsInner.kt");
|
runTest("compiler/testData/codegen/box/super/superConstructor/objectExtendsInner.kt");
|
||||||
@@ -15789,6 +15829,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
|
|||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/vararg"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/vararg"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("doNotCopyImmediatelyCreatedArrays.kt")
|
||||||
|
public void testDoNotCopyImmediatelyCreatedArrays() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/vararg/doNotCopyImmediatelyCreatedArrays.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("evaluationOrder.kt")
|
@TestMetadata("evaluationOrder.kt")
|
||||||
public void testEvaluationOrder() throws Exception {
|
public void testEvaluationOrder() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/vararg/evaluationOrder.kt");
|
runTest("compiler/testData/codegen/box/vararg/evaluationOrder.kt");
|
||||||
@@ -15799,6 +15844,16 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
|
|||||||
runTest("compiler/testData/codegen/box/vararg/kt1978.kt");
|
runTest("compiler/testData/codegen/box/vararg/kt1978.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt37779.kt")
|
||||||
|
public void testKt37779() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/vararg/kt37779.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt6192.kt")
|
||||||
|
public void testKt6192() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/vararg/kt6192.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("kt796_797.kt")
|
@TestMetadata("kt796_797.kt")
|
||||||
public void testKt796_797() throws Exception {
|
public void testKt796_797() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/vararg/kt796_797.kt");
|
runTest("compiler/testData/codegen/box/vararg/kt796_797.kt");
|
||||||
@@ -15814,6 +15869,16 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
|
|||||||
runTest("compiler/testData/codegen/box/vararg/singleAssignmentToVarargsInFunction.kt");
|
runTest("compiler/testData/codegen/box/vararg/singleAssignmentToVarargsInFunction.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("spreadCopiesArray.kt")
|
||||||
|
public void testSpreadCopiesArray() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/vararg/spreadCopiesArray.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("varargInFunParam.kt")
|
||||||
|
public void testVarargInFunParam() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/vararg/varargInFunParam.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("varargsAndFunctionLiterals.kt")
|
@TestMetadata("varargsAndFunctionLiterals.kt")
|
||||||
public void testVarargsAndFunctionLiterals() throws Exception {
|
public void testVarargsAndFunctionLiterals() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/vararg/varargsAndFunctionLiterals.kt");
|
runTest("compiler/testData/codegen/box/vararg/varargsAndFunctionLiterals.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user