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

Side by Side Diff: runtime/vm/object.cc

Issue 11318018: - Represent strings internally in UTF-16 format, this makes it (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/object.h" 5 #include "vm/object.h"
6 6
7 #include "include/dart_api.h" 7 #include "include/dart_api.h"
8 #include "platform/assert.h" 8 #include "platform/assert.h"
9 #include "vm/assembler.h" 9 #include "vm/assembler.h"
10 #include "vm/bigint_operations.h" 10 #include "vm/bigint_operations.h"
(...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698