OLD | NEW |
---|---|
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 Loading... | |
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) == ':') { |
cshapiro
2012/11/15 20:14:51
This file is an example of why we would like the r
erikcorry
2012/11/15 23:47:05
Done.
| |
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 Loading... | |
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 1667 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2180 const char* prefix, | 2180 const char* prefix, |
2181 intptr_t prefix_length, | 2181 intptr_t prefix_length, |
2182 const String& accessor_name) { | 2182 const String& accessor_name) { |
2183 intptr_t name_len = name.Length(); | 2183 intptr_t name_len = name.Length(); |
2184 intptr_t accessor_name_len = accessor_name.Length(); | 2184 intptr_t accessor_name_len = accessor_name.Length(); |
2185 | 2185 |
2186 if (name_len != (accessor_name_len + prefix_length)) { | 2186 if (name_len != (accessor_name_len + prefix_length)) { |
2187 return false; | 2187 return false; |
2188 } | 2188 } |
2189 for (intptr_t i = 0; i < prefix_length; i++) { | 2189 for (intptr_t i = 0; i < prefix_length; i++) { |
2190 if (name.CharAt(i) != prefix[i]) { | 2190 if (name.CodeUnitAt(i) != static_cast<uint32_t>(prefix[i])) { |
2191 return false; | 2191 return false; |
2192 } | 2192 } |
2193 } | 2193 } |
2194 for (intptr_t i = 0, j = prefix_length; i < accessor_name_len; i++, j++) { | 2194 for (intptr_t i = 0, j = prefix_length; i < accessor_name_len; i++, j++) { |
2195 if (name.CharAt(j) != accessor_name.CharAt(i)) { | 2195 if (name.CodeUnitAt(j) != accessor_name.CodeUnitAt(i)) { |
2196 return false; | 2196 return false; |
2197 } | 2197 } |
2198 } | 2198 } |
2199 return true; | 2199 return true; |
2200 } | 2200 } |
2201 | 2201 |
2202 | 2202 |
2203 RawFunction* Class::LookupFunction(const String& name) const { | 2203 RawFunction* Class::LookupFunction(const String& name) const { |
2204 Isolate* isolate = Isolate::Current(); | 2204 Isolate* isolate = Isolate::Current(); |
2205 ASSERT(name.IsOneByteString()); | 2205 ASSERT(name.IsOneByteString()); |
(...skipping 2284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4490 literal = iterator.MakeLiteralToken(obj); | 4490 literal = iterator.MakeLiteralToken(obj); |
4491 // Advance to be able to use next token kind. | 4491 // Advance to be able to use next token kind. |
4492 iterator.Advance(); | 4492 iterator.Advance(); |
4493 Token::Kind next = iterator.CurrentTokenKind(); | 4493 Token::Kind next = iterator.CurrentTokenKind(); |
4494 | 4494 |
4495 // Handle the current token. | 4495 // Handle the current token. |
4496 if (curr == Token::kSTRING) { | 4496 if (curr == Token::kSTRING) { |
4497 bool is_raw_string = false; | 4497 bool is_raw_string = false; |
4498 bool escape_characters = false; | 4498 bool escape_characters = false; |
4499 for (intptr_t i = 0; i < literal.Length(); i++) { | 4499 for (intptr_t i = 0; i < literal.Length(); i++) { |
4500 if (IsSpecialCharacter(literal.CharAt(i))) { | 4500 if (IsSpecialCharacter(literal.CodeUnitAt(i))) { |
4501 escape_characters = true; | 4501 escape_characters = true; |
4502 } | 4502 } |
4503 // TODO(4995): Temp solution for raw strings, this will break | 4503 // TODO(4995): Temp solution for raw strings, this will break |
4504 // if we saw a string that is not a raw string but has back slashes | 4504 // if we saw a string that is not a raw string but has back slashes |
4505 // in it. | 4505 // in it. |
4506 if ((literal.CharAt(i) == '\\')) { | 4506 if ((literal.CodeUnitAt(i) == '\\')) { |
4507 if ((next != Token::kINTERPOL_VAR) && | 4507 if ((next != Token::kINTERPOL_VAR) && |
4508 (next != Token::kINTERPOL_START) && | 4508 (next != Token::kINTERPOL_START) && |
4509 (prev != Token::kINTERPOL_VAR) && | 4509 (prev != Token::kINTERPOL_VAR) && |
4510 (prev != Token::kINTERPOL_END)) { | 4510 (prev != Token::kINTERPOL_END)) { |
4511 is_raw_string = true; | 4511 is_raw_string = true; |
4512 } else { | 4512 } else { |
4513 escape_characters = true; | 4513 escape_characters = true; |
4514 } | 4514 } |
4515 } | 4515 } |
4516 } | 4516 } |
4517 if ((prev != Token::kINTERPOL_VAR) && (prev != Token::kINTERPOL_END)) { | 4517 if ((prev != Token::kINTERPOL_VAR) && (prev != Token::kINTERPOL_END)) { |
4518 if (is_raw_string) { | 4518 if (is_raw_string) { |
4519 literals.Add(raw_string); | 4519 literals.Add(raw_string); |
4520 } | 4520 } |
4521 literals.Add(double_quotes); | 4521 literals.Add(double_quotes); |
4522 } | 4522 } |
4523 if (escape_characters) { | 4523 if (escape_characters) { |
4524 literal = String::EscapeSpecialCharacters(literal, is_raw_string); | 4524 literal = String::EscapeSpecialCharacters(literal, is_raw_string); |
4525 literals.Add(literal); | 4525 literals.Add(literal); |
4526 } else { | 4526 } else { |
4527 literals.Add(literal); | 4527 literals.Add(literal); |
4528 } | 4528 } |
4529 if ((next != Token::kINTERPOL_VAR) && (next != Token::kINTERPOL_START)) { | 4529 if ((next != Token::kINTERPOL_VAR) && (next != Token::kINTERPOL_START)) { |
4530 literals.Add(double_quotes); | 4530 literals.Add(double_quotes); |
4531 } | 4531 } |
4532 } else if (curr == Token::kINTERPOL_VAR) { | 4532 } else if (curr == Token::kINTERPOL_VAR) { |
4533 literals.Add(dollar); | 4533 literals.Add(dollar); |
4534 if (literal.CharAt(0) == Scanner::kPrivateIdentifierStart) { | 4534 if (literal.CodeUnitAt(0) == Scanner::kPrivateIdentifierStart) { |
4535 literal = String::SubString(literal, 0, literal.Length() - private_len); | 4535 literal = String::SubString(literal, 0, literal.Length() - private_len); |
4536 } | 4536 } |
4537 literals.Add(literal); | 4537 literals.Add(literal); |
4538 } else if (curr == Token::kIDENT) { | 4538 } else if (curr == Token::kIDENT) { |
4539 if (literal.CharAt(0) == Scanner::kPrivateIdentifierStart) { | 4539 if (literal.CodeUnitAt(0) == Scanner::kPrivateIdentifierStart) { |
4540 literal = String::SubString(literal, 0, literal.Length() - private_len); | 4540 literal = String::SubString(literal, 0, literal.Length() - private_len); |
4541 } | 4541 } |
4542 literals.Add(literal); | 4542 literals.Add(literal); |
4543 } else { | 4543 } else { |
4544 literals.Add(literal); | 4544 literals.Add(literal); |
4545 } | 4545 } |
4546 // Determine the separation text based on this current token. | 4546 // Determine the separation text based on this current token. |
4547 const String* separator = NULL; | 4547 const String* separator = NULL; |
4548 switch (curr) { | 4548 switch (curr) { |
4549 case Token::kLBRACE: | 4549 case Token::kLBRACE: |
(...skipping 523 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5073 const String& src = String::Handle(Source()); | 5073 const String& src = String::Handle(Source()); |
5074 intptr_t current_line = 1; | 5074 intptr_t current_line = 1; |
5075 intptr_t line_start = -1; | 5075 intptr_t line_start = -1; |
5076 intptr_t last_char = -1; | 5076 intptr_t last_char = -1; |
5077 for (intptr_t ix = 0; | 5077 for (intptr_t ix = 0; |
5078 (ix < src.Length()) && (current_line <= line_number); | 5078 (ix < src.Length()) && (current_line <= line_number); |
5079 ix++) { | 5079 ix++) { |
5080 if ((current_line == line_number) && (line_start < 0)) { | 5080 if ((current_line == line_number) && (line_start < 0)) { |
5081 line_start = ix; | 5081 line_start = ix; |
5082 } | 5082 } |
5083 if (src.CharAt(ix) == '\n') { | 5083 if (src.CodeUnitAt(ix) == '\n') { |
5084 current_line++; | 5084 current_line++; |
5085 } else if (src.CharAt(ix) == '\r') { | 5085 } else if (src.CodeUnitAt(ix) == '\r') { |
5086 if ((ix + 1 != src.Length()) && (src.CharAt(ix + 1) != '\n')) { | 5086 if ((ix + 1 != src.Length()) && (src.CodeUnitAt(ix + 1) != '\n')) { |
5087 current_line++; | 5087 current_line++; |
5088 } | 5088 } |
5089 } else { | 5089 } else { |
5090 last_char = ix; | 5090 last_char = ix; |
5091 } | 5091 } |
5092 } | 5092 } |
5093 // Guarantee that returned string is never NULL. | 5093 // Guarantee that returned string is never NULL. |
5094 String& line = String::Handle(Symbols::Empty()); | 5094 String& line = String::Handle(Symbols::Empty()); |
5095 if (line_start >= 0) { | 5095 if (line_start >= 0) { |
5096 line = String::SubString(src, line_start, last_char - line_start + 1); | 5096 line = String::SubString(src, line_start, last_char - line_start + 1); |
5097 } | 5097 } |
5098 return line.raw(); | 5098 return line.raw(); |
5099 } | 5099 } |
5100 | 5100 |
5101 | 5101 |
5102 RawString* Script::GetSnippet(intptr_t from_line, | 5102 RawString* Script::GetSnippet(intptr_t from_line, |
5103 intptr_t from_column, | 5103 intptr_t from_column, |
5104 intptr_t to_line, | 5104 intptr_t to_line, |
5105 intptr_t to_column) const { | 5105 intptr_t to_column) const { |
5106 const String& src = String::Handle(Source()); | 5106 const String& src = String::Handle(Source()); |
5107 intptr_t length = src.Length(); | 5107 intptr_t length = src.Length(); |
5108 intptr_t line = 1; | 5108 intptr_t line = 1; |
5109 intptr_t column = 1; | 5109 intptr_t column = 1; |
5110 intptr_t lookahead = 0; | 5110 intptr_t lookahead = 0; |
5111 intptr_t snippet_start = -1; | 5111 intptr_t snippet_start = -1; |
5112 intptr_t snippet_end = -1; | 5112 intptr_t snippet_end = -1; |
5113 char c = src.CharAt(lookahead); | 5113 char c = src.CodeUnitAt(lookahead); |
5114 while (lookahead != length) { | 5114 while (lookahead != length) { |
5115 if (snippet_start == -1) { | 5115 if (snippet_start == -1) { |
5116 if ((line == from_line) && (column == from_column)) { | 5116 if ((line == from_line) && (column == from_column)) { |
5117 snippet_start = lookahead; | 5117 snippet_start = lookahead; |
5118 } | 5118 } |
5119 } else if ((line == to_line) && (column == to_column)) { | 5119 } else if ((line == to_line) && (column == to_column)) { |
5120 snippet_end = lookahead; | 5120 snippet_end = lookahead; |
5121 break; | 5121 break; |
5122 } | 5122 } |
5123 if (c == '\n') { | 5123 if (c == '\n') { |
5124 line++; | 5124 line++; |
5125 column = 0; | 5125 column = 0; |
5126 } | 5126 } |
5127 column++; | 5127 column++; |
5128 lookahead++; | 5128 lookahead++; |
5129 if (lookahead != length) { | 5129 if (lookahead != length) { |
5130 // Replace '\r' with '\n' and a sequence of '\r' '\n' with a single '\n'. | 5130 // Replace '\r' with '\n' and a sequence of '\r' '\n' with a single '\n'. |
5131 if (src.CharAt(lookahead) == '\r') { | 5131 if (src.CodeUnitAt(lookahead) == '\r') { |
5132 c = '\n'; | 5132 c = '\n'; |
5133 if (lookahead + 1 != length && src.CharAt(lookahead) == '\n') { | 5133 if (lookahead + 1 != length && src.CodeUnitAt(lookahead) == '\n') { |
5134 lookahead++; | 5134 lookahead++; |
5135 } | 5135 } |
5136 } else { | 5136 } else { |
5137 c = src.CharAt(lookahead); | 5137 c = src.CodeUnitAt(lookahead); |
5138 } | 5138 } |
5139 } | 5139 } |
5140 } | 5140 } |
5141 String& snippet = String::Handle(); | 5141 String& snippet = String::Handle(); |
5142 if ((snippet_start != -1) && (snippet_end != -1)) { | 5142 if ((snippet_start != -1) && (snippet_end != -1)) { |
5143 snippet = | 5143 snippet = |
5144 String::SubString(src, snippet_start, snippet_end - snippet_start); | 5144 String::SubString(src, snippet_start, snippet_end - snippet_start); |
5145 } | 5145 } |
5146 return snippet.raw(); | 5146 return snippet.raw(); |
5147 } | 5147 } |
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5527 | 5527 |
5528 RawObject* Library::LookupLocalObject(const String& name) const { | 5528 RawObject* Library::LookupLocalObject(const String& name) const { |
5529 intptr_t index; | 5529 intptr_t index; |
5530 return LookupEntry(name, &index); | 5530 return LookupEntry(name, &index); |
5531 } | 5531 } |
5532 | 5532 |
5533 | 5533 |
5534 static bool ShouldBePrivate(const String& name) { | 5534 static bool ShouldBePrivate(const String& name) { |
5535 return | 5535 return |
5536 (name.Length() >= 1 && | 5536 (name.Length() >= 1 && |
5537 name.CharAt(0) == '_') || | 5537 name.CodeUnitAt(0) == '_') || |
5538 (name.Length() >= 5 && | 5538 (name.Length() >= 5 && |
5539 (name.CharAt(4) == '_' && | 5539 (name.CodeUnitAt(4) == '_' && |
5540 (name.CharAt(0) == 'g' || name.CharAt(0) == 's') && | 5540 (name.CodeUnitAt(0) == 'g' || name.CodeUnitAt(0) == 's') && |
5541 name.CharAt(1) == 'e' && | 5541 name.CodeUnitAt(1) == 'e' && |
5542 name.CharAt(2) == 't' && | 5542 name.CodeUnitAt(2) == 't' && |
5543 name.CharAt(3) == ':')); | 5543 name.CodeUnitAt(3) == ':')); |
5544 } | 5544 } |
5545 | 5545 |
5546 | 5546 |
5547 RawField* Library::LookupFieldAllowPrivate(const String& name) const { | 5547 RawField* Library::LookupFieldAllowPrivate(const String& name) const { |
5548 // First check if name is found in the local scope of the library. | 5548 // First check if name is found in the local scope of the library. |
5549 Field& field = Field::Handle(LookupLocalField(name)); | 5549 Field& field = Field::Handle(LookupLocalField(name)); |
5550 if (!field.IsNull()) { | 5550 if (!field.IsNull()) { |
5551 return field.raw(); | 5551 return field.raw(); |
5552 } | 5552 } |
5553 | 5553 |
(...skipping 4294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9848 return result; | 9848 return result; |
9849 } | 9849 } |
9850 | 9850 |
9851 | 9851 |
9852 intptr_t String::Hash(const String& str, intptr_t begin_index, intptr_t len) { | 9852 intptr_t String::Hash(const String& str, intptr_t begin_index, intptr_t len) { |
9853 ASSERT(begin_index >= 0); | 9853 ASSERT(begin_index >= 0); |
9854 ASSERT(len >= 0); | 9854 ASSERT(len >= 0); |
9855 ASSERT((begin_index + len) <= str.Length()); | 9855 ASSERT((begin_index + len) <= str.Length()); |
9856 StringHasher hasher; | 9856 StringHasher hasher; |
9857 for (intptr_t i = 0; i < len; i++) { | 9857 for (intptr_t i = 0; i < len; i++) { |
9858 hasher.Add(str.CharAt(begin_index + i)); | 9858 hasher.Add(str.CodeUnitAt(begin_index + i)); |
9859 } | 9859 } |
9860 return hasher.Finalize(String::kHashBits); | 9860 return hasher.Finalize(String::kHashBits); |
9861 } | 9861 } |
9862 | 9862 |
9863 | 9863 |
9864 template<typename T> | 9864 template<typename T> |
9865 static intptr_t HashImpl(const T* characters, intptr_t len) { | 9865 static intptr_t HashImpl(const T* characters, intptr_t len) { |
9866 ASSERT(len >= 0); | 9866 ASSERT(len >= 0); |
9867 StringHasher hasher; | 9867 StringHasher hasher; |
9868 for (intptr_t i = 0; i < len; i++) { | 9868 for (intptr_t i = 0; i < len; i++) { |
(...skipping 11 matching lines...) Expand all Loading... | |
9880 intptr_t String::Hash(const uint16_t* characters, intptr_t len) { | 9880 intptr_t String::Hash(const uint16_t* characters, intptr_t len) { |
9881 return HashImpl(characters, len); | 9881 return HashImpl(characters, len); |
9882 } | 9882 } |
9883 | 9883 |
9884 | 9884 |
9885 intptr_t String::Hash(const uint32_t* characters, intptr_t len) { | 9885 intptr_t String::Hash(const uint32_t* characters, intptr_t len) { |
9886 return HashImpl(characters, len); | 9886 return HashImpl(characters, len); |
9887 } | 9887 } |
9888 | 9888 |
9889 | 9889 |
9890 int32_t String::CharAt(intptr_t index) const { | 9890 uint32_t String::CodeUnitAt(intptr_t index) const { |
9891 intptr_t class_id = raw()->GetClassId(); | 9891 intptr_t class_id = raw()->GetClassId(); |
9892 ASSERT(RawObject::IsStringClassId(class_id)); | 9892 ASSERT(RawObject::IsStringClassId(class_id)); |
9893 NoGCScope no_gc; | 9893 NoGCScope no_gc; |
9894 if (class_id == kOneByteStringCid) { | 9894 if (class_id == kOneByteStringCid) { |
9895 return *OneByteString::CharAddr(*this, index); | 9895 return OneByteString::CodeUnitAt(*this, index); |
9896 } | 9896 } |
9897 if (class_id == kTwoByteStringCid) { | 9897 if (class_id == kTwoByteStringCid) { |
9898 return *TwoByteString::CharAddr(*this, index); | 9898 return TwoByteString::CodeUnitAt(*this, index); |
9899 } | 9899 } |
9900 if (class_id == kExternalOneByteStringCid) { | 9900 if (class_id == kExternalOneByteStringCid) { |
9901 return *ExternalOneByteString::CharAddr(*this, index); | 9901 return ExternalOneByteString::CodeUnitAt(*this, index); |
9902 } | 9902 } |
9903 ASSERT(class_id == kExternalTwoByteStringCid); | 9903 ASSERT(class_id == kExternalTwoByteStringCid); |
9904 return *ExternalTwoByteString::CharAddr(*this, index); | 9904 return ExternalTwoByteString::CodeUnitAt(*this, index); |
9905 } | 9905 } |
9906 | 9906 |
9907 | 9907 |
9908 intptr_t String::CharSize() const { | 9908 intptr_t String::CharSize() const { |
9909 intptr_t class_id = raw()->GetClassId(); | 9909 intptr_t class_id = raw()->GetClassId(); |
9910 if (class_id == kOneByteStringCid || class_id == kExternalOneByteStringCid) { | 9910 if (class_id == kOneByteStringCid || class_id == kExternalOneByteStringCid) { |
9911 return kOneByteChar; | 9911 return kOneByteChar; |
9912 } | 9912 } |
9913 ASSERT(class_id == kTwoByteStringCid || | 9913 ASSERT(class_id == kTwoByteStringCid || |
9914 class_id == kExternalTwoByteStringCid); | 9914 class_id == kExternalTwoByteStringCid); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9946 | 9946 |
9947 | 9947 |
9948 bool String::Equals(const char* str) const { | 9948 bool String::Equals(const char* str) const { |
9949 ASSERT(str != NULL); | 9949 ASSERT(str != NULL); |
9950 intptr_t len = strlen(str); | 9950 intptr_t len = strlen(str); |
9951 for (intptr_t i = 0; i < this->Length(); ++i) { | 9951 for (intptr_t i = 0; i < this->Length(); ++i) { |
9952 if (*str == '\0') { | 9952 if (*str == '\0') { |
9953 // Lengths don't match. | 9953 // Lengths don't match. |
9954 return false; | 9954 return false; |
9955 } | 9955 } |
9956 int32_t ch; | 9956 uint32_t ch; |
9957 intptr_t consumed = Utf8::Decode(reinterpret_cast<const uint8_t*>(str), | 9957 intptr_t consumed = Utf8::Decode(reinterpret_cast<const uint8_t*>(str), |
9958 len, | 9958 len, |
9959 &ch); | 9959 &ch); |
9960 if (consumed == 0 || this->CharAt(i) != ch) { | 9960 if (consumed == 0) return false; |
9961 return false; | 9961 |
9962 if (ch <= Utf16::kMaxCodeUnit) { | |
9963 if (this->CodeUnitAt(i) != ch) return false; | |
9964 } else { | |
9965 if (Utf16::CodePointAt(*this, i) != ch) return false; | |
9966 i++; | |
9962 } | 9967 } |
9963 str += consumed; | 9968 str += consumed; |
9964 len -= consumed; | 9969 len -= consumed; |
9965 } | 9970 } |
9966 return *str == '\0'; | 9971 return *str == '\0'; |
9967 } | 9972 } |
9968 | 9973 |
9969 | 9974 |
9970 bool String::Equals(const uint8_t* characters, intptr_t len) const { | 9975 bool String::Equals(const uint8_t* characters, intptr_t len) const { |
9971 if (len != this->Length()) { | 9976 if (len != this->Length()) { |
9972 // Lengths don't match. | 9977 // Lengths don't match. |
9973 return false; | 9978 return false; |
9974 } | 9979 } |
9975 | 9980 |
9976 for (intptr_t i = 0; i < len; i++) { | 9981 for (intptr_t i = 0; i < len; i++) { |
9977 if (this->CharAt(i) != characters[i]) { | 9982 if (this->CodeUnitAt(i) != characters[i]) { |
9978 return false; | 9983 return false; |
9979 } | 9984 } |
9980 } | 9985 } |
9981 return true; | 9986 return true; |
9982 } | 9987 } |
9983 | 9988 |
9984 | 9989 |
9985 bool String::Equals(const uint16_t* characters, intptr_t len) const { | 9990 bool String::Equals(const uint16_t* characters, intptr_t len) const { |
9986 if (len != this->Length()) { | 9991 if (len != this->Length()) { |
9987 // Lengths don't match. | 9992 // Lengths don't match. |
9988 return false; | 9993 return false; |
9989 } | 9994 } |
9990 | 9995 |
9991 for (intptr_t i = 0; i < len; i++) { | 9996 for (intptr_t i = 0; i < len; i++) { |
9992 if (this->CharAt(i) != characters[i]) { | 9997 if (this->CodeUnitAt(i) != characters[i]) { |
9993 return false; | 9998 return false; |
9994 } | 9999 } |
9995 } | 10000 } |
9996 return true; | 10001 return true; |
9997 } | 10002 } |
9998 | 10003 |
9999 | 10004 |
10000 bool String::Equals(const uint32_t* characters, intptr_t len) const { | 10005 bool String::Equals(const uint32_t* characters, intptr_t len) const { |
10001 if (len != this->Length()) { | 10006 if (len != this->Length()) { |
10002 // Lengths don't match. | 10007 // Lengths don't match. |
10003 return false; | 10008 return false; |
10004 } | 10009 } |
10005 | 10010 |
10006 for (intptr_t i = 0; i < len; i++) { | 10011 for (intptr_t i = 0; i < len; i++) { |
10007 if (this->CharAt(i) != static_cast<int32_t>(characters[i])) { | 10012 uint32_t c = this->CodeUnitAt(i); |
10013 if (c != characters[i]) { | |
10008 return false; | 10014 return false; |
10009 } | 10015 } |
10016 if (c > Utf16::kMaxCodeUnit) i++; | |
10010 } | 10017 } |
10011 return true; | 10018 return true; |
10012 } | 10019 } |
10013 | 10020 |
10014 | 10021 |
10015 intptr_t String::CompareTo(const String& other) const { | 10022 intptr_t String::CompareTo(const String& other) const { |
10016 const intptr_t this_len = this->Length(); | 10023 const intptr_t this_len = this->Length(); |
10017 const intptr_t other_len = other.IsNull() ? 0 : other.Length(); | 10024 const intptr_t other_len = other.IsNull() ? 0 : other.Length(); |
10018 const intptr_t len = (this_len < other_len) ? this_len : other_len; | 10025 const intptr_t len = (this_len < other_len) ? this_len : other_len; |
10026 // UTF-16 has the high surrogate before the low surrogate so we can compare | |
10027 // one code unit at a time for efficiency and still get the right ordering. | |
10019 for (intptr_t i = 0; i < len; i++) { | 10028 for (intptr_t i = 0; i < len; i++) { |
10020 int32_t this_code_point = this->CharAt(i); | 10029 int32_t this_code_unit = this->CodeUnitAt(i); |
10021 int32_t other_code_point = other.CharAt(i); | 10030 int32_t other_code_unit = other.CodeUnitAt(i); |
10022 if (this_code_point < other_code_point) { | 10031 if (this_code_unit < other_code_unit) { |
10023 return -1; | 10032 return -1; |
10024 } | 10033 } |
10025 if (this_code_point > other_code_point) { | 10034 if (this_code_unit > other_code_unit) { |
10026 return 1; | 10035 return 1; |
10027 } | 10036 } |
10028 } | 10037 } |
10029 if (this_len < other_len) return -1; | 10038 if (this_len < other_len) return -1; |
10030 if (this_len > other_len) return 1; | 10039 if (this_len > other_len) return 1; |
10031 return 0; | 10040 return 0; |
10032 } | 10041 } |
10033 | 10042 |
10034 | 10043 |
10035 bool String::StartsWith(const String& other) const { | 10044 bool String::StartsWith(const String& other) const { |
10036 if (other.IsNull() || (other.Length() > this->Length())) { | 10045 if (other.IsNull() || (other.Length() > this->Length())) { |
10037 return false; | 10046 return false; |
10038 } | 10047 } |
10039 intptr_t slen = other.Length(); | 10048 intptr_t slen = other.Length(); |
10040 for (int i = 0; i < slen; i++) { | 10049 for (int i = 0; i < slen; i++) { |
10041 if (this->CharAt(i) != other.CharAt(i)) { | 10050 if (this->CodeUnitAt(i) != other.CodeUnitAt(i)) { |
10042 return false; | 10051 return false; |
10043 } | 10052 } |
10044 } | 10053 } |
10045 return true; | 10054 return true; |
10046 } | 10055 } |
10047 | 10056 |
10048 | 10057 |
10049 RawInstance* String::Canonicalize() const { | 10058 RawInstance* String::Canonicalize() const { |
10050 if (IsCanonical()) { | 10059 if (IsCanonical()) { |
10051 return this->raw(); | 10060 return this->raw(); |
10052 } | 10061 } |
10053 return Symbols::New(*this); | 10062 return Symbols::New(*this); |
10054 } | 10063 } |
10055 | 10064 |
10056 | 10065 |
10057 RawString* String::New(const char* str, Heap::Space space) { | 10066 RawString* String::New(const char* str, Heap::Space space) { |
10058 ASSERT(str != NULL); | 10067 ASSERT(str != NULL); |
10059 intptr_t array_len = strlen(str); | 10068 intptr_t array_len = strlen(str); |
10060 const uint8_t* utf8_array = reinterpret_cast<const uint8_t*>(str); | 10069 const uint8_t* utf8_array = reinterpret_cast<const uint8_t*>(str); |
10061 return String::New(utf8_array, array_len, space); | 10070 return String::New(utf8_array, array_len, space); |
10062 } | 10071 } |
10063 | 10072 |
10064 | 10073 |
10065 RawString* String::New(const uint8_t* utf8_array, | 10074 RawString* String::New(const uint8_t* utf8_array, |
10066 intptr_t array_len, | 10075 intptr_t array_len, |
10067 Heap::Space space) { | 10076 Heap::Space space) { |
10068 Utf8::Type type; | 10077 Utf8::Type type; |
10069 intptr_t len = Utf8::CodePointCount(utf8_array, array_len, &type); | 10078 intptr_t len = Utf8::CodeUnitCount(utf8_array, array_len, &type); |
10070 if (type == Utf8::kAscii) { | 10079 if (type == Utf8::kAscii) { |
10071 const String& strobj = String::Handle(OneByteString::New(len, space)); | 10080 const String& strobj = String::Handle(OneByteString::New(len, space)); |
10072 if (len > 0) { | 10081 if (len > 0) { |
10073 NoGCScope no_gc; | 10082 NoGCScope no_gc; |
10074 Utf8::DecodeToAscii(utf8_array, array_len, | 10083 Utf8::DecodeToAscii(utf8_array, array_len, |
10075 OneByteString::CharAddr(strobj, 0), len); | 10084 OneByteString::CharAddr(strobj, 0), len); |
10076 } | 10085 } |
10077 return strobj.raw(); | 10086 return strobj.raw(); |
10078 } | 10087 } |
10079 ASSERT((type == Utf8::kBMP) || (type == Utf8::kSMP)); | 10088 ASSERT((type == Utf8::kBMP) || (type == Utf8::kSMP)); |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10337 return Symbols::Empty(); | 10346 return Symbols::Empty(); |
10338 } | 10347 } |
10339 if (begin_index > str.Length()) { | 10348 if (begin_index > str.Length()) { |
10340 return String::null(); | 10349 return String::null(); |
10341 } | 10350 } |
10342 String& result = String::Handle(); | 10351 String& result = String::Handle(); |
10343 bool is_one_byte_string = true; | 10352 bool is_one_byte_string = true; |
10344 intptr_t char_size = str.CharSize(); | 10353 intptr_t char_size = str.CharSize(); |
10345 if (char_size == kTwoByteChar) { | 10354 if (char_size == kTwoByteChar) { |
10346 for (intptr_t i = begin_index; i < begin_index + length; ++i) { | 10355 for (intptr_t i = begin_index; i < begin_index + length; ++i) { |
10347 if (str.CharAt(i) > 0x7F) { | 10356 if (str.CodeUnitAt(i) > 0x7F) { |
10348 is_one_byte_string = false; | 10357 is_one_byte_string = false; |
10349 break; | 10358 break; |
10350 } | 10359 } |
10351 } | 10360 } |
10352 } | 10361 } |
10353 if (is_one_byte_string) { | 10362 if (is_one_byte_string) { |
10354 result ^= OneByteString::New(length, space); | 10363 result ^= OneByteString::New(length, space); |
10355 } else { | 10364 } else { |
10356 result ^= TwoByteString::New(length, space); | 10365 result ^= TwoByteString::New(length, space); |
10357 } | 10366 } |
(...skipping 24 matching lines...) Expand all Loading... | |
10382 Utf8::Encode(*this, reinterpret_cast<char*>(utf8_array), array_len); | 10391 Utf8::Encode(*this, reinterpret_cast<char*>(utf8_array), array_len); |
10383 } | 10392 } |
10384 } | 10393 } |
10385 | 10394 |
10386 | 10395 |
10387 RawString* String::Transform(int32_t (*mapping)(int32_t ch), | 10396 RawString* String::Transform(int32_t (*mapping)(int32_t ch), |
10388 const String& str, | 10397 const String& str, |
10389 Heap::Space space) { | 10398 Heap::Space space) { |
10390 ASSERT(!str.IsNull()); | 10399 ASSERT(!str.IsNull()); |
10391 bool has_mapping = false; | 10400 bool has_mapping = false; |
10392 int32_t dst_max = 0; | 10401 uint32_t dst_max = 0; |
10393 intptr_t len = str.Length(); | 10402 intptr_t len = str.Length(); |
10403 intptr_t out_len = 0; | |
10394 // TODO(cshapiro): assume a transform is required, rollback if not. | 10404 // TODO(cshapiro): assume a transform is required, rollback if not. |
10395 for (intptr_t i = 0; i < len; ++i) { | 10405 intptr_t i = 0; |
10396 int32_t src = str.CharAt(i); | 10406 for (; i < len; ++i) { |
10397 int32_t dst = mapping(src); | 10407 uint32_t src = str.CodeUnitAt(i); |
10408 if (Utf16::IsSurrogate(src)) break; | |
10409 uint32_t dst = mapping(src); | |
10398 if (src != dst) { | 10410 if (src != dst) { |
10399 has_mapping = true; | 10411 has_mapping = true; |
10400 } | 10412 } |
10401 dst_max = Utils::Maximum(dst_max, dst); | 10413 dst_max = Utils::Maximum(dst_max, dst); |
10414 out_len += dst > Utf16::kMaxCodeUnit ? 2 : 1; | |
10415 } | |
10416 for (; i < len; ++i) { | |
10417 uint32_t src = Utf16::CodePointAt(str, i); | |
10418 uint32_t dst = mapping(src); | |
10419 if (src != dst) { | |
10420 has_mapping = true; | |
10421 } | |
10422 dst_max = Utils::Maximum(dst_max, dst); | |
10423 out_len += dst > Utf16::kMaxCodeUnit ? 2 : 1; | |
10424 if (src > Utf16::kMaxCodeUnit) ++i; | |
10402 } | 10425 } |
10403 if (!has_mapping) { | 10426 if (!has_mapping) { |
10404 return str.raw(); | 10427 return str.raw(); |
10405 } | 10428 } |
10406 if (dst_max <= 0x7F) { | 10429 if (dst_max <= 0x7F) { |
10407 return OneByteString::Transform(mapping, str, space); | 10430 return OneByteString::Transform(mapping, str, out_len, space); |
10408 } | 10431 } |
10409 ASSERT(dst_max > 0x7F); | 10432 ASSERT(dst_max > 0x7F); |
10410 return TwoByteString::Transform(mapping, str, space); | 10433 return TwoByteString::Transform(mapping, str, out_len, space); |
10411 } | 10434 } |
10412 | 10435 |
10413 | 10436 |
10414 RawString* String::ToUpperCase(const String& str, Heap::Space space) { | 10437 RawString* String::ToUpperCase(const String& str, Heap::Space space) { |
10415 // TODO(cshapiro): create a fast-path for OneByteString instances. | 10438 // TODO(cshapiro): create a fast-path for OneByteString instances. |
10416 return Transform(CaseMapping::ToUpper, str, space); | 10439 return Transform(CaseMapping::ToUpper, str, space); |
10417 } | 10440 } |
10418 | 10441 |
10419 | 10442 |
10420 RawString* String::ToLowerCase(const String& str, Heap::Space space) { | 10443 RawString* String::ToLowerCase(const String& str, Heap::Space space) { |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10607 intptr_t str_len = str.Length(); | 10630 intptr_t str_len = str.Length(); |
10608 String::Copy(result, pos, str, 0, str_len); | 10631 String::Copy(result, pos, str, 0, str_len); |
10609 pos += str_len; | 10632 pos += str_len; |
10610 } | 10633 } |
10611 return OneByteString::raw(result); | 10634 return OneByteString::raw(result); |
10612 } | 10635 } |
10613 | 10636 |
10614 | 10637 |
10615 RawOneByteString* OneByteString::Transform(int32_t (*mapping)(int32_t ch), | 10638 RawOneByteString* OneByteString::Transform(int32_t (*mapping)(int32_t ch), |
10616 const String& str, | 10639 const String& str, |
10640 int out_length, | |
10617 Heap::Space space) { | 10641 Heap::Space space) { |
10618 ASSERT(!str.IsNull()); | 10642 ASSERT(!str.IsNull()); |
10619 intptr_t len = str.Length(); | 10643 intptr_t len = str.Length(); |
10620 const String& result = String::Handle(OneByteString::New(len, space)); | 10644 const String& result = |
10621 for (intptr_t i = 0; i < len; ++i) { | 10645 String::Handle(OneByteString::New(out_length, space)); |
10622 int32_t ch = mapping(str.CharAt(i)); | 10646 for (intptr_t i = 0, j = 0; i < len; ++i, j++) { |
10623 ASSERT(ch >= 0 && ch <= 0x7F); | 10647 uint32_t old_ch = str.CodeUnitAt(i); |
10624 *CharAddr(result, i) = ch; | 10648 if (old_ch > Utf16::kMaxCodeUnit) i++; |
10649 uint32_t ch = mapping(old_ch); | |
10650 ASSERT(ch <= 0x7Fu); | |
10651 *CharAddr(result, j) = ch; | |
10625 } | 10652 } |
10626 return OneByteString::raw(result); | 10653 return OneByteString::raw(result); |
10627 } | 10654 } |
10628 | 10655 |
10629 | 10656 |
10630 RawTwoByteString* TwoByteString::EscapeSpecialCharacters(const String& str, | 10657 RawTwoByteString* TwoByteString::EscapeSpecialCharacters(const String& str, |
10631 bool raw_str) { | 10658 bool raw_str) { |
10632 intptr_t len = str.Length(); | 10659 intptr_t len = str.Length(); |
10633 if (len > 0) { | 10660 if (len > 0) { |
10634 intptr_t num_escapes = 0; | 10661 intptr_t num_escapes = 0; |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10698 RawTwoByteString* TwoByteString::New(intptr_t utf16_len, | 10725 RawTwoByteString* TwoByteString::New(intptr_t utf16_len, |
10699 const uint32_t* utf32_array, | 10726 const uint32_t* utf32_array, |
10700 intptr_t array_len, | 10727 intptr_t array_len, |
10701 Heap::Space space) { | 10728 Heap::Space space) { |
10702 ASSERT((array_len > 0) && (utf16_len >= array_len)); | 10729 ASSERT((array_len > 0) && (utf16_len >= array_len)); |
10703 const String& result = String::Handle(TwoByteString::New(utf16_len, space)); | 10730 const String& result = String::Handle(TwoByteString::New(utf16_len, space)); |
10704 { | 10731 { |
10705 NoGCScope no_gc; | 10732 NoGCScope no_gc; |
10706 intptr_t j = 0; | 10733 intptr_t j = 0; |
10707 for (intptr_t i = 0; i < array_len; ++i) { | 10734 for (intptr_t i = 0; i < array_len; ++i) { |
10708 if (utf32_array[i] > 0xffff) { | 10735 uint32_t code_point = utf32_array[i]; |
10736 if (code_point > Utf16::kMaxCodeUnit) { | |
10709 ASSERT(j < (utf16_len - 1)); | 10737 ASSERT(j < (utf16_len - 1)); |
10710 Utf8::ConvertUTF32ToUTF16(utf32_array[i], CharAddr(result, j)); | 10738 *CharAddr(result, j) = Utf16::LeadFromCodePoint(code_point); |
10739 *CharAddr(result, j + 1) = Utf16::TrailFromCodePoint(code_point); | |
10711 j += 2; | 10740 j += 2; |
10712 } else { | 10741 } else { |
10713 ASSERT(j < utf16_len); | 10742 ASSERT(j < utf16_len); |
10714 *CharAddr(result, j) = utf32_array[i]; | 10743 *CharAddr(result, j) = utf32_array[i]; |
10715 j += 1; | 10744 j += 1; |
10716 } | 10745 } |
10717 } | 10746 } |
10718 } | 10747 } |
10719 return TwoByteString::raw(result); | 10748 return TwoByteString::raw(result); |
10720 } | 10749 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10754 intptr_t str_len = str.Length(); | 10783 intptr_t str_len = str.Length(); |
10755 String::Copy(result, pos, str, 0, str_len); | 10784 String::Copy(result, pos, str, 0, str_len); |
10756 pos += str_len; | 10785 pos += str_len; |
10757 } | 10786 } |
10758 return TwoByteString::raw(result); | 10787 return TwoByteString::raw(result); |
10759 } | 10788 } |
10760 | 10789 |
10761 | 10790 |
10762 RawTwoByteString* TwoByteString::Transform(int32_t (*mapping)(int32_t ch), | 10791 RawTwoByteString* TwoByteString::Transform(int32_t (*mapping)(int32_t ch), |
10763 const String& str, | 10792 const String& str, |
10793 int out_length, | |
10764 Heap::Space space) { | 10794 Heap::Space space) { |
10765 ASSERT(!str.IsNull()); | 10795 ASSERT(!str.IsNull()); |
10766 intptr_t len = str.Length(); | 10796 intptr_t len = str.Length(); |
10767 const String& result = String::Handle(TwoByteString::New(len, space)); | 10797 const String& result = |
10768 for (intptr_t i = 0; i < len; ++i) { | 10798 String::Handle(TwoByteString::New(out_length, space)); |
10769 int32_t ch = mapping(str.CharAt(i)); | 10799 for (intptr_t i = 0, j = 0; i < len; ++i, j++) { |
10770 ASSERT(ch >= 0 && ch <= 0xFFFF); | 10800 uint32_t old_ch = Utf16::CodePointAt(str, i); |
10771 *CharAddr(result, i) = ch; | 10801 if (old_ch > Utf16::kMaxCodeUnit) i++; |
10802 uint32_t ch = mapping(old_ch); | |
10803 ASSERT(ch <= Utf16::kMaxCodePoint); | |
10804 if (ch <= Utf16::kMaxCodeUnit) { | |
10805 *CharAddr(result, j) = ch; | |
10806 } else { | |
10807 *CharAddr(result, j) = Utf16::LeadFromCodePoint(ch); | |
10808 *CharAddr(result, j + 1) = Utf16::TrailFromCodePoint(ch); | |
10809 ++j; | |
10810 } | |
10811 ASSERT(j <= out_length); | |
10772 } | 10812 } |
10773 return TwoByteString::raw(result); | 10813 return TwoByteString::raw(result); |
10774 } | 10814 } |
10775 | 10815 |
10776 | 10816 |
10777 static void AddFinalizer(const Object& referent, | 10817 static void AddFinalizer(const Object& referent, |
10778 void* peer, | 10818 void* peer, |
10779 Dart_WeakPersistentHandleFinalizer callback) { | 10819 Dart_WeakPersistentHandleFinalizer callback) { |
10780 ASSERT(callback != NULL); | 10820 ASSERT(callback != NULL); |
10781 ApiState* state = Isolate::Current()->api_state(); | 10821 ApiState* state = Isolate::Current()->api_state(); |
(...skipping 1221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
12003 } | 12043 } |
12004 return result.raw(); | 12044 return result.raw(); |
12005 } | 12045 } |
12006 | 12046 |
12007 | 12047 |
12008 const char* WeakProperty::ToCString() const { | 12048 const char* WeakProperty::ToCString() const { |
12009 return "_WeakProperty"; | 12049 return "_WeakProperty"; |
12010 } | 12050 } |
12011 | 12051 |
12012 } // namespace dart | 12052 } // namespace dart |
OLD | NEW |