From 97bcffb7c7d546e1062637f9ea2303f2d32f91d2 Mon Sep 17 00:00:00 2001 From: Joshua Litt Date: Wed, 26 Oct 2022 07:36:50 +0000 Subject: [PATCH] [dart2wasm] Fix string `fromCharCodes` for some unicode surrogate pairs. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Id6ceb12057a1e5a419eb7fc30b6995aed8159321 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/265620 Commit-Queue: Ömer Ağacan Reviewed-by: Ömer Ağacan --- sdk/lib/_internal/wasm/lib/class_id.dart | 8 +++++++ sdk/lib/_internal/wasm/lib/string_patch.dart | 25 +++++++++++--------- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/sdk/lib/_internal/wasm/lib/class_id.dart b/sdk/lib/_internal/wasm/lib/class_id.dart index d59c9ad9891..431ced7a533 100644 --- a/sdk/lib/_internal/wasm/lib/class_id.dart +++ b/sdk/lib/_internal/wasm/lib/class_id.dart @@ -22,6 +22,14 @@ class ClassID { external static int get cidFunction; @pragma("wasm:class-id", "dart.core#_Function") external static int get cid_Function; + @pragma("wasm:class-id", "dart.core#_List") + external static int get cidFixedLengthList; + @pragma("wasm:class-id", "dart.core#_ListBase") + external static int get cidListBase; + @pragma("wasm:class-id", "dart.core#_GrowableList") + external static int get cidGrowableList; + @pragma("wasm:class-id", "dart.core#_ImmutableList") + external static int get cidImmutableList; // Class IDs for RTI Types. @pragma("wasm:class-id", "dart.core#_NeverType") diff --git a/sdk/lib/_internal/wasm/lib/string_patch.dart b/sdk/lib/_internal/wasm/lib/string_patch.dart index cb5583f2129..0990d4283c4 100644 --- a/sdk/lib/_internal/wasm/lib/string_patch.dart +++ b/sdk/lib/_internal/wasm/lib/string_patch.dart @@ -125,12 +125,18 @@ abstract class _StringBase implements String { static String createFromCharCodes( Iterable charCodes, int start, int? end, int? limit) { // TODO(srdjan): Also skip copying of wide typed arrays. - if (charCodes is Uint8List) { - final actualEnd = - RangeError.checkValidRange(start, end, charCodes.length); - return _createOneByteString(charCodes, start, actualEnd - start); - } else if (charCodes is! Uint16List) { - return _createStringFromIterable(charCodes, start, end); + final ccid = ClassID.getID(charCodes); + if (ccid != ClassID.cidFixedLengthList && + ccid != ClassID.cidListBase && + ccid != ClassID.cidGrowableList && + ccid != ClassID.cidImmutableList) { + if (charCodes is Uint8List) { + final actualEnd = + RangeError.checkValidRange(start, end, charCodes.length); + return _createOneByteString(charCodes, start, actualEnd - start); + } else if (charCodes is! Uint16List) { + return _createStringFromIterable(charCodes, start, end); + } } final int codeCount = charCodes.length; final actualEnd = RangeError.checkValidRange(start, end, codeCount); @@ -172,11 +178,8 @@ abstract class _StringBase implements String { if (charCodes is EfficientLengthIterable) { int length = charCodes.length; final endVal = RangeError.checkValidRange(start, end, length); - final Uint16List charCodeList = Uint16List(endVal - start); - int i = 0; - for (final char in charCodes.take(endVal).skip(start)) { - charCodeList[i++] = char; - } + final charCodeList = + List.from(charCodes.take(endVal).skip(start), growable: false); return createFromCharCodes(charCodeList, 0, charCodeList.length, null); } // Don't know length of iterable, so iterate and see if all the values