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

Side by Side Diff: vm/object.cc

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

Powered by Google App Engine
This is Rietveld 408576698