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

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

Issue 982873004: Thread/Isolate refactoring: new(Isolate) -> new(Zone) (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 5 years, 9 months 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) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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/longjump.h" 5 #include "vm/longjump.h"
6 #include "vm/object_store.h" 6 #include "vm/object_store.h"
7 #include "vm/regexp_parser.h" 7 #include "vm/regexp_parser.h"
8 8
9 namespace dart { 9 namespace dart {
10 10
11 #define I isolate() 11 #define Z zone()
12 12
13 // Enables possessive quantifier syntax for testing. 13 // Enables possessive quantifier syntax for testing.
14 static const bool FLAG_regexp_possessive_quantifier = false; 14 static const bool FLAG_regexp_possessive_quantifier = false;
15 15
16 RegExpBuilder::RegExpBuilder() 16 RegExpBuilder::RegExpBuilder()
17 : isolate_(Isolate::Current()), 17 : zone_(Thread::Current()->zone()),
18 pending_empty_(false), 18 pending_empty_(false),
19 characters_(NULL), 19 characters_(NULL),
20 terms_(), 20 terms_(),
21 text_(), 21 text_(),
22 alternatives_() 22 alternatives_()
23 #ifdef DEBUG 23 #ifdef DEBUG
24 , last_added_(ADD_NONE) 24 , last_added_(ADD_NONE)
25 #endif 25 #endif
26 {} 26 {}
27 27
28 28
29 void RegExpBuilder::FlushCharacters() { 29 void RegExpBuilder::FlushCharacters() {
30 pending_empty_ = false; 30 pending_empty_ = false;
31 if (characters_ != NULL) { 31 if (characters_ != NULL) {
32 RegExpTree* atom = new(I) RegExpAtom(characters_); 32 RegExpTree* atom = new(Z) RegExpAtom(characters_);
33 characters_ = NULL; 33 characters_ = NULL;
34 text_.Add(atom); 34 text_.Add(atom);
35 LAST(ADD_ATOM); 35 LAST(ADD_ATOM);
36 } 36 }
37 } 37 }
38 38
39 39
40 void RegExpBuilder::FlushText() { 40 void RegExpBuilder::FlushText() {
41 FlushCharacters(); 41 FlushCharacters();
42 intptr_t num_text = text_.length(); 42 intptr_t num_text = text_.length();
43 if (num_text == 0) { 43 if (num_text == 0) {
44 return; 44 return;
45 } else if (num_text == 1) { 45 } else if (num_text == 1) {
46 terms_.Add(text_.Last()); 46 terms_.Add(text_.Last());
47 } else { 47 } else {
48 RegExpText* text = new(I) RegExpText(); 48 RegExpText* text = new(Z) RegExpText();
49 for (intptr_t i = 0; i < num_text; i++) 49 for (intptr_t i = 0; i < num_text; i++)
50 text_[i]->AppendToText(text); 50 text_[i]->AppendToText(text);
51 terms_.Add(text); 51 terms_.Add(text);
52 } 52 }
53 text_.Clear(); 53 text_.Clear();
54 } 54 }
55 55
56 56
57 void RegExpBuilder::AddCharacter(uint16_t c) { 57 void RegExpBuilder::AddCharacter(uint16_t c) {
58 pending_empty_ = false; 58 pending_empty_ = false;
59 if (characters_ == NULL) { 59 if (characters_ == NULL) {
60 characters_ = new(I) ZoneGrowableArray<uint16_t>(4); 60 characters_ = new(Z) ZoneGrowableArray<uint16_t>(4);
61 } 61 }
62 characters_->Add(c); 62 characters_->Add(c);
63 LAST(ADD_CHAR); 63 LAST(ADD_CHAR);
64 } 64 }
65 65
66 66
67 void RegExpBuilder::AddEmpty() { 67 void RegExpBuilder::AddEmpty() {
68 pending_empty_ = true; 68 pending_empty_ = true;
69 } 69 }
70 70
(...skipping 29 matching lines...) Expand all
100 void RegExpBuilder::FlushTerms() { 100 void RegExpBuilder::FlushTerms() {
101 FlushText(); 101 FlushText();
102 intptr_t num_terms = terms_.length(); 102 intptr_t num_terms = terms_.length();
103 RegExpTree* alternative; 103 RegExpTree* alternative;
104 if (num_terms == 0) { 104 if (num_terms == 0) {
105 alternative = RegExpEmpty::GetInstance(); 105 alternative = RegExpEmpty::GetInstance();
106 } else if (num_terms == 1) { 106 } else if (num_terms == 1) {
107 alternative = terms_.Last(); 107 alternative = terms_.Last();
108 } else { 108 } else {
109 ZoneGrowableArray<RegExpTree*>* terms = 109 ZoneGrowableArray<RegExpTree*>* terms =
110 new(I) ZoneGrowableArray<RegExpTree*>(); 110 new(Z) ZoneGrowableArray<RegExpTree*>();
111 for (intptr_t i = 0; i < terms_.length(); i++) { 111 for (intptr_t i = 0; i < terms_.length(); i++) {
112 terms->Add(terms_[i]); 112 terms->Add(terms_[i]);
113 } 113 }
114 alternative = new(I) RegExpAlternative(terms); 114 alternative = new(Z) RegExpAlternative(terms);
115 } 115 }
116 alternatives_.Add(alternative); 116 alternatives_.Add(alternative);
117 terms_.Clear(); 117 terms_.Clear();
118 LAST(ADD_NONE); 118 LAST(ADD_NONE);
119 } 119 }
120 120
121 121
122 RegExpTree* RegExpBuilder::ToRegExp() { 122 RegExpTree* RegExpBuilder::ToRegExp() {
123 FlushTerms(); 123 FlushTerms();
124 intptr_t num_alternatives = alternatives_.length(); 124 intptr_t num_alternatives = alternatives_.length();
125 if (num_alternatives == 0) { 125 if (num_alternatives == 0) {
126 return RegExpEmpty::GetInstance(); 126 return RegExpEmpty::GetInstance();
127 } 127 }
128 if (num_alternatives == 1) { 128 if (num_alternatives == 1) {
129 return alternatives_.Last(); 129 return alternatives_.Last();
130 } 130 }
131 ZoneGrowableArray<RegExpTree*>* alternatives = 131 ZoneGrowableArray<RegExpTree*>* alternatives =
132 new(I) ZoneGrowableArray<RegExpTree*>(); 132 new(Z) ZoneGrowableArray<RegExpTree*>();
133 for (intptr_t i = 0; i < alternatives_.length(); i++) { 133 for (intptr_t i = 0; i < alternatives_.length(); i++) {
134 alternatives->Add(alternatives_[i]); 134 alternatives->Add(alternatives_[i]);
135 } 135 }
136 return new(I) RegExpDisjunction(alternatives); 136 return new(Z) RegExpDisjunction(alternatives);
137 } 137 }
138 138
139 139
140 void RegExpBuilder::AddQuantifierToAtom( 140 void RegExpBuilder::AddQuantifierToAtom(
141 intptr_t min, 141 intptr_t min,
142 intptr_t max, 142 intptr_t max,
143 RegExpQuantifier::QuantifierType quantifier_type) { 143 RegExpQuantifier::QuantifierType quantifier_type) {
144 if (pending_empty_) { 144 if (pending_empty_) {
145 pending_empty_ = false; 145 pending_empty_ = false;
146 return; 146 return;
147 } 147 }
148 RegExpTree* atom; 148 RegExpTree* atom;
149 if (characters_ != NULL) { 149 if (characters_ != NULL) {
150 DEBUG_ASSERT(last_added_ == ADD_CHAR); 150 DEBUG_ASSERT(last_added_ == ADD_CHAR);
151 // Last atom was character. 151 // Last atom was character.
152 152
153 ZoneGrowableArray<uint16_t> *char_vector = 153 ZoneGrowableArray<uint16_t> *char_vector =
154 new(I) ZoneGrowableArray<uint16_t>(); 154 new(Z) ZoneGrowableArray<uint16_t>();
155 char_vector->AddArray(*characters_); 155 char_vector->AddArray(*characters_);
156 intptr_t num_chars = char_vector->length(); 156 intptr_t num_chars = char_vector->length();
157 if (num_chars > 1) { 157 if (num_chars > 1) {
158 ZoneGrowableArray<uint16_t> *prefix = 158 ZoneGrowableArray<uint16_t> *prefix =
159 new(I) ZoneGrowableArray<uint16_t>(); 159 new(Z) ZoneGrowableArray<uint16_t>();
160 for (intptr_t i = 0; i < num_chars - 1; i++) { 160 for (intptr_t i = 0; i < num_chars - 1; i++) {
161 prefix->Add(char_vector->At(i)); 161 prefix->Add(char_vector->At(i));
162 } 162 }
163 text_.Add(new(I) RegExpAtom(prefix)); 163 text_.Add(new(Z) RegExpAtom(prefix));
164 ZoneGrowableArray<uint16_t> *tail = new(I) ZoneGrowableArray<uint16_t>(); 164 ZoneGrowableArray<uint16_t> *tail = new(Z) ZoneGrowableArray<uint16_t>();
165 tail->Add(char_vector->At(num_chars - 1)); 165 tail->Add(char_vector->At(num_chars - 1));
166 char_vector = tail; 166 char_vector = tail;
167 } 167 }
168 characters_ = NULL; 168 characters_ = NULL;
169 atom = new(I) RegExpAtom(char_vector); 169 atom = new(Z) RegExpAtom(char_vector);
170 FlushText(); 170 FlushText();
171 } else if (text_.length() > 0) { 171 } else if (text_.length() > 0) {
172 DEBUG_ASSERT(last_added_ == ADD_ATOM); 172 DEBUG_ASSERT(last_added_ == ADD_ATOM);
173 atom = text_.RemoveLast(); 173 atom = text_.RemoveLast();
174 FlushText(); 174 FlushText();
175 } else if (terms_.length() > 0) { 175 } else if (terms_.length() > 0) {
176 DEBUG_ASSERT(last_added_ == ADD_ATOM); 176 DEBUG_ASSERT(last_added_ == ADD_ATOM);
177 atom = terms_.RemoveLast(); 177 atom = terms_.RemoveLast();
178 if (atom->max_match() == 0) { 178 if (atom->max_match() == 0) {
179 // Guaranteed to only match an empty string. 179 // Guaranteed to only match an empty string.
180 LAST(ADD_TERM); 180 LAST(ADD_TERM);
181 if (min == 0) { 181 if (min == 0) {
182 return; 182 return;
183 } 183 }
184 terms_.Add(atom); 184 terms_.Add(atom);
185 return; 185 return;
186 } 186 }
187 } else { 187 } else {
188 // Only call immediately after adding an atom or character! 188 // Only call immediately after adding an atom or character!
189 UNREACHABLE(); 189 UNREACHABLE();
190 return; 190 return;
191 } 191 }
192 terms_.Add(new(I) RegExpQuantifier(min, max, quantifier_type, atom)); 192 terms_.Add(new(Z) RegExpQuantifier(min, max, quantifier_type, atom));
193 LAST(ADD_TERM); 193 LAST(ADD_TERM);
194 } 194 }
195 195
196 // ---------------------------------------------------------------------------- 196 // ----------------------------------------------------------------------------
197 // Implementation of Parser 197 // Implementation of Parser
198 198
199 RegExpParser::RegExpParser(const String& in, 199 RegExpParser::RegExpParser(const String& in,
200 String* error, 200 String* error,
201 bool multiline) 201 bool multiline)
202 : isolate_(Isolate::Current()), 202 : zone_(Thread::Current()->zone()),
203 error_(error), 203 error_(error),
204 captures_(NULL), 204 captures_(NULL),
205 in_(in), 205 in_(in),
206 current_(kEndMarker), 206 current_(kEndMarker),
207 next_pos_(0), 207 next_pos_(0),
208 capture_count_(0), 208 capture_count_(0),
209 has_more_(true), 209 has_more_(true),
210 multiline_(multiline), 210 multiline_(multiline),
211 simple_(false), 211 simple_(false),
212 contains_anchor_(false), 212 contains_anchor_(false),
213 is_scanned_for_captures_(false), 213 is_scanned_for_captures_(false),
214 failed_(false) { 214 failed_(false) {
215 Advance(); 215 Advance();
216 } 216 }
217 217
218 218
219 bool RegExpParser::ParseFunction(ParsedFunction *parsed_function) { 219 bool RegExpParser::ParseFunction(ParsedFunction *parsed_function) {
220 Isolate* isolate = parsed_function->isolate(); 220 Zone* zone = parsed_function->zone();
221 JSRegExp& regexp = JSRegExp::Handle(parsed_function->function().regexp()); 221 JSRegExp& regexp = JSRegExp::Handle(parsed_function->function().regexp());
222 222
223 const String& pattern = String::Handle(regexp.pattern()); 223 const String& pattern = String::Handle(regexp.pattern());
224 const bool multiline = regexp.is_multi_line(); 224 const bool multiline = regexp.is_multi_line();
225 225
226 RegExpCompileData* compile_data = new(isolate) RegExpCompileData(); 226 RegExpCompileData* compile_data = new(zone) RegExpCompileData();
227 if (!RegExpParser::ParseRegExp(pattern, multiline, compile_data)) { 227 if (!RegExpParser::ParseRegExp(pattern, multiline, compile_data)) {
228 // Parsing failures are handled in the JSRegExp factory constructor. 228 // Parsing failures are handled in the JSRegExp factory constructor.
229 UNREACHABLE(); 229 UNREACHABLE();
230 } 230 }
231 231
232 regexp.set_num_bracket_expressions(compile_data->capture_count); 232 regexp.set_num_bracket_expressions(compile_data->capture_count);
233 if (compile_data->simple) { 233 if (compile_data->simple) {
234 regexp.set_is_simple(); 234 regexp.set_is_simple();
235 } else { 235 } else {
236 regexp.set_is_complex(); 236 regexp.set_is_complex();
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
312 // Alternative | Disjunction 312 // Alternative | Disjunction
313 // Alternative :: 313 // Alternative ::
314 // [empty] 314 // [empty]
315 // Term Alternative 315 // Term Alternative
316 // Term :: 316 // Term ::
317 // Assertion 317 // Assertion
318 // Atom 318 // Atom
319 // Atom Quantifier 319 // Atom Quantifier
320 RegExpTree* RegExpParser::ParseDisjunction() { 320 RegExpTree* RegExpParser::ParseDisjunction() {
321 // Used to store current state while parsing subexpressions. 321 // Used to store current state while parsing subexpressions.
322 RegExpParserState initial_state(NULL, INITIAL, 0, I); 322 RegExpParserState initial_state(NULL, INITIAL, 0, Z);
323 RegExpParserState* stored_state = &initial_state; 323 RegExpParserState* stored_state = &initial_state;
324 // Cache the builder in a local variable for quick access. 324 // Cache the builder in a local variable for quick access.
325 RegExpBuilder* builder = initial_state.builder(); 325 RegExpBuilder* builder = initial_state.builder();
326 while (true) { 326 while (true) {
327 switch (current()) { 327 switch (current()) {
328 case kEndMarker: 328 case kEndMarker:
329 if (stored_state->IsSubexpression()) { 329 if (stored_state->IsSubexpression()) {
330 // Inside a parenthesized group when hitting end of input. 330 // Inside a parenthesized group when hitting end of input.
331 ReportError("Unterminated group"); 331 ReportError("Unterminated group");
332 UNREACHABLE(); 332 UNREACHABLE();
(...skipping 17 matching lines...) Expand all
350 350
351 intptr_t capture_index = stored_state->capture_index(); 351 intptr_t capture_index = stored_state->capture_index();
352 SubexpressionType group_type = stored_state->group_type(); 352 SubexpressionType group_type = stored_state->group_type();
353 353
354 // Restore previous state. 354 // Restore previous state.
355 stored_state = stored_state->previous_state(); 355 stored_state = stored_state->previous_state();
356 builder = stored_state->builder(); 356 builder = stored_state->builder();
357 357
358 // Build result of subexpression. 358 // Build result of subexpression.
359 if (group_type == CAPTURE) { 359 if (group_type == CAPTURE) {
360 RegExpCapture* capture = new(I) RegExpCapture(body, capture_index); 360 RegExpCapture* capture = new(Z) RegExpCapture(body, capture_index);
361 (*captures_)[capture_index - 1] = capture; 361 (*captures_)[capture_index - 1] = capture;
362 body = capture; 362 body = capture;
363 } else if (group_type != GROUPING) { 363 } else if (group_type != GROUPING) {
364 ASSERT(group_type == POSITIVE_LOOKAHEAD || 364 ASSERT(group_type == POSITIVE_LOOKAHEAD ||
365 group_type == NEGATIVE_LOOKAHEAD); 365 group_type == NEGATIVE_LOOKAHEAD);
366 bool is_positive = (group_type == POSITIVE_LOOKAHEAD); 366 bool is_positive = (group_type == POSITIVE_LOOKAHEAD);
367 body = new(I) RegExpLookahead(body, 367 body = new(Z) RegExpLookahead(body,
368 is_positive, 368 is_positive,
369 end_capture_index - capture_index, 369 end_capture_index - capture_index,
370 capture_index); 370 capture_index);
371 } 371 }
372 builder->AddAtom(body); 372 builder->AddAtom(body);
373 // For compatibility with JSC and ES3, we allow quantifiers after 373 // For compatibility with JSC and ES3, we allow quantifiers after
374 // lookaheads, and break in all cases. 374 // lookaheads, and break in all cases.
375 break; 375 break;
376 } 376 }
377 case '|': { 377 case '|': {
378 Advance(); 378 Advance();
379 builder->NewAlternative(); 379 builder->NewAlternative();
380 continue; 380 continue;
381 } 381 }
382 case '*': 382 case '*':
383 case '+': 383 case '+':
384 case '?': 384 case '?':
385 ReportError("Nothing to repeat"); 385 ReportError("Nothing to repeat");
386 UNREACHABLE(); 386 UNREACHABLE();
387 case '^': { 387 case '^': {
388 Advance(); 388 Advance();
389 if (multiline_) { 389 if (multiline_) {
390 builder->AddAssertion( 390 builder->AddAssertion(
391 new(I) RegExpAssertion(RegExpAssertion::START_OF_LINE)); 391 new(Z) RegExpAssertion(RegExpAssertion::START_OF_LINE));
392 } else { 392 } else {
393 builder->AddAssertion( 393 builder->AddAssertion(
394 new(I) RegExpAssertion(RegExpAssertion::START_OF_INPUT)); 394 new(Z) RegExpAssertion(RegExpAssertion::START_OF_INPUT));
395 set_contains_anchor(); 395 set_contains_anchor();
396 } 396 }
397 continue; 397 continue;
398 } 398 }
399 case '$': { 399 case '$': {
400 Advance(); 400 Advance();
401 RegExpAssertion::AssertionType assertion_type = 401 RegExpAssertion::AssertionType assertion_type =
402 multiline_ ? RegExpAssertion::END_OF_LINE : 402 multiline_ ? RegExpAssertion::END_OF_LINE :
403 RegExpAssertion::END_OF_INPUT; 403 RegExpAssertion::END_OF_INPUT;
404 builder->AddAssertion(new RegExpAssertion(assertion_type)); 404 builder->AddAssertion(new RegExpAssertion(assertion_type));
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
438 captures_ = new ZoneGrowableArray<RegExpCapture*>(2); 438 captures_ = new ZoneGrowableArray<RegExpCapture*>(2);
439 } 439 }
440 if (captures_started() >= kMaxCaptures) { 440 if (captures_started() >= kMaxCaptures) {
441 ReportError("Too many captures"); 441 ReportError("Too many captures");
442 UNREACHABLE(); 442 UNREACHABLE();
443 } 443 }
444 captures_->Add(NULL); 444 captures_->Add(NULL);
445 } 445 }
446 // Store current state and begin new disjunction parsing. 446 // Store current state and begin new disjunction parsing.
447 stored_state = new RegExpParserState(stored_state, subexpr_type, 447 stored_state = new RegExpParserState(stored_state, subexpr_type,
448 captures_started(), I); 448 captures_started(), Z);
449 builder = stored_state->builder(); 449 builder = stored_state->builder();
450 continue; 450 continue;
451 } 451 }
452 case '[': { 452 case '[': {
453 RegExpTree* atom = ParseCharacterClass(); 453 RegExpTree* atom = ParseCharacterClass();
454 builder->AddAtom(atom); 454 builder->AddAtom(atom);
455 break; 455 break;
456 } 456 }
457 // Atom :: 457 // Atom ::
458 // \ AtomEscape 458 // \ AtomEscape
(...skipping 530 matching lines...) Expand 10 before | Expand all | Expand 10 after
989 static const char* kRangeOutOfOrder = "Range out of order in character class"; 989 static const char* kRangeOutOfOrder = "Range out of order in character class";
990 990
991 ASSERT(current() == '['); 991 ASSERT(current() == '[');
992 Advance(); 992 Advance();
993 bool is_negated = false; 993 bool is_negated = false;
994 if (current() == '^') { 994 if (current() == '^') {
995 is_negated = true; 995 is_negated = true;
996 Advance(); 996 Advance();
997 } 997 }
998 ZoneGrowableArray<CharacterRange>* ranges = 998 ZoneGrowableArray<CharacterRange>* ranges =
999 new(I) ZoneGrowableArray<CharacterRange>(2); 999 new(Z) ZoneGrowableArray<CharacterRange>(2);
1000 while (has_more() && current() != ']') { 1000 while (has_more() && current() != ']') {
1001 uint16_t char_class = kNoCharClass; 1001 uint16_t char_class = kNoCharClass;
1002 CharacterRange first = ParseClassAtom(&char_class); 1002 CharacterRange first = ParseClassAtom(&char_class);
1003 if (current() == '-') { 1003 if (current() == '-') {
1004 Advance(); 1004 Advance();
1005 if (current() == kEndMarker) { 1005 if (current() == kEndMarker) {
1006 // If we reach the end we break out of the loop and let the 1006 // If we reach the end we break out of the loop and let the
1007 // following code report an error. 1007 // following code report an error.
1008 break; 1008 break;
1009 } else if (current() == ']') { 1009 } else if (current() == ']') {
(...skipping 21 matching lines...) Expand all
1031 } 1031 }
1032 if (!has_more()) { 1032 if (!has_more()) {
1033 ReportError(kUnterminated); 1033 ReportError(kUnterminated);
1034 UNREACHABLE(); 1034 UNREACHABLE();
1035 } 1035 }
1036 Advance(); 1036 Advance();
1037 if (ranges->length() == 0) { 1037 if (ranges->length() == 0) {
1038 ranges->Add(CharacterRange::Everything()); 1038 ranges->Add(CharacterRange::Everything());
1039 is_negated = !is_negated; 1039 is_negated = !is_negated;
1040 } 1040 }
1041 return new(I) RegExpCharacterClass(ranges, is_negated); 1041 return new(Z) RegExpCharacterClass(ranges, is_negated);
1042 } 1042 }
1043 1043
1044 1044
1045 // ---------------------------------------------------------------------------- 1045 // ----------------------------------------------------------------------------
1046 // The Parser interface. 1046 // The Parser interface.
1047 1047
1048 bool RegExpParser::ParseRegExp(const String& input, 1048 bool RegExpParser::ParseRegExp(const String& input,
1049 bool multiline, 1049 bool multiline,
1050 RegExpCompileData* result) { 1050 RegExpCompileData* result) {
1051 ASSERT(result != NULL); 1051 ASSERT(result != NULL);
(...skipping 17 matching lines...) Expand all
1069 String::Concat(result->error, input)); 1069 String::Concat(result->error, input));
1070 const Array& args = Array::Handle(Array::New(1)); 1070 const Array& args = Array::Handle(Array::New(1));
1071 args.SetAt(0, message); 1071 args.SetAt(0, message);
1072 1072
1073 Exceptions::ThrowByType(Exceptions::kFormat, args); 1073 Exceptions::ThrowByType(Exceptions::kFormat, args);
1074 } 1074 }
1075 return !parser.failed(); 1075 return !parser.failed();
1076 } 1076 }
1077 1077
1078 } // namespace dart 1078 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698