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

Side by Side Diff: runtime/vm/object.cc

Issue 8383029: Implement external strings. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fully displace external string metadata Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698