diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/IntrinsicMethods.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/IntrinsicMethods.java index a6542cd57fb..e66dd8879d6 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/IntrinsicMethods.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/IntrinsicMethods.java @@ -175,6 +175,8 @@ public class IntrinsicMethods { intrinsicsMap.registerIntrinsic(KOTLIN_UINT.toSafe(), null, "compareTo", 1, java8UIntCompare); intrinsicsMap.registerIntrinsic(BUILT_INS_PACKAGE_FQ_NAME, null, "uintCompare", 2, java8UIntCompare); + intrinsicsMap.registerIntrinsic(KOTLIN_UINT.toSafe(), null, "toString", 0, new Java8UIntToString()); + Java8ULongDivide java8ULongDivide = new Java8ULongDivide(); intrinsicsMap.registerIntrinsic(KOTLIN_ULONG.toSafe(), null, "div", 1, java8ULongDivide); intrinsicsMap.registerIntrinsic(BUILT_INS_PACKAGE_FQ_NAME, null, "ulongDivide", 2, java8ULongDivide); @@ -186,6 +188,8 @@ public class IntrinsicMethods { Java8ULongCompare java8ULongCompare = new Java8ULongCompare(); intrinsicsMap.registerIntrinsic(KOTLIN_ULONG.toSafe(), null, "compareTo", 1, java8ULongCompare); intrinsicsMap.registerIntrinsic(BUILT_INS_PACKAGE_FQ_NAME, null, "ulongCompare", 2, java8ULongCompare); + + intrinsicsMap.registerIntrinsic(KOTLIN_ULONG.toSafe(), null, "toString", 0, new Java8ULongToString()); } } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/Java8Unsigned.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/Java8Unsigned.kt index c9db7339eb4..11616f97b2b 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/Java8Unsigned.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/Java8Unsigned.kt @@ -13,7 +13,8 @@ import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor abstract class UnsignedIntrinsic(private val targetDescriptor: String) : IntrinsicMethod() { override fun isApplicableToOverload(descriptor: CallableMemberDescriptor): Boolean { if (descriptor.containingDeclaration is PackageFragmentDescriptor) return true - val singleValueParameterTypeDescriptor = descriptor.valueParameters.single().type.constructor.declarationDescriptor + val valueParameter = descriptor.valueParameters.singleOrNull() ?: return true + val singleValueParameterTypeDescriptor = valueParameter.type.constructor.declarationDescriptor ?: throw AssertionError("Unexpected descriptor for unsigned intrinsic: $descriptor") return singleValueParameterTypeDescriptor.name.asString() == targetDescriptor } @@ -40,6 +41,13 @@ class Java8UIntCompare : UnsignedIntrinsic("UInt") { } } +class Java8UIntToString : UnsignedIntrinsic("UInt") { + override fun toCallable(method: CallableMethod): Callable = + createIntrinsicCallable(method) { + it.invokestatic("java/lang/Integer", "toUnsignedString", "(I)Ljava/lang/String;", false) + } +} + class Java8ULongDivide : UnsignedIntrinsic("ULong") { override fun toCallable(method: CallableMethod): Callable = createIntrinsicCallable(method) { @@ -60,3 +68,10 @@ class Java8ULongCompare : UnsignedIntrinsic("ULong") { it.invokestatic("java/lang/Long", "compareUnsigned", "(JJ)I", false) } } + +class Java8ULongToString : UnsignedIntrinsic("ULong") { + override fun toCallable(method: CallableMethod): Callable = + createIntrinsicCallable(method) { + it.invokestatic("java/lang/Long", "toUnsignedString", "(J)Ljava/lang/String;", false) + } +} diff --git a/compiler/testData/codegen/box/unsignedTypes/unsignedIntToString.kt b/compiler/testData/codegen/box/unsignedTypes/unsignedIntToString.kt new file mode 100644 index 00000000000..8c2f27b0ae4 --- /dev/null +++ b/compiler/testData/codegen/box/unsignedTypes/unsignedIntToString.kt @@ -0,0 +1,15 @@ +// KJS_WITH_FULL_RUNTIME +// WITH_RUNTIME + +fun box(): String { + val min = 0U.toString() + if ("0" != min) throw AssertionError(min) + + val middle = 2_147_483_647U.toString() + if ("2147483647" != middle) throw AssertionError(middle) + + val max = 4_294_967_295U.toString() + if ("4294967295" != max) throw AssertionError(max) + + return "OK" +} diff --git a/compiler/testData/codegen/box/unsignedTypes/unsignedLongToString.kt b/compiler/testData/codegen/box/unsignedTypes/unsignedLongToString.kt new file mode 100644 index 00000000000..de80a1a7b62 --- /dev/null +++ b/compiler/testData/codegen/box/unsignedTypes/unsignedLongToString.kt @@ -0,0 +1,15 @@ +// KJS_WITH_FULL_RUNTIME +// WITH_RUNTIME + +fun box(): String { + val min = 0UL.toString() + if ("0" != min) throw AssertionError(min) + + val middle = 9_223_372_036_854_775_807UL.toString() + if ("9223372036854775807" != middle) throw AssertionError(middle) + + val max = 18_446_744_073_709_551_615UL.toString() + if ("18446744073709551615" != max) throw AssertionError(max) + + return "OK" +} diff --git a/compiler/testData/codegen/bytecodeText/unsignedTypes/unsignedIntToString_jvm18.kt b/compiler/testData/codegen/bytecodeText/unsignedTypes/unsignedIntToString_jvm18.kt new file mode 100644 index 00000000000..8c7d674dbf5 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/unsignedTypes/unsignedIntToString_jvm18.kt @@ -0,0 +1,19 @@ +// JVM_TARGET: 1.8 +// WITH_RUNTIME +// IGNORE_BACKEND: JVM_IR + +fun box(): String { + val min = 0U.toString() + if ("0" != min) throw AssertionError(min) + + val middle = 2_147_483_647U.toString() + if ("2147483647" != middle) throw AssertionError(middle) + + val max = 4_294_967_295U.toString() + if ("4294967295" != max) throw AssertionError(max) + + return "OK" +} + +// 0 kotlin/UInt.toString +// 3 INVOKESTATIC java/lang/Integer.toUnsignedString \(I\)Ljava/lang/String; diff --git a/compiler/testData/codegen/bytecodeText/unsignedTypes/unsignedLongToString_jvm18.kt b/compiler/testData/codegen/bytecodeText/unsignedTypes/unsignedLongToString_jvm18.kt new file mode 100644 index 00000000000..3ca1ea43f2f --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/unsignedTypes/unsignedLongToString_jvm18.kt @@ -0,0 +1,19 @@ +// JVM_TARGET: 1.8 +// WITH_RUNTIME +// IGNORE_BACKEND: JVM_IR + +fun box(): String { + val min = 0UL.toString() + if ("0" != min) throw AssertionError(min) + + val middle = 9_223_372_036_854_775_807UL.toString() + if ("9223372036854775807" != middle) throw AssertionError(middle) + + val max = 18_446_744_073_709_551_615UL.toString() + if ("18446744073709551615" != max) throw AssertionError(max) + + return "OK" +} + +// 0 kotlin/ULong.toString +// 3 INVOKESTATIC java/lang/Long.toUnsignedString \(J\)Ljava/lang/String; diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index b4c1fd7dcc7..bb6917eaf15 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -25205,6 +25205,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/unsignedTypes/unsignedIntRemainder.kt"); } + @TestMetadata("unsignedIntToString.kt") + public void testUnsignedIntToString() throws Exception { + runTest("compiler/testData/codegen/box/unsignedTypes/unsignedIntToString.kt"); + } + @TestMetadata("unsignedLiteralsForMaxLongValue.kt") public void testUnsignedLiteralsForMaxLongValue() throws Exception { runTest("compiler/testData/codegen/box/unsignedTypes/unsignedLiteralsForMaxLongValue.kt"); @@ -25230,6 +25235,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/unsignedTypes/unsignedLongRemainder.kt"); } + @TestMetadata("unsignedLongToString.kt") + public void testUnsignedLongToString() throws Exception { + runTest("compiler/testData/codegen/box/unsignedTypes/unsignedLongToString.kt"); + } + @TestMetadata("unsignedRangeIterator.kt") public void testUnsignedRangeIterator() throws Exception { runTest("compiler/testData/codegen/box/unsignedTypes/unsignedRangeIterator.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java index 78b2e491e08..dcf4b40c98c 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java @@ -3643,6 +3643,11 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest { runTest("compiler/testData/codegen/bytecodeText/unsignedTypes/unsignedIntRemainder_jvm18.kt"); } + @TestMetadata("unsignedIntToString_jvm18.kt") + public void testUnsignedIntToString_jvm18() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/unsignedTypes/unsignedIntToString_jvm18.kt"); + } + @TestMetadata("unsignedLongCompare_jvm18.kt") public void testUnsignedLongCompare_jvm18() throws Exception { runTest("compiler/testData/codegen/bytecodeText/unsignedTypes/unsignedLongCompare_jvm18.kt"); @@ -3658,6 +3663,11 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest { runTest("compiler/testData/codegen/bytecodeText/unsignedTypes/unsignedLongRemainder_jvm18.kt"); } + @TestMetadata("unsignedLongToString_jvm18.kt") + public void testUnsignedLongToString_jvm18() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/unsignedTypes/unsignedLongToString_jvm18.kt"); + } + @TestMetadata("whenByUnsigned.kt") public void testWhenByUnsigned() throws Exception { runTest("compiler/testData/codegen/bytecodeText/unsignedTypes/whenByUnsigned.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 20cbbc58503..878d89a9634 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -25205,6 +25205,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/unsignedTypes/unsignedIntRemainder.kt"); } + @TestMetadata("unsignedIntToString.kt") + public void testUnsignedIntToString() throws Exception { + runTest("compiler/testData/codegen/box/unsignedTypes/unsignedIntToString.kt"); + } + @TestMetadata("unsignedLiteralsForMaxLongValue.kt") public void testUnsignedLiteralsForMaxLongValue() throws Exception { runTest("compiler/testData/codegen/box/unsignedTypes/unsignedLiteralsForMaxLongValue.kt"); @@ -25230,6 +25235,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/unsignedTypes/unsignedLongRemainder.kt"); } + @TestMetadata("unsignedLongToString.kt") + public void testUnsignedLongToString() throws Exception { + runTest("compiler/testData/codegen/box/unsignedTypes/unsignedLongToString.kt"); + } + @TestMetadata("unsignedRangeIterator.kt") public void testUnsignedRangeIterator() throws Exception { runTest("compiler/testData/codegen/box/unsignedTypes/unsignedRangeIterator.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 45d77e58a77..143807a628b 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -24110,6 +24110,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/unsignedTypes/unsignedIntRemainder.kt"); } + @TestMetadata("unsignedIntToString.kt") + public void testUnsignedIntToString() throws Exception { + runTest("compiler/testData/codegen/box/unsignedTypes/unsignedIntToString.kt"); + } + @TestMetadata("unsignedLiteralsForMaxLongValue.kt") public void testUnsignedLiteralsForMaxLongValue() throws Exception { runTest("compiler/testData/codegen/box/unsignedTypes/unsignedLiteralsForMaxLongValue.kt"); @@ -24135,6 +24140,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/unsignedTypes/unsignedLongRemainder.kt"); } + @TestMetadata("unsignedLongToString.kt") + public void testUnsignedLongToString() throws Exception { + runTest("compiler/testData/codegen/box/unsignedTypes/unsignedLongToString.kt"); + } + @TestMetadata("unsignedRangeIterator.kt") public void testUnsignedRangeIterator() throws Exception { runTest("compiler/testData/codegen/box/unsignedTypes/unsignedRangeIterator.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeTextTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeTextTestGenerated.java index dfdaefdce18..03546c84d99 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeTextTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeTextTestGenerated.java @@ -3598,6 +3598,11 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest { runTest("compiler/testData/codegen/bytecodeText/unsignedTypes/unsignedIntRemainder_jvm18.kt"); } + @TestMetadata("unsignedIntToString_jvm18.kt") + public void testUnsignedIntToString_jvm18() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/unsignedTypes/unsignedIntToString_jvm18.kt"); + } + @TestMetadata("unsignedLongCompare_jvm18.kt") public void testUnsignedLongCompare_jvm18() throws Exception { runTest("compiler/testData/codegen/bytecodeText/unsignedTypes/unsignedLongCompare_jvm18.kt"); @@ -3613,6 +3618,11 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest { runTest("compiler/testData/codegen/bytecodeText/unsignedTypes/unsignedLongRemainder_jvm18.kt"); } + @TestMetadata("unsignedLongToString_jvm18.kt") + public void testUnsignedLongToString_jvm18() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/unsignedTypes/unsignedLongToString_jvm18.kt"); + } + @TestMetadata("whenByUnsigned.kt") public void testWhenByUnsigned() throws Exception { runTest("compiler/testData/codegen/bytecodeText/unsignedTypes/whenByUnsigned.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index ee417faceec..5cae9cdc136 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -19365,6 +19365,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/unsignedTypes/unsignedIntRemainder.kt"); } + @TestMetadata("unsignedIntToString.kt") + public void testUnsignedIntToString() throws Exception { + runTest("compiler/testData/codegen/box/unsignedTypes/unsignedIntToString.kt"); + } + @TestMetadata("unsignedLiteralsForMaxLongValue.kt") public void testUnsignedLiteralsForMaxLongValue() throws Exception { runTest("compiler/testData/codegen/box/unsignedTypes/unsignedLiteralsForMaxLongValue.kt"); @@ -19390,6 +19395,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/unsignedTypes/unsignedLongRemainder.kt"); } + @TestMetadata("unsignedLongToString.kt") + public void testUnsignedLongToString() throws Exception { + runTest("compiler/testData/codegen/box/unsignedTypes/unsignedLongToString.kt"); + } + @TestMetadata("unsignedRangeIterator.kt") public void testUnsignedRangeIterator() throws Exception { runTest("compiler/testData/codegen/box/unsignedTypes/unsignedRangeIterator.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 3ba1e479c79..aa6d59beae0 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 @@ -20520,6 +20520,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/unsignedTypes/unsignedIntRemainder.kt"); } + @TestMetadata("unsignedIntToString.kt") + public void testUnsignedIntToString() throws Exception { + runTest("compiler/testData/codegen/box/unsignedTypes/unsignedIntToString.kt"); + } + @TestMetadata("unsignedLiteralsForMaxLongValue.kt") public void testUnsignedLiteralsForMaxLongValue() throws Exception { runTest("compiler/testData/codegen/box/unsignedTypes/unsignedLiteralsForMaxLongValue.kt"); @@ -20545,6 +20550,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/unsignedTypes/unsignedLongRemainder.kt"); } + @TestMetadata("unsignedLongToString.kt") + public void testUnsignedLongToString() throws Exception { + runTest("compiler/testData/codegen/box/unsignedTypes/unsignedLongToString.kt"); + } + @TestMetadata("unsignedRangeIterator.kt") public void testUnsignedRangeIterator() throws Exception { runTest("compiler/testData/codegen/box/unsignedTypes/unsignedRangeIterator.kt");