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