diff --git a/gradle.properties b/gradle.properties index 48cef59a057..441b7ca891a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -20,8 +20,8 @@ buildKotlinCompilerRepo=https://teamcity.jetbrains.com/guestAuth/app/rest/builds remoteRoot=konan_tests kotlinCompilerRepo=https://teamcity.jetbrains.com/guestAuth/app/rest/builds/buildType:(id:Kotlin_dev_Compiler),number:1.3.60-dev-346,branch:default:any,pinned:true/artifacts/content/maven kotlinVersion=1.3.60-dev-346 -kotlinStdlibRepo=https://teamcity.jetbrains.com/guestAuth/app/rest/builds/buildType:(id:Kotlin_dev_Compiler),number:1.3.60-dev-346,branch:default:any,pinned:true/artifacts/content/maven -kotlinStdlibVersion=1.3.60-dev-346 +kotlinStdlibRepo=https://teamcity.jetbrains.com/guestAuth/app/rest/builds/buildType:(id:Kotlin_dev_Compiler),number:1.3.60-dev-570,branch:default:any,pinned:true/artifacts/content/maven +kotlinStdlibVersion=1.3.60-dev-570 testKotlinCompilerVersion=1.3.60-dev-346 konanVersion=1.3.60 org.gradle.jvmargs='-Dfile.encoding=UTF-8' diff --git a/runtime/src/main/cpp/Arrays.cpp b/runtime/src/main/cpp/Arrays.cpp index cf3284392c6..aa261dff4cb 100644 --- a/runtime/src/main/cpp/Arrays.cpp +++ b/runtime/src/main/cpp/Arrays.cpp @@ -23,6 +23,8 @@ #include "Natives.h" #include "Types.h" +extern "C" void checkRangeIndexes(KInt from, KInt to, KInt size); + namespace { ALWAYS_INLINE inline void mutabilityCheck(KConstRef thiz) { @@ -32,6 +34,17 @@ ALWAYS_INLINE inline void mutabilityCheck(KConstRef thiz) { } } +template +inline void fillImpl(KRef thiz, KInt fromIndex, KInt toIndex, T value) { + ArrayHeader* array = thiz->array(); + checkRangeIndexes(fromIndex, toIndex, array->count_); + mutabilityCheck(thiz); + T* address = PrimitiveArrayAddressOfElementAt(array, fromIndex); + for (KInt index = fromIndex; index < toIndex; ++index) { + *address++ = value; + } +} + template inline void copyImpl(KConstRef thiz, KInt fromIndex, KRef destination, KInt toIndex, KInt count) { @@ -102,9 +115,7 @@ KInt Kotlin_Array_getArrayLength(KConstRef thiz) { void Kotlin_Array_fillImpl(KRef thiz, KInt fromIndex, KInt toIndex, KRef value) { ArrayHeader* array = thiz->array(); - if (fromIndex < 0 || toIndex < fromIndex || toIndex > array->count_) { - ThrowArrayIndexOutOfBoundsException(); - } + checkRangeIndexes(fromIndex, toIndex, array->count_); mutabilityCheck(thiz); for (KInt index = fromIndex; index < toIndex; ++index) { UpdateHeapRef(ArrayAddressOfElementAt(array, index), value); @@ -483,15 +494,36 @@ KInt Kotlin_IntArray_getArrayLength(KConstRef thiz) { return array->count_; } +void Kotlin_ByteArray_fillImpl(KRef thiz, KInt fromIndex, KInt toIndex, KByte value) { + fillImpl(thiz, fromIndex, toIndex, value); +} + +void Kotlin_ShortArray_fillImpl(KRef thiz, KInt fromIndex, KInt toIndex, KShort value) { + fillImpl(thiz, fromIndex, toIndex, value); +} + +void Kotlin_CharArray_fillImpl(KRef thiz, KInt fromIndex, KInt toIndex, KChar value) { + fillImpl(thiz, fromIndex, toIndex, value); +} + void Kotlin_IntArray_fillImpl(KRef thiz, KInt fromIndex, KInt toIndex, KInt value) { - ArrayHeader* array = thiz->array(); - if (fromIndex < 0 || toIndex < fromIndex || toIndex >= array->count_) { - ThrowArrayIndexOutOfBoundsException(); - } - mutabilityCheck(thiz); - for (KInt index = fromIndex; index < toIndex; ++index) { - *PrimitiveArrayAddressOfElementAt(array, index) = value; - } + fillImpl(thiz, fromIndex, toIndex, value); +} + +void Kotlin_LongArray_fillImpl(KRef thiz, KInt fromIndex, KInt toIndex, KLong value) { + fillImpl(thiz, fromIndex, toIndex, value); +} + +void Kotlin_FloatArray_fillImpl(KRef thiz, KInt fromIndex, KInt toIndex, KFloat value) { + fillImpl(thiz, fromIndex, toIndex, value); +} + +void Kotlin_DoubleArray_fillImpl(KRef thiz, KInt fromIndex, KInt toIndex, KDouble value) { + fillImpl(thiz, fromIndex, toIndex, value); +} + +void Kotlin_BooleanArray_fillImpl(KRef thiz, KInt fromIndex, KInt toIndex, KBoolean value) { + fillImpl(thiz, fromIndex, toIndex, value); } void Kotlin_ByteArray_copyImpl(KConstRef thiz, KInt fromIndex, diff --git a/runtime/src/main/kotlin/generated/_ArraysNative.kt b/runtime/src/main/kotlin/generated/_ArraysNative.kt index 8095cec296d..7c4b5932453 100644 --- a/runtime/src/main/kotlin/generated/_ArraysNative.kt +++ b/runtime/src/main/kotlin/generated/_ArraysNative.kt @@ -1341,6 +1341,141 @@ internal fun CharArray.copyOfUninitializedElements(newSize: Int): CharArray { return copyOfUninitializedElements(0, newSize) } +/** + * Fills this array or its subrange with the specified [element] value. + * + * @param fromIndex the start of the range (inclusive), 0 by default. + * @param toIndex the end of the range (exclusive), size of this array by default. + * + * @throws IndexOutOfBoundsException if [fromIndex] is less than zero or [toIndex] is greater than the size of this array. + * @throws IllegalArgumentException if [fromIndex] is greater than [toIndex]. + */ +@SinceKotlin("1.3") +@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") +public actual fun Array.fill(element: T, fromIndex: Int = 0, toIndex: Int = size): Unit { + arrayFill(this, fromIndex, toIndex, element) +} + +/** + * Fills this array or its subrange with the specified [element] value. + * + * @param fromIndex the start of the range (inclusive), 0 by default. + * @param toIndex the end of the range (exclusive), size of this array by default. + * + * @throws IndexOutOfBoundsException if [fromIndex] is less than zero or [toIndex] is greater than the size of this array. + * @throws IllegalArgumentException if [fromIndex] is greater than [toIndex]. + */ +@SinceKotlin("1.3") +@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") +public actual fun ByteArray.fill(element: Byte, fromIndex: Int = 0, toIndex: Int = size): Unit { + arrayFill(this, fromIndex, toIndex, element) +} + +/** + * Fills this array or its subrange with the specified [element] value. + * + * @param fromIndex the start of the range (inclusive), 0 by default. + * @param toIndex the end of the range (exclusive), size of this array by default. + * + * @throws IndexOutOfBoundsException if [fromIndex] is less than zero or [toIndex] is greater than the size of this array. + * @throws IllegalArgumentException if [fromIndex] is greater than [toIndex]. + */ +@SinceKotlin("1.3") +@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") +public actual fun ShortArray.fill(element: Short, fromIndex: Int = 0, toIndex: Int = size): Unit { + arrayFill(this, fromIndex, toIndex, element) +} + +/** + * Fills this array or its subrange with the specified [element] value. + * + * @param fromIndex the start of the range (inclusive), 0 by default. + * @param toIndex the end of the range (exclusive), size of this array by default. + * + * @throws IndexOutOfBoundsException if [fromIndex] is less than zero or [toIndex] is greater than the size of this array. + * @throws IllegalArgumentException if [fromIndex] is greater than [toIndex]. + */ +@SinceKotlin("1.3") +@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") +public actual fun IntArray.fill(element: Int, fromIndex: Int = 0, toIndex: Int = size): Unit { + arrayFill(this, fromIndex, toIndex, element) +} + +/** + * Fills this array or its subrange with the specified [element] value. + * + * @param fromIndex the start of the range (inclusive), 0 by default. + * @param toIndex the end of the range (exclusive), size of this array by default. + * + * @throws IndexOutOfBoundsException if [fromIndex] is less than zero or [toIndex] is greater than the size of this array. + * @throws IllegalArgumentException if [fromIndex] is greater than [toIndex]. + */ +@SinceKotlin("1.3") +@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") +public actual fun LongArray.fill(element: Long, fromIndex: Int = 0, toIndex: Int = size): Unit { + arrayFill(this, fromIndex, toIndex, element) +} + +/** + * Fills this array or its subrange with the specified [element] value. + * + * @param fromIndex the start of the range (inclusive), 0 by default. + * @param toIndex the end of the range (exclusive), size of this array by default. + * + * @throws IndexOutOfBoundsException if [fromIndex] is less than zero or [toIndex] is greater than the size of this array. + * @throws IllegalArgumentException if [fromIndex] is greater than [toIndex]. + */ +@SinceKotlin("1.3") +@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") +public actual fun FloatArray.fill(element: Float, fromIndex: Int = 0, toIndex: Int = size): Unit { + arrayFill(this, fromIndex, toIndex, element) +} + +/** + * Fills this array or its subrange with the specified [element] value. + * + * @param fromIndex the start of the range (inclusive), 0 by default. + * @param toIndex the end of the range (exclusive), size of this array by default. + * + * @throws IndexOutOfBoundsException if [fromIndex] is less than zero or [toIndex] is greater than the size of this array. + * @throws IllegalArgumentException if [fromIndex] is greater than [toIndex]. + */ +@SinceKotlin("1.3") +@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") +public actual fun DoubleArray.fill(element: Double, fromIndex: Int = 0, toIndex: Int = size): Unit { + arrayFill(this, fromIndex, toIndex, element) +} + +/** + * Fills this array or its subrange with the specified [element] value. + * + * @param fromIndex the start of the range (inclusive), 0 by default. + * @param toIndex the end of the range (exclusive), size of this array by default. + * + * @throws IndexOutOfBoundsException if [fromIndex] is less than zero or [toIndex] is greater than the size of this array. + * @throws IllegalArgumentException if [fromIndex] is greater than [toIndex]. + */ +@SinceKotlin("1.3") +@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") +public actual fun BooleanArray.fill(element: Boolean, fromIndex: Int = 0, toIndex: Int = size): Unit { + arrayFill(this, fromIndex, toIndex, element) +} + +/** + * Fills this array or its subrange with the specified [element] value. + * + * @param fromIndex the start of the range (inclusive), 0 by default. + * @param toIndex the end of the range (exclusive), size of this array by default. + * + * @throws IndexOutOfBoundsException if [fromIndex] is less than zero or [toIndex] is greater than the size of this array. + * @throws IllegalArgumentException if [fromIndex] is greater than [toIndex]. + */ +@SinceKotlin("1.3") +@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") +public actual fun CharArray.fill(element: Char, fromIndex: Int = 0, toIndex: Int = size): Unit { + arrayFill(this, fromIndex, toIndex, element) +} + /** * Returns an array containing all elements of the original array and then the given [element]. */ diff --git a/runtime/src/main/kotlin/kotlin/collections/ArrayUtil.kt b/runtime/src/main/kotlin/kotlin/collections/ArrayUtil.kt index 2726a2033df..92e6434586e 100644 --- a/runtime/src/main/kotlin/kotlin/collections/ArrayUtil.kt +++ b/runtime/src/main/kotlin/kotlin/collections/ArrayUtil.kt @@ -6,6 +6,7 @@ package kotlin.collections import kotlin.native.internal.PointsTo +import kotlin.native.internal.ExportForCppRuntime /** * Returns an array of objects of the given type with the given [size], initialized with _uninitialized_ values. @@ -75,10 +76,41 @@ internal fun Array.resetAt(index: Int) { @SymbolName("Kotlin_Array_fillImpl") @PointsTo(0b01000, 0, 0, 0b00001) // points to , points to . -external private fun fillImpl(array: Array, fromIndex: Int, toIndex: Int, value: Any?) +internal external fun arrayFill(array: Array, fromIndex: Int, toIndex: Int, value: T) + +@SymbolName("Kotlin_ByteArray_fillImpl") +internal external fun arrayFill(array: ByteArray, fromIndex: Int, toIndex: Int, value: Byte) + +@SymbolName("Kotlin_ShortArray_fillImpl") +internal external fun arrayFill(array: ShortArray, fromIndex: Int, toIndex: Int, value: Short) + +@SymbolName("Kotlin_CharArray_fillImpl") +internal external fun arrayFill(array: CharArray, fromIndex: Int, toIndex: Int, value: Char) @SymbolName("Kotlin_IntArray_fillImpl") -external private fun fillImpl(array: IntArray, fromIndex: Int, toIndex: Int, value: Int) +internal external fun arrayFill(array: IntArray, fromIndex: Int, toIndex: Int, value: Int) + +@SymbolName("Kotlin_LongArray_fillImpl") +internal external fun arrayFill(array: LongArray, fromIndex: Int, toIndex: Int, value: Long) + +@SymbolName("Kotlin_DoubleArray_fillImpl") +internal external fun arrayFill(array: DoubleArray, fromIndex: Int, toIndex: Int, value: Double) + +@SymbolName("Kotlin_FloatArray_fillImpl") +internal external fun arrayFill(array: FloatArray, fromIndex: Int, toIndex: Int, value: Float) + +@SymbolName("Kotlin_BooleanArray_fillImpl") +internal external fun arrayFill(array: BooleanArray, fromIndex: Int, toIndex: Int, value: Boolean) + +@ExportForCppRuntime +internal fun checkRangeIndexes(fromIndex: Int, toIndex: Int, size: Int) { + if (fromIndex < 0 || toIndex > size) { + throw IndexOutOfBoundsException("fromIndex: $fromIndex, toIndex: $toIndex, size: $size") + } + if (fromIndex > toIndex) { + throw IllegalArgumentException("fromIndex: $fromIndex > toIndex: $toIndex") + } +} /** * Resets a range of array elements at a specified [fromIndex] (inclusive) to [toIndex] (exclusive) range of indices @@ -88,11 +120,7 @@ external private fun fillImpl(array: IntArray, fromIndex: Int, toIndex: Int, val * either throwing exception or returning some kind of implementation-specific default value. */ internal fun Array.resetRange(fromIndex: Int, toIndex: Int) { - fillImpl(@Suppress("UNCHECKED_CAST") (this as Array), fromIndex, toIndex, null) -} - -internal fun IntArray.fill(fromIndex: Int, toIndex: Int, value: Int) { - fillImpl(this, fromIndex, toIndex, value) + arrayFill(@Suppress("UNCHECKED_CAST") (this as Array), fromIndex, toIndex, null) } @SymbolName("Kotlin_Array_copyImpl")