Native implementations of Array.fill
KT-32359
This commit is contained in:
+2
-2
@@ -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'
|
||||
|
||||
@@ -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<typename T>
|
||||
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<T>(array, fromIndex);
|
||||
for (KInt index = fromIndex; index < toIndex; ++index) {
|
||||
*address++ = value;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
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<KByte>(thiz, fromIndex, toIndex, value);
|
||||
}
|
||||
|
||||
void Kotlin_ShortArray_fillImpl(KRef thiz, KInt fromIndex, KInt toIndex, KShort value) {
|
||||
fillImpl<KShort>(thiz, fromIndex, toIndex, value);
|
||||
}
|
||||
|
||||
void Kotlin_CharArray_fillImpl(KRef thiz, KInt fromIndex, KInt toIndex, KChar value) {
|
||||
fillImpl<KChar>(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<KInt>(array, index) = value;
|
||||
}
|
||||
fillImpl<KInt>(thiz, fromIndex, toIndex, value);
|
||||
}
|
||||
|
||||
void Kotlin_LongArray_fillImpl(KRef thiz, KInt fromIndex, KInt toIndex, KLong value) {
|
||||
fillImpl<KLong>(thiz, fromIndex, toIndex, value);
|
||||
}
|
||||
|
||||
void Kotlin_FloatArray_fillImpl(KRef thiz, KInt fromIndex, KInt toIndex, KFloat value) {
|
||||
fillImpl<KFloat>(thiz, fromIndex, toIndex, value);
|
||||
}
|
||||
|
||||
void Kotlin_DoubleArray_fillImpl(KRef thiz, KInt fromIndex, KInt toIndex, KDouble value) {
|
||||
fillImpl<KDouble>(thiz, fromIndex, toIndex, value);
|
||||
}
|
||||
|
||||
void Kotlin_BooleanArray_fillImpl(KRef thiz, KInt fromIndex, KInt toIndex, KBoolean value) {
|
||||
fillImpl<KBoolean>(thiz, fromIndex, toIndex, value);
|
||||
}
|
||||
|
||||
void Kotlin_ByteArray_copyImpl(KConstRef thiz, KInt fromIndex,
|
||||
|
||||
@@ -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 <T> Array<T>.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].
|
||||
*/
|
||||
|
||||
@@ -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 <E> Array<E>.resetAt(index: Int) {
|
||||
|
||||
@SymbolName("Kotlin_Array_fillImpl")
|
||||
@PointsTo(0b01000, 0, 0, 0b00001) // <array> points to <value>, <value> points to <array>.
|
||||
external private fun fillImpl(array: Array<Any?>, fromIndex: Int, toIndex: Int, value: Any?)
|
||||
internal external fun <T> arrayFill(array: Array<T>, 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 <E> Array<E>.resetRange(fromIndex: Int, toIndex: Int) {
|
||||
fillImpl(@Suppress("UNCHECKED_CAST") (this as Array<Any?>), 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<Any?>), fromIndex, toIndex, null)
|
||||
}
|
||||
|
||||
@SymbolName("Kotlin_Array_copyImpl")
|
||||
|
||||
Reference in New Issue
Block a user