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

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

Powered by Google App Engine
This is Rietveld 408576698