diff --git a/compiler/testData/codegen/box/size/add.kt b/compiler/testData/codegen/box/size/add.kt index 3ffc31ed489..7b40d94964d 100644 --- a/compiler/testData/codegen/box/size/add.kt +++ b/compiler/testData/codegen/box/size/add.kt @@ -1,6 +1,6 @@ // TARGET_BACKEND: WASM -// WASM_DCE_EXPECTED_OUTPUT_SIZE: wasm 12_338 +// WASM_DCE_EXPECTED_OUTPUT_SIZE: wasm 12_946 // WASM_DCE_EXPECTED_OUTPUT_SIZE: mjs 5_579 // FILE: test.kt diff --git a/compiler/testData/codegen/box/size/helloWorldDOM.kt b/compiler/testData/codegen/box/size/helloWorldDOM.kt index 249bb2f9b60..772a8c944dd 100644 --- a/compiler/testData/codegen/box/size/helloWorldDOM.kt +++ b/compiler/testData/codegen/box/size/helloWorldDOM.kt @@ -1,6 +1,6 @@ // TARGET_BACKEND: WASM -// WASM_DCE_EXPECTED_OUTPUT_SIZE: wasm 13_699 +// WASM_DCE_EXPECTED_OUTPUT_SIZE: wasm 14_307 // WASM_DCE_EXPECTED_OUTPUT_SIZE: mjs 6_134 // FILE: test.kt diff --git a/compiler/testData/codegen/box/size/objectsOptimization.kt b/compiler/testData/codegen/box/size/objectsOptimization.kt index aafe4ab8cc8..3b9aab61ac2 100644 --- a/compiler/testData/codegen/box/size/objectsOptimization.kt +++ b/compiler/testData/codegen/box/size/objectsOptimization.kt @@ -1,6 +1,6 @@ // TARGET_BACKEND: WASM -// WASM_DCE_EXPECTED_OUTPUT_SIZE: wasm 18_008 +// WASM_DCE_EXPECTED_OUTPUT_SIZE: wasm 18_621 // WASM_DCE_EXPECTED_OUTPUT_SIZE: mjs 5_451 object Simple diff --git a/compiler/testData/codegen/box/size/ok.kt b/compiler/testData/codegen/box/size/ok.kt index 37e9901d7c1..2b036c023de 100644 --- a/compiler/testData/codegen/box/size/ok.kt +++ b/compiler/testData/codegen/box/size/ok.kt @@ -1,6 +1,6 @@ // TARGET_BACKEND: WASM -// WASM_DCE_EXPECTED_OUTPUT_SIZE: wasm 12_380 +// WASM_DCE_EXPECTED_OUTPUT_SIZE: wasm 12_988 // WASM_DCE_EXPECTED_OUTPUT_SIZE: mjs 5_451 fun box() = "OK" \ No newline at end of file diff --git a/compiler/testData/codegen/box/size/removeUnusedOverride.kt b/compiler/testData/codegen/box/size/removeUnusedOverride.kt index 49e1089a182..d24270b02cd 100644 --- a/compiler/testData/codegen/box/size/removeUnusedOverride.kt +++ b/compiler/testData/codegen/box/size/removeUnusedOverride.kt @@ -1,7 +1,7 @@ // TARGET_BACKEND: JS_IR // TARGET_BACKEND: WASM -// WASM_DCE_EXPECTED_OUTPUT_SIZE: wasm 12_883 +// WASM_DCE_EXPECTED_OUTPUT_SIZE: wasm 13_492 interface I { fun foo() = "OK" diff --git a/libraries/stdlib/test/collections/ArraysTest.kt b/libraries/stdlib/test/collections/ArraysTest.kt index 44e3ece5629..944583dddb9 100644 --- a/libraries/stdlib/test/collections/ArraysTest.kt +++ b/libraries/stdlib/test/collections/ArraysTest.kt @@ -5,10 +5,12 @@ package test.collections +import test.TestPlatform import test.assertStaticTypeIs import test.assertTypeEquals import test.collections.behaviors.* import test.comparisons.STRING_CASE_INSENSITIVE_ORDER +import test.testExceptOn import test.text.isAsciiLetter import kotlin.test.* import kotlin.random.Random @@ -65,6 +67,18 @@ class ArraysTest { assertEquals("4", arr2[arr2.lastIndex]) } + @Test fun arrayInit() { + val arr = Array(2) { it.toString() } + + assertEquals(2, arr.size) + assertEquals(0.toString(), arr[0]) + assertEquals(1.toString(), arr[1]) + + testExceptOn(TestPlatform.Js) { + assertFailsWith { Array(-1) { it.toString() } } + } + } + @Test fun byteArray() { val arr = ByteArray(2) @@ -72,6 +86,10 @@ class ArraysTest { assertEquals(arr.size, 2) assertEquals(expected, arr[0]) assertEquals(expected, arr[1]) + + testExceptOn(TestPlatform.Js) { + assertFailsWith { ByteArray(-1) } + } } @Test fun byteArrayInit() { @@ -80,6 +98,10 @@ class ArraysTest { assertEquals(2, arr.size) assertEquals(0.toByte(), arr[0]) assertEquals(1.toByte(), arr[1]) + + testExceptOn(TestPlatform.Js) { + assertFailsWith { ByteArray(-1) { it.toByte() } } + } } @Test fun shortArray() { @@ -89,6 +111,10 @@ class ArraysTest { assertEquals(arr.size, 2) assertEquals(expected, arr[0]) assertEquals(expected, arr[1]) + + testExceptOn(TestPlatform.Js) { + assertFailsWith { ShortArray(-1) } + } } @Test fun shortArrayInit() { @@ -97,6 +123,10 @@ class ArraysTest { assertEquals(2, arr.size) assertEquals(0.toShort(), arr[0]) assertEquals(1.toShort(), arr[1]) + + testExceptOn(TestPlatform.Js) { + assertFailsWith { ShortArray(-1) { it.toShort() } } + } } @Test fun intArray() { @@ -105,6 +135,10 @@ class ArraysTest { assertEquals(arr.size, 2) assertEquals(0, arr[0]) assertEquals(0, arr[1]) + + testExceptOn(TestPlatform.Js) { + assertFailsWith { IntArray(-1) } + } } @Test fun intArrayInit() { @@ -113,6 +147,10 @@ class ArraysTest { assertEquals(2, arr.size) assertEquals(0.toInt(), arr[0]) assertEquals(1.toInt(), arr[1]) + + testExceptOn(TestPlatform.Js) { + assertFailsWith { IntArray(-1) { it.toInt() } } + } } @Test fun longArray() { @@ -122,6 +160,10 @@ class ArraysTest { assertEquals(arr.size, 2) assertEquals(expected, arr[0]) assertEquals(expected, arr[1]) + + testExceptOn(TestPlatform.Js) { + assertFailsWith { LongArray(-1) } + } } @Test fun longArrayInit() { @@ -130,6 +172,10 @@ class ArraysTest { assertEquals(2, arr.size) assertEquals(0.toLong(), arr[0]) assertEquals(1.toLong(), arr[1]) + + testExceptOn(TestPlatform.Js) { + assertFailsWith { LongArray(-1) { it.toLong() } } + } } @Test fun floatArray() { @@ -139,6 +185,10 @@ class ArraysTest { assertEquals(arr.size, 2) assertEquals(expected, arr[0]) assertEquals(expected, arr[1]) + + testExceptOn(TestPlatform.Js) { + assertFailsWith { FloatArray(-1) } + } } @Test fun floatArrayInit() { @@ -147,6 +197,10 @@ class ArraysTest { assertEquals(2, arr.size) assertEquals(0.toFloat(), arr[0]) assertEquals(1.toFloat(), arr[1]) + + testExceptOn(TestPlatform.Js) { + assertFailsWith { FloatArray(-1) { it.toFloat() } } + } } @Test fun doubleArray() { @@ -155,6 +209,10 @@ class ArraysTest { assertEquals(arr.size, 2) assertEquals(0.0, arr[0]) assertEquals(0.0, arr[1]) + + testExceptOn(TestPlatform.Js) { + assertFailsWith { DoubleArray(-1) } + } } @Test fun doubleArrayInit() { @@ -163,6 +221,10 @@ class ArraysTest { assertEquals(2, arr.size) assertEquals(0.toDouble(), arr[0]) assertEquals(1.toDouble(), arr[1]) + + testExceptOn(TestPlatform.Js) { + assertFailsWith { DoubleArray(-1) { it.toDouble() } } + } } @Test fun charArray() { @@ -172,6 +234,10 @@ class ArraysTest { assertEquals(arr.size, 2) assertEquals(expected, arr[0]) assertEquals(expected, arr[1]) + + testExceptOn(TestPlatform.Js) { + assertFailsWith { CharArray(-1) } + } } @Test fun charArrayInit() { @@ -180,6 +246,10 @@ class ArraysTest { assertEquals(2, arr.size) assertEquals('a', arr[0]) assertEquals('b', arr[1]) + + testExceptOn(TestPlatform.Js) { + assertFailsWith { CharArray(-1) { 'a' + it } } + } } @Test fun booleanArray() { @@ -187,6 +257,10 @@ class ArraysTest { assertEquals(arr.size, 2) assertEquals(false, arr[0]) assertEquals(false, arr[1]) + + testExceptOn(TestPlatform.Js) { + assertFailsWith { BooleanArray(-1) } + } } @Test fun booleanArrayInit() { @@ -195,6 +269,10 @@ class ArraysTest { assertEquals(2, arr.size) assertEquals(true, arr[0]) assertEquals(false, arr[1]) + + testExceptOn(TestPlatform.Js) { + assertFailsWith { BooleanArray(-1) { it % 2 == 0 } } + } } @Test fun contentEquals() { diff --git a/libraries/stdlib/wasm/builtins/kotlin/Array.kt b/libraries/stdlib/wasm/builtins/kotlin/Array.kt index c567dd8968b..21d3a4e7a8f 100644 --- a/libraries/stdlib/wasm/builtins/kotlin/Array.kt +++ b/libraries/stdlib/wasm/builtins/kotlin/Array.kt @@ -23,7 +23,12 @@ import kotlin.wasm.internal.* * for more information on arrays. */ public class Array @PublishedApi internal constructor(size: Int) { - internal val storage: WasmAnyArray = WasmAnyArray(size) + internal val storage: WasmAnyArray + + init { + if (size < 0) throw IllegalArgumentException("Negative array size") + storage = WasmAnyArray(size) + } @WasmPrimitiveConstructor internal constructor(storage: WasmAnyArray) @@ -87,6 +92,7 @@ internal fun arrayIterator(array: Array) = object : Iterator { } internal inline fun createAnyArray(size: Int, init: (Int) -> T): Array { + if (size < 0) throw IllegalArgumentException("Negative array size") val result = WasmAnyArray(size) result.fill(size, init) return Array(result) diff --git a/libraries/stdlib/wasm/builtins/kotlin/Arrays.kt b/libraries/stdlib/wasm/builtins/kotlin/Arrays.kt index 0944c5db015..84a52263361 100644 --- a/libraries/stdlib/wasm/builtins/kotlin/Arrays.kt +++ b/libraries/stdlib/wasm/builtins/kotlin/Arrays.kt @@ -16,7 +16,12 @@ package kotlin import kotlin.wasm.internal.* public class ByteArray(size: Int) { - internal val storage = WasmByteArray(size) + internal val storage: WasmByteArray + + init { + if (size < 0) throw IllegalArgumentException("Negative array size") + storage = WasmByteArray(size) + } @WasmPrimitiveConstructor internal constructor(storage: WasmByteArray) @@ -46,13 +51,19 @@ internal fun byteArrayIterator(array: ByteArray) = object : ByteIterator() { } internal inline fun createByteArray(size: Int, init: (Int) -> Byte): ByteArray { + if (size < 0) throw IllegalArgumentException("Negative array size") val result = WasmByteArray(size) result.fill(size, init) return ByteArray(result) } public class CharArray(size: Int) { - internal val storage = WasmCharArray(size) + internal val storage: WasmCharArray + + init { + if (size < 0) throw IllegalArgumentException("Negative array size") + storage = WasmCharArray(size) + } @WasmPrimitiveConstructor internal constructor(storage: WasmCharArray) @@ -83,13 +94,19 @@ internal fun charArrayIterator(array: CharArray) = object : CharIterator() { } internal inline fun createCharArray(size: Int, init: (Int) -> Char): CharArray { + if (size < 0) throw IllegalArgumentException("Negative array size") val result = WasmCharArray(size) result.fill(size, init) return CharArray(result) } public class ShortArray(size: Int) { - internal val storage = WasmShortArray(size) + internal val storage: WasmShortArray + + init { + if (size < 0) throw IllegalArgumentException("Negative array size") + storage = WasmShortArray(size) + } @WasmPrimitiveConstructor internal constructor(storage: WasmShortArray) @@ -120,13 +137,19 @@ internal fun shortArrayIterator(array: ShortArray) = object : ShortIterator() { } internal inline fun createShortArray(size: Int, init: (Int) -> Short): ShortArray { + if (size < 0) throw IllegalArgumentException("Negative array size") val result = WasmShortArray(size) result.fill(size, init) return ShortArray(result) } public class IntArray(size: Int) { - internal val storage = WasmIntArray(size) + internal val storage: WasmIntArray + + init { + if (size < 0) throw IllegalArgumentException("Negative array size") + storage = WasmIntArray(size) + } @WasmPrimitiveConstructor internal constructor(storage: WasmIntArray) @@ -157,13 +180,19 @@ internal fun intArrayIterator(array: IntArray) = object : IntIterator() { } internal inline fun createIntArray(size: Int, init: (Int) -> Int): IntArray { + if (size < 0) throw IllegalArgumentException("Negative array size") val result = WasmIntArray(size) result.fill(size, init) return IntArray(result) } public class LongArray(size: Int) { - internal val storage = WasmLongArray (size) + internal val storage: WasmLongArray + + init { + if (size < 0) throw IllegalArgumentException("Negative array size") + storage = WasmLongArray(size) + } @WasmPrimitiveConstructor internal constructor(storage: WasmLongArray) @@ -193,13 +222,19 @@ internal fun longArrayIterator(array: LongArray) = object : LongIterator() { } internal inline fun createLongArray(size: Int, init: (Int) -> Long): LongArray { + if (size < 0) throw IllegalArgumentException("Negative array size") val result = WasmLongArray(size) result.fill(size, init) return LongArray(result) } public class FloatArray(size: Int) { - internal val storage = WasmFloatArray(size) + internal val storage: WasmFloatArray + + init { + if (size < 0) throw IllegalArgumentException("Negative array size") + storage = WasmFloatArray(size) + } @WasmPrimitiveConstructor internal constructor(storage: WasmFloatArray) @@ -229,13 +264,19 @@ internal fun floatArrayIterator(array: FloatArray) = object : FloatIterator() { } internal inline fun createFloatArray(size: Int, init: (Int) -> Float): FloatArray { + if (size < 0) throw IllegalArgumentException("Negative array size") val result = WasmFloatArray(size) result.fill(size, init) return FloatArray(result) } public class DoubleArray(size: Int) { - internal val storage = WasmDoubleArray(size) + internal val storage: WasmDoubleArray + + init { + if (size < 0) throw IllegalArgumentException("Negative array size") + storage = WasmDoubleArray(size) + } @WasmPrimitiveConstructor internal constructor(storage: WasmDoubleArray) @@ -265,13 +306,19 @@ internal fun doubleArrayIterator(array: DoubleArray) = object : DoubleIterator() } internal inline fun createDoubleArray(size: Int, init: (Int) -> Double): DoubleArray { + if (size < 0) throw IllegalArgumentException("Negative array size") val result = WasmDoubleArray(size) result.fill(size, init) return DoubleArray(result) } public class BooleanArray(size: Int) { - internal val storage = WasmByteArray(size) + internal val storage: WasmByteArray + + init { + if (size < 0) throw IllegalArgumentException("Negative array size") + storage = WasmByteArray(size) + } @WasmPrimitiveConstructor internal constructor(storage: WasmByteArray) @@ -305,6 +352,7 @@ private fun Boolean.reinterpretAsByte(): Byte = implementedAsIntrinsic internal inline fun createBooleanArray(size: Int, init: (Int) -> Boolean): BooleanArray { + if (size < 0) throw IllegalArgumentException("Negative array size") val result = WasmByteArray(size) result.fill(size) { init(it).reinterpretAsByte()