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 597 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
608 name = Symbols::OneByteString(); | 608 name = Symbols::OneByteString(); |
609 RegisterPrivateClass(cls, name, core_impl_lib); | 609 RegisterPrivateClass(cls, name, core_impl_lib); |
610 pending_classes.Add(cls, Heap::kOld); | 610 pending_classes.Add(cls, Heap::kOld); |
611 | 611 |
612 cls = Class::New<TwoByteString>(); | 612 cls = Class::New<TwoByteString>(); |
613 object_store->set_two_byte_string_class(cls); | 613 object_store->set_two_byte_string_class(cls); |
614 name = Symbols::TwoByteString(); | 614 name = Symbols::TwoByteString(); |
615 RegisterPrivateClass(cls, name, core_impl_lib); | 615 RegisterPrivateClass(cls, name, core_impl_lib); |
616 pending_classes.Add(cls, Heap::kOld); | 616 pending_classes.Add(cls, Heap::kOld); |
617 | 617 |
618 cls = Class::New<FourByteString>(); | |
619 object_store->set_four_byte_string_class(cls); | |
620 name = Symbols::FourByteString(); | |
621 RegisterPrivateClass(cls, name, core_impl_lib); | |
622 pending_classes.Add(cls, Heap::kOld); | |
623 | |
624 cls = Class::New<ExternalOneByteString>(); | 618 cls = Class::New<ExternalOneByteString>(); |
625 object_store->set_external_one_byte_string_class(cls); | 619 object_store->set_external_one_byte_string_class(cls); |
626 name = Symbols::ExternalOneByteString(); | 620 name = Symbols::ExternalOneByteString(); |
627 RegisterPrivateClass(cls, name, core_impl_lib); | 621 RegisterPrivateClass(cls, name, core_impl_lib); |
628 pending_classes.Add(cls, Heap::kOld); | 622 pending_classes.Add(cls, Heap::kOld); |
629 | 623 |
630 cls = Class::New<ExternalTwoByteString>(); | 624 cls = Class::New<ExternalTwoByteString>(); |
631 object_store->set_external_two_byte_string_class(cls); | 625 object_store->set_external_two_byte_string_class(cls); |
632 name = Symbols::ExternalTwoByteString(); | 626 name = Symbols::ExternalTwoByteString(); |
633 RegisterPrivateClass(cls, name, core_impl_lib); | 627 RegisterPrivateClass(cls, name, core_impl_lib); |
634 pending_classes.Add(cls, Heap::kOld); | 628 pending_classes.Add(cls, Heap::kOld); |
635 | 629 |
636 cls = Class::New<ExternalFourByteString>(); | |
637 object_store->set_external_four_byte_string_class(cls); | |
638 name = Symbols::ExternalFourByteString(); | |
639 RegisterPrivateClass(cls, name, core_impl_lib); | |
640 pending_classes.Add(cls, Heap::kOld); | |
641 | |
642 cls = Class::New<Stacktrace>(); | 630 cls = Class::New<Stacktrace>(); |
643 object_store->set_stacktrace_class(cls); | 631 object_store->set_stacktrace_class(cls); |
644 name = Symbols::Stacktrace(); | 632 name = Symbols::Stacktrace(); |
645 RegisterClass(cls, name, core_impl_lib); | 633 RegisterClass(cls, name, core_impl_lib); |
646 pending_classes.Add(cls, Heap::kOld); | 634 pending_classes.Add(cls, Heap::kOld); |
647 // Super type set below, after Object is allocated. | 635 // Super type set below, after Object is allocated. |
648 | 636 |
649 cls = Class::New<JSRegExp>(); | 637 cls = Class::New<JSRegExp>(); |
650 object_store->set_jsregexp_class(cls); | 638 object_store->set_jsregexp_class(cls); |
651 name = Symbols::JSSyntaxRegExp(); | 639 name = Symbols::JSSyntaxRegExp(); |
(...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1090 | 1078 |
1091 cls = Class::New<Bigint>(); | 1079 cls = Class::New<Bigint>(); |
1092 object_store->set_bigint_class(cls); | 1080 object_store->set_bigint_class(cls); |
1093 | 1081 |
1094 cls = Class::New<OneByteString>(); | 1082 cls = Class::New<OneByteString>(); |
1095 object_store->set_one_byte_string_class(cls); | 1083 object_store->set_one_byte_string_class(cls); |
1096 | 1084 |
1097 cls = Class::New<TwoByteString>(); | 1085 cls = Class::New<TwoByteString>(); |
1098 object_store->set_two_byte_string_class(cls); | 1086 object_store->set_two_byte_string_class(cls); |
1099 | 1087 |
1100 cls = Class::New<FourByteString>(); | |
1101 object_store->set_four_byte_string_class(cls); | |
1102 | |
1103 cls = Class::New<ExternalOneByteString>(); | 1088 cls = Class::New<ExternalOneByteString>(); |
1104 object_store->set_external_one_byte_string_class(cls); | 1089 object_store->set_external_one_byte_string_class(cls); |
1105 | 1090 |
1106 cls = Class::New<ExternalTwoByteString>(); | 1091 cls = Class::New<ExternalTwoByteString>(); |
1107 object_store->set_external_two_byte_string_class(cls); | 1092 object_store->set_external_two_byte_string_class(cls); |
1108 | 1093 |
1109 cls = Class::New<ExternalFourByteString>(); | |
1110 object_store->set_external_four_byte_string_class(cls); | |
1111 | |
1112 cls = Class::New<Bool>(); | 1094 cls = Class::New<Bool>(); |
1113 object_store->set_bool_class(cls); | 1095 object_store->set_bool_class(cls); |
1114 | 1096 |
1115 cls = Class::New<Stacktrace>(); | 1097 cls = Class::New<Stacktrace>(); |
1116 object_store->set_stacktrace_class(cls); | 1098 object_store->set_stacktrace_class(cls); |
1117 | 1099 |
1118 cls = Class::New<JSRegExp>(); | 1100 cls = Class::New<JSRegExp>(); |
1119 object_store->set_jsregexp_class(cls); | 1101 object_store->set_jsregexp_class(cls); |
1120 | 1102 |
1121 // Some classes are not stored in the object store. Yet we still need to | 1103 // Some classes are not stored in the object store. Yet we still need to |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1234 switch (id()) { | 1216 switch (id()) { |
1235 case kIntegerCid: | 1217 case kIntegerCid: |
1236 case kSmiCid: | 1218 case kSmiCid: |
1237 case kMintCid: | 1219 case kMintCid: |
1238 case kBigintCid: | 1220 case kBigintCid: |
1239 return Symbols::New("int"); | 1221 return Symbols::New("int"); |
1240 case kDoubleCid: | 1222 case kDoubleCid: |
1241 return Symbols::New("double"); | 1223 return Symbols::New("double"); |
1242 case kOneByteStringCid: | 1224 case kOneByteStringCid: |
1243 case kTwoByteStringCid: | 1225 case kTwoByteStringCid: |
1244 case kFourByteStringCid: | |
1245 case kExternalOneByteStringCid: | 1226 case kExternalOneByteStringCid: |
1246 case kExternalTwoByteStringCid: | 1227 case kExternalTwoByteStringCid: |
1247 case kExternalFourByteStringCid: | |
1248 return Symbols::New("String"); | 1228 return Symbols::New("String"); |
1249 case kArrayCid: | 1229 case kArrayCid: |
1250 case kImmutableArrayCid: | 1230 case kImmutableArrayCid: |
1251 case kGrowableObjectArrayCid: | 1231 case kGrowableObjectArrayCid: |
1252 return Symbols::New("List"); | 1232 return Symbols::New("List"); |
1253 case kInt8ArrayCid: | 1233 case kInt8ArrayCid: |
1254 case kExternalInt8ArrayCid: | 1234 case kExternalInt8ArrayCid: |
1255 return Symbols::New("Int8List"); | 1235 return Symbols::New("Int8List"); |
1256 case kUint8ArrayCid: | 1236 case kUint8ArrayCid: |
1257 case kExternalUint8ArrayCid: | 1237 case kExternalUint8ArrayCid: |
(...skipping 8583 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9841 const String& other_string = String::Cast(other); | 9821 const String& other_string = String::Cast(other); |
9842 if (this->HasHash() && other_string.HasHash() && | 9822 if (this->HasHash() && other_string.HasHash() && |
9843 (this->Hash() != other_string.Hash())) { | 9823 (this->Hash() != other_string.Hash())) { |
9844 return false; // Both sides have a hash code and it does not match. | 9824 return false; // Both sides have a hash code and it does not match. |
9845 } | 9825 } |
9846 return Equals(other_string, 0, other_string.Length()); | 9826 return Equals(other_string, 0, other_string.Length()); |
9847 } | 9827 } |
9848 | 9828 |
9849 | 9829 |
9850 bool String::Equals(const char* str) const { | 9830 bool String::Equals(const char* str) const { |
| 9831 ASSERT(str != NULL); |
| 9832 intptr_t len = strlen(str); |
9851 for (intptr_t i = 0; i < this->Length(); ++i) { | 9833 for (intptr_t i = 0; i < this->Length(); ++i) { |
9852 if (*str == '\0') { | 9834 if (*str == '\0') { |
9853 // Lengths don't match. | 9835 // Lengths don't match. |
9854 return false; | 9836 return false; |
9855 } | 9837 } |
9856 int32_t ch; | 9838 int32_t ch; |
9857 intptr_t consumed = Utf8::Decode(str, &ch); | 9839 intptr_t consumed = Utf8::Decode(reinterpret_cast<const uint8_t*>(str), |
| 9840 len, |
| 9841 &ch); |
9858 if (consumed == 0 || this->CharAt(i) != ch) { | 9842 if (consumed == 0 || this->CharAt(i) != ch) { |
9859 return false; | 9843 return false; |
9860 } | 9844 } |
9861 str += consumed; | 9845 str += consumed; |
| 9846 len -= consumed; |
9862 } | 9847 } |
9863 return *str == '\0'; | 9848 return *str == '\0'; |
9864 } | 9849 } |
9865 | 9850 |
9866 | 9851 |
9867 bool String::Equals(const uint8_t* characters, intptr_t len) const { | 9852 bool String::Equals(const uint8_t* characters, intptr_t len) const { |
9868 if (len != this->Length()) { | 9853 if (len != this->Length()) { |
9869 // Lengths don't match. | 9854 // Lengths don't match. |
9870 return false; | 9855 return false; |
9871 } | 9856 } |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9945 | 9930 |
9946 RawInstance* String::Canonicalize() const { | 9931 RawInstance* String::Canonicalize() const { |
9947 if (IsCanonical()) { | 9932 if (IsCanonical()) { |
9948 return this->raw(); | 9933 return this->raw(); |
9949 } | 9934 } |
9950 return Symbols::New(*this); | 9935 return Symbols::New(*this); |
9951 } | 9936 } |
9952 | 9937 |
9953 | 9938 |
9954 RawString* String::New(const char* str, Heap::Space space) { | 9939 RawString* String::New(const char* str, Heap::Space space) { |
9955 intptr_t width = 0; | 9940 ASSERT(str != NULL); |
9956 intptr_t len = Utf8::CodePointCount(str, &width); | 9941 intptr_t array_len = strlen(str); |
9957 if (width == 1) { | 9942 const uint8_t* utf8_array = reinterpret_cast<const uint8_t*>(str); |
9958 const OneByteString& onestr | 9943 return String::New(utf8_array, array_len, space); |
| 9944 } |
| 9945 |
| 9946 |
| 9947 RawString* String::New(const uint8_t* utf8_array, |
| 9948 intptr_t array_len, |
| 9949 Heap::Space space) { |
| 9950 Utf8::Type type; |
| 9951 intptr_t len = Utf8::CodePointCount(utf8_array, array_len, &type); |
| 9952 if (type == Utf8::kISOLatin1) { |
| 9953 const OneByteString& strobj |
9959 = OneByteString::Handle(OneByteString::New(len, space)); | 9954 = OneByteString::Handle(OneByteString::New(len, space)); |
9960 if (len > 0) { | 9955 if (len > 0) { |
9961 NoGCScope no_gc; | 9956 NoGCScope no_gc; |
9962 Utf8::Decode(str, onestr.CharAddr(0), len); | 9957 Utf8::DecodeToISOLatin1(utf8_array, array_len, strobj.CharAddr(0), len); |
9963 } | 9958 } |
9964 return onestr.raw(); | 9959 return strobj.raw(); |
9965 } else if (width == 2) { | |
9966 const TwoByteString& twostr = | |
9967 TwoByteString::Handle(TwoByteString::New(len, space)); | |
9968 NoGCScope no_gc; | |
9969 Utf8::Decode(str, twostr.CharAddr(0), len); | |
9970 return twostr.raw(); | |
9971 } | 9960 } |
9972 ASSERT(width == 4); | 9961 ASSERT((type == Utf8::kBMP) || (type == Utf8::kSMP)); |
9973 const FourByteString& fourstr = | 9962 const TwoByteString& strobj = |
9974 FourByteString::Handle(FourByteString::New(len, space)); | 9963 TwoByteString::Handle(TwoByteString::New(len, space)); |
9975 NoGCScope no_gc; | 9964 NoGCScope no_gc; |
9976 Utf8::Decode(str, fourstr.CharAddr(0), len); | 9965 Utf8::DecodeToUTF16(utf8_array, array_len, strobj.CharAddr(0), len); |
9977 return fourstr.raw(); | 9966 return strobj.raw(); |
9978 } | 9967 } |
9979 | 9968 |
9980 | 9969 |
9981 RawString* String::New(const uint8_t* characters, | 9970 RawString* String::New(const uint16_t* utf16_array, |
9982 intptr_t len, | 9971 intptr_t array_len, |
9983 Heap::Space space) { | |
9984 return OneByteString::New(characters, len, space); | |
9985 } | |
9986 | |
9987 | |
9988 RawString* String::New(const uint16_t* characters, | |
9989 intptr_t len, | |
9990 Heap::Space space) { | 9972 Heap::Space space) { |
9991 bool is_one_byte_string = true; | 9973 bool is_one_byte_string = true; |
9992 for (intptr_t i = 0; i < len; ++i) { | 9974 for (intptr_t i = 0; i < array_len; ++i) { |
9993 if (characters[i] > 0xFF) { | 9975 if (utf16_array[i] > 0xFF) { |
9994 is_one_byte_string = false; | 9976 is_one_byte_string = false; |
9995 break; | 9977 break; |
9996 } | 9978 } |
9997 } | 9979 } |
9998 if (is_one_byte_string) { | 9980 if (is_one_byte_string) { |
9999 return OneByteString::New(characters, len, space); | 9981 return OneByteString::New(utf16_array, array_len, space); |
10000 } | 9982 } |
10001 return TwoByteString::New(characters, len, space); | 9983 return TwoByteString::New(utf16_array, array_len, space); |
10002 } | 9984 } |
10003 | 9985 |
10004 | 9986 |
10005 RawString* String::New(const uint32_t* characters, | 9987 RawString* String::New(const uint32_t* utf32_array, |
10006 intptr_t len, | 9988 intptr_t array_len, |
10007 Heap::Space space) { | 9989 Heap::Space space) { |
10008 bool is_one_byte_string = true; | 9990 bool is_one_byte_string = true; |
10009 bool is_two_byte_string = true; | 9991 intptr_t utf16_len = array_len; |
10010 for (intptr_t i = 0; i < len; ++i) { | 9992 for (intptr_t i = 0; i < array_len; ++i) { |
10011 if (characters[i] > 0xFFFF) { | 9993 if (utf32_array[i] > 0xFF) { |
10012 is_two_byte_string = false; | |
10013 is_one_byte_string = false; | 9994 is_one_byte_string = false; |
10014 break; | 9995 } |
10015 } else if (characters[i] > 0xFF) { | 9996 if (utf32_array[i] > 0xFFFF) { |
10016 is_one_byte_string = false; | 9997 utf16_len += 1; |
10017 } | 9998 } |
10018 } | 9999 } |
10019 if (is_one_byte_string) { | 10000 if (is_one_byte_string) { |
10020 return OneByteString::New(characters, len, space); | 10001 return OneByteString::New(utf32_array, array_len, space); |
10021 } else if (is_two_byte_string) { | |
10022 return TwoByteString::New(characters, len, space); | |
10023 } | 10002 } |
10024 return FourByteString::New(characters, len, space); | 10003 return TwoByteString::New(utf16_len, utf32_array, array_len, space); |
10025 } | 10004 } |
10026 | 10005 |
10027 | 10006 |
10028 RawString* String::New(const String& str, Heap::Space space) { | 10007 RawString* String::New(const String& str, Heap::Space space) { |
10029 // Currently this just creates a copy of the string in the correct space. | 10008 // Currently this just creates a copy of the string in the correct space. |
10030 // Once we have external string support, this will also create a heap copy of | 10009 // Once we have external string support, this will also create a heap copy of |
10031 // the string if necessary. Some optimizations are possible, such as not | 10010 // the string if necessary. Some optimizations are possible, such as not |
10032 // copying internal strings into the same space. | 10011 // copying internal strings into the same space. |
10033 intptr_t len = str.Length(); | 10012 intptr_t len = str.Length(); |
10034 String& result = String::Handle(); | 10013 String& result = String::Handle(); |
10035 intptr_t char_size = str.CharSize(); | 10014 intptr_t char_size = str.CharSize(); |
10036 if (char_size == kOneByteChar) { | 10015 if (char_size == kOneByteChar) { |
10037 result ^= OneByteString::New(len, space); | 10016 result ^= OneByteString::New(len, space); |
10038 } else if (char_size == kTwoByteChar) { | 10017 } else { |
| 10018 ASSERT(char_size == kTwoByteChar); |
10039 result ^= TwoByteString::New(len, space); | 10019 result ^= TwoByteString::New(len, space); |
10040 } else { | |
10041 ASSERT(char_size == kFourByteChar); | |
10042 result ^= FourByteString::New(len, space); | |
10043 } | 10020 } |
10044 String::Copy(result, 0, str, 0, len); | 10021 String::Copy(result, 0, str, 0, len); |
10045 return result.raw(); | 10022 return result.raw(); |
10046 } | 10023 } |
10047 | 10024 |
10048 | 10025 |
10049 RawString* String::NewExternal(const uint8_t* characters, | 10026 RawString* String::NewExternal(const uint8_t* characters, |
10050 intptr_t len, | 10027 intptr_t len, |
10051 void* peer, | 10028 void* peer, |
10052 Dart_PeerFinalizer callback, | 10029 Dart_PeerFinalizer callback, |
10053 Heap::Space space) { | 10030 Heap::Space space) { |
10054 return ExternalOneByteString::New(characters, len, peer, callback, space); | 10031 return ExternalOneByteString::New(characters, len, peer, callback, space); |
10055 } | 10032 } |
10056 | 10033 |
10057 | 10034 |
10058 RawString* String::NewExternal(const uint16_t* characters, | 10035 RawString* String::NewExternal(const uint16_t* characters, |
10059 intptr_t len, | 10036 intptr_t len, |
10060 void* peer, | 10037 void* peer, |
10061 Dart_PeerFinalizer callback, | 10038 Dart_PeerFinalizer callback, |
10062 Heap::Space space) { | 10039 Heap::Space space) { |
10063 return ExternalTwoByteString::New(characters, len, peer, callback, space); | 10040 return ExternalTwoByteString::New(characters, len, peer, callback, space); |
10064 } | 10041 } |
10065 | 10042 |
10066 | 10043 |
10067 RawString* String::NewExternal(const uint32_t* characters, | |
10068 intptr_t len, | |
10069 void* peer, | |
10070 Dart_PeerFinalizer callback, | |
10071 Heap::Space space) { | |
10072 return ExternalFourByteString::New(characters, len, peer, callback, space); | |
10073 } | |
10074 | |
10075 | |
10076 void String::Copy(const String& dst, intptr_t dst_offset, | 10044 void String::Copy(const String& dst, intptr_t dst_offset, |
10077 const uint8_t* characters, | 10045 const uint8_t* characters, |
10078 intptr_t len) { | 10046 intptr_t len) { |
10079 ASSERT(dst_offset >= 0); | 10047 ASSERT(dst_offset >= 0); |
10080 ASSERT(len >= 0); | 10048 ASSERT(len >= 0); |
10081 ASSERT(len <= (dst.Length() - dst_offset)); | 10049 ASSERT(len <= (dst.Length() - dst_offset)); |
10082 if (dst.IsOneByteString()) { | 10050 if (dst.IsOneByteString()) { |
10083 const OneByteString& onestr = OneByteString::Cast(dst); | 10051 const OneByteString& onestr = OneByteString::Cast(dst); |
10084 NoGCScope no_gc; | 10052 NoGCScope no_gc; |
10085 if (len > 0) { | 10053 if (len > 0) { |
10086 memmove(onestr.CharAddr(dst_offset), characters, len); | 10054 memmove(onestr.CharAddr(dst_offset), characters, len); |
10087 } | 10055 } |
10088 } else if (dst.IsTwoByteString()) { | 10056 } else if (dst.IsTwoByteString()) { |
10089 const TwoByteString& twostr = TwoByteString::Cast(dst); | 10057 const TwoByteString& twostr = TwoByteString::Cast(dst); |
10090 NoGCScope no_gc; | 10058 NoGCScope no_gc; |
10091 for (intptr_t i = 0; i < len; ++i) { | 10059 for (intptr_t i = 0; i < len; ++i) { |
10092 *twostr.CharAddr(i + dst_offset) = characters[i]; | 10060 *twostr.CharAddr(i + dst_offset) = characters[i]; |
10093 } | 10061 } |
10094 } else { | |
10095 ASSERT(dst.IsFourByteString()); | |
10096 const FourByteString& fourstr = FourByteString::Cast(dst); | |
10097 NoGCScope no_gc; | |
10098 for (intptr_t i = 0; i < len; ++i) { | |
10099 *fourstr.CharAddr(i + dst_offset) = characters[i]; | |
10100 } | |
10101 } | 10062 } |
10102 } | 10063 } |
10103 | 10064 |
10104 | 10065 |
10105 void String::Copy(const String& dst, intptr_t dst_offset, | 10066 void String::Copy(const String& dst, intptr_t dst_offset, |
10106 const uint16_t* characters, | 10067 const uint16_t* utf16_array, |
10107 intptr_t len) { | 10068 intptr_t array_len) { |
10108 ASSERT(dst_offset >= 0); | 10069 ASSERT(dst_offset >= 0); |
10109 ASSERT(len >= 0); | 10070 ASSERT(array_len >= 0); |
10110 ASSERT(len <= (dst.Length() - dst_offset)); | 10071 ASSERT(array_len <= (dst.Length() - dst_offset)); |
10111 if (dst.IsOneByteString()) { | 10072 if (dst.IsOneByteString()) { |
10112 const OneByteString& onestr = OneByteString::Cast(dst); | 10073 const OneByteString& onestr = OneByteString::Cast(dst); |
10113 NoGCScope no_gc; | 10074 NoGCScope no_gc; |
10114 for (intptr_t i = 0; i < len; ++i) { | 10075 for (intptr_t i = 0; i < array_len; ++i) { |
10115 ASSERT(characters[i] <= 0xFF); | 10076 ASSERT(utf16_array[i] <= 0xFF); |
10116 *onestr.CharAddr(i + dst_offset) = characters[i]; | 10077 *onestr.CharAddr(i + dst_offset) = utf16_array[i]; |
10117 } | 10078 } |
10118 } else if (dst.IsTwoByteString()) { | 10079 } else { |
| 10080 ASSERT(dst.IsTwoByteString()); |
10119 const TwoByteString& twostr = TwoByteString::Cast(dst); | 10081 const TwoByteString& twostr = TwoByteString::Cast(dst); |
10120 NoGCScope no_gc; | 10082 NoGCScope no_gc; |
10121 if (len > 0) { | 10083 if (array_len > 0) { |
10122 memmove(twostr.CharAddr(dst_offset), characters, len * 2); | 10084 memmove(twostr.CharAddr(dst_offset), utf16_array, (array_len * 2)); |
10123 } | |
10124 } else { | |
10125 ASSERT(dst.IsFourByteString()); | |
10126 const FourByteString& fourstr = FourByteString::Cast(dst); | |
10127 NoGCScope no_gc; | |
10128 for (intptr_t i = 0; i < len; ++i) { | |
10129 *fourstr.CharAddr(i + dst_offset) = characters[i]; | |
10130 } | 10085 } |
10131 } | 10086 } |
10132 } | 10087 } |
10133 | 10088 |
10134 | |
10135 void String::Copy(const String& dst, intptr_t dst_offset, | |
10136 const uint32_t* characters, | |
10137 intptr_t len) { | |
10138 ASSERT(dst_offset >= 0); | |
10139 ASSERT(len >= 0); | |
10140 ASSERT(len <= (dst.Length() - dst_offset)); | |
10141 if (dst.IsOneByteString()) { | |
10142 const OneByteString& onestr = OneByteString::Cast(dst); | |
10143 NoGCScope no_gc; | |
10144 for (intptr_t i = 0; i < len; ++i) { | |
10145 ASSERT(characters[i] <= 0xFF); | |
10146 *onestr.CharAddr(i + dst_offset) = characters[i]; | |
10147 } | |
10148 } else if (dst.IsTwoByteString()) { | |
10149 const TwoByteString& twostr = TwoByteString::Cast(dst); | |
10150 NoGCScope no_gc; | |
10151 for (intptr_t i = 0; i < len; ++i) { | |
10152 ASSERT(characters[i] <= 0xFFFF); | |
10153 *twostr.CharAddr(i + dst_offset) = characters[i]; | |
10154 } | |
10155 } else { | |
10156 ASSERT(dst.IsFourByteString()); | |
10157 const FourByteString& fourstr = FourByteString::Cast(dst); | |
10158 NoGCScope no_gc; | |
10159 if (len > 0) { | |
10160 memmove(fourstr.CharAddr(dst_offset), characters, len * 4); | |
10161 } | |
10162 } | |
10163 } | |
10164 | |
10165 | 10089 |
10166 void String::Copy(const String& dst, intptr_t dst_offset, | 10090 void String::Copy(const String& dst, intptr_t dst_offset, |
10167 const String& src, intptr_t src_offset, | 10091 const String& src, intptr_t src_offset, |
10168 intptr_t len) { | 10092 intptr_t len) { |
10169 ASSERT(dst_offset >= 0); | 10093 ASSERT(dst_offset >= 0); |
10170 ASSERT(src_offset >= 0); | 10094 ASSERT(src_offset >= 0); |
10171 ASSERT(len >= 0); | 10095 ASSERT(len >= 0); |
10172 ASSERT(len <= (dst.Length() - dst_offset)); | 10096 ASSERT(len <= (dst.Length() - dst_offset)); |
10173 ASSERT(len <= (src.Length() - src_offset)); | 10097 ASSERT(len <= (src.Length() - src_offset)); |
10174 if (len > 0) { | 10098 if (len > 0) { |
10175 intptr_t char_size = src.CharSize(); | 10099 intptr_t char_size = src.CharSize(); |
10176 if (char_size == kOneByteChar) { | 10100 if (char_size == kOneByteChar) { |
10177 if (src.IsOneByteString()) { | 10101 if (src.IsOneByteString()) { |
10178 const OneByteString& onestr = OneByteString::Cast(src); | 10102 const OneByteString& onestr = OneByteString::Cast(src); |
10179 NoGCScope no_gc; | 10103 NoGCScope no_gc; |
10180 String::Copy(dst, dst_offset, onestr.CharAddr(0) + src_offset, len); | 10104 String::Copy(dst, dst_offset, onestr.CharAddr(0) + src_offset, len); |
10181 } else { | 10105 } else { |
10182 ASSERT(src.IsExternalOneByteString()); | 10106 ASSERT(src.IsExternalOneByteString()); |
10183 const ExternalOneByteString& onestr = ExternalOneByteString::Cast(src); | 10107 const ExternalOneByteString& onestr = ExternalOneByteString::Cast(src); |
10184 NoGCScope no_gc; | 10108 NoGCScope no_gc; |
10185 String::Copy(dst, dst_offset, onestr.CharAddr(0) + src_offset, len); | 10109 String::Copy(dst, dst_offset, onestr.CharAddr(0) + src_offset, len); |
10186 } | 10110 } |
10187 } else if (char_size == kTwoByteChar) { | 10111 } else { |
| 10112 ASSERT(char_size == kTwoByteChar); |
10188 if (src.IsTwoByteString()) { | 10113 if (src.IsTwoByteString()) { |
10189 const TwoByteString& twostr = TwoByteString::Cast(src); | 10114 const TwoByteString& twostr = TwoByteString::Cast(src); |
10190 NoGCScope no_gc; | 10115 NoGCScope no_gc; |
10191 String::Copy(dst, dst_offset, twostr.CharAddr(0) + src_offset, len); | 10116 String::Copy(dst, dst_offset, twostr.CharAddr(0) + src_offset, len); |
10192 } else { | 10117 } else { |
10193 ASSERT(src.IsExternalTwoByteString()); | 10118 ASSERT(src.IsExternalTwoByteString()); |
10194 const ExternalTwoByteString& twostr = ExternalTwoByteString::Cast(src); | 10119 const ExternalTwoByteString& twostr = ExternalTwoByteString::Cast(src); |
10195 NoGCScope no_gc; | 10120 NoGCScope no_gc; |
10196 String::Copy(dst, dst_offset, twostr.CharAddr(0) + src_offset, len); | 10121 String::Copy(dst, dst_offset, twostr.CharAddr(0) + src_offset, len); |
10197 } | 10122 } |
10198 } else { | |
10199 ASSERT(char_size == kFourByteChar); | |
10200 if (src.IsFourByteString()) { | |
10201 const FourByteString& fourstr = FourByteString::Cast(src); | |
10202 NoGCScope no_gc; | |
10203 String::Copy(dst, dst_offset, fourstr.CharAddr(0) + src_offset, len); | |
10204 } else { | |
10205 ASSERT(src.IsExternalFourByteString()); | |
10206 const ExternalFourByteString& fourstr = | |
10207 ExternalFourByteString::Cast(src); | |
10208 NoGCScope no_gc; | |
10209 String::Copy(dst, dst_offset, fourstr.CharAddr(0) + src_offset, len); | |
10210 } | |
10211 } | 10123 } |
10212 } | 10124 } |
10213 } | 10125 } |
10214 | 10126 |
10215 | 10127 |
10216 RawString* String::EscapeSpecialCharacters(const String& str, bool raw_str) { | 10128 RawString* String::EscapeSpecialCharacters(const String& str, bool raw_str) { |
10217 if (str.IsOneByteString()) { | 10129 if (str.IsOneByteString()) { |
10218 const OneByteString& onestr = OneByteString::Cast(str); | 10130 const OneByteString& onestr = OneByteString::Cast(str); |
10219 return onestr.EscapeSpecialCharacters(raw_str); | 10131 return onestr.EscapeSpecialCharacters(raw_str); |
10220 } | 10132 } |
10221 if (str.IsTwoByteString()) { | 10133 ASSERT(str.IsTwoByteString()); |
10222 const TwoByteString& twostr = TwoByteString::Cast(str); | 10134 const TwoByteString& twostr = TwoByteString::Cast(str); |
10223 return twostr.EscapeSpecialCharacters(raw_str); | 10135 return twostr.EscapeSpecialCharacters(raw_str); |
10224 } | |
10225 ASSERT(str.IsFourByteString()); | |
10226 const FourByteString& fourstr = FourByteString::Cast(str); | |
10227 return fourstr.EscapeSpecialCharacters(raw_str); | |
10228 } | 10136 } |
10229 | 10137 |
10230 | 10138 |
10231 RawString* String::NewFormatted(const char* format, ...) { | 10139 RawString* String::NewFormatted(const char* format, ...) { |
10232 va_list args; | 10140 va_list args; |
10233 va_start(args, format); | 10141 va_start(args, format); |
10234 RawString* result = NewFormattedV(format, args); | 10142 RawString* result = NewFormattedV(format, args); |
10235 NoGCScope no_gc; | 10143 NoGCScope no_gc; |
10236 va_end(args); | 10144 va_end(args); |
10237 return result; | 10145 return result; |
(...skipping 12 matching lines...) Expand all Loading... |
10250 | 10158 |
10251 return String::New(buffer); | 10159 return String::New(buffer); |
10252 } | 10160 } |
10253 | 10161 |
10254 | 10162 |
10255 RawString* String::Concat(const String& str1, | 10163 RawString* String::Concat(const String& str1, |
10256 const String& str2, | 10164 const String& str2, |
10257 Heap::Space space) { | 10165 Heap::Space space) { |
10258 ASSERT(!str1.IsNull() && !str2.IsNull()); | 10166 ASSERT(!str1.IsNull() && !str2.IsNull()); |
10259 intptr_t char_size = Utils::Maximum(str1.CharSize(), str2.CharSize()); | 10167 intptr_t char_size = Utils::Maximum(str1.CharSize(), str2.CharSize()); |
10260 if (char_size == kFourByteChar) { | |
10261 return FourByteString::Concat(str1, str2, space); | |
10262 } | |
10263 if (char_size == kTwoByteChar) { | 10168 if (char_size == kTwoByteChar) { |
10264 return TwoByteString::Concat(str1, str2, space); | 10169 return TwoByteString::Concat(str1, str2, space); |
10265 } | 10170 } |
10266 return OneByteString::Concat(str1, str2, space); | 10171 return OneByteString::Concat(str1, str2, space); |
10267 } | 10172 } |
10268 | 10173 |
10269 | 10174 |
10270 RawString* String::ConcatAll(const Array& strings, | 10175 RawString* String::ConcatAll(const Array& strings, |
10271 Heap::Space space) { | 10176 Heap::Space space) { |
10272 ASSERT(!strings.IsNull()); | 10177 ASSERT(!strings.IsNull()); |
10273 intptr_t result_len = 0; | 10178 intptr_t result_len = 0; |
10274 intptr_t strings_len = strings.Length(); | 10179 intptr_t strings_len = strings.Length(); |
10275 String& str = String::Handle(); | 10180 String& str = String::Handle(); |
10276 intptr_t char_size = kOneByteChar; | 10181 intptr_t char_size = kOneByteChar; |
10277 for (intptr_t i = 0; i < strings_len; i++) { | 10182 for (intptr_t i = 0; i < strings_len; i++) { |
10278 str ^= strings.At(i); | 10183 str ^= strings.At(i); |
10279 result_len += str.Length(); | 10184 result_len += str.Length(); |
10280 char_size = Utils::Maximum(char_size, str.CharSize()); | 10185 char_size = Utils::Maximum(char_size, str.CharSize()); |
10281 } | 10186 } |
10282 if (char_size == kOneByteChar) { | 10187 if (char_size == kOneByteChar) { |
10283 return OneByteString::ConcatAll(strings, result_len, space); | 10188 return OneByteString::ConcatAll(strings, result_len, space); |
10284 } else if (char_size == kTwoByteChar) { | |
10285 return TwoByteString::ConcatAll(strings, result_len, space); | |
10286 } | 10189 } |
10287 ASSERT(char_size == kFourByteChar); | 10190 ASSERT(char_size == kTwoByteChar); |
10288 return FourByteString::ConcatAll(strings, result_len, space); | 10191 return TwoByteString::ConcatAll(strings, result_len, space); |
10289 } | 10192 } |
10290 | 10193 |
10291 | 10194 |
10292 RawString* String::SubString(const String& str, | 10195 RawString* String::SubString(const String& str, |
10293 intptr_t begin_index, | 10196 intptr_t begin_index, |
10294 Heap::Space space) { | 10197 Heap::Space space) { |
10295 ASSERT(!str.IsNull()); | 10198 ASSERT(!str.IsNull()); |
10296 if (begin_index >= str.Length()) { | 10199 if (begin_index >= str.Length()) { |
10297 return String::null(); | 10200 return String::null(); |
10298 } | 10201 } |
10299 return String::SubString(str, begin_index, (str.Length() - begin_index)); | 10202 return String::SubString(str, begin_index, (str.Length() - begin_index)); |
10300 } | 10203 } |
10301 | 10204 |
10302 | 10205 |
10303 RawString* String::SubString(const String& str, | 10206 RawString* String::SubString(const String& str, |
10304 intptr_t begin_index, | 10207 intptr_t begin_index, |
10305 intptr_t length, | 10208 intptr_t length, |
10306 Heap::Space space) { | 10209 Heap::Space space) { |
10307 ASSERT(!str.IsNull()); | 10210 ASSERT(!str.IsNull()); |
10308 ASSERT(begin_index >= 0); | 10211 ASSERT(begin_index >= 0); |
10309 ASSERT(length >= 0); | 10212 ASSERT(length >= 0); |
10310 if (begin_index <= str.Length() && length == 0) { | 10213 if (begin_index <= str.Length() && length == 0) { |
10311 return Symbols::Empty(); | 10214 return Symbols::Empty(); |
10312 } | 10215 } |
10313 if (begin_index > str.Length()) { | 10216 if (begin_index > str.Length()) { |
10314 return String::null(); | 10217 return String::null(); |
10315 } | 10218 } |
10316 String& result = String::Handle(); | 10219 String& result = String::Handle(); |
10317 bool is_one_byte_string = true; | 10220 bool is_one_byte_string = true; |
10318 bool is_two_byte_string = true; | |
10319 intptr_t char_size = str.CharSize(); | 10221 intptr_t char_size = str.CharSize(); |
10320 if (char_size == kTwoByteChar) { | 10222 if (char_size == kTwoByteChar) { |
10321 for (intptr_t i = begin_index; i < begin_index + length; ++i) { | 10223 for (intptr_t i = begin_index; i < begin_index + length; ++i) { |
10322 if (str.CharAt(i) > 0xFF) { | 10224 if (str.CharAt(i) > 0xFF) { |
10323 is_one_byte_string = false; | 10225 is_one_byte_string = false; |
10324 break; | 10226 break; |
10325 } | 10227 } |
10326 } | 10228 } |
10327 } else if (char_size == kFourByteChar) { | |
10328 for (intptr_t i = begin_index; i < begin_index + length; ++i) { | |
10329 if (str.CharAt(i) > 0xFFFF) { | |
10330 is_one_byte_string = false; | |
10331 is_two_byte_string = false; | |
10332 break; | |
10333 } else if (str.CharAt(i) > 0xFF) { | |
10334 is_one_byte_string = false; | |
10335 } | |
10336 } | |
10337 } | 10229 } |
10338 if (is_one_byte_string) { | 10230 if (is_one_byte_string) { |
10339 result ^= OneByteString::New(length, space); | 10231 result ^= OneByteString::New(length, space); |
10340 } else if (is_two_byte_string) { | 10232 } else { |
10341 result ^= TwoByteString::New(length, space); | 10233 result ^= TwoByteString::New(length, space); |
10342 } else { | |
10343 result ^= FourByteString::New(length, space); | |
10344 } | 10234 } |
10345 String::Copy(result, 0, str, begin_index, length); | 10235 String::Copy(result, 0, str, begin_index, length); |
10346 return result.raw(); | 10236 return result.raw(); |
10347 } | 10237 } |
10348 | 10238 |
10349 | 10239 |
10350 const char* String::ToCString() const { | 10240 const char* String::ToCString() const { |
10351 intptr_t len = Utf8::Length(*this); | 10241 intptr_t len = Utf8::Length(*this); |
10352 Zone* zone = Isolate::Current()->current_zone(); | 10242 Zone* zone = Isolate::Current()->current_zone(); |
10353 char* result = zone->Alloc<char>(len + 1); | 10243 uint8_t* result = zone->Alloc<uint8_t>(len + 1); |
10354 Utf8::Encode(*this, result, len); | 10244 ToUTF8(result, len); |
10355 result[len] = 0; | 10245 result[len] = 0; |
10356 return result; | 10246 return reinterpret_cast<const char*>(result); |
| 10247 } |
| 10248 |
| 10249 |
| 10250 void String::ToUTF8(uint8_t* utf8_array, intptr_t array_len) const { |
| 10251 if (CharSize() == kOneByteChar) { |
| 10252 const OneByteString& obj = OneByteString::Cast(*this); |
| 10253 ASSERT(array_len >= obj.Length()); |
| 10254 if (obj.Length() > 0) { |
| 10255 memmove(utf8_array, obj.CharAddr(0), obj.Length()); |
| 10256 } |
| 10257 } else { |
| 10258 ASSERT(array_len >= Utf8::Length(*this)); |
| 10259 Utf8::Encode(*this, reinterpret_cast<char*>(utf8_array), array_len); |
| 10260 } |
10357 } | 10261 } |
10358 | 10262 |
10359 | 10263 |
10360 RawString* String::Transform(int32_t (*mapping)(int32_t ch), | 10264 RawString* String::Transform(int32_t (*mapping)(int32_t ch), |
10361 const String& str, | 10265 const String& str, |
10362 Heap::Space space) { | 10266 Heap::Space space) { |
10363 ASSERT(!str.IsNull()); | 10267 ASSERT(!str.IsNull()); |
10364 bool has_mapping = false; | 10268 bool has_mapping = false; |
10365 int32_t dst_max = 0; | 10269 int32_t dst_max = 0; |
10366 intptr_t len = str.Length(); | 10270 intptr_t len = str.Length(); |
10367 // TODO(cshapiro): assume a transform is required, rollback if not. | 10271 // TODO(cshapiro): assume a transform is required, rollback if not. |
10368 for (intptr_t i = 0; i < len; ++i) { | 10272 for (intptr_t i = 0; i < len; ++i) { |
10369 int32_t src = str.CharAt(i); | 10273 int32_t src = str.CharAt(i); |
10370 int32_t dst = mapping(src); | 10274 int32_t dst = mapping(src); |
10371 if (src != dst) { | 10275 if (src != dst) { |
10372 has_mapping = true; | 10276 has_mapping = true; |
10373 } | 10277 } |
10374 dst_max = Utils::Maximum(dst_max, dst); | 10278 dst_max = Utils::Maximum(dst_max, dst); |
10375 } | 10279 } |
10376 if (!has_mapping) { | 10280 if (!has_mapping) { |
10377 return str.raw(); | 10281 return str.raw(); |
10378 } | 10282 } |
10379 if (dst_max <= 0xFF) { | 10283 if (dst_max <= 0xFF) { |
10380 return OneByteString::Transform(mapping, str, space); | 10284 return OneByteString::Transform(mapping, str, space); |
10381 } | 10285 } |
10382 if (dst_max <= 0xFFFF) { | 10286 ASSERT(dst_max > 0xFF); |
10383 return TwoByteString::Transform(mapping, str, space); | 10287 return TwoByteString::Transform(mapping, str, space); |
10384 } | |
10385 ASSERT(dst_max > 0xFFFF); | |
10386 return FourByteString::Transform(mapping, str, space); | |
10387 } | 10288 } |
10388 | 10289 |
10389 | 10290 |
10390 RawString* String::ToUpperCase(const String& str, Heap::Space space) { | 10291 RawString* String::ToUpperCase(const String& str, Heap::Space space) { |
10391 // TODO(cshapiro): create a fast-path for OneByteString instances. | 10292 // TODO(cshapiro): create a fast-path for OneByteString instances. |
10392 return Transform(CaseMapping::ToUpper, str, space); | 10293 return Transform(CaseMapping::ToUpper, str, space); |
10393 } | 10294 } |
10394 | 10295 |
10395 | 10296 |
10396 RawString* String::ToLowerCase(const String& str, Heap::Space space) { | 10297 RawString* String::ToLowerCase(const String& str, Heap::Space space) { |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10507 } | 10408 } |
10508 return result.raw(); | 10409 return result.raw(); |
10509 } | 10410 } |
10510 | 10411 |
10511 | 10412 |
10512 RawOneByteString* OneByteString::New(const uint8_t* characters, | 10413 RawOneByteString* OneByteString::New(const uint8_t* characters, |
10513 intptr_t len, | 10414 intptr_t len, |
10514 Heap::Space space) { | 10415 Heap::Space space) { |
10515 const OneByteString& result = | 10416 const OneByteString& result = |
10516 OneByteString::Handle(OneByteString::New(len, space)); | 10417 OneByteString::Handle(OneByteString::New(len, space)); |
10517 String::Copy(result, 0, characters, len); | 10418 if (len > 0) { |
| 10419 NoGCScope no_gc; |
| 10420 memmove(result.CharAddr(0), characters, len); |
| 10421 } |
10518 return result.raw(); | 10422 return result.raw(); |
10519 } | 10423 } |
10520 | 10424 |
10521 | 10425 |
10522 RawOneByteString* OneByteString::New(const uint16_t* characters, | 10426 RawOneByteString* OneByteString::New(const uint16_t* characters, |
10523 intptr_t len, | 10427 intptr_t len, |
10524 Heap::Space space) { | 10428 Heap::Space space) { |
10525 const OneByteString& result = | 10429 const OneByteString& result = |
10526 OneByteString::Handle(OneByteString::New(len, space)); | 10430 OneByteString::Handle(OneByteString::New(len, space)); |
10527 String::Copy(result, 0, characters, len); | 10431 for (intptr_t i = 0; i < len; ++i) { |
| 10432 ASSERT(characters[i] <= 0xFF); |
| 10433 *result.CharAddr(i) = characters[i]; |
| 10434 } |
10528 return result.raw(); | 10435 return result.raw(); |
10529 } | 10436 } |
10530 | 10437 |
10531 | 10438 |
10532 RawOneByteString* OneByteString::New(const uint32_t* characters, | 10439 RawOneByteString* OneByteString::New(const uint32_t* characters, |
10533 intptr_t len, | 10440 intptr_t len, |
10534 Heap::Space space) { | 10441 Heap::Space space) { |
10535 const OneByteString& result = | 10442 const OneByteString& result = |
10536 OneByteString::Handle(OneByteString::New(len, space)); | 10443 OneByteString::Handle(OneByteString::New(len, space)); |
10537 String::Copy(result, 0, characters, len); | 10444 for (intptr_t i = 0; i < len; ++i) { |
| 10445 ASSERT(characters[i] <= 0xFF); |
| 10446 *result.CharAddr(i) = characters[i]; |
| 10447 } |
10538 return result.raw(); | 10448 return result.raw(); |
10539 } | 10449 } |
10540 | 10450 |
10541 | 10451 |
10542 RawOneByteString* OneByteString::New(const OneByteString& str, | 10452 RawOneByteString* OneByteString::New(const OneByteString& str, |
10543 Heap::Space space) { | 10453 Heap::Space space) { |
10544 intptr_t len = str.Length(); | 10454 intptr_t len = str.Length(); |
10545 const OneByteString& result = | 10455 const OneByteString& result = |
10546 OneByteString::Handle(OneByteString::New(len, space)); | 10456 OneByteString::Handle(OneByteString::New(len, space)); |
10547 String::Copy(result, 0, str, 0, len); | 10457 String::Copy(result, 0, str, 0, len); |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10649 space); | 10559 space); |
10650 NoGCScope no_gc; | 10560 NoGCScope no_gc; |
10651 result ^= raw; | 10561 result ^= raw; |
10652 result.SetLength(len); | 10562 result.SetLength(len); |
10653 result.SetHash(0); | 10563 result.SetHash(0); |
10654 } | 10564 } |
10655 return result.raw(); | 10565 return result.raw(); |
10656 } | 10566 } |
10657 | 10567 |
10658 | 10568 |
10659 RawTwoByteString* TwoByteString::New(const uint16_t* characters, | 10569 RawTwoByteString* TwoByteString::New(const uint16_t* utf16_array, |
10660 intptr_t len, | 10570 intptr_t array_len, |
10661 Heap::Space space) { | 10571 Heap::Space space) { |
| 10572 ASSERT(array_len > 0); |
10662 const TwoByteString& result = | 10573 const TwoByteString& result = |
10663 TwoByteString::Handle(TwoByteString::New(len, space)); | 10574 TwoByteString::Handle(TwoByteString::New(array_len, space)); |
10664 String::Copy(result, 0, characters, len); | 10575 { |
| 10576 NoGCScope no_gc; |
| 10577 memmove(result.CharAddr(0), utf16_array, (array_len * 2)); |
| 10578 } |
10665 return result.raw(); | 10579 return result.raw(); |
10666 } | 10580 } |
10667 | 10581 |
10668 | 10582 |
10669 RawTwoByteString* TwoByteString::New(const uint32_t* characters, | 10583 RawTwoByteString* TwoByteString::New(intptr_t utf16_len, |
10670 intptr_t len, | 10584 const uint32_t* utf32_array, |
| 10585 intptr_t array_len, |
10671 Heap::Space space) { | 10586 Heap::Space space) { |
| 10587 ASSERT((array_len > 0) && (utf16_len >= array_len)); |
10672 const TwoByteString& result = | 10588 const TwoByteString& result = |
10673 TwoByteString::Handle(TwoByteString::New(len, space)); | 10589 TwoByteString::Handle(TwoByteString::New(utf16_len, space)); |
10674 String::Copy(result, 0, characters, len); | 10590 { |
| 10591 NoGCScope no_gc; |
| 10592 intptr_t j = 0; |
| 10593 for (intptr_t i = 0; i < array_len; ++i) { |
| 10594 if (utf32_array[i] > 0xffff) { |
| 10595 ASSERT(j < (utf16_len - 1)); |
| 10596 Utf8::ConvertUTF32ToUTF16(utf32_array[i], result.CharAddr(j)); |
| 10597 j += 2; |
| 10598 } else { |
| 10599 ASSERT(j < utf16_len); |
| 10600 *result.CharAddr(j) = utf32_array[i]; |
| 10601 j += 1; |
| 10602 } |
| 10603 } |
| 10604 } |
10675 return result.raw(); | 10605 return result.raw(); |
10676 } | 10606 } |
10677 | 10607 |
10678 | 10608 |
10679 RawTwoByteString* TwoByteString::New(const TwoByteString& str, | 10609 RawTwoByteString* TwoByteString::New(const TwoByteString& str, |
10680 Heap::Space space) { | 10610 Heap::Space space) { |
10681 intptr_t len = str.Length(); | 10611 intptr_t len = str.Length(); |
10682 const TwoByteString& result = | 10612 const TwoByteString& result = |
10683 TwoByteString::Handle(TwoByteString::New(len, space)); | 10613 TwoByteString::Handle(TwoByteString::New(len, space)); |
10684 String::Copy(result, 0, str, 0, len); | 10614 String::Copy(result, 0, str, 0, len); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10732 } | 10662 } |
10733 return result.raw(); | 10663 return result.raw(); |
10734 } | 10664 } |
10735 | 10665 |
10736 | 10666 |
10737 const char* TwoByteString::ToCString() const { | 10667 const char* TwoByteString::ToCString() const { |
10738 return String::ToCString(); | 10668 return String::ToCString(); |
10739 } | 10669 } |
10740 | 10670 |
10741 | 10671 |
10742 RawFourByteString* FourByteString::EscapeSpecialCharacters(bool raw_str) const { | |
10743 intptr_t len = Length(); | |
10744 if (len > 0) { | |
10745 intptr_t num_escapes = 0; | |
10746 intptr_t index = 0; | |
10747 for (intptr_t i = 0; i < len; i++) { | |
10748 if (IsSpecialCharacter(*CharAddr(i)) || | |
10749 (!raw_str && (*CharAddr(i) == '\\'))) { | |
10750 num_escapes += 1; | |
10751 } | |
10752 } | |
10753 const FourByteString& dststr = FourByteString::Handle( | |
10754 FourByteString::New(len + num_escapes, Heap::kNew)); | |
10755 for (intptr_t i = 0; i < len; i++) { | |
10756 if (IsSpecialCharacter(*CharAddr(i))) { | |
10757 *(dststr.CharAddr(index)) = '\\'; | |
10758 *(dststr.CharAddr(index + 1)) = SpecialCharacter(*CharAddr(i)); | |
10759 index += 2; | |
10760 } else if (!raw_str && (*CharAddr(i) == '\\')) { | |
10761 *(dststr.CharAddr(index)) = '\\'; | |
10762 *(dststr.CharAddr(index + 1)) = '\\'; | |
10763 index += 2; | |
10764 } else { | |
10765 *(dststr.CharAddr(index)) = *CharAddr(i); | |
10766 index += 1; | |
10767 } | |
10768 } | |
10769 return dststr.raw(); | |
10770 } | |
10771 return FourByteString::null(); | |
10772 } | |
10773 | |
10774 | |
10775 RawFourByteString* FourByteString::New(intptr_t len, | |
10776 Heap::Space space) { | |
10777 ASSERT(Isolate::Current()->object_store()->four_byte_string_class() != | |
10778 Class::null()); | |
10779 if (len < 0 || len > kMaxElements) { | |
10780 // This should be caught before we reach here. | |
10781 FATAL1("Fatal error in FourByteString::New: invalid len %"Pd"\n", len); | |
10782 } | |
10783 FourByteString& result = FourByteString::Handle(); | |
10784 { | |
10785 RawObject* raw = Object::Allocate(FourByteString::kClassId, | |
10786 FourByteString::InstanceSize(len), | |
10787 space); | |
10788 NoGCScope no_gc; | |
10789 result ^= raw; | |
10790 result.SetLength(len); | |
10791 result.SetHash(0); | |
10792 } | |
10793 return result.raw(); | |
10794 } | |
10795 | |
10796 | |
10797 RawFourByteString* FourByteString::New(const uint32_t* characters, | |
10798 intptr_t len, | |
10799 Heap::Space space) { | |
10800 const FourByteString& result = | |
10801 FourByteString::Handle(FourByteString::New(len, space)); | |
10802 String::Copy(result, 0, characters, len); | |
10803 return result.raw(); | |
10804 } | |
10805 | |
10806 | |
10807 RawFourByteString* FourByteString::New(const FourByteString& str, | |
10808 Heap::Space space) { | |
10809 return FourByteString::New(str.CharAddr(0), str.Length(), space); | |
10810 } | |
10811 | |
10812 | |
10813 RawFourByteString* FourByteString::Concat(const String& str1, | |
10814 const String& str2, | |
10815 Heap::Space space) { | |
10816 intptr_t len1 = str1.Length(); | |
10817 intptr_t len2 = str2.Length(); | |
10818 intptr_t len = len1 + len2; | |
10819 const FourByteString& result = | |
10820 FourByteString::Handle(FourByteString::New(len, space)); | |
10821 String::Copy(result, 0, str1, 0, len1); | |
10822 String::Copy(result, len1, str2, 0, len2); | |
10823 return result.raw(); | |
10824 } | |
10825 | |
10826 | |
10827 RawFourByteString* FourByteString::ConcatAll(const Array& strings, | |
10828 intptr_t len, | |
10829 Heap::Space space) { | |
10830 const FourByteString& result = | |
10831 FourByteString::Handle(FourByteString::New(len, space)); | |
10832 String& str = String::Handle(); | |
10833 { | |
10834 intptr_t strings_len = strings.Length(); | |
10835 intptr_t pos = 0; | |
10836 for (intptr_t i = 0; i < strings_len; i++) { | |
10837 str ^= strings.At(i); | |
10838 intptr_t str_len = str.Length(); | |
10839 String::Copy(result, pos, str, 0, str_len); | |
10840 pos += str_len; | |
10841 } | |
10842 } | |
10843 return result.raw(); | |
10844 } | |
10845 | |
10846 | |
10847 RawFourByteString* FourByteString::Transform(int32_t (*mapping)(int32_t ch), | |
10848 const String& str, | |
10849 Heap::Space space) { | |
10850 ASSERT(!str.IsNull()); | |
10851 intptr_t len = str.Length(); | |
10852 const FourByteString& result = | |
10853 FourByteString::Handle(FourByteString::New(len, space)); | |
10854 for (intptr_t i = 0; i < len; ++i) { | |
10855 int32_t ch = mapping(str.CharAt(i)); | |
10856 ASSERT(ch >= 0 && ch <= 0x10FFFF); | |
10857 *result.CharAddr(i) = ch; | |
10858 } | |
10859 return result.raw(); | |
10860 } | |
10861 | |
10862 | |
10863 const char* FourByteString::ToCString() const { | |
10864 return String::ToCString(); | |
10865 } | |
10866 | |
10867 | |
10868 static void AddFinalizer(const Object& referent, | 10672 static void AddFinalizer(const Object& referent, |
10869 void* peer, | 10673 void* peer, |
10870 Dart_WeakPersistentHandleFinalizer callback) { | 10674 Dart_WeakPersistentHandleFinalizer callback) { |
10871 ASSERT(callback != NULL); | 10675 ASSERT(callback != NULL); |
10872 ApiState* state = Isolate::Current()->api_state(); | 10676 ApiState* state = Isolate::Current()->api_state(); |
10873 ASSERT(state != NULL); | 10677 ASSERT(state != NULL); |
10874 FinalizablePersistentHandle* weak_ref = | 10678 FinalizablePersistentHandle* weak_ref = |
10875 state->weak_persistent_handles().AllocateHandle(); | 10679 state->weak_persistent_handles().AllocateHandle(); |
10876 weak_ref->set_raw(referent); | 10680 weak_ref->set_raw(referent); |
10877 weak_ref->set_peer(peer); | 10681 weak_ref->set_peer(peer); |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10966 delete reinterpret_cast<ExternalStringData<uint16_t>*>(peer); | 10770 delete reinterpret_cast<ExternalStringData<uint16_t>*>(peer); |
10967 DeleteWeakPersistentHandle(handle); | 10771 DeleteWeakPersistentHandle(handle); |
10968 } | 10772 } |
10969 | 10773 |
10970 | 10774 |
10971 const char* ExternalTwoByteString::ToCString() const { | 10775 const char* ExternalTwoByteString::ToCString() const { |
10972 return String::ToCString(); | 10776 return String::ToCString(); |
10973 } | 10777 } |
10974 | 10778 |
10975 | 10779 |
10976 RawExternalFourByteString* ExternalFourByteString::New( | |
10977 const uint32_t* data, | |
10978 intptr_t len, | |
10979 void* peer, | |
10980 Dart_PeerFinalizer callback, | |
10981 Heap::Space space) { | |
10982 ASSERT(Isolate::Current()->object_store()-> | |
10983 external_four_byte_string_class() != Class::null()); | |
10984 if (len < 0 || len > kMaxElements) { | |
10985 // This should be caught before we reach here. | |
10986 FATAL1("Fatal error in ExternalFourByteString::New: invalid len %"Pd"\n", | |
10987 len); | |
10988 } | |
10989 ExternalFourByteString& result = ExternalFourByteString::Handle(); | |
10990 ExternalStringData<uint32_t>* external_data = | |
10991 new ExternalStringData<uint32_t>(data, peer, callback); | |
10992 { | |
10993 RawObject* raw = Object::Allocate(ExternalFourByteString::kClassId, | |
10994 ExternalFourByteString::InstanceSize(), | |
10995 space); | |
10996 NoGCScope no_gc; | |
10997 result ^= raw; | |
10998 result.SetLength(len); | |
10999 result.SetHash(0); | |
11000 result.SetExternalData(external_data); | |
11001 } | |
11002 AddFinalizer(result, external_data, ExternalFourByteString::Finalize); | |
11003 return result.raw(); | |
11004 } | |
11005 | |
11006 | |
11007 void ExternalFourByteString::Finalize(Dart_Handle handle, void* peer) { | |
11008 delete reinterpret_cast<ExternalStringData<uint32_t>*>(peer); | |
11009 DeleteWeakPersistentHandle(handle); | |
11010 } | |
11011 | |
11012 | |
11013 const char* ExternalFourByteString::ToCString() const { | |
11014 return String::ToCString(); | |
11015 } | |
11016 | |
11017 | |
11018 RawBool* Bool::True() { | 10780 RawBool* Bool::True() { |
11019 return Isolate::Current()->object_store()->true_value(); | 10781 return Isolate::Current()->object_store()->true_value(); |
11020 } | 10782 } |
11021 | 10783 |
11022 | 10784 |
11023 RawBool* Bool::False() { | 10785 RawBool* Bool::False() { |
11024 return Isolate::Current()->object_store()->false_value(); | 10786 return Isolate::Current()->object_store()->false_value(); |
11025 } | 10787 } |
11026 | 10788 |
11027 | 10789 |
(...skipping 1196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12224 } | 11986 } |
12225 return result.raw(); | 11987 return result.raw(); |
12226 } | 11988 } |
12227 | 11989 |
12228 | 11990 |
12229 const char* WeakProperty::ToCString() const { | 11991 const char* WeakProperty::ToCString() const { |
12230 return "_WeakProperty"; | 11992 return "_WeakProperty"; |
12231 } | 11993 } |
12232 | 11994 |
12233 } // namespace dart | 11995 } // namespace dart |
OLD | NEW |