[Wasm] some optimizations (KT-79937)
diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/WasmCompiledModuleFragment.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/WasmCompiledModuleFragment.kt
index aaf657e..32ba0d1 100644
--- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/WasmCompiledModuleFragment.kt
+++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/ir2wasm/WasmCompiledModuleFragment.kt
@@ -779,6 +779,9 @@
                     buildGetLocal(wasmCharArray, serviceCodeLocation)
                 }
 
+                buildConstI32(0, serviceCodeLocation)
+                buildGetLocal(length, serviceCodeLocation)
+
                 buildCall(WasmSymbol(createStringFunction), serviceCodeLocation)
                 buildSetLocal(temporary, serviceCodeLocation)
 
diff --git a/generators/builtins/primitives/CharGenerator.kt b/generators/builtins/primitives/CharGenerator.kt
index 612b73b..7cb2e79 100644
--- a/generators/builtins/primitives/CharGenerator.kt
+++ b/generators/builtins/primitives/CharGenerator.kt
@@ -580,7 +580,7 @@
         """
             val array = WasmCharArray(1)
             array.set(0, this)
-            return array.createString()
+            return array.createString(0, 1)
         """.trimIndent().setAsBlockBody()
     }
 
diff --git a/libraries/stdlib/wasm/builtins/kotlin/Char.kt b/libraries/stdlib/wasm/builtins/kotlin/Char.kt
index 234f6e9..ad4d06f 100644
--- a/libraries/stdlib/wasm/builtins/kotlin/Char.kt
+++ b/libraries/stdlib/wasm/builtins/kotlin/Char.kt
@@ -121,7 +121,7 @@
     public actual override fun toString(): String {
         val array = WasmCharArray(1)
         array.set(0, this)
-        return array.createString()
+        return array.createString(0, 1)
     }
 
     @kotlin.internal.IntrinsicConstEvaluation
diff --git a/libraries/stdlib/wasm/builtins/kotlin/String.kt b/libraries/stdlib/wasm/builtins/kotlin/String.kt
index 5512b89..0241983 100644
--- a/libraries/stdlib/wasm/builtins/kotlin/String.kt
+++ b/libraries/stdlib/wasm/builtins/kotlin/String.kt
@@ -7,7 +7,7 @@
 
 import kotlin.wasm.internal.*
 
-internal expect fun WasmCharArray.createString(): String
+internal expect fun WasmCharArray.createString(start: Int, end: Int): String
 
 internal expect fun String.getChars(): WasmCharArray
 
@@ -19,7 +19,7 @@
     }
 
     val chars = array_new_data0<WasmCharArray>(start, length)
-    val newString = chars.createString()
+    val newString = chars.createString(0, length)
     stringPool[poolId] = newString
     return newString
 }
\ No newline at end of file
diff --git a/libraries/stdlib/wasm/internal/kotlin/wasm/internal/Number2String.kt b/libraries/stdlib/wasm/internal/kotlin/wasm/internal/Number2String.kt
index 86c061c..87dea87 100644
--- a/libraries/stdlib/wasm/internal/kotlin/wasm/internal/Number2String.kt
+++ b/libraries/stdlib/wasm/internal/kotlin/wasm/internal/Number2String.kt
@@ -62,7 +62,7 @@
 
     utoaDecSimple(buf, inputValue, decimals)
 
-    return buf.createString()
+    return buf.createString(0, decimals)
 }
 
 private fun utoaDecSimple(buffer: WasmCharArray, numInput: UInt, offsetInput: Int) {
@@ -134,7 +134,7 @@
 
     utoaDecSimple64(buf, inputValue, decimals)
 
-    return buf.createString()
+    return buf.createString(0, decimals)
 }
 
 // Count number of decimals for u64 values
@@ -169,9 +169,9 @@
 
     val buf = WasmCharArray(MAX_DOUBLE_LENGTH)
     val size = dtoaCore(buf, value, isSinglePrecision)
-    val ret = WasmCharArray(size)
-    buf.copyInto(ret, 0, 0, size)
-    return ret.createString()
+//    val ret = WasmCharArray(size)
+//    buf.copyInto(ret, 0, 0, size)
+    return buf.createString(0, size)
 }
 
 private fun dtoaCore(buffer: WasmCharArray, valueInp: Double, isSinglePrecision: Boolean): Int {
diff --git a/libraries/stdlib/wasm/js/builtins/kotlin/String.kt b/libraries/stdlib/wasm/js/builtins/kotlin/String.kt
index df2a547..1abbdc4 100644
--- a/libraries/stdlib/wasm/js/builtins/kotlin/String.kt
+++ b/libraries/stdlib/wasm/js/builtins/kotlin/String.kt
@@ -110,7 +110,7 @@
 }
 
 @Suppress("NOTHING_TO_INLINE")
-internal actual fun WasmCharArray.createString(): String =
-    String(jsFromCharCodeArray(this, 0, this.len()).unsafeCast(), this, this.len())
+internal actual fun WasmCharArray.createString(start: Int, end: Int): String =
+    String(jsFromCharCodeArray(this, start, end).unsafeCast(), null, end - start)
 
 internal actual fun String.getChars() = this.chars
