Chromium Code Reviews| Index: runtime/lib/growable_array.dart |
| diff --git a/runtime/lib/growable_array.dart b/runtime/lib/growable_array.dart |
| index fd3426ccd95e1507a097c909608601291ddd5177..4d6b69785aa1f40549ac47f7e554bb0ddcb14606 100644 |
| --- a/runtime/lib/growable_array.dart |
| +++ b/runtime/lib/growable_array.dart |
| @@ -257,19 +257,68 @@ class _GrowableList<T> implements List<T> { |
| } |
| String join([String separator = ""]) { |
| - if (isEmpty) return ""; |
| - if (this.length == 1) return "${this[0]}"; |
| - StringBuffer buffer = new StringBuffer(); |
| - if (separator.isEmpty) { |
| - for (int i = 0; i < this.length; i++) { |
| - buffer.write(this[i]); |
| + final int length = this.length; |
| + if (length == 0) return ""; |
| + if (length == 1) return "${this[0]}"; |
| + if (separator.isNotEmpty) return _joinWithSeparator(separator); |
| + var i = 0; |
| + var codeUnitCount = 0; |
| + while (i < length) { |
| + final element = this[i]; |
| + final int cid = ClassID.getID(element); |
| + if (ClassID.cidOneByteString == cid) { |
| + codeUnitCount += element.length; |
| + i++; |
| + continue; |
| } |
| - } else { |
| - buffer.write(this[0]); |
| - for (int i = 1; i < this.length; i++) { |
| - buffer.write(separator); |
| - buffer.write(this[i]); |
| + final int firstNonOneByteStringLimit = i; |
| + var nextElement = element; |
| + while (nextElement is String) { |
| + i++; |
| + if (i == length) { |
| + return _StringBase._concatRangeNative(this, 0, length); |
| + } |
| + nextElement = this[i]; |
| + } |
| + // return _StringBase._interpolate(this); |
|
srdjan
2014/09/11 18:43:17
remove dead code
Lasse Reichstein Nielsen
2014/09/11 19:04:00
Acknowledged.
|
| + final list = new _List(length); |
| + for (int copyIndex = 0; copyIndex < i; copyIndex++) { |
| + list[copyIndex] = this[copyIndex]; |
| } |
| + // Is non-zero if list contains a non-onebyte string |
|
srdjan
2014/09/11 18:43:17
Terminate comment with perioid
Lasse Reichstein Nielsen
2014/09/11 19:04:00
Acknowledged.
|
| + var onebyteCanary = i - firstNonOneByteStringLimit; |
| + while (true) { |
| + final element = |
|
srdjan
2014/09/11 18:43:16
final String element?
Lasse Reichstein Nielsen
2014/09/11 19:04:00
Acknowledged.
|
| + (nextElement is String) ? nextElement |
| + :_forceToString(nextElement); |
| + onebyteCanary |= (ClassID.getID(element) ^ ClassID.cidOneByteString); |
| + list[i] = element; |
| + codeUnitCount += element.length; |
| + i++; |
| + if (i == length) break; |
| + nextElement = this[i]; |
| + } |
| + if (onebyteCanary == 0) { |
| + return _OneByteString._concatAll(list, codeUnitCount); |
| + } |
| + return _StringBase._concatRangeNative(list, 0, length); |
| + } |
| + return _OneByteString._concatAll(this, codeUnitCount); |
| + } |
| + |
| + static String _forceToString(Object object) { |
| + assert(object is! String); |
| + final result = object.toString(); |
| + if (result is String) return result; |
| + throw new ArgumentError(object); |
|
srdjan
2014/09/11 18:43:16
For this we should be using checked mode not expli
Lasse Reichstein Nielsen
2014/09/11 19:04:00
This is simulating the interpolation "$object". Wi
|
| + } |
| + |
| + String _joinWithSeparator(String separator) { |
| + StringBuffer buffer = new StringBuffer(); |
| + buffer.write(this[0]); |
| + for (int i = 1; i < this.length; i++) { |
| + buffer.write(separator); |
| + buffer.write(this[i]); |
| } |
| return buffer.toString(); |
| } |