| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 "vm/assembler.h" | 7 #include "vm/assembler.h" |
| 8 #include "vm/assert.h" | 8 #include "vm/assert.h" |
| 9 #include "vm/bigint_operations.h" | 9 #include "vm/bigint_operations.h" |
| 10 #include "vm/bootstrap.h" | 10 #include "vm/bootstrap.h" |
| (...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 458 cls = Class::New<TwoByteString>(); | 458 cls = Class::New<TwoByteString>(); |
| 459 object_store->set_two_byte_string_class(cls); | 459 object_store->set_two_byte_string_class(cls); |
| 460 RegisterClass(cls, "TwoByteString", impl_script, core_impl_lib); | 460 RegisterClass(cls, "TwoByteString", impl_script, core_impl_lib); |
| 461 pending_classes.Add(&Class::ZoneHandle(cls.raw())); | 461 pending_classes.Add(&Class::ZoneHandle(cls.raw())); |
| 462 | 462 |
| 463 cls = Class::New<FourByteString>(); | 463 cls = Class::New<FourByteString>(); |
| 464 object_store->set_four_byte_string_class(cls); | 464 object_store->set_four_byte_string_class(cls); |
| 465 RegisterClass(cls, "FourByteString", impl_script, core_impl_lib); | 465 RegisterClass(cls, "FourByteString", impl_script, core_impl_lib); |
| 466 pending_classes.Add(&Class::ZoneHandle(cls.raw())); | 466 pending_classes.Add(&Class::ZoneHandle(cls.raw())); |
| 467 | 467 |
| 468 cls = Class::New<ExternalOneByteString>(); |
| 469 object_store->set_external_one_byte_string_class(cls); |
| 470 RegisterClass(cls, "ExternalOneByteString", impl_script, core_impl_lib); |
| 471 pending_classes.Add(&Class::ZoneHandle(cls.raw())); |
| 472 |
| 473 cls = Class::New<ExternalTwoByteString>(); |
| 474 object_store->set_external_two_byte_string_class(cls); |
| 475 RegisterClass(cls, "ExternalTwoByteString", impl_script, core_impl_lib); |
| 476 pending_classes.Add(&Class::ZoneHandle(cls.raw())); |
| 477 |
| 478 cls = Class::New<ExternalFourByteString>(); |
| 479 object_store->set_external_four_byte_string_class(cls); |
| 480 RegisterClass(cls, "ExternalFourByteString", impl_script, core_impl_lib); |
| 481 pending_classes.Add(&Class::ZoneHandle(cls.raw())); |
| 482 |
| 468 cls = Class::New<UnhandledException>(); | 483 cls = Class::New<UnhandledException>(); |
| 469 object_store->set_unhandled_exception_class(cls); | 484 object_store->set_unhandled_exception_class(cls); |
| 470 RegisterClass(cls, "UnhandledException", impl_script, core_impl_lib); | 485 RegisterClass(cls, "UnhandledException", impl_script, core_impl_lib); |
| 471 pending_classes.Add(&Class::ZoneHandle(cls.raw())); | 486 pending_classes.Add(&Class::ZoneHandle(cls.raw())); |
| 472 | 487 |
| 473 cls = Class::New<Stacktrace>(); | 488 cls = Class::New<Stacktrace>(); |
| 474 object_store->set_stacktrace_class(cls); | 489 object_store->set_stacktrace_class(cls); |
| 475 RegisterClass(cls, "Stacktrace", impl_script, core_impl_lib); | 490 RegisterClass(cls, "Stacktrace", impl_script, core_impl_lib); |
| 476 pending_classes.Add(&Class::ZoneHandle(cls.raw())); | 491 pending_classes.Add(&Class::ZoneHandle(cls.raw())); |
| 477 // Super type set below, after Object is allocated. | 492 // Super type set below, after Object is allocated. |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 633 | 648 |
| 634 cls = Class::New<OneByteString>(); | 649 cls = Class::New<OneByteString>(); |
| 635 object_store->set_one_byte_string_class(cls); | 650 object_store->set_one_byte_string_class(cls); |
| 636 | 651 |
| 637 cls = Class::New<TwoByteString>(); | 652 cls = Class::New<TwoByteString>(); |
| 638 object_store->set_two_byte_string_class(cls); | 653 object_store->set_two_byte_string_class(cls); |
| 639 | 654 |
| 640 cls = Class::New<FourByteString>(); | 655 cls = Class::New<FourByteString>(); |
| 641 object_store->set_four_byte_string_class(cls); | 656 object_store->set_four_byte_string_class(cls); |
| 642 | 657 |
| 658 cls = Class::New<ExternalOneByteString>(); |
| 659 object_store->set_external_one_byte_string_class(cls); |
| 660 |
| 661 cls = Class::New<ExternalTwoByteString>(); |
| 662 object_store->set_external_two_byte_string_class(cls); |
| 663 |
| 664 cls = Class::New<ExternalFourByteString>(); |
| 665 object_store->set_external_four_byte_string_class(cls); |
| 666 |
| 643 cls = Class::New<Bool>(); | 667 cls = Class::New<Bool>(); |
| 644 object_store->set_bool_class(cls); | 668 object_store->set_bool_class(cls); |
| 645 | 669 |
| 646 cls = Class::New<UnhandledException>(); | 670 cls = Class::New<UnhandledException>(); |
| 647 object_store->set_unhandled_exception_class(cls); | 671 object_store->set_unhandled_exception_class(cls); |
| 648 | 672 |
| 649 cls = Class::New<Stacktrace>(); | 673 cls = Class::New<Stacktrace>(); |
| 650 object_store->set_stacktrace_class(cls); | 674 object_store->set_stacktrace_class(cls); |
| 651 | 675 |
| 652 cls = Class::New<JSRegExp>(); | 676 cls = Class::New<JSRegExp>(); |
| (...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1131 return object_store->double_class(); | 1155 return object_store->double_class(); |
| 1132 case kOneByteString: | 1156 case kOneByteString: |
| 1133 ASSERT(object_store->one_byte_string_class() != Class::null()); | 1157 ASSERT(object_store->one_byte_string_class() != Class::null()); |
| 1134 return object_store->one_byte_string_class(); | 1158 return object_store->one_byte_string_class(); |
| 1135 case kTwoByteString: | 1159 case kTwoByteString: |
| 1136 ASSERT(object_store->two_byte_string_class() != Class::null()); | 1160 ASSERT(object_store->two_byte_string_class() != Class::null()); |
| 1137 return object_store->two_byte_string_class(); | 1161 return object_store->two_byte_string_class(); |
| 1138 case kFourByteString: | 1162 case kFourByteString: |
| 1139 ASSERT(object_store->four_byte_string_class() != Class::null()); | 1163 ASSERT(object_store->four_byte_string_class() != Class::null()); |
| 1140 return object_store->four_byte_string_class(); | 1164 return object_store->four_byte_string_class(); |
| 1165 case kExternalOneByteString: |
| 1166 ASSERT(object_store->external_one_byte_string_class() != Class::null()); |
| 1167 return object_store->external_one_byte_string_class(); |
| 1168 case kExternalTwoByteString: |
| 1169 ASSERT(object_store->external_two_byte_string_class() != Class::null()); |
| 1170 return object_store->external_two_byte_string_class(); |
| 1171 case kExternalFourByteString: |
| 1172 ASSERT(object_store->external_four_byte_string_class() != Class::null()); |
| 1173 return object_store->external_four_byte_string_class(); |
| 1141 case kBool: | 1174 case kBool: |
| 1142 ASSERT(object_store->bool_class() != Class::null()); | 1175 ASSERT(object_store->bool_class() != Class::null()); |
| 1143 return object_store->bool_class(); | 1176 return object_store->bool_class(); |
| 1144 case kArray: | 1177 case kArray: |
| 1145 ASSERT(object_store->array_class() != Class::null()); | 1178 ASSERT(object_store->array_class() != Class::null()); |
| 1146 return object_store->array_class(); | 1179 return object_store->array_class(); |
| 1147 case kImmutableArray: | 1180 case kImmutableArray: |
| 1148 ASSERT(object_store->immutable_array_class() != Class::null()); | 1181 ASSERT(object_store->immutable_array_class() != Class::null()); |
| 1149 return object_store->immutable_array_class(); | 1182 return object_store->immutable_array_class(); |
| 1150 case kByteBuffer: | 1183 case kByteBuffer: |
| (...skipping 4433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5584 } | 5617 } |
| 5585 | 5618 |
| 5586 | 5619 |
| 5587 int32_t String::CharAt(intptr_t index) const { | 5620 int32_t String::CharAt(intptr_t index) const { |
| 5588 // String is an abstract class. | 5621 // String is an abstract class. |
| 5589 UNREACHABLE(); | 5622 UNREACHABLE(); |
| 5590 return 0; | 5623 return 0; |
| 5591 } | 5624 } |
| 5592 | 5625 |
| 5593 | 5626 |
| 5627 intptr_t String::CharSize() const { |
| 5628 // String is an abstract class. |
| 5629 UNREACHABLE(); |
| 5630 return 0; |
| 5631 } |
| 5632 |
| 5633 |
| 5594 bool String::Equals(const Instance& other) const { | 5634 bool String::Equals(const Instance& other) const { |
| 5595 if (this->raw() == other.raw()) { | 5635 if (this->raw() == other.raw()) { |
| 5596 // Both handles point to the same raw instance. | 5636 // Both handles point to the same raw instance. |
| 5597 return true; | 5637 return true; |
| 5598 } | 5638 } |
| 5599 | 5639 |
| 5600 if (!other.IsString() || other.IsNull()) { | 5640 if (!other.IsString() || other.IsNull()) { |
| 5601 return false; | 5641 return false; |
| 5602 } | 5642 } |
| 5603 | 5643 |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5847 } | 5887 } |
| 5848 return FourByteString::New(characters, len, space); | 5888 return FourByteString::New(characters, len, space); |
| 5849 } | 5889 } |
| 5850 | 5890 |
| 5851 | 5891 |
| 5852 RawString* String::New(const String& str, Heap::Space space) { | 5892 RawString* String::New(const String& str, Heap::Space space) { |
| 5853 // Currently this just creates a copy of the string in the correct space. | 5893 // Currently this just creates a copy of the string in the correct space. |
| 5854 // Once we have external string support, this will also create a heap copy of | 5894 // Once we have external string support, this will also create a heap copy of |
| 5855 // the string if necessary. Some optimizations are possible, such as not | 5895 // the string if necessary. Some optimizations are possible, such as not |
| 5856 // copying internal strings into the same space. | 5896 // copying internal strings into the same space. |
| 5857 if (str.IsOneByteString()) { | 5897 intptr_t len = str.Length(); |
| 5858 OneByteString& one_byte_str = OneByteString::Handle(); | 5898 String& result = String::Handle(); |
| 5859 one_byte_str ^= str.raw(); | 5899 intptr_t char_size = str.CharSize(); |
| 5860 return OneByteString::New(one_byte_str, space); | 5900 if (char_size == kOneByteChar) { |
| 5861 } else if (str.IsTwoByteString()) { | 5901 result ^= OneByteString::New(len, space); |
| 5862 TwoByteString& two_byte_str = TwoByteString::Handle(); | 5902 } else if (char_size == kTwoByteChar) { |
| 5863 two_byte_str ^= str.raw(); | 5903 result ^= TwoByteString::New(len, space); |
| 5864 return TwoByteString::New(two_byte_str, space); | 5904 } else { |
| 5905 ASSERT(char_size == kFourByteChar); |
| 5906 result ^= FourByteString::New(len, space); |
| 5865 } | 5907 } |
| 5866 ASSERT(str.IsFourByteString()); | 5908 String::Copy(result, 0, str, 0, len); |
| 5867 FourByteString& four_byte_str = FourByteString::Handle(); | 5909 return result.raw(); |
| 5868 four_byte_str ^= str.raw(); | |
| 5869 return FourByteString::New(four_byte_str, space); | |
| 5870 } | 5910 } |
| 5871 | 5911 |
| 5872 | 5912 |
| 5913 RawString* String::NewExternal(const uint8_t* characters, |
| 5914 intptr_t len, |
| 5915 void* peer, |
| 5916 PeerFinalizer callback, |
| 5917 Heap::Space space) { |
| 5918 return ExternalOneByteString::New(characters, len, peer, callback, space); |
| 5919 } |
| 5920 |
| 5921 |
| 5922 RawString* String::NewExternal(const uint16_t* characters, |
| 5923 intptr_t len, |
| 5924 void* peer, |
| 5925 PeerFinalizer callback, |
| 5926 Heap::Space space) { |
| 5927 return ExternalTwoByteString::New(characters, len, peer, callback, space); |
| 5928 } |
| 5929 |
| 5930 |
| 5931 RawString* String::NewExternal(const uint32_t* characters, |
| 5932 intptr_t len, |
| 5933 void* peer, |
| 5934 PeerFinalizer callback, |
| 5935 Heap::Space space) { |
| 5936 return ExternalFourByteString::New(characters, len, peer, callback, space); |
| 5937 } |
| 5938 |
| 5939 |
| 5873 void String::Copy(const String& dst, intptr_t dst_offset, | 5940 void String::Copy(const String& dst, intptr_t dst_offset, |
| 5874 const uint8_t* characters, | 5941 const uint8_t* characters, |
| 5875 intptr_t len) { | 5942 intptr_t len) { |
| 5876 ASSERT(dst_offset >= 0); | 5943 ASSERT(dst_offset >= 0); |
| 5877 ASSERT(len >= 0); | 5944 ASSERT(len >= 0); |
| 5878 ASSERT(len <= (dst.Length() - dst_offset)); | 5945 ASSERT(len <= (dst.Length() - dst_offset)); |
| 5879 if (dst.IsOneByteString()) { | 5946 if (dst.IsOneByteString()) { |
| 5880 OneByteString& onestr = OneByteString::Handle(); | 5947 OneByteString& onestr = OneByteString::Handle(); |
| 5881 onestr ^= dst.raw(); | 5948 onestr ^= dst.raw(); |
| 5882 NoGCScope no_gc; | 5949 NoGCScope no_gc; |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5971 | 6038 |
| 5972 void String::Copy(const String& dst, intptr_t dst_offset, | 6039 void String::Copy(const String& dst, intptr_t dst_offset, |
| 5973 const String& src, intptr_t src_offset, | 6040 const String& src, intptr_t src_offset, |
| 5974 intptr_t len) { | 6041 intptr_t len) { |
| 5975 ASSERT(dst_offset >= 0); | 6042 ASSERT(dst_offset >= 0); |
| 5976 ASSERT(src_offset >= 0); | 6043 ASSERT(src_offset >= 0); |
| 5977 ASSERT(len >= 0); | 6044 ASSERT(len >= 0); |
| 5978 ASSERT(len <= (dst.Length() - dst_offset)); | 6045 ASSERT(len <= (dst.Length() - dst_offset)); |
| 5979 ASSERT(len <= (src.Length() - src_offset)); | 6046 ASSERT(len <= (src.Length() - src_offset)); |
| 5980 if (len > 0) { | 6047 if (len > 0) { |
| 5981 if (src.IsOneByteString()) { | 6048 intptr_t char_size = src.CharSize(); |
| 5982 OneByteString& onestr = OneByteString::Handle(); | 6049 if (char_size == kOneByteChar) { |
| 5983 onestr ^= src.raw(); | 6050 if (src.IsOneByteString()) { |
| 5984 NoGCScope no_gc; | 6051 OneByteString& onestr = OneByteString::Handle(); |
| 5985 String::Copy(dst, dst_offset, onestr.CharAddr(0) + src_offset, len); | 6052 onestr ^= src.raw(); |
| 5986 } else if (src.IsTwoByteString()) { | 6053 NoGCScope no_gc; |
| 5987 TwoByteString& twostr = TwoByteString::Handle(); | 6054 String::Copy(dst, dst_offset, onestr.CharAddr(0) + src_offset, len); |
| 5988 twostr ^= src.raw(); | 6055 } else { |
| 5989 NoGCScope no_gc; | 6056 ASSERT(src.IsExternalOneByteString()); |
| 5990 String::Copy(dst, dst_offset, twostr.CharAddr(0) + src_offset, len); | 6057 ExternalOneByteString& onestr = ExternalOneByteString::Handle(); |
| 6058 onestr ^= src.raw(); |
| 6059 NoGCScope no_gc; |
| 6060 String::Copy(dst, dst_offset, onestr.CharAddr(0) + src_offset, len); |
| 6061 } |
| 6062 } else if (char_size == kTwoByteChar) { |
| 6063 if (src.IsTwoByteString()) { |
| 6064 TwoByteString& twostr = TwoByteString::Handle(); |
| 6065 twostr ^= src.raw(); |
| 6066 NoGCScope no_gc; |
| 6067 String::Copy(dst, dst_offset, twostr.CharAddr(0) + src_offset, len); |
| 6068 } else { |
| 6069 ASSERT(src.IsExternalTwoByteString()); |
| 6070 ExternalTwoByteString& twostr = ExternalTwoByteString::Handle(); |
| 6071 twostr ^= src.raw(); |
| 6072 NoGCScope no_gc; |
| 6073 String::Copy(dst, dst_offset, twostr.CharAddr(0) + src_offset, len); |
| 6074 } |
| 5991 } else { | 6075 } else { |
| 5992 ASSERT(src.IsFourByteString()); | 6076 ASSERT(char_size == kFourByteChar); |
| 5993 FourByteString& fourstr = FourByteString::Handle(); | 6077 if (src.IsFourByteString()) { |
| 5994 fourstr ^= src.raw(); | 6078 FourByteString& fourstr = FourByteString::Handle(); |
| 5995 NoGCScope no_gc; | 6079 fourstr ^= src.raw(); |
| 5996 String::Copy(dst, dst_offset, fourstr.CharAddr(0) + src_offset, len); | 6080 NoGCScope no_gc; |
| 6081 String::Copy(dst, dst_offset, fourstr.CharAddr(0) + src_offset, len); |
| 6082 } else { |
| 6083 ASSERT(src.IsExternalFourByteString()); |
| 6084 ExternalFourByteString& fourstr = ExternalFourByteString::Handle(); |
| 6085 fourstr ^= src.raw(); |
| 6086 NoGCScope no_gc; |
| 6087 String::Copy(dst, dst_offset, fourstr.CharAddr(0) + src_offset, len); |
| 6088 } |
| 5997 } | 6089 } |
| 5998 } | 6090 } |
| 5999 } | 6091 } |
| 6000 | 6092 |
| 6001 | 6093 |
| 6002 static void GrowSymbolTable(const Array& symbol_table, intptr_t table_size) { | 6094 static void GrowSymbolTable(const Array& symbol_table, intptr_t table_size) { |
| 6003 // TODO(iposva): Avoid exponential growth. | 6095 // TODO(iposva): Avoid exponential growth. |
| 6004 intptr_t new_table_size = table_size * 2; | 6096 intptr_t new_table_size = table_size * 2; |
| 6005 Array& new_symbol_table = Array::Handle(Array::New(new_table_size + 1)); | 6097 Array& new_symbol_table = Array::Handle(Array::New(new_table_size + 1)); |
| 6006 // Copy all elements from the original symbol table to the newly allocated | 6098 // Copy all elements from the original symbol table to the newly allocated |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6148 } | 6240 } |
| 6149 ASSERT(symbol.IsSymbol()); | 6241 ASSERT(symbol.IsSymbol()); |
| 6150 return symbol.raw(); | 6242 return symbol.raw(); |
| 6151 } | 6243 } |
| 6152 | 6244 |
| 6153 | 6245 |
| 6154 RawString* String::Concat(const String& str1, | 6246 RawString* String::Concat(const String& str1, |
| 6155 const String& str2, | 6247 const String& str2, |
| 6156 Heap::Space space) { | 6248 Heap::Space space) { |
| 6157 ASSERT(!str1.IsNull() && !str2.IsNull()); | 6249 ASSERT(!str1.IsNull() && !str2.IsNull()); |
| 6158 if (str1.IsFourByteString() || str2.IsFourByteString()) { | 6250 intptr_t char_size = Utils::Maximum(str1.CharSize(), str2.CharSize()); |
| 6251 if (char_size == kFourByteChar) { |
| 6159 return FourByteString::Concat(str1, str2, space); | 6252 return FourByteString::Concat(str1, str2, space); |
| 6160 } | 6253 } |
| 6161 if (str1.IsTwoByteString() || str2.IsTwoByteString()) { | 6254 if (char_size == kTwoByteChar) { |
| 6162 return TwoByteString::Concat(str1, str2, space); | 6255 return TwoByteString::Concat(str1, str2, space); |
| 6163 } | 6256 } |
| 6164 ASSERT(str1.IsOneByteString() && str2.IsOneByteString()); | |
| 6165 return OneByteString::Concat(str1, str2, space); | 6257 return OneByteString::Concat(str1, str2, space); |
| 6166 } | 6258 } |
| 6167 | 6259 |
| 6168 | 6260 |
| 6169 RawString* String::ConcatAll(const Array& strings, | 6261 RawString* String::ConcatAll(const Array& strings, |
| 6170 Heap::Space space) { | 6262 Heap::Space space) { |
| 6171 ASSERT(!strings.IsNull()); | 6263 ASSERT(!strings.IsNull()); |
| 6172 bool is_one_byte_string = true; | |
| 6173 bool is_two_byte_string = true; | |
| 6174 intptr_t result_len = 0; | 6264 intptr_t result_len = 0; |
| 6175 intptr_t strings_len = strings.Length(); | 6265 intptr_t strings_len = strings.Length(); |
| 6176 String& str = String::Handle(); | 6266 String& str = String::Handle(); |
| 6267 intptr_t char_size = kOneByteChar; |
| 6177 for (intptr_t i = 0; i < strings_len; i++) { | 6268 for (intptr_t i = 0; i < strings_len; i++) { |
| 6178 str ^= strings.At(i); | 6269 str ^= strings.At(i); |
| 6179 result_len += str.Length(); | 6270 result_len += str.Length(); |
| 6180 if (str.IsFourByteString()) { | 6271 char_size = Utils::Maximum(char_size, str.CharSize()); |
| 6181 is_one_byte_string = false; | |
| 6182 is_two_byte_string = false; | |
| 6183 } else if (str.IsTwoByteString()) { | |
| 6184 is_one_byte_string = false; | |
| 6185 } | |
| 6186 } | 6272 } |
| 6187 if (is_one_byte_string) { | 6273 if (char_size == kOneByteChar) { |
| 6188 return OneByteString::ConcatAll(strings, result_len, space); | 6274 return OneByteString::ConcatAll(strings, result_len, space); |
| 6189 } else if (is_two_byte_string) { | 6275 } else if (char_size == kTwoByteChar) { |
| 6190 return TwoByteString::ConcatAll(strings, result_len, space); | 6276 return TwoByteString::ConcatAll(strings, result_len, space); |
| 6191 } | 6277 } |
| 6278 ASSERT(char_size == kFourByteChar); |
| 6192 return FourByteString::ConcatAll(strings, result_len, space); | 6279 return FourByteString::ConcatAll(strings, result_len, space); |
| 6193 } | 6280 } |
| 6194 | 6281 |
| 6195 | 6282 |
| 6196 RawString* String::SubString(const String& str, | 6283 RawString* String::SubString(const String& str, |
| 6197 intptr_t begin_index, | 6284 intptr_t begin_index, |
| 6198 Heap::Space space) { | 6285 Heap::Space space) { |
| 6199 ASSERT(!str.IsNull()); | 6286 ASSERT(!str.IsNull()); |
| 6200 if (begin_index >= str.Length()) { | 6287 if (begin_index >= str.Length()) { |
| 6201 return String::null(); | 6288 return String::null(); |
| 6202 } | 6289 } |
| 6203 return String::SubString(str, begin_index, (str.Length() - begin_index)); | 6290 return String::SubString(str, begin_index, (str.Length() - begin_index)); |
| 6204 } | 6291 } |
| 6205 | 6292 |
| 6206 | 6293 |
| 6207 RawString* String::SubString(const String& str, | 6294 RawString* String::SubString(const String& str, |
| 6208 intptr_t begin_index, | 6295 intptr_t begin_index, |
| 6209 intptr_t length, | 6296 intptr_t length, |
| 6210 Heap::Space space) { | 6297 Heap::Space space) { |
| 6211 ASSERT(!str.IsNull()); | 6298 ASSERT(!str.IsNull()); |
| 6212 ASSERT(begin_index >= 0); | 6299 ASSERT(begin_index >= 0); |
| 6213 ASSERT(length >= 0); | 6300 ASSERT(length >= 0); |
| 6214 if (begin_index >= str.Length()) { | 6301 if (begin_index >= str.Length()) { |
| 6215 return String::null(); | 6302 return String::null(); |
| 6216 } | 6303 } |
| 6217 if (str.IsOneByteString()) { | 6304 String& result = String::Handle(); |
| 6218 OneByteString& obstr = OneByteString::Handle(); | 6305 bool is_one_byte_string = true; |
| 6219 obstr ^= str.raw(); | 6306 bool is_two_byte_string = true; |
| 6220 return OneByteString::SubString(obstr, begin_index, length, space); | 6307 intptr_t char_size = str.CharSize(); |
| 6221 } else if (str.IsTwoByteString()) { | 6308 if (char_size == kTwoByteChar) { |
| 6222 TwoByteString& twostr = TwoByteString::Handle(); | 6309 for (intptr_t i = begin_index; i < begin_index + length; ++i) { |
| 6223 twostr ^= str.raw(); | 6310 if (str.CharAt(i) > 0xFF) { |
| 6224 return TwoByteString::SubString(twostr, begin_index, length, space); | 6311 is_one_byte_string = false; |
| 6312 break; |
| 6313 } |
| 6314 } |
| 6315 } else if (char_size == kFourByteChar) { |
| 6316 for (intptr_t i = begin_index; i < begin_index + length; ++i) { |
| 6317 if (str.CharAt(i) > 0xFFFF) { |
| 6318 is_one_byte_string = false; |
| 6319 is_two_byte_string = false; |
| 6320 break; |
| 6321 } else if (str.CharAt(i) > 0xFF) { |
| 6322 is_one_byte_string = false; |
| 6323 } |
| 6324 } |
| 6225 } | 6325 } |
| 6226 ASSERT(str.IsFourByteString()); | 6326 if (is_one_byte_string) { |
| 6227 FourByteString& fourstr = FourByteString::Handle(); | 6327 result ^= OneByteString::New(length, space); |
| 6228 fourstr ^= str.raw(); | 6328 } else if (is_two_byte_string) { |
| 6229 return FourByteString::SubString(fourstr, begin_index, length, space); | 6329 result ^= TwoByteString::New(length, space); |
| 6330 } else { |
| 6331 result ^= FourByteString::New(length, space); |
| 6332 } |
| 6333 String::Copy(result, 0, str, begin_index, length); |
| 6334 return result.raw(); |
| 6230 } | 6335 } |
| 6231 | 6336 |
| 6232 | 6337 |
| 6233 const char* String::ToCString() const { | 6338 const char* String::ToCString() const { |
| 6234 intptr_t len = Utf8::Length(*this); | 6339 intptr_t len = Utf8::Length(*this); |
| 6235 Zone* zone = Isolate::Current()->current_zone(); | 6340 Zone* zone = Isolate::Current()->current_zone(); |
| 6236 char* result = reinterpret_cast<char*>(zone->Allocate(len + 1)); | 6341 char* result = reinterpret_cast<char*>(zone->Allocate(len + 1)); |
| 6237 Utf8::Encode(*this, result, len); | 6342 Utf8::Encode(*this, result, len); |
| 6238 result[len] = 0; | 6343 result[len] = 0; |
| 6239 return result; | 6344 return result; |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6367 for (intptr_t i = 0; i < strings_len; i++) { | 6472 for (intptr_t i = 0; i < strings_len; i++) { |
| 6368 str ^= strings.At(i); | 6473 str ^= strings.At(i); |
| 6369 intptr_t str_len = str.Length(); | 6474 intptr_t str_len = str.Length(); |
| 6370 String::Copy(result, pos, str, 0, str_len); | 6475 String::Copy(result, pos, str, 0, str_len); |
| 6371 pos += str_len; | 6476 pos += str_len; |
| 6372 } | 6477 } |
| 6373 return result.raw(); | 6478 return result.raw(); |
| 6374 } | 6479 } |
| 6375 | 6480 |
| 6376 | 6481 |
| 6377 RawString* OneByteString::SubString(const OneByteString& str, | |
| 6378 intptr_t begin_index, | |
| 6379 intptr_t length, | |
| 6380 Heap::Space space) { | |
| 6381 ASSERT(!str.IsNull()); | |
| 6382 ASSERT(begin_index < str.Length()); | |
| 6383 OneByteString& result = OneByteString::Handle(); | |
| 6384 if (length <= (str.Length() - begin_index)) { | |
| 6385 result ^= OneByteString::New(length, space); | |
| 6386 String::Copy(result, 0, str, begin_index, length); | |
| 6387 } | |
| 6388 // TODO(5418937): return a non-null object on error. | |
| 6389 return result.raw(); | |
| 6390 } | |
| 6391 | |
| 6392 | |
| 6393 RawOneByteString* OneByteString::Transform(int32_t (*mapping)(int32_t ch), | 6482 RawOneByteString* OneByteString::Transform(int32_t (*mapping)(int32_t ch), |
| 6394 const String& str, | 6483 const String& str, |
| 6395 Heap::Space space) { | 6484 Heap::Space space) { |
| 6396 ASSERT(!str.IsNull()); | 6485 ASSERT(!str.IsNull()); |
| 6397 intptr_t len = str.Length(); | 6486 intptr_t len = str.Length(); |
| 6398 const OneByteString& result = | 6487 const OneByteString& result = |
| 6399 OneByteString::Handle(OneByteString::New(len, space)); | 6488 OneByteString::Handle(OneByteString::New(len, space)); |
| 6400 for (intptr_t i = 0; i < len; ++i) { | 6489 for (intptr_t i = 0; i < len; ++i) { |
| 6401 int32_t ch = mapping(str.CharAt(i)); | 6490 int32_t ch = mapping(str.CharAt(i)); |
| 6402 ASSERT(ch >= 0 && ch <= 0xFF); | 6491 ASSERT(ch >= 0 && ch <= 0xFF); |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6486 for (intptr_t i = 0; i < strings_len; i++) { | 6575 for (intptr_t i = 0; i < strings_len; i++) { |
| 6487 str ^= strings.At(i); | 6576 str ^= strings.At(i); |
| 6488 intptr_t str_len = str.Length(); | 6577 intptr_t str_len = str.Length(); |
| 6489 String::Copy(result, pos, str, 0, str_len); | 6578 String::Copy(result, pos, str, 0, str_len); |
| 6490 pos += str_len; | 6579 pos += str_len; |
| 6491 } | 6580 } |
| 6492 return result.raw(); | 6581 return result.raw(); |
| 6493 } | 6582 } |
| 6494 | 6583 |
| 6495 | 6584 |
| 6496 RawString* TwoByteString::SubString(const TwoByteString& str, | |
| 6497 intptr_t begin_index, | |
| 6498 intptr_t length, | |
| 6499 Heap::Space space) { | |
| 6500 ASSERT(!str.IsNull()); | |
| 6501 ASSERT(begin_index < str.Length()); | |
| 6502 String& result = String::Handle(); | |
| 6503 if (length <= (str.Length() - begin_index)) { | |
| 6504 bool is_one_byte_string = true; | |
| 6505 for (intptr_t i = begin_index; i < begin_index + length; ++i) { | |
| 6506 if (str.CharAt(i) > 0xFF) { | |
| 6507 is_one_byte_string = false; | |
| 6508 break; | |
| 6509 } | |
| 6510 } | |
| 6511 if (is_one_byte_string) { | |
| 6512 result ^= OneByteString::New(length, space); | |
| 6513 } else { | |
| 6514 result ^= TwoByteString::New(length, space); | |
| 6515 } | |
| 6516 String::Copy(result, 0, str, begin_index, length); | |
| 6517 } | |
| 6518 // TODO(5418937): return a non-null object on error. | |
| 6519 return result.raw(); | |
| 6520 } | |
| 6521 | |
| 6522 | |
| 6523 RawTwoByteString* TwoByteString::Transform(int32_t (*mapping)(int32_t ch), | 6585 RawTwoByteString* TwoByteString::Transform(int32_t (*mapping)(int32_t ch), |
| 6524 const String& str, | 6586 const String& str, |
| 6525 Heap::Space space) { | 6587 Heap::Space space) { |
| 6526 ASSERT(!str.IsNull()); | 6588 ASSERT(!str.IsNull()); |
| 6527 intptr_t len = str.Length(); | 6589 intptr_t len = str.Length(); |
| 6528 const TwoByteString& result = | 6590 const TwoByteString& result = |
| 6529 TwoByteString::Handle(TwoByteString::New(len, space)); | 6591 TwoByteString::Handle(TwoByteString::New(len, space)); |
| 6530 for (intptr_t i = 0; i < len; ++i) { | 6592 for (intptr_t i = 0; i < len; ++i) { |
| 6531 int32_t ch = mapping(str.CharAt(i)); | 6593 int32_t ch = mapping(str.CharAt(i)); |
| 6532 ASSERT(ch >= 0 && ch <= 0xFFFF); | 6594 ASSERT(ch >= 0 && ch <= 0xFFFF); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6604 str ^= strings.At(i); | 6666 str ^= strings.At(i); |
| 6605 intptr_t str_len = str.Length(); | 6667 intptr_t str_len = str.Length(); |
| 6606 String::Copy(result, pos, str, 0, str_len); | 6668 String::Copy(result, pos, str, 0, str_len); |
| 6607 pos += str_len; | 6669 pos += str_len; |
| 6608 } | 6670 } |
| 6609 } | 6671 } |
| 6610 return result.raw(); | 6672 return result.raw(); |
| 6611 } | 6673 } |
| 6612 | 6674 |
| 6613 | 6675 |
| 6614 RawString* FourByteString::SubString(const FourByteString& str, | |
| 6615 intptr_t begin_index, | |
| 6616 intptr_t length, | |
| 6617 Heap::Space space) { | |
| 6618 ASSERT(!str.IsNull()); | |
| 6619 ASSERT(begin_index < str.Length()); | |
| 6620 String& result = String::Handle(); | |
| 6621 if (length <= (str.Length() - begin_index)) { | |
| 6622 bool is_one_byte_string = true; | |
| 6623 bool is_two_byte_string = true; | |
| 6624 for (intptr_t i = begin_index; i < begin_index + length; ++i) { | |
| 6625 if (str.CharAt(i) > 0xFFFF) { | |
| 6626 is_one_byte_string = false; | |
| 6627 is_two_byte_string = false; | |
| 6628 break; | |
| 6629 } else if (str.CharAt(i) > 0xFF) { | |
| 6630 is_one_byte_string = false; | |
| 6631 } | |
| 6632 } | |
| 6633 if (is_one_byte_string) { | |
| 6634 result ^= OneByteString::New(length, space); | |
| 6635 } else if (is_two_byte_string) { | |
| 6636 result ^= TwoByteString::New(length, space); | |
| 6637 } else { | |
| 6638 result ^= FourByteString::New(length, space); | |
| 6639 } | |
| 6640 String::Copy(result, 0, str, begin_index, length); | |
| 6641 } | |
| 6642 // TODO(5418937): return a non-null object on error. | |
| 6643 return result.raw(); | |
| 6644 } | |
| 6645 | |
| 6646 | |
| 6647 RawFourByteString* FourByteString::Transform(int32_t (*mapping)(int32_t ch), | 6676 RawFourByteString* FourByteString::Transform(int32_t (*mapping)(int32_t ch), |
| 6648 const String& str, | 6677 const String& str, |
| 6649 Heap::Space space) { | 6678 Heap::Space space) { |
| 6650 ASSERT(!str.IsNull()); | 6679 ASSERT(!str.IsNull()); |
| 6651 intptr_t len = str.Length(); | 6680 intptr_t len = str.Length(); |
| 6652 const FourByteString& result = | 6681 const FourByteString& result = |
| 6653 FourByteString::Handle(FourByteString::New(len, space)); | 6682 FourByteString::Handle(FourByteString::New(len, space)); |
| 6654 for (intptr_t i = 0; i < len; ++i) { | 6683 for (intptr_t i = 0; i < len; ++i) { |
| 6655 int32_t ch = mapping(str.CharAt(i)); | 6684 int32_t ch = mapping(str.CharAt(i)); |
| 6656 ASSERT(ch >= 0 && ch <= 0x10FFFF); | 6685 ASSERT(ch >= 0 && ch <= 0x10FFFF); |
| 6657 *result.CharAddr(i) = ch; | 6686 *result.CharAddr(i) = ch; |
| 6658 } | 6687 } |
| 6659 return result.raw(); | 6688 return result.raw(); |
| 6660 } | 6689 } |
| 6661 | 6690 |
| 6662 | 6691 |
| 6663 const char* FourByteString::ToCString() const { | 6692 const char* FourByteString::ToCString() const { |
| 6664 return String::ToCString(); | 6693 return String::ToCString(); |
| 6665 } | 6694 } |
| 6666 | 6695 |
| 6667 | 6696 |
| 6697 RawExternalOneByteString* ExternalOneByteString::New(const uint8_t* data, |
| 6698 intptr_t len, |
| 6699 void* peer, |
| 6700 PeerFinalizer callback, |
| 6701 Heap::Space space) { |
| 6702 Isolate* isolate = Isolate::Current(); |
| 6703 |
| 6704 const Class& cls = |
| 6705 Class::Handle(isolate->object_store()->external_one_byte_string_class()); |
| 6706 ExternalOneByteString& result = ExternalOneByteString::Handle(); |
| 6707 { |
| 6708 ExternalStringData<uint8_t>* external_data = |
| 6709 new ExternalStringData<uint8_t>(data, peer, callback); |
| 6710 RawObject* raw = Object::Allocate(cls, |
| 6711 ExternalOneByteString::InstanceSize(), |
| 6712 space); |
| 6713 NoGCScope no_gc; |
| 6714 result ^= raw; |
| 6715 result.SetLength(len); |
| 6716 result.SetHash(0); |
| 6717 result.SetExternalData(external_data); |
| 6718 } |
| 6719 return result.raw(); |
| 6720 } |
| 6721 |
| 6722 |
| 6723 const char* ExternalOneByteString::ToCString() const { |
| 6724 return String::ToCString(); |
| 6725 } |
| 6726 |
| 6727 |
| 6728 RawExternalTwoByteString* ExternalTwoByteString::New(const uint16_t* data, |
| 6729 intptr_t len, |
| 6730 void* peer, |
| 6731 PeerFinalizer callback, |
| 6732 Heap::Space space) { |
| 6733 Isolate* isolate = Isolate::Current(); |
| 6734 |
| 6735 const Class& cls = |
| 6736 Class::Handle(isolate->object_store()->external_two_byte_string_class()); |
| 6737 ExternalTwoByteString& result = ExternalTwoByteString::Handle(); |
| 6738 { |
| 6739 ExternalStringData<uint16_t>* external_data = |
| 6740 new ExternalStringData<uint16_t>(data, peer, callback); |
| 6741 RawObject* raw = Object::Allocate(cls, |
| 6742 ExternalTwoByteString::InstanceSize(), |
| 6743 space); |
| 6744 NoGCScope no_gc; |
| 6745 result ^= raw; |
| 6746 result.SetLength(len); |
| 6747 result.SetHash(0); |
| 6748 result.SetExternalData(external_data); |
| 6749 } |
| 6750 return result.raw(); |
| 6751 } |
| 6752 |
| 6753 |
| 6754 const char* ExternalTwoByteString::ToCString() const { |
| 6755 return String::ToCString(); |
| 6756 } |
| 6757 |
| 6758 |
| 6759 RawExternalFourByteString* ExternalFourByteString::New(const uint32_t* data, |
| 6760 intptr_t len, |
| 6761 void* peer, |
| 6762 PeerFinalizer callback, |
| 6763 Heap::Space space) { |
| 6764 Isolate* isolate = Isolate::Current(); |
| 6765 |
| 6766 const Class& cls = |
| 6767 Class::Handle(isolate->object_store()->external_four_byte_string_class()); |
| 6768 ExternalFourByteString& result = ExternalFourByteString::Handle(); |
| 6769 { |
| 6770 ExternalStringData<uint32_t>* external_data = |
| 6771 new ExternalStringData<uint32_t>(data, peer, callback); |
| 6772 RawObject* raw = Object::Allocate(cls, |
| 6773 ExternalFourByteString::InstanceSize(), |
| 6774 space); |
| 6775 NoGCScope no_gc; |
| 6776 result ^= raw; |
| 6777 result.SetLength(len); |
| 6778 result.SetHash(0); |
| 6779 result.SetExternalData(external_data); |
| 6780 } |
| 6781 return result.raw(); |
| 6782 } |
| 6783 |
| 6784 |
| 6785 const char* ExternalFourByteString::ToCString() const { |
| 6786 return String::ToCString(); |
| 6787 } |
| 6788 |
| 6789 |
| 6668 RawBool* Bool::True() { | 6790 RawBool* Bool::True() { |
| 6669 return Isolate::Current()->object_store()->true_value(); | 6791 return Isolate::Current()->object_store()->true_value(); |
| 6670 } | 6792 } |
| 6671 | 6793 |
| 6672 | 6794 |
| 6673 RawBool* Bool::False() { | 6795 RawBool* Bool::False() { |
| 6674 return Isolate::Current()->object_store()->false_value(); | 6796 return Isolate::Current()->object_store()->false_value(); |
| 6675 } | 6797 } |
| 6676 | 6798 |
| 6677 | 6799 |
| (...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7145 const String& str = String::Handle(pattern()); | 7267 const String& str = String::Handle(pattern()); |
| 7146 const char* format = "JSRegExp: pattern=%s flags=%s"; | 7268 const char* format = "JSRegExp: pattern=%s flags=%s"; |
| 7147 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); | 7269 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); |
| 7148 char* chars = reinterpret_cast<char*>( | 7270 char* chars = reinterpret_cast<char*>( |
| 7149 Isolate::Current()->current_zone()->Allocate(len + 1)); | 7271 Isolate::Current()->current_zone()->Allocate(len + 1)); |
| 7150 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); | 7272 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); |
| 7151 return chars; | 7273 return chars; |
| 7152 } | 7274 } |
| 7153 | 7275 |
| 7154 } // namespace dart | 7276 } // namespace dart |
| OLD | NEW |