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

Side by Side Diff: src/parsing/parser-base.h

Issue 1708193003: Reduce the memory footprint of expression classifiers (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Improve expression classifier accumulate Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
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 #ifndef V8_PARSING_PARSER_BASE_H 5 #ifndef V8_PARSING_PARSER_BASE_H
6 #define V8_PARSING_PARSER_BASE_H 6 #define V8_PARSING_PARSER_BASE_H
7 7
8 #include "src/ast/scopes.h" 8 #include "src/ast/scopes.h"
9 #include "src/bailout-reason.h" 9 #include "src/bailout-reason.h"
10 #include "src/hashmap.h" 10 #include "src/hashmap.h"
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after
378 DCHECK(is_resumable()); 378 DCHECK(is_resumable());
379 generator_object_variable_ = variable; 379 generator_object_variable_ = variable;
380 } 380 }
381 typename Traits::Type::GeneratorVariable* generator_object_variable() 381 typename Traits::Type::GeneratorVariable* generator_object_variable()
382 const { 382 const {
383 return generator_object_variable_; 383 return generator_object_variable_;
384 } 384 }
385 385
386 typename Traits::Type::Factory* factory() { return factory_; } 386 typename Traits::Type::Factory* factory() { return factory_; }
387 387
388 const List<DestructuringAssignment>& destructuring_assignments_to_rewrite() 388 const ZoneList<DestructuringAssignment>&
389 const { 389 destructuring_assignments_to_rewrite() const {
390 return destructuring_assignments_to_rewrite_; 390 return destructuring_assignments_to_rewrite_;
391 } 391 }
392 392
393 TailCallExpressionList& tail_call_expressions() { 393 TailCallExpressionList& tail_call_expressions() {
394 return tail_call_expressions_; 394 return tail_call_expressions_;
395 } 395 }
396 void AddImplicitTailCallExpression(ExpressionT expression) { 396 void AddImplicitTailCallExpression(ExpressionT expression) {
397 if (return_expr_context() == 397 if (return_expr_context() ==
398 ReturnExprContext::kInsideValidReturnStatement) { 398 ReturnExprContext::kInsideValidReturnStatement) {
399 tail_call_expressions_.AddImplicitTailCall(expression); 399 tail_call_expressions_.AddImplicitTailCall(expression);
400 } 400 }
401 } 401 }
402 void AddExplicitTailCallExpression(ExpressionT expression, 402 void AddExplicitTailCallExpression(ExpressionT expression,
403 const Scanner::Location& loc) { 403 const Scanner::Location& loc) {
404 DCHECK(expression->IsCall()); 404 DCHECK(expression->IsCall());
405 if (return_expr_context() == 405 if (return_expr_context() ==
406 ReturnExprContext::kInsideValidReturnStatement) { 406 ReturnExprContext::kInsideValidReturnStatement) {
407 tail_call_expressions_.AddExplicitTailCall(expression, loc); 407 tail_call_expressions_.AddExplicitTailCall(expression, loc);
408 } 408 }
409 } 409 }
410 410
411 ZoneList<typename ExpressionClassifier::Error>* GetReportedErrorList() {
412 return &reported_errors_;
413 }
414
411 ReturnExprContext return_expr_context() const { 415 ReturnExprContext return_expr_context() const {
412 return return_expr_context_; 416 return return_expr_context_;
413 } 417 }
414 void set_return_expr_context(ReturnExprContext context) { 418 void set_return_expr_context(ReturnExprContext context) {
415 return_expr_context_ = context; 419 return_expr_context_ = context;
416 } 420 }
417 421
418 ZoneList<ExpressionT>* non_patterns_to_rewrite() { 422 ZoneList<ExpressionT>* non_patterns_to_rewrite() {
419 return &non_patterns_to_rewrite_; 423 return &non_patterns_to_rewrite_;
420 } 424 }
421 425
422 void next_function_is_parenthesized(bool parenthesized) { 426 void next_function_is_parenthesized(bool parenthesized) {
423 next_function_is_parenthesized_ = parenthesized; 427 next_function_is_parenthesized_ = parenthesized;
424 } 428 }
425 429
426 bool this_function_is_parenthesized() const { 430 bool this_function_is_parenthesized() const {
427 return this_function_is_parenthesized_; 431 return this_function_is_parenthesized_;
428 } 432 }
429 433
430 private: 434 private:
431 void AddDestructuringAssignment(DestructuringAssignment pair) { 435 void AddDestructuringAssignment(DestructuringAssignment pair) {
432 destructuring_assignments_to_rewrite_.Add(pair); 436 destructuring_assignments_to_rewrite_.Add(pair, (*scope_stack_)->zone());
433 } 437 }
434 438
435 V8_INLINE Scope* scope() { return *scope_stack_; } 439 V8_INLINE Scope* scope() { return *scope_stack_; }
436 440
437 void AddNonPatternForRewriting(ExpressionT expr) { 441 void AddNonPatternForRewriting(ExpressionT expr) {
438 non_patterns_to_rewrite_.Add(expr, (*scope_stack_)->zone()); 442 non_patterns_to_rewrite_.Add(expr, (*scope_stack_)->zone());
439 } 443 }
440 444
441 // Used to assign an index to each literal that needs materialization in 445 // Used to assign an index to each literal that needs materialization in
442 // the function. Includes regexp literals, and boilerplate for object and 446 // the function. Includes regexp literals, and boilerplate for object and
(...skipping 16 matching lines...) Expand all
459 // For generators, this variable may hold the generator object. It variable 463 // For generators, this variable may hold the generator object. It variable
460 // is used by yield expressions and return statements. It is not necessary 464 // is used by yield expressions and return statements. It is not necessary
461 // for generator functions to have this variable set. 465 // for generator functions to have this variable set.
462 Variable* generator_object_variable_; 466 Variable* generator_object_variable_;
463 467
464 FunctionState** function_state_stack_; 468 FunctionState** function_state_stack_;
465 FunctionState* outer_function_state_; 469 FunctionState* outer_function_state_;
466 Scope** scope_stack_; 470 Scope** scope_stack_;
467 Scope* outer_scope_; 471 Scope* outer_scope_;
468 472
469 List<DestructuringAssignment> destructuring_assignments_to_rewrite_; 473 ZoneList<DestructuringAssignment> destructuring_assignments_to_rewrite_;
adamk 2016/06/06 20:51:02 Yikes, was this a memory leak before? Maybe pull t
nickie 2016/06/08 11:38:46 As far as I understand, it was not a memory leak.
adamk 2016/06/09 08:25:36 Ah, I forgot this was in FunctionState, not some Z
470 TailCallExpressionList tail_call_expressions_; 474 TailCallExpressionList tail_call_expressions_;
471 ReturnExprContext return_expr_context_; 475 ReturnExprContext return_expr_context_;
472 ZoneList<ExpressionT> non_patterns_to_rewrite_; 476 ZoneList<ExpressionT> non_patterns_to_rewrite_;
473 477
478 ZoneList<typename ExpressionClassifier::Error> reported_errors_;
479
474 typename Traits::Type::Factory* factory_; 480 typename Traits::Type::Factory* factory_;
475 481
476 // If true, the next (and immediately following) function literal is 482 // If true, the next (and immediately following) function literal is
477 // preceded by a parenthesis. 483 // preceded by a parenthesis.
478 bool next_function_is_parenthesized_; 484 bool next_function_is_parenthesized_;
479 485
480 // The value of the parents' next_function_is_parenthesized_, as it applies 486 // The value of the parents' next_function_is_parenthesized_, as it applies
481 // to this function. Filled in by constructor. 487 // to this function. Filled in by constructor.
482 bool this_function_is_parenthesized_; 488 bool this_function_is_parenthesized_;
483 489
(...skipping 702 matching lines...) Expand 10 before | Expand all | Expand 10 after
1186 expected_property_count_(0), 1192 expected_property_count_(0),
1187 this_location_(Scanner::Location::invalid()), 1193 this_location_(Scanner::Location::invalid()),
1188 return_location_(Scanner::Location::invalid()), 1194 return_location_(Scanner::Location::invalid()),
1189 super_location_(Scanner::Location::invalid()), 1195 super_location_(Scanner::Location::invalid()),
1190 kind_(kind), 1196 kind_(kind),
1191 generator_object_variable_(NULL), 1197 generator_object_variable_(NULL),
1192 function_state_stack_(function_state_stack), 1198 function_state_stack_(function_state_stack),
1193 outer_function_state_(*function_state_stack), 1199 outer_function_state_(*function_state_stack),
1194 scope_stack_(scope_stack), 1200 scope_stack_(scope_stack),
1195 outer_scope_(*scope_stack), 1201 outer_scope_(*scope_stack),
1202 destructuring_assignments_to_rewrite_(16, scope->zone()),
1196 tail_call_expressions_(scope->zone()), 1203 tail_call_expressions_(scope->zone()),
1197 return_expr_context_(ReturnExprContext::kInsideValidBlock), 1204 return_expr_context_(ReturnExprContext::kInsideValidBlock),
1198 non_patterns_to_rewrite_(0, scope->zone()), 1205 non_patterns_to_rewrite_(0, scope->zone()),
1206 reported_errors_(16, scope->zone()),
1199 factory_(factory), 1207 factory_(factory),
1200 next_function_is_parenthesized_(false), 1208 next_function_is_parenthesized_(false),
1201 this_function_is_parenthesized_(false) { 1209 this_function_is_parenthesized_(false) {
1202 *scope_stack_ = scope; 1210 *scope_stack_ = scope;
1203 *function_state_stack = this; 1211 *function_state_stack = this;
1204 if (outer_function_state_) { 1212 if (outer_function_state_) {
1205 this_function_is_parenthesized_ = 1213 this_function_is_parenthesized_ =
1206 outer_function_state_->next_function_is_parenthesized_; 1214 outer_function_state_->next_function_is_parenthesized_;
1207 outer_function_state_->next_function_is_parenthesized_ = false; 1215 outer_function_state_->next_function_is_parenthesized_ = false;
1208 } 1216 }
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after
1545 1553
1546 case Token::LBRACE: 1554 case Token::LBRACE:
1547 return this->ParseObjectLiteral(classifier, ok); 1555 return this->ParseObjectLiteral(classifier, ok);
1548 1556
1549 case Token::LPAREN: { 1557 case Token::LPAREN: {
1550 // Arrow function formal parameters are either a single identifier or a 1558 // Arrow function formal parameters are either a single identifier or a
1551 // list of BindingPattern productions enclosed in parentheses. 1559 // list of BindingPattern productions enclosed in parentheses.
1552 // Parentheses are not valid on the LHS of a BindingPattern, so we use the 1560 // Parentheses are not valid on the LHS of a BindingPattern, so we use the
1553 // is_valid_binding_pattern() check to detect multiple levels of 1561 // is_valid_binding_pattern() check to detect multiple levels of
1554 // parenthesization. 1562 // parenthesization.
1555 if (!classifier->is_valid_binding_pattern()) { 1563 bool pattern_error = !classifier->is_valid_binding_pattern();
1556 ArrowFormalParametersUnexpectedToken(classifier);
1557 }
1558 classifier->RecordPatternError(scanner()->peek_location(), 1564 classifier->RecordPatternError(scanner()->peek_location(),
1559 MessageTemplate::kUnexpectedToken, 1565 MessageTemplate::kUnexpectedToken,
1560 Token::String(Token::LPAREN)); 1566 Token::String(Token::LPAREN));
1567 if (pattern_error) ArrowFormalParametersUnexpectedToken(classifier);
adamk 2016/06/06 20:51:02 Why was this reordering necessary? I think I'm mis
nickie 2016/06/08 11:38:46 This one is not related to the "stack-based fashio
1561 Consume(Token::LPAREN); 1568 Consume(Token::LPAREN);
1562 if (Check(Token::RPAREN)) { 1569 if (Check(Token::RPAREN)) {
1563 // ()=>x. The continuation that looks for the => is in 1570 // ()=>x. The continuation that looks for the => is in
1564 // ParseAssignmentExpression. 1571 // ParseAssignmentExpression.
1565 classifier->RecordExpressionError(scanner()->location(), 1572 classifier->RecordExpressionError(scanner()->location(),
1566 MessageTemplate::kUnexpectedToken, 1573 MessageTemplate::kUnexpectedToken,
1567 Token::String(Token::RPAREN)); 1574 Token::String(Token::RPAREN));
1568 return factory()->NewEmptyParentheses(beg_pos); 1575 return factory()->NewEmptyParentheses(beg_pos);
1569 } else if (Check(Token::ELLIPSIS)) { 1576 } else if (Check(Token::ELLIPSIS)) {
1570 // (...x)=>x. The continuation that looks for the => is in 1577 // (...x)=>x. The continuation that looks for the => is in
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1656 return result; 1663 return result;
1657 } 1664 }
1658 1665
1659 template <class Traits> 1666 template <class Traits>
1660 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( 1667 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
1661 bool accept_IN, ExpressionClassifier* classifier, bool* ok) { 1668 bool accept_IN, ExpressionClassifier* classifier, bool* ok) {
1662 // Expression :: 1669 // Expression ::
1663 // AssignmentExpression 1670 // AssignmentExpression
1664 // Expression ',' AssignmentExpression 1671 // Expression ',' AssignmentExpression
1665 1672
1666 ExpressionClassifier binding_classifier(this); 1673 ExpressionClassifier binding_classifier(this);
adamk 2016/06/06 20:51:02 Can we wrap this and the next two lines in a block
nickie 2016/06/08 11:38:46 What you're suggesting is a common pattern in pars
adamk 2016/06/09 08:25:36 If you think it's unlikely to be a significant per
1667 ExpressionT result = 1674 ExpressionT result =
adamk 2016/06/06 20:51:02 If you can do the above, this'll have to be declar
1668 this->ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK); 1675 this->ParseAssignmentExpression(accept_IN, &binding_classifier, CHECK_OK);
1669 classifier->Accumulate(&binding_classifier, 1676 classifier->Accumulate(&binding_classifier,
1670 ExpressionClassifier::AllProductions); 1677 ExpressionClassifier::AllProductions);
1671 bool is_simple_parameter_list = this->IsIdentifier(result); 1678 bool is_simple_parameter_list = this->IsIdentifier(result);
1672 bool seen_rest = false; 1679 bool seen_rest = false;
1673 while (peek() == Token::COMMA) { 1680 while (peek() == Token::COMMA) {
1674 CheckNoTailCallExpressions(classifier, CHECK_OK); 1681 CheckNoTailCallExpressions(classifier, CHECK_OK);
1675 if (seen_rest) { 1682 if (seen_rest) {
1676 // At this point the production can't possibly be valid, but we don't know 1683 // At this point the production can't possibly be valid, but we don't know
1677 // which error to signal. 1684 // which error to signal.
1678 classifier->RecordArrowFormalParametersError( 1685 classifier->RecordArrowFormalParametersError(
1679 scanner()->peek_location(), MessageTemplate::kParamAfterRest); 1686 scanner()->peek_location(), MessageTemplate::kParamAfterRest);
1680 } 1687 }
1681 Consume(Token::COMMA); 1688 Consume(Token::COMMA);
1682 bool is_rest = false; 1689 bool is_rest = false;
1683 if (peek() == Token::ELLIPSIS) { 1690 if (peek() == Token::ELLIPSIS) {
1684 // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only 1691 // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only
1685 // as the formal parameters of'(x, y, ...z) => foo', and is not itself a 1692 // as the formal parameters of'(x, y, ...z) => foo', and is not itself a
1686 // valid expression or binding pattern. 1693 // valid expression or binding pattern.
1687 ExpressionUnexpectedToken(classifier); 1694 ExpressionUnexpectedToken(classifier);
1688 BindingPatternUnexpectedToken(classifier); 1695 BindingPatternUnexpectedToken(classifier);
1689 Consume(Token::ELLIPSIS); 1696 Consume(Token::ELLIPSIS);
1690 seen_rest = is_rest = true; 1697 seen_rest = is_rest = true;
1691 } 1698 }
1692 int pos = position(), expr_pos = peek_position(); 1699 int pos = position(), expr_pos = peek_position();
1700 ExpressionClassifier binding_classifier(this);
nickie 2016/06/08 11:38:46 Same thing; a block could be introduced here.
1693 ExpressionT right = this->ParseAssignmentExpression( 1701 ExpressionT right = this->ParseAssignmentExpression(
1694 accept_IN, &binding_classifier, CHECK_OK); 1702 accept_IN, &binding_classifier, CHECK_OK);
1695 classifier->Accumulate(&binding_classifier, 1703 classifier->Accumulate(&binding_classifier,
1696 ExpressionClassifier::AllProductions); 1704 ExpressionClassifier::AllProductions);
1697 if (is_rest) { 1705 if (is_rest) {
1698 if (!this->IsIdentifier(right) && !IsValidPattern(right)) { 1706 if (!this->IsIdentifier(right) && !IsValidPattern(right)) {
1699 classifier->RecordArrowFormalParametersError( 1707 classifier->RecordArrowFormalParametersError(
1700 Scanner::Location(pos, scanner()->location().end_pos), 1708 Scanner::Location(pos, scanner()->location().end_pos),
1701 MessageTemplate::kInvalidRestParameter); 1709 MessageTemplate::kInvalidRestParameter);
1702 } 1710 }
(...skipping 514 matching lines...) Expand 10 before | Expand all | Expand 10 after
2217 2225
2218 if (is_async && peek_any_identifier() && PeekAhead() == Token::ARROW) { 2226 if (is_async && peek_any_identifier() && PeekAhead() == Token::ARROW) {
2219 // async Identifier => AsyncConciseBody 2227 // async Identifier => AsyncConciseBody
2220 IdentifierT name = 2228 IdentifierT name =
2221 ParseAndClassifyIdentifier(&arrow_formals_classifier, CHECK_OK); 2229 ParseAndClassifyIdentifier(&arrow_formals_classifier, CHECK_OK);
2222 expression = this->ExpressionFromIdentifier( 2230 expression = this->ExpressionFromIdentifier(
2223 name, position(), scanner()->location().end_pos, scope_, factory()); 2231 name, position(), scanner()->location().end_pos, scope_, factory());
2224 } 2232 }
2225 2233
2226 if (peek() == Token::ARROW) { 2234 if (peek() == Token::ARROW) {
2227 classifier->RecordPatternError(scanner()->peek_location(), 2235 typename ExpressionClassifier::Error e1 =
2228 MessageTemplate::kUnexpectedToken, 2236 ExpressionClassifier::BindingPatternError(
2229 Token::String(Token::ARROW)); 2237 scanner()->peek_location(), MessageTemplate::kUnexpectedToken,
adamk 2016/06/06 20:51:02 Can you just store the location here, and move the
nickie 2016/06/08 11:38:46 Done.
2238 Token::String(Token::ARROW));
2239 typename ExpressionClassifier::Error e2 =
2240 ExpressionClassifier::AssignmentPatternError(
2241 scanner()->peek_location(), MessageTemplate::kUnexpectedToken,
2242 Token::String(Token::ARROW));
2230 ValidateArrowFormalParameters(&arrow_formals_classifier, expression, 2243 ValidateArrowFormalParameters(&arrow_formals_classifier, expression,
2231 parenthesized_formals, is_async, CHECK_OK); 2244 parenthesized_formals, is_async, CHECK_OK);
2232 // This reads strangely, but is correct: it checks whether any 2245 // This reads strangely, but is correct: it checks whether any
2233 // sub-expression of the parameter list failed to be a valid formal 2246 // sub-expression of the parameter list failed to be a valid formal
2234 // parameter initializer. Since YieldExpressions are banned anywhere 2247 // parameter initializer. Since YieldExpressions are banned anywhere
2235 // in an arrow parameter list, this is correct. 2248 // in an arrow parameter list, this is correct.
2236 // TODO(adamk): Rename "FormalParameterInitializerError" to refer to 2249 // TODO(adamk): Rename "FormalParameterInitializerError" to refer to
2237 // "YieldExpression", which is its only use. 2250 // "YieldExpression", which is its only use.
2238 ValidateFormalParameterInitializer(&arrow_formals_classifier, ok); 2251 ValidateFormalParameterInitializer(&arrow_formals_classifier, ok);
2239 2252
(...skipping 16 matching lines...) Expand all
2256 scope->set_start_position(lhs_beg_pos); 2269 scope->set_start_position(lhs_beg_pos);
2257 Scanner::Location duplicate_loc = Scanner::Location::invalid(); 2270 Scanner::Location duplicate_loc = Scanner::Location::invalid();
2258 this->ParseArrowFunctionFormalParameterList(&parameters, expression, loc, 2271 this->ParseArrowFunctionFormalParameterList(&parameters, expression, loc,
2259 &duplicate_loc, CHECK_OK); 2272 &duplicate_loc, CHECK_OK);
2260 if (duplicate_loc.IsValid()) { 2273 if (duplicate_loc.IsValid()) {
2261 arrow_formals_classifier.RecordDuplicateFormalParameterError( 2274 arrow_formals_classifier.RecordDuplicateFormalParameterError(
2262 duplicate_loc); 2275 duplicate_loc);
2263 } 2276 }
2264 expression = this->ParseArrowFunctionLiteral( 2277 expression = this->ParseArrowFunctionLiteral(
2265 accept_IN, parameters, is_async, arrow_formals_classifier, CHECK_OK); 2278 accept_IN, parameters, is_async, arrow_formals_classifier, CHECK_OK);
2279 arrow_formals_classifier.Discard();
2280 classifier->RecordBindingPatternError(e1);
2281 classifier->RecordAssignmentPatternError(e2);
2266 2282
2267 if (fni_ != nullptr) fni_->Infer(); 2283 if (fni_ != nullptr) fni_->Infer();
2268 2284
2269 return expression; 2285 return expression;
2270 } 2286 }
2271 2287
2272 if (this->IsValidReferenceExpression(expression)) { 2288 if (this->IsValidReferenceExpression(expression)) {
2273 arrow_formals_classifier.ForgiveAssignmentPatternError(); 2289 arrow_formals_classifier.ForgiveAssignmentPatternError();
2274 } 2290 }
2275 2291
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
2495 // LogicalOrExpression 2511 // LogicalOrExpression
2496 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression 2512 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression
2497 2513
2498 int pos = peek_position(); 2514 int pos = peek_position();
2499 // We start using the binary expression parser for prec >= 4 only! 2515 // We start using the binary expression parser for prec >= 4 only!
2500 ExpressionT expression = 2516 ExpressionT expression =
2501 this->ParseBinaryExpression(4, accept_IN, classifier, CHECK_OK); 2517 this->ParseBinaryExpression(4, accept_IN, classifier, CHECK_OK);
2502 if (peek() != Token::CONDITIONAL) return expression; 2518 if (peek() != Token::CONDITIONAL) return expression;
2503 CheckNoTailCallExpressions(classifier, CHECK_OK); 2519 CheckNoTailCallExpressions(classifier, CHECK_OK);
2504 Traits::RewriteNonPattern(classifier, CHECK_OK); 2520 Traits::RewriteNonPattern(classifier, CHECK_OK);
2521 BindingPatternUnexpectedToken(classifier);
2505 ArrowFormalParametersUnexpectedToken(classifier); 2522 ArrowFormalParametersUnexpectedToken(classifier);
2506 BindingPatternUnexpectedToken(classifier);
2507 Consume(Token::CONDITIONAL); 2523 Consume(Token::CONDITIONAL);
2508 // In parsing the first assignment expression in conditional 2524 // In parsing the first assignment expression in conditional
2509 // expressions we always accept the 'in' keyword; see ECMA-262, 2525 // expressions we always accept the 'in' keyword; see ECMA-262,
2510 // section 11.12, page 58. 2526 // section 11.12, page 58.
2511 ExpressionT left = ParseAssignmentExpression(true, classifier, CHECK_OK); 2527 ExpressionT left = ParseAssignmentExpression(true, classifier, CHECK_OK);
2512 Traits::RewriteNonPattern(classifier, CHECK_OK); 2528 Traits::RewriteNonPattern(classifier, CHECK_OK);
2513 Expect(Token::COLON, CHECK_OK); 2529 Expect(Token::COLON, CHECK_OK);
2514 ExpressionT right = 2530 ExpressionT right =
2515 ParseAssignmentExpression(accept_IN, classifier, CHECK_OK); 2531 ParseAssignmentExpression(accept_IN, classifier, CHECK_OK);
2516 Traits::RewriteNonPattern(classifier, CHECK_OK); 2532 Traits::RewriteNonPattern(classifier, CHECK_OK);
(...skipping 1076 matching lines...) Expand 10 before | Expand all | Expand 10 after
3593 has_seen_constructor_ = true; 3609 has_seen_constructor_ = true;
3594 return; 3610 return;
3595 } 3611 }
3596 } 3612 }
3597 3613
3598 3614
3599 } // namespace internal 3615 } // namespace internal
3600 } // namespace v8 3616 } // namespace v8
3601 3617
3602 #endif // V8_PARSING_PARSER_BASE_H 3618 #endif // V8_PARSING_PARSER_BASE_H
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698