| 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 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 381 | 381 |
| 382 cls = Class::New<OneByteString>(); | 382 cls = Class::New<OneByteString>(); |
| 383 object_store->set_one_byte_string_class(cls); | 383 object_store->set_one_byte_string_class(cls); |
| 384 | 384 |
| 385 cls = Class::New<TwoByteString>(); | 385 cls = Class::New<TwoByteString>(); |
| 386 object_store->set_two_byte_string_class(cls); | 386 object_store->set_two_byte_string_class(cls); |
| 387 | 387 |
| 388 cls = Class::New<FourByteString>(); | 388 cls = Class::New<FourByteString>(); |
| 389 object_store->set_four_byte_string_class(cls); | 389 object_store->set_four_byte_string_class(cls); |
| 390 | 390 |
| 391 cls = Class::New<ExternalOneByteString>(); |
| 392 object_store->set_external_one_byte_string_class(cls); |
| 393 |
| 394 cls = Class::New<ExternalTwoByteString>(); |
| 395 object_store->set_external_two_byte_string_class(cls); |
| 396 |
| 397 cls = Class::New<ExternalFourByteString>(); |
| 398 object_store->set_external_four_byte_string_class(cls); |
| 399 |
| 391 cls = Class::New<Bool>(); | 400 cls = Class::New<Bool>(); |
| 392 object_store->set_bool_class(cls); | 401 object_store->set_bool_class(cls); |
| 393 | 402 |
| 394 cls = Class::New<UnhandledException>(); | 403 cls = Class::New<UnhandledException>(); |
| 395 object_store->set_unhandled_exception_class(cls); | 404 object_store->set_unhandled_exception_class(cls); |
| 396 | 405 |
| 397 cls = Class::New<Stacktrace>(); | 406 cls = Class::New<Stacktrace>(); |
| 398 object_store->set_stacktrace_class(cls); | 407 object_store->set_stacktrace_class(cls); |
| 399 // Set the super type so that the 'toString' method is implemented. | 408 // Set the super type so that the 'toString' method is implemented. |
| 400 type = object_store->object_type(); | 409 type = object_store->object_type(); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 450 cls.set_name(name); | 459 cls.set_name(name); |
| 451 cls.set_script(impl_script); | 460 cls.set_script(impl_script); |
| 452 core_impl_lib.AddClass(cls); | 461 core_impl_lib.AddClass(cls); |
| 453 | 462 |
| 454 name = String::NewSymbol("FourByteString"); | 463 name = String::NewSymbol("FourByteString"); |
| 455 cls = object_store->four_byte_string_class(); | 464 cls = object_store->four_byte_string_class(); |
| 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 |
| 469 name = String::NewSymbol("ExternalOneByteString"); |
| 470 cls = object_store->external_one_byte_string_class(); |
| 471 cls.set_name(name); |
| 472 cls.set_script(impl_script); |
| 473 core_impl_lib.AddClass(cls); |
| 474 |
| 475 name = String::NewSymbol("ExternalTwoByteString"); |
| 476 cls = object_store->external_two_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("ExternalFourByteString"); |
| 482 cls = object_store->external_four_byte_string_class(); |
| 483 cls.set_name(name); |
| 484 cls.set_script(impl_script); |
| 485 core_impl_lib.AddClass(cls); |
| 486 |
| 460 name = String::NewSymbol("Mint"); | 487 name = String::NewSymbol("Mint"); |
| 461 cls = object_store->mint_class(); | 488 cls = object_store->mint_class(); |
| 462 cls.set_name(name); | 489 cls.set_name(name); |
| 463 cls.set_script(impl_script); | 490 cls.set_script(impl_script); |
| 464 core_impl_lib.AddClass(cls); | 491 core_impl_lib.AddClass(cls); |
| 465 | 492 |
| 466 name = String::NewSymbol("Bigint"); | 493 name = String::NewSymbol("Bigint"); |
| 467 cls = object_store->bigint_class(); | 494 cls = object_store->bigint_class(); |
| 468 cls.set_name(name); | 495 cls.set_name(name); |
| 469 cls.set_script(impl_script); | 496 cls.set_script(impl_script); |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 625 | 652 |
| 626 cls = Class::New<OneByteString>(); | 653 cls = Class::New<OneByteString>(); |
| 627 object_store->set_one_byte_string_class(cls); | 654 object_store->set_one_byte_string_class(cls); |
| 628 | 655 |
| 629 cls = Class::New<TwoByteString>(); | 656 cls = Class::New<TwoByteString>(); |
| 630 object_store->set_two_byte_string_class(cls); | 657 object_store->set_two_byte_string_class(cls); |
| 631 | 658 |
| 632 cls = Class::New<FourByteString>(); | 659 cls = Class::New<FourByteString>(); |
| 633 object_store->set_four_byte_string_class(cls); | 660 object_store->set_four_byte_string_class(cls); |
| 634 | 661 |
| 662 cls = Class::New<ExternalOneByteString>(); |
| 663 object_store->set_external_one_byte_string_class(cls); |
| 664 |
| 665 cls = Class::New<ExternalTwoByteString>(); |
| 666 object_store->set_external_two_byte_string_class(cls); |
| 667 |
| 668 cls = Class::New<ExternalFourByteString>(); |
| 669 object_store->set_external_four_byte_string_class(cls); |
| 670 |
| 635 cls = Class::New<Bool>(); | 671 cls = Class::New<Bool>(); |
| 636 object_store->set_bool_class(cls); | 672 object_store->set_bool_class(cls); |
| 637 | 673 |
| 638 cls = Class::New<UnhandledException>(); | 674 cls = Class::New<UnhandledException>(); |
| 639 object_store->set_unhandled_exception_class(cls); | 675 object_store->set_unhandled_exception_class(cls); |
| 640 | 676 |
| 641 cls = Class::New<Stacktrace>(); | 677 cls = Class::New<Stacktrace>(); |
| 642 object_store->set_stacktrace_class(cls); | 678 object_store->set_stacktrace_class(cls); |
| 643 | 679 |
| 644 cls = Class::New<JSRegExp>(); | 680 cls = Class::New<JSRegExp>(); |
| (...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1075 return object_store->double_class(); | 1111 return object_store->double_class(); |
| 1076 case kOneByteString: | 1112 case kOneByteString: |
| 1077 ASSERT(object_store->one_byte_string_class() != Class::null()); | 1113 ASSERT(object_store->one_byte_string_class() != Class::null()); |
| 1078 return object_store->one_byte_string_class(); | 1114 return object_store->one_byte_string_class(); |
| 1079 case kTwoByteString: | 1115 case kTwoByteString: |
| 1080 ASSERT(object_store->two_byte_string_class() != Class::null()); | 1116 ASSERT(object_store->two_byte_string_class() != Class::null()); |
| 1081 return object_store->two_byte_string_class(); | 1117 return object_store->two_byte_string_class(); |
| 1082 case kFourByteString: | 1118 case kFourByteString: |
| 1083 ASSERT(object_store->four_byte_string_class() != Class::null()); | 1119 ASSERT(object_store->four_byte_string_class() != Class::null()); |
| 1084 return object_store->four_byte_string_class(); | 1120 return object_store->four_byte_string_class(); |
| 1121 case kExternalOneByteString: |
| 1122 ASSERT(object_store->external_one_byte_string_class() != Class::null()); |
| 1123 return object_store->external_one_byte_string_class(); |
| 1124 case kExternalTwoByteString: |
| 1125 ASSERT(object_store->external_two_byte_string_class() != Class::null()); |
| 1126 return object_store->external_two_byte_string_class(); |
| 1127 case kExternalFourByteString: |
| 1128 ASSERT(object_store->external_four_byte_string_class() != Class::null()); |
| 1129 return object_store->external_four_byte_string_class(); |
| 1085 case kBool: | 1130 case kBool: |
| 1086 ASSERT(object_store->bool_class() != Class::null()); | 1131 ASSERT(object_store->bool_class() != Class::null()); |
| 1087 return object_store->bool_class(); | 1132 return object_store->bool_class(); |
| 1088 case kArray: | 1133 case kArray: |
| 1089 ASSERT(object_store->array_class() != Class::null()); | 1134 ASSERT(object_store->array_class() != Class::null()); |
| 1090 return object_store->array_class(); | 1135 return object_store->array_class(); |
| 1091 case kImmutableArray: | 1136 case kImmutableArray: |
| 1092 ASSERT(object_store->immutable_array_class() != Class::null()); | 1137 ASSERT(object_store->immutable_array_class() != Class::null()); |
| 1093 return object_store->immutable_array_class(); | 1138 return object_store->immutable_array_class(); |
| 1094 case kStacktrace: | 1139 case kStacktrace: |
| (...skipping 4204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5299 } | 5344 } |
| 5300 | 5345 |
| 5301 | 5346 |
| 5302 int32_t String::CharAt(intptr_t index) const { | 5347 int32_t String::CharAt(intptr_t index) const { |
| 5303 // String is an abstract class. | 5348 // String is an abstract class. |
| 5304 UNREACHABLE(); | 5349 UNREACHABLE(); |
| 5305 return 0; | 5350 return 0; |
| 5306 } | 5351 } |
| 5307 | 5352 |
| 5308 | 5353 |
| 5354 intptr_t String::CharSize() const { |
| 5355 // String is an abstract class. |
| 5356 UNREACHABLE(); |
| 5357 return 0; |
| 5358 } |
| 5359 |
| 5360 |
| 5309 bool String::Equals(const Instance& other) const { | 5361 bool String::Equals(const Instance& other) const { |
| 5310 if (this->raw() == other.raw()) { | 5362 if (this->raw() == other.raw()) { |
| 5311 // Both handles point to the same raw instance. | 5363 // Both handles point to the same raw instance. |
| 5312 return true; | 5364 return true; |
| 5313 } | 5365 } |
| 5314 | 5366 |
| 5315 if (!other.IsString() || other.IsNull()) { | 5367 if (!other.IsString() || other.IsNull()) { |
| 5316 return false; | 5368 return false; |
| 5317 } | 5369 } |
| 5318 | 5370 |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5562 } | 5614 } |
| 5563 return FourByteString::New(characters, len, space); | 5615 return FourByteString::New(characters, len, space); |
| 5564 } | 5616 } |
| 5565 | 5617 |
| 5566 | 5618 |
| 5567 RawString* String::New(const String& str, Heap::Space space) { | 5619 RawString* String::New(const String& str, Heap::Space space) { |
| 5568 // Currently this just creates a copy of the string in the correct space. | 5620 // Currently this just creates a copy of the string in the correct space. |
| 5569 // Once we have external string support, this will also create a heap copy of | 5621 // Once we have external string support, this will also create a heap copy of |
| 5570 // the string if necessary. Some optimizations are possible, such as not | 5622 // the string if necessary. Some optimizations are possible, such as not |
| 5571 // copying internal strings into the same space. | 5623 // copying internal strings into the same space. |
| 5572 if (str.IsOneByteString()) { | 5624 intptr_t len = str.Length(); |
| 5573 OneByteString& one_byte_str = OneByteString::Handle(); | 5625 String& result = String::Handle(); |
| 5574 one_byte_str ^= str.raw(); | 5626 intptr_t char_size = str.CharSize(); |
| 5575 return OneByteString::New(one_byte_str, space); | 5627 if (char_size == kOneByteChar) { |
| 5576 } else if (str.IsTwoByteString()) { | 5628 result ^= OneByteString::New(len, space); |
| 5577 TwoByteString& two_byte_str = TwoByteString::Handle(); | 5629 } else if (char_size == kTwoByteChar) { |
| 5578 two_byte_str ^= str.raw(); | 5630 result ^= TwoByteString::New(len, space); |
| 5579 return TwoByteString::New(two_byte_str, space); | 5631 } else { |
| 5632 ASSERT(char_size == kFourByteChar); |
| 5633 result ^= FourByteString::New(len, space); |
| 5580 } | 5634 } |
| 5581 ASSERT(str.IsFourByteString()); | 5635 String::Copy(result, 0, str, 0, len); |
| 5582 FourByteString& four_byte_str = FourByteString::Handle(); | 5636 return result.raw(); |
| 5583 four_byte_str ^= str.raw(); | |
| 5584 return FourByteString::New(four_byte_str, space); | |
| 5585 } | 5637 } |
| 5586 | 5638 |
| 5587 | 5639 |
| 5640 RawString* String::NewExternal(const uint8_t* characters, |
| 5641 intptr_t len, |
| 5642 void* peer, |
| 5643 Heap::Space space) { |
| 5644 return ExternalOneByteString::New(characters, len, peer, space); |
| 5645 } |
| 5646 |
| 5647 |
| 5648 RawString* String::NewExternal(const uint16_t* characters, |
| 5649 intptr_t len, |
| 5650 void* peer, |
| 5651 Heap::Space space) { |
| 5652 return ExternalTwoByteString::New(characters, len, peer, space); |
| 5653 } |
| 5654 |
| 5655 |
| 5656 RawString* String::NewExternal(const uint32_t* characters, |
| 5657 intptr_t len, |
| 5658 void* peer, |
| 5659 Heap::Space space) { |
| 5660 return ExternalFourByteString::New(characters, len, peer, space); |
| 5661 } |
| 5662 |
| 5663 |
| 5588 void String::Copy(const String& dst, intptr_t dst_offset, | 5664 void String::Copy(const String& dst, intptr_t dst_offset, |
| 5589 const uint8_t* characters, | 5665 const uint8_t* characters, |
| 5590 intptr_t len) { | 5666 intptr_t len) { |
| 5591 ASSERT(dst_offset >= 0); | 5667 ASSERT(dst_offset >= 0); |
| 5592 ASSERT(len >= 0); | 5668 ASSERT(len >= 0); |
| 5593 ASSERT(len <= (dst.Length() - dst_offset)); | 5669 ASSERT(len <= (dst.Length() - dst_offset)); |
| 5594 if (dst.IsOneByteString()) { | 5670 if (dst.IsOneByteString()) { |
| 5595 OneByteString& onestr = OneByteString::Handle(); | 5671 OneByteString& onestr = OneByteString::Handle(); |
| 5596 onestr ^= dst.raw(); | 5672 onestr ^= dst.raw(); |
| 5597 NoGCScope no_gc; | 5673 NoGCScope no_gc; |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5686 | 5762 |
| 5687 void String::Copy(const String& dst, intptr_t dst_offset, | 5763 void String::Copy(const String& dst, intptr_t dst_offset, |
| 5688 const String& src, intptr_t src_offset, | 5764 const String& src, intptr_t src_offset, |
| 5689 intptr_t len) { | 5765 intptr_t len) { |
| 5690 ASSERT(dst_offset >= 0); | 5766 ASSERT(dst_offset >= 0); |
| 5691 ASSERT(src_offset >= 0); | 5767 ASSERT(src_offset >= 0); |
| 5692 ASSERT(len >= 0); | 5768 ASSERT(len >= 0); |
| 5693 ASSERT(len <= (dst.Length() - dst_offset)); | 5769 ASSERT(len <= (dst.Length() - dst_offset)); |
| 5694 ASSERT(len <= (src.Length() - src_offset)); | 5770 ASSERT(len <= (src.Length() - src_offset)); |
| 5695 if (len > 0) { | 5771 if (len > 0) { |
| 5696 if (src.IsOneByteString()) { | 5772 intptr_t char_size = src.CharSize(); |
| 5697 OneByteString& onestr = OneByteString::Handle(); | 5773 if (char_size == kOneByteChar) { |
| 5698 onestr ^= src.raw(); | 5774 if (src.IsOneByteString()) { |
| 5699 NoGCScope no_gc; | 5775 OneByteString& onestr = OneByteString::Handle(); |
| 5700 String::Copy(dst, dst_offset, onestr.CharAddr(0) + src_offset, len); | 5776 onestr ^= src.raw(); |
| 5701 } else if (src.IsTwoByteString()) { | 5777 NoGCScope no_gc; |
| 5702 TwoByteString& twostr = TwoByteString::Handle(); | 5778 String::Copy(dst, dst_offset, onestr.CharAddr(0) + src_offset, len); |
| 5703 twostr ^= src.raw(); | 5779 } else { |
| 5704 NoGCScope no_gc; | 5780 ASSERT(src.IsExternalOneByteString()); |
| 5705 String::Copy(dst, dst_offset, twostr.CharAddr(0) + src_offset, len); | 5781 ExternalOneByteString& onestr = ExternalOneByteString::Handle(); |
| 5782 onestr ^= src.raw(); |
| 5783 NoGCScope no_gc; |
| 5784 String::Copy(dst, dst_offset, onestr.CharAddr(0) + src_offset, len); |
| 5785 } |
| 5786 } else if (char_size == kTwoByteChar) { |
| 5787 if (src.IsTwoByteString()) { |
| 5788 TwoByteString& twostr = TwoByteString::Handle(); |
| 5789 twostr ^= src.raw(); |
| 5790 NoGCScope no_gc; |
| 5791 String::Copy(dst, dst_offset, twostr.CharAddr(0) + src_offset, len); |
| 5792 } else { |
| 5793 ASSERT(src.IsExternalTwoByteString()); |
| 5794 ExternalTwoByteString& twostr = ExternalTwoByteString::Handle(); |
| 5795 twostr ^= src.raw(); |
| 5796 NoGCScope no_gc; |
| 5797 String::Copy(dst, dst_offset, twostr.CharAddr(0) + src_offset, len); |
| 5798 } |
| 5706 } else { | 5799 } else { |
| 5707 ASSERT(src.IsFourByteString()); | 5800 ASSERT(char_size == kFourByteChar); |
| 5708 FourByteString& fourstr = FourByteString::Handle(); | 5801 if (src.IsFourByteString()) { |
| 5709 fourstr ^= src.raw(); | 5802 FourByteString& fourstr = FourByteString::Handle(); |
| 5710 NoGCScope no_gc; | 5803 fourstr ^= src.raw(); |
| 5711 String::Copy(dst, dst_offset, fourstr.CharAddr(0) + src_offset, len); | 5804 NoGCScope no_gc; |
| 5805 String::Copy(dst, dst_offset, fourstr.CharAddr(0) + src_offset, len); |
| 5806 } else { |
| 5807 ASSERT(src.IsExternalFourByteString()); |
| 5808 ExternalFourByteString& fourstr = ExternalFourByteString::Handle(); |
| 5809 fourstr ^= src.raw(); |
| 5810 NoGCScope no_gc; |
| 5811 String::Copy(dst, dst_offset, fourstr.CharAddr(0) + src_offset, len); |
| 5812 } |
| 5712 } | 5813 } |
| 5713 } | 5814 } |
| 5714 } | 5815 } |
| 5715 | 5816 |
| 5716 | 5817 |
| 5717 static void GrowSymbolTable(const Array& symbol_table, intptr_t table_size) { | 5818 static void GrowSymbolTable(const Array& symbol_table, intptr_t table_size) { |
| 5718 // TODO(iposva): Avoid exponential growth. | 5819 // TODO(iposva): Avoid exponential growth. |
| 5719 intptr_t new_table_size = table_size * 2; | 5820 intptr_t new_table_size = table_size * 2; |
| 5720 Array& new_symbol_table = Array::Handle(Array::New(new_table_size + 1)); | 5821 Array& new_symbol_table = Array::Handle(Array::New(new_table_size + 1)); |
| 5721 // Copy all elements from the original symbol table to the newly allocated | 5822 // 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... |
| 5863 } | 5964 } |
| 5864 ASSERT(symbol.IsSymbol()); | 5965 ASSERT(symbol.IsSymbol()); |
| 5865 return symbol.raw(); | 5966 return symbol.raw(); |
| 5866 } | 5967 } |
| 5867 | 5968 |
| 5868 | 5969 |
| 5869 RawString* String::Concat(const String& str1, | 5970 RawString* String::Concat(const String& str1, |
| 5870 const String& str2, | 5971 const String& str2, |
| 5871 Heap::Space space) { | 5972 Heap::Space space) { |
| 5872 ASSERT(!str1.IsNull() && !str2.IsNull()); | 5973 ASSERT(!str1.IsNull() && !str2.IsNull()); |
| 5873 if (str1.IsFourByteString() || str2.IsFourByteString()) { | 5974 intptr_t char_size = Utils::Maximum(str1.CharSize(), str2.CharSize()); |
| 5975 if (char_size == kFourByteChar) { |
| 5874 return FourByteString::Concat(str1, str2, space); | 5976 return FourByteString::Concat(str1, str2, space); |
| 5875 } | 5977 } |
| 5876 if (str1.IsTwoByteString() || str2.IsTwoByteString()) { | 5978 if (char_size == kTwoByteChar) { |
| 5877 return TwoByteString::Concat(str1, str2, space); | 5979 return TwoByteString::Concat(str1, str2, space); |
| 5878 } | 5980 } |
| 5879 ASSERT(str1.IsOneByteString() && str2.IsOneByteString()); | |
| 5880 return OneByteString::Concat(str1, str2, space); | 5981 return OneByteString::Concat(str1, str2, space); |
| 5881 } | 5982 } |
| 5882 | 5983 |
| 5883 | 5984 |
| 5884 RawString* String::ConcatAll(const Array& strings, | 5985 RawString* String::ConcatAll(const Array& strings, |
| 5885 Heap::Space space) { | 5986 Heap::Space space) { |
| 5886 ASSERT(!strings.IsNull()); | 5987 ASSERT(!strings.IsNull()); |
| 5887 bool is_one_byte_string = true; | |
| 5888 bool is_two_byte_string = true; | |
| 5889 intptr_t result_len = 0; | 5988 intptr_t result_len = 0; |
| 5890 intptr_t strings_len = strings.Length(); | 5989 intptr_t strings_len = strings.Length(); |
| 5891 String& str = String::Handle(); | 5990 String& str = String::Handle(); |
| 5991 intptr_t char_size = kOneByteChar; |
| 5892 for (intptr_t i = 0; i < strings_len; i++) { | 5992 for (intptr_t i = 0; i < strings_len; i++) { |
| 5893 str ^= strings.At(i); | 5993 str ^= strings.At(i); |
| 5894 result_len += str.Length(); | 5994 result_len += str.Length(); |
| 5895 if (str.IsFourByteString()) { | 5995 char_size = Utils::Maximum(char_size, str.CharSize()); |
| 5896 is_one_byte_string = false; | |
| 5897 is_two_byte_string = false; | |
| 5898 } else if (str.IsTwoByteString()) { | |
| 5899 is_one_byte_string = false; | |
| 5900 } | |
| 5901 } | 5996 } |
| 5902 if (is_one_byte_string) { | 5997 if (char_size == kOneByteChar) { |
| 5903 return OneByteString::ConcatAll(strings, result_len, space); | 5998 return OneByteString::ConcatAll(strings, result_len, space); |
| 5904 } else if (is_two_byte_string) { | 5999 } else if (char_size == kTwoByteChar) { |
| 5905 return TwoByteString::ConcatAll(strings, result_len, space); | 6000 return TwoByteString::ConcatAll(strings, result_len, space); |
| 5906 } | 6001 } |
| 6002 ASSERT(char_size == kFourByteChar); |
| 5907 return FourByteString::ConcatAll(strings, result_len, space); | 6003 return FourByteString::ConcatAll(strings, result_len, space); |
| 5908 } | 6004 } |
| 5909 | 6005 |
| 5910 | 6006 |
| 5911 RawString* String::SubString(const String& str, | 6007 RawString* String::SubString(const String& str, |
| 5912 intptr_t begin_index, | 6008 intptr_t begin_index, |
| 5913 Heap::Space space) { | 6009 Heap::Space space) { |
| 5914 ASSERT(!str.IsNull()); | 6010 ASSERT(!str.IsNull()); |
| 5915 if (begin_index >= str.Length()) { | 6011 if (begin_index >= str.Length()) { |
| 5916 return String::null(); | 6012 return String::null(); |
| 5917 } | 6013 } |
| 5918 return String::SubString(str, begin_index, (str.Length() - begin_index)); | 6014 return String::SubString(str, begin_index, (str.Length() - begin_index)); |
| 5919 } | 6015 } |
| 5920 | 6016 |
| 5921 | 6017 |
| 5922 RawString* String::SubString(const String& str, | 6018 RawString* String::SubString(const String& str, |
| 5923 intptr_t begin_index, | 6019 intptr_t begin_index, |
| 5924 intptr_t length, | 6020 intptr_t length, |
| 5925 Heap::Space space) { | 6021 Heap::Space space) { |
| 5926 ASSERT(!str.IsNull()); | 6022 ASSERT(!str.IsNull()); |
| 5927 ASSERT(begin_index >= 0); | 6023 ASSERT(begin_index >= 0); |
| 5928 ASSERT(length >= 0); | 6024 ASSERT(length >= 0); |
| 5929 if (begin_index >= str.Length()) { | 6025 if (begin_index >= str.Length()) { |
| 5930 return String::null(); | 6026 return String::null(); |
| 5931 } | 6027 } |
| 5932 if (str.IsOneByteString()) { | 6028 String& result = String::Handle(); |
| 5933 OneByteString& obstr = OneByteString::Handle(); | 6029 bool is_one_byte_string = true; |
| 5934 obstr ^= str.raw(); | 6030 bool is_two_byte_string = true; |
| 5935 return OneByteString::SubString(obstr, begin_index, length, space); | 6031 intptr_t char_size = str.CharSize(); |
| 5936 } else if (str.IsTwoByteString()) { | 6032 if (char_size == kTwoByteChar) { |
| 5937 TwoByteString& twostr = TwoByteString::Handle(); | 6033 for (intptr_t i = begin_index; i < begin_index + length; ++i) { |
| 5938 twostr ^= str.raw(); | 6034 if (str.CharAt(i) > 0xFF) { |
| 5939 return TwoByteString::SubString(twostr, begin_index, length, space); | 6035 is_one_byte_string = false; |
| 6036 break; |
| 6037 } |
| 6038 } |
| 6039 } else if (char_size == kFourByteChar) { |
| 6040 for (intptr_t i = begin_index; i < begin_index + length; ++i) { |
| 6041 if (str.CharAt(i) > 0xFFFF) { |
| 6042 is_one_byte_string = false; |
| 6043 is_two_byte_string = false; |
| 6044 break; |
| 6045 } else if (str.CharAt(i) > 0xFF) { |
| 6046 is_one_byte_string = false; |
| 6047 } |
| 6048 } |
| 5940 } | 6049 } |
| 5941 ASSERT(str.IsFourByteString()); | 6050 if (is_one_byte_string) { |
| 5942 FourByteString& fourstr = FourByteString::Handle(); | 6051 result ^= OneByteString::New(length, space); |
| 5943 fourstr ^= str.raw(); | 6052 } else if (is_two_byte_string) { |
| 5944 return FourByteString::SubString(fourstr, begin_index, length, space); | 6053 result ^= TwoByteString::New(length, space); |
| 6054 } else { |
| 6055 result ^= FourByteString::New(length, space); |
| 6056 } |
| 6057 String::Copy(result, 0, str, begin_index, length); |
| 6058 return result.raw(); |
| 5945 } | 6059 } |
| 5946 | 6060 |
| 5947 | 6061 |
| 5948 const char* String::ToCString() const { | 6062 const char* String::ToCString() const { |
| 5949 intptr_t len = Utf8::Length(*this); | 6063 intptr_t len = Utf8::Length(*this); |
| 5950 Zone* zone = Isolate::Current()->current_zone(); | 6064 Zone* zone = Isolate::Current()->current_zone(); |
| 5951 char* result = reinterpret_cast<char*>(zone->Allocate(len + 1)); | 6065 char* result = reinterpret_cast<char*>(zone->Allocate(len + 1)); |
| 5952 Utf8::Encode(*this, result, len); | 6066 Utf8::Encode(*this, result, len); |
| 5953 result[len] = 0; | 6067 result[len] = 0; |
| 5954 return result; | 6068 return result; |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6082 for (intptr_t i = 0; i < strings_len; i++) { | 6196 for (intptr_t i = 0; i < strings_len; i++) { |
| 6083 str ^= strings.At(i); | 6197 str ^= strings.At(i); |
| 6084 intptr_t str_len = str.Length(); | 6198 intptr_t str_len = str.Length(); |
| 6085 String::Copy(result, pos, str, 0, str_len); | 6199 String::Copy(result, pos, str, 0, str_len); |
| 6086 pos += str_len; | 6200 pos += str_len; |
| 6087 } | 6201 } |
| 6088 return result.raw(); | 6202 return result.raw(); |
| 6089 } | 6203 } |
| 6090 | 6204 |
| 6091 | 6205 |
| 6092 RawString* OneByteString::SubString(const OneByteString& str, | |
| 6093 intptr_t begin_index, | |
| 6094 intptr_t length, | |
| 6095 Heap::Space space) { | |
| 6096 ASSERT(!str.IsNull()); | |
| 6097 ASSERT(begin_index < str.Length()); | |
| 6098 OneByteString& result = OneByteString::Handle(); | |
| 6099 if (length <= (str.Length() - begin_index)) { | |
| 6100 result ^= OneByteString::New(length, space); | |
| 6101 String::Copy(result, 0, str, begin_index, length); | |
| 6102 } | |
| 6103 // TODO(5418937): return a non-null object on error. | |
| 6104 return result.raw(); | |
| 6105 } | |
| 6106 | |
| 6107 | |
| 6108 RawOneByteString* OneByteString::Transform(int32_t (*mapping)(int32_t ch), | 6206 RawOneByteString* OneByteString::Transform(int32_t (*mapping)(int32_t ch), |
| 6109 const String& str, | 6207 const String& str, |
| 6110 Heap::Space space) { | 6208 Heap::Space space) { |
| 6111 ASSERT(!str.IsNull()); | 6209 ASSERT(!str.IsNull()); |
| 6112 intptr_t len = str.Length(); | 6210 intptr_t len = str.Length(); |
| 6113 const OneByteString& result = | 6211 const OneByteString& result = |
| 6114 OneByteString::Handle(OneByteString::New(len, space)); | 6212 OneByteString::Handle(OneByteString::New(len, space)); |
| 6115 for (intptr_t i = 0; i < len; ++i) { | 6213 for (intptr_t i = 0; i < len; ++i) { |
| 6116 int32_t ch = mapping(str.CharAt(i)); | 6214 int32_t ch = mapping(str.CharAt(i)); |
| 6117 ASSERT(ch >= 0 && ch <= 0xFF); | 6215 ASSERT(ch >= 0 && ch <= 0xFF); |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6201 for (intptr_t i = 0; i < strings_len; i++) { | 6299 for (intptr_t i = 0; i < strings_len; i++) { |
| 6202 str ^= strings.At(i); | 6300 str ^= strings.At(i); |
| 6203 intptr_t str_len = str.Length(); | 6301 intptr_t str_len = str.Length(); |
| 6204 String::Copy(result, pos, str, 0, str_len); | 6302 String::Copy(result, pos, str, 0, str_len); |
| 6205 pos += str_len; | 6303 pos += str_len; |
| 6206 } | 6304 } |
| 6207 return result.raw(); | 6305 return result.raw(); |
| 6208 } | 6306 } |
| 6209 | 6307 |
| 6210 | 6308 |
| 6211 RawString* TwoByteString::SubString(const TwoByteString& str, | |
| 6212 intptr_t begin_index, | |
| 6213 intptr_t length, | |
| 6214 Heap::Space space) { | |
| 6215 ASSERT(!str.IsNull()); | |
| 6216 ASSERT(begin_index < str.Length()); | |
| 6217 String& result = String::Handle(); | |
| 6218 if (length <= (str.Length() - begin_index)) { | |
| 6219 bool is_one_byte_string = true; | |
| 6220 for (intptr_t i = begin_index; i < begin_index + length; ++i) { | |
| 6221 if (str.CharAt(i) > 0xFF) { | |
| 6222 is_one_byte_string = false; | |
| 6223 break; | |
| 6224 } | |
| 6225 } | |
| 6226 if (is_one_byte_string) { | |
| 6227 result ^= OneByteString::New(length, space); | |
| 6228 } else { | |
| 6229 result ^= TwoByteString::New(length, space); | |
| 6230 } | |
| 6231 String::Copy(result, 0, str, begin_index, length); | |
| 6232 } | |
| 6233 // TODO(5418937): return a non-null object on error. | |
| 6234 return result.raw(); | |
| 6235 } | |
| 6236 | |
| 6237 | |
| 6238 RawTwoByteString* TwoByteString::Transform(int32_t (*mapping)(int32_t ch), | 6309 RawTwoByteString* TwoByteString::Transform(int32_t (*mapping)(int32_t ch), |
| 6239 const String& str, | 6310 const String& str, |
| 6240 Heap::Space space) { | 6311 Heap::Space space) { |
| 6241 ASSERT(!str.IsNull()); | 6312 ASSERT(!str.IsNull()); |
| 6242 intptr_t len = str.Length(); | 6313 intptr_t len = str.Length(); |
| 6243 const TwoByteString& result = | 6314 const TwoByteString& result = |
| 6244 TwoByteString::Handle(TwoByteString::New(len, space)); | 6315 TwoByteString::Handle(TwoByteString::New(len, space)); |
| 6245 for (intptr_t i = 0; i < len; ++i) { | 6316 for (intptr_t i = 0; i < len; ++i) { |
| 6246 int32_t ch = mapping(str.CharAt(i)); | 6317 int32_t ch = mapping(str.CharAt(i)); |
| 6247 ASSERT(ch >= 0 && ch <= 0xFFFF); | 6318 ASSERT(ch >= 0 && ch <= 0xFFFF); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6319 str ^= strings.At(i); | 6390 str ^= strings.At(i); |
| 6320 intptr_t str_len = str.Length(); | 6391 intptr_t str_len = str.Length(); |
| 6321 String::Copy(result, pos, str, 0, str_len); | 6392 String::Copy(result, pos, str, 0, str_len); |
| 6322 pos += str_len; | 6393 pos += str_len; |
| 6323 } | 6394 } |
| 6324 } | 6395 } |
| 6325 return result.raw(); | 6396 return result.raw(); |
| 6326 } | 6397 } |
| 6327 | 6398 |
| 6328 | 6399 |
| 6329 RawString* FourByteString::SubString(const FourByteString& str, | |
| 6330 intptr_t begin_index, | |
| 6331 intptr_t length, | |
| 6332 Heap::Space space) { | |
| 6333 ASSERT(!str.IsNull()); | |
| 6334 ASSERT(begin_index < str.Length()); | |
| 6335 String& result = String::Handle(); | |
| 6336 if (length <= (str.Length() - begin_index)) { | |
| 6337 bool is_one_byte_string = true; | |
| 6338 bool is_two_byte_string = true; | |
| 6339 for (intptr_t i = begin_index; i < begin_index + length; ++i) { | |
| 6340 if (str.CharAt(i) > 0xFFFF) { | |
| 6341 is_one_byte_string = false; | |
| 6342 is_two_byte_string = false; | |
| 6343 break; | |
| 6344 } else if (str.CharAt(i) > 0xFF) { | |
| 6345 is_one_byte_string = false; | |
| 6346 } | |
| 6347 } | |
| 6348 if (is_one_byte_string) { | |
| 6349 result ^= OneByteString::New(length, space); | |
| 6350 } else if (is_two_byte_string) { | |
| 6351 result ^= TwoByteString::New(length, space); | |
| 6352 } else { | |
| 6353 result ^= FourByteString::New(length, space); | |
| 6354 } | |
| 6355 String::Copy(result, 0, str, begin_index, length); | |
| 6356 } | |
| 6357 // TODO(5418937): return a non-null object on error. | |
| 6358 return result.raw(); | |
| 6359 } | |
| 6360 | |
| 6361 | |
| 6362 RawFourByteString* FourByteString::Transform(int32_t (*mapping)(int32_t ch), | 6400 RawFourByteString* FourByteString::Transform(int32_t (*mapping)(int32_t ch), |
| 6363 const String& str, | 6401 const String& str, |
| 6364 Heap::Space space) { | 6402 Heap::Space space) { |
| 6365 ASSERT(!str.IsNull()); | 6403 ASSERT(!str.IsNull()); |
| 6366 intptr_t len = str.Length(); | 6404 intptr_t len = str.Length(); |
| 6367 const FourByteString& result = | 6405 const FourByteString& result = |
| 6368 FourByteString::Handle(FourByteString::New(len, space)); | 6406 FourByteString::Handle(FourByteString::New(len, space)); |
| 6369 for (intptr_t i = 0; i < len; ++i) { | 6407 for (intptr_t i = 0; i < len; ++i) { |
| 6370 int32_t ch = mapping(str.CharAt(i)); | 6408 int32_t ch = mapping(str.CharAt(i)); |
| 6371 ASSERT(ch >= 0 && ch <= 0x10FFFF); | 6409 ASSERT(ch >= 0 && ch <= 0x10FFFF); |
| 6372 *result.CharAddr(i) = ch; | 6410 *result.CharAddr(i) = ch; |
| 6373 } | 6411 } |
| 6374 return result.raw(); | 6412 return result.raw(); |
| 6375 } | 6413 } |
| 6376 | 6414 |
| 6377 | 6415 |
| 6378 const char* FourByteString::ToCString() const { | 6416 const char* FourByteString::ToCString() const { |
| 6379 return String::ToCString(); | 6417 return String::ToCString(); |
| 6380 } | 6418 } |
| 6381 | 6419 |
| 6382 | 6420 |
| 6421 RawExternalOneByteString* ExternalOneByteString::New(const uint8_t* data, |
| 6422 intptr_t len, |
| 6423 void* peer, |
| 6424 Heap::Space space) { |
| 6425 Isolate* isolate = Isolate::Current(); |
| 6426 |
| 6427 const Class& cls = |
| 6428 Class::Handle(isolate->object_store()->external_one_byte_string_class()); |
| 6429 ExternalOneByteString& result = ExternalOneByteString::Handle(); |
| 6430 { |
| 6431 RawObject* raw = Object::Allocate(cls, |
| 6432 ExternalOneByteString::InstanceSize(), |
| 6433 space); |
| 6434 NoGCScope no_gc; |
| 6435 result ^= raw; |
| 6436 result.SetLength(len); |
| 6437 result.SetHash(0); |
| 6438 result.SetData(data); |
| 6439 result.SetPeer(peer); |
| 6440 } |
| 6441 return result.raw(); |
| 6442 } |
| 6443 |
| 6444 |
| 6445 const char* ExternalOneByteString::ToCString() const { |
| 6446 return String::ToCString(); |
| 6447 } |
| 6448 |
| 6449 |
| 6450 RawExternalTwoByteString* ExternalTwoByteString::New(const uint16_t* data, |
| 6451 intptr_t len, |
| 6452 void* peer, |
| 6453 Heap::Space space) { |
| 6454 Isolate* isolate = Isolate::Current(); |
| 6455 |
| 6456 const Class& cls = |
| 6457 Class::Handle(isolate->object_store()->external_two_byte_string_class()); |
| 6458 ExternalTwoByteString& result = ExternalTwoByteString::Handle(); |
| 6459 { |
| 6460 RawObject* raw = Object::Allocate(cls, |
| 6461 ExternalTwoByteString::InstanceSize(), |
| 6462 space); |
| 6463 NoGCScope no_gc; |
| 6464 result ^= raw; |
| 6465 result.SetLength(len); |
| 6466 result.SetHash(0); |
| 6467 result.SetData(data); |
| 6468 result.SetPeer(peer); |
| 6469 } |
| 6470 return result.raw(); |
| 6471 } |
| 6472 |
| 6473 |
| 6474 const char* ExternalTwoByteString::ToCString() const { |
| 6475 return String::ToCString(); |
| 6476 } |
| 6477 |
| 6478 |
| 6479 RawExternalFourByteString* ExternalFourByteString::New(const uint32_t* data, |
| 6480 intptr_t len, |
| 6481 void* peer, |
| 6482 Heap::Space space) { |
| 6483 Isolate* isolate = Isolate::Current(); |
| 6484 |
| 6485 const Class& cls = |
| 6486 Class::Handle(isolate->object_store()->external_four_byte_string_class()); |
| 6487 ExternalFourByteString& result = ExternalFourByteString::Handle(); |
| 6488 { |
| 6489 RawObject* raw = Object::Allocate(cls, |
| 6490 ExternalFourByteString::InstanceSize(), |
| 6491 space); |
| 6492 NoGCScope no_gc; |
| 6493 result ^= raw; |
| 6494 result.SetLength(len); |
| 6495 result.SetHash(0); |
| 6496 result.SetData(data); |
| 6497 result.SetPeer(peer); |
| 6498 } |
| 6499 return result.raw(); |
| 6500 } |
| 6501 |
| 6502 |
| 6503 const char* ExternalFourByteString::ToCString() const { |
| 6504 return String::ToCString(); |
| 6505 } |
| 6506 |
| 6507 |
| 6383 RawBool* Bool::True() { | 6508 RawBool* Bool::True() { |
| 6384 return Isolate::Current()->object_store()->true_value(); | 6509 return Isolate::Current()->object_store()->true_value(); |
| 6385 } | 6510 } |
| 6386 | 6511 |
| 6387 | 6512 |
| 6388 RawBool* Bool::False() { | 6513 RawBool* Bool::False() { |
| 6389 return Isolate::Current()->object_store()->false_value(); | 6514 return Isolate::Current()->object_store()->false_value(); |
| 6390 } | 6515 } |
| 6391 | 6516 |
| 6392 | 6517 |
| (...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6806 const String& str = String::Handle(pattern()); | 6931 const String& str = String::Handle(pattern()); |
| 6807 const char* format = "JSRegExp: pattern=%s flags=%s"; | 6932 const char* format = "JSRegExp: pattern=%s flags=%s"; |
| 6808 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); | 6933 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); |
| 6809 char* chars = reinterpret_cast<char*>( | 6934 char* chars = reinterpret_cast<char*>( |
| 6810 Isolate::Current()->current_zone()->Allocate(len + 1)); | 6935 Isolate::Current()->current_zone()->Allocate(len + 1)); |
| 6811 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); | 6936 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); |
| 6812 return chars; | 6937 return chars; |
| 6813 } | 6938 } |
| 6814 | 6939 |
| 6815 } // namespace dart | 6940 } // namespace dart |
| OLD | NEW |