| 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 594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 605 name = Symbols::OneByteString(); | 605 name = Symbols::OneByteString(); |
| 606 RegisterPrivateClass(cls, name, core_lib); | 606 RegisterPrivateClass(cls, name, core_lib); |
| 607 pending_classes.Add(cls, Heap::kOld); | 607 pending_classes.Add(cls, Heap::kOld); |
| 608 | 608 |
| 609 cls = Class::New<TwoByteString>(); | 609 cls = Class::New<TwoByteString>(); |
| 610 object_store->set_two_byte_string_class(cls); | 610 object_store->set_two_byte_string_class(cls); |
| 611 name = Symbols::TwoByteString(); | 611 name = Symbols::TwoByteString(); |
| 612 RegisterPrivateClass(cls, name, core_lib); | 612 RegisterPrivateClass(cls, name, core_lib); |
| 613 pending_classes.Add(cls, Heap::kOld); | 613 pending_classes.Add(cls, Heap::kOld); |
| 614 | 614 |
| 615 cls = Class::New<FourByteString>(); | |
| 616 object_store->set_four_byte_string_class(cls); | |
| 617 name = Symbols::FourByteString(); | |
| 618 RegisterPrivateClass(cls, name, core_lib); | |
| 619 pending_classes.Add(cls, Heap::kOld); | |
| 620 | |
| 621 cls = Class::New<ExternalOneByteString>(); | 615 cls = Class::New<ExternalOneByteString>(); |
| 622 object_store->set_external_one_byte_string_class(cls); | 616 object_store->set_external_one_byte_string_class(cls); |
| 623 name = Symbols::ExternalOneByteString(); | 617 name = Symbols::ExternalOneByteString(); |
| 624 RegisterPrivateClass(cls, name, core_lib); | 618 RegisterPrivateClass(cls, name, core_lib); |
| 625 pending_classes.Add(cls, Heap::kOld); | 619 pending_classes.Add(cls, Heap::kOld); |
| 626 | 620 |
| 627 cls = Class::New<ExternalTwoByteString>(); | 621 cls = Class::New<ExternalTwoByteString>(); |
| 628 object_store->set_external_two_byte_string_class(cls); | 622 object_store->set_external_two_byte_string_class(cls); |
| 629 name = Symbols::ExternalTwoByteString(); | 623 name = Symbols::ExternalTwoByteString(); |
| 630 RegisterPrivateClass(cls, name, core_lib); | 624 RegisterPrivateClass(cls, name, core_lib); |
| 631 pending_classes.Add(cls, Heap::kOld); | 625 pending_classes.Add(cls, Heap::kOld); |
| 632 | 626 |
| 633 cls = Class::New<ExternalFourByteString>(); | |
| 634 object_store->set_external_four_byte_string_class(cls); | |
| 635 name = Symbols::ExternalFourByteString(); | |
| 636 RegisterPrivateClass(cls, name, core_lib); | |
| 637 pending_classes.Add(cls, Heap::kOld); | |
| 638 | |
| 639 cls = Class::New<Stacktrace>(); | 627 cls = Class::New<Stacktrace>(); |
| 640 object_store->set_stacktrace_class(cls); | 628 object_store->set_stacktrace_class(cls); |
| 641 name = Symbols::Stacktrace(); | 629 name = Symbols::Stacktrace(); |
| 642 RegisterClass(cls, name, core_impl_lib); | 630 RegisterClass(cls, name, core_impl_lib); |
| 643 pending_classes.Add(cls, Heap::kOld); | 631 pending_classes.Add(cls, Heap::kOld); |
| 644 // Super type set below, after Object is allocated. | 632 // Super type set below, after Object is allocated. |
| 645 | 633 |
| 646 cls = Class::New<JSRegExp>(); | 634 cls = Class::New<JSRegExp>(); |
| 647 object_store->set_jsregexp_class(cls); | 635 object_store->set_jsregexp_class(cls); |
| 648 name = Symbols::JSSyntaxRegExp(); | 636 name = Symbols::JSSyntaxRegExp(); |
| (...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1096 | 1084 |
| 1097 cls = Class::New<Bigint>(); | 1085 cls = Class::New<Bigint>(); |
| 1098 object_store->set_bigint_class(cls); | 1086 object_store->set_bigint_class(cls); |
| 1099 | 1087 |
| 1100 cls = Class::New<OneByteString>(); | 1088 cls = Class::New<OneByteString>(); |
| 1101 object_store->set_one_byte_string_class(cls); | 1089 object_store->set_one_byte_string_class(cls); |
| 1102 | 1090 |
| 1103 cls = Class::New<TwoByteString>(); | 1091 cls = Class::New<TwoByteString>(); |
| 1104 object_store->set_two_byte_string_class(cls); | 1092 object_store->set_two_byte_string_class(cls); |
| 1105 | 1093 |
| 1106 cls = Class::New<FourByteString>(); | |
| 1107 object_store->set_four_byte_string_class(cls); | |
| 1108 | |
| 1109 cls = Class::New<ExternalOneByteString>(); | 1094 cls = Class::New<ExternalOneByteString>(); |
| 1110 object_store->set_external_one_byte_string_class(cls); | 1095 object_store->set_external_one_byte_string_class(cls); |
| 1111 | 1096 |
| 1112 cls = Class::New<ExternalTwoByteString>(); | 1097 cls = Class::New<ExternalTwoByteString>(); |
| 1113 object_store->set_external_two_byte_string_class(cls); | 1098 object_store->set_external_two_byte_string_class(cls); |
| 1114 | 1099 |
| 1115 cls = Class::New<ExternalFourByteString>(); | |
| 1116 object_store->set_external_four_byte_string_class(cls); | |
| 1117 | |
| 1118 cls = Class::New<Bool>(); | 1100 cls = Class::New<Bool>(); |
| 1119 object_store->set_bool_class(cls); | 1101 object_store->set_bool_class(cls); |
| 1120 | 1102 |
| 1121 cls = Class::New<Stacktrace>(); | 1103 cls = Class::New<Stacktrace>(); |
| 1122 object_store->set_stacktrace_class(cls); | 1104 object_store->set_stacktrace_class(cls); |
| 1123 | 1105 |
| 1124 cls = Class::New<JSRegExp>(); | 1106 cls = Class::New<JSRegExp>(); |
| 1125 object_store->set_jsregexp_class(cls); | 1107 object_store->set_jsregexp_class(cls); |
| 1126 | 1108 |
| 1127 // Some classes are not stored in the object store. Yet we still need to | 1109 // 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... |
| 1240 switch (id()) { | 1222 switch (id()) { |
| 1241 case kIntegerCid: | 1223 case kIntegerCid: |
| 1242 case kSmiCid: | 1224 case kSmiCid: |
| 1243 case kMintCid: | 1225 case kMintCid: |
| 1244 case kBigintCid: | 1226 case kBigintCid: |
| 1245 return Symbols::New("int"); | 1227 return Symbols::New("int"); |
| 1246 case kDoubleCid: | 1228 case kDoubleCid: |
| 1247 return Symbols::New("double"); | 1229 return Symbols::New("double"); |
| 1248 case kOneByteStringCid: | 1230 case kOneByteStringCid: |
| 1249 case kTwoByteStringCid: | 1231 case kTwoByteStringCid: |
| 1250 case kFourByteStringCid: | |
| 1251 case kExternalOneByteStringCid: | 1232 case kExternalOneByteStringCid: |
| 1252 case kExternalTwoByteStringCid: | 1233 case kExternalTwoByteStringCid: |
| 1253 case kExternalFourByteStringCid: | |
| 1254 return Symbols::New("String"); | 1234 return Symbols::New("String"); |
| 1255 case kArrayCid: | 1235 case kArrayCid: |
| 1256 case kImmutableArrayCid: | 1236 case kImmutableArrayCid: |
| 1257 case kGrowableObjectArrayCid: | 1237 case kGrowableObjectArrayCid: |
| 1258 return Symbols::New("List"); | 1238 return Symbols::New("List"); |
| 1259 case kInt8ArrayCid: | 1239 case kInt8ArrayCid: |
| 1260 case kExternalInt8ArrayCid: | 1240 case kExternalInt8ArrayCid: |
| 1261 return Symbols::New("Int8List"); | 1241 return Symbols::New("Int8List"); |
| 1262 case kUint8ArrayCid: | 1242 case kUint8ArrayCid: |
| 1263 case kExternalUint8ArrayCid: | 1243 case kExternalUint8ArrayCid: |
| (...skipping 8552 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9816 const String& other_string = String::Cast(other); | 9796 const String& other_string = String::Cast(other); |
| 9817 if (this->HasHash() && other_string.HasHash() && | 9797 if (this->HasHash() && other_string.HasHash() && |
| 9818 (this->Hash() != other_string.Hash())) { | 9798 (this->Hash() != other_string.Hash())) { |
| 9819 return false; // Both sides have a hash code and it does not match. | 9799 return false; // Both sides have a hash code and it does not match. |
| 9820 } | 9800 } |
| 9821 return Equals(other_string, 0, other_string.Length()); | 9801 return Equals(other_string, 0, other_string.Length()); |
| 9822 } | 9802 } |
| 9823 | 9803 |
| 9824 | 9804 |
| 9825 bool String::Equals(const char* str) const { | 9805 bool String::Equals(const char* str) const { |
| 9806 ASSERT(str != NULL); |
| 9807 intptr_t len = strlen(str); |
| 9826 for (intptr_t i = 0; i < this->Length(); ++i) { | 9808 for (intptr_t i = 0; i < this->Length(); ++i) { |
| 9827 if (*str == '\0') { | 9809 if (*str == '\0') { |
| 9828 // Lengths don't match. | 9810 // Lengths don't match. |
| 9829 return false; | 9811 return false; |
| 9830 } | 9812 } |
| 9831 int32_t ch; | 9813 int32_t ch; |
| 9832 intptr_t consumed = Utf8::Decode(str, &ch); | 9814 intptr_t consumed = Utf8::Decode(reinterpret_cast<const uint8_t*>(str), |
| 9815 len, |
| 9816 &ch); |
| 9833 if (consumed == 0 || this->CharAt(i) != ch) { | 9817 if (consumed == 0 || this->CharAt(i) != ch) { |
| 9834 return false; | 9818 return false; |
| 9835 } | 9819 } |
| 9836 str += consumed; | 9820 str += consumed; |
| 9821 len -= consumed; |
| 9837 } | 9822 } |
| 9838 return *str == '\0'; | 9823 return *str == '\0'; |
| 9839 } | 9824 } |
| 9840 | 9825 |
| 9841 | 9826 |
| 9842 bool String::Equals(const uint8_t* characters, intptr_t len) const { | 9827 bool String::Equals(const uint8_t* characters, intptr_t len) const { |
| 9843 if (len != this->Length()) { | 9828 if (len != this->Length()) { |
| 9844 // Lengths don't match. | 9829 // Lengths don't match. |
| 9845 return false; | 9830 return false; |
| 9846 } | 9831 } |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9920 | 9905 |
| 9921 RawInstance* String::Canonicalize() const { | 9906 RawInstance* String::Canonicalize() const { |
| 9922 if (IsCanonical()) { | 9907 if (IsCanonical()) { |
| 9923 return this->raw(); | 9908 return this->raw(); |
| 9924 } | 9909 } |
| 9925 return Symbols::New(*this); | 9910 return Symbols::New(*this); |
| 9926 } | 9911 } |
| 9927 | 9912 |
| 9928 | 9913 |
| 9929 RawString* String::New(const char* str, Heap::Space space) { | 9914 RawString* String::New(const char* str, Heap::Space space) { |
| 9930 intptr_t width = 0; | 9915 ASSERT(str != NULL); |
| 9931 intptr_t len = Utf8::CodePointCount(str, &width); | 9916 intptr_t array_len = strlen(str); |
| 9932 if (width == 1) { | 9917 const uint8_t* utf8_array = reinterpret_cast<const uint8_t*>(str); |
| 9933 const OneByteString& onestr | 9918 return String::New(utf8_array, array_len, space); |
| 9919 } |
| 9920 |
| 9921 |
| 9922 RawString* String::New(const uint8_t* utf8_array, |
| 9923 intptr_t array_len, |
| 9924 Heap::Space space) { |
| 9925 Utf8::Type type; |
| 9926 intptr_t len = Utf8::CodePointCount(utf8_array, array_len, &type); |
| 9927 if (type == Utf8::kAscii) { |
| 9928 const OneByteString& strobj |
| 9934 = OneByteString::Handle(OneByteString::New(len, space)); | 9929 = OneByteString::Handle(OneByteString::New(len, space)); |
| 9935 if (len > 0) { | 9930 if (len > 0) { |
| 9936 NoGCScope no_gc; | 9931 NoGCScope no_gc; |
| 9937 Utf8::Decode(str, onestr.CharAddr(0), len); | 9932 Utf8::DecodeToAscii(utf8_array, array_len, strobj.CharAddr(0), len); |
| 9938 } | 9933 } |
| 9939 return onestr.raw(); | 9934 return strobj.raw(); |
| 9940 } else if (width == 2) { | |
| 9941 const TwoByteString& twostr = | |
| 9942 TwoByteString::Handle(TwoByteString::New(len, space)); | |
| 9943 NoGCScope no_gc; | |
| 9944 Utf8::Decode(str, twostr.CharAddr(0), len); | |
| 9945 return twostr.raw(); | |
| 9946 } | 9935 } |
| 9947 ASSERT(width == 4); | 9936 ASSERT((type == Utf8::kBMP) || (type == Utf8::kSMP)); |
| 9948 const FourByteString& fourstr = | 9937 const TwoByteString& strobj = |
| 9949 FourByteString::Handle(FourByteString::New(len, space)); | 9938 TwoByteString::Handle(TwoByteString::New(len, space)); |
| 9950 NoGCScope no_gc; | 9939 NoGCScope no_gc; |
| 9951 Utf8::Decode(str, fourstr.CharAddr(0), len); | 9940 Utf8::DecodeToUTF16(utf8_array, array_len, strobj.CharAddr(0), len); |
| 9952 return fourstr.raw(); | 9941 return strobj.raw(); |
| 9953 } | 9942 } |
| 9954 | 9943 |
| 9955 | 9944 |
| 9956 RawString* String::New(const uint8_t* characters, | 9945 RawString* String::New(const uint16_t* utf16_array, |
| 9957 intptr_t len, | 9946 intptr_t array_len, |
| 9958 Heap::Space space) { | |
| 9959 return OneByteString::New(characters, len, space); | |
| 9960 } | |
| 9961 | |
| 9962 | |
| 9963 RawString* String::New(const uint16_t* characters, | |
| 9964 intptr_t len, | |
| 9965 Heap::Space space) { | 9947 Heap::Space space) { |
| 9966 bool is_one_byte_string = true; | 9948 bool is_one_byte_string = true; |
| 9967 for (intptr_t i = 0; i < len; ++i) { | 9949 for (intptr_t i = 0; i < array_len; ++i) { |
| 9968 if (characters[i] > 0xFF) { | 9950 if (utf16_array[i] > 0x7F) { |
| 9969 is_one_byte_string = false; | 9951 is_one_byte_string = false; |
| 9970 break; | 9952 break; |
| 9971 } | 9953 } |
| 9972 } | 9954 } |
| 9973 if (is_one_byte_string) { | 9955 if (is_one_byte_string) { |
| 9974 return OneByteString::New(characters, len, space); | 9956 return OneByteString::New(utf16_array, array_len, space); |
| 9975 } | 9957 } |
| 9976 return TwoByteString::New(characters, len, space); | 9958 return TwoByteString::New(utf16_array, array_len, space); |
| 9977 } | 9959 } |
| 9978 | 9960 |
| 9979 | 9961 |
| 9980 RawString* String::New(const uint32_t* characters, | 9962 RawString* String::New(const uint32_t* utf32_array, |
| 9981 intptr_t len, | 9963 intptr_t array_len, |
| 9982 Heap::Space space) { | 9964 Heap::Space space) { |
| 9983 bool is_one_byte_string = true; | 9965 bool is_one_byte_string = true; |
| 9984 bool is_two_byte_string = true; | 9966 intptr_t utf16_len = array_len; |
| 9985 for (intptr_t i = 0; i < len; ++i) { | 9967 for (intptr_t i = 0; i < array_len; ++i) { |
| 9986 if (characters[i] > 0xFFFF) { | 9968 if (utf32_array[i] > 0x7F) { |
| 9987 is_two_byte_string = false; | |
| 9988 is_one_byte_string = false; | 9969 is_one_byte_string = false; |
| 9989 break; | 9970 } |
| 9990 } else if (characters[i] > 0xFF) { | 9971 if (utf32_array[i] > 0xFFFF) { |
| 9991 is_one_byte_string = false; | 9972 utf16_len += 1; |
| 9992 } | 9973 } |
| 9993 } | 9974 } |
| 9994 if (is_one_byte_string) { | 9975 if (is_one_byte_string) { |
| 9995 return OneByteString::New(characters, len, space); | 9976 return OneByteString::New(utf32_array, array_len, space); |
| 9996 } else if (is_two_byte_string) { | |
| 9997 return TwoByteString::New(characters, len, space); | |
| 9998 } | 9977 } |
| 9999 return FourByteString::New(characters, len, space); | 9978 return TwoByteString::New(utf16_len, utf32_array, array_len, space); |
| 10000 } | 9979 } |
| 10001 | 9980 |
| 10002 | 9981 |
| 10003 RawString* String::New(const String& str, Heap::Space space) { | 9982 RawString* String::New(const String& str, Heap::Space space) { |
| 10004 // Currently this just creates a copy of the string in the correct space. | 9983 // Currently this just creates a copy of the string in the correct space. |
| 10005 // Once we have external string support, this will also create a heap copy of | 9984 // Once we have external string support, this will also create a heap copy of |
| 10006 // the string if necessary. Some optimizations are possible, such as not | 9985 // the string if necessary. Some optimizations are possible, such as not |
| 10007 // copying internal strings into the same space. | 9986 // copying internal strings into the same space. |
| 10008 intptr_t len = str.Length(); | 9987 intptr_t len = str.Length(); |
| 10009 String& result = String::Handle(); | 9988 String& result = String::Handle(); |
| 10010 intptr_t char_size = str.CharSize(); | 9989 intptr_t char_size = str.CharSize(); |
| 10011 if (char_size == kOneByteChar) { | 9990 if (char_size == kOneByteChar) { |
| 10012 result ^= OneByteString::New(len, space); | 9991 result ^= OneByteString::New(len, space); |
| 10013 } else if (char_size == kTwoByteChar) { | 9992 } else { |
| 9993 ASSERT(char_size == kTwoByteChar); |
| 10014 result ^= TwoByteString::New(len, space); | 9994 result ^= TwoByteString::New(len, space); |
| 10015 } else { | |
| 10016 ASSERT(char_size == kFourByteChar); | |
| 10017 result ^= FourByteString::New(len, space); | |
| 10018 } | 9995 } |
| 10019 String::Copy(result, 0, str, 0, len); | 9996 String::Copy(result, 0, str, 0, len); |
| 10020 return result.raw(); | 9997 return result.raw(); |
| 10021 } | 9998 } |
| 10022 | 9999 |
| 10023 | 10000 |
| 10024 RawString* String::NewExternal(const uint8_t* characters, | 10001 RawString* String::NewExternal(const uint8_t* characters, |
| 10025 intptr_t len, | 10002 intptr_t len, |
| 10026 void* peer, | 10003 void* peer, |
| 10027 Dart_PeerFinalizer callback, | 10004 Dart_PeerFinalizer callback, |
| 10028 Heap::Space space) { | 10005 Heap::Space space) { |
| 10029 return ExternalOneByteString::New(characters, len, peer, callback, space); | 10006 return ExternalOneByteString::New(characters, len, peer, callback, space); |
| 10030 } | 10007 } |
| 10031 | 10008 |
| 10032 | 10009 |
| 10033 RawString* String::NewExternal(const uint16_t* characters, | 10010 RawString* String::NewExternal(const uint16_t* characters, |
| 10034 intptr_t len, | 10011 intptr_t len, |
| 10035 void* peer, | 10012 void* peer, |
| 10036 Dart_PeerFinalizer callback, | 10013 Dart_PeerFinalizer callback, |
| 10037 Heap::Space space) { | 10014 Heap::Space space) { |
| 10038 return ExternalTwoByteString::New(characters, len, peer, callback, space); | 10015 return ExternalTwoByteString::New(characters, len, peer, callback, space); |
| 10039 } | 10016 } |
| 10040 | 10017 |
| 10041 | 10018 |
| 10042 RawString* String::NewExternal(const uint32_t* characters, | |
| 10043 intptr_t len, | |
| 10044 void* peer, | |
| 10045 Dart_PeerFinalizer callback, | |
| 10046 Heap::Space space) { | |
| 10047 return ExternalFourByteString::New(characters, len, peer, callback, space); | |
| 10048 } | |
| 10049 | |
| 10050 | |
| 10051 void String::Copy(const String& dst, intptr_t dst_offset, | 10019 void String::Copy(const String& dst, intptr_t dst_offset, |
| 10052 const uint8_t* characters, | 10020 const uint8_t* characters, |
| 10053 intptr_t len) { | 10021 intptr_t len) { |
| 10054 ASSERT(dst_offset >= 0); | 10022 ASSERT(dst_offset >= 0); |
| 10055 ASSERT(len >= 0); | 10023 ASSERT(len >= 0); |
| 10056 ASSERT(len <= (dst.Length() - dst_offset)); | 10024 ASSERT(len <= (dst.Length() - dst_offset)); |
| 10057 if (dst.IsOneByteString()) { | 10025 if (dst.IsOneByteString()) { |
| 10058 const OneByteString& onestr = OneByteString::Cast(dst); | 10026 const OneByteString& onestr = OneByteString::Cast(dst); |
| 10059 NoGCScope no_gc; | 10027 NoGCScope no_gc; |
| 10060 if (len > 0) { | 10028 if (len > 0) { |
| 10061 memmove(onestr.CharAddr(dst_offset), characters, len); | 10029 memmove(onestr.CharAddr(dst_offset), characters, len); |
| 10062 } | 10030 } |
| 10063 } else if (dst.IsTwoByteString()) { | 10031 } else if (dst.IsTwoByteString()) { |
| 10064 const TwoByteString& twostr = TwoByteString::Cast(dst); | 10032 const TwoByteString& twostr = TwoByteString::Cast(dst); |
| 10065 NoGCScope no_gc; | 10033 NoGCScope no_gc; |
| 10066 for (intptr_t i = 0; i < len; ++i) { | 10034 for (intptr_t i = 0; i < len; ++i) { |
| 10067 *twostr.CharAddr(i + dst_offset) = characters[i]; | 10035 *twostr.CharAddr(i + dst_offset) = characters[i]; |
| 10068 } | 10036 } |
| 10069 } else { | |
| 10070 ASSERT(dst.IsFourByteString()); | |
| 10071 const FourByteString& fourstr = FourByteString::Cast(dst); | |
| 10072 NoGCScope no_gc; | |
| 10073 for (intptr_t i = 0; i < len; ++i) { | |
| 10074 *fourstr.CharAddr(i + dst_offset) = characters[i]; | |
| 10075 } | |
| 10076 } | 10037 } |
| 10077 } | 10038 } |
| 10078 | 10039 |
| 10079 | 10040 |
| 10080 void String::Copy(const String& dst, intptr_t dst_offset, | 10041 void String::Copy(const String& dst, intptr_t dst_offset, |
| 10081 const uint16_t* characters, | 10042 const uint16_t* utf16_array, |
| 10082 intptr_t len) { | 10043 intptr_t array_len) { |
| 10083 ASSERT(dst_offset >= 0); | 10044 ASSERT(dst_offset >= 0); |
| 10084 ASSERT(len >= 0); | 10045 ASSERT(array_len >= 0); |
| 10085 ASSERT(len <= (dst.Length() - dst_offset)); | 10046 ASSERT(array_len <= (dst.Length() - dst_offset)); |
| 10086 if (dst.IsOneByteString()) { | 10047 if (dst.IsOneByteString()) { |
| 10087 const OneByteString& onestr = OneByteString::Cast(dst); | 10048 const OneByteString& onestr = OneByteString::Cast(dst); |
| 10088 NoGCScope no_gc; | 10049 NoGCScope no_gc; |
| 10089 for (intptr_t i = 0; i < len; ++i) { | 10050 for (intptr_t i = 0; i < array_len; ++i) { |
| 10090 ASSERT(characters[i] <= 0xFF); | 10051 ASSERT(utf16_array[i] <= 0x7F); |
| 10091 *onestr.CharAddr(i + dst_offset) = characters[i]; | 10052 *onestr.CharAddr(i + dst_offset) = utf16_array[i]; |
| 10092 } | 10053 } |
| 10093 } else if (dst.IsTwoByteString()) { | 10054 } else { |
| 10055 ASSERT(dst.IsTwoByteString()); |
| 10094 const TwoByteString& twostr = TwoByteString::Cast(dst); | 10056 const TwoByteString& twostr = TwoByteString::Cast(dst); |
| 10095 NoGCScope no_gc; | 10057 NoGCScope no_gc; |
| 10096 if (len > 0) { | 10058 if (array_len > 0) { |
| 10097 memmove(twostr.CharAddr(dst_offset), characters, len * 2); | 10059 memmove(twostr.CharAddr(dst_offset), utf16_array, (array_len * 2)); |
| 10098 } | |
| 10099 } else { | |
| 10100 ASSERT(dst.IsFourByteString()); | |
| 10101 const FourByteString& fourstr = FourByteString::Cast(dst); | |
| 10102 NoGCScope no_gc; | |
| 10103 for (intptr_t i = 0; i < len; ++i) { | |
| 10104 *fourstr.CharAddr(i + dst_offset) = characters[i]; | |
| 10105 } | 10060 } |
| 10106 } | 10061 } |
| 10107 } | 10062 } |
| 10108 | 10063 |
| 10109 | |
| 10110 void String::Copy(const String& dst, intptr_t dst_offset, | |
| 10111 const uint32_t* characters, | |
| 10112 intptr_t len) { | |
| 10113 ASSERT(dst_offset >= 0); | |
| 10114 ASSERT(len >= 0); | |
| 10115 ASSERT(len <= (dst.Length() - dst_offset)); | |
| 10116 if (dst.IsOneByteString()) { | |
| 10117 const OneByteString& onestr = OneByteString::Cast(dst); | |
| 10118 NoGCScope no_gc; | |
| 10119 for (intptr_t i = 0; i < len; ++i) { | |
| 10120 ASSERT(characters[i] <= 0xFF); | |
| 10121 *onestr.CharAddr(i + dst_offset) = characters[i]; | |
| 10122 } | |
| 10123 } else if (dst.IsTwoByteString()) { | |
| 10124 const TwoByteString& twostr = TwoByteString::Cast(dst); | |
| 10125 NoGCScope no_gc; | |
| 10126 for (intptr_t i = 0; i < len; ++i) { | |
| 10127 ASSERT(characters[i] <= 0xFFFF); | |
| 10128 *twostr.CharAddr(i + dst_offset) = characters[i]; | |
| 10129 } | |
| 10130 } else { | |
| 10131 ASSERT(dst.IsFourByteString()); | |
| 10132 const FourByteString& fourstr = FourByteString::Cast(dst); | |
| 10133 NoGCScope no_gc; | |
| 10134 if (len > 0) { | |
| 10135 memmove(fourstr.CharAddr(dst_offset), characters, len * 4); | |
| 10136 } | |
| 10137 } | |
| 10138 } | |
| 10139 | |
| 10140 | 10064 |
| 10141 void String::Copy(const String& dst, intptr_t dst_offset, | 10065 void String::Copy(const String& dst, intptr_t dst_offset, |
| 10142 const String& src, intptr_t src_offset, | 10066 const String& src, intptr_t src_offset, |
| 10143 intptr_t len) { | 10067 intptr_t len) { |
| 10144 ASSERT(dst_offset >= 0); | 10068 ASSERT(dst_offset >= 0); |
| 10145 ASSERT(src_offset >= 0); | 10069 ASSERT(src_offset >= 0); |
| 10146 ASSERT(len >= 0); | 10070 ASSERT(len >= 0); |
| 10147 ASSERT(len <= (dst.Length() - dst_offset)); | 10071 ASSERT(len <= (dst.Length() - dst_offset)); |
| 10148 ASSERT(len <= (src.Length() - src_offset)); | 10072 ASSERT(len <= (src.Length() - src_offset)); |
| 10149 if (len > 0) { | 10073 if (len > 0) { |
| 10150 intptr_t char_size = src.CharSize(); | 10074 intptr_t char_size = src.CharSize(); |
| 10151 if (char_size == kOneByteChar) { | 10075 if (char_size == kOneByteChar) { |
| 10152 if (src.IsOneByteString()) { | 10076 if (src.IsOneByteString()) { |
| 10153 const OneByteString& onestr = OneByteString::Cast(src); | 10077 const OneByteString& onestr = OneByteString::Cast(src); |
| 10154 NoGCScope no_gc; | 10078 NoGCScope no_gc; |
| 10155 String::Copy(dst, dst_offset, onestr.CharAddr(0) + src_offset, len); | 10079 String::Copy(dst, dst_offset, onestr.CharAddr(0) + src_offset, len); |
| 10156 } else { | 10080 } else { |
| 10157 ASSERT(src.IsExternalOneByteString()); | 10081 ASSERT(src.IsExternalOneByteString()); |
| 10158 const ExternalOneByteString& onestr = ExternalOneByteString::Cast(src); | 10082 const ExternalOneByteString& onestr = ExternalOneByteString::Cast(src); |
| 10159 NoGCScope no_gc; | 10083 NoGCScope no_gc; |
| 10160 String::Copy(dst, dst_offset, onestr.CharAddr(0) + src_offset, len); | 10084 String::Copy(dst, dst_offset, onestr.CharAddr(0) + src_offset, len); |
| 10161 } | 10085 } |
| 10162 } else if (char_size == kTwoByteChar) { | 10086 } else { |
| 10087 ASSERT(char_size == kTwoByteChar); |
| 10163 if (src.IsTwoByteString()) { | 10088 if (src.IsTwoByteString()) { |
| 10164 const TwoByteString& twostr = TwoByteString::Cast(src); | 10089 const TwoByteString& twostr = TwoByteString::Cast(src); |
| 10165 NoGCScope no_gc; | 10090 NoGCScope no_gc; |
| 10166 String::Copy(dst, dst_offset, twostr.CharAddr(0) + src_offset, len); | 10091 String::Copy(dst, dst_offset, twostr.CharAddr(0) + src_offset, len); |
| 10167 } else { | 10092 } else { |
| 10168 ASSERT(src.IsExternalTwoByteString()); | 10093 ASSERT(src.IsExternalTwoByteString()); |
| 10169 const ExternalTwoByteString& twostr = ExternalTwoByteString::Cast(src); | 10094 const ExternalTwoByteString& twostr = ExternalTwoByteString::Cast(src); |
| 10170 NoGCScope no_gc; | 10095 NoGCScope no_gc; |
| 10171 String::Copy(dst, dst_offset, twostr.CharAddr(0) + src_offset, len); | 10096 String::Copy(dst, dst_offset, twostr.CharAddr(0) + src_offset, len); |
| 10172 } | 10097 } |
| 10173 } else { | |
| 10174 ASSERT(char_size == kFourByteChar); | |
| 10175 if (src.IsFourByteString()) { | |
| 10176 const FourByteString& fourstr = FourByteString::Cast(src); | |
| 10177 NoGCScope no_gc; | |
| 10178 String::Copy(dst, dst_offset, fourstr.CharAddr(0) + src_offset, len); | |
| 10179 } else { | |
| 10180 ASSERT(src.IsExternalFourByteString()); | |
| 10181 const ExternalFourByteString& fourstr = | |
| 10182 ExternalFourByteString::Cast(src); | |
| 10183 NoGCScope no_gc; | |
| 10184 String::Copy(dst, dst_offset, fourstr.CharAddr(0) + src_offset, len); | |
| 10185 } | |
| 10186 } | 10098 } |
| 10187 } | 10099 } |
| 10188 } | 10100 } |
| 10189 | 10101 |
| 10190 | 10102 |
| 10191 RawString* String::EscapeSpecialCharacters(const String& str, bool raw_str) { | 10103 RawString* String::EscapeSpecialCharacters(const String& str, bool raw_str) { |
| 10192 if (str.IsOneByteString()) { | 10104 if (str.IsOneByteString()) { |
| 10193 const OneByteString& onestr = OneByteString::Cast(str); | 10105 const OneByteString& onestr = OneByteString::Cast(str); |
| 10194 return onestr.EscapeSpecialCharacters(raw_str); | 10106 return onestr.EscapeSpecialCharacters(raw_str); |
| 10195 } | 10107 } |
| 10196 if (str.IsTwoByteString()) { | 10108 ASSERT(str.IsTwoByteString()); |
| 10197 const TwoByteString& twostr = TwoByteString::Cast(str); | 10109 const TwoByteString& twostr = TwoByteString::Cast(str); |
| 10198 return twostr.EscapeSpecialCharacters(raw_str); | 10110 return twostr.EscapeSpecialCharacters(raw_str); |
| 10199 } | |
| 10200 ASSERT(str.IsFourByteString()); | |
| 10201 const FourByteString& fourstr = FourByteString::Cast(str); | |
| 10202 return fourstr.EscapeSpecialCharacters(raw_str); | |
| 10203 } | 10111 } |
| 10204 | 10112 |
| 10205 | 10113 |
| 10206 RawString* String::NewFormatted(const char* format, ...) { | 10114 RawString* String::NewFormatted(const char* format, ...) { |
| 10207 va_list args; | 10115 va_list args; |
| 10208 va_start(args, format); | 10116 va_start(args, format); |
| 10209 RawString* result = NewFormattedV(format, args); | 10117 RawString* result = NewFormattedV(format, args); |
| 10210 NoGCScope no_gc; | 10118 NoGCScope no_gc; |
| 10211 va_end(args); | 10119 va_end(args); |
| 10212 return result; | 10120 return result; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 10225 | 10133 |
| 10226 return String::New(buffer); | 10134 return String::New(buffer); |
| 10227 } | 10135 } |
| 10228 | 10136 |
| 10229 | 10137 |
| 10230 RawString* String::Concat(const String& str1, | 10138 RawString* String::Concat(const String& str1, |
| 10231 const String& str2, | 10139 const String& str2, |
| 10232 Heap::Space space) { | 10140 Heap::Space space) { |
| 10233 ASSERT(!str1.IsNull() && !str2.IsNull()); | 10141 ASSERT(!str1.IsNull() && !str2.IsNull()); |
| 10234 intptr_t char_size = Utils::Maximum(str1.CharSize(), str2.CharSize()); | 10142 intptr_t char_size = Utils::Maximum(str1.CharSize(), str2.CharSize()); |
| 10235 if (char_size == kFourByteChar) { | |
| 10236 return FourByteString::Concat(str1, str2, space); | |
| 10237 } | |
| 10238 if (char_size == kTwoByteChar) { | 10143 if (char_size == kTwoByteChar) { |
| 10239 return TwoByteString::Concat(str1, str2, space); | 10144 return TwoByteString::Concat(str1, str2, space); |
| 10240 } | 10145 } |
| 10241 return OneByteString::Concat(str1, str2, space); | 10146 return OneByteString::Concat(str1, str2, space); |
| 10242 } | 10147 } |
| 10243 | 10148 |
| 10244 | 10149 |
| 10245 RawString* String::ConcatAll(const Array& strings, | 10150 RawString* String::ConcatAll(const Array& strings, |
| 10246 Heap::Space space) { | 10151 Heap::Space space) { |
| 10247 ASSERT(!strings.IsNull()); | 10152 ASSERT(!strings.IsNull()); |
| 10248 intptr_t result_len = 0; | 10153 intptr_t result_len = 0; |
| 10249 intptr_t strings_len = strings.Length(); | 10154 intptr_t strings_len = strings.Length(); |
| 10250 String& str = String::Handle(); | 10155 String& str = String::Handle(); |
| 10251 intptr_t char_size = kOneByteChar; | 10156 intptr_t char_size = kOneByteChar; |
| 10252 for (intptr_t i = 0; i < strings_len; i++) { | 10157 for (intptr_t i = 0; i < strings_len; i++) { |
| 10253 str ^= strings.At(i); | 10158 str ^= strings.At(i); |
| 10254 result_len += str.Length(); | 10159 result_len += str.Length(); |
| 10255 char_size = Utils::Maximum(char_size, str.CharSize()); | 10160 char_size = Utils::Maximum(char_size, str.CharSize()); |
| 10256 } | 10161 } |
| 10257 if (char_size == kOneByteChar) { | 10162 if (char_size == kOneByteChar) { |
| 10258 return OneByteString::ConcatAll(strings, result_len, space); | 10163 return OneByteString::ConcatAll(strings, result_len, space); |
| 10259 } else if (char_size == kTwoByteChar) { | |
| 10260 return TwoByteString::ConcatAll(strings, result_len, space); | |
| 10261 } | 10164 } |
| 10262 ASSERT(char_size == kFourByteChar); | 10165 ASSERT(char_size == kTwoByteChar); |
| 10263 return FourByteString::ConcatAll(strings, result_len, space); | 10166 return TwoByteString::ConcatAll(strings, result_len, space); |
| 10264 } | 10167 } |
| 10265 | 10168 |
| 10266 | 10169 |
| 10267 RawString* String::SubString(const String& str, | 10170 RawString* String::SubString(const String& str, |
| 10268 intptr_t begin_index, | 10171 intptr_t begin_index, |
| 10269 Heap::Space space) { | 10172 Heap::Space space) { |
| 10270 ASSERT(!str.IsNull()); | 10173 ASSERT(!str.IsNull()); |
| 10271 if (begin_index >= str.Length()) { | 10174 if (begin_index >= str.Length()) { |
| 10272 return String::null(); | 10175 return String::null(); |
| 10273 } | 10176 } |
| 10274 return String::SubString(str, begin_index, (str.Length() - begin_index)); | 10177 return String::SubString(str, begin_index, (str.Length() - begin_index)); |
| 10275 } | 10178 } |
| 10276 | 10179 |
| 10277 | 10180 |
| 10278 RawString* String::SubString(const String& str, | 10181 RawString* String::SubString(const String& str, |
| 10279 intptr_t begin_index, | 10182 intptr_t begin_index, |
| 10280 intptr_t length, | 10183 intptr_t length, |
| 10281 Heap::Space space) { | 10184 Heap::Space space) { |
| 10282 ASSERT(!str.IsNull()); | 10185 ASSERT(!str.IsNull()); |
| 10283 ASSERT(begin_index >= 0); | 10186 ASSERT(begin_index >= 0); |
| 10284 ASSERT(length >= 0); | 10187 ASSERT(length >= 0); |
| 10285 if (begin_index <= str.Length() && length == 0) { | 10188 if (begin_index <= str.Length() && length == 0) { |
| 10286 return Symbols::Empty(); | 10189 return Symbols::Empty(); |
| 10287 } | 10190 } |
| 10288 if (begin_index > str.Length()) { | 10191 if (begin_index > str.Length()) { |
| 10289 return String::null(); | 10192 return String::null(); |
| 10290 } | 10193 } |
| 10291 String& result = String::Handle(); | 10194 String& result = String::Handle(); |
| 10292 bool is_one_byte_string = true; | 10195 bool is_one_byte_string = true; |
| 10293 bool is_two_byte_string = true; | |
| 10294 intptr_t char_size = str.CharSize(); | 10196 intptr_t char_size = str.CharSize(); |
| 10295 if (char_size == kTwoByteChar) { | 10197 if (char_size == kTwoByteChar) { |
| 10296 for (intptr_t i = begin_index; i < begin_index + length; ++i) { | 10198 for (intptr_t i = begin_index; i < begin_index + length; ++i) { |
| 10297 if (str.CharAt(i) > 0xFF) { | 10199 if (str.CharAt(i) > 0x7F) { |
| 10298 is_one_byte_string = false; | 10200 is_one_byte_string = false; |
| 10299 break; | 10201 break; |
| 10300 } | 10202 } |
| 10301 } | 10203 } |
| 10302 } else if (char_size == kFourByteChar) { | |
| 10303 for (intptr_t i = begin_index; i < begin_index + length; ++i) { | |
| 10304 if (str.CharAt(i) > 0xFFFF) { | |
| 10305 is_one_byte_string = false; | |
| 10306 is_two_byte_string = false; | |
| 10307 break; | |
| 10308 } else if (str.CharAt(i) > 0xFF) { | |
| 10309 is_one_byte_string = false; | |
| 10310 } | |
| 10311 } | |
| 10312 } | 10204 } |
| 10313 if (is_one_byte_string) { | 10205 if (is_one_byte_string) { |
| 10314 result ^= OneByteString::New(length, space); | 10206 result ^= OneByteString::New(length, space); |
| 10315 } else if (is_two_byte_string) { | 10207 } else { |
| 10316 result ^= TwoByteString::New(length, space); | 10208 result ^= TwoByteString::New(length, space); |
| 10317 } else { | |
| 10318 result ^= FourByteString::New(length, space); | |
| 10319 } | 10209 } |
| 10320 String::Copy(result, 0, str, begin_index, length); | 10210 String::Copy(result, 0, str, begin_index, length); |
| 10321 return result.raw(); | 10211 return result.raw(); |
| 10322 } | 10212 } |
| 10323 | 10213 |
| 10324 | 10214 |
| 10325 const char* String::ToCString() const { | 10215 const char* String::ToCString() const { |
| 10326 intptr_t len = Utf8::Length(*this); | 10216 intptr_t len = Utf8::Length(*this); |
| 10327 Zone* zone = Isolate::Current()->current_zone(); | 10217 Zone* zone = Isolate::Current()->current_zone(); |
| 10328 char* result = zone->Alloc<char>(len + 1); | 10218 uint8_t* result = zone->Alloc<uint8_t>(len + 1); |
| 10329 Utf8::Encode(*this, result, len); | 10219 ToUTF8(result, len); |
| 10330 result[len] = 0; | 10220 result[len] = 0; |
| 10331 return result; | 10221 return reinterpret_cast<const char*>(result); |
| 10222 } |
| 10223 |
| 10224 |
| 10225 void String::ToUTF8(uint8_t* utf8_array, intptr_t array_len) const { |
| 10226 if (CharSize() == kOneByteChar) { |
| 10227 const OneByteString& obj = OneByteString::Cast(*this); |
| 10228 ASSERT(array_len >= obj.Length()); |
| 10229 if (obj.Length() > 0) { |
| 10230 memmove(utf8_array, obj.CharAddr(0), obj.Length()); |
| 10231 } |
| 10232 } else { |
| 10233 ASSERT(array_len >= Utf8::Length(*this)); |
| 10234 Utf8::Encode(*this, reinterpret_cast<char*>(utf8_array), array_len); |
| 10235 } |
| 10332 } | 10236 } |
| 10333 | 10237 |
| 10334 | 10238 |
| 10335 RawString* String::Transform(int32_t (*mapping)(int32_t ch), | 10239 RawString* String::Transform(int32_t (*mapping)(int32_t ch), |
| 10336 const String& str, | 10240 const String& str, |
| 10337 Heap::Space space) { | 10241 Heap::Space space) { |
| 10338 ASSERT(!str.IsNull()); | 10242 ASSERT(!str.IsNull()); |
| 10339 bool has_mapping = false; | 10243 bool has_mapping = false; |
| 10340 int32_t dst_max = 0; | 10244 int32_t dst_max = 0; |
| 10341 intptr_t len = str.Length(); | 10245 intptr_t len = str.Length(); |
| 10342 // TODO(cshapiro): assume a transform is required, rollback if not. | 10246 // TODO(cshapiro): assume a transform is required, rollback if not. |
| 10343 for (intptr_t i = 0; i < len; ++i) { | 10247 for (intptr_t i = 0; i < len; ++i) { |
| 10344 int32_t src = str.CharAt(i); | 10248 int32_t src = str.CharAt(i); |
| 10345 int32_t dst = mapping(src); | 10249 int32_t dst = mapping(src); |
| 10346 if (src != dst) { | 10250 if (src != dst) { |
| 10347 has_mapping = true; | 10251 has_mapping = true; |
| 10348 } | 10252 } |
| 10349 dst_max = Utils::Maximum(dst_max, dst); | 10253 dst_max = Utils::Maximum(dst_max, dst); |
| 10350 } | 10254 } |
| 10351 if (!has_mapping) { | 10255 if (!has_mapping) { |
| 10352 return str.raw(); | 10256 return str.raw(); |
| 10353 } | 10257 } |
| 10354 if (dst_max <= 0xFF) { | 10258 if (dst_max <= 0x7F) { |
| 10355 return OneByteString::Transform(mapping, str, space); | 10259 return OneByteString::Transform(mapping, str, space); |
| 10356 } | 10260 } |
| 10357 if (dst_max <= 0xFFFF) { | 10261 ASSERT(dst_max > 0x7F); |
| 10358 return TwoByteString::Transform(mapping, str, space); | 10262 return TwoByteString::Transform(mapping, str, space); |
| 10359 } | |
| 10360 ASSERT(dst_max > 0xFFFF); | |
| 10361 return FourByteString::Transform(mapping, str, space); | |
| 10362 } | 10263 } |
| 10363 | 10264 |
| 10364 | 10265 |
| 10365 RawString* String::ToUpperCase(const String& str, Heap::Space space) { | 10266 RawString* String::ToUpperCase(const String& str, Heap::Space space) { |
| 10366 // TODO(cshapiro): create a fast-path for OneByteString instances. | 10267 // TODO(cshapiro): create a fast-path for OneByteString instances. |
| 10367 return Transform(CaseMapping::ToUpper, str, space); | 10268 return Transform(CaseMapping::ToUpper, str, space); |
| 10368 } | 10269 } |
| 10369 | 10270 |
| 10370 | 10271 |
| 10371 RawString* String::ToLowerCase(const String& str, Heap::Space space) { | 10272 RawString* String::ToLowerCase(const String& str, Heap::Space space) { |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10482 } | 10383 } |
| 10483 return result.raw(); | 10384 return result.raw(); |
| 10484 } | 10385 } |
| 10485 | 10386 |
| 10486 | 10387 |
| 10487 RawOneByteString* OneByteString::New(const uint8_t* characters, | 10388 RawOneByteString* OneByteString::New(const uint8_t* characters, |
| 10488 intptr_t len, | 10389 intptr_t len, |
| 10489 Heap::Space space) { | 10390 Heap::Space space) { |
| 10490 const OneByteString& result = | 10391 const OneByteString& result = |
| 10491 OneByteString::Handle(OneByteString::New(len, space)); | 10392 OneByteString::Handle(OneByteString::New(len, space)); |
| 10492 String::Copy(result, 0, characters, len); | 10393 if (len > 0) { |
| 10394 NoGCScope no_gc; |
| 10395 memmove(result.CharAddr(0), characters, len); |
| 10396 } |
| 10493 return result.raw(); | 10397 return result.raw(); |
| 10494 } | 10398 } |
| 10495 | 10399 |
| 10496 | 10400 |
| 10497 RawOneByteString* OneByteString::New(const uint16_t* characters, | 10401 RawOneByteString* OneByteString::New(const uint16_t* characters, |
| 10498 intptr_t len, | 10402 intptr_t len, |
| 10499 Heap::Space space) { | 10403 Heap::Space space) { |
| 10500 const OneByteString& result = | 10404 const OneByteString& result = |
| 10501 OneByteString::Handle(OneByteString::New(len, space)); | 10405 OneByteString::Handle(OneByteString::New(len, space)); |
| 10502 String::Copy(result, 0, characters, len); | 10406 for (intptr_t i = 0; i < len; ++i) { |
| 10407 ASSERT(characters[i] <= 0x7F); |
| 10408 *result.CharAddr(i) = characters[i]; |
| 10409 } |
| 10503 return result.raw(); | 10410 return result.raw(); |
| 10504 } | 10411 } |
| 10505 | 10412 |
| 10506 | 10413 |
| 10507 RawOneByteString* OneByteString::New(const uint32_t* characters, | 10414 RawOneByteString* OneByteString::New(const uint32_t* characters, |
| 10508 intptr_t len, | 10415 intptr_t len, |
| 10509 Heap::Space space) { | 10416 Heap::Space space) { |
| 10510 const OneByteString& result = | 10417 const OneByteString& result = |
| 10511 OneByteString::Handle(OneByteString::New(len, space)); | 10418 OneByteString::Handle(OneByteString::New(len, space)); |
| 10512 String::Copy(result, 0, characters, len); | 10419 for (intptr_t i = 0; i < len; ++i) { |
| 10420 ASSERT(characters[i] <= 0x7F); |
| 10421 *result.CharAddr(i) = characters[i]; |
| 10422 } |
| 10513 return result.raw(); | 10423 return result.raw(); |
| 10514 } | 10424 } |
| 10515 | 10425 |
| 10516 | 10426 |
| 10517 RawOneByteString* OneByteString::New(const OneByteString& str, | 10427 RawOneByteString* OneByteString::New(const OneByteString& str, |
| 10518 Heap::Space space) { | 10428 Heap::Space space) { |
| 10519 intptr_t len = str.Length(); | 10429 intptr_t len = str.Length(); |
| 10520 const OneByteString& result = | 10430 const OneByteString& result = |
| 10521 OneByteString::Handle(OneByteString::New(len, space)); | 10431 OneByteString::Handle(OneByteString::New(len, space)); |
| 10522 String::Copy(result, 0, str, 0, len); | 10432 String::Copy(result, 0, str, 0, len); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10558 | 10468 |
| 10559 RawOneByteString* OneByteString::Transform(int32_t (*mapping)(int32_t ch), | 10469 RawOneByteString* OneByteString::Transform(int32_t (*mapping)(int32_t ch), |
| 10560 const String& str, | 10470 const String& str, |
| 10561 Heap::Space space) { | 10471 Heap::Space space) { |
| 10562 ASSERT(!str.IsNull()); | 10472 ASSERT(!str.IsNull()); |
| 10563 intptr_t len = str.Length(); | 10473 intptr_t len = str.Length(); |
| 10564 const OneByteString& result = | 10474 const OneByteString& result = |
| 10565 OneByteString::Handle(OneByteString::New(len, space)); | 10475 OneByteString::Handle(OneByteString::New(len, space)); |
| 10566 for (intptr_t i = 0; i < len; ++i) { | 10476 for (intptr_t i = 0; i < len; ++i) { |
| 10567 int32_t ch = mapping(str.CharAt(i)); | 10477 int32_t ch = mapping(str.CharAt(i)); |
| 10568 ASSERT(ch >= 0 && ch <= 0xFF); | 10478 ASSERT(ch >= 0 && ch <= 0x7F); |
| 10569 *result.CharAddr(i) = ch; | 10479 *result.CharAddr(i) = ch; |
| 10570 } | 10480 } |
| 10571 return result.raw(); | 10481 return result.raw(); |
| 10572 } | 10482 } |
| 10573 | 10483 |
| 10574 | 10484 |
| 10575 const char* OneByteString::ToCString() const { | 10485 const char* OneByteString::ToCString() const { |
| 10576 return String::ToCString(); | 10486 return String::ToCString(); |
| 10577 } | 10487 } |
| 10578 | 10488 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10624 space); | 10534 space); |
| 10625 NoGCScope no_gc; | 10535 NoGCScope no_gc; |
| 10626 result ^= raw; | 10536 result ^= raw; |
| 10627 result.SetLength(len); | 10537 result.SetLength(len); |
| 10628 result.SetHash(0); | 10538 result.SetHash(0); |
| 10629 } | 10539 } |
| 10630 return result.raw(); | 10540 return result.raw(); |
| 10631 } | 10541 } |
| 10632 | 10542 |
| 10633 | 10543 |
| 10634 RawTwoByteString* TwoByteString::New(const uint16_t* characters, | 10544 RawTwoByteString* TwoByteString::New(const uint16_t* utf16_array, |
| 10635 intptr_t len, | 10545 intptr_t array_len, |
| 10636 Heap::Space space) { | 10546 Heap::Space space) { |
| 10547 ASSERT(array_len > 0); |
| 10637 const TwoByteString& result = | 10548 const TwoByteString& result = |
| 10638 TwoByteString::Handle(TwoByteString::New(len, space)); | 10549 TwoByteString::Handle(TwoByteString::New(array_len, space)); |
| 10639 String::Copy(result, 0, characters, len); | 10550 { |
| 10551 NoGCScope no_gc; |
| 10552 memmove(result.CharAddr(0), utf16_array, (array_len * 2)); |
| 10553 } |
| 10640 return result.raw(); | 10554 return result.raw(); |
| 10641 } | 10555 } |
| 10642 | 10556 |
| 10643 | 10557 |
| 10644 RawTwoByteString* TwoByteString::New(const uint32_t* characters, | 10558 RawTwoByteString* TwoByteString::New(intptr_t utf16_len, |
| 10645 intptr_t len, | 10559 const uint32_t* utf32_array, |
| 10560 intptr_t array_len, |
| 10646 Heap::Space space) { | 10561 Heap::Space space) { |
| 10562 ASSERT((array_len > 0) && (utf16_len >= array_len)); |
| 10647 const TwoByteString& result = | 10563 const TwoByteString& result = |
| 10648 TwoByteString::Handle(TwoByteString::New(len, space)); | 10564 TwoByteString::Handle(TwoByteString::New(utf16_len, space)); |
| 10649 String::Copy(result, 0, characters, len); | 10565 { |
| 10566 NoGCScope no_gc; |
| 10567 intptr_t j = 0; |
| 10568 for (intptr_t i = 0; i < array_len; ++i) { |
| 10569 if (utf32_array[i] > 0xffff) { |
| 10570 ASSERT(j < (utf16_len - 1)); |
| 10571 Utf8::ConvertUTF32ToUTF16(utf32_array[i], result.CharAddr(j)); |
| 10572 j += 2; |
| 10573 } else { |
| 10574 ASSERT(j < utf16_len); |
| 10575 *result.CharAddr(j) = utf32_array[i]; |
| 10576 j += 1; |
| 10577 } |
| 10578 } |
| 10579 } |
| 10650 return result.raw(); | 10580 return result.raw(); |
| 10651 } | 10581 } |
| 10652 | 10582 |
| 10653 | 10583 |
| 10654 RawTwoByteString* TwoByteString::New(const TwoByteString& str, | 10584 RawTwoByteString* TwoByteString::New(const TwoByteString& str, |
| 10655 Heap::Space space) { | 10585 Heap::Space space) { |
| 10656 intptr_t len = str.Length(); | 10586 intptr_t len = str.Length(); |
| 10657 const TwoByteString& result = | 10587 const TwoByteString& result = |
| 10658 TwoByteString::Handle(TwoByteString::New(len, space)); | 10588 TwoByteString::Handle(TwoByteString::New(len, space)); |
| 10659 String::Copy(result, 0, str, 0, len); | 10589 String::Copy(result, 0, str, 0, len); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10707 } | 10637 } |
| 10708 return result.raw(); | 10638 return result.raw(); |
| 10709 } | 10639 } |
| 10710 | 10640 |
| 10711 | 10641 |
| 10712 const char* TwoByteString::ToCString() const { | 10642 const char* TwoByteString::ToCString() const { |
| 10713 return String::ToCString(); | 10643 return String::ToCString(); |
| 10714 } | 10644 } |
| 10715 | 10645 |
| 10716 | 10646 |
| 10717 RawFourByteString* FourByteString::EscapeSpecialCharacters(bool raw_str) const { | |
| 10718 intptr_t len = Length(); | |
| 10719 if (len > 0) { | |
| 10720 intptr_t num_escapes = 0; | |
| 10721 intptr_t index = 0; | |
| 10722 for (intptr_t i = 0; i < len; i++) { | |
| 10723 if (IsSpecialCharacter(*CharAddr(i)) || | |
| 10724 (!raw_str && (*CharAddr(i) == '\\'))) { | |
| 10725 num_escapes += 1; | |
| 10726 } | |
| 10727 } | |
| 10728 const FourByteString& dststr = FourByteString::Handle( | |
| 10729 FourByteString::New(len + num_escapes, Heap::kNew)); | |
| 10730 for (intptr_t i = 0; i < len; i++) { | |
| 10731 if (IsSpecialCharacter(*CharAddr(i))) { | |
| 10732 *(dststr.CharAddr(index)) = '\\'; | |
| 10733 *(dststr.CharAddr(index + 1)) = SpecialCharacter(*CharAddr(i)); | |
| 10734 index += 2; | |
| 10735 } else if (!raw_str && (*CharAddr(i) == '\\')) { | |
| 10736 *(dststr.CharAddr(index)) = '\\'; | |
| 10737 *(dststr.CharAddr(index + 1)) = '\\'; | |
| 10738 index += 2; | |
| 10739 } else { | |
| 10740 *(dststr.CharAddr(index)) = *CharAddr(i); | |
| 10741 index += 1; | |
| 10742 } | |
| 10743 } | |
| 10744 return dststr.raw(); | |
| 10745 } | |
| 10746 return FourByteString::null(); | |
| 10747 } | |
| 10748 | |
| 10749 | |
| 10750 RawFourByteString* FourByteString::New(intptr_t len, | |
| 10751 Heap::Space space) { | |
| 10752 ASSERT(Isolate::Current()->object_store()->four_byte_string_class() != | |
| 10753 Class::null()); | |
| 10754 if (len < 0 || len > kMaxElements) { | |
| 10755 // This should be caught before we reach here. | |
| 10756 FATAL1("Fatal error in FourByteString::New: invalid len %"Pd"\n", len); | |
| 10757 } | |
| 10758 FourByteString& result = FourByteString::Handle(); | |
| 10759 { | |
| 10760 RawObject* raw = Object::Allocate(FourByteString::kClassId, | |
| 10761 FourByteString::InstanceSize(len), | |
| 10762 space); | |
| 10763 NoGCScope no_gc; | |
| 10764 result ^= raw; | |
| 10765 result.SetLength(len); | |
| 10766 result.SetHash(0); | |
| 10767 } | |
| 10768 return result.raw(); | |
| 10769 } | |
| 10770 | |
| 10771 | |
| 10772 RawFourByteString* FourByteString::New(const uint32_t* characters, | |
| 10773 intptr_t len, | |
| 10774 Heap::Space space) { | |
| 10775 const FourByteString& result = | |
| 10776 FourByteString::Handle(FourByteString::New(len, space)); | |
| 10777 String::Copy(result, 0, characters, len); | |
| 10778 return result.raw(); | |
| 10779 } | |
| 10780 | |
| 10781 | |
| 10782 RawFourByteString* FourByteString::New(const FourByteString& str, | |
| 10783 Heap::Space space) { | |
| 10784 return FourByteString::New(str.CharAddr(0), str.Length(), space); | |
| 10785 } | |
| 10786 | |
| 10787 | |
| 10788 RawFourByteString* FourByteString::Concat(const String& str1, | |
| 10789 const String& str2, | |
| 10790 Heap::Space space) { | |
| 10791 intptr_t len1 = str1.Length(); | |
| 10792 intptr_t len2 = str2.Length(); | |
| 10793 intptr_t len = len1 + len2; | |
| 10794 const FourByteString& result = | |
| 10795 FourByteString::Handle(FourByteString::New(len, space)); | |
| 10796 String::Copy(result, 0, str1, 0, len1); | |
| 10797 String::Copy(result, len1, str2, 0, len2); | |
| 10798 return result.raw(); | |
| 10799 } | |
| 10800 | |
| 10801 | |
| 10802 RawFourByteString* FourByteString::ConcatAll(const Array& strings, | |
| 10803 intptr_t len, | |
| 10804 Heap::Space space) { | |
| 10805 const FourByteString& result = | |
| 10806 FourByteString::Handle(FourByteString::New(len, space)); | |
| 10807 String& str = String::Handle(); | |
| 10808 { | |
| 10809 intptr_t strings_len = strings.Length(); | |
| 10810 intptr_t pos = 0; | |
| 10811 for (intptr_t i = 0; i < strings_len; i++) { | |
| 10812 str ^= strings.At(i); | |
| 10813 intptr_t str_len = str.Length(); | |
| 10814 String::Copy(result, pos, str, 0, str_len); | |
| 10815 pos += str_len; | |
| 10816 } | |
| 10817 } | |
| 10818 return result.raw(); | |
| 10819 } | |
| 10820 | |
| 10821 | |
| 10822 RawFourByteString* FourByteString::Transform(int32_t (*mapping)(int32_t ch), | |
| 10823 const String& str, | |
| 10824 Heap::Space space) { | |
| 10825 ASSERT(!str.IsNull()); | |
| 10826 intptr_t len = str.Length(); | |
| 10827 const FourByteString& result = | |
| 10828 FourByteString::Handle(FourByteString::New(len, space)); | |
| 10829 for (intptr_t i = 0; i < len; ++i) { | |
| 10830 int32_t ch = mapping(str.CharAt(i)); | |
| 10831 ASSERT(ch >= 0 && ch <= 0x10FFFF); | |
| 10832 *result.CharAddr(i) = ch; | |
| 10833 } | |
| 10834 return result.raw(); | |
| 10835 } | |
| 10836 | |
| 10837 | |
| 10838 const char* FourByteString::ToCString() const { | |
| 10839 return String::ToCString(); | |
| 10840 } | |
| 10841 | |
| 10842 | |
| 10843 static void AddFinalizer(const Object& referent, | 10647 static void AddFinalizer(const Object& referent, |
| 10844 void* peer, | 10648 void* peer, |
| 10845 Dart_WeakPersistentHandleFinalizer callback) { | 10649 Dart_WeakPersistentHandleFinalizer callback) { |
| 10846 ASSERT(callback != NULL); | 10650 ASSERT(callback != NULL); |
| 10847 ApiState* state = Isolate::Current()->api_state(); | 10651 ApiState* state = Isolate::Current()->api_state(); |
| 10848 ASSERT(state != NULL); | 10652 ASSERT(state != NULL); |
| 10849 FinalizablePersistentHandle* weak_ref = | 10653 FinalizablePersistentHandle* weak_ref = |
| 10850 state->weak_persistent_handles().AllocateHandle(); | 10654 state->weak_persistent_handles().AllocateHandle(); |
| 10851 weak_ref->set_raw(referent); | 10655 weak_ref->set_raw(referent); |
| 10852 weak_ref->set_peer(peer); | 10656 weak_ref->set_peer(peer); |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10941 delete reinterpret_cast<ExternalStringData<uint16_t>*>(peer); | 10745 delete reinterpret_cast<ExternalStringData<uint16_t>*>(peer); |
| 10942 DeleteWeakPersistentHandle(handle); | 10746 DeleteWeakPersistentHandle(handle); |
| 10943 } | 10747 } |
| 10944 | 10748 |
| 10945 | 10749 |
| 10946 const char* ExternalTwoByteString::ToCString() const { | 10750 const char* ExternalTwoByteString::ToCString() const { |
| 10947 return String::ToCString(); | 10751 return String::ToCString(); |
| 10948 } | 10752 } |
| 10949 | 10753 |
| 10950 | 10754 |
| 10951 RawExternalFourByteString* ExternalFourByteString::New( | |
| 10952 const uint32_t* data, | |
| 10953 intptr_t len, | |
| 10954 void* peer, | |
| 10955 Dart_PeerFinalizer callback, | |
| 10956 Heap::Space space) { | |
| 10957 ASSERT(Isolate::Current()->object_store()-> | |
| 10958 external_four_byte_string_class() != Class::null()); | |
| 10959 if (len < 0 || len > kMaxElements) { | |
| 10960 // This should be caught before we reach here. | |
| 10961 FATAL1("Fatal error in ExternalFourByteString::New: invalid len %"Pd"\n", | |
| 10962 len); | |
| 10963 } | |
| 10964 ExternalFourByteString& result = ExternalFourByteString::Handle(); | |
| 10965 ExternalStringData<uint32_t>* external_data = | |
| 10966 new ExternalStringData<uint32_t>(data, peer, callback); | |
| 10967 { | |
| 10968 RawObject* raw = Object::Allocate(ExternalFourByteString::kClassId, | |
| 10969 ExternalFourByteString::InstanceSize(), | |
| 10970 space); | |
| 10971 NoGCScope no_gc; | |
| 10972 result ^= raw; | |
| 10973 result.SetLength(len); | |
| 10974 result.SetHash(0); | |
| 10975 result.SetExternalData(external_data); | |
| 10976 } | |
| 10977 AddFinalizer(result, external_data, ExternalFourByteString::Finalize); | |
| 10978 return result.raw(); | |
| 10979 } | |
| 10980 | |
| 10981 | |
| 10982 void ExternalFourByteString::Finalize(Dart_Handle handle, void* peer) { | |
| 10983 delete reinterpret_cast<ExternalStringData<uint32_t>*>(peer); | |
| 10984 DeleteWeakPersistentHandle(handle); | |
| 10985 } | |
| 10986 | |
| 10987 | |
| 10988 const char* ExternalFourByteString::ToCString() const { | |
| 10989 return String::ToCString(); | |
| 10990 } | |
| 10991 | |
| 10992 | |
| 10993 RawBool* Bool::True() { | 10755 RawBool* Bool::True() { |
| 10994 return Isolate::Current()->object_store()->true_value(); | 10756 return Isolate::Current()->object_store()->true_value(); |
| 10995 } | 10757 } |
| 10996 | 10758 |
| 10997 | 10759 |
| 10998 RawBool* Bool::False() { | 10760 RawBool* Bool::False() { |
| 10999 return Isolate::Current()->object_store()->false_value(); | 10761 return Isolate::Current()->object_store()->false_value(); |
| 11000 } | 10762 } |
| 11001 | 10763 |
| 11002 | 10764 |
| (...skipping 1196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12199 } | 11961 } |
| 12200 return result.raw(); | 11962 return result.raw(); |
| 12201 } | 11963 } |
| 12202 | 11964 |
| 12203 | 11965 |
| 12204 const char* WeakProperty::ToCString() const { | 11966 const char* WeakProperty::ToCString() const { |
| 12205 return "_WeakProperty"; | 11967 return "_WeakProperty"; |
| 12206 } | 11968 } |
| 12207 | 11969 |
| 12208 } // namespace dart | 11970 } // namespace dart |
| OLD | NEW |