diff --git a/libraries/stdlib/wasm/builtins/kotlin/Char.kt b/libraries/stdlib/wasm/builtins/kotlin/Char.kt index 397760da479..8ed41b24c5f 100644 --- a/libraries/stdlib/wasm/builtins/kotlin/Char.kt +++ b/libraries/stdlib/wasm/builtins/kotlin/Char.kt @@ -93,7 +93,7 @@ public class Char private constructor(public val value: Char) : Comparable this.toInt().toDouble() override fun toString(): String = - String(charArrayOf(this)) + String.unsafeFromCharArray(charArrayOf(this)) override fun hashCode(): Int = this.toInt().hashCode() diff --git a/libraries/stdlib/wasm/builtins/kotlin/String.kt b/libraries/stdlib/wasm/builtins/kotlin/String.kt index f5bd56710a1..7a258c1657f 100644 --- a/libraries/stdlib/wasm/builtins/kotlin/String.kt +++ b/libraries/stdlib/wasm/builtins/kotlin/String.kt @@ -12,8 +12,11 @@ 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 internal constructor(internal val chars: CharArray) : Comparable, CharSequence { - public companion object; +public class String private constructor(internal val chars: CharArray) : Comparable, CharSequence { + public companion object { + // Note: doesn't copy the array, use with care. + internal fun unsafeFromCharArray(chars: CharArray) = String(chars) + } /** * Returns a string obtained by concatenating this string with the string representation of the given [other] object. @@ -68,4 +71,4 @@ public class String internal constructor(internal val chars: CharArray) : Compar } } -internal fun stringLiteral(startAddr: Int, length: Int) = String(unsafeRawMemoryToCharArray(startAddr, length)) +internal fun stringLiteral(startAddr: Int, length: Int) = String.unsafeFromCharArray(unsafeRawMemoryToCharArray(startAddr, length)) diff --git a/libraries/stdlib/wasm/internal/kotlin/wasm/internal/ExternalWrapper.kt b/libraries/stdlib/wasm/internal/kotlin/wasm/internal/ExternalWrapper.kt index e77472a4b2b..abbcbe07eac 100644 --- a/libraries/stdlib/wasm/internal/kotlin/wasm/internal/ExternalWrapper.kt +++ b/libraries/stdlib/wasm/internal/kotlin/wasm/internal/ExternalWrapper.kt @@ -147,7 +147,7 @@ internal fun convertJsStringToKotlinString(x: ExternalInterfaceType): String { val length = stringLength(x) val addr = unsafeGetScratchRawMemory(INT_SIZE_BYTES + length * CHAR_SIZE_BYTES) jsWriteStringIntoMemory(x, addr) - return kotlin.String(unsafeRawMemoryToCharArray(addr, length)) + return String.unsafeFromCharArray(unsafeRawMemoryToCharArray(addr, length)) } diff --git a/libraries/stdlib/wasm/internal/kotlin/wasm/internal/Number2String.kt b/libraries/stdlib/wasm/internal/kotlin/wasm/internal/Number2String.kt index 3c567c9cad5..dd23b076cf8 100644 --- a/libraries/stdlib/wasm/internal/kotlin/wasm/internal/Number2String.kt +++ b/libraries/stdlib/wasm/internal/kotlin/wasm/internal/Number2String.kt @@ -64,7 +64,7 @@ internal fun itoa32(inputValue: Int, radix: Int): String { if (sign == 1) buf[0] = CharCodes.MINUS.code.toChar() - return kotlin.String(buf) + return String.unsafeFromCharArray(buf) } private fun utoaDecSimple(buffer: CharArray, numInput: Int, offsetInput: Int) { @@ -144,7 +144,7 @@ internal fun itoa64(inputValue: Long, radix: Int): String { if (sign == 1) buf[0] = CharCodes.MINUS.code.toChar() - return kotlin.String(buf) + return String.unsafeFromCharArray(buf) } // Count number of decimals for u64 values @@ -178,7 +178,7 @@ internal fun dtoa(value: Double): String { val size = dtoaCore(buf, value) val ret = CharArray(size) buf.copyInto(ret, 0, 0, size) - return kotlin.String(ret) + return String.unsafeFromCharArray(ret) } private fun dtoaCore(buffer: CharArray, valueInp: Double): Int { diff --git a/libraries/stdlib/wasm/src/kotlin/Text.kt b/libraries/stdlib/wasm/src/kotlin/Text.kt index 9a4b27511a4..3a5948e4be8 100644 --- a/libraries/stdlib/wasm/src/kotlin/Text.kt +++ b/libraries/stdlib/wasm/src/kotlin/Text.kt @@ -252,7 +252,15 @@ public actual fun Char.isWhitespace(): Boolean = TODO("Wasm stdlib: Text") * Converts the characters in the specified array to a string. */ @SinceKotlin("1.2") -public actual fun String(chars: CharArray): String = TODO("Wasm stdlib: Text") +@Deprecated("Use CharArray.concatToString() instead", ReplaceWith("chars.concatToString()")) +@DeprecatedSinceKotlin(warningSince = "1.4", errorSince = "1.5") +public actual fun String(chars: CharArray): String { + var result = "" + for (char in chars) { + result += char + } + return result +} /** * Converts the characters from a portion of the specified array to a string. @@ -261,7 +269,17 @@ public actual fun String(chars: CharArray): String = TODO("Wasm stdlib: Text") * or `offset + length` is out of [chars] array bounds. */ @SinceKotlin("1.2") -public actual fun String(chars: CharArray, offset: Int, length: Int): String = TODO("Wasm stdlib: Text") +@Deprecated("Use CharArray.concatToString(startIndex, endIndex) instead", ReplaceWith("chars.concatToString(offset, offset + length)")) +@DeprecatedSinceKotlin(warningSince = "1.4", errorSince = "1.5") +public actual fun String(chars: CharArray, offset: Int, length: Int): String { + if (offset < 0 || length < 0 || chars.size - offset < length) + throw IndexOutOfBoundsException("size: ${chars.size}; offset: $offset; length: $length") + var result = "" + for (index in offset until offset + length) { + result += chars[index] + } + return result +} /** * Concatenates characters in this [CharArray] into a String. diff --git a/libraries/stdlib/wasm/src/kotlin/text/StringBuilder.kt b/libraries/stdlib/wasm/src/kotlin/text/StringBuilder.kt index 24b23b17936..e6cacd0a48f 100644 --- a/libraries/stdlib/wasm/src/kotlin/text/StringBuilder.kt +++ b/libraries/stdlib/wasm/src/kotlin/text/StringBuilder.kt @@ -15,7 +15,7 @@ internal fun insertString(array: CharArray, distIndex: Int, value: String, sourc } internal fun unsafeStringFromCharArray(array: CharArray, start: Int, size: Int): String = - kotlin.String(array.copyOfRange(start, start + size)) + String.unsafeFromCharArray(array.copyOfRange(start, start + size)) internal fun insertInt(array: CharArray, start: Int, value: Int): Int { val valueString = value.toString()