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

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 3 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 2217 matching lines...) Expand 10 before | Expand all | Expand 10 after
2228 const char* prefix, 2228 const char* prefix,
2229 intptr_t prefix_length, 2229 intptr_t prefix_length,
2230 const String& accessor_name) { 2230 const String& accessor_name) {
2231 intptr_t name_len = name.Length(); 2231 intptr_t name_len = name.Length();
2232 intptr_t accessor_name_len = accessor_name.Length(); 2232 intptr_t accessor_name_len = accessor_name.Length();
2233 2233
2234 if (name_len != (accessor_name_len + prefix_length)) { 2234 if (name_len != (accessor_name_len + prefix_length)) {
2235 return false; 2235 return false;
2236 } 2236 }
2237 for (intptr_t i = 0; i < prefix_length; i++) { 2237 for (intptr_t i = 0; i < prefix_length; i++) {
2238 if (name.CharAt(i) != prefix[i]) { 2238 if (name.CharAt(i) != static_cast<int32_t>(prefix[i])) {
2239 return false; 2239 return false;
2240 } 2240 }
2241 } 2241 }
2242 for (intptr_t i = 0, j = prefix_length; i < accessor_name_len; i++, j++) { 2242 for (intptr_t i = 0, j = prefix_length; i < accessor_name_len; i++, j++) {
2243 if (name.CharAt(j) != accessor_name.CharAt(i)) { 2243 if (name.CharAt(j) != accessor_name.CharAt(i)) {
2244 return false; 2244 return false;
2245 } 2245 }
2246 } 2246 }
2247 return true; 2247 return true;
2248 } 2248 }
(...skipping 6907 matching lines...) Expand 10 before | Expand all | Expand 10 after
9156 9156
9157 9157
9158 const char* Integer::ToCString() const { 9158 const char* Integer::ToCString() const {
9159 // Integer is an interface. No instances of Integer should exist. 9159 // Integer is an interface. No instances of Integer should exist.
9160 UNREACHABLE(); 9160 UNREACHABLE();
9161 return "Integer"; 9161 return "Integer";
9162 } 9162 }
9163 9163
9164 9164
9165 RawInteger* Integer::New(const String& str, Heap::Space space) { 9165 RawInteger* Integer::New(const String& str, Heap::Space space) {
9166 // We are not supposed to have integers represented as two byte or 9166 // We are not supposed to have integers represented as two byte strings.
9167 // four byte strings.
9168 ASSERT(str.IsOneByteString()); 9167 ASSERT(str.IsOneByteString());
9169 int64_t value; 9168 int64_t value;
9170 if (!OS::StringToInt64(str.ToCString(), &value)) { 9169 if (!OS::StringToInt64(str.ToCString(), &value)) {
9171 const Bigint& big = Bigint::Handle(Bigint::New(str, space)); 9170 const Bigint& big = Bigint::Handle(Bigint::New(str, space));
9172 ASSERT(!BigintOperations::FitsIntoSmi(big)); 9171 ASSERT(!BigintOperations::FitsIntoSmi(big));
9173 ASSERT(!BigintOperations::FitsIntoMint(big)); 9172 ASSERT(!BigintOperations::FitsIntoMint(big));
9174 return big.raw(); 9173 return big.raw();
9175 } 9174 }
9176 return Integer::New(value, space); 9175 return Integer::New(value, space);
9177 } 9176 }
(...skipping 742 matching lines...) Expand 10 before | Expand all | Expand 10 after
9920 intptr_t String::Hash(const uint8_t* characters, intptr_t len) { 9919 intptr_t String::Hash(const uint8_t* characters, intptr_t len) {
9921 return HashImpl(characters, len); 9920 return HashImpl(characters, len);
9922 } 9921 }
9923 9922
9924 9923
9925 intptr_t String::Hash(const uint16_t* characters, intptr_t len) { 9924 intptr_t String::Hash(const uint16_t* characters, intptr_t len) {
9926 return HashImpl(characters, len); 9925 return HashImpl(characters, len);
9927 } 9926 }
9928 9927
9929 9928
9930 intptr_t String::Hash(const uint32_t* characters, intptr_t len) { 9929 intptr_t String::Hash(const int32_t* characters, intptr_t len) {
9931 return HashImpl(characters, len); 9930 return HashImpl(characters, len);
9932 } 9931 }
9933 9932
9934 9933
9935 int32_t String::CharAt(intptr_t index) const { 9934 int32_t String::CharAt(intptr_t index) const {
9936 intptr_t class_id = raw()->GetClassId(); 9935 intptr_t class_id = raw()->GetClassId();
9937 ASSERT(RawObject::IsStringClassId(class_id)); 9936 ASSERT(RawObject::IsStringClassId(class_id));
9938 NoGCScope no_gc; 9937 NoGCScope no_gc;
9939 if (class_id == kOneByteStringCid) { 9938 if (class_id == kOneByteStringCid) {
9940 return *OneByteString::CharAddr(*this, index); 9939 return *OneByteString::CharAddr(*this, index);
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
9995 intptr_t len = strlen(str); 9994 intptr_t len = strlen(str);
9996 for (intptr_t i = 0; i < this->Length(); ++i) { 9995 for (intptr_t i = 0; i < this->Length(); ++i) {
9997 if (*str == '\0') { 9996 if (*str == '\0') {
9998 // Lengths don't match. 9997 // Lengths don't match.
9999 return false; 9998 return false;
10000 } 9999 }
10001 int32_t ch; 10000 int32_t ch;
10002 intptr_t consumed = Utf8::Decode(reinterpret_cast<const uint8_t*>(str), 10001 intptr_t consumed = Utf8::Decode(reinterpret_cast<const uint8_t*>(str),
10003 len, 10002 len,
10004 &ch); 10003 &ch);
10005 if (consumed == 0 || this->CharAt(i) != ch) { 10004 if (consumed == 0) return false;
10006 return false; 10005
10006 if (ch <= Utf16::kMaxCodeUnit) {
10007 if (this->CharAt(i) != ch) return false;
10008 } else {
10009 if (Utf16::CodePointAt(*this, i) != ch) return false;
10010 i++;
10007 } 10011 }
10008 str += consumed; 10012 str += consumed;
10009 len -= consumed; 10013 len -= consumed;
10010 } 10014 }
10011 return *str == '\0'; 10015 return *str == '\0';
10012 } 10016 }
10013 10017
10014 10018
10015 bool String::Equals(const uint8_t* characters, intptr_t len) const { 10019 bool String::Equals(const uint8_t* characters, intptr_t len) const {
10016 if (len != this->Length()) { 10020 if (len != this->Length()) {
(...skipping 18 matching lines...) Expand all
10035 10039
10036 for (intptr_t i = 0; i < len; i++) { 10040 for (intptr_t i = 0; i < len; i++) {
10037 if (this->CharAt(i) != characters[i]) { 10041 if (this->CharAt(i) != characters[i]) {
10038 return false; 10042 return false;
10039 } 10043 }
10040 } 10044 }
10041 return true; 10045 return true;
10042 } 10046 }
10043 10047
10044 10048
10045 bool String::Equals(const uint32_t* characters, intptr_t len) const {
10046 if (len != this->Length()) {
10047 // Lengths don't match.
10048 return false;
10049 }
10050
10051 for (intptr_t i = 0; i < len; i++) {
10052 if (this->CharAt(i) != static_cast<int32_t>(characters[i])) {
10053 return false;
10054 }
10055 }
10056 return true;
10057 }
10058
10059
10060 intptr_t String::CompareTo(const String& other) const { 10049 intptr_t String::CompareTo(const String& other) const {
10061 const intptr_t this_len = this->Length(); 10050 const intptr_t this_len = this->Length();
10062 const intptr_t other_len = other.IsNull() ? 0 : other.Length(); 10051 const intptr_t other_len = other.IsNull() ? 0 : other.Length();
10063 const intptr_t len = (this_len < other_len) ? this_len : other_len; 10052 const intptr_t len = (this_len < other_len) ? this_len : other_len;
10053 // UTF-16 has the high surrogate before the low surrogate so we can compare
10054 // one code unit at a time for efficiency and still get the right ordering.
10064 for (intptr_t i = 0; i < len; i++) { 10055 for (intptr_t i = 0; i < len; i++) {
10065 int32_t this_code_point = this->CharAt(i); 10056 int32_t this_code_unit = this->CharAt(i);
10066 int32_t other_code_point = other.CharAt(i); 10057 int32_t other_code_unit = other.CharAt(i);
10067 if (this_code_point < other_code_point) { 10058 if (this_code_unit < other_code_unit) {
10068 return -1; 10059 return -1;
10069 } 10060 }
10070 if (this_code_point > other_code_point) { 10061 if (this_code_unit > other_code_unit) {
10071 return 1; 10062 return 1;
10072 } 10063 }
10073 } 10064 }
10074 if (this_len < other_len) return -1; 10065 if (this_len < other_len) return -1;
10075 if (this_len > other_len) return 1; 10066 if (this_len > other_len) return 1;
10076 return 0; 10067 return 0;
10077 } 10068 }
10078 10069
10079 10070
10080 bool String::StartsWith(const String& other) const { 10071 bool String::StartsWith(const String& other) const {
(...skipping 23 matching lines...) Expand all
10104 intptr_t array_len = strlen(str); 10095 intptr_t array_len = strlen(str);
10105 const uint8_t* utf8_array = reinterpret_cast<const uint8_t*>(str); 10096 const uint8_t* utf8_array = reinterpret_cast<const uint8_t*>(str);
10106 return String::New(utf8_array, array_len, space); 10097 return String::New(utf8_array, array_len, space);
10107 } 10098 }
10108 10099
10109 10100
10110 RawString* String::New(const uint8_t* utf8_array, 10101 RawString* String::New(const uint8_t* utf8_array,
10111 intptr_t array_len, 10102 intptr_t array_len,
10112 Heap::Space space) { 10103 Heap::Space space) {
10113 Utf8::Type type; 10104 Utf8::Type type;
10114 intptr_t len = Utf8::CodePointCount(utf8_array, array_len, &type); 10105 intptr_t len = Utf8::CodeUnitCount(utf8_array, array_len, &type);
10115 if (type == Utf8::kLatin1) { 10106 if (type == Utf8::kLatin1) {
10116 const String& strobj = String::Handle(OneByteString::New(len, space)); 10107 const String& strobj = String::Handle(OneByteString::New(len, space));
10117 if (len > 0) { 10108 if (len > 0) {
10118 NoGCScope no_gc; 10109 NoGCScope no_gc;
10119 Utf8::DecodeToLatin1(utf8_array, array_len, 10110 Utf8::DecodeToLatin1(utf8_array, array_len,
10120 OneByteString::CharAddr(strobj, 0), len); 10111 OneByteString::CharAddr(strobj, 0), len);
10121 } 10112 }
10122 return strobj.raw(); 10113 return strobj.raw();
10123 } 10114 }
10124 ASSERT((type == Utf8::kBMP) || (type == Utf8::kSMP)); 10115 ASSERT((type == Utf8::kBMP) || (type == Utf8::kSMP));
(...skipping 15 matching lines...) Expand all
10140 break; 10131 break;
10141 } 10132 }
10142 } 10133 }
10143 if (is_one_byte_string) { 10134 if (is_one_byte_string) {
10144 return OneByteString::New(utf16_array, array_len, space); 10135 return OneByteString::New(utf16_array, array_len, space);
10145 } 10136 }
10146 return TwoByteString::New(utf16_array, array_len, space); 10137 return TwoByteString::New(utf16_array, array_len, space);
10147 } 10138 }
10148 10139
10149 10140
10150 RawString* String::New(const uint32_t* utf32_array, 10141 RawString* String::New(const int32_t* utf32_array,
10151 intptr_t array_len, 10142 intptr_t array_len,
10152 Heap::Space space) { 10143 Heap::Space space) {
10153 bool is_one_byte_string = true; 10144 bool is_one_byte_string = true;
10154 intptr_t utf16_len = array_len; 10145 intptr_t utf16_len = array_len;
10155 for (intptr_t i = 0; i < array_len; ++i) { 10146 for (intptr_t i = 0; i < array_len; ++i) {
10156 if (utf32_array[i] > 0xFF) { 10147 if (utf32_array[i] > 0xFF) {
10157 is_one_byte_string = false; 10148 is_one_byte_string = false;
10158 } 10149 }
10159 if (utf32_array[i] > 0xFFFF) { 10150 if (utf32_array[i] > 0xFFFF) {
10160 utf16_len += 1; 10151 utf16_len += 1;
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after
10506 } 10497 }
10507 10498
10508 10499
10509 RawString* String::Transform(int32_t (*mapping)(int32_t ch), 10500 RawString* String::Transform(int32_t (*mapping)(int32_t ch),
10510 const String& str, 10501 const String& str,
10511 Heap::Space space) { 10502 Heap::Space space) {
10512 ASSERT(!str.IsNull()); 10503 ASSERT(!str.IsNull());
10513 bool has_mapping = false; 10504 bool has_mapping = false;
10514 int32_t dst_max = 0; 10505 int32_t dst_max = 0;
10515 intptr_t len = str.Length(); 10506 intptr_t len = str.Length();
10507 intptr_t out_len = 0;
10516 // TODO(cshapiro): assume a transform is required, rollback if not. 10508 // TODO(cshapiro): assume a transform is required, rollback if not.
10517 for (intptr_t i = 0; i < len; ++i) { 10509 intptr_t i = 0;
10510 for (; i < len; ++i) {
10518 int32_t src = str.CharAt(i); 10511 int32_t src = str.CharAt(i);
10512 if (Utf16::IsSurrogate(src)) break;
10519 int32_t dst = mapping(src); 10513 int32_t dst = mapping(src);
10520 if (src != dst) { 10514 if (src != dst) {
10521 has_mapping = true; 10515 has_mapping = true;
10522 } 10516 }
10523 dst_max = Utils::Maximum(dst_max, dst); 10517 dst_max = Utils::Maximum(dst_max, dst);
10518 out_len += dst > Utf16::kMaxCodeUnit ? 2 : 1;
10519 }
10520 for (; i < len; ++i) {
10521 int32_t src = Utf16::CodePointAt(str, i);
10522 int32_t dst = mapping(src);
10523 if (src != dst) {
10524 has_mapping = true;
10525 }
10526 dst_max = Utils::Maximum(dst_max, dst);
10527 out_len += dst > Utf16::kMaxCodeUnit ? 2 : 1;
10528 if (src > Utf16::kMaxCodeUnit) ++i;
10524 } 10529 }
10525 if (!has_mapping) { 10530 if (!has_mapping) {
10526 return str.raw(); 10531 return str.raw();
10527 } 10532 }
10528 if (dst_max <= 0xFF) { 10533 if (dst_max <= 0xFF) {
10529 return OneByteString::Transform(mapping, str, space); 10534 return OneByteString::Transform(mapping, str, out_len, space);
10530 } 10535 }
10531 ASSERT(dst_max > 0xFF); 10536 ASSERT(dst_max > 0xFF);
10532 return TwoByteString::Transform(mapping, str, space); 10537 return TwoByteString::Transform(mapping, str, out_len, space);
10533 } 10538 }
10534 10539
10535 10540
10536 RawString* String::ToUpperCase(const String& str, Heap::Space space) { 10541 RawString* String::ToUpperCase(const String& str, Heap::Space space) {
10537 // TODO(cshapiro): create a fast-path for OneByteString instances. 10542 // TODO(cshapiro): create a fast-path for OneByteString instances.
10538 return Transform(CaseMapping::ToUpper, str, space); 10543 return Transform(CaseMapping::ToUpper, str, space);
10539 } 10544 }
10540 10545
10541 10546
10542 RawString* String::ToLowerCase(const String& str, Heap::Space space) { 10547 RawString* String::ToLowerCase(const String& str, Heap::Space space) {
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
10676 Heap::Space space) { 10681 Heap::Space space) {
10677 const String& result =String::Handle(OneByteString::New(len, space)); 10682 const String& result =String::Handle(OneByteString::New(len, space));
10678 for (intptr_t i = 0; i < len; ++i) { 10683 for (intptr_t i = 0; i < len; ++i) {
10679 ASSERT(characters[i] <= 0xFF); 10684 ASSERT(characters[i] <= 0xFF);
10680 *CharAddr(result, i) = characters[i]; 10685 *CharAddr(result, i) = characters[i];
10681 } 10686 }
10682 return OneByteString::raw(result); 10687 return OneByteString::raw(result);
10683 } 10688 }
10684 10689
10685 10690
10686 RawOneByteString* OneByteString::New(const uint32_t* characters, 10691 RawOneByteString* OneByteString::New(const int32_t* characters,
10687 intptr_t len, 10692 intptr_t len,
10688 Heap::Space space) { 10693 Heap::Space space) {
10689 const String& result = String::Handle(OneByteString::New(len, space)); 10694 const String& result = String::Handle(OneByteString::New(len, space));
10690 for (intptr_t i = 0; i < len; ++i) { 10695 for (intptr_t i = 0; i < len; ++i) {
10691 ASSERT(characters[i] <= 0xFF); 10696 ASSERT(characters[i] <= 0xFF);
10692 *CharAddr(result, i) = characters[i]; 10697 *CharAddr(result, i) = characters[i];
10693 } 10698 }
10694 return OneByteString::raw(result); 10699 return OneByteString::raw(result);
10695 } 10700 }
10696 10701
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
10729 intptr_t str_len = str.Length(); 10734 intptr_t str_len = str.Length();
10730 String::Copy(result, pos, str, 0, str_len); 10735 String::Copy(result, pos, str, 0, str_len);
10731 pos += str_len; 10736 pos += str_len;
10732 } 10737 }
10733 return OneByteString::raw(result); 10738 return OneByteString::raw(result);
10734 } 10739 }
10735 10740
10736 10741
10737 RawOneByteString* OneByteString::Transform(int32_t (*mapping)(int32_t ch), 10742 RawOneByteString* OneByteString::Transform(int32_t (*mapping)(int32_t ch),
10738 const String& str, 10743 const String& str,
10744 intptr_t out_length,
10739 Heap::Space space) { 10745 Heap::Space space) {
10740 ASSERT(!str.IsNull()); 10746 ASSERT(!str.IsNull());
10741 intptr_t len = str.Length(); 10747 intptr_t len = str.Length();
10742 const String& result = String::Handle(OneByteString::New(len, space)); 10748 const String& result =
10743 for (intptr_t i = 0; i < len; ++i) { 10749 String::Handle(OneByteString::New(out_length, space));
10744 int32_t ch = mapping(str.CharAt(i)); 10750 for (intptr_t i = 0, j = 0; i < len; ++i, j++) {
10745 ASSERT(ch >= 0 && ch <= 0xFF); 10751 int32_t old_ch = str.CharAt(i);
10746 *CharAddr(result, i) = ch; 10752 if (old_ch > Utf16::kMaxCodeUnit) i++;
10753 int32_t ch = mapping(old_ch);
10754 ASSERT(ch <= 0xFF);
10755 *CharAddr(result, j) = ch;
10747 } 10756 }
10748 return OneByteString::raw(result); 10757 return OneByteString::raw(result);
10749 } 10758 }
10750 10759
10751 10760
10752 RawTwoByteString* TwoByteString::EscapeSpecialCharacters(const String& str, 10761 RawTwoByteString* TwoByteString::EscapeSpecialCharacters(const String& str,
10753 bool raw_str) { 10762 bool raw_str) {
10754 intptr_t len = str.Length(); 10763 intptr_t len = str.Length();
10755 if (len > 0) { 10764 if (len > 0) {
10756 intptr_t num_escapes = 0; 10765 intptr_t num_escapes = 0;
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
10811 const String& result = String::Handle(TwoByteString::New(array_len, space)); 10820 const String& result = String::Handle(TwoByteString::New(array_len, space));
10812 { 10821 {
10813 NoGCScope no_gc; 10822 NoGCScope no_gc;
10814 memmove(CharAddr(result, 0), utf16_array, (array_len * 2)); 10823 memmove(CharAddr(result, 0), utf16_array, (array_len * 2));
10815 } 10824 }
10816 return TwoByteString::raw(result); 10825 return TwoByteString::raw(result);
10817 } 10826 }
10818 10827
10819 10828
10820 RawTwoByteString* TwoByteString::New(intptr_t utf16_len, 10829 RawTwoByteString* TwoByteString::New(intptr_t utf16_len,
10821 const uint32_t* utf32_array, 10830 const int32_t* utf32_array,
10822 intptr_t array_len, 10831 intptr_t array_len,
10823 Heap::Space space) { 10832 Heap::Space space) {
10824 ASSERT((array_len > 0) && (utf16_len >= array_len)); 10833 ASSERT((array_len > 0) && (utf16_len >= array_len));
10825 const String& result = String::Handle(TwoByteString::New(utf16_len, space)); 10834 const String& result = String::Handle(TwoByteString::New(utf16_len, space));
10826 { 10835 {
10827 NoGCScope no_gc; 10836 NoGCScope no_gc;
10828 intptr_t j = 0; 10837 intptr_t j = 0;
10829 for (intptr_t i = 0; i < array_len; ++i) { 10838 for (intptr_t i = 0; i < array_len; ++i) {
10830 if (utf32_array[i] > 0xffff) { 10839 int32_t code_point = utf32_array[i];
10840 if (code_point > Utf16::kMaxCodeUnit) {
10831 ASSERT(j < (utf16_len - 1)); 10841 ASSERT(j < (utf16_len - 1));
10832 Utf8::ConvertUTF32ToUTF16(utf32_array[i], CharAddr(result, j)); 10842 *CharAddr(result, j) = Utf16::LeadFromCodePoint(code_point);
10843 *CharAddr(result, j + 1) = Utf16::TrailFromCodePoint(code_point);
10833 j += 2; 10844 j += 2;
10834 } else { 10845 } else {
10835 ASSERT(j < utf16_len); 10846 ASSERT(j < utf16_len);
10836 *CharAddr(result, j) = utf32_array[i]; 10847 *CharAddr(result, j) = utf32_array[i];
10837 j += 1; 10848 j += 1;
10838 } 10849 }
10839 } 10850 }
10840 } 10851 }
10841 return TwoByteString::raw(result); 10852 return TwoByteString::raw(result);
10842 } 10853 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
10876 intptr_t str_len = str.Length(); 10887 intptr_t str_len = str.Length();
10877 String::Copy(result, pos, str, 0, str_len); 10888 String::Copy(result, pos, str, 0, str_len);
10878 pos += str_len; 10889 pos += str_len;
10879 } 10890 }
10880 return TwoByteString::raw(result); 10891 return TwoByteString::raw(result);
10881 } 10892 }
10882 10893
10883 10894
10884 RawTwoByteString* TwoByteString::Transform(int32_t (*mapping)(int32_t ch), 10895 RawTwoByteString* TwoByteString::Transform(int32_t (*mapping)(int32_t ch),
10885 const String& str, 10896 const String& str,
10897 intptr_t out_length,
10886 Heap::Space space) { 10898 Heap::Space space) {
10887 ASSERT(!str.IsNull()); 10899 ASSERT(!str.IsNull());
10888 intptr_t len = str.Length(); 10900 intptr_t len = str.Length();
10889 const String& result = String::Handle(TwoByteString::New(len, space)); 10901 const String& result =
10890 for (intptr_t i = 0; i < len; ++i) { 10902 String::Handle(TwoByteString::New(out_length, space));
10891 int32_t ch = mapping(str.CharAt(i)); 10903 for (intptr_t i = 0, j = 0; i < len; ++i, j++) {
10892 ASSERT(ch >= 0 && ch <= 0xFFFF); 10904 int32_t old_ch = Utf16::CodePointAt(str, i);
10893 *CharAddr(result, i) = ch; 10905 if (old_ch > Utf16::kMaxCodeUnit) i++;
10906 int32_t ch = mapping(old_ch);
10907 ASSERT(ch <= Utf16::kMaxCodePoint);
10908 if (ch <= Utf16::kMaxCodeUnit) {
10909 *CharAddr(result, j) = ch;
10910 } else {
10911 *CharAddr(result, j) = Utf16::LeadFromCodePoint(ch);
10912 *CharAddr(result, j + 1) = Utf16::TrailFromCodePoint(ch);
10913 ++j;
10914 }
10915 ASSERT(j <= out_length);
10894 } 10916 }
10895 return TwoByteString::raw(result); 10917 return TwoByteString::raw(result);
10896 } 10918 }
10897 10919
10898 10920
10899 RawExternalOneByteString* ExternalOneByteString::New( 10921 RawExternalOneByteString* ExternalOneByteString::New(
10900 const uint8_t* data, 10922 const uint8_t* data,
10901 intptr_t len, 10923 intptr_t len,
10902 void* peer, 10924 void* peer,
10903 Dart_PeerFinalizer callback, 10925 Dart_PeerFinalizer callback,
(...skipping 1182 matching lines...) Expand 10 before | Expand all | Expand 10 after
12086 } 12108 }
12087 return result.raw(); 12109 return result.raw();
12088 } 12110 }
12089 12111
12090 12112
12091 const char* WeakProperty::ToCString() const { 12113 const char* WeakProperty::ToCString() const {
12092 return "_WeakProperty"; 12114 return "_WeakProperty";
12093 } 12115 }
12094 12116
12095 } // namespace dart 12117 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/object_test.cc » ('j') | runtime/vm/scanner.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698