Chromium Code Reviews| 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 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 387 | 387 |
| 388 cls = Class::New<OneByteString>(); | 388 cls = Class::New<OneByteString>(); |
| 389 object_store->set_one_byte_string_class(cls); | 389 object_store->set_one_byte_string_class(cls); |
| 390 | 390 |
| 391 cls = Class::New<TwoByteString>(); | 391 cls = Class::New<TwoByteString>(); |
| 392 object_store->set_two_byte_string_class(cls); | 392 object_store->set_two_byte_string_class(cls); |
| 393 | 393 |
| 394 cls = Class::New<FourByteString>(); | 394 cls = Class::New<FourByteString>(); |
| 395 object_store->set_four_byte_string_class(cls); | 395 object_store->set_four_byte_string_class(cls); |
| 396 | 396 |
| 397 cls = Class::New<ExternalOneByteString>(); | |
| 398 object_store->set_external_one_byte_string_class(cls); | |
| 399 | |
| 400 cls = Class::New<ExternalTwoByteString>(); | |
| 401 object_store->set_external_two_byte_string_class(cls); | |
| 402 | |
| 403 cls = Class::New<ExternalFourByteString>(); | |
| 404 object_store->set_external_four_byte_string_class(cls); | |
| 405 | |
| 397 cls = Class::New<Bool>(); | 406 cls = Class::New<Bool>(); |
| 398 object_store->set_bool_class(cls); | 407 object_store->set_bool_class(cls); |
| 399 | 408 |
| 400 cls = Class::New<UnhandledException>(); | 409 cls = Class::New<UnhandledException>(); |
| 401 object_store->set_unhandled_exception_class(cls); | 410 object_store->set_unhandled_exception_class(cls); |
| 402 | 411 |
| 403 cls = Class::New<Stacktrace>(); | 412 cls = Class::New<Stacktrace>(); |
| 404 object_store->set_stacktrace_class(cls); | 413 object_store->set_stacktrace_class(cls); |
| 405 // Set the super type so that the 'toString' method is implemented. | 414 // Set the super type so that the 'toString' method is implemented. |
| 406 type = object_store->object_type(); | 415 type = object_store->object_type(); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 456 cls.set_name(name); | 465 cls.set_name(name); |
| 457 cls.set_script(impl_script); | 466 cls.set_script(impl_script); |
| 458 core_impl_lib.AddClass(cls); | 467 core_impl_lib.AddClass(cls); |
| 459 | 468 |
| 460 name = String::NewSymbol("FourByteString"); | 469 name = String::NewSymbol("FourByteString"); |
| 461 cls = object_store->four_byte_string_class(); | 470 cls = object_store->four_byte_string_class(); |
| 462 cls.set_name(name); | 471 cls.set_name(name); |
| 463 cls.set_script(impl_script); | 472 cls.set_script(impl_script); |
| 464 core_impl_lib.AddClass(cls); | 473 core_impl_lib.AddClass(cls); |
| 465 | 474 |
| 475 name = String::NewSymbol("ExternalOneByteString"); | |
| 476 cls = object_store->external_one_byte_string_class(); | |
| 477 cls.set_name(name); | |
| 478 cls.set_script(impl_script); | |
| 479 core_impl_lib.AddClass(cls); | |
| 480 | |
| 481 name = String::NewSymbol("ExternalTwoByteString"); | |
| 482 cls = object_store->external_two_byte_string_class(); | |
| 483 cls.set_name(name); | |
| 484 cls.set_script(impl_script); | |
| 485 core_impl_lib.AddClass(cls); | |
| 486 | |
| 487 name = String::NewSymbol("ExternalFourByteString"); | |
| 488 cls = object_store->external_four_byte_string_class(); | |
| 489 cls.set_name(name); | |
| 490 cls.set_script(impl_script); | |
| 491 core_impl_lib.AddClass(cls); | |
| 492 | |
| 466 name = String::NewSymbol("Mint"); | 493 name = String::NewSymbol("Mint"); |
| 467 cls = object_store->mint_class(); | 494 cls = object_store->mint_class(); |
| 468 cls.set_name(name); | 495 cls.set_name(name); |
| 469 cls.set_script(impl_script); | 496 cls.set_script(impl_script); |
| 470 core_impl_lib.AddClass(cls); | 497 core_impl_lib.AddClass(cls); |
| 471 | 498 |
| 472 name = String::NewSymbol("Bigint"); | 499 name = String::NewSymbol("Bigint"); |
| 473 cls = object_store->bigint_class(); | 500 cls = object_store->bigint_class(); |
| 474 cls.set_name(name); | 501 cls.set_name(name); |
| 475 cls.set_script(impl_script); | 502 cls.set_script(impl_script); |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 642 | 669 |
| 643 cls = Class::New<OneByteString>(); | 670 cls = Class::New<OneByteString>(); |
| 644 object_store->set_one_byte_string_class(cls); | 671 object_store->set_one_byte_string_class(cls); |
| 645 | 672 |
| 646 cls = Class::New<TwoByteString>(); | 673 cls = Class::New<TwoByteString>(); |
| 647 object_store->set_two_byte_string_class(cls); | 674 object_store->set_two_byte_string_class(cls); |
| 648 | 675 |
| 649 cls = Class::New<FourByteString>(); | 676 cls = Class::New<FourByteString>(); |
| 650 object_store->set_four_byte_string_class(cls); | 677 object_store->set_four_byte_string_class(cls); |
| 651 | 678 |
| 679 cls = Class::New<ExternalOneByteString>(); | |
| 680 object_store->set_external_one_byte_string_class(cls); | |
| 681 | |
| 682 cls = Class::New<ExternalTwoByteString>(); | |
| 683 object_store->set_external_two_byte_string_class(cls); | |
| 684 | |
| 685 cls = Class::New<ExternalFourByteString>(); | |
| 686 object_store->set_external_four_byte_string_class(cls); | |
| 687 | |
| 652 cls = Class::New<Bool>(); | 688 cls = Class::New<Bool>(); |
| 653 object_store->set_bool_class(cls); | 689 object_store->set_bool_class(cls); |
| 654 | 690 |
| 655 cls = Class::New<UnhandledException>(); | 691 cls = Class::New<UnhandledException>(); |
| 656 object_store->set_unhandled_exception_class(cls); | 692 object_store->set_unhandled_exception_class(cls); |
| 657 | 693 |
| 658 cls = Class::New<Stacktrace>(); | 694 cls = Class::New<Stacktrace>(); |
| 659 object_store->set_stacktrace_class(cls); | 695 object_store->set_stacktrace_class(cls); |
| 660 | 696 |
| 661 cls = Class::New<JSRegExp>(); | 697 cls = Class::New<JSRegExp>(); |
| (...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1093 return object_store->double_class(); | 1129 return object_store->double_class(); |
| 1094 case kOneByteString: | 1130 case kOneByteString: |
| 1095 ASSERT(object_store->one_byte_string_class() != Class::null()); | 1131 ASSERT(object_store->one_byte_string_class() != Class::null()); |
| 1096 return object_store->one_byte_string_class(); | 1132 return object_store->one_byte_string_class(); |
| 1097 case kTwoByteString: | 1133 case kTwoByteString: |
| 1098 ASSERT(object_store->two_byte_string_class() != Class::null()); | 1134 ASSERT(object_store->two_byte_string_class() != Class::null()); |
| 1099 return object_store->two_byte_string_class(); | 1135 return object_store->two_byte_string_class(); |
| 1100 case kFourByteString: | 1136 case kFourByteString: |
| 1101 ASSERT(object_store->four_byte_string_class() != Class::null()); | 1137 ASSERT(object_store->four_byte_string_class() != Class::null()); |
| 1102 return object_store->four_byte_string_class(); | 1138 return object_store->four_byte_string_class(); |
| 1139 case kExternalOneByteString: | |
| 1140 ASSERT(object_store->external_one_byte_string_class() != Class::null()); | |
| 1141 return object_store->external_one_byte_string_class(); | |
| 1142 case kExternalTwoByteString: | |
| 1143 ASSERT(object_store->external_two_byte_string_class() != Class::null()); | |
| 1144 return object_store->external_two_byte_string_class(); | |
| 1145 case kExternalFourByteString: | |
| 1146 ASSERT(object_store->external_four_byte_string_class() != Class::null()); | |
| 1147 return object_store->external_four_byte_string_class(); | |
| 1103 case kBool: | 1148 case kBool: |
| 1104 ASSERT(object_store->bool_class() != Class::null()); | 1149 ASSERT(object_store->bool_class() != Class::null()); |
| 1105 return object_store->bool_class(); | 1150 return object_store->bool_class(); |
| 1106 case kArray: | 1151 case kArray: |
| 1107 ASSERT(object_store->array_class() != Class::null()); | 1152 ASSERT(object_store->array_class() != Class::null()); |
| 1108 return object_store->array_class(); | 1153 return object_store->array_class(); |
| 1109 case kImmutableArray: | 1154 case kImmutableArray: |
| 1110 ASSERT(object_store->immutable_array_class() != Class::null()); | 1155 ASSERT(object_store->immutable_array_class() != Class::null()); |
| 1111 return object_store->immutable_array_class(); | 1156 return object_store->immutable_array_class(); |
| 1112 case kStacktrace: | 1157 case kStacktrace: |
| (...skipping 4317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5430 } | 5475 } |
| 5431 | 5476 |
| 5432 | 5477 |
| 5433 int32_t String::CharAt(intptr_t index) const { | 5478 int32_t String::CharAt(intptr_t index) const { |
| 5434 // String is an abstract class. | 5479 // String is an abstract class. |
| 5435 UNREACHABLE(); | 5480 UNREACHABLE(); |
| 5436 return 0; | 5481 return 0; |
| 5437 } | 5482 } |
| 5438 | 5483 |
| 5439 | 5484 |
| 5485 intptr_t String::CharSize() const { | |
| 5486 // String is an abstract class. | |
| 5487 UNREACHABLE(); | |
| 5488 return 0; | |
| 5489 } | |
| 5490 | |
| 5491 | |
| 5440 bool String::Equals(const Instance& other) const { | 5492 bool String::Equals(const Instance& other) const { |
| 5441 if (this->raw() == other.raw()) { | 5493 if (this->raw() == other.raw()) { |
| 5442 // Both handles point to the same raw instance. | 5494 // Both handles point to the same raw instance. |
| 5443 return true; | 5495 return true; |
| 5444 } | 5496 } |
| 5445 | 5497 |
| 5446 if (!other.IsString() || other.IsNull()) { | 5498 if (!other.IsString() || other.IsNull()) { |
| 5447 return false; | 5499 return false; |
| 5448 } | 5500 } |
| 5449 | 5501 |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5693 } | 5745 } |
| 5694 return FourByteString::New(characters, len, space); | 5746 return FourByteString::New(characters, len, space); |
| 5695 } | 5747 } |
| 5696 | 5748 |
| 5697 | 5749 |
| 5698 RawString* String::New(const String& str, Heap::Space space) { | 5750 RawString* String::New(const String& str, Heap::Space space) { |
| 5699 // Currently this just creates a copy of the string in the correct space. | 5751 // Currently this just creates a copy of the string in the correct space. |
| 5700 // Once we have external string support, this will also create a heap copy of | 5752 // Once we have external string support, this will also create a heap copy of |
| 5701 // the string if necessary. Some optimizations are possible, such as not | 5753 // the string if necessary. Some optimizations are possible, such as not |
| 5702 // copying internal strings into the same space. | 5754 // copying internal strings into the same space. |
| 5703 if (str.IsOneByteString()) { | 5755 intptr_t len = str.Length(); |
| 5704 OneByteString& one_byte_str = OneByteString::Handle(); | 5756 String& result = String::Handle(); |
| 5705 one_byte_str ^= str.raw(); | 5757 intptr_t char_size = str.CharSize(); |
| 5706 return OneByteString::New(one_byte_str, space); | 5758 if (char_size == kOneByteChar) { |
| 5707 } else if (str.IsTwoByteString()) { | 5759 result ^= OneByteString::New(len, space); |
| 5708 TwoByteString& two_byte_str = TwoByteString::Handle(); | 5760 } else if (char_size == kTwoByteChar) { |
| 5709 two_byte_str ^= str.raw(); | 5761 result ^= TwoByteString::New(len, space); |
| 5710 return TwoByteString::New(two_byte_str, space); | 5762 } else { |
| 5763 ASSERT(char_size == kFourByteChar); | |
| 5764 result ^= FourByteString::New(len, space); | |
| 5711 } | 5765 } |
| 5712 ASSERT(str.IsFourByteString()); | 5766 String::Copy(result, 0, str, 0, len); |
| 5713 FourByteString& four_byte_str = FourByteString::Handle(); | 5767 return result.raw(); |
| 5714 four_byte_str ^= str.raw(); | |
| 5715 return FourByteString::New(four_byte_str, space); | |
| 5716 } | 5768 } |
| 5717 | 5769 |
| 5718 | 5770 |
| 5771 RawString* String::NewExternal(const uint8_t* characters, | |
| 5772 intptr_t len, | |
| 5773 void* peer, | |
| 5774 PeerFinalizer callback, | |
| 5775 Heap::Space space) { | |
| 5776 return ExternalOneByteString::New(characters, len, peer, callback, space); | |
| 5777 } | |
| 5778 | |
| 5779 | |
| 5780 RawString* String::NewExternal(const uint16_t* characters, | |
| 5781 intptr_t len, | |
| 5782 void* peer, | |
| 5783 PeerFinalizer callback, | |
| 5784 Heap::Space space) { | |
| 5785 return ExternalTwoByteString::New(characters, len, peer, callback, space); | |
| 5786 } | |
| 5787 | |
| 5788 | |
| 5789 RawString* String::NewExternal(const uint32_t* characters, | |
| 5790 intptr_t len, | |
| 5791 void* peer, | |
| 5792 PeerFinalizer callback, | |
| 5793 Heap::Space space) { | |
| 5794 return ExternalFourByteString::New(characters, len, peer, callback, space); | |
| 5795 } | |
| 5796 | |
| 5797 | |
| 5719 void String::Copy(const String& dst, intptr_t dst_offset, | 5798 void String::Copy(const String& dst, intptr_t dst_offset, |
| 5720 const uint8_t* characters, | 5799 const uint8_t* characters, |
| 5721 intptr_t len) { | 5800 intptr_t len) { |
| 5722 ASSERT(dst_offset >= 0); | 5801 ASSERT(dst_offset >= 0); |
| 5723 ASSERT(len >= 0); | 5802 ASSERT(len >= 0); |
| 5724 ASSERT(len <= (dst.Length() - dst_offset)); | 5803 ASSERT(len <= (dst.Length() - dst_offset)); |
| 5725 if (dst.IsOneByteString()) { | 5804 if (dst.IsOneByteString()) { |
| 5726 OneByteString& onestr = OneByteString::Handle(); | 5805 OneByteString& onestr = OneByteString::Handle(); |
| 5727 onestr ^= dst.raw(); | 5806 onestr ^= dst.raw(); |
| 5728 NoGCScope no_gc; | 5807 NoGCScope no_gc; |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5817 | 5896 |
| 5818 void String::Copy(const String& dst, intptr_t dst_offset, | 5897 void String::Copy(const String& dst, intptr_t dst_offset, |
| 5819 const String& src, intptr_t src_offset, | 5898 const String& src, intptr_t src_offset, |
| 5820 intptr_t len) { | 5899 intptr_t len) { |
| 5821 ASSERT(dst_offset >= 0); | 5900 ASSERT(dst_offset >= 0); |
| 5822 ASSERT(src_offset >= 0); | 5901 ASSERT(src_offset >= 0); |
| 5823 ASSERT(len >= 0); | 5902 ASSERT(len >= 0); |
| 5824 ASSERT(len <= (dst.Length() - dst_offset)); | 5903 ASSERT(len <= (dst.Length() - dst_offset)); |
| 5825 ASSERT(len <= (src.Length() - src_offset)); | 5904 ASSERT(len <= (src.Length() - src_offset)); |
| 5826 if (len > 0) { | 5905 if (len > 0) { |
| 5827 if (src.IsOneByteString()) { | 5906 intptr_t char_size = src.CharSize(); |
| 5828 OneByteString& onestr = OneByteString::Handle(); | 5907 if (char_size == kOneByteChar) { |
| 5829 onestr ^= src.raw(); | 5908 if (src.IsOneByteString()) { |
| 5830 NoGCScope no_gc; | 5909 OneByteString& onestr = OneByteString::Handle(); |
| 5831 String::Copy(dst, dst_offset, onestr.CharAddr(0) + src_offset, len); | 5910 onestr ^= src.raw(); |
| 5832 } else if (src.IsTwoByteString()) { | 5911 NoGCScope no_gc; |
| 5833 TwoByteString& twostr = TwoByteString::Handle(); | 5912 String::Copy(dst, dst_offset, onestr.CharAddr(0) + src_offset, len); |
| 5834 twostr ^= src.raw(); | 5913 } else { |
| 5835 NoGCScope no_gc; | 5914 ASSERT(src.IsExternalOneByteString()); |
| 5836 String::Copy(dst, dst_offset, twostr.CharAddr(0) + src_offset, len); | 5915 ExternalOneByteString& onestr = ExternalOneByteString::Handle(); |
| 5916 onestr ^= src.raw(); | |
| 5917 NoGCScope no_gc; | |
| 5918 String::Copy(dst, dst_offset, onestr.CharAddr(0) + src_offset, len); | |
| 5919 } | |
| 5920 } else if (char_size == kTwoByteChar) { | |
| 5921 if (src.IsTwoByteString()) { | |
| 5922 TwoByteString& twostr = TwoByteString::Handle(); | |
| 5923 twostr ^= src.raw(); | |
| 5924 NoGCScope no_gc; | |
| 5925 String::Copy(dst, dst_offset, twostr.CharAddr(0) + src_offset, len); | |
| 5926 } else { | |
| 5927 ASSERT(src.IsExternalTwoByteString()); | |
| 5928 ExternalTwoByteString& twostr = ExternalTwoByteString::Handle(); | |
| 5929 twostr ^= src.raw(); | |
| 5930 NoGCScope no_gc; | |
| 5931 String::Copy(dst, dst_offset, twostr.CharAddr(0) + src_offset, len); | |
| 5932 } | |
| 5837 } else { | 5933 } else { |
| 5838 ASSERT(src.IsFourByteString()); | 5934 ASSERT(char_size == kFourByteChar); |
| 5839 FourByteString& fourstr = FourByteString::Handle(); | 5935 if (src.IsFourByteString()) { |
| 5840 fourstr ^= src.raw(); | 5936 FourByteString& fourstr = FourByteString::Handle(); |
| 5841 NoGCScope no_gc; | 5937 fourstr ^= src.raw(); |
| 5842 String::Copy(dst, dst_offset, fourstr.CharAddr(0) + src_offset, len); | 5938 NoGCScope no_gc; |
| 5939 String::Copy(dst, dst_offset, fourstr.CharAddr(0) + src_offset, len); | |
| 5940 } else { | |
| 5941 ASSERT(src.IsExternalFourByteString()); | |
| 5942 ExternalFourByteString& fourstr = ExternalFourByteString::Handle(); | |
| 5943 fourstr ^= src.raw(); | |
| 5944 NoGCScope no_gc; | |
| 5945 String::Copy(dst, dst_offset, fourstr.CharAddr(0) + src_offset, len); | |
| 5946 } | |
| 5843 } | 5947 } |
| 5844 } | 5948 } |
| 5845 } | 5949 } |
| 5846 | 5950 |
| 5847 | 5951 |
| 5848 static void GrowSymbolTable(const Array& symbol_table, intptr_t table_size) { | 5952 static void GrowSymbolTable(const Array& symbol_table, intptr_t table_size) { |
| 5849 // TODO(iposva): Avoid exponential growth. | 5953 // TODO(iposva): Avoid exponential growth. |
| 5850 intptr_t new_table_size = table_size * 2; | 5954 intptr_t new_table_size = table_size * 2; |
| 5851 Array& new_symbol_table = Array::Handle(Array::New(new_table_size + 1)); | 5955 Array& new_symbol_table = Array::Handle(Array::New(new_table_size + 1)); |
| 5852 // Copy all elements from the original symbol table to the newly allocated | 5956 // 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... | |
| 5994 } | 6098 } |
| 5995 ASSERT(symbol.IsSymbol()); | 6099 ASSERT(symbol.IsSymbol()); |
| 5996 return symbol.raw(); | 6100 return symbol.raw(); |
| 5997 } | 6101 } |
| 5998 | 6102 |
| 5999 | 6103 |
| 6000 RawString* String::Concat(const String& str1, | 6104 RawString* String::Concat(const String& str1, |
| 6001 const String& str2, | 6105 const String& str2, |
| 6002 Heap::Space space) { | 6106 Heap::Space space) { |
| 6003 ASSERT(!str1.IsNull() && !str2.IsNull()); | 6107 ASSERT(!str1.IsNull() && !str2.IsNull()); |
| 6004 if (str1.IsFourByteString() || str2.IsFourByteString()) { | 6108 intptr_t char_size = Utils::Maximum(str1.CharSize(), str2.CharSize()); |
| 6109 if (char_size == kFourByteChar) { | |
| 6005 return FourByteString::Concat(str1, str2, space); | 6110 return FourByteString::Concat(str1, str2, space); |
| 6006 } | 6111 } |
| 6007 if (str1.IsTwoByteString() || str2.IsTwoByteString()) { | 6112 if (char_size == kTwoByteChar) { |
| 6008 return TwoByteString::Concat(str1, str2, space); | 6113 return TwoByteString::Concat(str1, str2, space); |
| 6009 } | 6114 } |
| 6010 ASSERT(str1.IsOneByteString() && str2.IsOneByteString()); | |
| 6011 return OneByteString::Concat(str1, str2, space); | 6115 return OneByteString::Concat(str1, str2, space); |
| 6012 } | 6116 } |
| 6013 | 6117 |
| 6014 | 6118 |
| 6015 RawString* String::ConcatAll(const Array& strings, | 6119 RawString* String::ConcatAll(const Array& strings, |
| 6016 Heap::Space space) { | 6120 Heap::Space space) { |
| 6017 ASSERT(!strings.IsNull()); | 6121 ASSERT(!strings.IsNull()); |
| 6018 bool is_one_byte_string = true; | |
| 6019 bool is_two_byte_string = true; | |
| 6020 intptr_t result_len = 0; | 6122 intptr_t result_len = 0; |
| 6021 intptr_t strings_len = strings.Length(); | 6123 intptr_t strings_len = strings.Length(); |
| 6022 String& str = String::Handle(); | 6124 String& str = String::Handle(); |
| 6125 intptr_t char_size = kOneByteChar; | |
| 6023 for (intptr_t i = 0; i < strings_len; i++) { | 6126 for (intptr_t i = 0; i < strings_len; i++) { |
| 6024 str ^= strings.At(i); | 6127 str ^= strings.At(i); |
| 6025 result_len += str.Length(); | 6128 result_len += str.Length(); |
| 6026 if (str.IsFourByteString()) { | 6129 char_size = Utils::Maximum(char_size, str.CharSize()); |
| 6027 is_one_byte_string = false; | |
| 6028 is_two_byte_string = false; | |
| 6029 } else if (str.IsTwoByteString()) { | |
| 6030 is_one_byte_string = false; | |
| 6031 } | |
| 6032 } | 6130 } |
| 6033 if (is_one_byte_string) { | 6131 if (char_size == kOneByteChar) { |
| 6034 return OneByteString::ConcatAll(strings, result_len, space); | 6132 return OneByteString::ConcatAll(strings, result_len, space); |
| 6035 } else if (is_two_byte_string) { | 6133 } else if (char_size == kTwoByteChar) { |
| 6036 return TwoByteString::ConcatAll(strings, result_len, space); | 6134 return TwoByteString::ConcatAll(strings, result_len, space); |
| 6037 } | 6135 } |
| 6136 ASSERT(char_size == kFourByteChar); | |
| 6038 return FourByteString::ConcatAll(strings, result_len, space); | 6137 return FourByteString::ConcatAll(strings, result_len, space); |
| 6039 } | 6138 } |
| 6040 | 6139 |
| 6041 | 6140 |
| 6042 RawString* String::SubString(const String& str, | 6141 RawString* String::SubString(const String& str, |
| 6043 intptr_t begin_index, | 6142 intptr_t begin_index, |
| 6044 Heap::Space space) { | 6143 Heap::Space space) { |
| 6045 ASSERT(!str.IsNull()); | 6144 ASSERT(!str.IsNull()); |
| 6046 if (begin_index >= str.Length()) { | 6145 if (begin_index >= str.Length()) { |
| 6047 return String::null(); | 6146 return String::null(); |
| 6048 } | 6147 } |
| 6049 return String::SubString(str, begin_index, (str.Length() - begin_index)); | 6148 return String::SubString(str, begin_index, (str.Length() - begin_index)); |
| 6050 } | 6149 } |
| 6051 | 6150 |
| 6052 | 6151 |
| 6053 RawString* String::SubString(const String& str, | 6152 RawString* String::SubString(const String& str, |
| 6054 intptr_t begin_index, | 6153 intptr_t begin_index, |
| 6055 intptr_t length, | 6154 intptr_t length, |
| 6056 Heap::Space space) { | 6155 Heap::Space space) { |
| 6057 ASSERT(!str.IsNull()); | 6156 ASSERT(!str.IsNull()); |
| 6058 ASSERT(begin_index >= 0); | 6157 ASSERT(begin_index >= 0); |
| 6059 ASSERT(length >= 0); | 6158 ASSERT(length >= 0); |
| 6060 if (begin_index >= str.Length()) { | 6159 if (begin_index >= str.Length()) { |
| 6061 return String::null(); | 6160 return String::null(); |
| 6062 } | 6161 } |
| 6063 if (str.IsOneByteString()) { | 6162 String& result = String::Handle(); |
| 6064 OneByteString& obstr = OneByteString::Handle(); | 6163 bool is_one_byte_string = true; |
| 6065 obstr ^= str.raw(); | 6164 bool is_two_byte_string = true; |
| 6066 return OneByteString::SubString(obstr, begin_index, length, space); | 6165 intptr_t char_size = str.CharSize(); |
| 6067 } else if (str.IsTwoByteString()) { | 6166 if (char_size == kTwoByteChar) { |
| 6068 TwoByteString& twostr = TwoByteString::Handle(); | 6167 for (intptr_t i = begin_index; i < begin_index + length; ++i) { |
| 6069 twostr ^= str.raw(); | 6168 if (str.CharAt(i) > 0xFF) { |
| 6070 return TwoByteString::SubString(twostr, begin_index, length, space); | 6169 is_one_byte_string = false; |
| 6170 break; | |
| 6171 } | |
| 6172 } | |
| 6173 } else if (char_size == kFourByteChar) { | |
| 6174 for (intptr_t i = begin_index; i < begin_index + length; ++i) { | |
| 6175 if (str.CharAt(i) > 0xFFFF) { | |
| 6176 is_one_byte_string = false; | |
| 6177 is_two_byte_string = false; | |
| 6178 break; | |
| 6179 } else if (str.CharAt(i) > 0xFF) { | |
| 6180 is_one_byte_string = false; | |
| 6181 } | |
| 6182 } | |
| 6071 } | 6183 } |
| 6072 ASSERT(str.IsFourByteString()); | 6184 if (is_one_byte_string) { |
| 6073 FourByteString& fourstr = FourByteString::Handle(); | 6185 result ^= OneByteString::New(length, space); |
| 6074 fourstr ^= str.raw(); | 6186 } else if (is_two_byte_string) { |
| 6075 return FourByteString::SubString(fourstr, begin_index, length, space); | 6187 result ^= TwoByteString::New(length, space); |
| 6188 } else { | |
| 6189 result ^= FourByteString::New(length, space); | |
| 6190 } | |
| 6191 String::Copy(result, 0, str, begin_index, length); | |
| 6192 return result.raw(); | |
| 6076 } | 6193 } |
| 6077 | 6194 |
| 6078 | 6195 |
| 6079 const char* String::ToCString() const { | 6196 const char* String::ToCString() const { |
| 6080 intptr_t len = Utf8::Length(*this); | 6197 intptr_t len = Utf8::Length(*this); |
| 6081 Zone* zone = Isolate::Current()->current_zone(); | 6198 Zone* zone = Isolate::Current()->current_zone(); |
| 6082 char* result = reinterpret_cast<char*>(zone->Allocate(len + 1)); | 6199 char* result = reinterpret_cast<char*>(zone->Allocate(len + 1)); |
| 6083 Utf8::Encode(*this, result, len); | 6200 Utf8::Encode(*this, result, len); |
| 6084 result[len] = 0; | 6201 result[len] = 0; |
| 6085 return result; | 6202 return result; |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6213 for (intptr_t i = 0; i < strings_len; i++) { | 6330 for (intptr_t i = 0; i < strings_len; i++) { |
| 6214 str ^= strings.At(i); | 6331 str ^= strings.At(i); |
| 6215 intptr_t str_len = str.Length(); | 6332 intptr_t str_len = str.Length(); |
| 6216 String::Copy(result, pos, str, 0, str_len); | 6333 String::Copy(result, pos, str, 0, str_len); |
| 6217 pos += str_len; | 6334 pos += str_len; |
| 6218 } | 6335 } |
| 6219 return result.raw(); | 6336 return result.raw(); |
| 6220 } | 6337 } |
| 6221 | 6338 |
| 6222 | 6339 |
| 6223 RawString* OneByteString::SubString(const OneByteString& str, | |
| 6224 intptr_t begin_index, | |
| 6225 intptr_t length, | |
| 6226 Heap::Space space) { | |
| 6227 ASSERT(!str.IsNull()); | |
| 6228 ASSERT(begin_index < str.Length()); | |
| 6229 OneByteString& result = OneByteString::Handle(); | |
| 6230 if (length <= (str.Length() - begin_index)) { | |
| 6231 result ^= OneByteString::New(length, space); | |
| 6232 String::Copy(result, 0, str, begin_index, length); | |
| 6233 } | |
| 6234 // TODO(5418937): return a non-null object on error. | |
| 6235 return result.raw(); | |
| 6236 } | |
| 6237 | |
| 6238 | |
| 6239 RawOneByteString* OneByteString::Transform(int32_t (*mapping)(int32_t ch), | 6340 RawOneByteString* OneByteString::Transform(int32_t (*mapping)(int32_t ch), |
| 6240 const String& str, | 6341 const String& str, |
| 6241 Heap::Space space) { | 6342 Heap::Space space) { |
| 6242 ASSERT(!str.IsNull()); | 6343 ASSERT(!str.IsNull()); |
| 6243 intptr_t len = str.Length(); | 6344 intptr_t len = str.Length(); |
| 6244 const OneByteString& result = | 6345 const OneByteString& result = |
| 6245 OneByteString::Handle(OneByteString::New(len, space)); | 6346 OneByteString::Handle(OneByteString::New(len, space)); |
| 6246 for (intptr_t i = 0; i < len; ++i) { | 6347 for (intptr_t i = 0; i < len; ++i) { |
| 6247 int32_t ch = mapping(str.CharAt(i)); | 6348 int32_t ch = mapping(str.CharAt(i)); |
| 6248 ASSERT(ch >= 0 && ch <= 0xFF); | 6349 ASSERT(ch >= 0 && ch <= 0xFF); |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6332 for (intptr_t i = 0; i < strings_len; i++) { | 6433 for (intptr_t i = 0; i < strings_len; i++) { |
| 6333 str ^= strings.At(i); | 6434 str ^= strings.At(i); |
| 6334 intptr_t str_len = str.Length(); | 6435 intptr_t str_len = str.Length(); |
| 6335 String::Copy(result, pos, str, 0, str_len); | 6436 String::Copy(result, pos, str, 0, str_len); |
| 6336 pos += str_len; | 6437 pos += str_len; |
| 6337 } | 6438 } |
| 6338 return result.raw(); | 6439 return result.raw(); |
| 6339 } | 6440 } |
| 6340 | 6441 |
| 6341 | 6442 |
| 6342 RawString* TwoByteString::SubString(const TwoByteString& str, | |
| 6343 intptr_t begin_index, | |
| 6344 intptr_t length, | |
| 6345 Heap::Space space) { | |
| 6346 ASSERT(!str.IsNull()); | |
| 6347 ASSERT(begin_index < str.Length()); | |
| 6348 String& result = String::Handle(); | |
| 6349 if (length <= (str.Length() - begin_index)) { | |
| 6350 bool is_one_byte_string = true; | |
| 6351 for (intptr_t i = begin_index; i < begin_index + length; ++i) { | |
| 6352 if (str.CharAt(i) > 0xFF) { | |
| 6353 is_one_byte_string = false; | |
| 6354 break; | |
| 6355 } | |
| 6356 } | |
| 6357 if (is_one_byte_string) { | |
| 6358 result ^= OneByteString::New(length, space); | |
| 6359 } else { | |
| 6360 result ^= TwoByteString::New(length, space); | |
| 6361 } | |
| 6362 String::Copy(result, 0, str, begin_index, length); | |
| 6363 } | |
| 6364 // TODO(5418937): return a non-null object on error. | |
| 6365 return result.raw(); | |
| 6366 } | |
| 6367 | |
| 6368 | |
| 6369 RawTwoByteString* TwoByteString::Transform(int32_t (*mapping)(int32_t ch), | 6443 RawTwoByteString* TwoByteString::Transform(int32_t (*mapping)(int32_t ch), |
| 6370 const String& str, | 6444 const String& str, |
| 6371 Heap::Space space) { | 6445 Heap::Space space) { |
| 6372 ASSERT(!str.IsNull()); | 6446 ASSERT(!str.IsNull()); |
| 6373 intptr_t len = str.Length(); | 6447 intptr_t len = str.Length(); |
| 6374 const TwoByteString& result = | 6448 const TwoByteString& result = |
| 6375 TwoByteString::Handle(TwoByteString::New(len, space)); | 6449 TwoByteString::Handle(TwoByteString::New(len, space)); |
| 6376 for (intptr_t i = 0; i < len; ++i) { | 6450 for (intptr_t i = 0; i < len; ++i) { |
| 6377 int32_t ch = mapping(str.CharAt(i)); | 6451 int32_t ch = mapping(str.CharAt(i)); |
| 6378 ASSERT(ch >= 0 && ch <= 0xFFFF); | 6452 ASSERT(ch >= 0 && ch <= 0xFFFF); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6450 str ^= strings.At(i); | 6524 str ^= strings.At(i); |
| 6451 intptr_t str_len = str.Length(); | 6525 intptr_t str_len = str.Length(); |
| 6452 String::Copy(result, pos, str, 0, str_len); | 6526 String::Copy(result, pos, str, 0, str_len); |
| 6453 pos += str_len; | 6527 pos += str_len; |
| 6454 } | 6528 } |
| 6455 } | 6529 } |
| 6456 return result.raw(); | 6530 return result.raw(); |
| 6457 } | 6531 } |
| 6458 | 6532 |
| 6459 | 6533 |
| 6460 RawString* FourByteString::SubString(const FourByteString& str, | |
| 6461 intptr_t begin_index, | |
| 6462 intptr_t length, | |
| 6463 Heap::Space space) { | |
| 6464 ASSERT(!str.IsNull()); | |
| 6465 ASSERT(begin_index < str.Length()); | |
| 6466 String& result = String::Handle(); | |
| 6467 if (length <= (str.Length() - begin_index)) { | |
| 6468 bool is_one_byte_string = true; | |
| 6469 bool is_two_byte_string = true; | |
| 6470 for (intptr_t i = begin_index; i < begin_index + length; ++i) { | |
| 6471 if (str.CharAt(i) > 0xFFFF) { | |
| 6472 is_one_byte_string = false; | |
| 6473 is_two_byte_string = false; | |
| 6474 break; | |
| 6475 } else if (str.CharAt(i) > 0xFF) { | |
| 6476 is_one_byte_string = false; | |
| 6477 } | |
| 6478 } | |
| 6479 if (is_one_byte_string) { | |
| 6480 result ^= OneByteString::New(length, space); | |
| 6481 } else if (is_two_byte_string) { | |
| 6482 result ^= TwoByteString::New(length, space); | |
| 6483 } else { | |
| 6484 result ^= FourByteString::New(length, space); | |
| 6485 } | |
| 6486 String::Copy(result, 0, str, begin_index, length); | |
| 6487 } | |
| 6488 // TODO(5418937): return a non-null object on error. | |
| 6489 return result.raw(); | |
| 6490 } | |
| 6491 | |
| 6492 | |
| 6493 RawFourByteString* FourByteString::Transform(int32_t (*mapping)(int32_t ch), | 6534 RawFourByteString* FourByteString::Transform(int32_t (*mapping)(int32_t ch), |
| 6494 const String& str, | 6535 const String& str, |
| 6495 Heap::Space space) { | 6536 Heap::Space space) { |
| 6496 ASSERT(!str.IsNull()); | 6537 ASSERT(!str.IsNull()); |
| 6497 intptr_t len = str.Length(); | 6538 intptr_t len = str.Length(); |
| 6498 const FourByteString& result = | 6539 const FourByteString& result = |
| 6499 FourByteString::Handle(FourByteString::New(len, space)); | 6540 FourByteString::Handle(FourByteString::New(len, space)); |
| 6500 for (intptr_t i = 0; i < len; ++i) { | 6541 for (intptr_t i = 0; i < len; ++i) { |
| 6501 int32_t ch = mapping(str.CharAt(i)); | 6542 int32_t ch = mapping(str.CharAt(i)); |
| 6502 ASSERT(ch >= 0 && ch <= 0x10FFFF); | 6543 ASSERT(ch >= 0 && ch <= 0x10FFFF); |
| 6503 *result.CharAddr(i) = ch; | 6544 *result.CharAddr(i) = ch; |
| 6504 } | 6545 } |
| 6505 return result.raw(); | 6546 return result.raw(); |
| 6506 } | 6547 } |
| 6507 | 6548 |
| 6508 | 6549 |
| 6509 const char* FourByteString::ToCString() const { | 6550 const char* FourByteString::ToCString() const { |
| 6510 return String::ToCString(); | 6551 return String::ToCString(); |
| 6511 } | 6552 } |
| 6512 | 6553 |
| 6513 | 6554 |
| 6555 RawExternalOneByteString* ExternalOneByteString::New(const uint8_t* data, | |
| 6556 intptr_t len, | |
| 6557 void* peer, | |
| 6558 PeerFinalizer callback, | |
| 6559 Heap::Space space) { | |
| 6560 Isolate* isolate = Isolate::Current(); | |
| 6561 | |
| 6562 const Class& cls = | |
| 6563 Class::Handle(isolate->object_store()->external_one_byte_string_class()); | |
| 6564 ExternalOneByteString& result = ExternalOneByteString::Handle(); | |
| 6565 { | |
| 6566 RawExternalStringData<uint8_t>* external_data = | |
|
Ivan Posva
2011/11/18 19:36:44
Naming this Raw is very confusing, the expectation
cshapiro
2011/11/19 01:08:29
Fixed.
| |
| 6567 new RawExternalStringData<uint8_t>(data, peer, callback); | |
| 6568 RawObject* raw = Object::Allocate(cls, | |
| 6569 ExternalOneByteString::InstanceSize(), | |
| 6570 space); | |
| 6571 NoGCScope no_gc; | |
| 6572 result ^= raw; | |
| 6573 result.SetLength(len); | |
| 6574 result.SetHash(0); | |
| 6575 result.SetExternalData(external_data); | |
| 6576 } | |
| 6577 return result.raw(); | |
| 6578 } | |
| 6579 | |
| 6580 | |
| 6581 const char* ExternalOneByteString::ToCString() const { | |
| 6582 return String::ToCString(); | |
| 6583 } | |
| 6584 | |
| 6585 | |
| 6586 RawExternalTwoByteString* ExternalTwoByteString::New(const uint16_t* data, | |
| 6587 intptr_t len, | |
| 6588 void* peer, | |
| 6589 PeerFinalizer callback, | |
| 6590 Heap::Space space) { | |
| 6591 Isolate* isolate = Isolate::Current(); | |
| 6592 | |
| 6593 const Class& cls = | |
| 6594 Class::Handle(isolate->object_store()->external_two_byte_string_class()); | |
| 6595 ExternalTwoByteString& result = ExternalTwoByteString::Handle(); | |
| 6596 { | |
| 6597 RawExternalStringData<uint16_t>* external_data = | |
| 6598 new RawExternalStringData<uint16_t>(data, peer, callback); | |
| 6599 RawObject* raw = Object::Allocate(cls, | |
| 6600 ExternalTwoByteString::InstanceSize(), | |
| 6601 space); | |
| 6602 NoGCScope no_gc; | |
| 6603 result ^= raw; | |
| 6604 result.SetLength(len); | |
| 6605 result.SetHash(0); | |
| 6606 result.SetExternalData(external_data); | |
| 6607 } | |
| 6608 return result.raw(); | |
| 6609 } | |
| 6610 | |
| 6611 | |
| 6612 const char* ExternalTwoByteString::ToCString() const { | |
| 6613 return String::ToCString(); | |
| 6614 } | |
| 6615 | |
| 6616 | |
| 6617 RawExternalFourByteString* ExternalFourByteString::New(const uint32_t* data, | |
| 6618 intptr_t len, | |
| 6619 void* peer, | |
| 6620 PeerFinalizer callback, | |
| 6621 Heap::Space space) { | |
| 6622 Isolate* isolate = Isolate::Current(); | |
| 6623 | |
| 6624 const Class& cls = | |
| 6625 Class::Handle(isolate->object_store()->external_four_byte_string_class()); | |
| 6626 ExternalFourByteString& result = ExternalFourByteString::Handle(); | |
| 6627 { | |
| 6628 RawExternalStringData<uint32_t>* external_data = | |
| 6629 new RawExternalStringData<uint32_t>(data, peer, callback); | |
| 6630 RawObject* raw = Object::Allocate(cls, | |
| 6631 ExternalFourByteString::InstanceSize(), | |
| 6632 space); | |
| 6633 NoGCScope no_gc; | |
| 6634 result ^= raw; | |
| 6635 result.SetLength(len); | |
| 6636 result.SetHash(0); | |
| 6637 result.SetExternalData(external_data); | |
| 6638 } | |
| 6639 return result.raw(); | |
| 6640 } | |
| 6641 | |
| 6642 | |
| 6643 const char* ExternalFourByteString::ToCString() const { | |
| 6644 return String::ToCString(); | |
| 6645 } | |
| 6646 | |
| 6647 | |
| 6514 RawBool* Bool::True() { | 6648 RawBool* Bool::True() { |
| 6515 return Isolate::Current()->object_store()->true_value(); | 6649 return Isolate::Current()->object_store()->true_value(); |
| 6516 } | 6650 } |
| 6517 | 6651 |
| 6518 | 6652 |
| 6519 RawBool* Bool::False() { | 6653 RawBool* Bool::False() { |
| 6520 return Isolate::Current()->object_store()->false_value(); | 6654 return Isolate::Current()->object_store()->false_value(); |
| 6521 } | 6655 } |
| 6522 | 6656 |
| 6523 | 6657 |
| (...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6944 const String& str = String::Handle(pattern()); | 7078 const String& str = String::Handle(pattern()); |
| 6945 const char* format = "JSRegExp: pattern=%s flags=%s"; | 7079 const char* format = "JSRegExp: pattern=%s flags=%s"; |
| 6946 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); | 7080 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); |
| 6947 char* chars = reinterpret_cast<char*>( | 7081 char* chars = reinterpret_cast<char*>( |
| 6948 Isolate::Current()->current_zone()->Allocate(len + 1)); | 7082 Isolate::Current()->current_zone()->Allocate(len + 1)); |
| 6949 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); | 7083 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); |
| 6950 return chars; | 7084 return chars; |
| 6951 } | 7085 } |
| 6952 | 7086 |
| 6953 } // namespace dart | 7087 } // namespace dart |
| OLD | NEW |