diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/IrInterpreter.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/IrInterpreter.kt index c5687eaf8a3..c69f786c8fc 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/IrInterpreter.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/IrInterpreter.kt @@ -700,32 +700,44 @@ class IrInterpreter(private val irBuiltIns: IrBuiltIns, private val bodyMap: Map } private fun interpretVararg(expression: IrVararg): ExecutionResult { + fun arrayToList(value: Any?): List { + return when (value) { + is ByteArray -> value.toList() + is CharArray -> value.toList() + is ShortArray -> value.toList() + is IntArray -> value.toList() + is LongArray -> value.toList() + is FloatArray -> value.toList() + is DoubleArray -> value.toList() + is BooleanArray -> value.toList() + is Array<*> -> value.toList() + else -> listOf(value) + } + } + val args = expression.elements.flatMap { it.interpret().check { executionResult -> return executionResult } return@flatMap when (val result = stack.popReturnValue()) { is Wrapper -> listOf(result.value) - is Primitive<*> -> - when (val value = result.value) { - is ByteArray -> value.toList() - is CharArray -> value.toList() - is ShortArray -> value.toList() - is IntArray -> value.toList() - is LongArray -> value.toList() - is FloatArray -> value.toList() - is DoubleArray -> value.toList() - is BooleanArray -> value.toList() - is Array<*> -> value.toList() - else -> listOf(value) - } + is Primitive<*> -> arrayToList(result.value) + is Common -> when { + result.irClass.defaultType.isUnsignedArray() -> arrayToList((result.fields.single().state as Primitive<*>).value) + else -> listOf(result) + } else -> listOf(result) } } - val array = when ((expression.type.classifierOrFail.owner as? IrDeclaration)?.nameForIrSerialization?.asString()) { - "UByteArray", "UShortArray", "UIntArray", "ULongArray" -> { + val array = when { + expression.type.isUnsignedArray() -> { val owner = expression.type.classOrNull!!.owner val storageProperty = owner.declarations.filterIsInstance().first { it.name.asString() == "storage" } - val primitiveArray = args.map { ((it as Common).fields.single().state as Primitive<*>).value } + val primitiveArray = args.map { + when (it) { + is Common -> (it.fields.single().state as Primitive<*>).value // is unsigned number + else -> it // is primitive number + } + } val unsignedArray = primitiveArray.toPrimitiveStateArray(storageProperty.backingField!!.type) Common(owner).apply { setSuperClassRecursive() diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/Utils.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/Utils.kt index 9cac5c6675f..ff5f9287241 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/Utils.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/Utils.kt @@ -214,6 +214,13 @@ internal fun State?.getCorrectReceiverByFunction(irFunction: IrFunction): State? internal fun IrFunction.getCapitalizedFileName() = this.file.name.replace(".kt", "Kt").capitalizeAsciiOnly() +internal fun IrType.isUnsigned() = this.isUByte() || this.isUShort() || this.isUInt() || this.isULong() +internal fun IrType.isUnsignedArray(): Boolean { + if (this !is IrSimpleType || classifier !is IrClassSymbol) return false + val fqName = (classifier.owner as IrDeclarationWithName).fqNameWhenAvailable?.asString() + return fqName in setOf("kotlin.UByteArray", "kotlin.UShortArray", "kotlin.UIntArray", "kotlin.ULongArray") +} + internal fun IrType.isPrimitiveArray(): Boolean { return this.getClass()?.fqNameWhenAvailable?.toUnsafe()?.let { StandardNames.isPrimitiveArray(it) } ?: false }