OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |