Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(157)

Side by Side Diff: runtime/vm/object.cc

Issue 11368138: Add some support for the code-point code-unit distinction. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Implemented feedback from patch set 2. Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/object.h" 5 #include "vm/object.h"
6 6
7 #include "include/dart_api.h" 7 #include "include/dart_api.h"
8 #include "platform/assert.h" 8 #include "platform/assert.h"
9 #include "vm/assembler.h" 9 #include "vm/assembler.h"
10 #include "vm/bigint_operations.h" 10 #include "vm/bigint_operations.h"
(...skipping 2169 matching lines...) Expand 10 before | Expand all | Expand 10 after
2180 const char* prefix, 2180 const char* prefix,
2181 intptr_t prefix_length, 2181 intptr_t prefix_length,
2182 const String& accessor_name) { 2182 const String& accessor_name) {
2183 intptr_t name_len = name.Length(); 2183 intptr_t name_len = name.Length();
2184 intptr_t accessor_name_len = accessor_name.Length(); 2184 intptr_t accessor_name_len = accessor_name.Length();
2185 2185
2186 if (name_len != (accessor_name_len + prefix_length)) { 2186 if (name_len != (accessor_name_len + prefix_length)) {
2187 return false; 2187 return false;
2188 } 2188 }
2189 for (intptr_t i = 0; i < prefix_length; i++) { 2189 for (intptr_t i = 0; i < prefix_length; i++) {
2190 if (name.CharAt(i) != prefix[i]) { 2190 if (name.CharAt(i) != static_cast<int32_t>(prefix[i])) {
2191 return false; 2191 return false;
2192 } 2192 }
2193 } 2193 }
2194 for (intptr_t i = 0, j = prefix_length; i < accessor_name_len; i++, j++) { 2194 for (intptr_t i = 0, j = prefix_length; i < accessor_name_len; i++, j++) {
2195 if (name.CharAt(j) != accessor_name.CharAt(i)) { 2195 if (name.CharAt(j) != accessor_name.CharAt(i)) {
2196 return false; 2196 return false;
2197 } 2197 }
2198 } 2198 }
2199 return true; 2199 return true;
2200 } 2200 }
(...skipping 7674 matching lines...) Expand 10 before | Expand all | Expand 10 after
9875 intptr_t String::Hash(const uint8_t* characters, intptr_t len) { 9875 intptr_t String::Hash(const uint8_t* characters, intptr_t len) {
9876 return HashImpl(characters, len); 9876 return HashImpl(characters, len);
9877 } 9877 }
9878 9878
9879 9879
9880 intptr_t String::Hash(const uint16_t* characters, intptr_t len) { 9880 intptr_t String::Hash(const uint16_t* characters, intptr_t len) {
9881 return HashImpl(characters, len); 9881 return HashImpl(characters, len);
9882 } 9882 }
9883 9883
9884 9884
9885 intptr_t String::Hash(const uint32_t* characters, intptr_t len) { 9885 intptr_t String::Hash(const int32_t* characters, intptr_t len) {
9886 return HashImpl(characters, len); 9886 return HashImpl(characters, len);
9887 } 9887 }
9888 9888
9889 9889
9890 int32_t String::CharAt(intptr_t index) const { 9890 int32_t String::CharAt(intptr_t index) const {
9891 intptr_t class_id = raw()->GetClassId(); 9891 intptr_t class_id = raw()->GetClassId();
9892 ASSERT(RawObject::IsStringClassId(class_id)); 9892 ASSERT(RawObject::IsStringClassId(class_id));
9893 NoGCScope no_gc; 9893 NoGCScope no_gc;
9894 if (class_id == kOneByteStringCid) { 9894 if (class_id == kOneByteStringCid) {
9895 return *OneByteString::CharAddr(*this, index); 9895 return OneByteString::CharAt(*this, index);
cshapiro 2012/11/17 02:25:27 Why was this changed? I think the code on the rig
erikcorry 2012/11/19 12:40:41 Reverted.
9896 } 9896 }
9897 if (class_id == kTwoByteStringCid) { 9897 if (class_id == kTwoByteStringCid) {
9898 return *TwoByteString::CharAddr(*this, index); 9898 return TwoByteString::CharAt(*this, index);
9899 } 9899 }
9900 if (class_id == kExternalOneByteStringCid) { 9900 if (class_id == kExternalOneByteStringCid) {
9901 return *ExternalOneByteString::CharAddr(*this, index); 9901 return ExternalOneByteString::CharAt(*this, index);
9902 } 9902 }
9903 ASSERT(class_id == kExternalTwoByteStringCid); 9903 ASSERT(class_id == kExternalTwoByteStringCid);
9904 return *ExternalTwoByteString::CharAddr(*this, index); 9904 return ExternalTwoByteString::CharAt(*this, index);
9905 } 9905 }
9906 9906
9907 9907
9908 intptr_t String::CharSize() const { 9908 intptr_t String::CharSize() const {
9909 intptr_t class_id = raw()->GetClassId(); 9909 intptr_t class_id = raw()->GetClassId();
9910 if (class_id == kOneByteStringCid || class_id == kExternalOneByteStringCid) { 9910 if (class_id == kOneByteStringCid || class_id == kExternalOneByteStringCid) {
9911 return kOneByteChar; 9911 return kOneByteChar;
9912 } 9912 }
9913 ASSERT(class_id == kTwoByteStringCid || 9913 ASSERT(class_id == kTwoByteStringCid ||
9914 class_id == kExternalTwoByteStringCid); 9914 class_id == kExternalTwoByteStringCid);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
9950 intptr_t len = strlen(str); 9950 intptr_t len = strlen(str);
9951 for (intptr_t i = 0; i < this->Length(); ++i) { 9951 for (intptr_t i = 0; i < this->Length(); ++i) {
9952 if (*str == '\0') { 9952 if (*str == '\0') {
9953 // Lengths don't match. 9953 // Lengths don't match.
9954 return false; 9954 return false;
9955 } 9955 }
9956 int32_t ch; 9956 int32_t ch;
9957 intptr_t consumed = Utf8::Decode(reinterpret_cast<const uint8_t*>(str), 9957 intptr_t consumed = Utf8::Decode(reinterpret_cast<const uint8_t*>(str),
9958 len, 9958 len,
9959 &ch); 9959 &ch);
9960 if (consumed == 0 || this->CharAt(i) != ch) { 9960 if (consumed == 0) return false;
9961 return false; 9961
9962 if (ch <= Utf16::kMaxCodeUnit) {
9963 if (this->CharAt(i) != ch) return false;
9964 } else {
9965 if (Utf16::CodePointAt(*this, i) != ch) return false;
9966 i++;
9962 } 9967 }
9963 str += consumed; 9968 str += consumed;
9964 len -= consumed; 9969 len -= consumed;
9965 } 9970 }
9966 return *str == '\0'; 9971 return *str == '\0';
9967 } 9972 }
9968 9973
9969 9974
9970 bool String::Equals(const uint8_t* characters, intptr_t len) const { 9975 bool String::Equals(const uint8_t* characters, intptr_t len) const {
9971 if (len != this->Length()) { 9976 if (len != this->Length()) {
(...skipping 18 matching lines...) Expand all
9990 9995
9991 for (intptr_t i = 0; i < len; i++) { 9996 for (intptr_t i = 0; i < len; i++) {
9992 if (this->CharAt(i) != characters[i]) { 9997 if (this->CharAt(i) != characters[i]) {
9993 return false; 9998 return false;
9994 } 9999 }
9995 } 10000 }
9996 return true; 10001 return true;
9997 } 10002 }
9998 10003
9999 10004
10000 bool String::Equals(const uint32_t* characters, intptr_t len) const { 10005 bool String::Equals(const int32_t* characters, intptr_t len) const {
10001 if (len != this->Length()) { 10006 if (len != this->Length()) {
10002 // Lengths don't match. 10007 // Lengths don't match.
10003 return false; 10008 return false;
10004 } 10009 }
10005 10010
10006 for (intptr_t i = 0; i < len; i++) { 10011 for (intptr_t i = 0; i < len; i++) {
10007 if (this->CharAt(i) != static_cast<int32_t>(characters[i])) { 10012 int32_t c = this->CharAt(i);
cshapiro 2012/11/17 02:25:27 This also looks like noise.
erikcorry 2012/11/19 12:40:41 This function was an attempt to compare a UTF-32 s
10013 if (c != characters[i]) {
10008 return false; 10014 return false;
10009 } 10015 }
10016 if (c > Utf16::kMaxCodeUnit) i++;
cshapiro 2012/11/17 02:25:27 I am confused about this line. A comment would be
erikcorry 2012/11/19 12:40:41 Ditto
10010 } 10017 }
siva 2012/11/16 22:32:04 I don't quite get this implementation.
erikcorry 2012/11/19 12:40:41 Ditto.
10011 return true; 10018 return true;
10012 } 10019 }
10013 10020
10014 10021
10015 intptr_t String::CompareTo(const String& other) const { 10022 intptr_t String::CompareTo(const String& other) const {
10016 const intptr_t this_len = this->Length(); 10023 const intptr_t this_len = this->Length();
10017 const intptr_t other_len = other.IsNull() ? 0 : other.Length(); 10024 const intptr_t other_len = other.IsNull() ? 0 : other.Length();
10018 const intptr_t len = (this_len < other_len) ? this_len : other_len; 10025 const intptr_t len = (this_len < other_len) ? this_len : other_len;
10026 // UTF-16 has the high surrogate before the low surrogate so we can compare
10027 // one code unit at a time for efficiency and still get the right ordering.
10019 for (intptr_t i = 0; i < len; i++) { 10028 for (intptr_t i = 0; i < len; i++) {
10020 int32_t this_code_point = this->CharAt(i); 10029 int32_t this_code_unit = this->CharAt(i);
10021 int32_t other_code_point = other.CharAt(i); 10030 int32_t other_code_unit = other.CharAt(i);
10022 if (this_code_point < other_code_point) { 10031 if (this_code_unit < other_code_unit) {
10023 return -1; 10032 return -1;
10024 } 10033 }
10025 if (this_code_point > other_code_point) { 10034 if (this_code_unit > other_code_unit) {
10026 return 1; 10035 return 1;
10027 } 10036 }
10028 } 10037 }
10029 if (this_len < other_len) return -1; 10038 if (this_len < other_len) return -1;
10030 if (this_len > other_len) return 1; 10039 if (this_len > other_len) return 1;
10031 return 0; 10040 return 0;
10032 } 10041 }
10033 10042
10034 10043
10035 bool String::StartsWith(const String& other) const { 10044 bool String::StartsWith(const String& other) const {
(...skipping 23 matching lines...) Expand all
10059 intptr_t array_len = strlen(str); 10068 intptr_t array_len = strlen(str);
10060 const uint8_t* utf8_array = reinterpret_cast<const uint8_t*>(str); 10069 const uint8_t* utf8_array = reinterpret_cast<const uint8_t*>(str);
10061 return String::New(utf8_array, array_len, space); 10070 return String::New(utf8_array, array_len, space);
10062 } 10071 }
10063 10072
10064 10073
10065 RawString* String::New(const uint8_t* utf8_array, 10074 RawString* String::New(const uint8_t* utf8_array,
10066 intptr_t array_len, 10075 intptr_t array_len,
10067 Heap::Space space) { 10076 Heap::Space space) {
10068 Utf8::Type type; 10077 Utf8::Type type;
10069 intptr_t len = Utf8::CodePointCount(utf8_array, array_len, &type); 10078 intptr_t len = Utf8::CodeUnitCount(utf8_array, array_len, &type);
10070 if (type == Utf8::kAscii) { 10079 if (type == Utf8::kAscii) {
10071 const String& strobj = String::Handle(OneByteString::New(len, space)); 10080 const String& strobj = String::Handle(OneByteString::New(len, space));
10072 if (len > 0) { 10081 if (len > 0) {
10073 NoGCScope no_gc; 10082 NoGCScope no_gc;
10074 Utf8::DecodeToAscii(utf8_array, array_len, 10083 Utf8::DecodeToAscii(utf8_array, array_len,
10075 OneByteString::CharAddr(strobj, 0), len); 10084 OneByteString::CharAddr(strobj, 0), len);
10076 } 10085 }
10077 return strobj.raw(); 10086 return strobj.raw();
10078 } 10087 }
10079 ASSERT((type == Utf8::kBMP) || (type == Utf8::kSMP)); 10088 ASSERT((type == Utf8::kBMP) || (type == Utf8::kSMP));
(...skipping 15 matching lines...) Expand all
10095 break; 10104 break;
10096 } 10105 }
10097 } 10106 }
10098 if (is_one_byte_string) { 10107 if (is_one_byte_string) {
10099 return OneByteString::New(utf16_array, array_len, space); 10108 return OneByteString::New(utf16_array, array_len, space);
10100 } 10109 }
10101 return TwoByteString::New(utf16_array, array_len, space); 10110 return TwoByteString::New(utf16_array, array_len, space);
10102 } 10111 }
10103 10112
10104 10113
10105 RawString* String::New(const uint32_t* utf32_array, 10114 RawString* String::New(const int32_t* utf32_array,
10106 intptr_t array_len, 10115 intptr_t array_len,
10107 Heap::Space space) { 10116 Heap::Space space) {
10108 bool is_one_byte_string = true; 10117 bool is_one_byte_string = true;
10109 intptr_t utf16_len = array_len; 10118 intptr_t utf16_len = array_len;
10110 for (intptr_t i = 0; i < array_len; ++i) { 10119 for (intptr_t i = 0; i < array_len; ++i) {
10111 if (utf32_array[i] > 0x7F) { 10120 if (utf32_array[i] > 0x7F) {
10112 is_one_byte_string = false; 10121 is_one_byte_string = false;
10113 } 10122 }
10114 if (utf32_array[i] > 0xFFFF) { 10123 if (utf32_array[i] > 0xFFFF) {
10115 utf16_len += 1; 10124 utf16_len += 1;
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
10384 } 10393 }
10385 10394
10386 10395
10387 RawString* String::Transform(int32_t (*mapping)(int32_t ch), 10396 RawString* String::Transform(int32_t (*mapping)(int32_t ch),
10388 const String& str, 10397 const String& str,
10389 Heap::Space space) { 10398 Heap::Space space) {
10390 ASSERT(!str.IsNull()); 10399 ASSERT(!str.IsNull());
10391 bool has_mapping = false; 10400 bool has_mapping = false;
10392 int32_t dst_max = 0; 10401 int32_t dst_max = 0;
10393 intptr_t len = str.Length(); 10402 intptr_t len = str.Length();
10403 intptr_t out_len = 0;
10394 // TODO(cshapiro): assume a transform is required, rollback if not. 10404 // TODO(cshapiro): assume a transform is required, rollback if not.
10395 for (intptr_t i = 0; i < len; ++i) { 10405 intptr_t i = 0;
10406 for (; i < len; ++i) {
10396 int32_t src = str.CharAt(i); 10407 int32_t src = str.CharAt(i);
10408 if (Utf16::IsSurrogate(src)) break;
10397 int32_t dst = mapping(src); 10409 int32_t dst = mapping(src);
10398 if (src != dst) { 10410 if (src != dst) {
10399 has_mapping = true; 10411 has_mapping = true;
10400 } 10412 }
10401 dst_max = Utils::Maximum(dst_max, dst); 10413 dst_max = Utils::Maximum(dst_max, dst);
10414 out_len += dst > Utf16::kMaxCodeUnit ? 2 : 1;
10415 }
10416 for (; i < len; ++i) {
10417 int32_t src = Utf16::CodePointAt(str, i);
10418 int32_t dst = mapping(src);
10419 if (src != dst) {
10420 has_mapping = true;
10421 }
10422 dst_max = Utils::Maximum(dst_max, dst);
10423 out_len += dst > Utf16::kMaxCodeUnit ? 2 : 1;
10424 if (src > Utf16::kMaxCodeUnit) ++i;
10402 } 10425 }
10403 if (!has_mapping) { 10426 if (!has_mapping) {
10404 return str.raw(); 10427 return str.raw();
10405 } 10428 }
10406 if (dst_max <= 0x7F) { 10429 if (dst_max <= 0x7F) {
10407 return OneByteString::Transform(mapping, str, space); 10430 return OneByteString::Transform(mapping, str, out_len, space);
10408 } 10431 }
10409 ASSERT(dst_max > 0x7F); 10432 ASSERT(dst_max > 0x7F);
10410 return TwoByteString::Transform(mapping, str, space); 10433 return TwoByteString::Transform(mapping, str, out_len, space);
10411 } 10434 }
10412 10435
10413 10436
10414 RawString* String::ToUpperCase(const String& str, Heap::Space space) { 10437 RawString* String::ToUpperCase(const String& str, Heap::Space space) {
10415 // TODO(cshapiro): create a fast-path for OneByteString instances. 10438 // TODO(cshapiro): create a fast-path for OneByteString instances.
10416 return Transform(CaseMapping::ToUpper, str, space); 10439 return Transform(CaseMapping::ToUpper, str, space);
10417 } 10440 }
10418 10441
10419 10442
10420 RawString* String::ToLowerCase(const String& str, Heap::Space space) { 10443 RawString* String::ToLowerCase(const String& str, Heap::Space space) {
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
10554 Heap::Space space) { 10577 Heap::Space space) {
10555 const String& result =String::Handle(OneByteString::New(len, space)); 10578 const String& result =String::Handle(OneByteString::New(len, space));
10556 for (intptr_t i = 0; i < len; ++i) { 10579 for (intptr_t i = 0; i < len; ++i) {
10557 ASSERT(characters[i] <= 0x7F); 10580 ASSERT(characters[i] <= 0x7F);
10558 *CharAddr(result, i) = characters[i]; 10581 *CharAddr(result, i) = characters[i];
10559 } 10582 }
10560 return OneByteString::raw(result); 10583 return OneByteString::raw(result);
10561 } 10584 }
10562 10585
10563 10586
10564 RawOneByteString* OneByteString::New(const uint32_t* characters, 10587 RawOneByteString* OneByteString::New(const int32_t* characters,
10565 intptr_t len, 10588 intptr_t len,
10566 Heap::Space space) { 10589 Heap::Space space) {
10567 const String& result = String::Handle(OneByteString::New(len, space)); 10590 const String& result = String::Handle(OneByteString::New(len, space));
10568 for (intptr_t i = 0; i < len; ++i) { 10591 for (intptr_t i = 0; i < len; ++i) {
10569 ASSERT(characters[i] <= 0x7F); 10592 ASSERT(characters[i] <= 0x7F);
10570 *CharAddr(result, i) = characters[i]; 10593 *CharAddr(result, i) = characters[i];
10571 } 10594 }
10572 return OneByteString::raw(result); 10595 return OneByteString::raw(result);
10573 } 10596 }
10574 10597
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
10607 intptr_t str_len = str.Length(); 10630 intptr_t str_len = str.Length();
10608 String::Copy(result, pos, str, 0, str_len); 10631 String::Copy(result, pos, str, 0, str_len);
10609 pos += str_len; 10632 pos += str_len;
10610 } 10633 }
10611 return OneByteString::raw(result); 10634 return OneByteString::raw(result);
10612 } 10635 }
10613 10636
10614 10637
10615 RawOneByteString* OneByteString::Transform(int32_t (*mapping)(int32_t ch), 10638 RawOneByteString* OneByteString::Transform(int32_t (*mapping)(int32_t ch),
10616 const String& str, 10639 const String& str,
10640 int out_length,
10617 Heap::Space space) { 10641 Heap::Space space) {
10618 ASSERT(!str.IsNull()); 10642 ASSERT(!str.IsNull());
10619 intptr_t len = str.Length(); 10643 intptr_t len = str.Length();
10620 const String& result = String::Handle(OneByteString::New(len, space)); 10644 const String& result =
10621 for (intptr_t i = 0; i < len; ++i) { 10645 String::Handle(OneByteString::New(out_length, space));
10622 int32_t ch = mapping(str.CharAt(i)); 10646 for (intptr_t i = 0, j = 0; i < len; ++i, j++) {
10623 ASSERT(ch >= 0 && ch <= 0x7F); 10647 int32_t old_ch = str.CharAt(i);
10624 *CharAddr(result, i) = ch; 10648 if (old_ch > Utf16::kMaxCodeUnit) i++;
10649 int32_t ch = mapping(old_ch);
10650 ASSERT(ch <= 0x7F);
10651 *CharAddr(result, j) = ch;
10625 } 10652 }
10626 return OneByteString::raw(result); 10653 return OneByteString::raw(result);
10627 } 10654 }
10628 10655
10629 10656
10630 RawTwoByteString* TwoByteString::EscapeSpecialCharacters(const String& str, 10657 RawTwoByteString* TwoByteString::EscapeSpecialCharacters(const String& str,
10631 bool raw_str) { 10658 bool raw_str) {
10632 intptr_t len = str.Length(); 10659 intptr_t len = str.Length();
10633 if (len > 0) { 10660 if (len > 0) {
10634 intptr_t num_escapes = 0; 10661 intptr_t num_escapes = 0;
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
10689 const String& result = String::Handle(TwoByteString::New(array_len, space)); 10716 const String& result = String::Handle(TwoByteString::New(array_len, space));
10690 { 10717 {
10691 NoGCScope no_gc; 10718 NoGCScope no_gc;
10692 memmove(CharAddr(result, 0), utf16_array, (array_len * 2)); 10719 memmove(CharAddr(result, 0), utf16_array, (array_len * 2));
10693 } 10720 }
10694 return TwoByteString::raw(result); 10721 return TwoByteString::raw(result);
10695 } 10722 }
10696 10723
10697 10724
10698 RawTwoByteString* TwoByteString::New(intptr_t utf16_len, 10725 RawTwoByteString* TwoByteString::New(intptr_t utf16_len,
10699 const uint32_t* utf32_array, 10726 const int32_t* utf32_array,
10700 intptr_t array_len, 10727 intptr_t array_len,
10701 Heap::Space space) { 10728 Heap::Space space) {
10702 ASSERT((array_len > 0) && (utf16_len >= array_len)); 10729 ASSERT((array_len > 0) && (utf16_len >= array_len));
10703 const String& result = String::Handle(TwoByteString::New(utf16_len, space)); 10730 const String& result = String::Handle(TwoByteString::New(utf16_len, space));
10704 { 10731 {
10705 NoGCScope no_gc; 10732 NoGCScope no_gc;
10706 intptr_t j = 0; 10733 intptr_t j = 0;
10707 for (intptr_t i = 0; i < array_len; ++i) { 10734 for (intptr_t i = 0; i < array_len; ++i) {
10708 if (utf32_array[i] > 0xffff) { 10735 int32_t code_point = utf32_array[i];
10736 if (code_point > Utf16::kMaxCodeUnit) {
10709 ASSERT(j < (utf16_len - 1)); 10737 ASSERT(j < (utf16_len - 1));
10710 Utf8::ConvertUTF32ToUTF16(utf32_array[i], CharAddr(result, j)); 10738 *CharAddr(result, j) = Utf16::LeadFromCodePoint(code_point);
10739 *CharAddr(result, j + 1) = Utf16::TrailFromCodePoint(code_point);
10711 j += 2; 10740 j += 2;
10712 } else { 10741 } else {
10713 ASSERT(j < utf16_len); 10742 ASSERT(j < utf16_len);
10714 *CharAddr(result, j) = utf32_array[i]; 10743 *CharAddr(result, j) = utf32_array[i];
10715 j += 1; 10744 j += 1;
10716 } 10745 }
10717 } 10746 }
10718 } 10747 }
10719 return TwoByteString::raw(result); 10748 return TwoByteString::raw(result);
10720 } 10749 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
10754 intptr_t str_len = str.Length(); 10783 intptr_t str_len = str.Length();
10755 String::Copy(result, pos, str, 0, str_len); 10784 String::Copy(result, pos, str, 0, str_len);
10756 pos += str_len; 10785 pos += str_len;
10757 } 10786 }
10758 return TwoByteString::raw(result); 10787 return TwoByteString::raw(result);
10759 } 10788 }
10760 10789
10761 10790
10762 RawTwoByteString* TwoByteString::Transform(int32_t (*mapping)(int32_t ch), 10791 RawTwoByteString* TwoByteString::Transform(int32_t (*mapping)(int32_t ch),
10763 const String& str, 10792 const String& str,
10793 int out_length,
10764 Heap::Space space) { 10794 Heap::Space space) {
10765 ASSERT(!str.IsNull()); 10795 ASSERT(!str.IsNull());
10766 intptr_t len = str.Length(); 10796 intptr_t len = str.Length();
10767 const String& result = String::Handle(TwoByteString::New(len, space)); 10797 const String& result =
10768 for (intptr_t i = 0; i < len; ++i) { 10798 String::Handle(TwoByteString::New(out_length, space));
10769 int32_t ch = mapping(str.CharAt(i)); 10799 for (intptr_t i = 0, j = 0; i < len; ++i, j++) {
10770 ASSERT(ch >= 0 && ch <= 0xFFFF); 10800 int32_t old_ch = Utf16::CodePointAt(str, i);
10771 *CharAddr(result, i) = ch; 10801 if (old_ch > Utf16::kMaxCodeUnit) i++;
10802 int32_t ch = mapping(old_ch);
10803 ASSERT(ch <= Utf16::kMaxCodePoint);
siva 2012/11/16 22:32:04 We assert here that ch <= Utf16::kMaxCodePoint but
erikcorry 2012/11/19 12:40:41 No, the assert checks against kMaxCodePoint (0x10f
10804 if (ch <= Utf16::kMaxCodeUnit) {
10805 *CharAddr(result, j) = ch;
10806 } else {
10807 *CharAddr(result, j) = Utf16::LeadFromCodePoint(ch);
10808 *CharAddr(result, j + 1) = Utf16::TrailFromCodePoint(ch);
10809 ++j;
10810 }
10811 ASSERT(j <= out_length);
10772 } 10812 }
10773 return TwoByteString::raw(result); 10813 return TwoByteString::raw(result);
10774 } 10814 }
10775 10815
10776 10816
10777 static void AddFinalizer(const Object& referent, 10817 static void AddFinalizer(const Object& referent,
10778 void* peer, 10818 void* peer,
10779 Dart_WeakPersistentHandleFinalizer callback) { 10819 Dart_WeakPersistentHandleFinalizer callback) {
10780 ASSERT(callback != NULL); 10820 ASSERT(callback != NULL);
10781 ApiState* state = Isolate::Current()->api_state(); 10821 ApiState* state = Isolate::Current()->api_state();
(...skipping 1221 matching lines...) Expand 10 before | Expand all | Expand 10 after
12003 } 12043 }
12004 return result.raw(); 12044 return result.raw();
12005 } 12045 }
12006 12046
12007 12047
12008 const char* WeakProperty::ToCString() const { 12048 const char* WeakProperty::ToCString() const {
12009 return "_WeakProperty"; 12049 return "_WeakProperty";
12010 } 12050 }
12011 12051
12012 } // namespace dart 12052 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698