[WASM] Add array copy intrinsic

This commit is contained in:
Igor Yakovlev
2022-06-29 18:51:31 +02:00
committed by teamcity
parent 8306b1bd71
commit 0ea7e8b70a
17 changed files with 218 additions and 203 deletions
@@ -15,7 +15,7 @@ import kotlin.wasm.internal.*
* for more information on arrays.
*/
public class Array<T> constructor(size: Int) {
private var storage: WasmAnyArray = WasmAnyArray(size)
internal val storage: WasmAnyArray = WasmAnyArray(size)
/**
* Creates a new array with the specified [size], where each element is calculated by calling the specified
@@ -8,7 +8,7 @@ package kotlin
import kotlin.wasm.internal.*
public class ByteArray(size: Int) {
private var storage = WasmByteArray(size)
internal val storage = WasmByteArray(size)
public constructor(size: Int, init: (Int) -> Byte) : this(size) {
storage.fill(size, init)
@@ -38,7 +38,7 @@ internal fun byteArrayIterator(array: ByteArray) = object : ByteIterator() {
public class CharArray(size: Int) {
private var storage = WasmCharArray(size)
internal val storage = WasmCharArray(size)
public constructor(size: Int, init: (Int) -> Char) : this(size) {
storage.fill(size) { init(it) }
@@ -69,7 +69,7 @@ internal fun charArrayIterator(array: CharArray) = object : CharIterator() {
public class ShortArray(size: Int) {
private var storage = WasmShortArray(size)
internal val storage = WasmShortArray(size)
public constructor(size: Int, init: (Int) -> Short) : this(size) {
storage.fill(size, init)
@@ -100,7 +100,7 @@ internal fun shortArrayIterator(array: ShortArray) = object : ShortIterator() {
public class IntArray(size: Int) {
private var storage = WasmIntArray(size)
internal val storage = WasmIntArray(size)
public constructor(size: Int, init: (Int) -> Int) : this(size) {
storage.fill(size, init)
@@ -131,7 +131,7 @@ internal fun intArrayIterator(array: IntArray) = object : IntIterator() {
public class LongArray(size: Int) {
private var storage = WasmLongArray (size)
internal val storage = WasmLongArray (size)
public constructor(size: Int, init: (Int) -> Long) : this(size) {
storage.fill(size, init)
@@ -161,7 +161,7 @@ internal fun longArrayIterator(array: LongArray) = object : LongIterator() {
public class FloatArray(size: Int) {
private var storage = WasmFloatArray(size)
internal val storage = WasmFloatArray(size)
public constructor(size: Int, init: (Int) -> Float) : this(size) {
storage.fill(size, init)
@@ -191,7 +191,7 @@ internal fun floatArrayIterator(array: FloatArray) = object : FloatIterator() {
public class DoubleArray(size: Int) {
private var storage = WasmDoubleArray(size)
internal val storage = WasmDoubleArray(size)
public constructor(size: Int, init: (Int) -> Double) : this(size) {
storage.fill(size, init)
@@ -221,7 +221,7 @@ internal fun doubleArrayIterator(array: DoubleArray) = object : DoubleIterator()
public class BooleanArray(size: Int) {
private var storage = WasmByteArray(size)
internal val storage = WasmByteArray(size)
public constructor(size: Int, init: (Int) -> Boolean) : this(size) {
storage.fill(size) { init(it).toInt().reinterpretAsByte() }
+29 -20
View File
@@ -22,12 +22,15 @@ public class String private constructor(internal val chars: WasmCharArray) : Com
* Returns a string obtained by concatenating this string with the string representation of the given [other] object.
*/
public operator fun plus(other: Any?): String {
val thisChars = chars
val otherChars = if (other is String) other.chars else other.toString().chars
val newCharsLen = chars.len() + otherChars.len()
val newChars = WasmCharArray(newCharsLen)
newChars.fill(newCharsLen) { i ->
if (i < chars.len()) chars.get(i) else otherChars.get(i - chars.len())
}
val thisLen = thisChars.len()
val otherLen = otherChars.len()
if (otherLen == 0) return String(thisChars)
val newChars = WasmCharArray(thisLen + otherLen)
thisChars.copyTo(newChars, 0, 0, thisLen)
otherChars.copyTo(newChars, 0, thisLen, otherLen)
return String(newChars)
}
@@ -47,42 +50,48 @@ public class String private constructor(internal val chars: WasmCharArray) : Com
public override fun subSequence(startIndex: Int, endIndex: Int): CharSequence {
val actualStartIndex = startIndex.coerceAtLeast(0)
val actualEndIndex = endIndex.coerceAtMost(chars.len())
val thisChars = chars
val actualEndIndex = endIndex.coerceAtMost(thisChars.len())
val newCharsLen = actualEndIndex - actualStartIndex
val newChars = WasmCharArray(newCharsLen)
newChars.fill(newCharsLen) { i ->
chars.get(actualStartIndex + i)
}
thisChars.copyTo(newChars, actualStartIndex, 0, newCharsLen)
return String(newChars)
}
public override fun compareTo(other: String): Int {
val len = min(this.length, other.length)
val thisChars = this.chars
val otherChars = other.chars
val thisLength = thisChars.len()
val otherLength = otherChars.len()
val len = min(thisLength, otherLength)
for (i in 0 until len) {
val l = this[i]
val r = other[i]
val l = thisChars.get(i)
val r = otherChars.get(i)
if (l != r)
return l - r
}
return this.length - other.length
return thisLength - otherLength
}
public override fun equals(other: Any?): Boolean {
if (other is String)
return this.compareTo(other) == 0
return false
}
public override fun equals(other: Any?): Boolean =
other != null &&
other is String &&
(this.length == other.length) &&
this.compareTo(other) == 0
public override fun toString(): String = this
public override fun hashCode(): Int {
if (_hashCode != 0 || this.isEmpty())
val thisLength = length
if (_hashCode != 0 || thisLength == null)
return _hashCode
var hash = 0
var i = 0
while (i < chars.len()) {
while (i < thisLength) {
hash = 31 * hash + chars.get(i).toInt()
i++
}
@@ -24,6 +24,9 @@ internal fun <To> wasm_ref_cast(a: Any?): To =
internal fun <To> wasm_ref_test(a: Any?): Boolean =
implementedAsIntrinsic
internal fun <T> wasm_array_copy(destination: T, destinationIndex: Int, source: T, sourceIndex: Int, length: Int): Unit =
implementedAsIntrinsic
@WasmOp(WasmOp.I32_EQ)
public external fun wasm_i32_eq(a: Int, b: Int): Boolean
@@ -1017,18 +1017,8 @@ public actual fun CharArray?.contentToString(): String {
@SinceKotlin("1.3")
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
public actual fun <T> Array<out T>.copyInto(destination: Array<T>, destinationOffset: Int = 0, startIndex: Int = 0, endIndex: Int = size): Array<T> {
AbstractList.checkRangeIndexes(startIndex, endIndex, this.size)
val rangeSize = endIndex - startIndex
AbstractList.checkRangeIndexes(destinationOffset, destinationOffset + rangeSize, destination.size)
if (this !== destination || destinationOffset <= startIndex) {
for (index in 0 until rangeSize) {
destination[destinationOffset + index] = this[startIndex + index]
}
} else {
for (index in rangeSize - 1 downTo 0) {
destination[destinationOffset + index] = this[startIndex + index]
}
}
@Suppress("UNCHECKED_CAST")
arrayCopy(this as Array<Any?>, startIndex, destination as Array<Any?>, destinationOffset, endIndex - startIndex)
return destination
}
@@ -1051,18 +1041,7 @@ public actual fun <T> Array<out T>.copyInto(destination: Array<T>, destinationOf
@SinceKotlin("1.3")
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
public actual fun ByteArray.copyInto(destination: ByteArray, destinationOffset: Int = 0, startIndex: Int = 0, endIndex: Int = size): ByteArray {
AbstractList.checkRangeIndexes(startIndex, endIndex, this.size)
val rangeSize = endIndex - startIndex
AbstractList.checkRangeIndexes(destinationOffset, destinationOffset + rangeSize, destination.size)
if (this !== destination || destinationOffset <= startIndex) {
for (index in 0 until rangeSize) {
destination[destinationOffset + index] = this[startIndex + index]
}
} else {
for (index in rangeSize - 1 downTo 0) {
destination[destinationOffset + index] = this[startIndex + index]
}
}
arrayCopy(this, startIndex, destination, destinationOffset, endIndex - startIndex)
return destination
}
@@ -1085,18 +1064,7 @@ public actual fun ByteArray.copyInto(destination: ByteArray, destinationOffset:
@SinceKotlin("1.3")
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
public actual fun ShortArray.copyInto(destination: ShortArray, destinationOffset: Int = 0, startIndex: Int = 0, endIndex: Int = size): ShortArray {
AbstractList.checkRangeIndexes(startIndex, endIndex, this.size)
val rangeSize = endIndex - startIndex
AbstractList.checkRangeIndexes(destinationOffset, destinationOffset + rangeSize, destination.size)
if (this !== destination || destinationOffset <= startIndex) {
for (index in 0 until rangeSize) {
destination[destinationOffset + index] = this[startIndex + index]
}
} else {
for (index in rangeSize - 1 downTo 0) {
destination[destinationOffset + index] = this[startIndex + index]
}
}
arrayCopy(this, startIndex, destination, destinationOffset, endIndex - startIndex)
return destination
}
@@ -1119,18 +1087,7 @@ public actual fun ShortArray.copyInto(destination: ShortArray, destinationOffset
@SinceKotlin("1.3")
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
public actual fun IntArray.copyInto(destination: IntArray, destinationOffset: Int = 0, startIndex: Int = 0, endIndex: Int = size): IntArray {
AbstractList.checkRangeIndexes(startIndex, endIndex, this.size)
val rangeSize = endIndex - startIndex
AbstractList.checkRangeIndexes(destinationOffset, destinationOffset + rangeSize, destination.size)
if (this !== destination || destinationOffset <= startIndex) {
for (index in 0 until rangeSize) {
destination[destinationOffset + index] = this[startIndex + index]
}
} else {
for (index in rangeSize - 1 downTo 0) {
destination[destinationOffset + index] = this[startIndex + index]
}
}
arrayCopy(this, startIndex, destination, destinationOffset, endIndex - startIndex)
return destination
}
@@ -1153,18 +1110,7 @@ public actual fun IntArray.copyInto(destination: IntArray, destinationOffset: In
@SinceKotlin("1.3")
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
public actual fun LongArray.copyInto(destination: LongArray, destinationOffset: Int = 0, startIndex: Int = 0, endIndex: Int = size): LongArray {
AbstractList.checkRangeIndexes(startIndex, endIndex, this.size)
val rangeSize = endIndex - startIndex
AbstractList.checkRangeIndexes(destinationOffset, destinationOffset + rangeSize, destination.size)
if (this !== destination || destinationOffset <= startIndex) {
for (index in 0 until rangeSize) {
destination[destinationOffset + index] = this[startIndex + index]
}
} else {
for (index in rangeSize - 1 downTo 0) {
destination[destinationOffset + index] = this[startIndex + index]
}
}
arrayCopy(this, startIndex, destination, destinationOffset, endIndex - startIndex)
return destination
}
@@ -1187,18 +1133,7 @@ public actual fun LongArray.copyInto(destination: LongArray, destinationOffset:
@SinceKotlin("1.3")
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
public actual fun FloatArray.copyInto(destination: FloatArray, destinationOffset: Int = 0, startIndex: Int = 0, endIndex: Int = size): FloatArray {
AbstractList.checkRangeIndexes(startIndex, endIndex, this.size)
val rangeSize = endIndex - startIndex
AbstractList.checkRangeIndexes(destinationOffset, destinationOffset + rangeSize, destination.size)
if (this !== destination || destinationOffset <= startIndex) {
for (index in 0 until rangeSize) {
destination[destinationOffset + index] = this[startIndex + index]
}
} else {
for (index in rangeSize - 1 downTo 0) {
destination[destinationOffset + index] = this[startIndex + index]
}
}
arrayCopy(this, startIndex, destination, destinationOffset, endIndex - startIndex)
return destination
}
@@ -1221,18 +1156,7 @@ public actual fun FloatArray.copyInto(destination: FloatArray, destinationOffset
@SinceKotlin("1.3")
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
public actual fun DoubleArray.copyInto(destination: DoubleArray, destinationOffset: Int = 0, startIndex: Int = 0, endIndex: Int = size): DoubleArray {
AbstractList.checkRangeIndexes(startIndex, endIndex, this.size)
val rangeSize = endIndex - startIndex
AbstractList.checkRangeIndexes(destinationOffset, destinationOffset + rangeSize, destination.size)
if (this !== destination || destinationOffset <= startIndex) {
for (index in 0 until rangeSize) {
destination[destinationOffset + index] = this[startIndex + index]
}
} else {
for (index in rangeSize - 1 downTo 0) {
destination[destinationOffset + index] = this[startIndex + index]
}
}
arrayCopy(this, startIndex, destination, destinationOffset, endIndex - startIndex)
return destination
}
@@ -1255,18 +1179,7 @@ public actual fun DoubleArray.copyInto(destination: DoubleArray, destinationOffs
@SinceKotlin("1.3")
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
public actual fun BooleanArray.copyInto(destination: BooleanArray, destinationOffset: Int = 0, startIndex: Int = 0, endIndex: Int = size): BooleanArray {
AbstractList.checkRangeIndexes(startIndex, endIndex, this.size)
val rangeSize = endIndex - startIndex
AbstractList.checkRangeIndexes(destinationOffset, destinationOffset + rangeSize, destination.size)
if (this !== destination || destinationOffset <= startIndex) {
for (index in 0 until rangeSize) {
destination[destinationOffset + index] = this[startIndex + index]
}
} else {
for (index in rangeSize - 1 downTo 0) {
destination[destinationOffset + index] = this[startIndex + index]
}
}
arrayCopy(this, startIndex, destination, destinationOffset, endIndex - startIndex)
return destination
}
@@ -1289,18 +1202,7 @@ public actual fun BooleanArray.copyInto(destination: BooleanArray, destinationOf
@SinceKotlin("1.3")
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
public actual fun CharArray.copyInto(destination: CharArray, destinationOffset: Int = 0, startIndex: Int = 0, endIndex: Int = size): CharArray {
AbstractList.checkRangeIndexes(startIndex, endIndex, this.size)
val rangeSize = endIndex - startIndex
AbstractList.checkRangeIndexes(destinationOffset, destinationOffset + rangeSize, destination.size)
if (this !== destination || destinationOffset <= startIndex) {
for (index in 0 until rangeSize) {
destination[destinationOffset + index] = this[startIndex + index]
}
} else {
for (index in rangeSize - 1 downTo 0) {
destination[destinationOffset + index] = this[startIndex + index]
}
}
arrayCopy(this, startIndex, destination, destinationOffset, endIndex - startIndex)
return destination
}
@@ -32,7 +32,11 @@ internal class WasmAnyArray(size: Int) {
@WasmOp(WasmOp.ARRAY_LEN)
fun len(): Int =
implementedAsIntrinsic
implementedAsIntrinsic
}
internal inline fun WasmAnyArray.copyTo(destination: WasmAnyArray, sourceIndex: Int, destinationIndex: Int, length: Int) {
wasm_array_copy<WasmAnyArray>(destination, destinationIndex, this, sourceIndex, length)
}
internal inline fun WasmAnyArray.fill(size: Int, init: (Int) -> Any?) {
@@ -41,8 +45,7 @@ internal inline fun WasmAnyArray.fill(size: Int, init: (Int) -> Any?) {
set(i, init(i))
i++
}
}
}
@WasmArrayOf(Byte::class, isNullable = false)
internal class WasmByteArray(size: Int) {
@WasmOp(WasmOp.ARRAY_GET_S)
@@ -55,7 +58,11 @@ internal class WasmByteArray(size: Int) {
@WasmOp(WasmOp.ARRAY_LEN)
fun len(): Int =
implementedAsIntrinsic
implementedAsIntrinsic
}
internal inline fun WasmByteArray.copyTo(destination: WasmByteArray, sourceIndex: Int, destinationIndex: Int, length: Int) {
wasm_array_copy<WasmByteArray>(destination, destinationIndex, this, sourceIndex, length)
}
internal inline fun WasmByteArray.fill(size: Int, init: (Int) -> Byte) {
@@ -64,8 +71,7 @@ internal inline fun WasmByteArray.fill(size: Int, init: (Int) -> Byte) {
set(i, init(i))
i++
}
}
}
@WasmArrayOf(Char::class, isNullable = false)
internal class WasmCharArray(size: Int) {
@WasmOp(WasmOp.ARRAY_GET_U)
@@ -78,7 +84,11 @@ internal class WasmCharArray(size: Int) {
@WasmOp(WasmOp.ARRAY_LEN)
fun len(): Int =
implementedAsIntrinsic
implementedAsIntrinsic
}
internal inline fun WasmCharArray.copyTo(destination: WasmCharArray, sourceIndex: Int, destinationIndex: Int, length: Int) {
wasm_array_copy<WasmCharArray>(destination, destinationIndex, this, sourceIndex, length)
}
internal inline fun WasmCharArray.fill(size: Int, init: (Int) -> Char) {
@@ -87,8 +97,7 @@ internal inline fun WasmCharArray.fill(size: Int, init: (Int) -> Char) {
set(i, init(i))
i++
}
}
}
@WasmArrayOf(Short::class, isNullable = false)
internal class WasmShortArray(size: Int) {
@WasmOp(WasmOp.ARRAY_GET_S)
@@ -101,7 +110,11 @@ internal class WasmShortArray(size: Int) {
@WasmOp(WasmOp.ARRAY_LEN)
fun len(): Int =
implementedAsIntrinsic
implementedAsIntrinsic
}
internal inline fun WasmShortArray.copyTo(destination: WasmShortArray, sourceIndex: Int, destinationIndex: Int, length: Int) {
wasm_array_copy<WasmShortArray>(destination, destinationIndex, this, sourceIndex, length)
}
internal inline fun WasmShortArray.fill(size: Int, init: (Int) -> Short) {
@@ -110,8 +123,7 @@ internal inline fun WasmShortArray.fill(size: Int, init: (Int) -> Short) {
set(i, init(i))
i++
}
}
}
@WasmArrayOf(Int::class, isNullable = false)
internal class WasmIntArray(size: Int) {
@WasmOp(WasmOp.ARRAY_GET)
@@ -124,7 +136,11 @@ internal class WasmIntArray(size: Int) {
@WasmOp(WasmOp.ARRAY_LEN)
fun len(): Int =
implementedAsIntrinsic
implementedAsIntrinsic
}
internal inline fun WasmIntArray.copyTo(destination: WasmIntArray, sourceIndex: Int, destinationIndex: Int, length: Int) {
wasm_array_copy<WasmIntArray>(destination, destinationIndex, this, sourceIndex, length)
}
internal inline fun WasmIntArray.fill(size: Int, init: (Int) -> Int) {
@@ -133,8 +149,7 @@ internal inline fun WasmIntArray.fill(size: Int, init: (Int) -> Int) {
set(i, init(i))
i++
}
}
}
@WasmArrayOf(Long::class, isNullable = false)
internal class WasmLongArray(size: Int) {
@WasmOp(WasmOp.ARRAY_GET)
@@ -147,7 +162,11 @@ internal class WasmLongArray(size: Int) {
@WasmOp(WasmOp.ARRAY_LEN)
fun len(): Int =
implementedAsIntrinsic
implementedAsIntrinsic
}
internal inline fun WasmLongArray.copyTo(destination: WasmLongArray, sourceIndex: Int, destinationIndex: Int, length: Int) {
wasm_array_copy<WasmLongArray>(destination, destinationIndex, this, sourceIndex, length)
}
internal inline fun WasmLongArray.fill(size: Int, init: (Int) -> Long) {
@@ -156,8 +175,7 @@ internal inline fun WasmLongArray.fill(size: Int, init: (Int) -> Long) {
set(i, init(i))
i++
}
}
}
@WasmArrayOf(Float::class, isNullable = false)
internal class WasmFloatArray(size: Int) {
@WasmOp(WasmOp.ARRAY_GET)
@@ -170,7 +188,11 @@ internal class WasmFloatArray(size: Int) {
@WasmOp(WasmOp.ARRAY_LEN)
fun len(): Int =
implementedAsIntrinsic
implementedAsIntrinsic
}
internal inline fun WasmFloatArray.copyTo(destination: WasmFloatArray, sourceIndex: Int, destinationIndex: Int, length: Int) {
wasm_array_copy<WasmFloatArray>(destination, destinationIndex, this, sourceIndex, length)
}
internal inline fun WasmFloatArray.fill(size: Int, init: (Int) -> Float) {
@@ -179,8 +201,7 @@ internal inline fun WasmFloatArray.fill(size: Int, init: (Int) -> Float) {
set(i, init(i))
i++
}
}
}
@WasmArrayOf(Double::class, isNullable = false)
internal class WasmDoubleArray(size: Int) {
@WasmOp(WasmOp.ARRAY_GET)
@@ -193,7 +214,11 @@ internal class WasmDoubleArray(size: Int) {
@WasmOp(WasmOp.ARRAY_LEN)
fun len(): Int =
implementedAsIntrinsic
implementedAsIntrinsic
}
internal inline fun WasmDoubleArray.copyTo(destination: WasmDoubleArray, sourceIndex: Int, destinationIndex: Int, length: Int) {
wasm_array_copy<WasmDoubleArray>(destination, destinationIndex, this, sourceIndex, length)
}
internal inline fun WasmDoubleArray.fill(size: Int, init: (Int) -> Double) {
@@ -202,5 +227,4 @@ internal inline fun WasmDoubleArray.fill(size: Int, init: (Int) -> Double) {
set(i, init(i))
i++
}
}
}
@@ -252,6 +252,7 @@ internal annotation class WasmOp(val name: String) {
const val ARRAY_GET_U = "ARRAY_GET_U"
const val ARRAY_SET = "ARRAY_SET"
const val ARRAY_LEN = "ARRAY_LEN"
const val ARRAY_COPY = "ARRAY_COPY"
const val I31_NEW = "I31_NEW"
const val I31_GET_S = "I31_GET_S"
const val I31_GET_U = "I31_GET_U"
@@ -5,6 +5,84 @@
package kotlin.collections
import kotlin.wasm.internal.copyTo
private inline fun rangeCheck(index: Int, count: Int, arraySize: Int) {
if (index < 0 || count < 0 || index + count > arraySize) throw IndexOutOfBoundsException()
}
internal inline fun arrayCopy(array: ByteArray, fromIndex: Int, destination: ByteArray, toIndex: Int, count: Int) {
val srcStorage = array.storage
rangeCheck(fromIndex, count, srcStorage.len())
val dstStorage = destination.storage
rangeCheck(toIndex, count, dstStorage.len())
srcStorage.copyTo(dstStorage, fromIndex, toIndex, count)
}
internal inline fun arrayCopy(array: ShortArray, fromIndex: Int, destination: ShortArray, toIndex: Int, count: Int) {
val srcStorage = array.storage
rangeCheck(fromIndex, count, srcStorage.len())
val dstStorage = destination.storage
rangeCheck(toIndex, count, dstStorage.len())
srcStorage.copyTo(dstStorage, fromIndex, toIndex, count)
}
internal inline fun arrayCopy(array: CharArray, fromIndex: Int, destination: CharArray, toIndex: Int, count: Int) {
val srcStorage = array.storage
rangeCheck(fromIndex, count, srcStorage.len())
val dstStorage = destination.storage
rangeCheck(toIndex, count, dstStorage.len())
srcStorage.copyTo(dstStorage, fromIndex, toIndex, count)
}
internal inline fun arrayCopy(array: IntArray, fromIndex: Int, destination: IntArray, toIndex: Int, count: Int) {
val srcStorage = array.storage
rangeCheck(fromIndex, count, srcStorage.len())
val dstStorage = destination.storage
rangeCheck(toIndex, count, dstStorage.len())
srcStorage.copyTo(dstStorage, fromIndex, toIndex, count)
}
internal inline fun arrayCopy(array: LongArray, fromIndex: Int, destination: LongArray, toIndex: Int, count: Int) {
val srcStorage = array.storage
rangeCheck(fromIndex, count, srcStorage.len())
val dstStorage = destination.storage
rangeCheck(toIndex, count, dstStorage.len())
srcStorage.copyTo(dstStorage, fromIndex, toIndex, count)
}
internal inline fun arrayCopy(array: FloatArray, fromIndex: Int, destination: FloatArray, toIndex: Int, count: Int) {
val srcStorage = array.storage
rangeCheck(fromIndex, count, srcStorage.len())
val dstStorage = destination.storage
rangeCheck(toIndex, count, dstStorage.len())
srcStorage.copyTo(dstStorage, fromIndex, toIndex, count)
}
internal inline fun arrayCopy(array: DoubleArray, fromIndex: Int, destination: DoubleArray, toIndex: Int, count: Int) {
val srcStorage = array.storage
rangeCheck(fromIndex, count, srcStorage.len())
val dstStorage = destination.storage
rangeCheck(toIndex, count, dstStorage.len())
srcStorage.copyTo(dstStorage, fromIndex, toIndex, count)
}
internal inline fun arrayCopy(array: BooleanArray, fromIndex: Int, destination: BooleanArray, toIndex: Int, count: Int) {
val srcStorage = array.storage
rangeCheck(fromIndex, count, srcStorage.len())
val dstStorage = destination.storage
rangeCheck(toIndex, count, dstStorage.len())
srcStorage.copyTo(dstStorage, fromIndex, toIndex, count)
}
internal inline fun arrayCopy(array: Array<Any?>, fromIndex: Int, destination: Array<Any?>, toIndex: Int, count: Int) {
val srcStorage = array.storage
rangeCheck(fromIndex, count, srcStorage.len())
val dstStorage = destination.storage
rangeCheck(toIndex, count, dstStorage.len())
srcStorage.copyTo(dstStorage, fromIndex, toIndex, count)
}
/**
* Returns a *typed* array containing all of the elements of this collection.
*
@@ -7,18 +7,14 @@ package kotlin.text
import kotlin.wasm.internal.*
internal fun insertString(array: CharArray, distIndex: Int, value: String, sourceIndex: Int, count: Int): Int {
var arrayIdx = distIndex
var stringIdx = sourceIndex
repeat(count) {
array[arrayIdx++] = value[stringIdx++]
}
internal fun insertString(array: CharArray, destinationIndex: Int, value: String, sourceIndex: Int, count: Int): Int {
value.chars.copyTo(array.storage, sourceIndex, destinationIndex, count)
return count
}
internal fun unsafeStringFromCharArray(array: CharArray, start: Int, size: Int): String {
val copy = WasmCharArray(size)
copy.fill(size) { array[it + start] }
array.storage.copyTo(copy, start, 0, size)
return String.unsafeFromCharArray(copy)
}
@@ -74,7 +74,7 @@ public actual fun String(chars: CharArray, offset: Int, length: Int): String {
throw IndexOutOfBoundsException()
val copy = WasmCharArray(length)
copy.fill(length) { chars[it + offset] }
chars.storage.copyTo(copy, offset, 0, length)
return String.unsafeFromCharArray(copy)
}
@@ -84,8 +84,10 @@ public actual fun String(chars: CharArray, offset: Int, length: Int): String {
@SinceKotlin("1.4")
@WasExperimental(ExperimentalStdlibApi::class)
public actual fun CharArray.concatToString(): String {
val copy = WasmCharArray(this.size)
copy.fill(this.size) { this[it] }
val thisStorage = this.storage
val thisLength = thisStorage.len()
val copy = WasmCharArray(thisLength)
this.storage.copyTo(copy, 0, 0, thisLength)
return String.unsafeFromCharArray(copy)
}
@@ -106,7 +108,7 @@ public actual fun CharArray.concatToString(startIndex: Int = 0, endIndex: Int =
val length = endIndex - startIndex
val copy = WasmCharArray(length)
copy.fill(length) { this[it + startIndex] }
this.storage.copyTo(copy, startIndex, 0, length)
return String.unsafeFromCharArray(copy)
}
@@ -116,7 +118,11 @@ public actual fun CharArray.concatToString(startIndex: Int = 0, endIndex: Int =
@SinceKotlin("1.4")
@WasExperimental(ExperimentalStdlibApi::class)
public actual fun String.toCharArray(): CharArray {
return CharArray(length) { get(it) }
val thisChars = this.chars
val thisLength = thisChars.len()
val newArray = CharArray(thisLength)
thisChars.copyTo(newArray.storage, 0, 0, thisLength)
return newArray
}
/**
@@ -133,7 +139,10 @@ public actual fun String.toCharArray(): CharArray {
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
public actual fun String.toCharArray(startIndex: Int = 0, endIndex: Int = this.length): CharArray {
AbstractList.checkBoundsIndexes(startIndex, endIndex, length)
return CharArray(endIndex - startIndex) { get(startIndex + it) }
val newLength = endIndex - startIndex
val newArray = CharArray(newLength)
this.chars.copyTo(newArray.storage, startIndex, 0, newLength)
return newArray
}
/**
@@ -350,9 +350,9 @@ private val decompositionValueIndex = shortArrayOf(
)
internal fun getDecompositionByIndex(index: Int): IntArray {
val valueIndex = decompositionValueIndex[index]
val size = decompositionValueIndex[index + 1] - valueIndex
return IntArray(size) { shift ->
decompositionValues[valueIndex + shift]
}
val startIndex = decompositionValueIndex[index].toInt()
val endIndex = decompositionValueIndex[index + 1].toInt()
val result = IntArray(endIndex - startIndex)
decompositionValues.copyInto(result, startIndex = startIndex, endIndex = endIndex)
return result
}