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

Side by Side Diff: src/parsing/parser.cc

Issue 1439693002: [runtime] Support Proxy setPrototypeOf trap (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@2015-11-09_new_Proxy_1417063011
Patch Set: merging with master Created 5 years 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
« no previous file with comments | « src/parsing/parser.h ('k') | src/parsing/pattern-rewriter.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/parsing/parser.h" 5 #include "src/parsing/parser.h"
6 6
7 #include "src/api.h" 7 #include "src/api.h"
8 #include "src/ast/ast.h" 8 #include "src/ast/ast.h"
9 #include "src/ast/ast-literal-reindexer.h" 9 #include "src/ast/ast-literal-reindexer.h"
10 #include "src/ast/scopeinfo.h" 10 #include "src/ast/scopeinfo.h"
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 } 94 }
95 95
96 96
97 RegExpBuilder::RegExpBuilder(Zone* zone) 97 RegExpBuilder::RegExpBuilder(Zone* zone)
98 : zone_(zone), 98 : zone_(zone),
99 pending_empty_(false), 99 pending_empty_(false),
100 characters_(NULL), 100 characters_(NULL),
101 terms_(), 101 terms_(),
102 alternatives_() 102 alternatives_()
103 #ifdef DEBUG 103 #ifdef DEBUG
104 , last_added_(ADD_NONE) 104 ,
105 last_added_(ADD_NONE)
105 #endif 106 #endif
106 {} 107 {
108 }
107 109
108 110
109 void RegExpBuilder::FlushCharacters() { 111 void RegExpBuilder::FlushCharacters() {
110 pending_empty_ = false; 112 pending_empty_ = false;
111 if (characters_ != NULL) { 113 if (characters_ != NULL) {
112 RegExpTree* atom = new(zone()) RegExpAtom(characters_->ToConstVector()); 114 RegExpTree* atom = new (zone()) RegExpAtom(characters_->ToConstVector());
113 characters_ = NULL; 115 characters_ = NULL;
114 text_.Add(atom, zone()); 116 text_.Add(atom, zone());
115 LAST(ADD_ATOM); 117 LAST(ADD_ATOM);
116 } 118 }
117 } 119 }
118 120
119 121
120 void RegExpBuilder::FlushText() { 122 void RegExpBuilder::FlushText() {
121 FlushCharacters(); 123 FlushCharacters();
122 int num_text = text_.length(); 124 int num_text = text_.length();
123 if (num_text == 0) { 125 if (num_text == 0) {
124 return; 126 return;
125 } else if (num_text == 1) { 127 } else if (num_text == 1) {
126 terms_.Add(text_.last(), zone()); 128 terms_.Add(text_.last(), zone());
127 } else { 129 } else {
128 RegExpText* text = new(zone()) RegExpText(zone()); 130 RegExpText* text = new (zone()) RegExpText(zone());
129 for (int i = 0; i < num_text; i++) 131 for (int i = 0; i < num_text; i++) text_.Get(i)->AppendToText(text, zone());
130 text_.Get(i)->AppendToText(text, zone());
131 terms_.Add(text, zone()); 132 terms_.Add(text, zone());
132 } 133 }
133 text_.Clear(); 134 text_.Clear();
134 } 135 }
135 136
136 137
137 void RegExpBuilder::AddCharacter(uc16 c) { 138 void RegExpBuilder::AddCharacter(uc16 c) {
138 pending_empty_ = false; 139 pending_empty_ = false;
139 if (characters_ == NULL) { 140 if (characters_ == NULL) {
140 characters_ = new(zone()) ZoneList<uc16>(4, zone()); 141 characters_ = new (zone()) ZoneList<uc16>(4, zone());
141 } 142 }
142 characters_->Add(c, zone()); 143 characters_->Add(c, zone());
143 LAST(ADD_CHAR); 144 LAST(ADD_CHAR);
144 } 145 }
145 146
146 147
147 void RegExpBuilder::AddEmpty() { 148 void RegExpBuilder::AddEmpty() { pending_empty_ = true; }
148 pending_empty_ = true;
149 }
150 149
151 150
152 void RegExpBuilder::AddAtom(RegExpTree* term) { 151 void RegExpBuilder::AddAtom(RegExpTree* term) {
153 if (term->IsEmpty()) { 152 if (term->IsEmpty()) {
154 AddEmpty(); 153 AddEmpty();
155 return; 154 return;
156 } 155 }
157 if (term->IsTextElement()) { 156 if (term->IsTextElement()) {
158 FlushCharacters(); 157 FlushCharacters();
159 text_.Add(term, zone()); 158 text_.Add(term, zone());
160 } else { 159 } else {
161 FlushText(); 160 FlushText();
162 terms_.Add(term, zone()); 161 terms_.Add(term, zone());
163 } 162 }
164 LAST(ADD_ATOM); 163 LAST(ADD_ATOM);
165 } 164 }
166 165
167 166
168 void RegExpBuilder::AddAssertion(RegExpTree* assert) { 167 void RegExpBuilder::AddAssertion(RegExpTree* assert) {
169 FlushText(); 168 FlushText();
170 terms_.Add(assert, zone()); 169 terms_.Add(assert, zone());
171 LAST(ADD_ASSERT); 170 LAST(ADD_ASSERT);
172 } 171 }
173 172
174 173
175 void RegExpBuilder::NewAlternative() { 174 void RegExpBuilder::NewAlternative() { FlushTerms(); }
176 FlushTerms();
177 }
178 175
179 176
180 void RegExpBuilder::FlushTerms() { 177 void RegExpBuilder::FlushTerms() {
181 FlushText(); 178 FlushText();
182 int num_terms = terms_.length(); 179 int num_terms = terms_.length();
183 RegExpTree* alternative; 180 RegExpTree* alternative;
184 if (num_terms == 0) { 181 if (num_terms == 0) {
185 alternative = new (zone()) RegExpEmpty(); 182 alternative = new (zone()) RegExpEmpty();
186 } else if (num_terms == 1) { 183 } else if (num_terms == 1) {
187 alternative = terms_.last(); 184 alternative = terms_.last();
188 } else { 185 } else {
189 alternative = new(zone()) RegExpAlternative(terms_.GetList(zone())); 186 alternative = new (zone()) RegExpAlternative(terms_.GetList(zone()));
190 } 187 }
191 alternatives_.Add(alternative, zone()); 188 alternatives_.Add(alternative, zone());
192 terms_.Clear(); 189 terms_.Clear();
193 LAST(ADD_NONE); 190 LAST(ADD_NONE);
194 } 191 }
195 192
196 193
197 RegExpTree* RegExpBuilder::ToRegExp() { 194 RegExpTree* RegExpBuilder::ToRegExp() {
198 FlushTerms(); 195 FlushTerms();
199 int num_alternatives = alternatives_.length(); 196 int num_alternatives = alternatives_.length();
200 if (num_alternatives == 0) return new (zone()) RegExpEmpty(); 197 if (num_alternatives == 0) return new (zone()) RegExpEmpty();
201 if (num_alternatives == 1) return alternatives_.last(); 198 if (num_alternatives == 1) return alternatives_.last();
202 return new(zone()) RegExpDisjunction(alternatives_.GetList(zone())); 199 return new (zone()) RegExpDisjunction(alternatives_.GetList(zone()));
203 } 200 }
204 201
205 202
206 void RegExpBuilder::AddQuantifierToAtom( 203 void RegExpBuilder::AddQuantifierToAtom(
207 int min, int max, RegExpQuantifier::QuantifierType quantifier_type) { 204 int min, int max, RegExpQuantifier::QuantifierType quantifier_type) {
208 if (pending_empty_) { 205 if (pending_empty_) {
209 pending_empty_ = false; 206 pending_empty_ = false;
210 return; 207 return;
211 } 208 }
212 RegExpTree* atom; 209 RegExpTree* atom;
213 if (characters_ != NULL) { 210 if (characters_ != NULL) {
214 DCHECK(last_added_ == ADD_CHAR); 211 DCHECK(last_added_ == ADD_CHAR);
215 // Last atom was character. 212 // Last atom was character.
216 Vector<const uc16> char_vector = characters_->ToConstVector(); 213 Vector<const uc16> char_vector = characters_->ToConstVector();
217 int num_chars = char_vector.length(); 214 int num_chars = char_vector.length();
218 if (num_chars > 1) { 215 if (num_chars > 1) {
219 Vector<const uc16> prefix = char_vector.SubVector(0, num_chars - 1); 216 Vector<const uc16> prefix = char_vector.SubVector(0, num_chars - 1);
220 text_.Add(new(zone()) RegExpAtom(prefix), zone()); 217 text_.Add(new (zone()) RegExpAtom(prefix), zone());
221 char_vector = char_vector.SubVector(num_chars - 1, num_chars); 218 char_vector = char_vector.SubVector(num_chars - 1, num_chars);
222 } 219 }
223 characters_ = NULL; 220 characters_ = NULL;
224 atom = new(zone()) RegExpAtom(char_vector); 221 atom = new (zone()) RegExpAtom(char_vector);
225 FlushText(); 222 FlushText();
226 } else if (text_.length() > 0) { 223 } else if (text_.length() > 0) {
227 DCHECK(last_added_ == ADD_ATOM); 224 DCHECK(last_added_ == ADD_ATOM);
228 atom = text_.RemoveLast(); 225 atom = text_.RemoveLast();
229 FlushText(); 226 FlushText();
230 } else if (terms_.length() > 0) { 227 } else if (terms_.length() > 0) {
231 DCHECK(last_added_ == ADD_ATOM); 228 DCHECK(last_added_ == ADD_ATOM);
232 atom = terms_.RemoveLast(); 229 atom = terms_.RemoveLast();
233 if (atom->max_match() == 0) { 230 if (atom->max_match() == 0) {
234 // Guaranteed to only match an empty string. 231 // Guaranteed to only match an empty string.
235 LAST(ADD_TERM); 232 LAST(ADD_TERM);
236 if (min == 0) { 233 if (min == 0) {
237 return; 234 return;
238 } 235 }
239 terms_.Add(atom, zone()); 236 terms_.Add(atom, zone());
240 return; 237 return;
241 } 238 }
242 } else { 239 } else {
243 // Only call immediately after adding an atom or character! 240 // Only call immediately after adding an atom or character!
244 UNREACHABLE(); 241 UNREACHABLE();
245 return; 242 return;
246 } 243 }
247 terms_.Add( 244 terms_.Add(new (zone()) RegExpQuantifier(min, max, quantifier_type, atom),
248 new(zone()) RegExpQuantifier(min, max, quantifier_type, atom), zone()); 245 zone());
249 LAST(ADD_TERM); 246 LAST(ADD_TERM);
250 } 247 }
251 248
252 249
253 FunctionEntry ParseData::GetFunctionEntry(int start) { 250 FunctionEntry ParseData::GetFunctionEntry(int start) {
254 // The current pre-data entry must be a FunctionEntry with the given 251 // The current pre-data entry must be a FunctionEntry with the given
255 // start position. 252 // start position.
256 if ((function_index_ + FunctionEntry::kSize <= Length()) && 253 if ((function_index_ + FunctionEntry::kSize <= Length()) &&
257 (static_cast<int>(Data()[function_index_]) == start)) { 254 (static_cast<int>(Data()[function_index_]) == start)) {
258 int index = function_index_; 255 int index = function_index_;
(...skipping 20 matching lines...) Expand all
279 int data_length = Length(); 276 int data_length = Length();
280 if (data_length < PreparseDataConstants::kHeaderSize) return false; 277 if (data_length < PreparseDataConstants::kHeaderSize) return false;
281 if (Magic() != PreparseDataConstants::kMagicNumber) return false; 278 if (Magic() != PreparseDataConstants::kMagicNumber) return false;
282 if (Version() != PreparseDataConstants::kCurrentVersion) return false; 279 if (Version() != PreparseDataConstants::kCurrentVersion) return false;
283 if (HasError()) return false; 280 if (HasError()) return false;
284 // Check that the space allocated for function entries is sane. 281 // Check that the space allocated for function entries is sane.
285 int functions_size = FunctionsSize(); 282 int functions_size = FunctionsSize();
286 if (functions_size < 0) return false; 283 if (functions_size < 0) return false;
287 if (functions_size % FunctionEntry::kSize != 0) return false; 284 if (functions_size % FunctionEntry::kSize != 0) return false;
288 // Check that the total size has room for header and function entries. 285 // Check that the total size has room for header and function entries.
289 int minimum_size = 286 int minimum_size = PreparseDataConstants::kHeaderSize + functions_size;
290 PreparseDataConstants::kHeaderSize + functions_size;
291 if (data_length < minimum_size) return false; 287 if (data_length < minimum_size) return false;
292 return true; 288 return true;
293 } 289 }
294 290
295 291
296 void ParseData::Initialize() { 292 void ParseData::Initialize() {
297 // Prepares state for use. 293 // Prepares state for use.
298 int data_length = Length(); 294 int data_length = Length();
299 if (data_length >= PreparseDataConstants::kHeaderSize) { 295 if (data_length >= PreparseDataConstants::kHeaderSize) {
300 function_index_ = PreparseDataConstants::kHeaderSize; 296 function_index_ = PreparseDataConstants::kHeaderSize;
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 // 'continue' statement targets). Upon construction, a new target is 398 // 'continue' statement targets). Upon construction, a new target is
403 // added; it is removed upon destruction. 399 // added; it is removed upon destruction.
404 400
405 class Target BASE_EMBEDDED { 401 class Target BASE_EMBEDDED {
406 public: 402 public:
407 Target(Target** variable, BreakableStatement* statement) 403 Target(Target** variable, BreakableStatement* statement)
408 : variable_(variable), statement_(statement), previous_(*variable) { 404 : variable_(variable), statement_(statement), previous_(*variable) {
409 *variable = this; 405 *variable = this;
410 } 406 }
411 407
412 ~Target() { 408 ~Target() { *variable_ = previous_; }
413 *variable_ = previous_;
414 }
415 409
416 Target* previous() { return previous_; } 410 Target* previous() { return previous_; }
417 BreakableStatement* statement() { return statement_; } 411 BreakableStatement* statement() { return statement_; }
418 412
419 private: 413 private:
420 Target** variable_; 414 Target** variable_;
421 BreakableStatement* statement_; 415 BreakableStatement* statement_;
422 Target* previous_; 416 Target* previous_;
423 }; 417 };
424 418
425 419
426 class TargetScope BASE_EMBEDDED { 420 class TargetScope BASE_EMBEDDED {
427 public: 421 public:
428 explicit TargetScope(Target** variable) 422 explicit TargetScope(Target** variable)
429 : variable_(variable), previous_(*variable) { 423 : variable_(variable), previous_(*variable) {
430 *variable = NULL; 424 *variable = NULL;
431 } 425 }
432 426
433 ~TargetScope() { 427 ~TargetScope() { *variable_ = previous_; }
434 *variable_ = previous_;
435 }
436 428
437 private: 429 private:
438 Target** variable_; 430 Target** variable_;
439 Target* previous_; 431 Target* previous_;
440 }; 432 };
441 433
442 434
443 // ---------------------------------------------------------------------------- 435 // ----------------------------------------------------------------------------
444 // The CHECK_OK macro is a convenient macro to enforce error 436 // The CHECK_OK macro is a convenient macro to enforce error
445 // handling for functions that may fail (by returning !*ok). 437 // handling for functions that may fail (by returning !*ok).
446 // 438 //
447 // CAUTION: This macro appends extra statements after a call, 439 // CAUTION: This macro appends extra statements after a call,
448 // thus it must never be used where only a single statement 440 // thus it must never be used where only a single statement
449 // is correct (e.g. an if statement branch w/o braces)! 441 // is correct (e.g. an if statement branch w/o braces)!
450 442
451 #define CHECK_OK ok); \ 443 #define CHECK_OK ok); \
452 if (!*ok) return NULL; \ 444 if (!*ok) return NULL; \
453 ((void)0 445 ((void)0
454 #define DUMMY ) // to make indentation work 446 #define DUMMY ) // to make indentation work
455 #undef DUMMY 447 #undef DUMMY
456 448
457 #define CHECK_FAILED /**/); \ 449 #define CHECK_FAILED /**/); \
458 if (failed_) return NULL; \ 450 if (failed_) return NULL; \
459 ((void)0 451 ((void)0
460 #define DUMMY ) // to make indentation work 452 #define DUMMY ) // to make indentation work
461 #undef DUMMY 453 #undef DUMMY
462 454
463 // ---------------------------------------------------------------------------- 455 // ----------------------------------------------------------------------------
464 // Implementation of Parser 456 // Implementation of Parser
465 457
466 bool ParserTraits::IsEval(const AstRawString* identifier) const { 458 bool ParserTraits::IsEval(const AstRawString* identifier) const {
467 return identifier == parser_->ast_value_factory()->eval_string(); 459 return identifier == parser_->ast_value_factory()->eval_string();
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
518 510
519 void ParserTraits::CheckAssigningFunctionLiteralToProperty(Expression* left, 511 void ParserTraits::CheckAssigningFunctionLiteralToProperty(Expression* left,
520 Expression* right) { 512 Expression* right) {
521 DCHECK(left != NULL); 513 DCHECK(left != NULL);
522 if (left->IsProperty() && right->IsFunctionLiteral()) { 514 if (left->IsProperty() && right->IsFunctionLiteral()) {
523 right->AsFunctionLiteral()->set_pretenure(); 515 right->AsFunctionLiteral()->set_pretenure();
524 } 516 }
525 } 517 }
526 518
527 519
528 void ParserTraits::CheckPossibleEvalCall(Expression* expression, 520 void ParserTraits::CheckPossibleEvalCall(Expression* expression, Scope* scope) {
529 Scope* scope) {
530 VariableProxy* callee = expression->AsVariableProxy(); 521 VariableProxy* callee = expression->AsVariableProxy();
531 if (callee != NULL && 522 if (callee != NULL &&
532 callee->raw_name() == parser_->ast_value_factory()->eval_string()) { 523 callee->raw_name() == parser_->ast_value_factory()->eval_string()) {
533 scope->DeclarationScope()->RecordEvalCall(); 524 scope->DeclarationScope()->RecordEvalCall();
534 scope->RecordEvalCall(); 525 scope->RecordEvalCall();
535 } 526 }
536 } 527 }
537 528
538 529
539 Expression* ParserTraits::MarkExpressionAsAssigned(Expression* expression) { 530 Expression* ParserTraits::MarkExpressionAsAssigned(Expression* expression) {
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
629 } 620 }
630 } 621 }
631 } 622 }
632 // Desugar '+foo' => 'foo*1' 623 // Desugar '+foo' => 'foo*1'
633 if (op == Token::ADD) { 624 if (op == Token::ADD) {
634 return factory->NewBinaryOperation( 625 return factory->NewBinaryOperation(
635 Token::MUL, expression, factory->NewNumberLiteral(1, pos, true), pos); 626 Token::MUL, expression, factory->NewNumberLiteral(1, pos, true), pos);
636 } 627 }
637 // The same idea for '-foo' => 'foo*(-1)'. 628 // The same idea for '-foo' => 'foo*(-1)'.
638 if (op == Token::SUB) { 629 if (op == Token::SUB) {
639 return factory->NewBinaryOperation( 630 return factory->NewBinaryOperation(Token::MUL, expression,
640 Token::MUL, expression, factory->NewNumberLiteral(-1, pos), pos); 631 factory->NewNumberLiteral(-1, pos), pos);
641 } 632 }
642 // ...and one more time for '~foo' => 'foo^(~0)'. 633 // ...and one more time for '~foo' => 'foo^(~0)'.
643 if (op == Token::BIT_NOT) { 634 if (op == Token::BIT_NOT) {
644 return factory->NewBinaryOperation( 635 return factory->NewBinaryOperation(Token::BIT_XOR, expression,
645 Token::BIT_XOR, expression, factory->NewNumberLiteral(~0, pos), pos); 636 factory->NewNumberLiteral(~0, pos), pos);
646 } 637 }
647 return factory->NewUnaryOperation(op, expression, pos); 638 return factory->NewUnaryOperation(op, expression, pos);
648 } 639 }
649 640
650 641
651 Expression* ParserTraits::NewThrowReferenceError( 642 Expression* ParserTraits::NewThrowReferenceError(
652 MessageTemplate::Template message, int pos) { 643 MessageTemplate::Template message, int pos) {
653 return NewThrowError(Runtime::kNewReferenceError, message, 644 return NewThrowError(Runtime::kNewReferenceError, message,
654 parser_->ast_value_factory()->empty_string(), pos); 645 parser_->ast_value_factory()->empty_string(), pos);
655 } 646 }
(...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after
1044 1035
1045 // Enter 'scope' with the given parsing mode. 1036 // Enter 'scope' with the given parsing mode.
1046 ParsingModeScope parsing_mode_scope(this, parsing_mode); 1037 ParsingModeScope parsing_mode_scope(this, parsing_mode);
1047 AstNodeFactory function_factory(ast_value_factory()); 1038 AstNodeFactory function_factory(ast_value_factory());
1048 FunctionState function_state(&function_state_, &scope_, scope, 1039 FunctionState function_state(&function_state_, &scope_, scope,
1049 kNormalFunction, &function_factory); 1040 kNormalFunction, &function_factory);
1050 1041
1051 // Don't count the mode in the use counters--give the program a chance 1042 // Don't count the mode in the use counters--give the program a chance
1052 // to enable script/module-wide strict/strong mode below. 1043 // to enable script/module-wide strict/strong mode below.
1053 scope_->SetLanguageMode(info->language_mode()); 1044 scope_->SetLanguageMode(info->language_mode());
1054 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); 1045 ZoneList<Statement*>* body = new (zone()) ZoneList<Statement*>(16, zone());
1055 bool ok = true; 1046 bool ok = true;
1056 int beg_pos = scanner()->location().beg_pos; 1047 int beg_pos = scanner()->location().beg_pos;
1057 if (info->is_module()) { 1048 if (info->is_module()) {
1058 ParseModuleItemList(body, &ok); 1049 ParseModuleItemList(body, &ok);
1059 } else { 1050 } else {
1060 ParseStatementList(body, Token::EOS, &ok); 1051 ParseStatementList(body, Token::EOS, &ok);
1061 } 1052 }
1062 1053
1063 // The parser will peek but not consume EOS. Our scope logically goes all 1054 // The parser will peek but not consume EOS. Our scope logically goes all
1064 // the way to the EOS, though. 1055 // the way to the EOS, though.
1065 scope->set_end_position(scanner()->peek_location().beg_pos); 1056 scope->set_end_position(scanner()->peek_location().beg_pos);
1066 1057
1067 if (ok && is_strict(language_mode())) { 1058 if (ok && is_strict(language_mode())) {
1068 CheckStrictOctalLiteral(beg_pos, scanner()->location().end_pos, &ok); 1059 CheckStrictOctalLiteral(beg_pos, scanner()->location().end_pos, &ok);
1069 } 1060 }
1070 if (ok && is_sloppy(language_mode()) && allow_harmony_sloppy_function()) { 1061 if (ok && is_sloppy(language_mode()) && allow_harmony_sloppy_function()) {
1071 // TODO(littledan): Function bindings on the global object that modify 1062 // TODO(littledan): Function bindings on the global object that modify
1072 // pre-existing bindings should be made writable, enumerable and 1063 // pre-existing bindings should be made writable, enumerable and
1073 // nonconfigurable if possible, whereas this code will leave attributes 1064 // nonconfigurable if possible, whereas this code will leave attributes
1074 // unchanged if the property already exists. 1065 // unchanged if the property already exists.
1075 InsertSloppyBlockFunctionVarBindings(scope, &ok); 1066 InsertSloppyBlockFunctionVarBindings(scope, &ok);
1076 } 1067 }
1077 if (ok && (is_strict(language_mode()) || allow_harmony_sloppy() || 1068 if (ok && (is_strict(language_mode()) || allow_harmony_sloppy() ||
1078 allow_harmony_destructuring_bind())) { 1069 allow_harmony_destructuring_bind())) {
1079 CheckConflictingVarDeclarations(scope_, &ok); 1070 CheckConflictingVarDeclarations(scope_, &ok);
1080 } 1071 }
1081 1072
1082 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { 1073 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) {
1083 if (body->length() != 1 || 1074 if (body->length() != 1 || !body->at(0)->IsExpressionStatement() ||
1084 !body->at(0)->IsExpressionStatement() || 1075 !body->at(0)
1085 !body->at(0)->AsExpressionStatement()-> 1076 ->AsExpressionStatement()
1086 expression()->IsFunctionLiteral()) { 1077 ->expression()
1078 ->IsFunctionLiteral()) {
1087 ReportMessage(MessageTemplate::kSingleFunctionLiteral); 1079 ReportMessage(MessageTemplate::kSingleFunctionLiteral);
1088 ok = false; 1080 ok = false;
1089 } 1081 }
1090 } 1082 }
1091 1083
1092 if (ok) { 1084 if (ok) {
1093 result = factory()->NewFunctionLiteral( 1085 result = factory()->NewFunctionLiteral(
1094 ast_value_factory()->empty_string(), ast_value_factory(), scope_, 1086 ast_value_factory()->empty_string(), ast_value_factory(), scope_,
1095 body, function_state.materialized_literal_count(), 1087 body, function_state.materialized_literal_count(),
1096 function_state.expected_property_count(), 0, 1088 function_state.expected_property_count(), 0,
(...skipping 23 matching lines...) Expand all
1120 timer.Start(); 1112 timer.Start();
1121 } 1113 }
1122 Handle<SharedFunctionInfo> shared_info = info->shared_info(); 1114 Handle<SharedFunctionInfo> shared_info = info->shared_info();
1123 1115
1124 // Initialize parser state. 1116 // Initialize parser state.
1125 source = String::Flatten(source); 1117 source = String::Flatten(source);
1126 FunctionLiteral* result; 1118 FunctionLiteral* result;
1127 if (source->IsExternalTwoByteString()) { 1119 if (source->IsExternalTwoByteString()) {
1128 ExternalTwoByteStringUtf16CharacterStream stream( 1120 ExternalTwoByteStringUtf16CharacterStream stream(
1129 Handle<ExternalTwoByteString>::cast(source), 1121 Handle<ExternalTwoByteString>::cast(source),
1130 shared_info->start_position(), 1122 shared_info->start_position(), shared_info->end_position());
1131 shared_info->end_position());
1132 result = ParseLazy(isolate, info, &stream); 1123 result = ParseLazy(isolate, info, &stream);
1133 } else { 1124 } else {
1134 GenericStringUtf16CharacterStream stream(source, 1125 GenericStringUtf16CharacterStream stream(
1135 shared_info->start_position(), 1126 source, shared_info->start_position(), shared_info->end_position());
1136 shared_info->end_position());
1137 result = ParseLazy(isolate, info, &stream); 1127 result = ParseLazy(isolate, info, &stream);
1138 } 1128 }
1139 1129
1140 if (FLAG_trace_parse && result != NULL) { 1130 if (FLAG_trace_parse && result != NULL) {
1141 double ms = timer.Elapsed().InMillisecondsF(); 1131 double ms = timer.Elapsed().InMillisecondsF();
1142 base::SmartArrayPointer<char> name_chars = 1132 base::SmartArrayPointer<char> name_chars =
1143 result->debug_name()->ToCString(); 1133 result->debug_name()->ToCString();
1144 PrintF("[parsing function: %s - took %0.3f ms]\n", name_chars.get(), ms); 1134 PrintF("[parsing function: %s - took %0.3f ms]\n", name_chars.get(), ms);
1145 } 1135 }
1146 return result; 1136 return result;
(...skipping 29 matching lines...) Expand all
1176 scope = Scope::DeserializeScopeChain(isolate, zone(), 1166 scope = Scope::DeserializeScopeChain(isolate, zone(),
1177 info->closure()->context(), scope); 1167 info->closure()->context(), scope);
1178 } 1168 }
1179 original_scope_ = scope; 1169 original_scope_ = scope;
1180 AstNodeFactory function_factory(ast_value_factory()); 1170 AstNodeFactory function_factory(ast_value_factory());
1181 FunctionState function_state(&function_state_, &scope_, scope, 1171 FunctionState function_state(&function_state_, &scope_, scope,
1182 shared_info->kind(), &function_factory); 1172 shared_info->kind(), &function_factory);
1183 DCHECK(is_sloppy(scope->language_mode()) || 1173 DCHECK(is_sloppy(scope->language_mode()) ||
1184 is_strict(info->language_mode())); 1174 is_strict(info->language_mode()));
1185 DCHECK(info->language_mode() == shared_info->language_mode()); 1175 DCHECK(info->language_mode() == shared_info->language_mode());
1186 FunctionLiteral::FunctionType function_type = shared_info->is_expression() 1176 FunctionLiteral::FunctionType function_type =
1187 ? (shared_info->is_anonymous() 1177 shared_info->is_expression()
1188 ? FunctionLiteral::ANONYMOUS_EXPRESSION 1178 ? (shared_info->is_anonymous()
1189 : FunctionLiteral::NAMED_EXPRESSION) 1179 ? FunctionLiteral::ANONYMOUS_EXPRESSION
1190 : FunctionLiteral::DECLARATION; 1180 : FunctionLiteral::NAMED_EXPRESSION)
1181 : FunctionLiteral::DECLARATION;
1191 bool ok = true; 1182 bool ok = true;
1192 1183
1193 if (shared_info->is_arrow()) { 1184 if (shared_info->is_arrow()) {
1194 Scope* scope = 1185 Scope* scope =
1195 NewScope(scope_, FUNCTION_SCOPE, FunctionKind::kArrowFunction); 1186 NewScope(scope_, FUNCTION_SCOPE, FunctionKind::kArrowFunction);
1196 SetLanguageMode(scope, shared_info->language_mode()); 1187 SetLanguageMode(scope, shared_info->language_mode());
1197 scope->set_start_position(shared_info->start_position()); 1188 scope->set_start_position(shared_info->start_position());
1198 ExpressionClassifier formals_classifier; 1189 ExpressionClassifier formals_classifier;
1199 ParserFormalParameters formals(scope); 1190 ParserFormalParameters formals(scope);
1200 Checkpoint checkpoint(this); 1191 Checkpoint checkpoint(this);
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1271 // StatementList :: 1262 // StatementList ::
1272 // (StatementListItem)* <end_token> 1263 // (StatementListItem)* <end_token>
1273 1264
1274 // Allocate a target stack to use for this set of source 1265 // Allocate a target stack to use for this set of source
1275 // elements. This way, all scripts and functions get their own 1266 // elements. This way, all scripts and functions get their own
1276 // target stack thus avoiding illegal breaks and continues across 1267 // target stack thus avoiding illegal breaks and continues across
1277 // functions. 1268 // functions.
1278 TargetScope scope(&this->target_stack_); 1269 TargetScope scope(&this->target_stack_);
1279 1270
1280 DCHECK(body != NULL); 1271 DCHECK(body != NULL);
1281 bool directive_prologue = true; // Parsing directive prologue. 1272 bool directive_prologue = true; // Parsing directive prologue.
1282 1273
1283 while (peek() != end_token) { 1274 while (peek() != end_token) {
1284 if (directive_prologue && peek() != Token::STRING) { 1275 if (directive_prologue && peek() != Token::STRING) {
1285 directive_prologue = false; 1276 directive_prologue = false;
1286 } 1277 }
1287 1278
1288 Scanner::Location token_loc = scanner()->peek_location(); 1279 Scanner::Location token_loc = scanner()->peek_location();
1289 Scanner::Location old_this_loc = function_state_->this_location(); 1280 Scanner::Location old_this_loc = function_state_->this_location();
1290 Scanner::Location old_super_loc = function_state_->super_location(); 1281 Scanner::Location old_super_loc = function_state_->super_location();
1291 Statement* stat = ParseStatementListItem(CHECK_OK); 1282 Statement* stat = ParseStatementListItem(CHECK_OK);
(...skipping 10 matching lines...) Expand all
1302 } 1293 }
1303 if (super_loc.beg_pos != old_super_loc.beg_pos && 1294 if (super_loc.beg_pos != old_super_loc.beg_pos &&
1304 super_loc.beg_pos != token_loc.beg_pos) { 1295 super_loc.beg_pos != token_loc.beg_pos) {
1305 ReportMessageAt(super_loc, MessageTemplate::kStrongConstructorSuper); 1296 ReportMessageAt(super_loc, MessageTemplate::kStrongConstructorSuper);
1306 *ok = false; 1297 *ok = false;
1307 return nullptr; 1298 return nullptr;
1308 } 1299 }
1309 } 1300 }
1310 1301
1311 if (stat == NULL || stat->IsEmpty()) { 1302 if (stat == NULL || stat->IsEmpty()) {
1312 directive_prologue = false; // End of directive prologue. 1303 directive_prologue = false; // End of directive prologue.
1313 continue; 1304 continue;
1314 } 1305 }
1315 1306
1316 if (directive_prologue) { 1307 if (directive_prologue) {
1317 // A shot at a directive. 1308 // A shot at a directive.
1318 ExpressionStatement* e_stat; 1309 ExpressionStatement* e_stat;
1319 Literal* literal; 1310 Literal* literal;
1320 // Still processing directive prologue? 1311 // Still processing directive prologue?
1321 if ((e_stat = stat->AsExpressionStatement()) != NULL && 1312 if ((e_stat = stat->AsExpressionStatement()) != NULL &&
1322 (literal = e_stat->expression()->AsLiteral()) != NULL && 1313 (literal = e_stat->expression()->AsLiteral()) != NULL &&
(...skipping 908 matching lines...) Expand 10 before | Expand all | Expand 10 after
2231 ZoneList<const AstRawString*>* names, bool* ok) { 2222 ZoneList<const AstRawString*>* names, bool* ok) {
2232 // FunctionDeclaration :: 2223 // FunctionDeclaration ::
2233 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' 2224 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
2234 // GeneratorDeclaration :: 2225 // GeneratorDeclaration ::
2235 // 'function' '*' Identifier '(' FormalParameterListopt ')' 2226 // 'function' '*' Identifier '(' FormalParameterListopt ')'
2236 // '{' FunctionBody '}' 2227 // '{' FunctionBody '}'
2237 Expect(Token::FUNCTION, CHECK_OK); 2228 Expect(Token::FUNCTION, CHECK_OK);
2238 int pos = position(); 2229 int pos = position();
2239 bool is_generator = Check(Token::MUL); 2230 bool is_generator = Check(Token::MUL);
2240 bool is_strict_reserved = false; 2231 bool is_strict_reserved = false;
2241 const AstRawString* name = ParseIdentifierOrStrictReservedWord( 2232 const AstRawString* name =
2242 &is_strict_reserved, CHECK_OK); 2233 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
2243 2234
2244 if (fni_ != NULL) { 2235 if (fni_ != NULL) {
2245 fni_->Enter(); 2236 fni_->Enter();
2246 fni_->PushEnclosingName(name); 2237 fni_->PushEnclosingName(name);
2247 } 2238 }
2248 FunctionLiteral* fun = ParseFunctionLiteral( 2239 FunctionLiteral* fun = ParseFunctionLiteral(
2249 name, scanner()->location(), 2240 name, scanner()->location(),
2250 is_strict_reserved ? kFunctionNameIsStrictReserved 2241 is_strict_reserved ? kFunctionNameIsStrictReserved
2251 : kFunctionNameValidityUnknown, 2242 : kFunctionNameValidityUnknown,
2252 is_generator ? FunctionKind::kGeneratorFunction 2243 is_generator ? FunctionKind::kGeneratorFunction
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
2349 } 2340 }
2350 2341
2351 2342
2352 Block* Parser::ParseBlock(ZoneList<const AstRawString*>* labels, bool* ok) { 2343 Block* Parser::ParseBlock(ZoneList<const AstRawString*>* labels, bool* ok) {
2353 // The harmony mode uses block elements instead of statements. 2344 // The harmony mode uses block elements instead of statements.
2354 // 2345 //
2355 // Block :: 2346 // Block ::
2356 // '{' StatementList '}' 2347 // '{' StatementList '}'
2357 2348
2358 // Construct block expecting 16 statements. 2349 // Construct block expecting 16 statements.
2359 Block* body = 2350 Block* body = factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition);
2360 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition);
2361 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE); 2351 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE);
2362 2352
2363 // Parse the statements and collect escaping labels. 2353 // Parse the statements and collect escaping labels.
2364 Expect(Token::LBRACE, CHECK_OK); 2354 Expect(Token::LBRACE, CHECK_OK);
2365 block_scope->set_start_position(scanner()->location().beg_pos); 2355 block_scope->set_start_position(scanner()->location().beg_pos);
2366 { BlockState block_state(&scope_, block_scope); 2356 {
2357 BlockState block_state(&scope_, block_scope);
2367 Target target(&this->target_stack_, body); 2358 Target target(&this->target_stack_, body);
2368 2359
2369 while (peek() != Token::RBRACE) { 2360 while (peek() != Token::RBRACE) {
2370 Statement* stat = ParseStatementListItem(CHECK_OK); 2361 Statement* stat = ParseStatementListItem(CHECK_OK);
2371 if (stat && !stat->IsEmpty()) { 2362 if (stat && !stat->IsEmpty()) {
2372 body->statements()->Add(stat, zone()); 2363 body->statements()->Add(stat, zone());
2373 } 2364 }
2374 } 2365 }
2375 } 2366 }
2376 Expect(Token::RBRACE, CHECK_OK); 2367 Expect(Token::RBRACE, CHECK_OK);
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
2585 2576
2586 parsing_result->bindings_loc = 2577 parsing_result->bindings_loc =
2587 Scanner::Location(bindings_start, scanner()->location().end_pos); 2578 Scanner::Location(bindings_start, scanner()->location().end_pos);
2588 } 2579 }
2589 2580
2590 2581
2591 static bool ContainsLabel(ZoneList<const AstRawString*>* labels, 2582 static bool ContainsLabel(ZoneList<const AstRawString*>* labels,
2592 const AstRawString* label) { 2583 const AstRawString* label) {
2593 DCHECK(label != NULL); 2584 DCHECK(label != NULL);
2594 if (labels != NULL) { 2585 if (labels != NULL) {
2595 for (int i = labels->length(); i-- > 0; ) { 2586 for (int i = labels->length(); i-- > 0;) {
2596 if (labels->at(i) == label) { 2587 if (labels->at(i) == label) {
2597 return true; 2588 return true;
2598 } 2589 }
2599 } 2590 }
2600 } 2591 }
2601 return false; 2592 return false;
2602 } 2593 }
2603 2594
2604 2595
2605 Statement* Parser::ParseExpressionOrLabelledStatement( 2596 Statement* Parser::ParseExpressionOrLabelledStatement(
(...skipping 11 matching lines...) Expand all
2617 case Token::FUNCTION: 2608 case Token::FUNCTION:
2618 case Token::LBRACE: 2609 case Token::LBRACE:
2619 UNREACHABLE(); // Always handled by the callers. 2610 UNREACHABLE(); // Always handled by the callers.
2620 case Token::CLASS: 2611 case Token::CLASS:
2621 ReportUnexpectedToken(Next()); 2612 ReportUnexpectedToken(Next());
2622 *ok = false; 2613 *ok = false;
2623 return nullptr; 2614 return nullptr;
2624 2615
2625 case Token::THIS: 2616 case Token::THIS:
2626 if (!FLAG_strong_this) break; 2617 if (!FLAG_strong_this) break;
2627 // Fall through. 2618 // Fall through.
2628 case Token::SUPER: 2619 case Token::SUPER:
2629 if (is_strong(language_mode()) && 2620 if (is_strong(language_mode()) &&
2630 IsClassConstructor(function_state_->kind())) { 2621 IsClassConstructor(function_state_->kind())) {
2631 bool is_this = peek() == Token::THIS; 2622 bool is_this = peek() == Token::THIS;
2632 Expression* expr; 2623 Expression* expr;
2633 ExpressionClassifier classifier; 2624 ExpressionClassifier classifier;
2634 if (is_this) { 2625 if (is_this) {
2635 expr = ParseStrongInitializationExpression(&classifier, CHECK_OK); 2626 expr = ParseStrongInitializationExpression(&classifier, CHECK_OK);
2636 } else { 2627 } else {
2637 expr = ParseStrongSuperCallExpression(&classifier, CHECK_OK); 2628 expr = ParseStrongSuperCallExpression(&classifier, CHECK_OK);
(...skipping 20 matching lines...) Expand all
2658 } 2649 }
2659 break; 2650 break;
2660 2651
2661 default: 2652 default:
2662 break; 2653 break;
2663 } 2654 }
2664 2655
2665 bool starts_with_idenfifier = peek_any_identifier(); 2656 bool starts_with_idenfifier = peek_any_identifier();
2666 Expression* expr = ParseExpression(true, CHECK_OK); 2657 Expression* expr = ParseExpression(true, CHECK_OK);
2667 if (peek() == Token::COLON && starts_with_idenfifier && expr != NULL && 2658 if (peek() == Token::COLON && starts_with_idenfifier && expr != NULL &&
2668 expr->AsVariableProxy() != NULL && 2659 expr->AsVariableProxy() != NULL && !expr->AsVariableProxy()->is_this()) {
2669 !expr->AsVariableProxy()->is_this()) {
2670 // Expression is a single identifier, and not, e.g., a parenthesized 2660 // Expression is a single identifier, and not, e.g., a parenthesized
2671 // identifier. 2661 // identifier.
2672 VariableProxy* var = expr->AsVariableProxy(); 2662 VariableProxy* var = expr->AsVariableProxy();
2673 const AstRawString* label = var->raw_name(); 2663 const AstRawString* label = var->raw_name();
2674 // TODO(1240780): We don't check for redeclaration of labels 2664 // TODO(1240780): We don't check for redeclaration of labels
2675 // during preparsing since keeping track of the set of active 2665 // during preparsing since keeping track of the set of active
2676 // labels requires nontrivial changes to the way scopes are 2666 // labels requires nontrivial changes to the way scopes are
2677 // structured. However, these are probably changes we want to 2667 // structured. However, these are probably changes we want to
2678 // make later anyway so we should go back and fix this then. 2668 // make later anyway so we should go back and fix this then.
2679 if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) { 2669 if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) {
2680 ParserTraits::ReportMessage(MessageTemplate::kLabelRedeclaration, label); 2670 ParserTraits::ReportMessage(MessageTemplate::kLabelRedeclaration, label);
2681 *ok = false; 2671 *ok = false;
2682 return NULL; 2672 return NULL;
2683 } 2673 }
2684 if (labels == NULL) { 2674 if (labels == NULL) {
2685 labels = new(zone()) ZoneList<const AstRawString*>(4, zone()); 2675 labels = new (zone()) ZoneList<const AstRawString*>(4, zone());
2686 } 2676 }
2687 labels->Add(label, zone()); 2677 labels->Add(label, zone());
2688 // Remove the "ghost" variable that turned out to be a label 2678 // Remove the "ghost" variable that turned out to be a label
2689 // from the top scope. This way, we don't try to resolve it 2679 // from the top scope. This way, we don't try to resolve it
2690 // during the scope processing. 2680 // during the scope processing.
2691 scope_->RemoveUnresolved(var); 2681 scope_->RemoveUnresolved(var);
2692 Expect(Token::COLON, CHECK_OK); 2682 Expect(Token::COLON, CHECK_OK);
2693 return ParseStatement(labels, ok); 2683 return ParseStatement(labels, ok);
2694 } 2684 }
2695 2685
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
2731 Expression* condition = ParseExpression(true, CHECK_OK); 2721 Expression* condition = ParseExpression(true, CHECK_OK);
2732 Expect(Token::RPAREN, CHECK_OK); 2722 Expect(Token::RPAREN, CHECK_OK);
2733 Statement* then_statement = ParseSubStatement(labels, CHECK_OK); 2723 Statement* then_statement = ParseSubStatement(labels, CHECK_OK);
2734 Statement* else_statement = NULL; 2724 Statement* else_statement = NULL;
2735 if (peek() == Token::ELSE) { 2725 if (peek() == Token::ELSE) {
2736 Next(); 2726 Next();
2737 else_statement = ParseSubStatement(labels, CHECK_OK); 2727 else_statement = ParseSubStatement(labels, CHECK_OK);
2738 } else { 2728 } else {
2739 else_statement = factory()->NewEmptyStatement(RelocInfo::kNoPosition); 2729 else_statement = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
2740 } 2730 }
2741 return factory()->NewIfStatement( 2731 return factory()->NewIfStatement(condition, then_statement, else_statement,
2742 condition, then_statement, else_statement, pos); 2732 pos);
2743 } 2733 }
2744 2734
2745 2735
2746 Statement* Parser::ParseContinueStatement(bool* ok) { 2736 Statement* Parser::ParseContinueStatement(bool* ok) {
2747 // ContinueStatement :: 2737 // ContinueStatement ::
2748 // 'continue' Identifier? ';' 2738 // 'continue' Identifier? ';'
2749 2739
2750 int pos = peek_position(); 2740 int pos = peek_position();
2751 Expect(Token::CONTINUE, CHECK_OK); 2741 Expect(Token::CONTINUE, CHECK_OK);
2752 const AstRawString* label = NULL; 2742 const AstRawString* label = NULL;
2753 Token::Value tok = peek(); 2743 Token::Value tok = peek();
2754 if (!scanner()->HasAnyLineTerminatorBeforeNext() && 2744 if (!scanner()->HasAnyLineTerminatorBeforeNext() && tok != Token::SEMICOLON &&
2755 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { 2745 tok != Token::RBRACE && tok != Token::EOS) {
2756 // ECMA allows "eval" or "arguments" as labels even in strict mode. 2746 // ECMA allows "eval" or "arguments" as labels even in strict mode.
2757 label = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); 2747 label = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
2758 } 2748 }
2759 IterationStatement* target = LookupContinueTarget(label, CHECK_OK); 2749 IterationStatement* target = LookupContinueTarget(label, CHECK_OK);
2760 if (target == NULL) { 2750 if (target == NULL) {
2761 // Illegal continue statement. 2751 // Illegal continue statement.
2762 MessageTemplate::Template message = MessageTemplate::kIllegalContinue; 2752 MessageTemplate::Template message = MessageTemplate::kIllegalContinue;
2763 if (label != NULL) { 2753 if (label != NULL) {
2764 message = MessageTemplate::kUnknownLabel; 2754 message = MessageTemplate::kUnknownLabel;
2765 } 2755 }
2766 ParserTraits::ReportMessage(message, label); 2756 ParserTraits::ReportMessage(message, label);
2767 *ok = false; 2757 *ok = false;
2768 return NULL; 2758 return NULL;
2769 } 2759 }
2770 ExpectSemicolon(CHECK_OK); 2760 ExpectSemicolon(CHECK_OK);
2771 return factory()->NewContinueStatement(target, pos); 2761 return factory()->NewContinueStatement(target, pos);
2772 } 2762 }
2773 2763
2774 2764
2775 Statement* Parser::ParseBreakStatement(ZoneList<const AstRawString*>* labels, 2765 Statement* Parser::ParseBreakStatement(ZoneList<const AstRawString*>* labels,
2776 bool* ok) { 2766 bool* ok) {
2777 // BreakStatement :: 2767 // BreakStatement ::
2778 // 'break' Identifier? ';' 2768 // 'break' Identifier? ';'
2779 2769
2780 int pos = peek_position(); 2770 int pos = peek_position();
2781 Expect(Token::BREAK, CHECK_OK); 2771 Expect(Token::BREAK, CHECK_OK);
2782 const AstRawString* label = NULL; 2772 const AstRawString* label = NULL;
2783 Token::Value tok = peek(); 2773 Token::Value tok = peek();
2784 if (!scanner()->HasAnyLineTerminatorBeforeNext() && 2774 if (!scanner()->HasAnyLineTerminatorBeforeNext() && tok != Token::SEMICOLON &&
2785 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { 2775 tok != Token::RBRACE && tok != Token::EOS) {
2786 // ECMA allows "eval" or "arguments" as labels even in strict mode. 2776 // ECMA allows "eval" or "arguments" as labels even in strict mode.
2787 label = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK); 2777 label = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
2788 } 2778 }
2789 // Parse labeled break statements that target themselves into 2779 // Parse labeled break statements that target themselves into
2790 // empty statements, e.g. 'l1: l2: l3: break l2;' 2780 // empty statements, e.g. 'l1: l2: l3: break l2;'
2791 if (label != NULL && ContainsLabel(labels, label)) { 2781 if (label != NULL && ContainsLabel(labels, label)) {
2792 ExpectSemicolon(CHECK_OK); 2782 ExpectSemicolon(CHECK_OK);
2793 return factory()->NewEmptyStatement(pos); 2783 return factory()->NewEmptyStatement(pos);
2794 } 2784 }
2795 BreakableStatement* target = NULL; 2785 BreakableStatement* target = NULL;
(...skipping 20 matching lines...) Expand all
2816 // Consume the return token. It is necessary to do that before 2806 // Consume the return token. It is necessary to do that before
2817 // reporting any errors on it, because of the way errors are 2807 // reporting any errors on it, because of the way errors are
2818 // reported (underlining). 2808 // reported (underlining).
2819 Expect(Token::RETURN, CHECK_OK); 2809 Expect(Token::RETURN, CHECK_OK);
2820 Scanner::Location loc = scanner()->location(); 2810 Scanner::Location loc = scanner()->location();
2821 function_state_->set_return_location(loc); 2811 function_state_->set_return_location(loc);
2822 2812
2823 Token::Value tok = peek(); 2813 Token::Value tok = peek();
2824 Statement* result; 2814 Statement* result;
2825 Expression* return_value; 2815 Expression* return_value;
2826 if (scanner()->HasAnyLineTerminatorBeforeNext() || 2816 if (scanner()->HasAnyLineTerminatorBeforeNext() || tok == Token::SEMICOLON ||
2827 tok == Token::SEMICOLON || 2817 tok == Token::RBRACE || tok == Token::EOS) {
2828 tok == Token::RBRACE ||
2829 tok == Token::EOS) {
2830 if (IsSubclassConstructor(function_state_->kind())) { 2818 if (IsSubclassConstructor(function_state_->kind())) {
2831 return_value = ThisExpression(scope_, factory(), loc.beg_pos); 2819 return_value = ThisExpression(scope_, factory(), loc.beg_pos);
2832 } else { 2820 } else {
2833 return_value = GetLiteralUndefined(position()); 2821 return_value = GetLiteralUndefined(position());
2834 } 2822 }
2835 } else { 2823 } else {
2836 if (is_strong(language_mode()) && 2824 if (is_strong(language_mode()) &&
2837 IsClassConstructor(function_state_->kind())) { 2825 IsClassConstructor(function_state_->kind())) {
2838 int pos = peek_position(); 2826 int pos = peek_position();
2839 ReportMessageAt(Scanner::Location(pos, pos + 1), 2827 ReportMessageAt(Scanner::Location(pos, pos + 1),
2840 MessageTemplate::kStrongConstructorReturnValue); 2828 MessageTemplate::kStrongConstructorReturnValue);
2841 *ok = false; 2829 *ok = false;
2842 return NULL; 2830 return NULL;
2843 } 2831 }
2844 2832
2845 int pos = peek_position(); 2833 int pos = peek_position();
2846 return_value = ParseExpression(true, CHECK_OK); 2834 return_value = ParseExpression(true, CHECK_OK);
2847 2835
2848 if (IsSubclassConstructor(function_state_->kind())) { 2836 if (IsSubclassConstructor(function_state_->kind())) {
2849 // For subclass constructors we need to return this in case of undefined 2837 // For subclass constructors we need to return this in case of undefined
2850 // and throw an exception in case of a non object. 2838 // and throw an exception in case of a non object.
2851 // 2839 //
2852 // return expr; 2840 // return expr;
2853 // 2841 //
2854 // Is rewritten as: 2842 // Is rewritten as:
2855 // 2843 //
2856 // return (temp = expr) === undefined ? this : 2844 // return (temp = expr) === undefined ? this :
2857 // %_IsSpecObject(temp) ? temp : throw new TypeError(...); 2845 // %_IsSpecObject(temp) ? temp : throw new TypeError(...);
2858 Variable* temp = scope_->NewTemporary( 2846 Variable* temp =
2859 ast_value_factory()->empty_string()); 2847 scope_->NewTemporary(ast_value_factory()->empty_string());
2860 Assignment* assign = factory()->NewAssignment( 2848 Assignment* assign = factory()->NewAssignment(
2861 Token::ASSIGN, factory()->NewVariableProxy(temp), return_value, pos); 2849 Token::ASSIGN, factory()->NewVariableProxy(temp), return_value, pos);
2862 2850
2863 Expression* throw_expression = 2851 Expression* throw_expression =
2864 NewThrowTypeError(MessageTemplate::kDerivedConstructorReturn, 2852 NewThrowTypeError(MessageTemplate::kDerivedConstructorReturn,
2865 ast_value_factory()->empty_string(), pos); 2853 ast_value_factory()->empty_string(), pos);
2866 2854
2867 // %_IsSpecObject(temp) 2855 // %_IsSpecObject(temp)
2868 ZoneList<Expression*>* is_spec_object_args = 2856 ZoneList<Expression*>* is_spec_object_args =
2869 new (zone()) ZoneList<Expression*>(1, zone()); 2857 new (zone()) ZoneList<Expression*>(1, zone());
(...skipping 15 matching lines...) Expand all
2885 return_value = factory()->NewConditional( 2873 return_value = factory()->NewConditional(
2886 is_undefined, ThisExpression(scope_, factory(), pos), 2874 is_undefined, ThisExpression(scope_, factory(), pos),
2887 is_object_conditional, pos); 2875 is_object_conditional, pos);
2888 } 2876 }
2889 } 2877 }
2890 ExpectSemicolon(CHECK_OK); 2878 ExpectSemicolon(CHECK_OK);
2891 2879
2892 if (is_generator()) { 2880 if (is_generator()) {
2893 Expression* generator = factory()->NewVariableProxy( 2881 Expression* generator = factory()->NewVariableProxy(
2894 function_state_->generator_object_variable()); 2882 function_state_->generator_object_variable());
2895 Expression* yield = factory()->NewYield( 2883 Expression* yield = factory()->NewYield(generator, return_value,
2896 generator, return_value, Yield::kFinal, loc.beg_pos); 2884 Yield::kFinal, loc.beg_pos);
2897 result = factory()->NewExpressionStatement(yield, loc.beg_pos); 2885 result = factory()->NewExpressionStatement(yield, loc.beg_pos);
2898 } else { 2886 } else {
2899 result = factory()->NewReturnStatement(return_value, loc.beg_pos); 2887 result = factory()->NewReturnStatement(return_value, loc.beg_pos);
2900 } 2888 }
2901 2889
2902 Scope* decl_scope = scope_->DeclarationScope(); 2890 Scope* decl_scope = scope_->DeclarationScope();
2903 if (decl_scope->is_script_scope() || decl_scope->is_eval_scope()) { 2891 if (decl_scope->is_script_scope() || decl_scope->is_eval_scope()) {
2904 ReportMessageAt(loc, MessageTemplate::kIllegalReturn); 2892 ReportMessageAt(loc, MessageTemplate::kIllegalReturn);
2905 *ok = false; 2893 *ok = false;
2906 return NULL; 2894 return NULL;
(...skipping 16 matching lines...) Expand all
2923 return NULL; 2911 return NULL;
2924 } 2912 }
2925 2913
2926 Expect(Token::LPAREN, CHECK_OK); 2914 Expect(Token::LPAREN, CHECK_OK);
2927 Expression* expr = ParseExpression(true, CHECK_OK); 2915 Expression* expr = ParseExpression(true, CHECK_OK);
2928 Expect(Token::RPAREN, CHECK_OK); 2916 Expect(Token::RPAREN, CHECK_OK);
2929 2917
2930 scope_->DeclarationScope()->RecordWithStatement(); 2918 scope_->DeclarationScope()->RecordWithStatement();
2931 Scope* with_scope = NewScope(scope_, WITH_SCOPE); 2919 Scope* with_scope = NewScope(scope_, WITH_SCOPE);
2932 Block* body; 2920 Block* body;
2933 { BlockState block_state(&scope_, with_scope); 2921 {
2922 BlockState block_state(&scope_, with_scope);
2934 with_scope->set_start_position(scanner()->peek_location().beg_pos); 2923 with_scope->set_start_position(scanner()->peek_location().beg_pos);
2935 2924
2936 // The body of the with statement must be enclosed in an additional 2925 // The body of the with statement must be enclosed in an additional
2937 // lexical scope in case the body is a FunctionDeclaration. 2926 // lexical scope in case the body is a FunctionDeclaration.
2938 body = factory()->NewBlock(labels, 1, false, RelocInfo::kNoPosition); 2927 body = factory()->NewBlock(labels, 1, false, RelocInfo::kNoPosition);
2939 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE); 2928 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE);
2940 block_scope->set_start_position(scanner()->location().beg_pos); 2929 block_scope->set_start_position(scanner()->location().beg_pos);
2941 { 2930 {
2942 BlockState block_state(&scope_, block_scope); 2931 BlockState block_state(&scope_, block_scope);
2943 Target target(&this->target_stack_, body); 2932 Target target(&this->target_stack_, body);
(...skipping 24 matching lines...) Expand all
2968 if (*default_seen_ptr) { 2957 if (*default_seen_ptr) {
2969 ReportMessage(MessageTemplate::kMultipleDefaultsInSwitch); 2958 ReportMessage(MessageTemplate::kMultipleDefaultsInSwitch);
2970 *ok = false; 2959 *ok = false;
2971 return NULL; 2960 return NULL;
2972 } 2961 }
2973 *default_seen_ptr = true; 2962 *default_seen_ptr = true;
2974 } 2963 }
2975 Expect(Token::COLON, CHECK_OK); 2964 Expect(Token::COLON, CHECK_OK);
2976 int pos = position(); 2965 int pos = position();
2977 ZoneList<Statement*>* statements = 2966 ZoneList<Statement*>* statements =
2978 new(zone()) ZoneList<Statement*>(5, zone()); 2967 new (zone()) ZoneList<Statement*>(5, zone());
2979 Statement* stat = NULL; 2968 Statement* stat = NULL;
2980 while (peek() != Token::CASE && 2969 while (peek() != Token::CASE && peek() != Token::DEFAULT &&
2981 peek() != Token::DEFAULT &&
2982 peek() != Token::RBRACE) { 2970 peek() != Token::RBRACE) {
2983 stat = ParseStatementListItem(CHECK_OK); 2971 stat = ParseStatementListItem(CHECK_OK);
2984 statements->Add(stat, zone()); 2972 statements->Add(stat, zone());
2985 } 2973 }
2986 if (is_strong(language_mode()) && stat != NULL && !stat->IsJump() && 2974 if (is_strong(language_mode()) && stat != NULL && !stat->IsJump() &&
2987 peek() != Token::RBRACE) { 2975 peek() != Token::RBRACE) {
2988 ReportMessageAt(scanner()->location(), 2976 ReportMessageAt(scanner()->location(),
2989 MessageTemplate::kStrongSwitchFallthrough); 2977 MessageTemplate::kStrongSwitchFallthrough);
2990 *ok = false; 2978 *ok = false;
2991 return NULL; 2979 return NULL;
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
3080 Expect(Token::THROW, CHECK_OK); 3068 Expect(Token::THROW, CHECK_OK);
3081 int pos = position(); 3069 int pos = position();
3082 if (scanner()->HasAnyLineTerminatorBeforeNext()) { 3070 if (scanner()->HasAnyLineTerminatorBeforeNext()) {
3083 ReportMessage(MessageTemplate::kNewlineAfterThrow); 3071 ReportMessage(MessageTemplate::kNewlineAfterThrow);
3084 *ok = false; 3072 *ok = false;
3085 return NULL; 3073 return NULL;
3086 } 3074 }
3087 Expression* exception = ParseExpression(true, CHECK_OK); 3075 Expression* exception = ParseExpression(true, CHECK_OK);
3088 ExpectSemicolon(CHECK_OK); 3076 ExpectSemicolon(CHECK_OK);
3089 3077
3090 return factory()->NewExpressionStatement( 3078 return factory()->NewExpressionStatement(factory()->NewThrow(exception, pos),
3091 factory()->NewThrow(exception, pos), pos); 3079 pos);
3092 } 3080 }
3093 3081
3094 3082
3095 TryStatement* Parser::ParseTryStatement(bool* ok) { 3083 TryStatement* Parser::ParseTryStatement(bool* ok) {
3096 // TryStatement :: 3084 // TryStatement ::
3097 // 'try' Block Catch 3085 // 'try' Block Catch
3098 // 'try' Block Finally 3086 // 'try' Block Finally
3099 // 'try' Block Catch Finally 3087 // 'try' Block Catch Finally
3100 // 3088 //
3101 // Catch :: 3089 // Catch ::
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
3313 Runtime::kThrowIteratorResultNotAnObject, throw_arguments, pos); 3301 Runtime::kThrowIteratorResultNotAnObject, throw_arguments, pos);
3314 3302
3315 return factory()->NewBinaryOperation( 3303 return factory()->NewBinaryOperation(
3316 Token::AND, 3304 Token::AND,
3317 factory()->NewUnaryOperation(Token::NOT, is_spec_object_call, pos), 3305 factory()->NewUnaryOperation(Token::NOT, is_spec_object_call, pos),
3318 throw_call, pos); 3306 throw_call, pos);
3319 } 3307 }
3320 3308
3321 3309
3322 void Parser::InitializeForEachStatement(ForEachStatement* stmt, 3310 void Parser::InitializeForEachStatement(ForEachStatement* stmt,
3323 Expression* each, 3311 Expression* each, Expression* subject,
3324 Expression* subject,
3325 Statement* body) { 3312 Statement* body) {
3326 ForOfStatement* for_of = stmt->AsForOfStatement(); 3313 ForOfStatement* for_of = stmt->AsForOfStatement();
3327 3314
3328 if (for_of != NULL) { 3315 if (for_of != NULL) {
3329 Variable* iterator = scope_->NewTemporary( 3316 Variable* iterator =
3330 ast_value_factory()->dot_iterator_string()); 3317 scope_->NewTemporary(ast_value_factory()->dot_iterator_string());
3331 Variable* result = scope_->NewTemporary( 3318 Variable* result =
3332 ast_value_factory()->dot_result_string()); 3319 scope_->NewTemporary(ast_value_factory()->dot_result_string());
3333 3320
3334 Expression* assign_iterator; 3321 Expression* assign_iterator;
3335 Expression* next_result; 3322 Expression* next_result;
3336 Expression* result_done; 3323 Expression* result_done;
3337 Expression* assign_each; 3324 Expression* assign_each;
3338 3325
3339 // iterator = subject[Symbol.iterator]() 3326 // iterator = subject[Symbol.iterator]()
3340 assign_iterator = factory()->NewAssignment( 3327 assign_iterator = factory()->NewAssignment(
3341 Token::ASSIGN, factory()->NewVariableProxy(iterator), 3328 Token::ASSIGN, factory()->NewVariableProxy(iterator),
3342 GetIterator(subject, factory()), subject->position()); 3329 GetIterator(subject, factory()), subject->position());
3343 3330
3344 // !%_IsSpecObject(result = iterator.next()) && 3331 // !%_IsSpecObject(result = iterator.next()) &&
3345 // %ThrowIteratorResultNotAnObject(result) 3332 // %ThrowIteratorResultNotAnObject(result)
3346 { 3333 {
3347 // result = iterator.next() 3334 // result = iterator.next()
3348 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); 3335 Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
3349 next_result = 3336 next_result =
3350 BuildIteratorNextResult(iterator_proxy, result, subject->position()); 3337 BuildIteratorNextResult(iterator_proxy, result, subject->position());
3351 } 3338 }
3352 3339
3353 // result.done 3340 // result.done
3354 { 3341 {
3355 Expression* done_literal = factory()->NewStringLiteral( 3342 Expression* done_literal = factory()->NewStringLiteral(
3356 ast_value_factory()->done_string(), RelocInfo::kNoPosition); 3343 ast_value_factory()->done_string(), RelocInfo::kNoPosition);
3357 Expression* result_proxy = factory()->NewVariableProxy(result); 3344 Expression* result_proxy = factory()->NewVariableProxy(result);
3358 result_done = factory()->NewProperty( 3345 result_done = factory()->NewProperty(result_proxy, done_literal,
3359 result_proxy, done_literal, RelocInfo::kNoPosition); 3346 RelocInfo::kNoPosition);
3360 } 3347 }
3361 3348
3362 // each = result.value 3349 // each = result.value
3363 { 3350 {
3364 Expression* value_literal = factory()->NewStringLiteral( 3351 Expression* value_literal = factory()->NewStringLiteral(
3365 ast_value_factory()->value_string(), RelocInfo::kNoPosition); 3352 ast_value_factory()->value_string(), RelocInfo::kNoPosition);
3366 Expression* result_proxy = factory()->NewVariableProxy(result); 3353 Expression* result_proxy = factory()->NewVariableProxy(result);
3367 Expression* result_value = factory()->NewProperty( 3354 Expression* result_value = factory()->NewProperty(
3368 result_proxy, value_literal, RelocInfo::kNoPosition); 3355 result_proxy, value_literal, RelocInfo::kNoPosition);
3369 assign_each = factory()->NewAssignment(Token::ASSIGN, each, result_value, 3356 assign_each = factory()->NewAssignment(Token::ASSIGN, each, result_value,
3370 RelocInfo::kNoPosition); 3357 RelocInfo::kNoPosition);
3371 } 3358 }
3372 3359
3373 for_of->Initialize(each, subject, body, 3360 for_of->Initialize(each, subject, body, assign_iterator, next_result,
3374 assign_iterator, 3361 result_done, assign_each);
3375 next_result,
3376 result_done,
3377 assign_each);
3378 } else { 3362 } else {
3379 stmt->Initialize(each, subject, body); 3363 stmt->Initialize(each, subject, body);
3380 } 3364 }
3381 } 3365 }
3382 3366
3383 3367
3384 Statement* Parser::DesugarLexicalBindingsInForStatement( 3368 Statement* Parser::DesugarLexicalBindingsInForStatement(
3385 Scope* inner_scope, bool is_const, ZoneList<const AstRawString*>* names, 3369 Scope* inner_scope, bool is_const, ZoneList<const AstRawString*>* names,
3386 ForStatement* loop, Statement* init, Expression* cond, Statement* next, 3370 ForStatement* loop, Statement* init, Expression* cond, Statement* next,
3387 Statement* body, bool* ok) { 3371 Statement* body, bool* ok) {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
3435 const AstRawString* temp_name = ast_value_factory()->dot_for_string(); 3419 const AstRawString* temp_name = ast_value_factory()->dot_for_string();
3436 3420
3437 // For each lexical variable x: 3421 // For each lexical variable x:
3438 // make statement: temp_x = x. 3422 // make statement: temp_x = x.
3439 for (int i = 0; i < names->length(); i++) { 3423 for (int i = 0; i < names->length(); i++) {
3440 VariableProxy* proxy = NewUnresolved(names->at(i), LET); 3424 VariableProxy* proxy = NewUnresolved(names->at(i), LET);
3441 Variable* temp = scope_->NewTemporary(temp_name); 3425 Variable* temp = scope_->NewTemporary(temp_name);
3442 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); 3426 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
3443 Assignment* assignment = factory()->NewAssignment( 3427 Assignment* assignment = factory()->NewAssignment(
3444 Token::ASSIGN, temp_proxy, proxy, RelocInfo::kNoPosition); 3428 Token::ASSIGN, temp_proxy, proxy, RelocInfo::kNoPosition);
3445 Statement* assignment_statement = factory()->NewExpressionStatement( 3429 Statement* assignment_statement =
3446 assignment, RelocInfo::kNoPosition); 3430 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
3447 outer_block->statements()->Add(assignment_statement, zone()); 3431 outer_block->statements()->Add(assignment_statement, zone());
3448 temps.Add(temp, zone()); 3432 temps.Add(temp, zone());
3449 } 3433 }
3450 3434
3451 Variable* first = NULL; 3435 Variable* first = NULL;
3452 // Make statement: first = 1. 3436 // Make statement: first = 1.
3453 if (next) { 3437 if (next) {
3454 first = scope_->NewTemporary(temp_name); 3438 first = scope_->NewTemporary(temp_name);
3455 VariableProxy* first_proxy = factory()->NewVariableProxy(first); 3439 VariableProxy* first_proxy = factory()->NewVariableProxy(first);
3456 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition); 3440 Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after
3715 // { 3699 // {
3716 // <let x' be a temporary variable> 3700 // <let x' be a temporary variable>
3717 // for (x' in/of e) { 3701 // for (x' in/of e) {
3718 // let/const/var x; 3702 // let/const/var x;
3719 // x = x'; 3703 // x = x';
3720 // b; 3704 // b;
3721 // } 3705 // }
3722 // let x; // for TDZ 3706 // let x; // for TDZ
3723 // } 3707 // }
3724 3708
3725 Variable* temp = scope_->NewTemporary( 3709 Variable* temp =
3726 ast_value_factory()->dot_for_string()); 3710 scope_->NewTemporary(ast_value_factory()->dot_for_string());
3727 ForEachStatement* loop = 3711 ForEachStatement* loop =
3728 factory()->NewForEachStatement(mode, labels, stmt_pos); 3712 factory()->NewForEachStatement(mode, labels, stmt_pos);
3729 Target target(&this->target_stack_, loop); 3713 Target target(&this->target_stack_, loop);
3730 3714
3731 Expression* enumerable = ParseExpression(true, CHECK_OK); 3715 Expression* enumerable = ParseExpression(true, CHECK_OK);
3732 3716
3733 Expect(Token::RPAREN, CHECK_OK); 3717 Expect(Token::RPAREN, CHECK_OK);
3734 3718
3735 Scope* body_scope = NewScope(scope_, BLOCK_SCOPE); 3719 Scope* body_scope = NewScope(scope_, BLOCK_SCOPE);
3736 body_scope->set_start_position(scanner()->location().beg_pos); 3720 body_scope->set_start_position(scanner()->location().beg_pos);
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
3897 Expression* exp = ParseExpression(true, CHECK_OK); 3881 Expression* exp = ParseExpression(true, CHECK_OK);
3898 next = factory()->NewExpressionStatement(exp, exp->position()); 3882 next = factory()->NewExpressionStatement(exp, exp->position());
3899 } 3883 }
3900 Expect(Token::RPAREN, CHECK_OK); 3884 Expect(Token::RPAREN, CHECK_OK);
3901 3885
3902 Statement* body = ParseSubStatement(NULL, CHECK_OK); 3886 Statement* body = ParseSubStatement(NULL, CHECK_OK);
3903 3887
3904 Statement* result = NULL; 3888 Statement* result = NULL;
3905 if (lexical_bindings.length() > 0) { 3889 if (lexical_bindings.length() > 0) {
3906 scope_ = for_scope; 3890 scope_ = for_scope;
3907 result = DesugarLexicalBindingsInForStatement( 3891 result = DesugarLexicalBindingsInForStatement(inner_scope, is_const,
3908 inner_scope, is_const, &lexical_bindings, loop, init, cond, 3892 &lexical_bindings, loop, init,
3909 next, body, CHECK_OK); 3893 cond, next, body, CHECK_OK);
3910 scope_ = saved_scope; 3894 scope_ = saved_scope;
3911 for_scope->set_end_position(scanner()->location().end_pos); 3895 for_scope->set_end_position(scanner()->location().end_pos);
3912 } else { 3896 } else {
3913 scope_ = saved_scope; 3897 scope_ = saved_scope;
3914 for_scope->set_end_position(scanner()->location().end_pos); 3898 for_scope->set_end_position(scanner()->location().end_pos);
3915 for_scope = for_scope->FinalizeBlockScope(); 3899 for_scope = for_scope->FinalizeBlockScope();
3916 if (for_scope) { 3900 if (for_scope) {
3917 // Rewrite a for statement of the form 3901 // Rewrite a for statement of the form
3918 // for (const x = i; c; n) b 3902 // for (const x = i; c; n) b
3919 // 3903 //
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
4098 if (!Rewriter::Rewrite(this, expr, ast_value_factory())) { 4082 if (!Rewriter::Rewrite(this, expr, ast_value_factory())) {
4099 *ok = false; 4083 *ok = false;
4100 return nullptr; 4084 return nullptr;
4101 } 4085 }
4102 return expr; 4086 return expr;
4103 } 4087 }
4104 4088
4105 4089
4106 void ParserTraits::ParseArrowFunctionFormalParameterList( 4090 void ParserTraits::ParseArrowFunctionFormalParameterList(
4107 ParserFormalParameters* parameters, Expression* expr, 4091 ParserFormalParameters* parameters, Expression* expr,
4108 const Scanner::Location& params_loc, 4092 const Scanner::Location& params_loc, Scanner::Location* duplicate_loc,
4109 Scanner::Location* duplicate_loc, bool* ok) { 4093 bool* ok) {
4110 if (expr->IsEmptyParentheses()) return; 4094 if (expr->IsEmptyParentheses()) return;
4111 4095
4112 ParseArrowFunctionFormalParameters(parameters, expr, params_loc, ok); 4096 ParseArrowFunctionFormalParameters(parameters, expr, params_loc, ok);
4113 if (!*ok) return; 4097 if (!*ok) return;
4114 4098
4115 ExpressionClassifier classifier; 4099 ExpressionClassifier classifier;
4116 if (!parameters->is_simple) { 4100 if (!parameters->is_simple) {
4117 classifier.RecordNonSimpleParameter(); 4101 classifier.RecordNonSimpleParameter();
4118 } 4102 }
4119 for (int i = 0; i < parameters->Arity(); ++i) { 4103 for (int i = 0; i < parameters->Arity(); ++i) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
4154 LanguageMode language_mode, bool* ok) { 4138 LanguageMode language_mode, bool* ok) {
4155 // Function :: 4139 // Function ::
4156 // '(' FormalParameterList? ')' '{' FunctionBody '}' 4140 // '(' FormalParameterList? ')' '{' FunctionBody '}'
4157 // 4141 //
4158 // Getter :: 4142 // Getter ::
4159 // '(' ')' '{' FunctionBody '}' 4143 // '(' ')' '{' FunctionBody '}'
4160 // 4144 //
4161 // Setter :: 4145 // Setter ::
4162 // '(' PropertySetParameterList ')' '{' FunctionBody '}' 4146 // '(' PropertySetParameterList ')' '{' FunctionBody '}'
4163 4147
4164 int pos = function_token_pos == RelocInfo::kNoPosition 4148 int pos = function_token_pos == RelocInfo::kNoPosition ? peek_position()
4165 ? peek_position() : function_token_pos; 4149 : function_token_pos;
4166 4150
4167 bool is_generator = IsGeneratorFunction(kind); 4151 bool is_generator = IsGeneratorFunction(kind);
4168 4152
4169 // Anonymous functions were passed either the empty symbol or a null 4153 // Anonymous functions were passed either the empty symbol or a null
4170 // handle as the function name. Remember if we were passed a non-empty 4154 // handle as the function name. Remember if we were passed a non-empty
4171 // handle to decide whether to invoke function name inference. 4155 // handle to decide whether to invoke function name inference.
4172 bool should_infer_name = function_name == NULL; 4156 bool should_infer_name = function_name == NULL;
4173 4157
4174 // We want a non-null handle as the function name. 4158 // We want a non-null handle as the function name.
4175 if (should_infer_name) { 4159 if (should_infer_name) {
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
4246 4230
4247 Expect(Token::LPAREN, CHECK_OK); 4231 Expect(Token::LPAREN, CHECK_OK);
4248 int start_position = scanner()->location().beg_pos; 4232 int start_position = scanner()->location().beg_pos;
4249 scope_->set_start_position(start_position); 4233 scope_->set_start_position(start_position);
4250 ParserFormalParameters formals(scope); 4234 ParserFormalParameters formals(scope);
4251 ParseFormalParameterList(&formals, &formals_classifier, CHECK_OK); 4235 ParseFormalParameterList(&formals, &formals_classifier, CHECK_OK);
4252 arity = formals.Arity(); 4236 arity = formals.Arity();
4253 Expect(Token::RPAREN, CHECK_OK); 4237 Expect(Token::RPAREN, CHECK_OK);
4254 int formals_end_position = scanner()->location().end_pos; 4238 int formals_end_position = scanner()->location().end_pos;
4255 4239
4256 CheckArityRestrictions(arity, arity_restriction, 4240 CheckArityRestrictions(arity, arity_restriction, formals.has_rest,
4257 formals.has_rest, start_position, 4241 start_position, formals_end_position, CHECK_OK);
4258 formals_end_position, CHECK_OK);
4259 Expect(Token::LBRACE, CHECK_OK); 4242 Expect(Token::LBRACE, CHECK_OK);
4260 4243
4261 // Determine if the function can be parsed lazily. Lazy parsing is different 4244 // Determine if the function can be parsed lazily. Lazy parsing is different
4262 // from lazy compilation; we need to parse more eagerly than we compile. 4245 // from lazy compilation; we need to parse more eagerly than we compile.
4263 4246
4264 // We can only parse lazily if we also compile lazily. The heuristics for 4247 // We can only parse lazily if we also compile lazily. The heuristics for
4265 // lazy compilation are: 4248 // lazy compilation are:
4266 // - It must not have been prohibited by the caller to Parse (some callers 4249 // - It must not have been prohibited by the caller to Parse (some callers
4267 // need a full AST). 4250 // need a full AST).
4268 // - The outer scope must allow lazy compilation of inner functions. 4251 // - The outer scope must allow lazy compilation of inner functions.
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
4555 Expression* initial_value = 4538 Expression* initial_value =
4556 factory()->NewVariableProxy(parameters.scope->parameter(i)); 4539 factory()->NewVariableProxy(parameters.scope->parameter(i));
4557 if (parameter.initializer != nullptr) { 4540 if (parameter.initializer != nullptr) {
4558 // IS_UNDEFINED($param) ? initializer : $param 4541 // IS_UNDEFINED($param) ? initializer : $param
4559 DCHECK(!parameter.is_rest); 4542 DCHECK(!parameter.is_rest);
4560 auto condition = factory()->NewCompareOperation( 4543 auto condition = factory()->NewCompareOperation(
4561 Token::EQ_STRICT, 4544 Token::EQ_STRICT,
4562 factory()->NewVariableProxy(parameters.scope->parameter(i)), 4545 factory()->NewVariableProxy(parameters.scope->parameter(i)),
4563 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition), 4546 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
4564 RelocInfo::kNoPosition); 4547 RelocInfo::kNoPosition);
4565 initial_value = factory()->NewConditional( 4548 initial_value =
4566 condition, parameter.initializer, initial_value, 4549 factory()->NewConditional(condition, parameter.initializer,
4567 RelocInfo::kNoPosition); 4550 initial_value, RelocInfo::kNoPosition);
4568 descriptor.initialization_pos = parameter.initializer->position(); 4551 descriptor.initialization_pos = parameter.initializer->position();
4569 initializer_position = parameter.initializer_end_position; 4552 initializer_position = parameter.initializer_end_position;
4570 } else if (parameter.is_rest) { 4553 } else if (parameter.is_rest) {
4571 // $rest = []; 4554 // $rest = [];
4572 // for (var $argument_index = $rest_index; 4555 // for (var $argument_index = $rest_index;
4573 // $argument_index < %_ArgumentsLength(); 4556 // $argument_index < %_ArgumentsLength();
4574 // ++$argument_index) { 4557 // ++$argument_index) {
4575 // %AppendElement($rest, %_Arguments($argument_index)); 4558 // %AppendElement($rest, %_Arguments($argument_index));
4576 // } 4559 // }
4577 // let <param> = $rest; 4560 // let <param> = $rest;
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
4676 } 4659 }
4677 4660
4678 4661
4679 ZoneList<Statement*>* Parser::ParseEagerFunctionBody( 4662 ZoneList<Statement*>* Parser::ParseEagerFunctionBody(
4680 const AstRawString* function_name, int pos, 4663 const AstRawString* function_name, int pos,
4681 const ParserFormalParameters& parameters, FunctionKind kind, 4664 const ParserFormalParameters& parameters, FunctionKind kind,
4682 FunctionLiteral::FunctionType function_type, bool* ok) { 4665 FunctionLiteral::FunctionType function_type, bool* ok) {
4683 // Everything inside an eagerly parsed function will be parsed eagerly 4666 // Everything inside an eagerly parsed function will be parsed eagerly
4684 // (see comment above). 4667 // (see comment above).
4685 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); 4668 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
4686 ZoneList<Statement*>* result = new(zone()) ZoneList<Statement*>(8, zone()); 4669 ZoneList<Statement*>* result = new (zone()) ZoneList<Statement*>(8, zone());
4687 4670
4688 static const int kFunctionNameAssignmentIndex = 0; 4671 static const int kFunctionNameAssignmentIndex = 0;
4689 if (function_type == FunctionLiteral::NAMED_EXPRESSION) { 4672 if (function_type == FunctionLiteral::NAMED_EXPRESSION) {
4690 DCHECK(function_name != NULL); 4673 DCHECK(function_name != NULL);
4691 // If we have a named function expression, we add a local variable 4674 // If we have a named function expression, we add a local variable
4692 // declaration to the body of the function with the name of the 4675 // declaration to the body of the function with the name of the
4693 // function and let it refer to the function itself (closure). 4676 // function and let it refer to the function itself (closure).
4694 // Not having parsed the function body, the language mode may still change, 4677 // Not having parsed the function body, the language mode may still change,
4695 // so we reserve a spot and create the actual const assignment later. 4678 // so we reserve a spot and create the actual const assignment later.
4696 DCHECK_EQ(kFunctionNameAssignmentIndex, result->length()); 4679 DCHECK_EQ(kFunctionNameAssignmentIndex, result->length());
(...skipping 11 matching lines...) Expand all
4708 inner_block->set_scope(inner_scope); 4691 inner_block->set_scope(inner_scope);
4709 body = inner_block->statements(); 4692 body = inner_block->statements();
4710 } 4693 }
4711 4694
4712 { 4695 {
4713 BlockState block_state(&scope_, inner_scope); 4696 BlockState block_state(&scope_, inner_scope);
4714 4697
4715 // For generators, allocate and yield an iterator on function entry. 4698 // For generators, allocate and yield an iterator on function entry.
4716 if (IsGeneratorFunction(kind)) { 4699 if (IsGeneratorFunction(kind)) {
4717 ZoneList<Expression*>* arguments = 4700 ZoneList<Expression*>* arguments =
4718 new(zone()) ZoneList<Expression*>(0, zone()); 4701 new (zone()) ZoneList<Expression*>(0, zone());
4719 CallRuntime* allocation = factory()->NewCallRuntime( 4702 CallRuntime* allocation = factory()->NewCallRuntime(
4720 Runtime::kCreateJSGeneratorObject, arguments, pos); 4703 Runtime::kCreateJSGeneratorObject, arguments, pos);
4721 VariableProxy* init_proxy = factory()->NewVariableProxy( 4704 VariableProxy* init_proxy = factory()->NewVariableProxy(
4722 function_state_->generator_object_variable()); 4705 function_state_->generator_object_variable());
4723 Assignment* assignment = factory()->NewAssignment( 4706 Assignment* assignment = factory()->NewAssignment(
4724 Token::INIT, init_proxy, allocation, RelocInfo::kNoPosition); 4707 Token::INIT, init_proxy, allocation, RelocInfo::kNoPosition);
4725 VariableProxy* get_proxy = factory()->NewVariableProxy( 4708 VariableProxy* get_proxy = factory()->NewVariableProxy(
4726 function_state_->generator_object_variable()); 4709 function_state_->generator_object_variable());
4727 Yield* yield = factory()->NewYield( 4710 Yield* yield = factory()->NewYield(get_proxy, assignment, Yield::kInitial,
4728 get_proxy, assignment, Yield::kInitial, RelocInfo::kNoPosition); 4711 RelocInfo::kNoPosition);
4729 body->Add(factory()->NewExpressionStatement( 4712 body->Add(
4730 yield, RelocInfo::kNoPosition), zone()); 4713 factory()->NewExpressionStatement(yield, RelocInfo::kNoPosition),
4714 zone());
4731 } 4715 }
4732 4716
4733 ParseStatementList(body, Token::RBRACE, CHECK_OK); 4717 ParseStatementList(body, Token::RBRACE, CHECK_OK);
4734 4718
4735 if (IsGeneratorFunction(kind)) { 4719 if (IsGeneratorFunction(kind)) {
4736 VariableProxy* get_proxy = factory()->NewVariableProxy( 4720 VariableProxy* get_proxy = factory()->NewVariableProxy(
4737 function_state_->generator_object_variable()); 4721 function_state_->generator_object_variable());
4738 Expression* undefined = 4722 Expression* undefined =
4739 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition); 4723 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition);
4740 Yield* yield = factory()->NewYield(get_proxy, undefined, Yield::kFinal, 4724 Yield* yield = factory()->NewYield(get_proxy, undefined, Yield::kFinal,
4741 RelocInfo::kNoPosition); 4725 RelocInfo::kNoPosition);
4742 body->Add(factory()->NewExpressionStatement( 4726 body->Add(
4743 yield, RelocInfo::kNoPosition), zone()); 4727 factory()->NewExpressionStatement(yield, RelocInfo::kNoPosition),
4728 zone());
4744 } 4729 }
4745 4730
4746 if (IsSubclassConstructor(kind)) { 4731 if (IsSubclassConstructor(kind)) {
4747 body->Add( 4732 body->Add(
4748 factory()->NewReturnStatement( 4733 factory()->NewReturnStatement(
4749 this->ThisExpression(scope_, factory(), RelocInfo::kNoPosition), 4734 this->ThisExpression(scope_, factory(), RelocInfo::kNoPosition),
4750 RelocInfo::kNoPosition), 4735 RelocInfo::kNoPosition),
4751 zone()); 4736 zone());
4752 } 4737 }
4753 } 4738 }
4754 4739
4755 Expect(Token::RBRACE, CHECK_OK); 4740 Expect(Token::RBRACE, CHECK_OK);
4756 scope_->set_end_position(scanner()->location().end_pos); 4741 scope_->set_end_position(scanner()->location().end_pos);
4757 4742
4758 if (!parameters.is_simple) { 4743 if (!parameters.is_simple) {
4759 DCHECK_NOT_NULL(inner_scope); 4744 DCHECK_NOT_NULL(inner_scope);
4760 DCHECK_EQ(body, inner_block->statements()); 4745 DCHECK_EQ(body, inner_block->statements());
4761 SetLanguageMode(scope_, inner_scope->language_mode()); 4746 SetLanguageMode(scope_, inner_scope->language_mode());
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
4939 } 4924 }
4940 4925
4941 4926
4942 Expression* Parser::ParseV8Intrinsic(bool* ok) { 4927 Expression* Parser::ParseV8Intrinsic(bool* ok) {
4943 // CallRuntime :: 4928 // CallRuntime ::
4944 // '%' Identifier Arguments 4929 // '%' Identifier Arguments
4945 4930
4946 int pos = peek_position(); 4931 int pos = peek_position();
4947 Expect(Token::MOD, CHECK_OK); 4932 Expect(Token::MOD, CHECK_OK);
4948 // Allow "eval" or "arguments" for backward compatibility. 4933 // Allow "eval" or "arguments" for backward compatibility.
4949 const AstRawString* name = ParseIdentifier(kAllowRestrictedIdentifiers, 4934 const AstRawString* name =
4950 CHECK_OK); 4935 ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
4951 Scanner::Location spread_pos; 4936 Scanner::Location spread_pos;
4952 ExpressionClassifier classifier; 4937 ExpressionClassifier classifier;
4953 ZoneList<Expression*>* args = 4938 ZoneList<Expression*>* args =
4954 ParseArguments(&spread_pos, &classifier, CHECK_OK); 4939 ParseArguments(&spread_pos, &classifier, CHECK_OK);
4955 ValidateExpression(&classifier, CHECK_OK); 4940 ValidateExpression(&classifier, CHECK_OK);
4956 4941
4957 DCHECK(!spread_pos.IsValid()); 4942 DCHECK(!spread_pos.IsValid());
4958 4943
4959 if (extension_ != NULL) { 4944 if (extension_ != NULL) {
4960 // The extension structures are only accessible while parsing the 4945 // The extension structures are only accessible while parsing the
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
5010 return factory()->NewUndefinedLiteral(position); 4995 return factory()->NewUndefinedLiteral(position);
5011 } 4996 }
5012 4997
5013 4998
5014 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { 4999 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) {
5015 Declaration* decl = scope->CheckConflictingVarDeclarations(); 5000 Declaration* decl = scope->CheckConflictingVarDeclarations();
5016 if (decl != NULL) { 5001 if (decl != NULL) {
5017 // In ES6, conflicting variable bindings are early errors. 5002 // In ES6, conflicting variable bindings are early errors.
5018 const AstRawString* name = decl->proxy()->raw_name(); 5003 const AstRawString* name = decl->proxy()->raw_name();
5019 int position = decl->proxy()->position(); 5004 int position = decl->proxy()->position();
5020 Scanner::Location location = position == RelocInfo::kNoPosition 5005 Scanner::Location location =
5021 ? Scanner::Location::invalid() 5006 position == RelocInfo::kNoPosition
5022 : Scanner::Location(position, position + 1); 5007 ? Scanner::Location::invalid()
5008 : Scanner::Location(position, position + 1);
5023 ParserTraits::ReportMessageAt(location, MessageTemplate::kVarRedeclaration, 5009 ParserTraits::ReportMessageAt(location, MessageTemplate::kVarRedeclaration,
5024 name); 5010 name);
5025 *ok = false; 5011 *ok = false;
5026 } 5012 }
5027 } 5013 }
5028 5014
5029 5015
5030 void Parser::InsertShadowingVarBindingInitializers(Block* inner_block) { 5016 void Parser::InsertShadowingVarBindingInitializers(Block* inner_block) {
5031 // For each var-binding that shadows a parameter, insert an assignment 5017 // For each var-binding that shadows a parameter, insert an assignment
5032 // initializing the variable with the parameter. 5018 // initializing the variable with the parameter.
5033 Scope* inner_scope = inner_block->scope(); 5019 Scope* inner_scope = inner_block->scope();
5034 DCHECK(inner_scope->is_declaration_scope()); 5020 DCHECK(inner_scope->is_declaration_scope());
5035 Scope* function_scope = inner_scope->outer_scope(); 5021 Scope* function_scope = inner_scope->outer_scope();
5036 DCHECK(function_scope->is_function_scope()); 5022 DCHECK(function_scope->is_function_scope());
5037 ZoneList<Declaration*>* decls = inner_scope->declarations(); 5023 ZoneList<Declaration*>* decls = inner_scope->declarations();
5038 for (int i = 0; i < decls->length(); ++i) { 5024 for (int i = 0; i < decls->length(); ++i) {
5039 Declaration* decl = decls->at(i); 5025 Declaration* decl = decls->at(i);
5040 if (decl->mode() != VAR || !decl->IsVariableDeclaration()) continue; 5026 if (decl->mode() != VAR || !decl->IsVariableDeclaration()) continue;
5041 const AstRawString* name = decl->proxy()->raw_name(); 5027 const AstRawString* name = decl->proxy()->raw_name();
5042 Variable* parameter = function_scope->LookupLocal(name); 5028 Variable* parameter = function_scope->LookupLocal(name);
5043 if (parameter == nullptr) continue; 5029 if (parameter == nullptr) continue;
5044 VariableProxy* to = inner_scope->NewUnresolved(factory(), name); 5030 VariableProxy* to = inner_scope->NewUnresolved(factory(), name);
5045 VariableProxy* from = factory()->NewVariableProxy(parameter); 5031 VariableProxy* from = factory()->NewVariableProxy(parameter);
5046 Expression* assignment = factory()->NewAssignment( 5032 Expression* assignment = factory()->NewAssignment(Token::ASSIGN, to, from,
5047 Token::ASSIGN, to, from, RelocInfo::kNoPosition); 5033 RelocInfo::kNoPosition);
5048 Statement* statement = factory()->NewExpressionStatement( 5034 Statement* statement =
5049 assignment, RelocInfo::kNoPosition); 5035 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
5050 inner_block->statements()->InsertAt(0, statement, zone()); 5036 inner_block->statements()->InsertAt(0, statement, zone());
5051 } 5037 }
5052 } 5038 }
5053 5039
5054 5040
5055 void Parser::InsertSloppyBlockFunctionVarBindings(Scope* scope, bool* ok) { 5041 void Parser::InsertSloppyBlockFunctionVarBindings(Scope* scope, bool* ok) {
5056 // For each variable which is used as a function declaration in a sloppy 5042 // For each variable which is used as a function declaration in a sloppy
5057 // block, 5043 // block,
5058 DCHECK(scope->is_declaration_scope()); 5044 DCHECK(scope->is_declaration_scope());
5059 SloppyBlockFunctionMap* map = scope->sloppy_block_function_map(); 5045 SloppyBlockFunctionMap* map = scope->sloppy_block_function_map();
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
5230 Advance(); 5216 Advance();
5231 } 5217 }
5232 5218
5233 5219
5234 void RegExpParser::Advance(int dist) { 5220 void RegExpParser::Advance(int dist) {
5235 next_pos_ += dist - 1; 5221 next_pos_ += dist - 1;
5236 Advance(); 5222 Advance();
5237 } 5223 }
5238 5224
5239 5225
5240 bool RegExpParser::simple() { 5226 bool RegExpParser::simple() { return simple_; }
5241 return simple_;
5242 }
5243 5227
5244 5228
5245 bool RegExpParser::IsSyntaxCharacter(uc32 c) { 5229 bool RegExpParser::IsSyntaxCharacter(uc32 c) {
5246 return c == '^' || c == '$' || c == '\\' || c == '.' || c == '*' || 5230 return c == '^' || c == '$' || c == '\\' || c == '.' || c == '*' ||
5247 c == '+' || c == '?' || c == '(' || c == ')' || c == '[' || c == ']' || 5231 c == '+' || c == '?' || c == '(' || c == ')' || c == '[' || c == ']' ||
5248 c == '{' || c == '}' || c == '|'; 5232 c == '{' || c == '}' || c == '|';
5249 } 5233 }
5250 5234
5251 5235
5252 RegExpTree* RegExpParser::ReportError(Vector<const char> message) { 5236 RegExpTree* RegExpParser::ReportError(Vector<const char> message) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
5285 // Atom Quantifier 5269 // Atom Quantifier
5286 RegExpTree* RegExpParser::ParseDisjunction() { 5270 RegExpTree* RegExpParser::ParseDisjunction() {
5287 // Used to store current state while parsing subexpressions. 5271 // Used to store current state while parsing subexpressions.
5288 RegExpParserState initial_state(NULL, INITIAL, RegExpLookaround::LOOKAHEAD, 0, 5272 RegExpParserState initial_state(NULL, INITIAL, RegExpLookaround::LOOKAHEAD, 0,
5289 zone()); 5273 zone());
5290 RegExpParserState* state = &initial_state; 5274 RegExpParserState* state = &initial_state;
5291 // Cache the builder in a local variable for quick access. 5275 // Cache the builder in a local variable for quick access.
5292 RegExpBuilder* builder = initial_state.builder(); 5276 RegExpBuilder* builder = initial_state.builder();
5293 while (true) { 5277 while (true) {
5294 switch (current()) { 5278 switch (current()) {
5295 case kEndMarker: 5279 case kEndMarker:
5296 if (state->IsSubexpression()) { 5280 if (state->IsSubexpression()) {
5297 // Inside a parenthesized group when hitting end of input. 5281 // Inside a parenthesized group when hitting end of input.
5298 ReportError(CStrVector("Unterminated group") CHECK_FAILED); 5282 ReportError(CStrVector("Unterminated group") CHECK_FAILED);
5299 } 5283 }
5300 DCHECK_EQ(INITIAL, state->group_type()); 5284 DCHECK_EQ(INITIAL, state->group_type());
5301 // Parsing completed successfully. 5285 // Parsing completed successfully.
5302 return builder->ToRegExp(); 5286 return builder->ToRegExp();
5303 case ')': { 5287 case ')': {
5304 if (!state->IsSubexpression()) { 5288 if (!state->IsSubexpression()) {
5305 ReportError(CStrVector("Unmatched ')'") CHECK_FAILED); 5289 ReportError(CStrVector("Unmatched ')'") CHECK_FAILED);
5306 } 5290 }
5307 DCHECK_NE(INITIAL, state->group_type()); 5291 DCHECK_NE(INITIAL, state->group_type());
5308 5292
5309 Advance(); 5293 Advance();
5310 // End disjunction parsing and convert builder content to new single 5294 // End disjunction parsing and convert builder content to new single
5311 // regexp atom. 5295 // regexp atom.
5312 RegExpTree* body = builder->ToRegExp(); 5296 RegExpTree* body = builder->ToRegExp();
5313 5297
5314 int end_capture_index = captures_started(); 5298 int end_capture_index = captures_started();
5315 5299
5316 int capture_index = state->capture_index(); 5300 int capture_index = state->capture_index();
5317 SubexpressionType group_type = state->group_type(); 5301 SubexpressionType group_type = state->group_type();
5318 5302
5319 // Build result of subexpression. 5303 // Build result of subexpression.
5320 if (group_type == CAPTURE) { 5304 if (group_type == CAPTURE) {
5321 RegExpCapture* capture = GetCapture(capture_index); 5305 RegExpCapture* capture = GetCapture(capture_index);
5322 capture->set_body(body); 5306 capture->set_body(body);
5323 body = capture; 5307 body = capture;
5324 } else if (group_type != GROUPING) { 5308 } else if (group_type != GROUPING) {
5325 DCHECK(group_type == POSITIVE_LOOKAROUND || 5309 DCHECK(group_type == POSITIVE_LOOKAROUND ||
5326 group_type == NEGATIVE_LOOKAROUND); 5310 group_type == NEGATIVE_LOOKAROUND);
5327 bool is_positive = (group_type == POSITIVE_LOOKAROUND); 5311 bool is_positive = (group_type == POSITIVE_LOOKAROUND);
5328 body = new (zone()) RegExpLookaround( 5312 body = new (zone()) RegExpLookaround(
5329 body, is_positive, end_capture_index - capture_index, capture_index, 5313 body, is_positive, end_capture_index - capture_index,
5330 state->lookaround_type()); 5314 capture_index, state->lookaround_type());
5331 } 5315 }
5332 5316
5333 // Restore previous state. 5317 // Restore previous state.
5334 state = state->previous_state(); 5318 state = state->previous_state();
5335 builder = state->builder(); 5319 builder = state->builder();
5336 5320
5337 builder->AddAtom(body); 5321 builder->AddAtom(body);
5338 // For compatability with JSC and ES3, we allow quantifiers after 5322 // For compatability with JSC and ES3, we allow quantifiers after
5339 // lookaheads, and break in all cases. 5323 // lookaheads, and break in all cases.
5340 break; 5324 break;
5341 } 5325 }
5342 case '|': { 5326 case '|': {
5343 Advance(); 5327 Advance();
5344 builder->NewAlternative(); 5328 builder->NewAlternative();
5345 continue; 5329 continue;
5346 } 5330 }
5347 case '*': 5331 case '*':
5348 case '+': 5332 case '+':
5349 case '?': 5333 case '?':
5350 return ReportError(CStrVector("Nothing to repeat")); 5334 return ReportError(CStrVector("Nothing to repeat"));
5351 case '^': { 5335 case '^': {
5352 Advance(); 5336 Advance();
5353 if (multiline_) { 5337 if (multiline_) {
5354 builder->AddAssertion( 5338 builder->AddAssertion(
5355 new(zone()) RegExpAssertion(RegExpAssertion::START_OF_LINE)); 5339 new (zone()) RegExpAssertion(RegExpAssertion::START_OF_LINE));
5356 } else { 5340 } else {
5357 builder->AddAssertion( 5341 builder->AddAssertion(
5358 new(zone()) RegExpAssertion(RegExpAssertion::START_OF_INPUT)); 5342 new (zone()) RegExpAssertion(RegExpAssertion::START_OF_INPUT));
5359 set_contains_anchor(); 5343 set_contains_anchor();
5360 } 5344 }
5361 continue; 5345 continue;
5362 } 5346 }
5363 case '$': { 5347 case '$': {
5364 Advance(); 5348 Advance();
5365 RegExpAssertion::AssertionType assertion_type = 5349 RegExpAssertion::AssertionType assertion_type =
5366 multiline_ ? RegExpAssertion::END_OF_LINE : 5350 multiline_ ? RegExpAssertion::END_OF_LINE
5367 RegExpAssertion::END_OF_INPUT; 5351 : RegExpAssertion::END_OF_INPUT;
5368 builder->AddAssertion(new(zone()) RegExpAssertion(assertion_type)); 5352 builder->AddAssertion(new (zone()) RegExpAssertion(assertion_type));
5369 continue; 5353 continue;
5370 } 5354 }
5371 case '.': { 5355 case '.': {
5372 Advance(); 5356 Advance();
5373 // everything except \x0a, \x0d, \u2028 and \u2029 5357 // everything except \x0a, \x0d, \u2028 and \u2029
5374 ZoneList<CharacterRange>* ranges = 5358 ZoneList<CharacterRange>* ranges =
5375 new(zone()) ZoneList<CharacterRange>(2, zone()); 5359 new (zone()) ZoneList<CharacterRange>(2, zone());
5376 CharacterRange::AddClassEscape('.', ranges, zone()); 5360 CharacterRange::AddClassEscape('.', ranges, zone());
5377 RegExpTree* atom = new(zone()) RegExpCharacterClass(ranges, false); 5361 RegExpTree* atom = new (zone()) RegExpCharacterClass(ranges, false);
5378 builder->AddAtom(atom); 5362 builder->AddAtom(atom);
5379 break; 5363 break;
5380 } 5364 }
5381 case '(': { 5365 case '(': {
5382 SubexpressionType subexpr_type = CAPTURE; 5366 SubexpressionType subexpr_type = CAPTURE;
5383 RegExpLookaround::Type lookaround_type = state->lookaround_type(); 5367 RegExpLookaround::Type lookaround_type = state->lookaround_type();
5384 Advance(); 5368 Advance();
5385 if (current() == '?') { 5369 if (current() == '?') {
5370 switch (Next()) {
5371 case ':':
5372 subexpr_type = GROUPING;
5373 break;
5374 case '=':
5375 lookaround_type = RegExpLookaround::LOOKAHEAD;
5376 subexpr_type = POSITIVE_LOOKAROUND;
5377 break;
5378 case '!':
5379 lookaround_type = RegExpLookaround::LOOKAHEAD;
5380 subexpr_type = NEGATIVE_LOOKAROUND;
5381 break;
5382 case '<':
5383 if (FLAG_harmony_regexp_lookbehind) {
5384 Advance();
5385 lookaround_type = RegExpLookaround::LOOKBEHIND;
5386 if (Next() == '=') {
5387 subexpr_type = POSITIVE_LOOKAROUND;
5388 break;
5389 } else if (Next() == '!') {
5390 subexpr_type = NEGATIVE_LOOKAROUND;
5391 break;
5392 }
5393 }
5394 // Fall through.
5395 default:
5396 ReportError(CStrVector("Invalid group") CHECK_FAILED);
5397 break;
5398 }
5399 Advance(2);
5400 } else {
5401 if (captures_started_ >= kMaxCaptures) {
5402 ReportError(CStrVector("Too many captures") CHECK_FAILED);
5403 }
5404 captures_started_++;
5405 }
5406 // Store current state and begin new disjunction parsing.
5407 state = new (zone()) RegExpParserState(
5408 state, subexpr_type, lookaround_type, captures_started_, zone());
5409 builder = state->builder();
5410 continue;
5411 }
5412 case '[': {
5413 RegExpTree* atom = ParseCharacterClass(CHECK_FAILED);
5414 builder->AddAtom(atom);
5415 break;
5416 }
5417 // Atom ::
5418 // \ AtomEscape
5419 case '\\':
5386 switch (Next()) { 5420 switch (Next()) {
5387 case ':': 5421 case kEndMarker:
5388 subexpr_type = GROUPING; 5422 return ReportError(CStrVector("\\ at end of pattern"));
5389 break; 5423 case 'b':
5390 case '=': 5424 Advance(2);
5391 lookaround_type = RegExpLookaround::LOOKAHEAD; 5425 builder->AddAssertion(
5392 subexpr_type = POSITIVE_LOOKAROUND; 5426 new (zone()) RegExpAssertion(RegExpAssertion::BOUNDARY));
5393 break; 5427 continue;
5394 case '!': 5428 case 'B':
5395 lookaround_type = RegExpLookaround::LOOKAHEAD; 5429 Advance(2);
5396 subexpr_type = NEGATIVE_LOOKAROUND; 5430 builder->AddAssertion(
5397 break; 5431 new (zone()) RegExpAssertion(RegExpAssertion::NON_BOUNDARY));
5398 case '<': 5432 continue;
5399 if (FLAG_harmony_regexp_lookbehind) { 5433 // AtomEscape ::
5434 // CharacterClassEscape
5435 //
5436 // CharacterClassEscape :: one of
5437 // d D s S w W
5438 case 'd':
5439 case 'D':
5440 case 's':
5441 case 'S':
5442 case 'w':
5443 case 'W': {
5444 uc32 c = Next();
5445 Advance(2);
5446 ZoneList<CharacterRange>* ranges =
5447 new (zone()) ZoneList<CharacterRange>(2, zone());
5448 CharacterRange::AddClassEscape(c, ranges, zone());
5449 RegExpTree* atom = new (zone()) RegExpCharacterClass(ranges, false);
5450 builder->AddAtom(atom);
5451 break;
5452 }
5453 case '1':
5454 case '2':
5455 case '3':
5456 case '4':
5457 case '5':
5458 case '6':
5459 case '7':
5460 case '8':
5461 case '9': {
5462 int index = 0;
5463 if (ParseBackReferenceIndex(&index)) {
5464 if (state->IsInsideCaptureGroup(index)) {
5465 // The backreference is inside the capture group it refers to.
5466 // Nothing can possibly have been captured yet.
5467 builder->AddEmpty();
5468 } else {
5469 RegExpCapture* capture = GetCapture(index);
5470 RegExpTree* atom = new (zone()) RegExpBackReference(capture);
5471 builder->AddAtom(atom);
5472 }
5473 break;
5474 }
5475 uc32 first_digit = Next();
5476 if (first_digit == '8' || first_digit == '9') {
5477 // If the 'u' flag is present, only syntax characters can be
5478 // escaped,
5479 // no other identity escapes are allowed. If the 'u' flag is not
5480 // present, all identity escapes are allowed.
5481 if (!FLAG_harmony_unicode_regexps || !unicode_) {
5482 builder->AddCharacter(first_digit);
5483 Advance(2);
5484 } else {
5485 return ReportError(CStrVector("Invalid escape"));
5486 }
5487 break;
5488 }
5489 }
5490 // FALLTHROUGH
5491 case '0': {
5492 Advance();
5493 uc32 octal = ParseOctalLiteral();
5494 builder->AddCharacter(octal);
5495 break;
5496 }
5497 // ControlEscape :: one of
5498 // f n r t v
5499 case 'f':
5500 Advance(2);
5501 builder->AddCharacter('\f');
5502 break;
5503 case 'n':
5504 Advance(2);
5505 builder->AddCharacter('\n');
5506 break;
5507 case 'r':
5508 Advance(2);
5509 builder->AddCharacter('\r');
5510 break;
5511 case 't':
5512 Advance(2);
5513 builder->AddCharacter('\t');
5514 break;
5515 case 'v':
5516 Advance(2);
5517 builder->AddCharacter('\v');
5518 break;
5519 case 'c': {
5520 Advance();
5521 uc32 controlLetter = Next();
5522 // Special case if it is an ASCII letter.
5523 // Convert lower case letters to uppercase.
5524 uc32 letter = controlLetter & ~('a' ^ 'A');
5525 if (letter < 'A' || 'Z' < letter) {
5526 // controlLetter is not in range 'A'-'Z' or 'a'-'z'.
5527 // This is outside the specification. We match JSC in
5528 // reading the backslash as a literal character instead
5529 // of as starting an escape.
5530 builder->AddCharacter('\\');
5531 } else {
5532 Advance(2);
5533 builder->AddCharacter(controlLetter & 0x1f);
5534 }
5535 break;
5536 }
5537 case 'x': {
5538 Advance(2);
5539 uc32 value;
5540 if (ParseHexEscape(2, &value)) {
5541 builder->AddCharacter(value);
5542 } else if (!FLAG_harmony_unicode_regexps || !unicode_) {
5543 builder->AddCharacter('x');
5544 } else {
5545 // If the 'u' flag is present, invalid escapes are not treated as
5546 // identity escapes.
5547 return ReportError(CStrVector("Invalid escape"));
5548 }
5549 break;
5550 }
5551 case 'u': {
5552 Advance(2);
5553 uc32 value;
5554 if (ParseUnicodeEscape(&value)) {
5555 builder->AddCharacter(value);
5556 } else if (!FLAG_harmony_unicode_regexps || !unicode_) {
5557 builder->AddCharacter('u');
5558 } else {
5559 // If the 'u' flag is present, invalid escapes are not treated as
5560 // identity escapes.
5561 return ReportError(CStrVector("Invalid unicode escape"));
5562 }
5563 break;
5564 }
5565 default:
5566 Advance();
5567 // If the 'u' flag is present, only syntax characters can be
5568 // escaped, no
5569 // other identity escapes are allowed. If the 'u' flag is not
5570 // present,
5571 // all identity escapes are allowed.
5572 if (!FLAG_harmony_unicode_regexps || !unicode_ ||
5573 IsSyntaxCharacter(current())) {
5574 builder->AddCharacter(current());
5400 Advance(); 5575 Advance();
5401 lookaround_type = RegExpLookaround::LOOKBEHIND; 5576 } else {
5402 if (Next() == '=') { 5577 return ReportError(CStrVector("Invalid escape"));
5403 subexpr_type = POSITIVE_LOOKAROUND; 5578 }
5404 break; 5579 break;
5405 } else if (Next() == '!') { 5580 }
5406 subexpr_type = NEGATIVE_LOOKAROUND; 5581 break;
5407 break; 5582 case '{': {
5408 } 5583 int dummy;
5409 } 5584 if (ParseIntervalQuantifier(&dummy, &dummy)) {
5410 // Fall through. 5585 ReportError(CStrVector("Nothing to repeat") CHECK_FAILED);
5411 default: 5586 }
5412 ReportError(CStrVector("Invalid group") CHECK_FAILED); 5587 // fallthrough
5413 break;
5414 }
5415 Advance(2);
5416 } else {
5417 if (captures_started_ >= kMaxCaptures) {
5418 ReportError(CStrVector("Too many captures") CHECK_FAILED);
5419 }
5420 captures_started_++;
5421 }
5422 // Store current state and begin new disjunction parsing.
5423 state = new (zone()) RegExpParserState(
5424 state, subexpr_type, lookaround_type, captures_started_, zone());
5425 builder = state->builder();
5426 continue;
5427 }
5428 case '[': {
5429 RegExpTree* atom = ParseCharacterClass(CHECK_FAILED);
5430 builder->AddAtom(atom);
5431 break;
5432 }
5433 // Atom ::
5434 // \ AtomEscape
5435 case '\\':
5436 switch (Next()) {
5437 case kEndMarker:
5438 return ReportError(CStrVector("\\ at end of pattern"));
5439 case 'b':
5440 Advance(2);
5441 builder->AddAssertion(
5442 new(zone()) RegExpAssertion(RegExpAssertion::BOUNDARY));
5443 continue;
5444 case 'B':
5445 Advance(2);
5446 builder->AddAssertion(
5447 new(zone()) RegExpAssertion(RegExpAssertion::NON_BOUNDARY));
5448 continue;
5449 // AtomEscape ::
5450 // CharacterClassEscape
5451 //
5452 // CharacterClassEscape :: one of
5453 // d D s S w W
5454 case 'd': case 'D': case 's': case 'S': case 'w': case 'W': {
5455 uc32 c = Next();
5456 Advance(2);
5457 ZoneList<CharacterRange>* ranges =
5458 new(zone()) ZoneList<CharacterRange>(2, zone());
5459 CharacterRange::AddClassEscape(c, ranges, zone());
5460 RegExpTree* atom = new(zone()) RegExpCharacterClass(ranges, false);
5461 builder->AddAtom(atom);
5462 break;
5463 }
5464 case '1': case '2': case '3': case '4': case '5': case '6':
5465 case '7': case '8': case '9': {
5466 int index = 0;
5467 if (ParseBackReferenceIndex(&index)) {
5468 if (state->IsInsideCaptureGroup(index)) {
5469 // The backreference is inside the capture group it refers to.
5470 // Nothing can possibly have been captured yet.
5471 builder->AddEmpty();
5472 } else {
5473 RegExpCapture* capture = GetCapture(index);
5474 RegExpTree* atom = new (zone()) RegExpBackReference(capture);
5475 builder->AddAtom(atom);
5476 }
5477 break;
5478 }
5479 uc32 first_digit = Next();
5480 if (first_digit == '8' || first_digit == '9') {
5481 // If the 'u' flag is present, only syntax characters can be escaped,
5482 // no other identity escapes are allowed. If the 'u' flag is not
5483 // present, all identity escapes are allowed.
5484 if (!FLAG_harmony_unicode_regexps || !unicode_) {
5485 builder->AddCharacter(first_digit);
5486 Advance(2);
5487 } else {
5488 return ReportError(CStrVector("Invalid escape"));
5489 }
5490 break;
5491 }
5492 }
5493 // FALLTHROUGH
5494 case '0': {
5495 Advance();
5496 uc32 octal = ParseOctalLiteral();
5497 builder->AddCharacter(octal);
5498 break;
5499 }
5500 // ControlEscape :: one of
5501 // f n r t v
5502 case 'f':
5503 Advance(2);
5504 builder->AddCharacter('\f');
5505 break;
5506 case 'n':
5507 Advance(2);
5508 builder->AddCharacter('\n');
5509 break;
5510 case 'r':
5511 Advance(2);
5512 builder->AddCharacter('\r');
5513 break;
5514 case 't':
5515 Advance(2);
5516 builder->AddCharacter('\t');
5517 break;
5518 case 'v':
5519 Advance(2);
5520 builder->AddCharacter('\v');
5521 break;
5522 case 'c': {
5523 Advance();
5524 uc32 controlLetter = Next();
5525 // Special case if it is an ASCII letter.
5526 // Convert lower case letters to uppercase.
5527 uc32 letter = controlLetter & ~('a' ^ 'A');
5528 if (letter < 'A' || 'Z' < letter) {
5529 // controlLetter is not in range 'A'-'Z' or 'a'-'z'.
5530 // This is outside the specification. We match JSC in
5531 // reading the backslash as a literal character instead
5532 // of as starting an escape.
5533 builder->AddCharacter('\\');
5534 } else {
5535 Advance(2);
5536 builder->AddCharacter(controlLetter & 0x1f);
5537 }
5538 break;
5539 }
5540 case 'x': {
5541 Advance(2);
5542 uc32 value;
5543 if (ParseHexEscape(2, &value)) {
5544 builder->AddCharacter(value);
5545 } else if (!FLAG_harmony_unicode_regexps || !unicode_) {
5546 builder->AddCharacter('x');
5547 } else {
5548 // If the 'u' flag is present, invalid escapes are not treated as
5549 // identity escapes.
5550 return ReportError(CStrVector("Invalid escape"));
5551 }
5552 break;
5553 }
5554 case 'u': {
5555 Advance(2);
5556 uc32 value;
5557 if (ParseUnicodeEscape(&value)) {
5558 builder->AddCharacter(value);
5559 } else if (!FLAG_harmony_unicode_regexps || !unicode_) {
5560 builder->AddCharacter('u');
5561 } else {
5562 // If the 'u' flag is present, invalid escapes are not treated as
5563 // identity escapes.
5564 return ReportError(CStrVector("Invalid unicode escape"));
5565 }
5566 break;
5567 } 5588 }
5568 default: 5589 default:
5569 Advance(); 5590 builder->AddCharacter(current());
5570 // If the 'u' flag is present, only syntax characters can be escaped, no 5591 Advance();
5571 // other identity escapes are allowed. If the 'u' flag is not present, 5592 break;
5572 // all identity escapes are allowed.
5573 if (!FLAG_harmony_unicode_regexps || !unicode_ ||
5574 IsSyntaxCharacter(current())) {
5575 builder->AddCharacter(current());
5576 Advance();
5577 } else {
5578 return ReportError(CStrVector("Invalid escape"));
5579 }
5580 break;
5581 }
5582 break;
5583 case '{': {
5584 int dummy;
5585 if (ParseIntervalQuantifier(&dummy, &dummy)) {
5586 ReportError(CStrVector("Nothing to repeat") CHECK_FAILED);
5587 }
5588 // fallthrough
5589 }
5590 default:
5591 builder->AddCharacter(current());
5592 Advance();
5593 break;
5594 } // end switch(current()) 5593 } // end switch(current())
5595 5594
5596 int min; 5595 int min;
5597 int max; 5596 int max;
5598 switch (current()) { 5597 switch (current()) {
5599 // QuantifierPrefix :: 5598 // QuantifierPrefix ::
5600 // * 5599 // *
5601 // + 5600 // +
5602 // ? 5601 // ?
5603 // { 5602 // {
5604 case '*': 5603 case '*':
5605 min = 0; 5604 min = 0;
5606 max = RegExpTree::kInfinity; 5605 max = RegExpTree::kInfinity;
5607 Advance(); 5606 Advance();
5608 break; 5607 break;
5609 case '+': 5608 case '+':
5610 min = 1; 5609 min = 1;
5611 max = RegExpTree::kInfinity; 5610 max = RegExpTree::kInfinity;
5612 Advance(); 5611 Advance();
5613 break; 5612 break;
5614 case '?': 5613 case '?':
5615 min = 0; 5614 min = 0;
5616 max = 1; 5615 max = 1;
5617 Advance(); 5616 Advance();
5618 break; 5617 break;
5619 case '{': 5618 case '{':
5620 if (ParseIntervalQuantifier(&min, &max)) { 5619 if (ParseIntervalQuantifier(&min, &max)) {
5621 if (max < min) { 5620 if (max < min) {
5622 ReportError(CStrVector("numbers out of order in {} quantifier.") 5621 ReportError(CStrVector("numbers out of order in {} quantifier.")
5623 CHECK_FAILED); 5622 CHECK_FAILED);
5624 } 5623 }
5625 break; 5624 break;
5626 } else { 5625 } else {
5627 continue; 5626 continue;
5628 } 5627 }
5629 default: 5628 default:
5630 continue; 5629 continue;
5631 } 5630 }
5632 RegExpQuantifier::QuantifierType quantifier_type = RegExpQuantifier::GREEDY; 5631 RegExpQuantifier::QuantifierType quantifier_type = RegExpQuantifier::GREEDY;
5633 if (current() == '?') { 5632 if (current() == '?') {
5634 quantifier_type = RegExpQuantifier::NON_GREEDY; 5633 quantifier_type = RegExpQuantifier::NON_GREEDY;
5635 Advance(); 5634 Advance();
5636 } else if (FLAG_regexp_possessive_quantifier && current() == '+') { 5635 } else if (FLAG_regexp_possessive_quantifier && current() == '+') {
5637 // FLAG_regexp_possessive_quantifier is a debug-only flag. 5636 // FLAG_regexp_possessive_quantifier is a debug-only flag.
5638 quantifier_type = RegExpQuantifier::POSSESSIVE; 5637 quantifier_type = RegExpQuantifier::POSSESSIVE;
5639 Advance(); 5638 Advance();
5640 } 5639 }
5641 builder->AddQuantifierToAtom(min, max, quantifier_type); 5640 builder->AddQuantifierToAtom(min, max, quantifier_type);
5642 } 5641 }
5643 } 5642 }
5644 5643
5645 5644
5646 #ifdef DEBUG 5645 #ifdef DEBUG
5647 // Currently only used in an DCHECK. 5646 // Currently only used in an DCHECK.
5648 static bool IsSpecialClassEscape(uc32 c) { 5647 static bool IsSpecialClassEscape(uc32 c) {
5649 switch (c) { 5648 switch (c) {
5650 case 'd': case 'D': 5649 case 'd':
5651 case 's': case 'S': 5650 case 'D':
5652 case 'w': case 'W': 5651 case 's':
5652 case 'S':
5653 case 'w':
5654 case 'W':
5653 return true; 5655 return true;
5654 default: 5656 default:
5655 return false; 5657 return false;
5656 } 5658 }
5657 } 5659 }
5658 #endif 5660 #endif
5659 5661
5660 5662
5661 // In order to know whether an escape is a backreference or not we have to scan 5663 // In order to know whether an escape is a backreference or not we have to scan
5662 // the entire regexp and find the number of capturing parentheses. However we 5664 // the entire regexp and find the number of capturing parentheses. However we
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after
5929 return '\t'; 5931 return '\t';
5930 case 'v': 5932 case 'v':
5931 Advance(); 5933 Advance();
5932 return '\v'; 5934 return '\v';
5933 case 'c': { 5935 case 'c': {
5934 uc32 controlLetter = Next(); 5936 uc32 controlLetter = Next();
5935 uc32 letter = controlLetter & ~('A' ^ 'a'); 5937 uc32 letter = controlLetter & ~('A' ^ 'a');
5936 // For compatibility with JSC, inside a character class 5938 // For compatibility with JSC, inside a character class
5937 // we also accept digits and underscore as control characters. 5939 // we also accept digits and underscore as control characters.
5938 if ((controlLetter >= '0' && controlLetter <= '9') || 5940 if ((controlLetter >= '0' && controlLetter <= '9') ||
5939 controlLetter == '_' || 5941 controlLetter == '_' || (letter >= 'A' && letter <= 'Z')) {
5940 (letter >= 'A' && letter <= 'Z')) {
5941 Advance(2); 5942 Advance(2);
5942 // Control letters mapped to ASCII control characters in the range 5943 // Control letters mapped to ASCII control characters in the range
5943 // 0x00-0x1f. 5944 // 0x00-0x1f.
5944 return controlLetter & 0x1f; 5945 return controlLetter & 0x1f;
5945 } 5946 }
5946 // We match JSC in reading the backslash as a literal 5947 // We match JSC in reading the backslash as a literal
5947 // character instead of as starting an escape. 5948 // character instead of as starting an escape.
5948 return '\\'; 5949 return '\\';
5949 } 5950 }
5950 case '0': case '1': case '2': case '3': case '4': case '5': 5951 case '0':
5951 case '6': case '7': 5952 case '1':
5953 case '2':
5954 case '3':
5955 case '4':
5956 case '5':
5957 case '6':
5958 case '7':
5952 // For compatibility, we interpret a decimal escape that isn't 5959 // For compatibility, we interpret a decimal escape that isn't
5953 // a back reference (and therefore either \0 or not valid according 5960 // a back reference (and therefore either \0 or not valid according
5954 // to the specification) as a 1..3 digit octal character code. 5961 // to the specification) as a 1..3 digit octal character code.
5955 return ParseOctalLiteral(); 5962 return ParseOctalLiteral();
5956 case 'x': { 5963 case 'x': {
5957 Advance(); 5964 Advance();
5958 uc32 value; 5965 uc32 value;
5959 if (ParseHexEscape(2, &value)) { 5966 if (ParseHexEscape(2, &value)) {
5960 return value; 5967 return value;
5961 } 5968 }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
5999 } 6006 }
6000 return 0; 6007 return 0;
6001 } 6008 }
6002 6009
6003 6010
6004 CharacterRange RegExpParser::ParseClassAtom(uc16* char_class) { 6011 CharacterRange RegExpParser::ParseClassAtom(uc16* char_class) {
6005 DCHECK_EQ(0, *char_class); 6012 DCHECK_EQ(0, *char_class);
6006 uc32 first = current(); 6013 uc32 first = current();
6007 if (first == '\\') { 6014 if (first == '\\') {
6008 switch (Next()) { 6015 switch (Next()) {
6009 case 'w': case 'W': case 'd': case 'D': case 's': case 'S': { 6016 case 'w':
6017 case 'W':
6018 case 'd':
6019 case 'D':
6020 case 's':
6021 case 'S': {
6010 *char_class = Next(); 6022 *char_class = Next();
6011 Advance(2); 6023 Advance(2);
6012 return CharacterRange::Singleton(0); // Return dummy value. 6024 return CharacterRange::Singleton(0); // Return dummy value.
6013 } 6025 }
6014 case kEndMarker: 6026 case kEndMarker:
6015 return ReportError(CStrVector("\\ at end of pattern")); 6027 return ReportError(CStrVector("\\ at end of pattern"));
6016 default: 6028 default:
6017 uc32 c = ParseClassCharacterEscape(CHECK_FAILED); 6029 uc32 c = ParseClassCharacterEscape(CHECK_FAILED);
6018 return CharacterRange::Singleton(c); 6030 return CharacterRange::Singleton(c);
6019 } 6031 }
6020 } else { 6032 } else {
6021 Advance(); 6033 Advance();
6022 return CharacterRange::Singleton(first); 6034 return CharacterRange::Singleton(first);
6023 } 6035 }
6024 } 6036 }
6025 6037
6026 6038
6027 static const uc16 kNoCharClass = 0; 6039 static const uc16 kNoCharClass = 0;
6028 6040
6029 // Adds range or pre-defined character class to character ranges. 6041 // Adds range or pre-defined character class to character ranges.
6030 // If char_class is not kInvalidClass, it's interpreted as a class 6042 // If char_class is not kInvalidClass, it's interpreted as a class
6031 // escape (i.e., 's' means whitespace, from '\s'). 6043 // escape (i.e., 's' means whitespace, from '\s').
6032 static inline void AddRangeOrEscape(ZoneList<CharacterRange>* ranges, 6044 static inline void AddRangeOrEscape(ZoneList<CharacterRange>* ranges,
6033 uc16 char_class, 6045 uc16 char_class, CharacterRange range,
6034 CharacterRange range,
6035 Zone* zone) { 6046 Zone* zone) {
6036 if (char_class != kNoCharClass) { 6047 if (char_class != kNoCharClass) {
6037 CharacterRange::AddClassEscape(char_class, ranges, zone); 6048 CharacterRange::AddClassEscape(char_class, ranges, zone);
6038 } else { 6049 } else {
6039 ranges->Add(range, zone); 6050 ranges->Add(range, zone);
6040 } 6051 }
6041 } 6052 }
6042 6053
6043 6054
6044 RegExpTree* RegExpParser::ParseCharacterClass() { 6055 RegExpTree* RegExpParser::ParseCharacterClass() {
6045 static const char* kUnterminated = "Unterminated character class"; 6056 static const char* kUnterminated = "Unterminated character class";
6046 static const char* kRangeOutOfOrder = "Range out of order in character class"; 6057 static const char* kRangeOutOfOrder = "Range out of order in character class";
6047 6058
6048 DCHECK_EQ(current(), '['); 6059 DCHECK_EQ(current(), '[');
6049 Advance(); 6060 Advance();
6050 bool is_negated = false; 6061 bool is_negated = false;
6051 if (current() == '^') { 6062 if (current() == '^') {
6052 is_negated = true; 6063 is_negated = true;
6053 Advance(); 6064 Advance();
6054 } 6065 }
6055 ZoneList<CharacterRange>* ranges = 6066 ZoneList<CharacterRange>* ranges =
6056 new(zone()) ZoneList<CharacterRange>(2, zone()); 6067 new (zone()) ZoneList<CharacterRange>(2, zone());
6057 while (has_more() && current() != ']') { 6068 while (has_more() && current() != ']') {
6058 uc16 char_class = kNoCharClass; 6069 uc16 char_class = kNoCharClass;
6059 CharacterRange first = ParseClassAtom(&char_class CHECK_FAILED); 6070 CharacterRange first = ParseClassAtom(&char_class CHECK_FAILED);
6060 if (current() == '-') { 6071 if (current() == '-') {
6061 Advance(); 6072 Advance();
6062 if (current() == kEndMarker) { 6073 if (current() == kEndMarker) {
6063 // If we reach the end we break out of the loop and let the 6074 // If we reach the end we break out of the loop and let the
6064 // following code report an error. 6075 // following code report an error.
6065 break; 6076 break;
6066 } else if (current() == ']') { 6077 } else if (current() == ']') {
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
6242 Expression* cooked_str = cooked_strings->at(i); 6253 Expression* cooked_str = cooked_strings->at(i);
6243 6254
6244 // Let middle be ToString(sub). 6255 // Let middle be ToString(sub).
6245 ZoneList<Expression*>* args = 6256 ZoneList<Expression*>* args =
6246 new (zone()) ZoneList<Expression*>(1, zone()); 6257 new (zone()) ZoneList<Expression*>(1, zone());
6247 args->Add(sub, zone()); 6258 args->Add(sub, zone());
6248 Expression* middle = factory()->NewCallRuntime(Runtime::kInlineToString, 6259 Expression* middle = factory()->NewCallRuntime(Runtime::kInlineToString,
6249 args, sub->position()); 6260 args, sub->position());
6250 6261
6251 expr = factory()->NewBinaryOperation( 6262 expr = factory()->NewBinaryOperation(
6252 Token::ADD, factory()->NewBinaryOperation( 6263 Token::ADD, factory()->NewBinaryOperation(Token::ADD, expr, middle,
6253 Token::ADD, expr, middle, expr->position()), 6264 expr->position()),
6254 cooked_str, sub->position()); 6265 cooked_str, sub->position());
6255 } 6266 }
6256 return expr; 6267 return expr;
6257 } else { 6268 } else {
6258 uint32_t hash = ComputeTemplateLiteralHash(lit); 6269 uint32_t hash = ComputeTemplateLiteralHash(lit);
6259 6270
6260 int cooked_idx = function_state_->NextMaterializedLiteralIndex(); 6271 int cooked_idx = function_state_->NextMaterializedLiteralIndex();
6261 int raw_idx = function_state_->NextMaterializedLiteralIndex(); 6272 int raw_idx = function_state_->NextMaterializedLiteralIndex();
6262 6273
6263 // $getTemplateCallSite 6274 // $getTemplateCallSite
6264 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(4, zone()); 6275 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(4, zone());
6265 args->Add(factory()->NewArrayLiteral( 6276 args->Add(factory()->NewArrayLiteral(
6266 const_cast<ZoneList<Expression*>*>(cooked_strings), 6277 const_cast<ZoneList<Expression*>*>(cooked_strings),
6267 cooked_idx, is_strong(language_mode()), pos), 6278 cooked_idx, is_strong(language_mode()), pos),
6268 zone()); 6279 zone());
6269 args->Add( 6280 args->Add(factory()->NewArrayLiteral(
6270 factory()->NewArrayLiteral( 6281 const_cast<ZoneList<Expression*>*>(raw_strings), raw_idx,
6271 const_cast<ZoneList<Expression*>*>(raw_strings), raw_idx, 6282 is_strong(language_mode()), pos),
6272 is_strong(language_mode()), pos), 6283 zone());
6273 zone());
6274 6284
6275 // Ensure hash is suitable as a Smi value 6285 // Ensure hash is suitable as a Smi value
6276 Smi* hash_obj = Smi::cast(Internals::IntToSmi(static_cast<int>(hash))); 6286 Smi* hash_obj = Smi::cast(Internals::IntToSmi(static_cast<int>(hash)));
6277 args->Add(factory()->NewSmiLiteral(hash_obj->value(), pos), zone()); 6287 args->Add(factory()->NewSmiLiteral(hash_obj->value(), pos), zone());
6278 6288
6279 this->CheckPossibleEvalCall(tag, scope_); 6289 this->CheckPossibleEvalCall(tag, scope_);
6280 Expression* call_site = factory()->NewCallRuntime( 6290 Expression* call_site = factory()->NewCallRuntime(
6281 Context::GET_TEMPLATE_CALL_SITE_INDEX, args, start); 6291 Context::GET_TEMPLATE_CALL_SITE_INDEX, args, start);
6282 6292
6283 // Call TagFn 6293 // Call TagFn
6284 ZoneList<Expression*>* call_args = 6294 ZoneList<Expression*>* call_args =
6285 new (zone()) ZoneList<Expression*>(expressions->length() + 1, zone()); 6295 new (zone()) ZoneList<Expression*>(expressions->length() + 1, zone());
6286 call_args->Add(call_site, zone()); 6296 call_args->Add(call_site, zone());
6287 call_args->AddAll(*expressions, zone()); 6297 call_args->AddAll(*expressions, zone());
6288 return factory()->NewCall(tag, call_args, pos); 6298 return factory()->NewCall(tag, call_args, pos);
6289 } 6299 }
6290 } 6300 }
6291 6301
6292 6302
6293 uint32_t Parser::ComputeTemplateLiteralHash(const TemplateLiteral* lit) { 6303 uint32_t Parser::ComputeTemplateLiteralHash(const TemplateLiteral* lit) {
6294 const ZoneList<Expression*>* raw_strings = lit->raw(); 6304 const ZoneList<Expression*>* raw_strings = lit->raw();
6295 int total = raw_strings->length(); 6305 int total = raw_strings->length();
6296 DCHECK(total); 6306 DCHECK(total);
6297 6307
6298 uint32_t running_hash = 0; 6308 uint32_t running_hash = 0;
6299 6309
6300 for (int index = 0; index < total; ++index) { 6310 for (int index = 0; index < total; ++index) {
6301 if (index) { 6311 if (index) {
6302 running_hash = StringHasher::ComputeRunningHashOneByte( 6312 running_hash =
6303 running_hash, "${}", 3); 6313 StringHasher::ComputeRunningHashOneByte(running_hash, "${}", 3);
6304 } 6314 }
6305 6315
6306 const AstRawString* raw_string = 6316 const AstRawString* raw_string =
6307 raw_strings->at(index)->AsLiteral()->raw_value()->AsString(); 6317 raw_strings->at(index)->AsLiteral()->raw_value()->AsString();
6308 if (raw_string->is_one_byte()) { 6318 if (raw_string->is_one_byte()) {
6309 const char* data = reinterpret_cast<const char*>(raw_string->raw_data()); 6319 const char* data = reinterpret_cast<const char*>(raw_string->raw_data());
6310 running_hash = StringHasher::ComputeRunningHashOneByte( 6320 running_hash = StringHasher::ComputeRunningHashOneByte(
6311 running_hash, data, raw_string->length()); 6321 running_hash, data, raw_string->length());
6312 } else { 6322 } else {
6313 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data()); 6323 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data());
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
6455 } 6465 }
6456 6466
6457 6467
6458 void Parser::RaiseLanguageMode(LanguageMode mode) { 6468 void Parser::RaiseLanguageMode(LanguageMode mode) {
6459 SetLanguageMode(scope_, 6469 SetLanguageMode(scope_,
6460 static_cast<LanguageMode>(scope_->language_mode() | mode)); 6470 static_cast<LanguageMode>(scope_->language_mode() | mode));
6461 } 6471 }
6462 6472
6463 } // namespace internal 6473 } // namespace internal
6464 } // namespace v8 6474 } // namespace v8
OLDNEW
« no previous file with comments | « src/parsing/parser.h ('k') | src/parsing/pattern-rewriter.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698