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

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

Issue 11368138: Add some support for the code-point code-unit distinction. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/object.h" 5 #include "vm/object.h"
6 6
7 #include "include/dart_api.h" 7 #include "include/dart_api.h"
8 #include "platform/assert.h" 8 #include "platform/assert.h"
9 #include "vm/assembler.h" 9 #include "vm/assembler.h"
10 #include "vm/bigint_operations.h" 10 #include "vm/bigint_operations.h"
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 // _MyClass@6b3832b.named -> _MyClass.named 134 // _MyClass@6b3832b.named -> _MyClass.named
135 // 135 //
136 static RawString* IdentifierPrettyName(const String& name) { 136 static RawString* IdentifierPrettyName(const String& name) {
137 intptr_t len = name.Length(); 137 intptr_t len = name.Length();
138 intptr_t start = 0; 138 intptr_t start = 0;
139 intptr_t at_pos = len; // Position of '@' in the name. 139 intptr_t at_pos = len; // Position of '@' in the name.
140 intptr_t dot_pos = len; // Position of '.' in the name. 140 intptr_t dot_pos = len; // Position of '.' in the name.
141 bool is_setter = false; 141 bool is_setter = false;
142 142
143 for (int i = 0; i < name.Length(); i++) { 143 for (int i = 0; i < name.Length(); i++) {
144 if (name.CharAt(i) == ':') { 144 if (name.CodeUnitAt(i) == ':') {
145 ASSERT(start == 0); 145 ASSERT(start == 0);
146 if (name.CharAt(0) == 's') { 146 if (name.CodeUnitAt(0) == 's') {
147 is_setter = true; 147 is_setter = true;
148 } 148 }
149 start = i + 1; 149 start = i + 1;
150 } else if (name.CharAt(i) == '@') { 150 } else if (name.CodeUnitAt(i) == '@') {
151 ASSERT(at_pos == len); 151 ASSERT(at_pos == len);
152 at_pos = i; 152 at_pos = i;
153 } else if (name.CharAt(i) == '.') { 153 } else if (name.CodeUnitAt(i) == '.') {
154 dot_pos = i; 154 dot_pos = i;
155 break; 155 break;
156 } 156 }
157 } 157 }
158 intptr_t limit = (at_pos < dot_pos ? at_pos : dot_pos); 158 intptr_t limit = (at_pos < dot_pos ? at_pos : dot_pos);
159 if (start == 0 && limit == len) { 159 if (start == 0 && limit == len) {
160 // This name is fine as it is. 160 // This name is fine as it is.
161 return name.raw(); 161 return name.raw();
162 } 162 }
163 163
164 const String& result = 164 const String& result =
165 String::Handle(String::SubString(name, start, (limit - start))); 165 String::Handle(String::SubString(name, start, (limit - start)));
166 166
167 // Look for a second '@' now to correctly handle names like 167 // Look for a second '@' now to correctly handle names like
168 // "_ReceivePortImpl@6be832b._internal@6be832b". 168 // "_ReceivePortImpl@6be832b._internal@6be832b".
169 at_pos = len; 169 at_pos = len;
170 for (int i = dot_pos; i < name.Length(); i++) { 170 for (int i = dot_pos; i < name.Length(); i++) {
171 if (name.CharAt(i) == '@') { 171 if (name.CodeUnitAt(i) == '@') {
172 ASSERT(at_pos == len); 172 ASSERT(at_pos == len);
173 at_pos = i; 173 at_pos = i;
174 } 174 }
175 } 175 }
176 176
177 intptr_t suffix_len = at_pos - dot_pos; 177 intptr_t suffix_len = at_pos - dot_pos;
178 if (suffix_len > 1) { 178 if (suffix_len > 1) {
179 // This is a named constructor. Add the name back to the string. 179 // This is a named constructor. Add the name back to the string.
180 const String& suffix = 180 const String& suffix =
181 String::Handle(String::SubString(name, dot_pos, suffix_len)); 181 String::Handle(String::SubString(name, dot_pos, suffix_len));
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after
482 Class::NewInterface(name, script, Scanner::kDummyTokenIndex)); 482 Class::NewInterface(name, script, Scanner::kDummyTokenIndex));
483 lib.AddClass(cls); 483 lib.AddClass(cls);
484 return cls.raw(); 484 return cls.raw();
485 } 485 }
486 486
487 487
488 void Object::RegisterClass(const Class& cls, 488 void Object::RegisterClass(const Class& cls,
489 const String& name, 489 const String& name,
490 const Library& lib) { 490 const Library& lib) {
491 ASSERT(name.Length() > 0); 491 ASSERT(name.Length() > 0);
492 ASSERT(name.CharAt(0) != '_'); 492 ASSERT(name.CodeUnitAt(0) != '_');
493 cls.set_name(name); 493 cls.set_name(name);
494 lib.AddClass(cls); 494 lib.AddClass(cls);
495 } 495 }
496 496
497 497
498 void Object::RegisterPrivateClass(const Class& cls, 498 void Object::RegisterPrivateClass(const Class& cls,
499 const String& public_class_name, 499 const String& public_class_name,
500 const Library& lib) { 500 const Library& lib) {
501 ASSERT(public_class_name.Length() > 0); 501 ASSERT(public_class_name.Length() > 0);
502 ASSERT(public_class_name.CharAt(0) == '_'); 502 ASSERT(public_class_name.CodeUnitAt(0) == '_');
503 String& str = String::Handle(); 503 String& str = String::Handle();
504 str = lib.PrivateName(public_class_name); 504 str = lib.PrivateName(public_class_name);
505 cls.set_name(str); 505 cls.set_name(str);
506 lib.AddClass(cls); 506 lib.AddClass(cls);
507 } 507 }
508 508
509 509
510 RawError* Object::Init(Isolate* isolate) { 510 RawError* Object::Init(Isolate* isolate) {
511 TIMERSCOPE(time_bootstrap); 511 TIMERSCOPE(time_bootstrap);
512 ObjectStore* object_store = isolate->object_store(); 512 ObjectStore* object_store = isolate->object_store();
(...skipping 1678 matching lines...) Expand 10 before | Expand all | Expand 10 after
2191 const char* prefix, 2191 const char* prefix,
2192 intptr_t prefix_length, 2192 intptr_t prefix_length,
2193 const String& accessor_name) { 2193 const String& accessor_name) {
2194 intptr_t name_len = name.Length(); 2194 intptr_t name_len = name.Length();
2195 intptr_t accessor_name_len = accessor_name.Length(); 2195 intptr_t accessor_name_len = accessor_name.Length();
2196 2196
2197 if (name_len != (accessor_name_len + prefix_length)) { 2197 if (name_len != (accessor_name_len + prefix_length)) {
2198 return false; 2198 return false;
2199 } 2199 }
2200 for (intptr_t i = 0; i < prefix_length; i++) { 2200 for (intptr_t i = 0; i < prefix_length; i++) {
2201 if (name.CharAt(i) != prefix[i]) { 2201 if (name.CodeUnitAt(i) != static_cast<uint32_t>(prefix[i])) {
2202 return false; 2202 return false;
2203 } 2203 }
2204 } 2204 }
2205 for (intptr_t i = 0, j = prefix_length; i < accessor_name_len; i++, j++) { 2205 for (intptr_t i = 0, j = prefix_length; i < accessor_name_len; i++, j++) {
2206 if (name.CharAt(j) != accessor_name.CharAt(i)) { 2206 if (name.CodeUnitAt(j) != accessor_name.CodeUnitAt(i)) {
2207 return false; 2207 return false;
2208 } 2208 }
2209 } 2209 }
2210 return true; 2210 return true;
2211 } 2211 }
2212 2212
2213 2213
2214 RawFunction* Class::LookupFunction(const String& name) const { 2214 RawFunction* Class::LookupFunction(const String& name) const {
2215 Isolate* isolate = Isolate::Current(); 2215 Isolate* isolate = Isolate::Current();
2216 ASSERT(name.IsOneByteString()); 2216 ASSERT(name.IsOneByteString());
(...skipping 2238 matching lines...) Expand 10 before | Expand all | Expand 10 after
4455 literal = iterator.MakeLiteralToken(obj); 4455 literal = iterator.MakeLiteralToken(obj);
4456 // Advance to be able to use next token kind. 4456 // Advance to be able to use next token kind.
4457 iterator.Advance(); 4457 iterator.Advance();
4458 Token::Kind next = iterator.CurrentTokenKind(); 4458 Token::Kind next = iterator.CurrentTokenKind();
4459 4459
4460 // Handle the current token. 4460 // Handle the current token.
4461 if (curr == Token::kSTRING) { 4461 if (curr == Token::kSTRING) {
4462 bool is_raw_string = false; 4462 bool is_raw_string = false;
4463 bool escape_characters = false; 4463 bool escape_characters = false;
4464 for (intptr_t i = 0; i < literal.Length(); i++) { 4464 for (intptr_t i = 0; i < literal.Length(); i++) {
4465 if (IsSpecialCharacter(literal.CharAt(i))) { 4465 if (IsSpecialCharacter(literal.CodeUnitAt(i))) {
4466 escape_characters = true; 4466 escape_characters = true;
4467 } 4467 }
4468 // TODO(4995): Temp solution for raw strings, this will break 4468 // TODO(4995): Temp solution for raw strings, this will break
4469 // if we saw a string that is not a raw string but has back slashes 4469 // if we saw a string that is not a raw string but has back slashes
4470 // in it. 4470 // in it.
4471 if ((literal.CharAt(i) == '\\')) { 4471 if ((literal.CodeUnitAt(i) == '\\')) {
4472 if ((next != Token::kINTERPOL_VAR) && 4472 if ((next != Token::kINTERPOL_VAR) &&
4473 (next != Token::kINTERPOL_START) && 4473 (next != Token::kINTERPOL_START) &&
4474 (prev != Token::kINTERPOL_VAR) && 4474 (prev != Token::kINTERPOL_VAR) &&
4475 (prev != Token::kINTERPOL_END)) { 4475 (prev != Token::kINTERPOL_END)) {
4476 is_raw_string = true; 4476 is_raw_string = true;
4477 } else { 4477 } else {
4478 escape_characters = true; 4478 escape_characters = true;
4479 } 4479 }
4480 } 4480 }
4481 } 4481 }
4482 if ((prev != Token::kINTERPOL_VAR) && (prev != Token::kINTERPOL_END)) { 4482 if ((prev != Token::kINTERPOL_VAR) && (prev != Token::kINTERPOL_END)) {
4483 if (is_raw_string) { 4483 if (is_raw_string) {
4484 literals.Add(raw_string); 4484 literals.Add(raw_string);
4485 } 4485 }
4486 literals.Add(double_quotes); 4486 literals.Add(double_quotes);
4487 } 4487 }
4488 if (escape_characters) { 4488 if (escape_characters) {
4489 literal = String::EscapeSpecialCharacters(literal, is_raw_string); 4489 literal = String::EscapeSpecialCharacters(literal, is_raw_string);
4490 literals.Add(literal); 4490 literals.Add(literal);
4491 } else { 4491 } else {
4492 literals.Add(literal); 4492 literals.Add(literal);
4493 } 4493 }
4494 if ((next != Token::kINTERPOL_VAR) && (next != Token::kINTERPOL_START)) { 4494 if ((next != Token::kINTERPOL_VAR) && (next != Token::kINTERPOL_START)) {
4495 literals.Add(double_quotes); 4495 literals.Add(double_quotes);
4496 } 4496 }
4497 } else if (curr == Token::kINTERPOL_VAR) { 4497 } else if (curr == Token::kINTERPOL_VAR) {
4498 literals.Add(dollar); 4498 literals.Add(dollar);
4499 if (literal.CharAt(0) == Scanner::kPrivateIdentifierStart) { 4499 if (literal.CodeUnitAt(0) == Scanner::kPrivateIdentifierStart) {
4500 literal = String::SubString(literal, 0, literal.Length() - private_len); 4500 literal = String::SubString(literal, 0, literal.Length() - private_len);
4501 } 4501 }
4502 literals.Add(literal); 4502 literals.Add(literal);
4503 } else if (curr == Token::kIDENT) { 4503 } else if (curr == Token::kIDENT) {
4504 if (literal.CharAt(0) == Scanner::kPrivateIdentifierStart) { 4504 if (literal.CodeUnitAt(0) == Scanner::kPrivateIdentifierStart) {
4505 literal = String::SubString(literal, 0, literal.Length() - private_len); 4505 literal = String::SubString(literal, 0, literal.Length() - private_len);
4506 } 4506 }
4507 literals.Add(literal); 4507 literals.Add(literal);
4508 } else { 4508 } else {
4509 literals.Add(literal); 4509 literals.Add(literal);
4510 } 4510 }
4511 // Determine the separation text based on this current token. 4511 // Determine the separation text based on this current token.
4512 const String* separator = NULL; 4512 const String* separator = NULL;
4513 switch (curr) { 4513 switch (curr) {
4514 case Token::kLBRACE: 4514 case Token::kLBRACE:
(...skipping 523 matching lines...) Expand 10 before | Expand all | Expand 10 after
5038 const String& src = String::Handle(Source()); 5038 const String& src = String::Handle(Source());
5039 intptr_t current_line = 1; 5039 intptr_t current_line = 1;
5040 intptr_t line_start = -1; 5040 intptr_t line_start = -1;
5041 intptr_t last_char = -1; 5041 intptr_t last_char = -1;
5042 for (intptr_t ix = 0; 5042 for (intptr_t ix = 0;
5043 (ix < src.Length()) && (current_line <= line_number); 5043 (ix < src.Length()) && (current_line <= line_number);
5044 ix++) { 5044 ix++) {
5045 if ((current_line == line_number) && (line_start < 0)) { 5045 if ((current_line == line_number) && (line_start < 0)) {
5046 line_start = ix; 5046 line_start = ix;
5047 } 5047 }
5048 if (src.CharAt(ix) == '\n') { 5048 if (src.CodeUnitAt(ix) == '\n') {
5049 current_line++; 5049 current_line++;
5050 } else if (src.CharAt(ix) == '\r') { 5050 } else if (src.CodeUnitAt(ix) == '\r') {
5051 if ((ix + 1 != src.Length()) && (src.CharAt(ix + 1) != '\n')) { 5051 if ((ix + 1 != src.Length()) && (src.CodeUnitAt(ix + 1) != '\n')) {
5052 current_line++; 5052 current_line++;
5053 } 5053 }
5054 } else { 5054 } else {
5055 last_char = ix; 5055 last_char = ix;
5056 } 5056 }
5057 } 5057 }
5058 // Guarantee that returned string is never NULL. 5058 // Guarantee that returned string is never NULL.
5059 String& line = String::Handle(Symbols::Empty()); 5059 String& line = String::Handle(Symbols::Empty());
5060 if (line_start >= 0) { 5060 if (line_start >= 0) {
5061 line = String::SubString(src, line_start, last_char - line_start + 1); 5061 line = String::SubString(src, line_start, last_char - line_start + 1);
5062 } 5062 }
5063 return line.raw(); 5063 return line.raw();
5064 } 5064 }
5065 5065
5066 5066
5067 RawString* Script::GetSnippet(intptr_t from_line, 5067 RawString* Script::GetSnippet(intptr_t from_line,
5068 intptr_t from_column, 5068 intptr_t from_column,
5069 intptr_t to_line, 5069 intptr_t to_line,
5070 intptr_t to_column) const { 5070 intptr_t to_column) const {
5071 const String& src = String::Handle(Source()); 5071 const String& src = String::Handle(Source());
5072 intptr_t length = src.Length(); 5072 intptr_t length = src.Length();
5073 intptr_t line = 1; 5073 intptr_t line = 1;
5074 intptr_t column = 1; 5074 intptr_t column = 1;
5075 intptr_t lookahead = 0; 5075 intptr_t lookahead = 0;
5076 intptr_t snippet_start = -1; 5076 intptr_t snippet_start = -1;
5077 intptr_t snippet_end = -1; 5077 intptr_t snippet_end = -1;
5078 char c = src.CharAt(lookahead); 5078 char c = src.CodeUnitAt(lookahead);
5079 while (lookahead != length) { 5079 while (lookahead != length) {
5080 if (snippet_start == -1) { 5080 if (snippet_start == -1) {
5081 if ((line == from_line) && (column == from_column)) { 5081 if ((line == from_line) && (column == from_column)) {
5082 snippet_start = lookahead; 5082 snippet_start = lookahead;
5083 } 5083 }
5084 } else if ((line == to_line) && (column == to_column)) { 5084 } else if ((line == to_line) && (column == to_column)) {
5085 snippet_end = lookahead; 5085 snippet_end = lookahead;
5086 break; 5086 break;
5087 } 5087 }
5088 if (c == '\n') { 5088 if (c == '\n') {
5089 line++; 5089 line++;
5090 column = 0; 5090 column = 0;
5091 } 5091 }
5092 column++; 5092 column++;
5093 lookahead++; 5093 lookahead++;
5094 if (lookahead != length) { 5094 if (lookahead != length) {
5095 // Replace '\r' with '\n' and a sequence of '\r' '\n' with a single '\n'. 5095 // Replace '\r' with '\n' and a sequence of '\r' '\n' with a single '\n'.
5096 if (src.CharAt(lookahead) == '\r') { 5096 if (src.CodeUnitAt(lookahead) == '\r') {
5097 c = '\n'; 5097 c = '\n';
5098 if (lookahead + 1 != length && src.CharAt(lookahead) == '\n') { 5098 if (lookahead + 1 != length && src.CodeUnitAt(lookahead) == '\n') {
5099 lookahead++; 5099 lookahead++;
5100 } 5100 }
5101 } else { 5101 } else {
5102 c = src.CharAt(lookahead); 5102 c = src.CodeUnitAt(lookahead);
5103 } 5103 }
5104 } 5104 }
5105 } 5105 }
5106 String& snippet = String::Handle(); 5106 String& snippet = String::Handle();
5107 if ((snippet_start != -1) && (snippet_end != -1)) { 5107 if ((snippet_start != -1) && (snippet_end != -1)) {
5108 snippet = 5108 snippet =
5109 String::SubString(src, snippet_start, snippet_end - snippet_start); 5109 String::SubString(src, snippet_start, snippet_end - snippet_start);
5110 } 5110 }
5111 return snippet.raw(); 5111 return snippet.raw();
5112 } 5112 }
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after
5492 5492
5493 RawObject* Library::LookupLocalObject(const String& name) const { 5493 RawObject* Library::LookupLocalObject(const String& name) const {
5494 intptr_t index; 5494 intptr_t index;
5495 return LookupEntry(name, &index); 5495 return LookupEntry(name, &index);
5496 } 5496 }
5497 5497
5498 5498
5499 static bool ShouldBePrivate(const String& name) { 5499 static bool ShouldBePrivate(const String& name) {
5500 return 5500 return
5501 (name.Length() >= 1 && 5501 (name.Length() >= 1 &&
5502 name.CharAt(0) == '_') || 5502 name.CodeUnitAt(0) == '_') ||
5503 (name.Length() >= 5 && 5503 (name.Length() >= 5 &&
5504 (name.CharAt(4) == '_' && 5504 (name.CodeUnitAt(4) == '_' &&
5505 (name.CharAt(0) == 'g' || name.CharAt(0) == 's') && 5505 (name.CodeUnitAt(0) == 'g' || name.CodeUnitAt(0) == 's') &&
5506 name.CharAt(1) == 'e' && 5506 name.CodeUnitAt(1) == 'e' &&
5507 name.CharAt(2) == 't' && 5507 name.CodeUnitAt(2) == 't' &&
5508 name.CharAt(3) == ':')); 5508 name.CodeUnitAt(3) == ':'));
5509 } 5509 }
5510 5510
5511 5511
5512 RawField* Library::LookupFieldAllowPrivate(const String& name) const { 5512 RawField* Library::LookupFieldAllowPrivate(const String& name) const {
5513 // First check if name is found in the local scope of the library. 5513 // First check if name is found in the local scope of the library.
5514 Field& field = Field::Handle(LookupLocalField(name)); 5514 Field& field = Field::Handle(LookupLocalField(name));
5515 if (!field.IsNull()) { 5515 if (!field.IsNull()) {
5516 return field.raw(); 5516 return field.raw();
5517 } 5517 }
5518 5518
(...skipping 4259 matching lines...) Expand 10 before | Expand all | Expand 10 after
9778 return result; 9778 return result;
9779 } 9779 }
9780 9780
9781 9781
9782 intptr_t String::Hash(const String& str, intptr_t begin_index, intptr_t len) { 9782 intptr_t String::Hash(const String& str, intptr_t begin_index, intptr_t len) {
9783 ASSERT(begin_index >= 0); 9783 ASSERT(begin_index >= 0);
9784 ASSERT(len >= 0); 9784 ASSERT(len >= 0);
9785 ASSERT((begin_index + len) <= str.Length()); 9785 ASSERT((begin_index + len) <= str.Length());
9786 StringHasher hasher; 9786 StringHasher hasher;
9787 for (intptr_t i = 0; i < len; i++) { 9787 for (intptr_t i = 0; i < len; i++) {
9788 hasher.Add(str.CharAt(begin_index + i)); 9788 hasher.Add(str.CodeUnitAt(begin_index + i));
9789 } 9789 }
9790 return hasher.Finalize(String::kHashBits); 9790 return hasher.Finalize(String::kHashBits);
9791 } 9791 }
9792 9792
9793 9793
9794 template<typename T> 9794 template<typename T>
9795 static intptr_t HashImpl(const T* characters, intptr_t len) { 9795 static intptr_t HashImpl(const T* characters, intptr_t len) {
9796 ASSERT(len >= 0); 9796 ASSERT(len >= 0);
9797 StringHasher hasher; 9797 StringHasher hasher;
9798 for (intptr_t i = 0; i < len; i++) { 9798 for (intptr_t i = 0; i < len; i++) {
(...skipping 11 matching lines...) Expand all
9810 intptr_t String::Hash(const uint16_t* characters, intptr_t len) { 9810 intptr_t String::Hash(const uint16_t* characters, intptr_t len) {
9811 return HashImpl(characters, len); 9811 return HashImpl(characters, len);
9812 } 9812 }
9813 9813
9814 9814
9815 intptr_t String::Hash(const uint32_t* characters, intptr_t len) { 9815 intptr_t String::Hash(const uint32_t* characters, intptr_t len) {
9816 return HashImpl(characters, len); 9816 return HashImpl(characters, len);
9817 } 9817 }
9818 9818
9819 9819
9820 int32_t String::CharAt(intptr_t index) const { 9820 uint32_t String::CharAt(intptr_t index) const {
9821 intptr_t class_id = raw()->GetClassId(); 9821 intptr_t class_id = raw()->GetClassId();
9822 ASSERT(RawObject::IsStringClassId(class_id)); 9822 ASSERT(RawObject::IsStringClassId(class_id));
9823 NoGCScope no_gc; 9823 NoGCScope no_gc;
9824 if (class_id == kOneByteStringCid) { 9824 if (class_id == kOneByteStringCid) {
9825 return *OneByteString::CharAddr(*this, index); 9825 return OneByteString::CharAt(*this, index);
9826 } 9826 }
9827 if (class_id == kTwoByteStringCid) { 9827 if (class_id == kTwoByteStringCid) {
9828 return *TwoByteString::CharAddr(*this, index); 9828 return TwoByteString::CharAt(*this, index);
9829 } 9829 }
9830 if (class_id == kExternalOneByteStringCid) { 9830 if (class_id == kExternalOneByteStringCid) {
9831 return *ExternalOneByteString::CharAddr(*this, index); 9831 return ExternalOneByteString::CharAt(*this, index);
9832 } 9832 }
9833 ASSERT(class_id == kExternalTwoByteStringCid); 9833 ASSERT(class_id == kExternalTwoByteStringCid);
9834 return *ExternalTwoByteString::CharAddr(*this, index); 9834 return ExternalTwoByteString::CharAt(*this, index);
9835 } 9835 }
9836 9836
9837 9837
9838 uint32_t String::CodeUnitAt(intptr_t index) const {
9839 intptr_t class_id = raw()->GetClassId();
9840 ASSERT(RawObject::IsStringClassId(class_id));
9841 NoGCScope no_gc;
9842 if (class_id == kOneByteStringCid) {
9843 return OneByteString::CodeUnitAt(*this, index);
9844 }
9845 if (class_id == kTwoByteStringCid) {
9846 return TwoByteString::CodeUnitAt(*this, index);
9847 }
9848 if (class_id == kExternalOneByteStringCid) {
9849 return ExternalOneByteString::CodeUnitAt(*this, index);
9850 }
9851 ASSERT(class_id == kExternalTwoByteStringCid);
9852 return ExternalTwoByteString::CodeUnitAt(*this, index);
9853 }
9854
9855
9838 intptr_t String::CharSize() const { 9856 intptr_t String::CharSize() const {
9839 intptr_t class_id = raw()->GetClassId(); 9857 intptr_t class_id = raw()->GetClassId();
9840 if (class_id == kOneByteStringCid || class_id == kExternalOneByteStringCid) { 9858 if (class_id == kOneByteStringCid || class_id == kExternalOneByteStringCid) {
9841 return kOneByteChar; 9859 return kOneByteChar;
9842 } 9860 }
9843 ASSERT(class_id == kTwoByteStringCid || 9861 ASSERT(class_id == kTwoByteStringCid ||
9844 class_id == kExternalTwoByteStringCid); 9862 class_id == kExternalTwoByteStringCid);
9845 return kTwoByteChar; 9863 return kTwoByteChar;
9846 } 9864 }
9847 9865
(...skipping 28 matching lines...) Expand all
9876 9894
9877 9895
9878 bool String::Equals(const char* str) const { 9896 bool String::Equals(const char* str) const {
9879 ASSERT(str != NULL); 9897 ASSERT(str != NULL);
9880 intptr_t len = strlen(str); 9898 intptr_t len = strlen(str);
9881 for (intptr_t i = 0; i < this->Length(); ++i) { 9899 for (intptr_t i = 0; i < this->Length(); ++i) {
9882 if (*str == '\0') { 9900 if (*str == '\0') {
9883 // Lengths don't match. 9901 // Lengths don't match.
9884 return false; 9902 return false;
9885 } 9903 }
9886 int32_t ch; 9904 uint32_t ch;
9887 intptr_t consumed = Utf8::Decode(reinterpret_cast<const uint8_t*>(str), 9905 intptr_t consumed = Utf8::Decode(reinterpret_cast<const uint8_t*>(str),
9888 len, 9906 len,
9889 &ch); 9907 &ch);
9890 if (consumed == 0 || this->CharAt(i) != ch) { 9908 if (consumed == 0) return false;
9891 return false; 9909
9910 if (ch <= Utf16::kMaxCodeUnit) {
9911 if (this->CodeUnitAt(i) != ch) return false;
9912 } else {
9913 if (this->CharAt(i) != ch) return false;
9914 i++;
9892 } 9915 }
9893 str += consumed; 9916 str += consumed;
9894 len -= consumed; 9917 len -= consumed;
9895 } 9918 }
9896 return *str == '\0'; 9919 return *str == '\0';
9897 } 9920 }
9898 9921
9899 9922
9900 bool String::Equals(const uint8_t* characters, intptr_t len) const { 9923 bool String::Equals(const uint8_t* characters, intptr_t len) const {
9901 if (len != this->Length()) { 9924 if (len != this->Length()) {
9902 // Lengths don't match. 9925 // Lengths don't match.
9903 return false; 9926 return false;
9904 } 9927 }
9905 9928
9906 for (intptr_t i = 0; i < len; i++) { 9929 for (intptr_t i = 0; i < len; i++) {
9907 if (this->CharAt(i) != characters[i]) { 9930 if (this->CodeUnitAt(i) != characters[i]) {
9908 return false; 9931 return false;
9909 } 9932 }
9910 } 9933 }
9911 return true; 9934 return true;
9912 } 9935 }
9913 9936
9914 9937
9915 bool String::Equals(const uint16_t* characters, intptr_t len) const { 9938 bool String::Equals(const uint16_t* characters, intptr_t len) const {
9916 if (len != this->Length()) { 9939 if (len != this->Length()) {
9917 // Lengths don't match. 9940 // Lengths don't match.
9918 return false; 9941 return false;
9919 } 9942 }
9920 9943
9921 for (intptr_t i = 0; i < len; i++) { 9944 for (intptr_t i = 0; i < len; i++) {
9922 if (this->CharAt(i) != characters[i]) { 9945 if (this->CodeUnitAt(i) != characters[i]) {
9923 return false; 9946 return false;
9924 } 9947 }
9925 } 9948 }
9926 return true; 9949 return true;
9927 } 9950 }
9928 9951
9929 9952
9930 bool String::Equals(const uint32_t* characters, intptr_t len) const { 9953 bool String::Equals(const uint32_t* characters, intptr_t len) const {
9931 if (len != this->Length()) { 9954 if (len != this->Length()) {
9932 // Lengths don't match. 9955 // Lengths don't match.
9933 return false; 9956 return false;
9934 } 9957 }
9935 9958
9936 for (intptr_t i = 0; i < len; i++) { 9959 for (intptr_t i = 0; i < len; i++) {
9937 if (this->CharAt(i) != static_cast<int32_t>(characters[i])) { 9960 uint32_t c = this->CharAt(i);
9961 if (c != characters[i]) {
9938 return false; 9962 return false;
9939 } 9963 }
9964 if (c > Utf16::kMaxCodeUnit) i++;
9940 } 9965 }
9941 return true; 9966 return true;
9942 } 9967 }
9943 9968
9944 9969
9945 intptr_t String::CompareTo(const String& other) const { 9970 intptr_t String::CompareTo(const String& other) const {
9946 const intptr_t this_len = this->Length(); 9971 const intptr_t this_len = this->Length();
9947 const intptr_t other_len = other.IsNull() ? 0 : other.Length(); 9972 const intptr_t other_len = other.IsNull() ? 0 : other.Length();
9948 const intptr_t len = (this_len < other_len) ? this_len : other_len; 9973 const intptr_t len = (this_len < other_len) ? this_len : other_len;
9949 for (intptr_t i = 0; i < len; i++) { 9974 for (intptr_t i = 0; i < len; i++) {
(...skipping 11 matching lines...) Expand all
9961 return 0; 9986 return 0;
9962 } 9987 }
9963 9988
9964 9989
9965 bool String::StartsWith(const String& other) const { 9990 bool String::StartsWith(const String& other) const {
9966 if (other.IsNull() || (other.Length() > this->Length())) { 9991 if (other.IsNull() || (other.Length() > this->Length())) {
9967 return false; 9992 return false;
9968 } 9993 }
9969 intptr_t slen = other.Length(); 9994 intptr_t slen = other.Length();
9970 for (int i = 0; i < slen; i++) { 9995 for (int i = 0; i < slen; i++) {
9971 if (this->CharAt(i) != other.CharAt(i)) { 9996 if (this->CodeUnitAt(i) != other.CodeUnitAt(i)) {
9972 return false; 9997 return false;
9973 } 9998 }
9974 } 9999 }
9975 return true; 10000 return true;
9976 } 10001 }
9977 10002
9978 10003
9979 RawInstance* String::Canonicalize() const { 10004 RawInstance* String::Canonicalize() const {
9980 if (IsCanonical()) { 10005 if (IsCanonical()) {
9981 return this->raw(); 10006 return this->raw();
9982 } 10007 }
9983 return Symbols::New(*this); 10008 return Symbols::New(*this);
9984 } 10009 }
9985 10010
9986 10011
9987 RawString* String::New(const char* str, Heap::Space space) { 10012 RawString* String::New(const char* str, Heap::Space space) {
9988 ASSERT(str != NULL); 10013 ASSERT(str != NULL);
9989 intptr_t array_len = strlen(str); 10014 intptr_t array_len = strlen(str);
9990 const uint8_t* utf8_array = reinterpret_cast<const uint8_t*>(str); 10015 const uint8_t* utf8_array = reinterpret_cast<const uint8_t*>(str);
9991 return String::New(utf8_array, array_len, space); 10016 return String::New(utf8_array, array_len, space);
9992 } 10017 }
9993 10018
9994 10019
9995 RawString* String::New(const uint8_t* utf8_array, 10020 RawString* String::New(const uint8_t* utf8_array,
9996 intptr_t array_len, 10021 intptr_t array_len,
9997 Heap::Space space) { 10022 Heap::Space space) {
9998 Utf8::Type type; 10023 Utf8::Type type;
9999 intptr_t len = Utf8::CodePointCount(utf8_array, array_len, &type); 10024 intptr_t len = Utf8::CodeUnitCount(utf8_array, array_len, &type);
10000 if (type == Utf8::kAscii) { 10025 if (type == Utf8::kAscii) {
10001 const String& strobj = String::Handle(OneByteString::New(len, space)); 10026 const String& strobj = String::Handle(OneByteString::New(len, space));
10002 if (len > 0) { 10027 if (len > 0) {
10003 NoGCScope no_gc; 10028 NoGCScope no_gc;
10004 Utf8::DecodeToAscii(utf8_array, array_len, 10029 Utf8::DecodeToAscii(utf8_array, array_len,
10005 OneByteString::CharAddr(strobj, 0), len); 10030 OneByteString::CharAddr(strobj, 0), len);
10006 } 10031 }
10007 return strobj.raw(); 10032 return strobj.raw();
10008 } 10033 }
10009 ASSERT((type == Utf8::kBMP) || (type == Utf8::kSMP)); 10034 ASSERT((type == Utf8::kBMP) || (type == Utf8::kSMP));
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
10267 return Symbols::Empty(); 10292 return Symbols::Empty();
10268 } 10293 }
10269 if (begin_index > str.Length()) { 10294 if (begin_index > str.Length()) {
10270 return String::null(); 10295 return String::null();
10271 } 10296 }
10272 String& result = String::Handle(); 10297 String& result = String::Handle();
10273 bool is_one_byte_string = true; 10298 bool is_one_byte_string = true;
10274 intptr_t char_size = str.CharSize(); 10299 intptr_t char_size = str.CharSize();
10275 if (char_size == kTwoByteChar) { 10300 if (char_size == kTwoByteChar) {
10276 for (intptr_t i = begin_index; i < begin_index + length; ++i) { 10301 for (intptr_t i = begin_index; i < begin_index + length; ++i) {
10277 if (str.CharAt(i) > 0x7F) { 10302 if (str.CodeUnitAt(i) > 0x7F) {
10278 is_one_byte_string = false; 10303 is_one_byte_string = false;
10279 break; 10304 break;
10280 } 10305 }
10281 } 10306 }
10282 } 10307 }
10283 if (is_one_byte_string) { 10308 if (is_one_byte_string) {
10284 result ^= OneByteString::New(length, space); 10309 result ^= OneByteString::New(length, space);
10285 } else { 10310 } else {
10286 result ^= TwoByteString::New(length, space); 10311 result ^= TwoByteString::New(length, space);
10287 } 10312 }
(...skipping 24 matching lines...) Expand all
10312 Utf8::Encode(*this, reinterpret_cast<char*>(utf8_array), array_len); 10337 Utf8::Encode(*this, reinterpret_cast<char*>(utf8_array), array_len);
10313 } 10338 }
10314 } 10339 }
10315 10340
10316 10341
10317 RawString* String::Transform(int32_t (*mapping)(int32_t ch), 10342 RawString* String::Transform(int32_t (*mapping)(int32_t ch),
10318 const String& str, 10343 const String& str,
10319 Heap::Space space) { 10344 Heap::Space space) {
10320 ASSERT(!str.IsNull()); 10345 ASSERT(!str.IsNull());
10321 bool has_mapping = false; 10346 bool has_mapping = false;
10322 int32_t dst_max = 0; 10347 uint32_t dst_max = 0;
10323 intptr_t len = str.Length(); 10348 intptr_t len = str.Length();
10349 intptr_t out_len = 0;
10324 // TODO(cshapiro): assume a transform is required, rollback if not. 10350 // TODO(cshapiro): assume a transform is required, rollback if not.
10325 for (intptr_t i = 0; i < len; ++i) { 10351 intptr_t i = 0;
10326 int32_t src = str.CharAt(i); 10352 for (; i < len; ++i) {
10327 int32_t dst = mapping(src); 10353 uint32_t src = str.CodeUnitAt(i);
10354 if (Utf16::IsSurrogate(src)) break;
10355 uint32_t dst = mapping(src);
10328 if (src != dst) { 10356 if (src != dst) {
10329 has_mapping = true; 10357 has_mapping = true;
10330 } 10358 }
10331 dst_max = Utils::Maximum(dst_max, dst); 10359 dst_max = Utils::Maximum(dst_max, dst);
10360 out_len += dst > Utf16::kMaxCodeUnit ? 2 : 1;
10361 }
10362 for (; i < len; ++i) {
10363 uint32_t src = str.CharAt(i);
10364 uint32_t dst = mapping(src);
10365 if (src != dst) {
10366 has_mapping = true;
10367 }
10368 dst_max = Utils::Maximum(dst_max, dst);
10369 out_len += dst > Utf16::kMaxCodeUnit ? 2 : 1;
10370 if (src > Utf16::kMaxCodeUnit) ++i;
10332 } 10371 }
10333 if (!has_mapping) { 10372 if (!has_mapping) {
10334 return str.raw(); 10373 return str.raw();
10335 } 10374 }
10336 if (dst_max <= 0x7F) { 10375 if (dst_max <= 0x7F) {
10337 return OneByteString::Transform(mapping, str, space); 10376 return OneByteString::Transform(mapping, str, out_len, space);
10338 } 10377 }
10339 ASSERT(dst_max > 0x7F); 10378 ASSERT(dst_max > 0x7F);
10340 return TwoByteString::Transform(mapping, str, space); 10379 return TwoByteString::Transform(mapping, str, out_len, space);
10341 } 10380 }
10342 10381
10343 10382
10344 RawString* String::ToUpperCase(const String& str, Heap::Space space) { 10383 RawString* String::ToUpperCase(const String& str, Heap::Space space) {
10345 // TODO(cshapiro): create a fast-path for OneByteString instances. 10384 // TODO(cshapiro): create a fast-path for OneByteString instances.
10346 return Transform(CaseMapping::ToUpper, str, space); 10385 return Transform(CaseMapping::ToUpper, str, space);
10347 } 10386 }
10348 10387
10349 10388
10350 RawString* String::ToLowerCase(const String& str, Heap::Space space) { 10389 RawString* String::ToLowerCase(const String& str, Heap::Space space) {
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
10537 intptr_t str_len = str.Length(); 10576 intptr_t str_len = str.Length();
10538 String::Copy(result, pos, str, 0, str_len); 10577 String::Copy(result, pos, str, 0, str_len);
10539 pos += str_len; 10578 pos += str_len;
10540 } 10579 }
10541 return OneByteString::raw(result); 10580 return OneByteString::raw(result);
10542 } 10581 }
10543 10582
10544 10583
10545 RawOneByteString* OneByteString::Transform(int32_t (*mapping)(int32_t ch), 10584 RawOneByteString* OneByteString::Transform(int32_t (*mapping)(int32_t ch),
10546 const String& str, 10585 const String& str,
10586 int out_length,
10547 Heap::Space space) { 10587 Heap::Space space) {
10548 ASSERT(!str.IsNull()); 10588 ASSERT(!str.IsNull());
10549 intptr_t len = str.Length(); 10589 intptr_t len = str.Length();
10550 const String& result = String::Handle(OneByteString::New(len, space)); 10590 const String& result =
10551 for (intptr_t i = 0; i < len; ++i) { 10591 String::Handle(OneByteString::New(out_length, space));
10552 int32_t ch = mapping(str.CharAt(i)); 10592 for (intptr_t i = 0, j = 0; i < len; ++i, j++) {
10553 ASSERT(ch >= 0 && ch <= 0x7F); 10593 uint32_t old_ch = str.CharAt(i);
10554 *CharAddr(result, i) = ch; 10594 if (old_ch > Utf16::kMaxCodeUnit) i++;
10595 uint32_t ch = mapping(old_ch);
10596 ASSERT(ch <= 0x7Fu);
10597 *CharAddr(result, j) = ch;
10555 } 10598 }
10556 return OneByteString::raw(result); 10599 return OneByteString::raw(result);
10557 } 10600 }
10558 10601
10559 10602
10560 RawTwoByteString* TwoByteString::EscapeSpecialCharacters(const String& str, 10603 RawTwoByteString* TwoByteString::EscapeSpecialCharacters(const String& str,
10561 bool raw_str) { 10604 bool raw_str) {
10562 intptr_t len = str.Length(); 10605 intptr_t len = str.Length();
10563 if (len > 0) { 10606 if (len > 0) {
10564 intptr_t num_escapes = 0; 10607 intptr_t num_escapes = 0;
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
10628 RawTwoByteString* TwoByteString::New(intptr_t utf16_len, 10671 RawTwoByteString* TwoByteString::New(intptr_t utf16_len,
10629 const uint32_t* utf32_array, 10672 const uint32_t* utf32_array,
10630 intptr_t array_len, 10673 intptr_t array_len,
10631 Heap::Space space) { 10674 Heap::Space space) {
10632 ASSERT((array_len > 0) && (utf16_len >= array_len)); 10675 ASSERT((array_len > 0) && (utf16_len >= array_len));
10633 const String& result = String::Handle(TwoByteString::New(utf16_len, space)); 10676 const String& result = String::Handle(TwoByteString::New(utf16_len, space));
10634 { 10677 {
10635 NoGCScope no_gc; 10678 NoGCScope no_gc;
10636 intptr_t j = 0; 10679 intptr_t j = 0;
10637 for (intptr_t i = 0; i < array_len; ++i) { 10680 for (intptr_t i = 0; i < array_len; ++i) {
10638 if (utf32_array[i] > 0xffff) { 10681 uint32_t code_point = utf32_array[i];
10682 if (code_point > Utf16::kMaxCodeUnit) {
10639 ASSERT(j < (utf16_len - 1)); 10683 ASSERT(j < (utf16_len - 1));
10640 Utf8::ConvertUTF32ToUTF16(utf32_array[i], CharAddr(result, j)); 10684 *CharAddr(result, j) = Utf16::LeadFromCodePoint(code_point);
10685 *CharAddr(result, j + 1) = Utf16::TrailFromCodePoint(code_point);
10641 j += 2; 10686 j += 2;
10642 } else { 10687 } else {
10643 ASSERT(j < utf16_len); 10688 ASSERT(j < utf16_len);
10644 *CharAddr(result, j) = utf32_array[i]; 10689 *CharAddr(result, j) = utf32_array[i];
10645 j += 1; 10690 j += 1;
10646 } 10691 }
10647 } 10692 }
10648 } 10693 }
10649 return TwoByteString::raw(result); 10694 return TwoByteString::raw(result);
10650 } 10695 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
10684 intptr_t str_len = str.Length(); 10729 intptr_t str_len = str.Length();
10685 String::Copy(result, pos, str, 0, str_len); 10730 String::Copy(result, pos, str, 0, str_len);
10686 pos += str_len; 10731 pos += str_len;
10687 } 10732 }
10688 return TwoByteString::raw(result); 10733 return TwoByteString::raw(result);
10689 } 10734 }
10690 10735
10691 10736
10692 RawTwoByteString* TwoByteString::Transform(int32_t (*mapping)(int32_t ch), 10737 RawTwoByteString* TwoByteString::Transform(int32_t (*mapping)(int32_t ch),
10693 const String& str, 10738 const String& str,
10739 int out_length,
10694 Heap::Space space) { 10740 Heap::Space space) {
10695 ASSERT(!str.IsNull()); 10741 ASSERT(!str.IsNull());
10696 intptr_t len = str.Length(); 10742 intptr_t len = str.Length();
10697 const String& result = String::Handle(TwoByteString::New(len, space)); 10743 const String& result =
10698 for (intptr_t i = 0; i < len; ++i) { 10744 String::Handle(TwoByteString::New(out_length, space));
10699 int32_t ch = mapping(str.CharAt(i)); 10745 for (intptr_t i = 0, j = 0; i < len; ++i, j++) {
10700 ASSERT(ch >= 0 && ch <= 0xFFFF); 10746 uint32_t old_ch = str.CharAt(i);
10701 *CharAddr(result, i) = ch; 10747 if (old_ch > Utf16::kMaxCodeUnit) i++;
10748 uint32_t ch = mapping(old_ch);
10749 ASSERT(ch <= Utf16::kMaxCodePoint);
10750 if (ch <= Utf16::kMaxCodeUnit) {
10751 *CharAddr(result, j) = ch;
10752 } else {
10753 *CharAddr(result, j) = Utf16::LeadFromCodePoint(ch);
10754 *CharAddr(result, j + 1) = Utf16::TrailFromCodePoint(ch);
10755 ++j;
10756 }
10757 ASSERT(j <= out_length);
10702 } 10758 }
10703 return TwoByteString::raw(result); 10759 return TwoByteString::raw(result);
10704 } 10760 }
10705 10761
10706 10762
10707 static void AddFinalizer(const Object& referent, 10763 static void AddFinalizer(const Object& referent,
10708 void* peer, 10764 void* peer,
10709 Dart_WeakPersistentHandleFinalizer callback) { 10765 Dart_WeakPersistentHandleFinalizer callback) {
10710 ASSERT(callback != NULL); 10766 ASSERT(callback != NULL);
10711 ApiState* state = Isolate::Current()->api_state(); 10767 ApiState* state = Isolate::Current()->api_state();
(...skipping 1221 matching lines...) Expand 10 before | Expand all | Expand 10 after
11933 } 11989 }
11934 return result.raw(); 11990 return result.raw();
11935 } 11991 }
11936 11992
11937 11993
11938 const char* WeakProperty::ToCString() const { 11994 const char* WeakProperty::ToCString() const {
11939 return "_WeakProperty"; 11995 return "_WeakProperty";
11940 } 11996 }
11941 11997
11942 } // namespace dart 11998 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698