diff --git a/libraries/stdlib/wasm/src/kotlin/text/StringBuilderWasm.kt b/libraries/stdlib/wasm/src/kotlin/text/StringBuilderWasm.kt
index e589976..7670c8a 100644
--- a/libraries/stdlib/wasm/src/kotlin/text/StringBuilderWasm.kt
+++ b/libraries/stdlib/wasm/src/kotlin/text/StringBuilderWasm.kt
@@ -49,9 +49,9 @@
 }
 
 internal actual fun unsafeStringFromCharArray(array: CharArray, start: Int, size: Int): String {
-    val copy = WasmCharArray(size)
-    copyWasmArray(array.storage, copy, start, 0, size)
-    return copy.createString()
+//    val copy = WasmCharArray(size)
+//    copyWasmArray(array.storage, copy, start, 0, size)
+    return array.storage.createString(start, start + size)
 }
 
 internal actual fun insertInt(array: CharArray, start: Int, value: Int): Int {
diff --git a/libraries/stdlib/wasm/src/kotlin/text/StringsWasm.kt b/libraries/stdlib/wasm/src/kotlin/text/StringsWasm.kt
index 172fe4d..22b9424 100644
--- a/libraries/stdlib/wasm/src/kotlin/text/StringsWasm.kt
+++ b/libraries/stdlib/wasm/src/kotlin/text/StringsWasm.kt
@@ -73,9 +73,9 @@
     if (offset < 0 || length < 0 || offset + length > chars.size)
         throw IndexOutOfBoundsException()
 
-    val copy = WasmCharArray(length)
-    copyWasmArray(chars.storage, copy, offset, 0, length)
-    return copy.createString()
+//    val copy = WasmCharArray(length)
+//    copyWasmArray(chars.storage, copy, offset, 0, length)
+    return chars.storage.createString(offset, offset + length)
 }
 
 /**
@@ -85,9 +85,9 @@
 public actual fun CharArray.concatToString(): String {
     val thisStorage = this.storage
     val thisLength = thisStorage.len()
-    val copy = WasmCharArray(thisLength)
-    copyWasmArray(this.storage, copy, 0, 0, thisLength)
-    return copy.createString()
+//    val copy = WasmCharArray(thisLength)
+//    copyWasmArray(this.storage, copy, 0, 0, thisLength)
+    return thisStorage.createString(0, thisLength)
 }
 
 /**
@@ -104,10 +104,10 @@
 public actual fun CharArray.concatToString(startIndex: Int = 0, endIndex: Int = this.size): String {
     AbstractList.checkBoundsIndexes(startIndex, endIndex, this.size)
 
-    val length = endIndex - startIndex
-    val copy = WasmCharArray(length)
-    copyWasmArray(this.storage, copy, startIndex, 0, length)
-    return copy.createString()
+//    val length = endIndex - startIndex
+//    val copy = WasmCharArray(length)
+//    copyWasmArray(this.storage, copy, startIndex, 0, length)
+    return this.storage.createString(startIndex, endIndex)
 }
 
 /**
diff --git a/libraries/stdlib/wasm/src/kotlin/util/UnsignedWasm.kt b/libraries/stdlib/wasm/src/kotlin/util/UnsignedWasm.kt
index c307845..1fad181 100644
--- a/libraries/stdlib/wasm/src/kotlin/util/UnsignedWasm.kt
+++ b/libraries/stdlib/wasm/src/kotlin/util/UnsignedWasm.kt
@@ -123,12 +123,12 @@
 }
 
 internal fun WasmCharArray.createStringStartingFrom(index: Int): String {
-    if (index == 0) return createString()
-    val newLength = this.len() - index
-    if (newLength == 0) return ""
-    val newChars = WasmCharArray(newLength)
-    copyWasmArray(this, newChars, index, 0, newLength)
-    return newChars.createString()
+//    if (index == 0) return createString(0, this.len())
+//    val newLength = this.len() - index
+//    if (newLength == 0) return ""
+//    val newChars = WasmCharArray(newLength)
+//    copyWasmArray(this, newChars, index, 0, newLength)
+    return this.createString(index, this.len())
 }
 
 private fun Int.getChar() = if (this < 10) '0' + this else 'a' + (this - 10)
diff --git a/libraries/stdlib/wasm/wasi/builtins/kotlin/String.kt b/libraries/stdlib/wasm/wasi/builtins/kotlin/String.kt
index f1382c9..89c184e 100644
--- a/libraries/stdlib/wasm/wasi/builtins/kotlin/String.kt
+++ b/libraries/stdlib/wasm/wasi/builtins/kotlin/String.kt
@@ -72,10 +72,10 @@
 
     public actual override fun subSequence(startIndex: Int, endIndex: Int): CharSequence {
         checkStringBounds(startIndex, endIndex, length)
-        val newLength = endIndex - startIndex
-        val newChars = WasmCharArray(newLength)
-        copyWasmArray(chars, newChars, startIndex, 0, newLength)
-        return newChars.createString()
+//        val newLength = endIndex - startIndex
+//        val newChars = WasmCharArray(newLength)
+//        copyWasmArray(chars, newChars, startIndex, 0, newLength)
+        return chars.createString(startIndex, endIndex)
     }
 
     private fun checkStringBounds(startIndex: Int, endIndex: Int, length: Int) {
@@ -153,7 +153,14 @@
     }
 }
 
-internal actual fun WasmCharArray.createString(): String =
-    String(null, this.len(), this)
+internal actual fun WasmCharArray.createString(start: Int, end: Int): String {
+    if (start == 0 && end == this.len()) {
+        return String(null, end, this)
+    }
+    val length = end - start
+    val copy = WasmCharArray(length)
+    copyWasmArray(this, copy, start, 0, length)
+    return String(null, length, copy)
+}
 
 internal actual fun String.getChars() = this.chars
\ No newline at end of file