[K/Wasm] Generate wasm-specific unsigned implementations ^KT-58039 Fixed

This commit is contained in:
Artem Kobzar
2024-01-23 18:49:06 +01:00
committed by Space Team
parent b59993d88a
commit 8c69ffe8c9
24 changed files with 666 additions and 541 deletions
@@ -132,13 +132,13 @@ class WasmSymbols(
val voidClass = getIrClass(FqName("kotlin.wasm.internal.Void"))
val voidType by lazy { voidClass.defaultType }
private val consumeAnyIntoVoid = getInternalFunction("consumeAnyIntoVoid")
val uByteType by lazy { getIrClass(FqName("kotlin.UByte")).defaultType }
val uShortType by lazy { getIrClass(FqName("kotlin.UShort")).defaultType }
val uIntType by lazy { getIrClass(FqName("kotlin.UInt")).defaultType }
val uLongType by lazy { getIrClass(FqName("kotlin.ULong")).defaultType }
private val consumeAnyIntoVoid = getInternalFunction("consumeAnyIntoVoid")
private val consumePrimitiveIntoVoid = mapOf(
context.irBuiltIns.booleanType to getInternalFunction("consumeBooleanIntoVoid"),
context.irBuiltIns.byteType to getInternalFunction("consumeByteIntoVoid"),
@@ -153,14 +153,20 @@ class WasmSymbols(
fun findVoidConsumer(type: IrType): IrSimpleFunctionSymbol =
consumePrimitiveIntoVoid[type] ?: consumeAnyIntoVoid
val equalityFunctions = mapOf(
val equalityFunctions by lazy {
mapOf(
context.irBuiltIns.booleanType to getInternalFunction("wasm_i32_eq"),
context.irBuiltIns.byteType to getInternalFunction("wasm_i32_eq"),
context.irBuiltIns.shortType to getInternalFunction("wasm_i32_eq"),
uByteType to getInternalFunction("wasm_i32_eq"),
uShortType to getInternalFunction("wasm_i32_eq"),
context.irBuiltIns.charType to getInternalFunction("wasm_i32_eq"),
context.irBuiltIns.intType to getInternalFunction("wasm_i32_eq"),
context.irBuiltIns.longType to getInternalFunction("wasm_i64_eq")
uIntType to getInternalFunction("wasm_i32_eq"),
context.irBuiltIns.longType to getInternalFunction("wasm_i64_eq"),
uLongType to getInternalFunction("wasm_i64_eq")
)
}
val floatEqualityFunctions = mapOf(
context.irBuiltIns.floatType to getInternalFunction("wasm_f32_eq"),
+2 -2
View File
@@ -1,8 +1,8 @@
// TARGET_BACKEND: WASM
// RUN_THIRD_PARTY_OPTIMIZER
// WASM_DCE_EXPECTED_OUTPUT_SIZE: wasm 12_814
// WASM_DCE_EXPECTED_OUTPUT_SIZE: mjs 4_526
// WASM_DCE_EXPECTED_OUTPUT_SIZE: wasm 12_773
// WASM_DCE_EXPECTED_OUTPUT_SIZE: mjs 4_528
// WASM_OPT_EXPECTED_OUTPUT_SIZE: 2_640
// FILE: test.kt
+2 -2
View File
@@ -1,9 +1,9 @@
// TARGET_BACKEND: WASM
// RUN_THIRD_PARTY_OPTIMIZER
// WASM_DCE_EXPECTED_OUTPUT_SIZE: wasm 41_349
// WASM_DCE_EXPECTED_OUTPUT_SIZE: wasm 35_154
// WASM_DCE_EXPECTED_OUTPUT_SIZE: mjs 4_552
// WASM_OPT_EXPECTED_OUTPUT_SIZE: 9_847
// WASM_OPT_EXPECTED_OUTPUT_SIZE: 8_586
fun box(): String {
println("Hello, World!")
+2 -1
View File
@@ -2,7 +2,8 @@
// TARGET_BACKEND: WASM
// RUN_THIRD_PARTY_OPTIMIZER
// WASM_DCE_EXPECTED_OUTPUT_SIZE: wasm 13_362
// WASM_DCE_EXPECTED_OUTPUT_SIZE: wasm 13_321
// WASM_DCE_EXPECTED_OUTPUT_SIZE: mjs 4_398
// WASM_OPT_EXPECTED_OUTPUT_SIZE: 3_900
interface I {
+65 -52
View File
@@ -215,67 +215,80 @@ fun box() {
// _ArraysWasm.kt:1700 $kotlin.collections.copyOfUninitializedElements (11, 4)
// StringBuilder.kt:179 $kotlin.text.StringBuilder.append (8, 29, 36, 45, 19, 8, 8)
// StringBuilderWasm.kt:52 $kotlin.text.insertInt (22, 28)
// Primitives.kt:1359 $kotlin.Int__toString-impl (21, 8, 24)
// Number2String.kt:199 $kotlin.wasm.internal.<init properties Number2String.kt>
// Number2String.kt:200 $kotlin.wasm.internal.<init properties Number2String.kt>
// Number2String.kt:201 $kotlin.wasm.internal.<init properties Number2String.kt>
// Number2String.kt:202 $kotlin.wasm.internal.<init properties Number2String.kt>
// Number2String.kt:203 $kotlin.wasm.internal.<init properties Number2String.kt>
// Number2String.kt:204 $kotlin.wasm.internal.<init properties Number2String.kt>
// Number2String.kt:206 $kotlin.wasm.internal.<init properties Number2String.kt>
// Library.kt:93 $kotlin.wasm.internal.<init properties Number2String.kt> (2841, 2841, 2841, 2841, 3432, 3432, 3432, 3432, 3453, 3432, 11556, 11560, 3484, 3463, 11556, 11560, 3515, 3494, 11556, 11560, 3546, 3525, 11556, 11560, 3581, 3560, 11556, 11560, 3612, 3591, 11556, 11560, 3643, 3622, 11556, 11560, 3674, 3653, 11556, 11560, 3709, 3688, 11556, 11560, 3740, 3719, 11556, 11560, 3771, 3750, 11556, 11560, 3802, 3781, 11556, 11560, 3837, 3816, 11556, 11560, 3868, 3847, 11556, 11560, 3899, 3878, 11556, 11560, 3930, 3909, 11556, 11560, 3965, 3944, 11556, 11560, 3996, 3975, 11556, 11560, 4027, 4006, 11556, 11560, 4058, 4037, 11556, 11560, 4093, 4072, 11556, 11560, 4124, 4103, 11556, 11560, 4155, 4134, 11556, 11560, 4186, 4165, 11556, 11560, 4221, 4200, 11556, 11560, 4252, 4231, 11556, 11560, 4283, 4262, 11556, 11560, 4314, 4293, 11556, 11560, 4349, 4328, 11556, 11560, 4380, 4359, 11556, 11560, 4411, 4390, 11556, 11560, 4442, 4421, 11556, 11560, 4477, 4456, 11556, 11560, 4508, 4487, 11556, 11560, 4539, 4518, 11556, 11560, 4570, 4549, 11556, 11560, 4605, 4584, 11556, 11560, 4636, 4615, 11556, 11560, 4667, 4646, 11556, 11560, 4698, 4677, 11556, 11560, 4733, 4712, 11556, 11560, 4764, 4743, 11556, 11560, 4795, 4774, 11556, 11560, 4826, 4805, 11556, 11560, 4861, 4840, 11556, 11560, 4892, 4871, 11556, 11560, 4923, 4902, 11556, 11560, 4954, 4933, 11556, 11560, 4989, 4968, 11556, 11560, 5020, 4999, 11556, 11560, 5051, 5030, 11556, 11560, 5082, 5061, 11556, 11560, 5117, 5096, 11556, 11560, 5148, 5127, 11556, 11560, 5179, 5158, 11556, 11560, 5210, 5189, 11556, 11560, 5245, 5224, 11556, 11560, 5276, 5255, 11556, 11560, 5307, 5286, 11556, 11560, 5338, 5317, 11556, 11560, 5373, 5352, 11556, 11560, 5404, 5383, 11556, 11560, 5435, 5414, 11556, 11560, 5466, 5445, 11556, 11560, 5501, 5480, 11556, 11560, 5532, 5511, 11556, 11560, 5563, 5542, 11556, 11560, 5594, 5573, 11556, 11560, 5629, 5608, 11556, 11560, 5660, 5639, 11556, 11560, 5691, 5670, 11556, 11560, 5722, 5701, 11556, 11560, 5757, 5736, 11556, 11560, 5788, 5767, 11556, 11560, 5819, 5798, 11556, 11560, 5850, 5829, 11556, 11560, 5885, 5864, 11556, 11560, 5916, 5895, 11556, 11560, 5947, 5926, 11556, 11560, 5978, 5957, 11556, 11560, 6013, 5992, 11556, 11560, 6044, 6023, 11556, 11560, 6075, 6054, 11556, 11560, 6106, 6085, 11556, 11560, 6141, 6120, 11556, 11560, 6172, 6151, 11556, 11560, 6203, 6182, 11556, 11560, 3432, 3432)
// Primitives.kt:1359 $kotlin.Int__toString-impl (8, 20)
// Number2String.kt:191 $kotlin.wasm.internal.<init properties Number2String.kt>
// Number2String.kt:192 $kotlin.wasm.internal.<init properties Number2String.kt>
// Number2String.kt:193 $kotlin.wasm.internal.<init properties Number2String.kt>
// Number2String.kt:194 $kotlin.wasm.internal.<init properties Number2String.kt>
// Number2String.kt:195 $kotlin.wasm.internal.<init properties Number2String.kt>
// Number2String.kt:196 $kotlin.wasm.internal.<init properties Number2String.kt>
// Number2String.kt:198 $kotlin.wasm.internal.<init properties Number2String.kt>
// Library.kt:93 $kotlin.wasm.internal.<init properties Number2String.kt> (2619, 2619, 2619, 2619, 3210, 3210, 3210, 3210, 3231, 3210, 11556, 11560, 3262, 3241, 11556, 11560, 3293, 3272, 11556, 11560, 3324, 3303, 11556, 11560, 3359, 3338, 11556, 11560, 3390, 3369, 11556, 11560, 3421, 3400, 11556, 11560, 3452, 3431, 11556, 11560, 3487, 3466, 11556, 11560, 3518, 3497, 11556, 11560, 3549, 3528, 11556, 11560, 3580, 3559, 11556, 11560, 3615, 3594, 11556, 11560, 3646, 3625, 11556, 11560, 3677, 3656, 11556, 11560, 3708, 3687, 11556, 11560, 3743, 3722, 11556, 11560, 3774, 3753, 11556, 11560, 3805, 3784, 11556, 11560, 3836, 3815, 11556, 11560, 3871, 3850, 11556, 11560, 3902, 3881, 11556, 11560, 3933, 3912, 11556, 11560, 3964, 3943, 11556, 11560, 3999, 3978, 11556, 11560, 4030, 4009, 11556, 11560, 4061, 4040, 11556, 11560, 4092, 4071, 11556, 11560, 4127, 4106, 11556, 11560, 4158, 4137, 11556, 11560, 4189, 4168, 11556, 11560, 4220, 4199, 11556, 11560, 4255, 4234, 11556, 11560, 4286, 4265, 11556, 11560, 4317, 4296, 11556, 11560, 4348, 4327, 11556, 11560, 4383, 4362, 11556, 11560, 4414, 4393, 11556, 11560, 4445, 4424, 11556, 11560, 4476, 4455, 11556, 11560, 4511, 4490, 11556, 11560, 4542, 4521, 11556, 11560, 4573, 4552, 11556, 11560, 4604, 4583, 11556, 11560, 4639, 4618, 11556, 11560, 4670, 4649, 11556, 11560, 4701, 4680, 11556, 11560, 4732, 4711, 11556, 11560, 4767, 4746, 11556, 11560, 4798, 4777, 11556, 11560, 4829, 4808, 11556, 11560, 4860, 4839, 11556, 11560, 4895, 4874, 11556, 11560, 4926, 4905, 11556, 11560, 4957, 4936, 11556, 11560, 4988, 4967, 11556, 11560, 5023, 5002, 11556, 11560, 5054, 5033, 11556, 11560, 5085, 5064, 11556, 11560, 5116, 5095, 11556, 11560, 5151, 5130, 11556, 11560, 5182, 5161, 11556, 11560, 5213, 5192, 11556, 11560, 5244, 5223, 11556, 11560, 5279, 5258, 11556, 11560, 5310, 5289, 11556, 11560, 5341, 5320, 11556, 11560, 5372, 5351, 11556, 11560, 5407, 5386, 11556, 11560, 5438, 5417, 11556, 11560, 5469, 5448, 11556, 11560, 5500, 5479, 11556, 11560, 5535, 5514, 11556, 11560, 5566, 5545, 11556, 11560, 5597, 5576, 11556, 11560, 5628, 5607, 11556, 11560, 5663, 5642, 11556, 11560, 5694, 5673, 11556, 11560, 5725, 5704, 11556, 11560, 5756, 5735, 11556, 11560, 5791, 5770, 11556, 11560, 5822, 5801, 11556, 11560, 5853, 5832, 11556, 11560, 5884, 5863, 11556, 11560, 5919, 5898, 11556, 11560, 5950, 5929, 11556, 11560, 5981, 5960, 11556, 11560, 3210, 3210)
// Library.kt:69 $kotlin.wasm.internal.<init properties Number2String.kt> (69, 77)
// Number2String.kt:219 $kotlin.wasm.internal.<init properties Number2String.kt>
// Number2String.kt:211 $kotlin.wasm.internal.<init properties Number2String.kt>
// ULong.kt:17 $kotlin.<ULong__<get-data>-impl> (125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125)
// Library.kt:54 $kotlin.wasm.internal.<init properties Number2String.kt> (66, 74)
// Number2String.kt:47 $kotlin.wasm.internal.itoa32 (8, 16, 8, 21, 29, 21)
// Number2String.kt:50 $kotlin.wasm.internal.itoa32 (8, 17, 8, 8)
// Number2String.kt:53 $kotlin.wasm.internal.itoa32 (8, 22, 8)
// Number2String.kt:55 $kotlin.wasm.internal.itoa32 (8, 26, 8)
// Number2String.kt:57 $kotlin.wasm.internal.itoa32 (15, 31, 15)
// Number2String.kt:58 $kotlin.wasm.internal.itoa32 (11, 19, 11, 24, 32, 24, 4)
// Assertions.kt:14 $kotlin.assert (11, 18, 4, 11, 18, 4, 11, 18, 4, 11, 18, 4, 11, 18, 4)
// Assertions.kt:21 $kotlin.assert (9, 8, 9, 8, 9, 8, 9, 8, 9, 8)
// Assertions.kt:25 $kotlin.assert (1, 1, 1, 1, 1)
// Assertions.kt:15 $kotlin.assert (1, 1, 1, 1, 1)
// Number2String.kt:59 $kotlin.wasm.internal.itoa32 (23, 31, 23, 51)
// Number2String.kt:61 $kotlin.wasm.internal.itoa32 (34, 19, 46, 19)
// Number2String.kt:107 $kotlin.wasm.internal.decimalCount32 (8, 16, 8)
// Number2String.kt:108 $kotlin.wasm.internal.decimalCount32 (12, 20, 12)
// Number2String.kt:109 $kotlin.wasm.internal.decimalCount32 (19, 24, 33, 24, 19, 12)
// Number2String.kt:62 $kotlin.wasm.internal.itoa32 (28, 14)
// Number2String.kt:63 $kotlin.wasm.internal.itoa32 (18, 23, 33, 4)
// Number2String.kt:71 $kotlin.wasm.internal.utoaDecSimple (11, 23, 11, 11, 4)
// Number2String.kt:72 $kotlin.wasm.internal.utoaDecSimple (11, 18, 26, 11, 4)
// Number2String.kt:73 $kotlin.wasm.internal.utoaDecSimple (11, 25, 11, 30, 45, 52, 30, 4)
// Number2String.kt:75 $kotlin.wasm.internal.utoaDecSimple (14, 4)
// Number2String.kt:76 $kotlin.wasm.internal.utoaDecSimple (17, 4)
// Number2String.kt:78 $kotlin.wasm.internal.utoaDecSimple (16, 22, 16, 8)
// Primitives.kt:1066 $kotlin.Int__div-impl (24, 12, 69, 96)
// Number2String.kt:79 $kotlin.wasm.internal.utoaDecSimple (16, 22, 16, 8)
// Number2String.kt:80 $kotlin.wasm.internal.utoaDecSimple (14, 8)
// Number2String.kt:81 $kotlin.wasm.internal.utoaDecSimple
// Number2String.kt:48 $kotlin.wasm.internal.itoa32 (8, 22, 8)
// Number2String.kt:50 $kotlin.wasm.internal.itoa32 (21, 34, 21)
// Number2String.kt:51 $kotlin.wasm.internal.itoa32 (23, 52, 4)
// Number2String.kt:52 $kotlin.wasm.internal.itoa32 (41, 25, 4)
// UInt.kt:36 $kotlin.wasm.internal.itoa32
// UInt.kt:414 $kotlin.wasm.internal.itoa32 (44, 39, 49)
// UInt.kt:17 $kotlin.<UInt__<init>-impl>
// Number2String.kt:58 $kotlin.wasm.internal.utoa32 (8, 22, 8)
// Number2String.kt:60 $kotlin.wasm.internal.utoa32 (34, 19)
// Number2String.kt:105 $kotlin.wasm.internal.decimalCount32 (8, 8, 8)
// UInt.kt:68 $kotlin.wasm.internal.decimalCount32 (4, 12, 35, 43, 75, 84)
// UInt.kt:64 $kotlin.wasm.internal.decimalCount32 (70, 82, 87, 93, 99, 104, 70, 82, 87, 93, 99, 104, 70, 82, 87, 93, 99, 104)
// UInt.kt:17 $kotlin.<UInt__<get-data>-impl> (124, 124, 124, 124, 124, 124, 124, 124, 124)
// UInt.kt:31 $kotlin.wasm.internal.decimalCount32 (65, 69, 46, 72, 65, 69, 46, 72, 65, 69, 46, 72)
// WasmMath.kt:16 $kotlin.wasm.internal.wasm_u32_compareTo (18, 21, 4, 48, 51, 34, 4, 61, 18, 21, 4, 48, 51, 34, 4, 61, 18, 21, 4, 48, 51, 34, 4, 61, 18, 21, 4, 48, 51, 34, 4, 61)
// Number2String.kt:106 $kotlin.wasm.internal.decimalCount32 (12, 12, 12)
// Number2String.kt:107 $kotlin.wasm.internal.decimalCount32 (19, 24, 24, 24, 19, 12)
// Number2String.kt:61 $kotlin.wasm.internal.utoa32 (28, 14)
// Number2String.kt:63 $kotlin.wasm.internal.utoa32 (18, 23, 35, 4)
// Number2String.kt:69 $kotlin.wasm.internal.utoaDecSimple (11, 23, 11, 11, 4)
// Assertions.kt:14 $kotlin.assert (11, 18, 4, 11, 18, 4, 11, 18, 4, 11, 18, 4)
// Assertions.kt:21 $kotlin.assert (9, 8, 9, 8, 9, 8, 9, 8)
// Assertions.kt:25 $kotlin.assert (1, 1, 1, 1)
// Assertions.kt:15 $kotlin.assert (1, 1, 1, 1)
// Number2String.kt:70 $kotlin.wasm.internal.utoaDecSimple (11, 18, 26, 11, 4)
// Number2String.kt:71 $kotlin.wasm.internal.utoaDecSimple (11, 25, 11, 30, 45, 52, 30, 4)
// Number2String.kt:73 $kotlin.wasm.internal.utoaDecSimple (14, 4)
// Number2String.kt:74 $kotlin.wasm.internal.utoaDecSimple (17, 4)
// Number2String.kt:76 $kotlin.wasm.internal.utoaDecSimple (16, 8)
// UInt.kt:51 $kotlin.wasm.internal.utoaDecSimple (75, 81, 101, 107)
// UInt.kt:121 $kotlin.wasm.internal.utoaDecSimple (67, 73, 56, 79)
// Number2String.kt:77 $kotlin.wasm.internal.utoaDecSimple (16, 8)
// UInt.kt:146 $kotlin.wasm.internal.utoaDecSimple (70, 76, 56, 82)
// Number2String.kt:78 $kotlin.wasm.internal.utoaDecSimple (14, 8)
// Number2String.kt:79 $kotlin.wasm.internal.utoaDecSimple
// Primitives.kt:1159 $kotlin.Int__dec-impl (15, 8, 16)
// Number2String.kt:82 $kotlin.wasm.internal.utoaDecSimple (8, 19, 39, 27, 15)
// Number2String.kt:41 $kotlin.wasm.internal.digitToChar (20, 11, 23, 11, 4)
// Number2String.kt:9 $kotlin.wasm.internal.CharCodes_initEntries
// Number2String.kt:80 $kotlin.wasm.internal.utoaDecSimple (8, 19, 41, 27, 15)
// UInt.kt:54 $kotlin.wasm.internal.utoaDecSimple (3, 28)
// UInt.kt:313 $kotlin.wasm.internal.utoaDecSimple (37, 41)
// Number2String.kt:43 $kotlin.wasm.internal.digitToChar (20, 11, 23, 11, 4)
// Number2String.kt:11 $kotlin.wasm.internal.CharCodes_initEntries
// Enum.kt:9 $kotlin.Enum.<init> (4, 4, 4, 4, 4)
// Enum.kt:11 $kotlin.Enum.<init> (4, 4, 4, 4, 4)
// Enum.kt:27 $kotlin.Enum.<init> (1, 1, 1, 1, 1)
// Number2String.kt:7 $kotlin.wasm.internal.CharCodes.<init> (29, 29, 29, 29, 29)
// Number2String.kt:38 $kotlin.wasm.internal.CharCodes.<init> (1, 1, 1, 1, 1)
// Number2String.kt:10 $kotlin.wasm.internal.CharCodes_initEntries
// Number2String.kt:11 $kotlin.wasm.internal.CharCodes_initEntries
// Number2String.kt:9 $kotlin.wasm.internal.CharCodes.<init> (29, 29, 29, 29, 29)
// Number2String.kt:40 $kotlin.wasm.internal.CharCodes.<init> (1, 1, 1, 1, 1)
// Number2String.kt:12 $kotlin.wasm.internal.CharCodes_initEntries
// Number2String.kt:32 $kotlin.wasm.internal.CharCodes_initEntries
// Number2String.kt:42 $kotlin.wasm.internal.digitToChar (25, 32, 12, 39, 4)
// Number2String.kt:13 $kotlin.wasm.internal.CharCodes_initEntries
// Number2String.kt:14 $kotlin.wasm.internal.CharCodes_initEntries
// Number2String.kt:34 $kotlin.wasm.internal.CharCodes_initEntries
// Number2String.kt:44 $kotlin.wasm.internal.digitToChar (25, 32, 12, 39, 4)
// Primitives.kt:1306 $kotlin.Int__toChar-impl (18, 9, 45)
// Number2String.kt:83 $kotlin.wasm.internal.utoaDecSimple (13, 19, 13, 13)
// Number2String.kt:84 $kotlin.wasm.internal.utoaDecSimple
// Number2String.kt:64 $kotlin.wasm.internal.itoa32 (8, 16, 8)
// Number2String.kt:67 $kotlin.wasm.internal.itoa32 (15, 4)
// String.kt:46 $kotlin.wasm.internal.itoa32
// String.kt:138 $kotlin.wasm.internal.itoa32 (4, 4, 4, 4, 11, 17, 22, 29, 4, 34)
// Number2String.kt:81 $kotlin.wasm.internal.utoaDecSimple (13, 13, 13, 13)
// UInt.kt:55 $kotlin.wasm.internal.utoaDecSimple
// UInt.kt:64 $kotlin.wasm.internal.utoaDecSimple (70, 82, 87, 93, 99, 104)
// UInt.kt:31 $kotlin.wasm.internal.utoaDecSimple (65, 69, 46, 72)
// Number2String.kt:82 $kotlin.wasm.internal.utoaDecSimple
// Number2String.kt:65 $kotlin.wasm.internal.utoa32 (15, 4)
// String.kt:44 $kotlin.wasm.internal.utoa32
// String.kt:138 $kotlin.wasm.internal.utoa32 (4, 4, 4, 4, 11, 17, 22, 29, 4, 34)
// Number2String.kt:54 $kotlin.wasm.internal.itoa32 (15, 51, 4)
// StringBuilderWasm.kt:53 $kotlin.text.insertInt (17, 29, 4)
// StringBuilderWasm.kt:54 $kotlin.text.insertInt (17, 24, 31, 44, 47, 4, 4)
// StringBuilderWasm.kt:55 $kotlin.text.insertInt (11, 4)
@@ -35,49 +35,59 @@ fun box() {
// test.kt:9 $box (8, 4)
// test.kt:10 $box (9, 8)
// test.kt:11 $box (12, 14, 8)
// Primitives.kt:1359 $kotlin.Int__toString-impl (21, 8, 24)
// Number2String.kt:199 $kotlin.wasm.internal.<init properties Number2String.kt>
// Number2String.kt:200 $kotlin.wasm.internal.<init properties Number2String.kt>
// Number2String.kt:201 $kotlin.wasm.internal.<init properties Number2String.kt>
// Number2String.kt:202 $kotlin.wasm.internal.<init properties Number2String.kt>
// Number2String.kt:203 $kotlin.wasm.internal.<init properties Number2String.kt>
// Number2String.kt:204 $kotlin.wasm.internal.<init properties Number2String.kt>
// Number2String.kt:206 $kotlin.wasm.internal.<init properties Number2String.kt>
// Library.kt:93 $kotlin.wasm.internal.<init properties Number2String.kt> (2841, 2841, 2841, 2841, 3432, 3432, 3432, 3432, 3453, 3432, 11556, 11560, 3484, 3463, 11556, 11560, 3515, 3494, 11556, 11560, 3546, 3525, 11556, 11560, 3581, 3560, 11556, 11560, 3612, 3591, 11556, 11560, 3643, 3622, 11556, 11560, 3674, 3653, 11556, 11560, 3709, 3688, 11556, 11560, 3740, 3719, 11556, 11560, 3771, 3750, 11556, 11560, 3802, 3781, 11556, 11560, 3837, 3816, 11556, 11560, 3868, 3847, 11556, 11560, 3899, 3878, 11556, 11560, 3930, 3909, 11556, 11560, 3965, 3944, 11556, 11560, 3996, 3975, 11556, 11560, 4027, 4006, 11556, 11560, 4058, 4037, 11556, 11560, 4093, 4072, 11556, 11560, 4124, 4103, 11556, 11560, 4155, 4134, 11556, 11560, 4186, 4165, 11556, 11560, 4221, 4200, 11556, 11560, 4252, 4231, 11556, 11560, 4283, 4262, 11556, 11560, 4314, 4293, 11556, 11560, 4349, 4328, 11556, 11560, 4380, 4359, 11556, 11560, 4411, 4390, 11556, 11560, 4442, 4421, 11556, 11560, 4477, 4456, 11556, 11560, 4508, 4487, 11556, 11560, 4539, 4518, 11556, 11560, 4570, 4549, 11556, 11560, 4605, 4584, 11556, 11560, 4636, 4615, 11556, 11560, 4667, 4646, 11556, 11560, 4698, 4677, 11556, 11560, 4733, 4712, 11556, 11560, 4764, 4743, 11556, 11560, 4795, 4774, 11556, 11560, 4826, 4805, 11556, 11560, 4861, 4840, 11556, 11560, 4892, 4871, 11556, 11560, 4923, 4902, 11556, 11560, 4954, 4933, 11556, 11560, 4989, 4968, 11556, 11560, 5020, 4999, 11556, 11560, 5051, 5030, 11556, 11560, 5082, 5061, 11556, 11560, 5117, 5096, 11556, 11560, 5148, 5127, 11556, 11560, 5179, 5158, 11556, 11560, 5210, 5189, 11556, 11560, 5245, 5224, 11556, 11560, 5276, 5255, 11556, 11560, 5307, 5286, 11556, 11560, 5338, 5317, 11556, 11560, 5373, 5352, 11556, 11560, 5404, 5383, 11556, 11560, 5435, 5414, 11556, 11560, 5466, 5445, 11556, 11560, 5501, 5480, 11556, 11560, 5532, 5511, 11556, 11560, 5563, 5542, 11556, 11560, 5594, 5573, 11556, 11560, 5629, 5608, 11556, 11560, 5660, 5639, 11556, 11560, 5691, 5670, 11556, 11560, 5722, 5701, 11556, 11560, 5757, 5736, 11556, 11560, 5788, 5767, 11556, 11560, 5819, 5798, 11556, 11560, 5850, 5829, 11556, 11560, 5885, 5864, 11556, 11560, 5916, 5895, 11556, 11560, 5947, 5926, 11556, 11560, 5978, 5957, 11556, 11560, 6013, 5992, 11556, 11560, 6044, 6023, 11556, 11560, 6075, 6054, 11556, 11560, 6106, 6085, 11556, 11560, 6141, 6120, 11556, 11560, 6172, 6151, 11556, 11560, 6203, 6182, 11556, 11560, 3432, 3432)
// Primitives.kt:1359 $kotlin.Int__toString-impl (8, 20)
// Number2String.kt:191 $kotlin.wasm.internal.<init properties Number2String.kt>
// Number2String.kt:192 $kotlin.wasm.internal.<init properties Number2String.kt>
// Number2String.kt:193 $kotlin.wasm.internal.<init properties Number2String.kt>
// Number2String.kt:194 $kotlin.wasm.internal.<init properties Number2String.kt>
// Number2String.kt:195 $kotlin.wasm.internal.<init properties Number2String.kt>
// Number2String.kt:196 $kotlin.wasm.internal.<init properties Number2String.kt>
// Number2String.kt:198 $kotlin.wasm.internal.<init properties Number2String.kt>
// Library.kt:93 $kotlin.wasm.internal.<init properties Number2String.kt> (2619, 2619, 2619, 2619, 3210, 3210, 3210, 3210, 3231, 3210, 11556, 11560, 3262, 3241, 11556, 11560, 3293, 3272, 11556, 11560, 3324, 3303, 11556, 11560, 3359, 3338, 11556, 11560, 3390, 3369, 11556, 11560, 3421, 3400, 11556, 11560, 3452, 3431, 11556, 11560, 3487, 3466, 11556, 11560, 3518, 3497, 11556, 11560, 3549, 3528, 11556, 11560, 3580, 3559, 11556, 11560, 3615, 3594, 11556, 11560, 3646, 3625, 11556, 11560, 3677, 3656, 11556, 11560, 3708, 3687, 11556, 11560, 3743, 3722, 11556, 11560, 3774, 3753, 11556, 11560, 3805, 3784, 11556, 11560, 3836, 3815, 11556, 11560, 3871, 3850, 11556, 11560, 3902, 3881, 11556, 11560, 3933, 3912, 11556, 11560, 3964, 3943, 11556, 11560, 3999, 3978, 11556, 11560, 4030, 4009, 11556, 11560, 4061, 4040, 11556, 11560, 4092, 4071, 11556, 11560, 4127, 4106, 11556, 11560, 4158, 4137, 11556, 11560, 4189, 4168, 11556, 11560, 4220, 4199, 11556, 11560, 4255, 4234, 11556, 11560, 4286, 4265, 11556, 11560, 4317, 4296, 11556, 11560, 4348, 4327, 11556, 11560, 4383, 4362, 11556, 11560, 4414, 4393, 11556, 11560, 4445, 4424, 11556, 11560, 4476, 4455, 11556, 11560, 4511, 4490, 11556, 11560, 4542, 4521, 11556, 11560, 4573, 4552, 11556, 11560, 4604, 4583, 11556, 11560, 4639, 4618, 11556, 11560, 4670, 4649, 11556, 11560, 4701, 4680, 11556, 11560, 4732, 4711, 11556, 11560, 4767, 4746, 11556, 11560, 4798, 4777, 11556, 11560, 4829, 4808, 11556, 11560, 4860, 4839, 11556, 11560, 4895, 4874, 11556, 11560, 4926, 4905, 11556, 11560, 4957, 4936, 11556, 11560, 4988, 4967, 11556, 11560, 5023, 5002, 11556, 11560, 5054, 5033, 11556, 11560, 5085, 5064, 11556, 11560, 5116, 5095, 11556, 11560, 5151, 5130, 11556, 11560, 5182, 5161, 11556, 11560, 5213, 5192, 11556, 11560, 5244, 5223, 11556, 11560, 5279, 5258, 11556, 11560, 5310, 5289, 11556, 11560, 5341, 5320, 11556, 11560, 5372, 5351, 11556, 11560, 5407, 5386, 11556, 11560, 5438, 5417, 11556, 11560, 5469, 5448, 11556, 11560, 5500, 5479, 11556, 11560, 5535, 5514, 11556, 11560, 5566, 5545, 11556, 11560, 5597, 5576, 11556, 11560, 5628, 5607, 11556, 11560, 5663, 5642, 11556, 11560, 5694, 5673, 11556, 11560, 5725, 5704, 11556, 11560, 5756, 5735, 11556, 11560, 5791, 5770, 11556, 11560, 5822, 5801, 11556, 11560, 5853, 5832, 11556, 11560, 5884, 5863, 11556, 11560, 5919, 5898, 11556, 11560, 5950, 5929, 11556, 11560, 5981, 5960, 11556, 11560, 3210, 3210)
// Library.kt:69 $kotlin.wasm.internal.<init properties Number2String.kt> (69, 77)
// Number2String.kt:219 $kotlin.wasm.internal.<init properties Number2String.kt>
// Number2String.kt:211 $kotlin.wasm.internal.<init properties Number2String.kt>
// ULong.kt:17 $kotlin.<ULong__<get-data>-impl> (125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125)
// Library.kt:54 $kotlin.wasm.internal.<init properties Number2String.kt> (66, 74)
// Number2String.kt:47 $kotlin.wasm.internal.itoa32 (8, 16, 8, 21, 29, 21)
// Number2String.kt:50 $kotlin.wasm.internal.itoa32 (8, 17, 8, 8)
// Number2String.kt:53 $kotlin.wasm.internal.itoa32 (8, 22, 8)
// Number2String.kt:55 $kotlin.wasm.internal.itoa32 (8, 26, 8)
// Number2String.kt:57 $kotlin.wasm.internal.itoa32 (15, 31, 15)
// Number2String.kt:58 $kotlin.wasm.internal.itoa32 (11, 19, 11, 24, 32, 24, 4)
// Assertions.kt:14 $kotlin.assert (11, 18, 4, 11, 18, 4, 11, 18, 4, 11, 18, 4, 11, 18, 4, 11, 18, 4)
// Assertions.kt:21 $kotlin.assert (9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8)
// Assertions.kt:25 $kotlin.assert (1, 1, 1, 1, 1, 1)
// Assertions.kt:15 $kotlin.assert (1, 1, 1, 1, 1, 1)
// Number2String.kt:59 $kotlin.wasm.internal.itoa32 (23, 31, 23, 51)
// Number2String.kt:61 $kotlin.wasm.internal.itoa32 (34, 19, 46, 19)
// Number2String.kt:107 $kotlin.wasm.internal.decimalCount32 (8, 16, 8)
// Number2String.kt:108 $kotlin.wasm.internal.decimalCount32 (12, 20, 12)
// Number2String.kt:109 $kotlin.wasm.internal.decimalCount32 (19, 24, 33, 24, 19, 12)
// Number2String.kt:62 $kotlin.wasm.internal.itoa32 (28, 14)
// Number2String.kt:63 $kotlin.wasm.internal.itoa32 (18, 23, 33, 4)
// Number2String.kt:71 $kotlin.wasm.internal.utoaDecSimple (11, 23, 11, 11, 4)
// Number2String.kt:72 $kotlin.wasm.internal.utoaDecSimple (11, 18, 26, 11, 4)
// Number2String.kt:73 $kotlin.wasm.internal.utoaDecSimple (11, 25, 11, 30, 45, 52, 30, 4)
// Number2String.kt:75 $kotlin.wasm.internal.utoaDecSimple (14, 4)
// Number2String.kt:76 $kotlin.wasm.internal.utoaDecSimple (17, 4)
// Number2String.kt:78 $kotlin.wasm.internal.utoaDecSimple (16, 22, 16, 8, 16, 22, 16, 8)
// Primitives.kt:1066 $kotlin.Int__div-impl (24, 12, 69, 96, 24, 12, 69, 96)
// Number2String.kt:79 $kotlin.wasm.internal.utoaDecSimple (16, 22, 16, 8, 16, 22, 16, 8)
// Number2String.kt:80 $kotlin.wasm.internal.utoaDecSimple (14, 8, 14, 8)
// Number2String.kt:81 $kotlin.wasm.internal.utoaDecSimple (8, 8)
// Number2String.kt:48 $kotlin.wasm.internal.itoa32 (8, 22, 8)
// Number2String.kt:50 $kotlin.wasm.internal.itoa32 (21, 34, 21)
// Number2String.kt:51 $kotlin.wasm.internal.itoa32 (23, 52, 4)
// Number2String.kt:52 $kotlin.wasm.internal.itoa32 (41, 25, 4)
// UInt.kt:36 $kotlin.wasm.internal.itoa32
// UInt.kt:414 $kotlin.wasm.internal.itoa32 (44, 39, 49)
// UInt.kt:17 $kotlin.<UInt__<init>-impl>
// Number2String.kt:58 $kotlin.wasm.internal.utoa32 (8, 22, 8)
// Number2String.kt:60 $kotlin.wasm.internal.utoa32 (34, 19)
// Number2String.kt:105 $kotlin.wasm.internal.decimalCount32 (8, 8, 8)
// UInt.kt:68 $kotlin.wasm.internal.decimalCount32 (4, 12, 35, 43, 75, 84)
// UInt.kt:64 $kotlin.wasm.internal.decimalCount32 (70, 82, 87, 93, 99, 104, 70, 82, 87, 93, 99, 104, 70, 82, 87, 93, 99, 104)
// UInt.kt:17 $kotlin.<UInt__<get-data>-impl> (124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124)
// UInt.kt:31 $kotlin.wasm.internal.decimalCount32 (65, 69, 46, 72, 65, 69, 46, 72, 65, 69, 46, 72)
// WasmMath.kt:16 $kotlin.wasm.internal.wasm_u32_compareTo (18, 21, 4, 48, 51, 34, 4, 61, 18, 21, 4, 48, 51, 34, 4, 61, 18, 21, 4, 48, 51, 34, 4, 61, 18, 21, 4, 48, 51, 34, 4, 61, 18, 21, 4, 48, 51, 34, 4, 61)
// Number2String.kt:106 $kotlin.wasm.internal.decimalCount32 (12, 12, 12)
// Number2String.kt:107 $kotlin.wasm.internal.decimalCount32 (19, 24, 24, 24, 19, 12)
// Number2String.kt:61 $kotlin.wasm.internal.utoa32 (28, 14)
// Number2String.kt:63 $kotlin.wasm.internal.utoa32 (18, 23, 35, 4)
// Number2String.kt:69 $kotlin.wasm.internal.utoaDecSimple (11, 23, 11, 11, 4)
// Assertions.kt:14 $kotlin.assert (11, 18, 4, 11, 18, 4, 11, 18, 4, 11, 18, 4, 11, 18, 4)
// Assertions.kt:21 $kotlin.assert (9, 8, 9, 8, 9, 8, 9, 8, 9, 8)
// Assertions.kt:25 $kotlin.assert (1, 1, 1, 1, 1)
// Assertions.kt:15 $kotlin.assert (1, 1, 1, 1, 1)
// Number2String.kt:70 $kotlin.wasm.internal.utoaDecSimple (11, 18, 26, 11, 4)
// Number2String.kt:71 $kotlin.wasm.internal.utoaDecSimple (11, 25, 11, 30, 45, 52, 30, 4)
// Number2String.kt:73 $kotlin.wasm.internal.utoaDecSimple (14, 4)
// Number2String.kt:74 $kotlin.wasm.internal.utoaDecSimple (17, 4)
// Number2String.kt:76 $kotlin.wasm.internal.utoaDecSimple (16, 8, 16, 8)
// UInt.kt:51 $kotlin.wasm.internal.utoaDecSimple (75, 81, 101, 107, 75, 81, 101, 107)
// UInt.kt:121 $kotlin.wasm.internal.utoaDecSimple (67, 73, 56, 79, 67, 73, 56, 79)
// Number2String.kt:77 $kotlin.wasm.internal.utoaDecSimple (16, 8, 16, 8)
// UInt.kt:146 $kotlin.wasm.internal.utoaDecSimple (70, 76, 56, 82, 70, 76, 56, 82)
// Number2String.kt:78 $kotlin.wasm.internal.utoaDecSimple (14, 8, 14, 8)
// Number2String.kt:79 $kotlin.wasm.internal.utoaDecSimple (8, 8)
// Primitives.kt:1159 $kotlin.Int__dec-impl (15, 8, 16, 15, 8, 16)
// Number2String.kt:82 $kotlin.wasm.internal.utoaDecSimple (8, 19, 39, 27, 15, 8, 19, 39, 27, 15)
// Number2String.kt:41 $kotlin.wasm.internal.digitToChar (20, 11, 23, 11, 4, 20, 11, 23, 11, 4)
// Number2String.kt:80 $kotlin.wasm.internal.utoaDecSimple (8, 19, 41, 27, 15, 8, 19, 41, 27, 15)
// UInt.kt:54 $kotlin.wasm.internal.utoaDecSimple (3, 28, 3, 28)
// UInt.kt:313 $kotlin.wasm.internal.utoaDecSimple (37, 41, 37, 41)
// Number2String.kt:43 $kotlin.wasm.internal.digitToChar (20, 11, 23, 11, 4, 20, 11, 23, 11, 4)
// String.kt:141 $kotlin.stringLiteral (17, 28, 17, 17, 28, 17, 17, 28, 17, 17, 28, 17, 17, 28, 17)
// Array.kt:59 $kotlin.Array.get (19, 26, 34, 8, 19, 26, 34, 8, 19, 26, 34, 8, 19, 26, 34, 8, 19, 26, 34, 8)
// ThrowHelpers.kt:29 $kotlin.wasm.internal.rangeCheck (6, 14, 6, 19, 28, 19, 6, 14, 6, 19, 28, 19, 6, 14, 6, 19, 28, 19, 6, 14, 6, 19, 28, 19, 6, 14, 6, 19, 28, 19, 6, 14, 6, 19, 28, 19, 6, 14, 6, 19, 28, 19, 6, 14, 6, 19, 28, 19, 6, 14, 6, 19, 28, 19, 6, 14, 6, 19, 28, 19)
@@ -91,22 +101,25 @@ fun box() {
// Array.kt:75 $kotlin.Array.set (8, 20, 27, 16, 8, 20, 27, 16, 8, 20, 27, 16, 8, 20, 27, 16, 8, 20, 27, 16)
// Array.kt:76 $kotlin.Array.set (5, 5, 5, 5, 5)
// String.kt:149 $kotlin.stringLiteral (11, 4, 11, 4, 11, 4, 11, 4, 11, 4)
// Number2String.kt:9 $kotlin.wasm.internal.CharCodes_initEntries
// Number2String.kt:11 $kotlin.wasm.internal.CharCodes_initEntries
// Enum.kt:9 $kotlin.Enum.<init> (4, 4, 4, 4, 4)
// Enum.kt:11 $kotlin.Enum.<init> (4, 4, 4, 4, 4)
// Enum.kt:27 $kotlin.Enum.<init> (1, 1, 1, 1, 1)
// Number2String.kt:7 $kotlin.wasm.internal.CharCodes.<init> (29, 29, 29, 29, 29)
// Number2String.kt:38 $kotlin.wasm.internal.CharCodes.<init> (1, 1, 1, 1, 1)
// Number2String.kt:10 $kotlin.wasm.internal.CharCodes_initEntries
// Number2String.kt:11 $kotlin.wasm.internal.CharCodes_initEntries
// Number2String.kt:9 $kotlin.wasm.internal.CharCodes.<init> (29, 29, 29, 29, 29)
// Number2String.kt:40 $kotlin.wasm.internal.CharCodes.<init> (1, 1, 1, 1, 1)
// Number2String.kt:12 $kotlin.wasm.internal.CharCodes_initEntries
// Number2String.kt:32 $kotlin.wasm.internal.CharCodes_initEntries
// Number2String.kt:42 $kotlin.wasm.internal.digitToChar (25, 32, 12, 39, 4, 25, 32, 12, 39, 4)
// Number2String.kt:13 $kotlin.wasm.internal.CharCodes_initEntries
// Number2String.kt:14 $kotlin.wasm.internal.CharCodes_initEntries
// Number2String.kt:34 $kotlin.wasm.internal.CharCodes_initEntries
// Number2String.kt:44 $kotlin.wasm.internal.digitToChar (25, 32, 12, 39, 4, 25, 32, 12, 39, 4)
// Primitives.kt:1306 $kotlin.Int__toChar-impl (18, 9, 45, 18, 9, 45)
// Number2String.kt:83 $kotlin.wasm.internal.utoaDecSimple (13, 19, 13, 13, 13, 19, 13, 13)
// Number2String.kt:84 $kotlin.wasm.internal.utoaDecSimple
// Number2String.kt:64 $kotlin.wasm.internal.itoa32 (8, 16, 8)
// Number2String.kt:67 $kotlin.wasm.internal.itoa32 (15, 4)
// String.kt:46 $kotlin.wasm.internal.itoa32
// String.kt:138 $kotlin.wasm.internal.itoa32 (4, 4, 4, 4, 11, 17, 22, 29, 4, 34)
// Number2String.kt:81 $kotlin.wasm.internal.utoaDecSimple (13, 13, 13, 13, 13, 13, 13, 13)
// UInt.kt:55 $kotlin.wasm.internal.utoaDecSimple (2, 2)
// UInt.kt:64 $kotlin.wasm.internal.utoaDecSimple (70, 82, 87, 93, 99, 104, 70, 82, 87, 93, 99, 104)
// UInt.kt:31 $kotlin.wasm.internal.utoaDecSimple (65, 69, 46, 72, 65, 69, 46, 72)
// Number2String.kt:82 $kotlin.wasm.internal.utoaDecSimple
// Number2String.kt:65 $kotlin.wasm.internal.utoa32 (15, 4)
// String.kt:44 $kotlin.wasm.internal.utoa32
// String.kt:138 $kotlin.wasm.internal.utoa32 (4, 4, 4, 4, 11, 17, 22, 29, 4, 34)
// Number2String.kt:54 $kotlin.wasm.internal.itoa32 (15, 51, 4)
// test.kt:13 $box
@@ -17,7 +17,10 @@ import java.io.File
class IrInterpreterHelpersSourceFilesProvider(testServices: TestServices) : AdditionalSourceProvider(testServices) {
companion object {
private const val HELPERS_PATH = "./compiler/testData/ir/interpreter/helpers"
private const val UNSIGNED_PATH = "./libraries/stdlib/unsigned/src/kotlin"
private val UNSIGNED_PATH = arrayOf(
"./libraries/stdlib/unsigned/src/kotlin",
"./libraries/stdlib/jvm/src/kotlin/util/UnsignedJVM.kt"
)
private val RUNTIME_PATHS = arrayOf(
"./libraries/stdlib/src/kotlin/ranges/Progressions.kt",
"./libraries/stdlib/src/kotlin/ranges/ProgressionIterators.kt",
@@ -60,6 +63,12 @@ class IrInterpreterHelpersSourceFilesProvider(testServices: TestServices) : Addi
}
override fun produceAdditionalFiles(globalDirectives: RegisteredDirectives, module: TestModule): List<TestFile> {
return getTestFilesForEachDirectory(HELPERS_PATH, UNSIGNED_PATH, *RUNTIME_PATHS, *ANNOTATIONS_PATHS, REFLECT_PATH)
return getTestFilesForEachDirectory(
HELPERS_PATH,
*UNSIGNED_PATH,
*RUNTIME_PATHS,
*ANNOTATIONS_PATHS,
REFLECT_PATH
)
}
}
@@ -234,7 +234,7 @@ class WasmPrimitivesGenerator(writer: PrintWriter) : BasePrimitivesGenerator(wri
override fun MethodBuilder.modifyGeneratedToString(thisKind: PrimitiveType) {
when (thisKind) {
in PrimitiveType.floatingPoint -> "dtoa(this${thisKind.castToIfNecessary(PrimitiveType.DOUBLE)})"
PrimitiveType.INT, PrimitiveType.LONG -> "itoa${thisKind.bitSize}(this, 10)"
PrimitiveType.INT, PrimitiveType.LONG -> "itoa${thisKind.bitSize}(this)"
else -> "this.toInt().toString()"
}.setAsExpressionBody()
}
+29 -26
View File
@@ -19,7 +19,7 @@ fun generateUnsignedTypes(
targetDir: File,
generate: (File, (PrintWriter) -> BuiltInsSourceGenerator) -> Unit
) {
for (type in UnsignedType.values()) {
for (type in UnsignedType.entries) {
generate(File(targetDir, "kotlin/${type.capitalized}.kt")) { UnsignedTypeGenerator(type, it) }
generate(File(targetDir, "kotlin/${type.capitalized}Array.kt")) { UnsignedArrayGenerator(type, it) }
}
@@ -30,8 +30,8 @@ fun generateUnsignedTypes(
}
class UnsignedTypeGenerator(val type: UnsignedType, out: PrintWriter) : BuiltInsSourceGenerator(out) {
val className = type.capitalized
val storageType = type.asSigned.capitalized
private val className = type.capitalized
private val storageType = type.asSigned.capitalized
internal fun binaryOperatorDoc(operator: String, operand1: UnsignedType, operand2: UnsignedType): String = when (operator) {
"floorDiv" ->
@@ -119,7 +119,7 @@ class UnsignedTypeGenerator(val type: UnsignedType, out: PrintWriter) : BuiltIns
private fun generateCompareTo() {
for (otherType in UnsignedType.values()) {
for (otherType in UnsignedType.entries) {
out.println("""
/**
* Compares this value with the specified value for order.
@@ -155,7 +155,7 @@ class UnsignedTypeGenerator(val type: UnsignedType, out: PrintWriter) : BuiltIns
}
private fun generateOperator(name: String) {
for (otherType in UnsignedType.values()) {
for (otherType in UnsignedType.entries) {
val returnType = getOperatorReturnType(type, otherType)
out.printDoc(binaryOperatorDoc(name, type, otherType), " ")
@@ -176,7 +176,7 @@ class UnsignedTypeGenerator(val type: UnsignedType, out: PrintWriter) : BuiltIns
}
private fun generateFloorDivMod(name: String) {
for (otherType in UnsignedType.values()) {
for (otherType in UnsignedType.entries) {
val operationType = getOperatorReturnType(type, otherType)
val returnType = if (name == "mod") otherType else operationType
@@ -299,14 +299,16 @@ class UnsignedTypeGenerator(val type: UnsignedType, out: PrintWriter) : BuiltIns
out.println(" @kotlin.internal.InlineOnly")
out.print(" public inline fun to$signed(): $signed = ")
out.println(when {
type == UnsignedType.UINT && otherType == UnsignedType.ULONG -> "uintToLong(data)"
otherType < type -> "data.to$signed()"
otherType == type -> "data"
else -> "data.to$signed() and ${type.mask}"
})
}
)
}
out.println()
for (otherType in UnsignedType.values()) {
for (otherType in UnsignedType.entries) {
val name = otherType.capitalized
if (type == otherType)
@@ -332,11 +334,14 @@ class UnsignedTypeGenerator(val type: UnsignedType, out: PrintWriter) : BuiltIns
out.println(" @kotlin.internal.InlineOnly")
out.print(" public inline fun to$name(): $name = ")
out.println(when {
out.println(
when {
type == UnsignedType.UINT && otherType == UnsignedType.ULONG -> "uintToULong(data)"
otherType > type -> "${otherType.capitalized}(data.to${otherType.asSigned.capitalized}() and ${type.mask})"
otherType == type -> "this"
else -> "data.to${otherType.capitalized}()"
})
}
)
}
out.println()
}
@@ -359,16 +364,16 @@ class UnsignedTypeGenerator(val type: UnsignedType, out: PrintWriter) : BuiltIns
out.print(" public inline fun to$otherName(): $otherName = ")
when (type) {
UnsignedType.UINT, UnsignedType.ULONG ->
out.println(if (otherType == PrimitiveType.FLOAT) "this.toDouble().toFloat()" else className.lowercase() + "ToDouble(data)")
out.println(className.lowercase() + "To$otherName(data)")
else ->
out.println("this.toInt().to$otherName()")
out.println("uintTo$otherName(this.toInt())")
}
}
out.println()
}
private fun generateExtensionConversions() {
for (otherType in UnsignedType.values()) {
for (otherType in UnsignedType.entries) {
val otherSigned = otherType.asSigned.capitalized
val thisSigned = type.asSigned.capitalized
@@ -424,18 +429,16 @@ class UnsignedTypeGenerator(val type: UnsignedType, out: PrintWriter) : BuiltIns
out.println("@WasExperimental(ExperimentalUnsignedTypes::class)")
out.println("@kotlin.internal.InlineOnly")
out.print("public inline fun $otherName.to$className(): $className = ")
val conversion = if (otherType == PrimitiveType.DOUBLE) "" else ".toDouble()"
out.println("doubleTo$className(this$conversion)")
out.println("${otherName.lowercase()}To$className(this)")
}
}
private fun generateToStringHashCode() {
out.print(" public override fun toString(): String = ")
when (type) {
UnsignedType.UBYTE, UnsignedType.USHORT -> out.println("toInt().toString()")
UnsignedType.UINT -> out.println("toLong().toString()")
UnsignedType.UINT -> out.println("uintToString(data)")
UnsignedType.ULONG -> out.println("ulongToString(data)")
}
@@ -455,11 +458,11 @@ class UnsignedTypeGenerator(val type: UnsignedType, out: PrintWriter) : BuiltIns
class UnsignedArrayGenerator(val type: UnsignedType, out: PrintWriter) : BuiltInsSourceGenerator(out) {
val elementType = type.capitalized
val arrayType = elementType + "Array"
val arrayTypeOf = elementType.lowercase() + "ArrayOf"
val storageElementType = type.asSigned.capitalized
val storageArrayType = storageElementType + "Array"
private val elementType = type.capitalized
private val arrayType = elementType + "Array"
private val arrayTypeOf = elementType.lowercase() + "ArrayOf"
private val storageElementType = type.asSigned.capitalized
private val storageArrayType = storageElementType + "Array"
override fun generateBody() {
out.println("import kotlin.jvm.*")
out.println()
@@ -548,10 +551,10 @@ public inline fun $arrayTypeOf(vararg elements: $elementType): $arrayType = elem
}
class UnsignedRangeGenerator(val type: UnsignedType, out: PrintWriter) : BuiltInsSourceGenerator(out) {
val elementType = type.capitalized
val signedType = type.asSigned.capitalized
val stepType = signedType
val stepMinValue = "$stepType.MIN_VALUE"
private val elementType = type.capitalized
private val signedType = type.asSigned.capitalized
private val stepType = signedType
private val stepMinValue = "$stepType.MIN_VALUE"
override fun getPackage(): String = "kotlin.ranges"
@@ -1,25 +1,24 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@file:kotlin.jvm.JvmName("UnsignedKt")
package kotlin
@PublishedApi
internal fun uintCompare(v1: Int, v2: Int): Int = (v1 xor Int.MIN_VALUE).compareTo(v2 xor Int.MIN_VALUE)
@PublishedApi
internal fun ulongCompare(v1: Long, v2: Long): Int = (v1 xor Long.MIN_VALUE).compareTo(v2 xor Long.MIN_VALUE)
@PublishedApi
internal fun uintDivide(v1: UInt, v2: UInt): UInt = (v1.toLong() / v2.toLong()).toUInt()
@PublishedApi
internal fun uintRemainder(v1: UInt, v2: UInt): UInt = (v1.toLong() % v2.toLong()).toUInt()
import kotlin.internal.InlineOnly
// CHANGES IN THIS FILE SHOULD BE SYNCED WITH THE SAME CHANGES IN: UnsignedJVM.kt and UnsignedJs.kt
// Division and remainder are based on Guava's UnsignedLongs implementation
// Copyright 2011 The Guava Authors
@PublishedApi
internal fun ulongDivide(v1: ULong, v2: ULong): ULong {
internal actual fun uintRemainder(v1: UInt, v2: UInt): UInt = (v1.toLong() % v2.toLong()).toUInt()
@PublishedApi
internal actual fun uintDivide(v1: UInt, v2: UInt): UInt = (v1.toLong() / v2.toLong()).toUInt()
@PublishedApi
internal actual fun ulongDivide(v1: ULong, v2: ULong): ULong {
val dividend = v1.toLong()
val divisor = v2.toLong()
if (divisor < 0) { // i.e., divisor >= 2^63:
@@ -39,7 +38,7 @@ internal fun ulongDivide(v1: ULong, v2: ULong): ULong {
}
@PublishedApi
internal fun ulongRemainder(v1: ULong, v2: ULong): ULong {
internal actual fun ulongRemainder(v1: ULong, v2: ULong): ULong {
val dividend = v1.toLong()
val divisor = v2.toLong()
if (divisor < 0) { // i.e., divisor >= 2^63:
@@ -62,44 +61,78 @@ internal fun ulongRemainder(v1: ULong, v2: ULong): ULong {
}
@PublishedApi
internal fun doubleToUInt(v: Double): UInt = when {
v.isNaN() -> 0u
v <= UInt.MIN_VALUE.toDouble() -> UInt.MIN_VALUE
v >= UInt.MAX_VALUE.toDouble() -> UInt.MAX_VALUE
v <= Int.MAX_VALUE -> v.toInt().toUInt()
else -> (v - Int.MAX_VALUE).toInt().toUInt() + Int.MAX_VALUE.toUInt() // Int.MAX_VALUE < v < UInt.MAX_VALUE
internal actual fun uintCompare(v1: Int, v2: Int): Int = (v1 xor Int.MIN_VALUE).compareTo(v2 xor Int.MIN_VALUE)
@PublishedApi
internal actual fun ulongCompare(v1: Long, v2: Long): Int = (v1 xor Long.MIN_VALUE).compareTo(v2 xor Long.MIN_VALUE)
@PublishedApi
@InlineOnly
internal actual inline fun uintToULong(value: Int): ULong = ULong(uintToLong(value))
@PublishedApi
@InlineOnly
internal actual inline fun uintToLong(value: Int): Long = value.toLong() and 0xFFFF_FFFF
@PublishedApi
@InlineOnly
internal actual inline fun uintToFloat(value: Int): Float = uintToDouble(value).toFloat()
@PublishedApi
@InlineOnly
internal actual inline fun floatToUInt(value: Float): UInt = doubleToUInt(value.toDouble())
@PublishedApi
internal actual fun uintToDouble(value: Int): Double = (value and Int.MAX_VALUE).toDouble() + (value ushr 31 shl 30).toDouble() * 2
@PublishedApi
internal actual fun doubleToUInt(value: Double): UInt = when {
value.isNaN() -> 0u
value <= UInt.MIN_VALUE.toDouble() -> UInt.MIN_VALUE
value >= UInt.MAX_VALUE.toDouble() -> UInt.MAX_VALUE
value <= Int.MAX_VALUE -> value.toInt().toUInt()
else -> (value - Int.MAX_VALUE).toInt().toUInt() + Int.MAX_VALUE.toUInt() // Int.MAX_VALUE < v < UInt.MAX_VALUE
}
@PublishedApi
internal fun doubleToULong(v: Double): ULong = when {
v.isNaN() -> 0u
v <= ULong.MIN_VALUE.toDouble() -> ULong.MIN_VALUE
v >= ULong.MAX_VALUE.toDouble() -> ULong.MAX_VALUE
v < Long.MAX_VALUE -> v.toLong().toULong()
@InlineOnly
internal actual inline fun ulongToFloat(value: Long): Float = ulongToDouble(value).toFloat()
@PublishedApi
@InlineOnly
internal actual inline fun floatToULong(value: Float): ULong = doubleToULong(value.toDouble())
@PublishedApi
internal actual fun ulongToDouble(value: Long): Double = (value ushr 11).toDouble() * 2048 + (value and 2047)
@PublishedApi
internal actual fun doubleToULong(value: Double): ULong = when {
value.isNaN() -> 0u
value <= ULong.MIN_VALUE.toDouble() -> ULong.MIN_VALUE
value >= ULong.MAX_VALUE.toDouble() -> ULong.MAX_VALUE
value < Long.MAX_VALUE -> value.toLong().toULong()
// Real values from Long.MAX_VALUE to (Long.MAX_VALUE + 1) are not representable in Double, so don't handle them.
else -> (v - 9223372036854775808.0).toLong().toULong() + 9223372036854775808uL // Long.MAX_VALUE + 1 < v < ULong.MAX_VALUE
else -> (value - 9223372036854775808.0).toLong().toULong() + 9223372036854775808uL // Long.MAX_VALUE + 1 < v < ULong.MAX_VALUE
}
@InlineOnly
internal actual inline fun uintToString(value: Int): String = uintToLong(value).toString()
@PublishedApi
internal fun uintToDouble(v: Int): Double = (v and Int.MAX_VALUE).toDouble() + (v ushr 31 shl 30).toDouble() * 2
@InlineOnly
internal actual inline fun uintToString(value: Int, base: Int): String = ulongToString(uintToLong(value), base)
@PublishedApi
internal fun ulongToDouble(v: Long): Double = (v ushr 11).toDouble() * 2048 + (v and 2047)
@InlineOnly
internal actual inline fun ulongToString(value: Long): String = ulongToString(value, 10)
internal actual fun ulongToString(value: Long, base: Int): String {
if (value >= 0) return value.toString(base)
internal fun ulongToString(v: Long): String = ulongToString(v, 10)
internal fun ulongToString(v: Long, base: Int): String {
if (v >= 0) return v.toString(base)
var quotient = ((v ushr 1) / base) shl 1
var rem = v - quotient * base
var quotient = ((value ushr 1) / base) shl 1
var rem = value - quotient * base
if (rem >= base) {
rem -= base
quotient += 1
}
return quotient.toString(base) + rem.toString(base)
}
+71 -37
View File
@@ -1,25 +1,25 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@file:kotlin.jvm.JvmName("UnsignedKt")
package kotlin
@PublishedApi
internal fun uintCompare(v1: Int, v2: Int): Int = (v1 xor Int.MIN_VALUE).compareTo(v2 xor Int.MIN_VALUE)
@PublishedApi
internal fun ulongCompare(v1: Long, v2: Long): Int = (v1 xor Long.MIN_VALUE).compareTo(v2 xor Long.MIN_VALUE)
@PublishedApi
internal fun uintDivide(v1: UInt, v2: UInt): UInt = (v1.toLong() / v2.toLong()).toUInt()
@PublishedApi
internal fun uintRemainder(v1: UInt, v2: UInt): UInt = (v1.toLong() % v2.toLong()).toUInt()
import kotlin.internal.InlineOnly
// CHANGES IN THIS FILE SHOULD BE SYNCED WITH THE SAME CHANGES IN: UnsignedJVM.kt and kotlin-native/Unsigned.kt
// Division and remainder are based on Guava's UnsignedLongs implementation
// Copyright 2011 The Guava Authors
@PublishedApi
internal fun ulongDivide(v1: ULong, v2: ULong): ULong {
internal actual fun uintRemainder(v1: UInt, v2: UInt): UInt = (v1.toLong() % v2.toLong()).toUInt()
@PublishedApi
internal actual fun uintDivide(v1: UInt, v2: UInt): UInt = (v1.toLong() / v2.toLong()).toUInt()
@PublishedApi
internal actual fun ulongDivide(v1: ULong, v2: ULong): ULong {
val dividend = v1.toLong()
val divisor = v2.toLong()
if (divisor < 0) { // i.e., divisor >= 2^63:
@@ -39,7 +39,7 @@ internal fun ulongDivide(v1: ULong, v2: ULong): ULong {
}
@PublishedApi
internal fun ulongRemainder(v1: ULong, v2: ULong): ULong {
internal actual fun ulongRemainder(v1: ULong, v2: ULong): ULong {
val dividend = v1.toLong()
val divisor = v2.toLong()
if (divisor < 0) { // i.e., divisor >= 2^63:
@@ -62,44 +62,78 @@ internal fun ulongRemainder(v1: ULong, v2: ULong): ULong {
}
@PublishedApi
internal fun doubleToUInt(v: Double): UInt = when {
v.isNaN() -> 0u
v <= UInt.MIN_VALUE.toDouble() -> UInt.MIN_VALUE
v >= UInt.MAX_VALUE.toDouble() -> UInt.MAX_VALUE
v <= Int.MAX_VALUE -> v.toInt().toUInt()
else -> (v - Int.MAX_VALUE).toInt().toUInt() + Int.MAX_VALUE.toUInt() // Int.MAX_VALUE < v < UInt.MAX_VALUE
internal actual fun uintCompare(v1: Int, v2: Int): Int = (v1 xor Int.MIN_VALUE).compareTo(v2 xor Int.MIN_VALUE)
@PublishedApi
internal actual fun ulongCompare(v1: Long, v2: Long): Int = (v1 xor Long.MIN_VALUE).compareTo(v2 xor Long.MIN_VALUE)
@PublishedApi
@InlineOnly
internal actual inline fun uintToULong(value: Int): ULong = ULong(uintToLong(value))
@PublishedApi
@InlineOnly
internal actual inline fun uintToLong(value: Int): Long = value.toLong() and 0xFFFF_FFFF
@PublishedApi
@InlineOnly
internal actual inline fun uintToFloat(value: Int): Float = uintToDouble(value).toFloat()
@PublishedApi
@InlineOnly
internal actual inline fun floatToUInt(value: Float): UInt = doubleToUInt(value.toDouble())
@PublishedApi
internal actual fun uintToDouble(value: Int): Double = (value and Int.MAX_VALUE).toDouble() + (value ushr 31 shl 30).toDouble() * 2
@PublishedApi
internal actual fun doubleToUInt(value: Double): UInt = when {
value.isNaN() -> 0u
value <= UInt.MIN_VALUE.toDouble() -> UInt.MIN_VALUE
value >= UInt.MAX_VALUE.toDouble() -> UInt.MAX_VALUE
value <= Int.MAX_VALUE -> value.toInt().toUInt()
else -> (value - Int.MAX_VALUE).toInt().toUInt() + Int.MAX_VALUE.toUInt() // Int.MAX_VALUE < v < UInt.MAX_VALUE
}
@PublishedApi
internal fun doubleToULong(v: Double): ULong = when {
v.isNaN() -> 0u
v <= ULong.MIN_VALUE.toDouble() -> ULong.MIN_VALUE
v >= ULong.MAX_VALUE.toDouble() -> ULong.MAX_VALUE
v < Long.MAX_VALUE -> v.toLong().toULong()
@InlineOnly
internal actual inline fun ulongToFloat(value: Long): Float = ulongToDouble(value).toFloat()
@PublishedApi
@InlineOnly
internal actual inline fun floatToULong(value: Float): ULong = doubleToULong(value.toDouble())
@PublishedApi
internal actual fun ulongToDouble(value: Long): Double = (value ushr 11).toDouble() * 2048 + (value and 2047)
@PublishedApi
internal actual fun doubleToULong(value: Double): ULong = when {
value.isNaN() -> 0u
value <= ULong.MIN_VALUE.toDouble() -> ULong.MIN_VALUE
value >= ULong.MAX_VALUE.toDouble() -> ULong.MAX_VALUE
value < Long.MAX_VALUE -> value.toLong().toULong()
// Real values from Long.MAX_VALUE to (Long.MAX_VALUE + 1) are not representable in Double, so don't handle them.
else -> (v - 9223372036854775808.0).toLong().toULong() + 9223372036854775808uL // Long.MAX_VALUE + 1 < v < ULong.MAX_VALUE
else -> (value - 9223372036854775808.0).toLong().toULong() + 9223372036854775808uL // Long.MAX_VALUE + 1 < v < ULong.MAX_VALUE
}
@InlineOnly
internal actual inline fun uintToString(value: Int): String = uintToLong(value).toString()
@PublishedApi
internal fun uintToDouble(v: Int): Double = (v and Int.MAX_VALUE).toDouble() + (v ushr 31 shl 30).toDouble() * 2
@InlineOnly
internal actual inline fun uintToString(value: Int, base: Int): String = ulongToString(uintToLong(value), base)
@PublishedApi
internal fun ulongToDouble(v: Long): Double = (v ushr 11).toDouble() * 2048 + (v and 2047)
@InlineOnly
internal actual inline fun ulongToString(value: Long): String = ulongToString(value, 10)
internal actual fun ulongToString(value: Long, base: Int): String {
if (value >= 0) return value.toString(base)
internal fun ulongToString(v: Long): String = ulongToString(v, 10)
internal fun ulongToString(v: Long, base: Int): String {
if (v >= 0) return v.toString(base)
var quotient = ((v ushr 1) / base) shl 1
var rem = v - quotient * base
var quotient = ((value ushr 1) / base) shl 1
var rem = value - quotient * base
if (rem >= base) {
rem -= base
quotient += 1
}
return quotient.toString(base) + rem.toString(base)
}
@@ -1,25 +1,24 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@file:kotlin.jvm.JvmName("UnsignedKt")
package kotlin
@PublishedApi
internal fun uintCompare(v1: Int, v2: Int): Int = (v1 xor Int.MIN_VALUE).compareTo(v2 xor Int.MIN_VALUE)
@PublishedApi
internal fun ulongCompare(v1: Long, v2: Long): Int = (v1 xor Long.MIN_VALUE).compareTo(v2 xor Long.MIN_VALUE)
@PublishedApi
internal fun uintDivide(v1: UInt, v2: UInt): UInt = (v1.toLong() / v2.toLong()).toUInt()
@PublishedApi
internal fun uintRemainder(v1: UInt, v2: UInt): UInt = (v1.toLong() % v2.toLong()).toUInt()
import kotlin.internal.InlineOnly
// CHANGES IN THIS FILE SHOULD BE SYNCED WITH THE SAME CHANGES IN: UnsignedJs.kt and kotlin-native/Unsigned.kt
// Division and remainder are based on Guava's UnsignedLongs implementation
// Copyright 2011 The Guava Authors
@PublishedApi
internal fun ulongDivide(v1: ULong, v2: ULong): ULong {
internal actual fun uintRemainder(v1: UInt, v2: UInt): UInt = (v1.toLong() % v2.toLong()).toUInt()
@PublishedApi
internal actual fun uintDivide(v1: UInt, v2: UInt): UInt = (v1.toLong() / v2.toLong()).toUInt()
@PublishedApi
internal actual fun ulongDivide(v1: ULong, v2: ULong): ULong {
val dividend = v1.toLong()
val divisor = v2.toLong()
if (divisor < 0) { // i.e., divisor >= 2^63:
@@ -39,7 +38,7 @@ internal fun ulongDivide(v1: ULong, v2: ULong): ULong {
}
@PublishedApi
internal fun ulongRemainder(v1: ULong, v2: ULong): ULong {
internal actual fun ulongRemainder(v1: ULong, v2: ULong): ULong {
val dividend = v1.toLong()
val divisor = v2.toLong()
if (divisor < 0) { // i.e., divisor >= 2^63:
@@ -62,44 +61,78 @@ internal fun ulongRemainder(v1: ULong, v2: ULong): ULong {
}
@PublishedApi
internal fun doubleToUInt(v: Double): UInt = when {
v.isNaN() -> 0u
v <= UInt.MIN_VALUE.toDouble() -> UInt.MIN_VALUE
v >= UInt.MAX_VALUE.toDouble() -> UInt.MAX_VALUE
v <= Int.MAX_VALUE -> v.toInt().toUInt()
else -> (v - Int.MAX_VALUE).toInt().toUInt() + Int.MAX_VALUE.toUInt() // Int.MAX_VALUE < v < UInt.MAX_VALUE
internal actual fun uintCompare(v1: Int, v2: Int): Int = (v1 xor Int.MIN_VALUE).compareTo(v2 xor Int.MIN_VALUE)
@PublishedApi
internal actual fun ulongCompare(v1: Long, v2: Long): Int = (v1 xor Long.MIN_VALUE).compareTo(v2 xor Long.MIN_VALUE)
@PublishedApi
@InlineOnly
internal actual inline fun uintToULong(value: Int): ULong = ULong(uintToLong(value))
@PublishedApi
@InlineOnly
internal actual inline fun uintToLong(value: Int): Long = value.toLong() and 0xFFFF_FFFF
@PublishedApi
@InlineOnly
internal actual inline fun uintToFloat(value: Int): Float = uintToDouble(value).toFloat()
@PublishedApi
@InlineOnly
internal actual inline fun floatToUInt(value: Float): UInt = doubleToUInt(value.toDouble())
@PublishedApi
internal actual fun uintToDouble(value: Int): Double = (value and Int.MAX_VALUE).toDouble() + (value ushr 31 shl 30).toDouble() * 2
@PublishedApi
internal actual fun doubleToUInt(value: Double): UInt = when {
value.isNaN() -> 0u
value <= UInt.MIN_VALUE.toDouble() -> UInt.MIN_VALUE
value >= UInt.MAX_VALUE.toDouble() -> UInt.MAX_VALUE
value <= Int.MAX_VALUE -> value.toInt().toUInt()
else -> (value - Int.MAX_VALUE).toInt().toUInt() + Int.MAX_VALUE.toUInt() // Int.MAX_VALUE < v < UInt.MAX_VALUE
}
@PublishedApi
internal fun doubleToULong(v: Double): ULong = when {
v.isNaN() -> 0u
v <= ULong.MIN_VALUE.toDouble() -> ULong.MIN_VALUE
v >= ULong.MAX_VALUE.toDouble() -> ULong.MAX_VALUE
v < Long.MAX_VALUE -> v.toLong().toULong()
@InlineOnly
internal actual inline fun ulongToFloat(value: Long): Float = ulongToDouble(value).toFloat()
@PublishedApi
@InlineOnly
internal actual inline fun floatToULong(value: Float): ULong = doubleToULong(value.toDouble())
@PublishedApi
internal actual fun ulongToDouble(value: Long): Double = (value ushr 11).toDouble() * 2048 + (value and 2047)
@PublishedApi
internal actual fun doubleToULong(value: Double): ULong = when {
value.isNaN() -> 0u
value <= ULong.MIN_VALUE.toDouble() -> ULong.MIN_VALUE
value >= ULong.MAX_VALUE.toDouble() -> ULong.MAX_VALUE
value < Long.MAX_VALUE -> value.toLong().toULong()
// Real values from Long.MAX_VALUE to (Long.MAX_VALUE + 1) are not representable in Double, so don't handle them.
else -> (v - 9223372036854775808.0).toLong().toULong() + 9223372036854775808uL // Long.MAX_VALUE + 1 < v < ULong.MAX_VALUE
else -> (value - 9223372036854775808.0).toLong().toULong() + 9223372036854775808uL // Long.MAX_VALUE + 1 < v < ULong.MAX_VALUE
}
@InlineOnly
internal actual inline fun uintToString(value: Int): String = uintToLong(value).toString()
@PublishedApi
internal fun uintToDouble(v: Int): Double = (v and Int.MAX_VALUE).toDouble() + (v ushr 31 shl 30).toDouble() * 2
@InlineOnly
internal actual inline fun uintToString(value: Int, base: Int): String = ulongToString(uintToLong(value), base)
@PublishedApi
internal fun ulongToDouble(v: Long): Double = (v ushr 11).toDouble() * 2048 + (v and 2047)
@InlineOnly
internal actual inline fun ulongToString(value: Long): String = ulongToString(value, 10)
internal actual fun ulongToString(value: Long, base: Int): String {
if (value >= 0) return value.toString(base)
internal fun ulongToString(v: Long): String = ulongToString(v, 10)
internal fun ulongToString(v: Long, base: Int): String {
if (v >= 0) return v.toString(base)
var quotient = ((v ushr 1) / base) shl 1
var rem = v - quotient * base
var quotient = ((value ushr 1) / base) shl 1
var rem = value - quotient * base
if (rem >= base) {
rem -= base
quotient += 1
}
return quotient.toString(base) + rem.toString(base)
}
@@ -342,14 +342,14 @@ public value class UByte @kotlin.internal.IntrinsicConstEvaluation @PublishedApi
* The resulting `Float` value represents the same numerical value as this `UByte`.
*/
@kotlin.internal.InlineOnly
public inline fun toFloat(): Float = this.toInt().toFloat()
public inline fun toFloat(): Float = uintToFloat(this.toInt())
/**
* Converts this [UByte] value to [Double].
*
* The resulting `Double` value represents the same numerical value as this `UByte`.
*/
@kotlin.internal.InlineOnly
public inline fun toDouble(): Double = this.toInt().toDouble()
public inline fun toDouble(): Double = uintToDouble(this.toInt())
public override fun toString(): String = toInt().toString()
+5 -5
View File
@@ -320,7 +320,7 @@ public value class UInt @kotlin.internal.IntrinsicConstEvaluation @PublishedApi
* whereas the most significant 32 bits are filled with zeros.
*/
@kotlin.internal.InlineOnly
public inline fun toLong(): Long = data.toLong() and 0xFFFF_FFFF
public inline fun toLong(): Long = uintToLong(data)
/**
* Converts this [UInt] value to [UByte].
@@ -354,7 +354,7 @@ public value class UInt @kotlin.internal.IntrinsicConstEvaluation @PublishedApi
* whereas the most significant 32 bits are filled with zeros.
*/
@kotlin.internal.InlineOnly
public inline fun toULong(): ULong = ULong(data.toLong() and 0xFFFF_FFFF)
public inline fun toULong(): ULong = uintToULong(data)
/**
* Converts this [UInt] value to [Float].
@@ -364,7 +364,7 @@ public value class UInt @kotlin.internal.IntrinsicConstEvaluation @PublishedApi
* the one with zero at least significant bit of mantissa is selected.
*/
@kotlin.internal.InlineOnly
public inline fun toFloat(): Float = this.toDouble().toFloat()
public inline fun toFloat(): Float = uintToFloat(data)
/**
* Converts this [UInt] value to [Double].
*
@@ -373,7 +373,7 @@ public value class UInt @kotlin.internal.IntrinsicConstEvaluation @PublishedApi
@kotlin.internal.InlineOnly
public inline fun toDouble(): Double = uintToDouble(data)
public override fun toString(): String = toLong().toString()
public override fun toString(): String = uintToString(data)
}
@@ -434,7 +434,7 @@ public inline fun Long.toUInt(): UInt = UInt(this.toInt())
@SinceKotlin("1.5")
@WasExperimental(ExperimentalUnsignedTypes::class)
@kotlin.internal.InlineOnly
public inline fun Float.toUInt(): UInt = doubleToUInt(this.toDouble())
public inline fun Float.toUInt(): UInt = floatToUInt(this)
/**
* Converts this [Double] value to [UInt].
*
@@ -365,7 +365,7 @@ public value class ULong @kotlin.internal.IntrinsicConstEvaluation @PublishedApi
* the one with zero at least significant bit of mantissa is selected.
*/
@kotlin.internal.InlineOnly
public inline fun toFloat(): Float = this.toDouble().toFloat()
public inline fun toFloat(): Float = ulongToFloat(data)
/**
* Converts this [ULong] value to [Double].
*
@@ -437,7 +437,7 @@ public inline fun Long.toULong(): ULong = ULong(this)
@SinceKotlin("1.5")
@WasExperimental(ExperimentalUnsignedTypes::class)
@kotlin.internal.InlineOnly
public inline fun Float.toULong(): ULong = doubleToULong(this.toDouble())
public inline fun Float.toULong(): ULong = floatToULong(this)
/**
* Converts this [Double] value to [ULong].
*
@@ -343,14 +343,14 @@ public value class UShort @kotlin.internal.IntrinsicConstEvaluation @PublishedAp
* The resulting `Float` value represents the same numerical value as this `UShort`.
*/
@kotlin.internal.InlineOnly
public inline fun toFloat(): Float = this.toInt().toFloat()
public inline fun toFloat(): Float = uintToFloat(this.toInt())
/**
* Converts this [UShort] value to [Double].
*
* The resulting `Double` value represents the same numerical value as this `UShort`.
*/
@kotlin.internal.InlineOnly
public inline fun toDouble(): Double = this.toInt().toDouble()
public inline fun toDouble(): Double = uintToDouble(this.toInt())
public override fun toString(): String = toInt().toString()
@@ -36,7 +36,7 @@ public /*inline*/ fun UShort.toString(radix: Int): String = this.toInt().toStrin
@SinceKotlin("1.5")
@WasExperimental(ExperimentalUnsignedTypes::class)
//@kotlin.internal.InlineOnly
public /*inline*/ fun UInt.toString(radix: Int): String = this.toLong().toString(radix)
public /*inline*/ fun UInt.toString(radix: Int): String = uintToString(this.toInt(), checkRadix(radix))
/**
* Returns a string representation of this [Long] value in the specified [radix].
@@ -1,105 +1,62 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@file:kotlin.jvm.JvmName("UnsignedKt")
package kotlin
@PublishedApi
internal fun uintCompare(v1: Int, v2: Int): Int = (v1 xor Int.MIN_VALUE).compareTo(v2 xor Int.MIN_VALUE)
@PublishedApi
internal fun ulongCompare(v1: Long, v2: Long): Int = (v1 xor Long.MIN_VALUE).compareTo(v2 xor Long.MIN_VALUE)
internal expect fun uintRemainder(v1: UInt, v2: UInt): UInt
@PublishedApi
internal fun uintDivide(v1: UInt, v2: UInt): UInt = (v1.toLong() / v2.toLong()).toUInt()
@PublishedApi
internal fun uintRemainder(v1: UInt, v2: UInt): UInt = (v1.toLong() % v2.toLong()).toUInt()
// Division and remainder are based on Guava's UnsignedLongs implementation
// Copyright 2011 The Guava Authors
internal expect fun ulongRemainder(v1: ULong, v2: ULong): ULong
@PublishedApi
internal fun ulongDivide(v1: ULong, v2: ULong): ULong {
val dividend = v1.toLong()
val divisor = v2.toLong()
if (divisor < 0) { // i.e., divisor >= 2^63:
return if (v1 < v2) ULong(0) else ULong(1)
}
// Optimization - use signed division if both dividend and divisor < 2^63
if (dividend >= 0) {
return ULong(dividend / divisor)
}
// Otherwise, approximate the quotient, check, and correct if necessary.
val quotient = ((dividend ushr 1) / divisor) shl 1
val rem = dividend - quotient * divisor
return ULong(quotient + if (ULong(rem) >= ULong(divisor)) 1 else 0)
}
internal expect fun uintDivide(v1: UInt, v2: UInt): UInt
@PublishedApi
internal fun ulongRemainder(v1: ULong, v2: ULong): ULong {
val dividend = v1.toLong()
val divisor = v2.toLong()
if (divisor < 0) { // i.e., divisor >= 2^63:
return if (v1 < v2) {
v1 // dividend < divisor
} else {
v1 - v2 // dividend >= divisor
}
}
// Optimization - use signed modulus if both dividend and divisor < 2^63
if (dividend >= 0) {
return ULong(dividend % divisor)
}
// Otherwise, approximate the quotient, check, and correct if necessary.
val quotient = ((dividend ushr 1) / divisor) shl 1
val rem = dividend - quotient * divisor
return ULong(rem - if (ULong(rem) >= ULong(divisor)) divisor else 0)
}
internal expect fun ulongDivide(v1: ULong, v2: ULong): ULong
@PublishedApi
internal fun doubleToUInt(v: Double): UInt = when {
v.isNaN() -> 0u
v <= UInt.MIN_VALUE.toDouble() -> UInt.MIN_VALUE
v >= UInt.MAX_VALUE.toDouble() -> UInt.MAX_VALUE
v <= Int.MAX_VALUE -> v.toInt().toUInt()
else -> (v - Int.MAX_VALUE).toInt().toUInt() + Int.MAX_VALUE.toUInt() // Int.MAX_VALUE < v < UInt.MAX_VALUE
}
internal expect fun uintCompare(v1: Int, v2: Int): Int
@PublishedApi
internal fun doubleToULong(v: Double): ULong = when {
v.isNaN() -> 0u
v <= ULong.MIN_VALUE.toDouble() -> ULong.MIN_VALUE
v >= ULong.MAX_VALUE.toDouble() -> ULong.MAX_VALUE
v < Long.MAX_VALUE -> v.toLong().toULong()
// Real values from Long.MAX_VALUE to (Long.MAX_VALUE + 1) are not representable in Double, so don't handle them.
else -> (v - 9223372036854775808.0).toLong().toULong() + 9223372036854775808uL // Long.MAX_VALUE + 1 < v < ULong.MAX_VALUE
}
internal expect fun ulongCompare(v1: Long, v2: Long): Int
@PublishedApi
internal fun uintToDouble(v: Int): Double = (v and Int.MAX_VALUE).toDouble() + (v ushr 31 shl 30).toDouble() * 2
internal expect fun uintToULong(value: Int): ULong
@PublishedApi
internal fun ulongToDouble(v: Long): Double = (v ushr 11).toDouble() * 2048 + (v and 2047)
internal expect fun uintToLong(value: Int): Long
@PublishedApi
internal expect fun uintToFloat(value: Int): Float
internal fun ulongToString(v: Long): String = ulongToString(v, 10)
@PublishedApi
internal expect fun floatToUInt(value: Float): UInt
internal fun ulongToString(v: Long, base: Int): String {
if (v >= 0) return v.toString(base)
@PublishedApi
internal expect fun uintToDouble(value: Int): Double
var quotient = ((v ushr 1) / base) shl 1
var rem = v - quotient * base
if (rem >= base) {
rem -= base
quotient += 1
}
return quotient.toString(base) + rem.toString(base)
}
@PublishedApi
internal expect fun doubleToUInt(value: Double): UInt
@PublishedApi
internal expect fun ulongToFloat(value: Long): Float
@PublishedApi
internal expect fun floatToULong(value: Float): ULong
@PublishedApi
internal expect fun ulongToDouble(value: Long): Double
@PublishedApi
internal expect fun doubleToULong(value: Double): ULong
internal expect fun uintToString(value: Int): String
internal expect fun uintToString(value: Int, base: Int): String
internal expect fun ulongToString(value: Long): String
internal expect fun ulongToString(value: Long, base: Int): String
@@ -1356,7 +1356,7 @@ public class Int private constructor(private val value: Int) : Number(), Compara
@kotlin.internal.IntrinsicConstEvaluation
public override fun toString(): String =
itoa32(this, 10)
itoa32(this)
@kotlin.internal.IntrinsicConstEvaluation
public override fun equals(other: Any?): Boolean =
@@ -1865,7 +1865,7 @@ public class Long private constructor(private val value: Long) : Number(), Compa
@kotlin.internal.IntrinsicConstEvaluation
public override fun toString(): String =
itoa64(this, 10)
itoa64(this)
@kotlin.internal.IntrinsicConstEvaluation
public override fun equals(other: Any?): Boolean =
@@ -4,6 +4,8 @@
*/
package kotlin.wasm.internal
// Based on the AssemblyScript implementation [https://github.com/AssemblyScript/assemblyscript/blob/1e0466ef94fa5cacd0984e4f31a0087de51538a8/std/assembly/util/number.ts]
private enum class CharCodes(val code: Int) {
// PERCENT(0x25),
PLUS(0x2B),
@@ -42,125 +44,115 @@ private fun digitToChar(input: Int): Char {
return (CharCodes._0.code + input).toChar()
}
// Inspired by the AssemblyScript implementation
internal fun itoa32(inputValue: Int, radix: Int): String {
if (radix < 2 || radix > 36)
throw IllegalArgumentException("Radix argument is unreasonable")
if (radix != 10)
TODO("When we need it")
internal fun itoa32(inputValue: Int): String {
if (inputValue == 0) return "0"
// We can't represent abs(Int.MIN_VALUE), so just hardcode it here
if (inputValue == Int.MIN_VALUE) return "-2147483648"
val sign = inputValue ushr 31
assert(sign == 1 || sign == 0)
val absValue = if (sign == 1) -inputValue else inputValue
val isNegative = inputValue < 0
val absValue = if (isNegative) -inputValue else inputValue
val absValueString = utoa32(absValue.toUInt())
val decimals = decimalCount32(absValue) + sign
return if (isNegative) "-$absValueString" else absValueString
}
internal fun utoa32(inputValue: UInt): String {
if (inputValue == 0U) return "0"
val decimals = decimalCount32(inputValue)
val buf = WasmCharArray(decimals)
utoaDecSimple(buf, absValue, decimals)
if (sign == 1)
buf.set(0, CharCodes.MINUS.code.toChar())
utoaDecSimple(buf, inputValue, decimals)
return buf.createString()
}
private fun utoaDecSimple(buffer: WasmCharArray, numInput: Int, offsetInput: Int) {
assert(numInput != 0)
private fun utoaDecSimple(buffer: WasmCharArray, numInput: UInt, offsetInput: Int) {
assert(numInput != 0U)
assert(buffer.len() > 0)
assert(offsetInput > 0 && offsetInput <= buffer.len())
var num = numInput
var offset = offsetInput
do {
val t = num / 10
val r = num % 10
val t = num / 10U
val r = num % 10U
num = t
offset--
buffer.set(offset, digitToChar(r))
} while (num > 0)
buffer.set(offset, digitToChar(r.toInt()))
} while (num > 0U)
}
private fun utoaDecSimple64(buffer: WasmCharArray, numInput: Long, offsetInput: Int) {
assert(numInput != 0L)
private fun utoaDecSimple64(buffer: WasmCharArray, numInput: ULong, offsetInput: Int) {
assert(numInput != 0UL)
assert(buffer.len() > 0)
assert(offsetInput > 0 && offsetInput <= buffer.len())
var num = numInput
var offset = offsetInput
do {
val t = num / 10
val r = (num % 10).toInt()
val t = num / 10U
val r = num % 10U
num = t
offset--
buffer.set(offset, digitToChar(r))
} while (num > 0)
buffer.set(offset, digitToChar(r.toInt()))
} while (num > 0U)
}
private fun Boolean.toInt() = if (this) 1 else 0
private fun Boolean.toLong() = if (this) 1L else 0L
private fun decimalCount32(value: Int): Int {
if (value < 100000) {
if (value < 100) {
return 1 + (value >= 10).toInt()
private fun decimalCount32(value: UInt): Int {
if (value < 100000u) {
if (value < 100u) {
return 1 + (value >= 10u).toInt()
} else {
return 3 + (value >= 10000).toInt() + (value >= 1000).toInt()
return 3 + (value >= 10000u).toInt() + (value >= 1000u).toInt()
}
} else {
if (value < 10000000) {
return 6 + (value >= 1000000).toInt()
if (value < 10000000u) {
return 6 + (value >= 1000000u).toInt()
} else {
return 8 + (value >= 1000000000).toInt() + (value >= 100000000).toInt()
return 8 + (value >= 1000000000u).toInt() + (value >= 100000000u).toInt()
}
}
}
internal fun itoa64(inputValue: Long, radix: Int): String {
internal fun itoa64(inputValue: Long): String {
if (inputValue in Int.MIN_VALUE..Int.MAX_VALUE)
return itoa32(inputValue.toInt(), radix)
return itoa32(inputValue.toInt())
if (radix < 2 || radix > 36)
throw IllegalArgumentException("Radix argument is unreasonable")
val isNegative = inputValue < 0
val absValue = if (isNegative) -inputValue else inputValue
val absValueString = utoa64(absValue.toULong())
if (inputValue == 0L) return "0"
// We can't represent abs(Long.MIN_VALUE), so just hardcode it here
if (inputValue == Long.MIN_VALUE) return "-9223372036854775808"
return if (isNegative) "-$absValueString" else absValueString
}
if (radix != 10) {
TODO("When we need it")
}
internal fun utoa64(inputValue: ULong): String {
if (inputValue <= UInt.MAX_VALUE) return utoa32(inputValue.toUInt())
val sign = (inputValue ushr 63).toInt()
assert(sign == 1 || sign == 0)
val absValue = if (sign == 1) -inputValue else inputValue
val decimals = decimalCount64High(absValue) + sign
val decimals = decimalCount64High(inputValue)
val buf = WasmCharArray(decimals)
utoaDecSimple64(buf, absValue, decimals)
if (sign == 1)
buf.set(0, CharCodes.MINUS.code.toChar())
utoaDecSimple64(buf, inputValue, decimals)
return buf.createString()
}
// Count number of decimals for u64 values
// In our case input value always greater than 2^32-1 so we can skip some parts
private fun decimalCount64High(value: Long): Int {
if (value < 1000000000000000) {
if (value < 1000000000000) {
return 10 + (value >= 100000000000).toInt() + (value >= 10000000000).toInt()
private fun decimalCount64High(value: ULong): Int {
if (value < 1000000000000000UL) {
if (value < 1000000000000UL) {
return 10 + (value >= 100000000000UL).toInt() + (value >= 10000000000UL).toInt()
} else {
return 13 + (value >= 100000000000000).toInt() + (value >= 10000000000000).toInt()
return 13 + (value >= 100000000000000UL).toInt() + (value >= 10000000000000UL).toInt()
}
} else {
if (value < 100000000000000000) {
return 16 + (value >= 10000000000000000).toInt()
if (value < 100000000000000000UL) {
return 16 + (value >= 10000000000000000UL).toInt()
} else {
return 18 + (value >= 1000000000000000000).toInt()
return 18 + (value >= 10000000000000000000UL).toInt() + (value >= 1000000000000000000UL).toInt()
}
}
}
@@ -331,7 +323,7 @@ private fun genDigits(buffer: WasmCharArray, w_frc: Long, mp_frc: Long, mp_exp:
var p1 = (mp_frc ushr one_exp).toInt()
var p2 = mp_frc and mask
var kappa = decimalCount32(p1)
var kappa = decimalCount32(p1.toUInt())
var len = sign
while (kappa > 0) {
@@ -11,6 +11,14 @@ package kotlin.wasm.internal
internal fun wasm_i32_compareTo(x: Int, y: Int): Int =
wasm_i32_ge_s(x, y).toInt() - wasm_i32_le_s(x, y).toInt()
@PublishedApi
internal fun wasm_u32_compareTo(x: Int, y: Int): Int =
wasm_i32_ge_u(x, y).toInt() - wasm_i32_le_u(x, y).toInt()
@PublishedApi
internal fun wasm_i64_compareTo(x: Long, y: Long): Int =
wasm_i64_ge_s(x, y).toInt() - wasm_i64_le_s(x, y).toInt()
@PublishedApi
internal fun wasm_u64_compareTo(x: Long, y: Long): Int =
wasm_i64_ge_u(x, y).toInt() - wasm_i64_le_u(x, y).toInt()
@@ -5,7 +5,6 @@
package kotlin.text
import kotlin.math.abs
import kotlin.wasm.internal.wasm_f32_demote_f64
/**
@@ -103,7 +102,7 @@ public actual fun String.toDoubleOrNull(): Double? {
* @throws IllegalArgumentException when [radix] is not a valid radix for number to string conversion.
*/
@SinceKotlin("1.2")
public actual fun Byte.toString(radix: Int): String = this.toLong().toString(radix)
public actual fun Byte.toString(radix: Int): String = this.toInt().toString(radix)
/**
* Returns a string representation of this [Short] value in the specified [radix].
@@ -111,7 +110,7 @@ public actual fun Byte.toString(radix: Int): String = this.toLong().toString(rad
* @throws IllegalArgumentException when [radix] is not a valid radix for number to string conversion.
*/
@SinceKotlin("1.2")
public actual fun Short.toString(radix: Int): String = this.toLong().toString(radix)
public actual fun Short.toString(radix: Int): String = this.toInt().toString(radix)
/**
* Returns a string representation of this [Int] value in the specified [radix].
@@ -119,7 +118,13 @@ public actual fun Short.toString(radix: Int): String = this.toLong().toString(ra
* @throws IllegalArgumentException when [radix] is not a valid radix for number to string conversion.
*/
@SinceKotlin("1.2")
public actual fun Int.toString(radix: Int): String = toLong().toString(radix)
public actual fun Int.toString(radix: Int): String {
val isNegative = this < 0
val absValue = if (isNegative) -this else this
val absValueString = uintToString(absValue, checkRadix(radix))
return if (isNegative) "-$absValueString" else absValueString
}
/**
* Returns a string representation of this [Long] value in the specified [radix].
@@ -128,28 +133,9 @@ public actual fun Int.toString(radix: Int): String = toLong().toString(radix)
*/
@SinceKotlin("1.2")
public actual fun Long.toString(radix: Int): String {
checkRadix(radix)
fun Long.getChar() = toInt().let { if (it < 10) '0' + it else 'a' + (it - 10) }
if (radix == 10) return toString()
if (this in 0 until radix) return getChar().toString()
val isNegative = this < 0
val buffer = CharArray(Long.SIZE_BITS + 1)
val absValue = if (isNegative) -this else this
val absValueString = ulongToString(absValue, checkRadix(radix))
var currentBufferIndex = buffer.lastIndex
var current: Long = this
while(current != 0L) {
buffer[currentBufferIndex] = abs(current % radix).getChar()
current /= radix
currentBufferIndex--
}
if (isNegative) {
buffer[currentBufferIndex] = '-'
currentBufferIndex--
}
return buffer.concatToString(currentBufferIndex + 1)
return if (isNegative) "-$absValueString" else absValueString
}
@@ -1,105 +1,134 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@file:kotlin.jvm.JvmName("UnsignedKt")
package kotlin
@PublishedApi
internal fun uintCompare(v1: Int, v2: Int): Int = (v1 xor Int.MIN_VALUE).compareTo(v2 xor Int.MIN_VALUE)
@PublishedApi
internal fun ulongCompare(v1: Long, v2: Long): Int = (v1 xor Long.MIN_VALUE).compareTo(v2 xor Long.MIN_VALUE)
import kotlin.internal.InlineOnly
import kotlin.math.abs
import kotlin.wasm.internal.*
import kotlin.wasm.internal.WasmOp
import kotlin.wasm.internal.implementedAsIntrinsic
import kotlin.wasm.internal.wasm_u32_compareTo
@PublishedApi
internal fun uintDivide(v1: UInt, v2: UInt): UInt = (v1.toLong() / v2.toLong()).toUInt()
@PublishedApi
internal fun uintRemainder(v1: UInt, v2: UInt): UInt = (v1.toLong() % v2.toLong()).toUInt()
// Division and remainder are based on Guava's UnsignedLongs implementation
// Copyright 2011 The Guava Authors
@WasmOp(WasmOp.I32_REM_U)
internal actual fun uintRemainder(v1: UInt, v2: UInt): UInt = implementedAsIntrinsic
@PublishedApi
internal fun ulongDivide(v1: ULong, v2: ULong): ULong {
val dividend = v1.toLong()
val divisor = v2.toLong()
if (divisor < 0) { // i.e., divisor >= 2^63:
return if (v1 < v2) ULong(0) else ULong(1)
@WasmOp(WasmOp.I32_DIV_U)
internal actual fun uintDivide(v1: UInt, v2: UInt): UInt = implementedAsIntrinsic
@PublishedApi
@WasmOp(WasmOp.I64_REM_U)
internal actual fun ulongRemainder(v1: ULong, v2: ULong): ULong = implementedAsIntrinsic
@PublishedApi
@WasmOp(WasmOp.I64_DIV_U)
internal actual fun ulongDivide(v1: ULong, v2: ULong): ULong = implementedAsIntrinsic
@PublishedApi
@InlineOnly
internal actual inline fun uintCompare(v1: Int, v2: Int): Int = wasm_u32_compareTo(v1, v2)
@PublishedApi
@InlineOnly
internal actual inline fun ulongCompare(v1: Long, v2: Long): Int = wasm_u64_compareTo(v1, v2)
@PublishedApi
@WasmOp(WasmOp.I64_EXTEND_I32_U)
internal actual fun uintToULong(value: Int): ULong = implementedAsIntrinsic
@PublishedApi
@WasmOp(WasmOp.I64_EXTEND_I32_U)
internal actual fun uintToLong(value: Int): Long = implementedAsIntrinsic
@PublishedApi
@WasmOp(WasmOp.F32_CONVERT_I32_U)
internal actual fun uintToFloat(value: Int): Float = implementedAsIntrinsic
@PublishedApi
@WasmOp(WasmOp.I32_TRUNC_SAT_F32_U)
internal actual fun floatToUInt(value: Float): UInt = implementedAsIntrinsic
@PublishedApi
@WasmOp(WasmOp.F64_CONVERT_I32_U)
internal actual fun uintToDouble(value: Int): Double = implementedAsIntrinsic
@PublishedApi
@WasmOp(WasmOp.I32_TRUNC_SAT_F64_U)
internal actual fun doubleToUInt(value: Double): UInt = implementedAsIntrinsic
@PublishedApi
@WasmOp(WasmOp.F32_CONVERT_I64_U)
internal actual fun ulongToFloat(value: Long): Float = implementedAsIntrinsic
@PublishedApi
@WasmOp(WasmOp.I64_TRUNC_SAT_F32_U)
internal actual fun floatToULong(value: Float): ULong = implementedAsIntrinsic
@PublishedApi
@WasmOp(WasmOp.F64_CONVERT_I64_U)
internal actual fun ulongToDouble(value: Long): Double = implementedAsIntrinsic
@PublishedApi
@WasmOp(WasmOp.I64_TRUNC_SAT_F64_U)
internal actual fun doubleToULong(value: Double): ULong = implementedAsIntrinsic
@InlineOnly
internal actual inline fun uintToString(value: Int): String = utoa32(value.toUInt())
internal actual fun uintToString(value: Int, base: Int): String {
var unsignedValue = value.toUInt()
if (base == 10) return unsignedValue.toString()
if (value in 0 until base) return value.getChar().toString()
val buffer = WasmCharArray(UInt.SIZE_BITS)
val ulongRadix = base.toUInt()
var currentBufferIndex = UInt.SIZE_BITS - 1
while (unsignedValue != 0U) {
buffer.set(currentBufferIndex, (unsignedValue % ulongRadix).toInt().getChar())
unsignedValue /= ulongRadix
currentBufferIndex--
}
// Optimization - use signed division if both dividend and divisor < 2^63
if (dividend >= 0) {
return ULong(dividend / divisor)
}
// Otherwise, approximate the quotient, check, and correct if necessary.
val quotient = ((dividend ushr 1) / divisor) shl 1
val rem = dividend - quotient * divisor
return ULong(quotient + if (ULong(rem) >= ULong(divisor)) 1 else 0)
return buffer.createStringStartingFrom(currentBufferIndex + 1)
}
@PublishedApi
internal fun ulongRemainder(v1: ULong, v2: ULong): ULong {
val dividend = v1.toLong()
val divisor = v2.toLong()
if (divisor < 0) { // i.e., divisor >= 2^63:
return if (v1 < v2) {
v1 // dividend < divisor
} else {
v1 - v2 // dividend >= divisor
}
@InlineOnly
internal actual inline fun ulongToString(value: Long): String = utoa64(value.toULong())
internal actual fun ulongToString(value: Long, base: Int): String {
var unsignedValue = value.toULong()
if (base == 10) return unsignedValue.toString()
if (value in 0 until base) return value.toInt().getChar().toString()
val buffer = WasmCharArray(ULong.SIZE_BITS)
val ulongRadix = base.toULong()
var currentBufferIndex = ULong.SIZE_BITS - 1
while (unsignedValue != 0UL) {
buffer.set(currentBufferIndex, (unsignedValue % ulongRadix).toInt().getChar())
unsignedValue /= ulongRadix
currentBufferIndex--
}
// Optimization - use signed modulus if both dividend and divisor < 2^63
if (dividend >= 0) {
return ULong(dividend % divisor)
}
// Otherwise, approximate the quotient, check, and correct if necessary.
val quotient = ((dividend ushr 1) / divisor) shl 1
val rem = dividend - quotient * divisor
return ULong(rem - if (ULong(rem) >= ULong(divisor)) divisor else 0)
return buffer.createStringStartingFrom(currentBufferIndex + 1)
}
@PublishedApi
internal fun doubleToUInt(v: Double): UInt = when {
v.isNaN() -> 0u
v <= UInt.MIN_VALUE.toDouble() -> UInt.MIN_VALUE
v >= UInt.MAX_VALUE.toDouble() -> UInt.MAX_VALUE
v <= Int.MAX_VALUE -> v.toInt().toUInt()
else -> (v - Int.MAX_VALUE).toInt().toUInt() + Int.MAX_VALUE.toUInt() // Int.MAX_VALUE < v < UInt.MAX_VALUE
}
@PublishedApi
internal fun doubleToULong(v: Double): ULong = when {
v.isNaN() -> 0u
v <= ULong.MIN_VALUE.toDouble() -> ULong.MIN_VALUE
v >= ULong.MAX_VALUE.toDouble() -> ULong.MAX_VALUE
v < Long.MAX_VALUE -> v.toLong().toULong()
// Real values from Long.MAX_VALUE to (Long.MAX_VALUE + 1) are not representable in Double, so don't handle them.
else -> (v - 9223372036854775808.0).toLong().toULong() + 9223372036854775808uL // Long.MAX_VALUE + 1 < v < ULong.MAX_VALUE
}
@PublishedApi
internal fun uintToDouble(v: Int): Double = (v and Int.MAX_VALUE).toDouble() + (v ushr 31 shl 30).toDouble() * 2
@PublishedApi
internal fun ulongToDouble(v: Long): Double = (v ushr 11).toDouble() * 2048 + (v and 2047)
internal fun ulongToString(v: Long): String = ulongToString(v, 10)
internal fun ulongToString(v: Long, base: Int): String {
if (v >= 0) return v.toString(base)
var quotient = ((v ushr 1) / base) shl 1
var rem = v - quotient * base
if (rem >= base) {
rem -= base
quotient += 1
}
return quotient.toString(base) + rem.toString(base)
internal fun WasmCharArray.createStringStartingFrom(index: Int): String {
if (index == 0) return createString()
val newLength = this.len() - index
if (newLength == 0) return ""
val newChars = WasmCharArray(newLength)
copyWasmArray(this, newChars, index, 0, newLength)
return newChars.createString()
}
private fun Int.getChar() = if (this < 10) '0' + this else 'a' + (this - 10)
+9 -1
View File
@@ -65,7 +65,15 @@ the Kotlin IntelliJ IDEA plugin:
- License: Apache 2 ([license/third_party/gwt_license.txt][gwt])
- Origin: Derived from GWT, (C) 2007-08 Google Inc.
- Path: libraries/stdlib/unsigned/src/kotlin/UnsignedUtils.kt
- Path: libraries/stdlib/js/src/kotlin/UnsignedJs.kt
- License: Apache 2 ([license/third_party/guava_license.txt][guava])
- Origin: Derived from Guava's UnsignedLongs, (C) 2011 The Guava Authors
- Path: libraries/stdlib/jvm/src/kotlin/util/UnsignedJVM.kt
- License: Apache 2 ([license/third_party/guava_license.txt][guava])
- Origin: Derived from Guava's UnsignedLongs, (C) 2011 The Guava Authors
- Path: kotlin-native/runtime/src/main/kotlin/kotlin/Unsigned.kt
- License: Apache 2 ([license/third_party/guava_license.txt][guava])
- Origin: Derived from Guava's UnsignedLongs, (C) 2011 The Guava Authors