[dart2wasm] StringBuffer improvements

Use `U16List` instead of `Uint16List` as the character buffer type.
Access the Wasm array directly when writing characters and converting
the final buffer to a String. This avoids bounds checks and uses
`array.copy` when allocating the final string.

Change-Id: I570494e8349adc7a268544544516c9947abc8604
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/371681
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Ömer Ağacan <omersa@google.com>
diff --git a/sdk/lib/_internal/wasm/lib/string.dart b/sdk/lib/_internal/wasm/lib/string.dart
index f83307c..ec6b650 100644
--- a/sdk/lib/_internal/wasm/lib/string.dart
+++ b/sdk/lib/_internal/wasm/lib/string.dart
@@ -58,12 +58,39 @@
         U8List bytes, int start, int end) =>
     createOneByteStringFromCharactersArray(bytes.data, start, end);
 
+/// Create a [OneByteString] with the [array] contents in the range from
+/// [start] to [end] (exclusive).
 @pragma("wasm:prefer-inline")
 OneByteString createOneByteStringFromCharactersArray(
-    WasmArray<WasmI8> bytes, int start, int end) {
+    WasmArray<WasmI8> array, int start, int end) {
   final len = end - start;
   final s = OneByteString.withLength(len);
-  s._array.copy(0, bytes, start, len);
+  s._array.copy(0, array, start, len);
+  return s;
+}
+
+/// Same as [createOneByteStringFromCharactersArray], but the one-byte
+/// character array is an `i16 array` instead of `i8 array`.
+@pragma("wasm:prefer-inline")
+OneByteString createOneByteStringFromTwoByteCharactersArray(
+    WasmArray<WasmI16> array, int start, int end) {
+  final len = end - start;
+  final s = OneByteString.withLength(len);
+  for (int i = 0; i < len; i += 1) {
+    final i16 = array.readUnsigned(start + i);
+    s._array.write(i, i16);
+  }
+  return s;
+}
+
+/// Create a [TwoByteString] with the [array] contents in the range from
+/// [start] to [end] (exclusive).
+@pragma("wasm:prefer-inline")
+TwoByteString createTwoByteStringFromCharactersArray(
+    WasmArray<WasmI16> array, int start, int end) {
+  final len = end - start;
+  final s = TwoByteString.withLength(len);
+  s._array.copy(0, array, start, len);
   return s;
 }
 
diff --git a/sdk/lib/_internal/wasm/lib/string_buffer_patch.dart b/sdk/lib/_internal/wasm/lib/string_buffer_patch.dart
index d5d74d8..96c8779 100644
--- a/sdk/lib/_internal/wasm/lib/string_buffer_patch.dart
+++ b/sdk/lib/_internal/wasm/lib/string_buffer_patch.dart
@@ -3,11 +3,10 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import "dart:_internal" show patch;
-import "dart:_string" show StringBase, TwoByteString;
+import "dart:_string";
+import "dart:_typed_data";
 import "dart:_wasm";
 
-import "dart:typed_data" show Uint16List;
-
 @patch
 class StringBuffer {
   static const int _BUFFER_SIZE = 64;
@@ -42,7 +41,7 @@
    * used when writing short strings or individual char codes to the
    * buffer. The buffer is allocated on demand.
    */
-  Uint16List? _buffer;
+  WasmArray<WasmI16>? _buffer;
   int _bufferPosition = 0;
 
   /**
@@ -80,7 +79,7 @@
       }
       _ensureCapacity(1);
       final localBuffer = _buffer!;
-      localBuffer[_bufferPosition++] = charCode;
+      localBuffer.write(_bufferPosition++, charCode);
       _bufferCodeUnitMagnitude |= charCode;
     } else {
       if (charCode > 0x10FFFF) {
@@ -89,8 +88,8 @@
       _ensureCapacity(2);
       int bits = charCode - 0x10000;
       final localBuffer = _buffer!;
-      localBuffer[_bufferPosition++] = 0xD800 | (bits >> 10);
-      localBuffer[_bufferPosition++] = 0xDC00 | (bits & 0x3FF);
+      localBuffer.write(_bufferPosition++, 0xD800 | (bits >> 10));
+      localBuffer.write(_bufferPosition++, 0xDC00 | (bits & 0x3FF));
       _bufferCodeUnitMagnitude |= 0xFFFF;
     }
   }
@@ -140,7 +139,7 @@
   void _ensureCapacity(int n) {
     final localBuffer = _buffer;
     if (localBuffer == null) {
-      _buffer = Uint16List(_BUFFER_SIZE);
+      _buffer = WasmArray<WasmI16>(_BUFFER_SIZE);
     } else if (_bufferPosition + n > localBuffer.length) {
       _consumeBuffer();
     }
@@ -212,11 +211,11 @@
   /**
    * Create a [String] from the UFT-16 code units in buffer.
    */
-  static String _create(Uint16List buffer, int length, bool isLatin1) {
+  static String _create(WasmArray<WasmI16> buffer, int length, bool isLatin1) {
     if (isLatin1) {
-      return StringBase.createOneByteString(buffer, 0, length);
+      return createOneByteStringFromTwoByteCharactersArray(buffer, 0, length);
     } else {
-      return TwoByteString.allocateFromTwoByteList(buffer, 0, length);
+      return createTwoByteStringFromCharactersArray(buffer, 0, length);
     }
   }
 }