diff --git a/compiler/testData/codegen/box/inlineClasses/UIntArraySortExample.kt b/compiler/testData/codegen/box/inlineClasses/UIntArraySortExample.kt new file mode 100644 index 00000000000..8709cc3f3a0 --- /dev/null +++ b/compiler/testData/codegen/box/inlineClasses/UIntArraySortExample.kt @@ -0,0 +1,116 @@ +// !LANGUAGE: +InlineClasses + +inline class UInt(private val value: Int) : Comparable { + companion object { + private const val INT_MASK = 0xffffffffL + } + + fun asInt(): Int = value + + fun toLong(): Long = value.toLong() and INT_MASK + + override fun compareTo(other: UInt): Int = + flip().compareTo(other.flip()) + + override fun toString(): String { + return toLong().toString() + } + + private fun flip(): Int = + value xor Int.MIN_VALUE +} + +inline class UIntArray(private val intArray: IntArray) { + val size: Int get() = intArray.size + + operator fun get(index: Int): UInt = UInt(intArray[index]) + + operator fun set(index: Int, value: UInt) { + intArray[index] = value.asInt() + } + + operator fun iterator(): UIntIterator = UIntIterator(intArray.iterator()) +} + +inline class UIntIterator(private val intIterator: IntIterator) : Iterator { + override fun next(): UInt { + return UInt(intIterator.next()) + } + + override fun hasNext(): Boolean { + return intIterator.hasNext() + } +} + +fun uIntArrayOf(vararg u: Int): UIntArray = UIntArray(u) + +fun UIntArray.swap(i: Int, j: Int) { + this[j] = this[i].also { this[i] = this[j] } +} + +fun UIntArray.quickSort() { + quickSort(0, size - 1) +} + +private fun UIntArray.quickSort(l: Int, r: Int) { + if (l < r) { + val q = partition(l, r) + quickSort(l, q - 1) + quickSort(q + 1, r) + } +} + +private fun UIntArray.partition(l: Int, r: Int): Int { + val m = this[(l + r) / 2] + var i = l + var j = r + while (i <= j) { + while (this[i] < m) i++ + while (this[j] > m) j-- + if (i <= j) + swap(i++, j--) + } + + return i +} + +fun check(array: UIntArray, resultAsInt: String, resultAsInner: String) { + val actualAsInt = StringBuilder() + val actualAsInner = StringBuilder() + for (n in array) { + actualAsInt.append("${n.asInt()} ") + actualAsInner.append(n.toString() + " ") + } + + if (actualAsInt.toString() != resultAsInt) { + throw IllegalStateException("wrong result as int (actual): $actualAsInt ; expected: $resultAsInt") + } + + if (actualAsInner.toString() != resultAsInner) { + throw IllegalStateException("wrong result as inner (actual): $actualAsInner ; expected: $resultAsInner") + } +} + +fun box(): String { + val a1 = uIntArrayOf(1, 2, 3) + a1.quickSort() + + check(a1, "1 2 3 ", "1 2 3 ") + + val a2 = uIntArrayOf(-1) + a2.quickSort() + + check(a2, "-1 ", "4294967295 ") + + val a3 = uIntArrayOf(-1, 1, 0) + a3.quickSort() + + check(a3, "0 1 -1 ", "0 1 4294967295 ") + + val a4 = uIntArrayOf(-1, Int.MAX_VALUE) + a4.quickSort() + + check(a4, "${Int.MAX_VALUE} -1 ", "2147483647 4294967295 ") + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/inlineClasses/uIntArrayIteratorWithoutBoxing.kt b/compiler/testData/codegen/bytecodeText/inlineClasses/uIntArrayIteratorWithoutBoxing.kt new file mode 100644 index 00000000000..095fabca6c8 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/inlineClasses/uIntArrayIteratorWithoutBoxing.kt @@ -0,0 +1,39 @@ +// !LANGUAGE: +InlineClasses + +inline class UInt(private val value: Int) + +inline class UIntArray(private val intArray: IntArray) { + operator fun iterator(): UIntIterator = UIntIterator(intArray.iterator()) // create iterator +} + +inline class UIntIterator(private val intIterator: IntIterator) : Iterator { + override fun next(): UInt { + return UInt(intIterator.next()) + } + + override fun hasNext(): Boolean { + return intIterator.hasNext() + } +} + +fun uIntArrayOf(vararg u: Int): UIntArray = UIntArray(u) + +fun test() { + val a = uIntArrayOf(1, 2, 3, 4) + for (element in a) { + takeUInt(element) + } +} + +fun takeUInt(u: UInt) {} + +// 0 INVOKESTATIC UInt\$Erased.box +// 0 INVOKEVIRTUAL UInt.unbox + +// 0 INVOKEVIRTUAL UIntIterator.iterator +// 1 INVOKESTATIC kotlin/jvm/internal/ArrayIteratorsKt.iterator + +// 0 intValue + +// inside wrong bridge +// 1 valueOf \ No newline at end of file diff --git a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 4a731a93ce9..cde69be481e 100644 --- a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -10461,6 +10461,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes doTest(fileName); } + @TestMetadata("UIntArraySortExample.kt") + public void testUIntArraySortExample() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/UIntArraySortExample.kt"); + doTest(fileName); + } + @TestMetadata("useInlineClassesInsideElvisOperator.kt") public void testUseInlineClassesInsideElvisOperator() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/useInlineClassesInsideElvisOperator.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index e5e7623d786..09ea04e5178 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -10461,6 +10461,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("UIntArraySortExample.kt") + public void testUIntArraySortExample() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/UIntArraySortExample.kt"); + doTest(fileName); + } + @TestMetadata("useInlineClassesInsideElvisOperator.kt") public void testUseInlineClassesInsideElvisOperator() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/useInlineClassesInsideElvisOperator.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java index 855d4abec24..4031de70dab 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java @@ -1968,6 +1968,12 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest { doTest(fileName); } + @TestMetadata("uIntArrayIteratorWithoutBoxing.kt") + public void testUIntArrayIteratorWithoutBoxing() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/inlineClasses/uIntArrayIteratorWithoutBoxing.kt"); + doTest(fileName); + } + @TestMetadata("uIntArraySwapBoxing.kt") public void testUIntArraySwapBoxing() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/inlineClasses/uIntArraySwapBoxing.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index cbc409ef7eb..59db8f151ac 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -10461,6 +10461,12 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes doTest(fileName); } + @TestMetadata("UIntArraySortExample.kt") + public void testUIntArraySortExample() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/UIntArraySortExample.kt"); + doTest(fileName); + } + @TestMetadata("useInlineClassesInsideElvisOperator.kt") public void testUseInlineClassesInsideElvisOperator() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/useInlineClassesInsideElvisOperator.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index 6b3b95fc024..a9b8d27f57e 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -11445,6 +11445,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { doTest(fileName); } + @TestMetadata("UIntArraySortExample.kt") + public void testUIntArraySortExample() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/UIntArraySortExample.kt"); + doTest(fileName); + } + @TestMetadata("useInlineClassesInsideElvisOperator.kt") public void testUseInlineClassesInsideElvisOperator() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/inlineClasses/useInlineClassesInsideElvisOperator.kt");