[WASM] Replace String storage type from CharArray to WasmCharArray

This commit is contained in:
Igor Yakovlev
2022-03-02 20:50:19 +01:00
committed by teamcity
parent fb0819d490
commit d881f0d2a6
8 changed files with 113 additions and 55 deletions
+31 -10
View File
@@ -12,20 +12,27 @@ import kotlin.math.min
* The `String` class represents character strings. All string literals in Kotlin programs, such as `"abc"`, are
* implemented as instances of this class.
*/
public class String private constructor(internal val chars: CharArray) : Comparable<String>, CharSequence {
public class String private constructor(internal val chars: WasmCharArray) : Comparable<String>, CharSequence {
public companion object {
// Note: doesn't copy the array, use with care.
internal fun unsafeFromCharArray(chars: CharArray) = String(chars)
internal fun unsafeFromCharArray(chars: WasmCharArray) = String(chars)
}
/**
* Returns a string obtained by concatenating this string with the string representation of the given [other] object.
*/
public operator fun plus(other: Any?): String =
String(chars + other.toString().chars)
public operator fun plus(other: Any?): String {
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())
}
return String(newChars)
}
public override val length: Int
get() = chars.size
get() = chars.len()
/**
* Returns the character of this string at the specified [index].
@@ -33,10 +40,20 @@ public class String private constructor(internal val chars: CharArray) : Compara
* If the [index] is out of bounds of this string, throws an [IndexOutOfBoundsException] except in Kotlin/JS
* where the behavior is unspecified.
*/
public override fun get(index: Int): Char = chars[index]
public override fun get(index: Int): Char {
if (index < 0 || index >= chars.len()) throw IndexOutOfBoundsException()
return chars.get(index)
}
public override fun subSequence(startIndex: Int, endIndex: Int): CharSequence {
return String(chars.sliceArray(startIndex until endIndex))
val actualStartIndex = startIndex.coerceAtLeast(0)
val actualEndIndex = endIndex.coerceAtMost(chars.len())
val newCharsLen = actualEndIndex - actualStartIndex
val newChars = WasmCharArray(newCharsLen)
newChars.fill(newCharsLen) { i ->
chars.get(actualStartIndex + i)
}
return String(newChars)
}
public override fun compareTo(other: String): Int {
@@ -62,12 +79,16 @@ public class String private constructor(internal val chars: CharArray) : Compara
public override fun hashCode(): Int {
if (_hashCode != 0 || this.isEmpty())
return _hashCode
var hash = 0
for (c in chars)
hash = 31 * hash + c.toInt()
var i = 0
while (i < chars.len()) {
hash = 31 * hash + chars.get(i).toInt()
i++
}
_hashCode = hash
return _hashCode
}
}
internal fun stringLiteral(startAddr: Int, length: Int) = String.unsafeFromCharArray(unsafeRawMemoryToCharArray(startAddr, length))
internal fun stringLiteral(startAddr: Int, length: Int) = String.unsafeFromCharArray(unsafeRawMemoryToWasmCharArray(startAddr, length))