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

Side by Side Diff: src/preparser.h

Issue 160073006: Implement handling of arrow functions in the parser (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Made tests more comprehensive Created 6 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 | Annotate | Revision Log
« no previous file with comments | « src/parser.cc ('k') | src/scanner.h » ('j') | src/scanner.h » ('J')
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 #ifndef V8_PREPARSER_H 5 #ifndef V8_PREPARSER_H
6 #define V8_PREPARSER_H 6 #define V8_PREPARSER_H
7 7
8 #include "src/func-name-inferrer.h" 8 #include "src/func-name-inferrer.h"
9 #include "src/hashmap.h" 9 #include "src/hashmap.h"
10 #include "src/scopes.h" 10 #include "src/scopes.h"
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
54 // }; 54 // };
55 // // ... 55 // // ...
56 // }; 56 // };
57 57
58 template <typename Traits> 58 template <typename Traits>
59 class ParserBase : public Traits { 59 class ParserBase : public Traits {
60 public: 60 public:
61 // Shorten type names defined by Traits. 61 // Shorten type names defined by Traits.
62 typedef typename Traits::Type::Expression ExpressionT; 62 typedef typename Traits::Type::Expression ExpressionT;
63 typedef typename Traits::Type::Identifier IdentifierT; 63 typedef typename Traits::Type::Identifier IdentifierT;
64 typedef typename Traits::Type::FunctionLiteral FunctionLiteralT;
64 65
65 ParserBase(Scanner* scanner, uintptr_t stack_limit, 66 ParserBase(Scanner* scanner, uintptr_t stack_limit,
66 v8::Extension* extension, 67 v8::Extension* extension,
67 ParserRecorder* log, 68 ParserRecorder* log,
68 typename Traits::Type::Zone* zone, 69 typename Traits::Type::Zone* zone,
69 typename Traits::Type::Parser this_object) 70 typename Traits::Type::Parser this_object)
70 : Traits(this_object), 71 : Traits(this_object),
71 parenthesized_function_(false), 72 parenthesized_function_(false),
72 scope_(NULL), 73 scope_(NULL),
73 function_state_(NULL), 74 function_state_(NULL),
74 extension_(extension), 75 extension_(extension),
75 fni_(NULL), 76 fni_(NULL),
76 log_(log), 77 log_(log),
77 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly. 78 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly.
78 scanner_(scanner), 79 scanner_(scanner),
79 stack_limit_(stack_limit), 80 stack_limit_(stack_limit),
80 stack_overflow_(false), 81 stack_overflow_(false),
81 allow_lazy_(false), 82 allow_lazy_(false),
82 allow_natives_syntax_(false), 83 allow_natives_syntax_(false),
83 allow_generators_(false), 84 allow_generators_(false),
84 allow_for_of_(false), 85 allow_for_of_(false),
86 allow_arrow_functions_(false),
85 zone_(zone) { } 87 zone_(zone) { }
86 88
87 // Getters that indicate whether certain syntactical constructs are 89 // Getters that indicate whether certain syntactical constructs are
88 // allowed to be parsed by this instance of the parser. 90 // allowed to be parsed by this instance of the parser.
89 bool allow_lazy() const { return allow_lazy_; } 91 bool allow_lazy() const { return allow_lazy_; }
90 bool allow_natives_syntax() const { return allow_natives_syntax_; } 92 bool allow_natives_syntax() const { return allow_natives_syntax_; }
91 bool allow_generators() const { return allow_generators_; } 93 bool allow_generators() const { return allow_generators_; }
92 bool allow_for_of() const { return allow_for_of_; } 94 bool allow_for_of() const { return allow_for_of_; }
95 bool allow_arrow_functions() const { return allow_arrow_functions_; }
93 bool allow_modules() const { return scanner()->HarmonyModules(); } 96 bool allow_modules() const { return scanner()->HarmonyModules(); }
94 bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); } 97 bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); }
95 bool allow_harmony_numeric_literals() const { 98 bool allow_harmony_numeric_literals() const {
96 return scanner()->HarmonyNumericLiterals(); 99 return scanner()->HarmonyNumericLiterals();
97 } 100 }
98 101
99 // Setters that determine whether certain syntactical constructs are 102 // Setters that determine whether certain syntactical constructs are
100 // allowed to be parsed by this instance of the parser. 103 // allowed to be parsed by this instance of the parser.
101 void set_allow_lazy(bool allow) { allow_lazy_ = allow; } 104 void set_allow_lazy(bool allow) { allow_lazy_ = allow; }
102 void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; } 105 void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; }
103 void set_allow_generators(bool allow) { allow_generators_ = allow; } 106 void set_allow_generators(bool allow) { allow_generators_ = allow; }
104 void set_allow_for_of(bool allow) { allow_for_of_ = allow; } 107 void set_allow_for_of(bool allow) { allow_for_of_ = allow; }
108 void set_allow_arrow_functions(bool allow) { allow_arrow_functions_ = allow; }
105 void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); } 109 void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); }
106 void set_allow_harmony_scoping(bool allow) { 110 void set_allow_harmony_scoping(bool allow) {
107 scanner()->SetHarmonyScoping(allow); 111 scanner()->SetHarmonyScoping(allow);
108 } 112 }
109 void set_allow_harmony_numeric_literals(bool allow) { 113 void set_allow_harmony_numeric_literals(bool allow) {
110 scanner()->SetHarmonyNumericLiterals(allow); 114 scanner()->SetHarmonyNumericLiterals(allow);
111 } 115 }
112 116
113 protected: 117 protected:
114 enum AllowEvalOrArgumentsAsIdentifier { 118 enum AllowEvalOrArgumentsAsIdentifier {
(...skipping 29 matching lines...) Expand all
144 }; 148 };
145 149
146 class FunctionState BASE_EMBEDDED { 150 class FunctionState BASE_EMBEDDED {
147 public: 151 public:
148 FunctionState( 152 FunctionState(
149 FunctionState** function_state_stack, 153 FunctionState** function_state_stack,
150 typename Traits::Type::Scope** scope_stack, 154 typename Traits::Type::Scope** scope_stack,
151 typename Traits::Type::Scope* scope, 155 typename Traits::Type::Scope* scope,
152 typename Traits::Type::Zone* zone = NULL, 156 typename Traits::Type::Zone* zone = NULL,
153 AstValueFactory* ast_value_factory = NULL); 157 AstValueFactory* ast_value_factory = NULL);
158 FunctionState(
159 FunctionState** function_state_stack,
160 typename Traits::Type::Scope** scope_stack,
161 typename Traits::Type::Scope** scope,
162 typename Traits::Type::Zone* zone,
163 AstValueFactory* ast_value_factory);
154 ~FunctionState(); 164 ~FunctionState();
155 165
156 int NextMaterializedLiteralIndex() { 166 int NextMaterializedLiteralIndex() {
157 return next_materialized_literal_index_++; 167 return next_materialized_literal_index_++;
158 } 168 }
159 int materialized_literal_count() { 169 int materialized_literal_count() {
160 return next_materialized_literal_index_ - JSFunction::kLiteralsPrefixSize; 170 return next_materialized_literal_index_ - JSFunction::kLiteralsPrefixSize;
161 } 171 }
162 172
163 int NextHandlerIndex() { return next_handler_index_++; } 173 int NextHandlerIndex() { return next_handler_index_++; }
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
327 void CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) { 337 void CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) {
328 Scanner::Location octal = scanner()->octal_position(); 338 Scanner::Location octal = scanner()->octal_position();
329 if (octal.IsValid() && beg_pos <= octal.beg_pos && 339 if (octal.IsValid() && beg_pos <= octal.beg_pos &&
330 octal.end_pos <= end_pos) { 340 octal.end_pos <= end_pos) {
331 ReportMessageAt(octal, "strict_octal_literal"); 341 ReportMessageAt(octal, "strict_octal_literal");
332 scanner()->clear_octal_position(); 342 scanner()->clear_octal_position();
333 *ok = false; 343 *ok = false;
334 } 344 }
335 } 345 }
336 346
347 // Validates strict mode for function parameter lists. This has to be
348 // done after parsing the function, since the function can declare
349 // itself strict.
350 void CheckStrictFunctionNameAndParameters(
351 IdentifierT function_name,
352 bool function_name_is_strict_reserved,
353 const Scanner::Location& function_name_loc,
354 const Scanner::Location& eval_args_error_loc,
355 const Scanner::Location& dupe_error_loc,
356 const Scanner::Location& reserved_loc,
357 bool* ok) {
358 if (this->IsEvalOrArguments(function_name)) {
359 Traits::ReportMessageAt(function_name_loc, "strict_eval_arguments");
360 *ok = false;
361 return;
362 }
363 if (function_name_is_strict_reserved) {
364 Traits::ReportMessageAt(function_name_loc, "unexpected_strict_reserved");
365 *ok = false;
366 return;
367 }
368 if (eval_args_error_loc.IsValid()) {
369 Traits::ReportMessageAt(eval_args_error_loc, "strict_eval_arguments");
370 *ok = false;
371 return;
372 }
373 if (dupe_error_loc.IsValid()) {
374 Traits::ReportMessageAt(dupe_error_loc, "strict_param_dupe");
375 *ok = false;
376 return;
377 }
378 if (reserved_loc.IsValid()) {
379 Traits::ReportMessageAt(reserved_loc, "unexpected_strict_reserved");
380 *ok = false;
381 return;
382 }
383 }
384
337 // Determine precedence of given token. 385 // Determine precedence of given token.
338 static int Precedence(Token::Value token, bool accept_IN) { 386 static int Precedence(Token::Value token, bool accept_IN) {
339 if (token == Token::IN && !accept_IN) 387 if (token == Token::IN && !accept_IN)
340 return 0; // 0 precedence will terminate binary expression parsing 388 return 0; // 0 precedence will terminate binary expression parsing
341 return Token::Precedence(token); 389 return Token::Precedence(token);
342 } 390 }
343 391
344 typename Traits::Type::Factory* factory() { 392 typename Traits::Type::Factory* factory() {
345 return function_state_->factory(); 393 return function_state_->factory();
346 } 394 }
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
397 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); 445 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok);
398 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); 446 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok);
399 ExpressionT ParseUnaryExpression(bool* ok); 447 ExpressionT ParseUnaryExpression(bool* ok);
400 ExpressionT ParsePostfixExpression(bool* ok); 448 ExpressionT ParsePostfixExpression(bool* ok);
401 ExpressionT ParseLeftHandSideExpression(bool* ok); 449 ExpressionT ParseLeftHandSideExpression(bool* ok);
402 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); 450 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok);
403 ExpressionT ParseMemberExpression(bool* ok); 451 ExpressionT ParseMemberExpression(bool* ok);
404 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, 452 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression,
405 bool* ok); 453 bool* ok);
406 454
455 // There are two ways of parsing arrow functions: if the beginning of an
456 // arrow function can be determined prior to process the parameter list
457 // (e.g. the current scanning position is known to be an arrow function
458 // and not an AssignmentExpression) then the first version is used. In
459 // most cases, we parse the parameter list as an AssignmentExpression
460 // and interpret the AST when the arrow "=>" token is found, using the
461 // second version.
462 // The overloaded ParseArrowFunctionLiteral() functions mainly deal with
463 // parsing/interpreting the parameter list, and then they both call
464 // ParseArrowFunctionLiteralBody() before consuming the arrow token.
465 ExpressionT ParseArrowFunctionLiteral(bool* ok);
466 ExpressionT ParseArrowFunctionLiteral(int start_pos,
467 ExpressionT params_ast,
468 bool* ok);
469 ExpressionT ParseArrowFunctionLiteralBody(
470 FunctionState* function_state,
471 typename Traits::Type::ScopePtr scope,
472 int num_parameters,
473 const Scanner::Location& eval_args_error_loc,
474 const Scanner::Location& dupe_error_loc,
475 const Scanner::Location& reserved_loc,
476 FunctionLiteral::IsParenthesizedFlag parenthesized,
477 int start_pos,
478 bool* ok);
479
407 // Checks if the expression is a valid reference expression (e.g., on the 480 // Checks if the expression is a valid reference expression (e.g., on the
408 // left-hand side of assignments). Although ruled out by ECMA as early errors, 481 // left-hand side of assignments). Although ruled out by ECMA as early errors,
409 // we allow calls for web compatibility and rewrite them to a runtime throw. 482 // we allow calls for web compatibility and rewrite them to a runtime throw.
410 ExpressionT CheckAndRewriteReferenceExpression( 483 ExpressionT CheckAndRewriteReferenceExpression(
411 ExpressionT expression, 484 ExpressionT expression,
412 Scanner::Location location, const char* message, bool* ok); 485 Scanner::Location location, const char* message, bool* ok);
413 486
414 // Used to detect duplicates in object literals. Each of the values 487 // Used to detect duplicates in object literals. Each of the values
415 // kGetterProperty, kSetterProperty and kValueProperty represents 488 // kGetterProperty, kSetterProperty and kValueProperty represents
416 // a type of object literal property. When parsing a property, its 489 // a type of object literal property. When parsing a property, its
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
480 553
481 private: 554 private:
482 Scanner* scanner_; 555 Scanner* scanner_;
483 uintptr_t stack_limit_; 556 uintptr_t stack_limit_;
484 bool stack_overflow_; 557 bool stack_overflow_;
485 558
486 bool allow_lazy_; 559 bool allow_lazy_;
487 bool allow_natives_syntax_; 560 bool allow_natives_syntax_;
488 bool allow_generators_; 561 bool allow_generators_;
489 bool allow_for_of_; 562 bool allow_for_of_;
563 bool allow_arrow_functions_;
490 564
491 typename Traits::Type::Zone* zone_; // Only used by Parser. 565 typename Traits::Type::Zone* zone_; // Only used by Parser.
492 }; 566 };
493 567
494 568
495 class PreParserIdentifier { 569 class PreParserIdentifier {
496 public: 570 public:
497 PreParserIdentifier() : type_(kUnknownIdentifier) {} 571 PreParserIdentifier() : type_(kUnknownIdentifier) {}
498 static PreParserIdentifier Default() { 572 static PreParserIdentifier Default() {
499 return PreParserIdentifier(kUnknownIdentifier); 573 return PreParserIdentifier(kUnknownIdentifier);
500 } 574 }
501 static PreParserIdentifier Eval() { 575 static PreParserIdentifier Eval() {
502 return PreParserIdentifier(kEvalIdentifier); 576 return PreParserIdentifier(kEvalIdentifier);
503 } 577 }
504 static PreParserIdentifier Arguments() { 578 static PreParserIdentifier Arguments() {
505 return PreParserIdentifier(kArgumentsIdentifier); 579 return PreParserIdentifier(kArgumentsIdentifier);
506 } 580 }
507 static PreParserIdentifier FutureReserved() { 581 static PreParserIdentifier FutureReserved() {
508 return PreParserIdentifier(kFutureReservedIdentifier); 582 return PreParserIdentifier(kFutureReservedIdentifier);
509 } 583 }
510 static PreParserIdentifier FutureStrictReserved() { 584 static PreParserIdentifier FutureStrictReserved() {
511 return PreParserIdentifier(kFutureStrictReservedIdentifier); 585 return PreParserIdentifier(kFutureStrictReservedIdentifier);
512 } 586 }
513 static PreParserIdentifier Yield() { 587 static PreParserIdentifier Yield() {
514 return PreParserIdentifier(kYieldIdentifier); 588 return PreParserIdentifier(kYieldIdentifier);
515 } 589 }
516 bool IsEval() { return type_ == kEvalIdentifier; } 590 bool IsEval() const { return type_ == kEvalIdentifier; }
517 bool IsArguments() { return type_ == kArgumentsIdentifier; } 591 bool IsArguments() const { return type_ == kArgumentsIdentifier; }
518 bool IsEvalOrArguments() { return type_ >= kEvalIdentifier; } 592 bool IsEvalOrArguments() { return type_ >= kEvalIdentifier; }
519 bool IsYield() { return type_ == kYieldIdentifier; } 593 bool IsYield() const { return type_ == kYieldIdentifier; }
520 bool IsFutureReserved() { return type_ == kFutureReservedIdentifier; } 594 bool IsFutureReserved() { return type_ == kFutureReservedIdentifier; }
521 bool IsFutureStrictReserved() { 595 bool IsFutureStrictReserved() const {
522 return type_ == kFutureStrictReservedIdentifier; 596 return type_ == kFutureStrictReservedIdentifier;
523 } 597 }
524 bool IsValidStrictVariable() { return type_ == kUnknownIdentifier; } 598 bool IsValidStrictVariable() { return type_ == kUnknownIdentifier; }
525 599
600 // Allow identifier->name()[->length()] to work. The preparser
601 // does not need the actual positions/lengths of the identifiers.
602 const PreParserIdentifier* operator->() const { return this; }
603 const PreParserIdentifier raw_name() const { return *this; }
604
605 int position() const {
606 return 0;
607 }
608
609 int length() const {
610 if (IsEval()) return 4;
611 if (IsArguments()) return 9;
612 if (IsYield()) return 5;
613 return 0;
614 }
615
526 private: 616 private:
527 enum Type { 617 enum Type {
528 kUnknownIdentifier, 618 kUnknownIdentifier,
529 kFutureReservedIdentifier, 619 kFutureReservedIdentifier,
530 kFutureStrictReservedIdentifier, 620 kFutureStrictReservedIdentifier,
531 kYieldIdentifier, 621 kYieldIdentifier,
532 kEvalIdentifier, 622 kEvalIdentifier,
533 kArgumentsIdentifier 623 kArgumentsIdentifier
534 }; 624 };
535 explicit PreParserIdentifier(Type type) : type_(type) {} 625 explicit PreParserIdentifier(Type type) : type_(type) {}
536 Type type_; 626 Type type_;
537 627
538 friend class PreParserExpression; 628 friend class PreParserExpression;
629 friend class PreParserScope;
539 }; 630 };
540 631
541 632
542 // Bits 0 and 1 are used to identify the type of expression: 633 // Bits 0 and 1 are used to identify the type of expression:
543 // If bit 0 is set, it's an identifier. 634 // If bit 0 is set, it's an identifier.
544 // if bit 1 is set, it's a string literal. 635 // if bit 1 is set, it's a string literal.
545 // If neither is set, it's no particular type, and both set isn't 636 // If neither is set, it's no particular type, and both set isn't
546 // use yet. 637 // use yet.
547 class PreParserExpression { 638 class PreParserExpression {
548 public: 639 public:
549 static PreParserExpression Default() { 640 static PreParserExpression Default() {
550 return PreParserExpression(kUnknownExpression); 641 return PreParserExpression(kUnknownExpression);
551 } 642 }
552 643
553 static PreParserExpression FromIdentifier(PreParserIdentifier id) { 644 static PreParserExpression FromIdentifier(PreParserIdentifier id) {
554 return PreParserExpression(kIdentifierFlag | 645 return PreParserExpression(kTypeIdentifier |
555 (id.type_ << kIdentifierShift)); 646 (id.type_ << kIdentifierShift));
556 } 647 }
557 648
649 static PreParserExpression BinaryOperation(PreParserExpression left,
650 PreParserExpression right) {
651 int left_bits = left.BinaryOperationBits();
652 int right_bits = right.BinaryOperationBits();
653
654 int code = left_bits | right_bits;
655 if (left_bits & right_bits & kBinaryOperationHasEval)
656 code |= kBinaryOperationHasDuplicatedIdentifier;
657 else if (left_bits & right_bits & kBinaryOperationHasArguments)
658 code |= kBinaryOperationHasDuplicatedIdentifier;
659 // TODO(aperezdc): Handle other duplicate identifier
660
661 return PreParserExpression(kTypeBinaryOperation | code);
662 }
663
558 static PreParserExpression StringLiteral() { 664 static PreParserExpression StringLiteral() {
559 return PreParserExpression(kUnknownStringLiteral); 665 return PreParserExpression(kUnknownStringLiteral);
560 } 666 }
561 667
562 static PreParserExpression UseStrictStringLiteral() { 668 static PreParserExpression UseStrictStringLiteral() {
563 return PreParserExpression(kUseStrictString); 669 return PreParserExpression(kUseStrictString);
564 } 670 }
565 671
566 static PreParserExpression This() { 672 static PreParserExpression This() {
567 return PreParserExpression(kThisExpression); 673 return PreParserExpression(kThisExpression);
568 } 674 }
569 675
570 static PreParserExpression ThisProperty() { 676 static PreParserExpression ThisProperty() {
571 return PreParserExpression(kThisPropertyExpression); 677 return PreParserExpression(kThisPropertyExpression);
572 } 678 }
573 679
574 static PreParserExpression Property() { 680 static PreParserExpression Property() {
575 return PreParserExpression(kPropertyExpression); 681 return PreParserExpression(kPropertyExpression);
576 } 682 }
577 683
578 static PreParserExpression Call() { 684 static PreParserExpression Call() {
579 return PreParserExpression(kCallExpression); 685 return PreParserExpression(kCallExpression);
580 } 686 }
581 687
582 bool IsIdentifier() { return (code_ & kIdentifierFlag) != 0; } 688 bool IsIdentifier() const {
689 return (code_ & kTypeMask) == kTypeIdentifier;
690 }
583 691
584 PreParserIdentifier AsIdentifier() { 692 PreParserIdentifier AsIdentifier() const {
585 ASSERT(IsIdentifier()); 693 ASSERT(IsIdentifier());
586 return PreParserIdentifier( 694 return PreParserIdentifier(
587 static_cast<PreParserIdentifier::Type>(code_ >> kIdentifierShift)); 695 static_cast<PreParserIdentifier::Type>(code_ >> kIdentifierShift));
588 } 696 }
589 697
590 bool IsStringLiteral() { return (code_ & kStringLiteralFlag) != 0; } 698 bool IsStringLiteral() const {
699 return (code_ & kTypeMask) == kTypeStringLiteral;
700 }
591 701
592 bool IsUseStrictLiteral() { 702 bool IsUseStrictLiteral() {
593 return (code_ & kStringLiteralMask) == kUseStrictString; 703 return (code_ & kUseStrictString) == kUseStrictString;
594 } 704 }
595 705
596 bool IsThis() { return code_ == kThisExpression; } 706 bool IsThis() { return code_ == kThisExpression; }
597 707
598 bool IsThisProperty() { return code_ == kThisPropertyExpression; } 708 bool IsThisProperty() { return code_ == kThisPropertyExpression; }
599 709
600 bool IsProperty() { 710 bool IsProperty() {
601 return code_ == kPropertyExpression || code_ == kThisPropertyExpression; 711 return code_ == kPropertyExpression || code_ == kThisPropertyExpression;
602 } 712 }
603 713
604 bool IsCall() { return code_ == kCallExpression; } 714 bool IsCall() { return code_ == kCallExpression; }
605 715
606 bool IsValidReferenceExpression() { 716 bool IsValidReferenceExpression() {
607 return IsIdentifier() || IsProperty(); 717 return IsIdentifier() || IsProperty();
608 } 718 }
609 719
610 // At the moment PreParser doesn't track these expression types. 720 // At the moment PreParser doesn't track these expression types.
611 bool IsFunctionLiteral() const { return false; } 721 bool IsFunctionLiteral() const { return false; }
612 bool IsCallNew() const { return false; } 722 bool IsCallNew() const { return false; }
613 723
614 PreParserExpression AsFunctionLiteral() { return *this; } 724 PreParserExpression AsFunctionLiteral() { return *this; }
615 725
726 bool IsBinaryOperation() const {
727 return (code_ & kTypeMask) == kTypeBinaryOperation;
728 }
729
616 // Dummy implementation for making expression->somefunc() work in both Parser 730 // Dummy implementation for making expression->somefunc() work in both Parser
617 // and PreParser. 731 // and PreParser.
618 PreParserExpression* operator->() { return this; } 732 PreParserExpression* operator->() { return this; }
619 733
620 // More dummy implementations of things PreParser doesn't need to track: 734 // More dummy implementations of things PreParser doesn't need to track:
621 void set_index(int index) {} // For YieldExpressions 735 void set_index(int index) {} // For YieldExpressions
622 void set_parenthesized() {} 736 void set_parenthesized() {}
623 737
738 int position() const { return RelocInfo::kNoPosition; }
739 void set_function_token_position(int position) {}
740 void set_ast_properties(int* ast_properties) {}
741 void set_dont_optimize_reason(BailoutReason dont_optimize_reason) {}
742
743 bool HasEval() const {
744 if (IsBinaryOperation()) return (code_ & kBinaryOperationHasEval) != 0;
745 if (IsIdentifier()) return AsIdentifier().IsEval();
746 return false;
747 }
748
749 bool HasArguments() const {
750 if (IsBinaryOperation()) return (code_ & kBinaryOperationHasArguments) != 0;
751 if (IsIdentifier()) return AsIdentifier().IsArguments();
752 return false;
753 }
754
755 bool HasFutureStrictReserved() const {
756 if (IsBinaryOperation())
757 return (code_ & kBinaryOperationHasFutureStrictReserved) != 0;
758 if (IsIdentifier())
759 return (AsIdentifier().IsFutureStrictReserved() ||
760 AsIdentifier().IsYield());
761 return false;
762 }
763 bool HasDuplicatedIdentifier() const {
764 return IsBinaryOperation() &&
765 (code_ & kBinaryOperationHasDuplicatedIdentifier) != 0;
766 }
767
768 bool operator==(const PreParserExpression& other) const {
769 return code_ == other.code_;
770 }
771 bool operator!=(const PreParserExpression& other) const {
772 return code_ != other.code_;
773 }
774
624 private: 775 private:
625 // Least significant 2 bits are used as flags. Bits 0 and 1 represent 776 // Least significant 2 bits are used as expression type. If the expression
626 // identifiers or strings literals, and are mutually exclusive, but can both 777 // is an identifier or a string literal, the other bits describe the type
627 // be absent. If the expression is an identifier or a string literal, the 778 // (see PreParserIdentifier::Type and string literal constants below). For
628 // other bits describe the type (see PreParserIdentifier::Type and string 779 // binary operations, the other bits are flags which further describe the
629 // literal constants below). 780 // contents of the expression.
630 enum { 781 enum {
631 kUnknownExpression = 0, 782 kUnknownExpression = 0,
783
784 kTypeMask = 1 | 2,
785
632 // Identifiers 786 // Identifiers
633 kIdentifierFlag = 1, // Used to detect labels. 787 kTypeIdentifier = 1, // Used to detect labels.
634 kIdentifierShift = 3, 788 kIdentifierShift = 3,
635 789
636 kStringLiteralFlag = 2, // Used to detect directive prologue. 790 kTypeStringLiteral = 2, // Used to detect directive prologue.
637 kUnknownStringLiteral = kStringLiteralFlag, 791 kUnknownStringLiteral = kTypeStringLiteral,
638 kUseStrictString = kStringLiteralFlag | 8, 792 kUseStrictString = kTypeStringLiteral | 8,
639 kStringLiteralMask = kUseStrictString, 793 kStringLiteralMask = kUseStrictString,
640 794
795 // Binary operations. Those are needed to detect certain keywords and
796 // duplicated identifier in parameter lists for arrow functions, because
797 // they are initially parsed as comma-separated expressions.
798 kTypeBinaryOperation = 3,
799 kBinaryOperationHasEval = 1 << 2,
800 kBinaryOperationHasArguments = 2 << 2,
801 kBinaryOperationHasFutureStrictReserved = 4 << 2,
802 kBinaryOperationHasDuplicatedIdentifier = 8 << 2,
803
641 // Below here applies if neither identifier nor string literal. Reserve the 804 // Below here applies if neither identifier nor string literal. Reserve the
642 // 2 least significant bits for flags. 805 // 2 least significant bits for flags.
643 kThisExpression = 1 << 2, 806 kThisExpression = 1 << 2,
644 kThisPropertyExpression = 2 << 2, 807 kThisPropertyExpression = 2 << 2,
645 kPropertyExpression = 3 << 2, 808 kPropertyExpression = 3 << 2,
646 kCallExpression = 4 << 2 809 kCallExpression = 4 << 2
647 }; 810 };
648 811
649 explicit PreParserExpression(int expression_code) : code_(expression_code) {} 812 explicit PreParserExpression(int expression_code) : code_(expression_code) {}
650 813
814 V8_INLINE int BinaryOperationBits() const {
815 if (IsBinaryOperation()) return code_;
816 if (IsIdentifier()) {
817 const PreParserIdentifier ident = AsIdentifier();
818 if (ident.IsEval()) return kBinaryOperationHasEval;
819 if (ident.IsArguments()) return kBinaryOperationHasArguments;
820 if (ident.IsYield() || ident.IsFutureStrictReserved())
821 return kBinaryOperationHasFutureStrictReserved;
822 }
823 return 0;
824 }
825
651 int code_; 826 int code_;
652 }; 827 };
653 828
654 829
655 // PreParserExpressionList doesn't actually store the expressions because 830 // PreParserExpressionList doesn't actually store the expressions because
656 // PreParser doesn't need to. 831 // PreParser doesn't need to.
657 class PreParserExpressionList { 832 class PreParserExpressionList {
658 public: 833 public:
659 // These functions make list->Add(some_expression) work (and do nothing). 834 // These functions make list->Add(some_expression) work (and do nothing).
660 PreParserExpressionList() : length_(0) {} 835 PreParserExpressionList() : length_(0) {}
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
722 public: 897 public:
723 // These functions make list->Add(some_expression) work as no-ops. 898 // These functions make list->Add(some_expression) work as no-ops.
724 PreParserStatementList() {} 899 PreParserStatementList() {}
725 PreParserStatementList* operator->() { return this; } 900 PreParserStatementList* operator->() { return this; }
726 void Add(PreParserStatement, void*) {} 901 void Add(PreParserStatement, void*) {}
727 }; 902 };
728 903
729 904
730 class PreParserScope { 905 class PreParserScope {
731 public: 906 public:
732 explicit PreParserScope(PreParserScope* outer_scope, ScopeType scope_type) 907 explicit PreParserScope(PreParserScope* outer_scope,
733 : scope_type_(scope_type) { 908 ScopeType scope_type,
909 void* = NULL)
910 : scope_type_(scope_type), declared_parameters_(0) {
734 strict_mode_ = outer_scope ? outer_scope->strict_mode() : SLOPPY; 911 strict_mode_ = outer_scope ? outer_scope->strict_mode() : SLOPPY;
735 } 912 }
736 913
737 ScopeType type() { return scope_type_; } 914 ScopeType type() { return scope_type_; }
738 StrictMode strict_mode() const { return strict_mode_; } 915 StrictMode strict_mode() const { return strict_mode_; }
739 void SetStrictMode(StrictMode strict_mode) { strict_mode_ = strict_mode; } 916 void SetStrictMode(StrictMode strict_mode) { strict_mode_ = strict_mode; }
740 917
918 // TODO(aperezdc): Would allowing lazy compilation in preparser make sense?
919 bool AllowsLazyCompilation() const { return false; }
920
921 void set_start_position(int position) {}
922 void set_end_position(int position) {}
923
924 bool IsDeclared(const PreParserIdentifier& identifier) const {
925 return (declared_parameters_ & (1 << identifier.type_)) != 0;
926 }
927
928 void DeclareParameter(const PreParserIdentifier& identifier, VariableMode) {
929 declared_parameters_ |= (1 << identifier.type_);
930 }
931
932 // Allow scope->Foo() to work.
933 PreParserScope* operator->() { return this; }
934
741 private: 935 private:
742 ScopeType scope_type_; 936 ScopeType scope_type_;
743 StrictMode strict_mode_; 937 StrictMode strict_mode_;
938 int declared_parameters_;
744 }; 939 };
745 940
746 941
747 class PreParserFactory { 942 class PreParserFactory {
748 public: 943 public:
749 explicit PreParserFactory(void* extra_param1, void* extra_param2) {} 944 explicit PreParserFactory(void* extra_param1, void* extra_param2) {}
750 PreParserExpression NewStringLiteral(PreParserIdentifier identifier, 945 PreParserExpression NewStringLiteral(PreParserIdentifier identifier,
751 int pos) { 946 int pos) {
752 return PreParserExpression::Default(); 947 return PreParserExpression::Default();
753 } 948 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
794 return PreParserExpression::Property(); 989 return PreParserExpression::Property();
795 } 990 }
796 PreParserExpression NewUnaryOperation(Token::Value op, 991 PreParserExpression NewUnaryOperation(Token::Value op,
797 PreParserExpression expression, 992 PreParserExpression expression,
798 int pos) { 993 int pos) {
799 return PreParserExpression::Default(); 994 return PreParserExpression::Default();
800 } 995 }
801 PreParserExpression NewBinaryOperation(Token::Value op, 996 PreParserExpression NewBinaryOperation(Token::Value op,
802 PreParserExpression left, 997 PreParserExpression left,
803 PreParserExpression right, int pos) { 998 PreParserExpression right, int pos) {
804 return PreParserExpression::Default(); 999 return PreParserExpression::BinaryOperation(left, right);
805 } 1000 }
806 PreParserExpression NewCompareOperation(Token::Value op, 1001 PreParserExpression NewCompareOperation(Token::Value op,
807 PreParserExpression left, 1002 PreParserExpression left,
808 PreParserExpression right, int pos) { 1003 PreParserExpression right, int pos) {
809 return PreParserExpression::Default(); 1004 return PreParserExpression::Default();
810 } 1005 }
811 PreParserExpression NewAssignment(Token::Value op, 1006 PreParserExpression NewAssignment(Token::Value op,
812 PreParserExpression left, 1007 PreParserExpression left,
813 PreParserExpression right, 1008 PreParserExpression right,
814 int pos) { 1009 int pos) {
(...skipping 20 matching lines...) Expand all
835 PreParserExpression NewCall(PreParserExpression expression, 1030 PreParserExpression NewCall(PreParserExpression expression,
836 PreParserExpressionList arguments, 1031 PreParserExpressionList arguments,
837 int pos) { 1032 int pos) {
838 return PreParserExpression::Call(); 1033 return PreParserExpression::Call();
839 } 1034 }
840 PreParserExpression NewCallNew(PreParserExpression expression, 1035 PreParserExpression NewCallNew(PreParserExpression expression,
841 PreParserExpressionList arguments, 1036 PreParserExpressionList arguments,
842 int pos) { 1037 int pos) {
843 return PreParserExpression::Default(); 1038 return PreParserExpression::Default();
844 } 1039 }
1040 PreParserStatement NewReturnStatement(PreParserExpression expression,
1041 int pos) {
1042 return PreParserStatement::Default();
1043 }
1044 PreParserExpression
1045 NewFunctionLiteral(PreParserIdentifier name,
1046 AstValueFactory* ast_value_factory,
1047 PreParserScope& scope,
1048 PreParserStatementList body,
1049 int materialized_literal_count,
1050 int expected_property_count,
1051 int handler_count,
1052 int parameter_count,
1053 FunctionLiteral::ParameterFlag has_duplicate_parameters,
1054 FunctionLiteral::FunctionType function_type,
1055 FunctionLiteral::IsFunctionFlag is_function,
1056 FunctionLiteral::IsParenthesizedFlag is_parenthesized,
1057 FunctionLiteral::IsGeneratorFlag is_generator,
1058 int position) {
1059 return PreParserExpression::Default();
1060 }
1061
1062 // Return the object itself as AstVisitor and implement the needed
1063 // dummy method right in this class.
1064 PreParserFactory* visitor() { return this; }
1065 BailoutReason dont_optimize_reason() { return kNoReason; }
1066 int* ast_properties() { static int dummy = 42; return &dummy; }
845 }; 1067 };
846 1068
847 1069
848 class PreParser; 1070 class PreParser;
849 1071
850 class PreParserTraits { 1072 class PreParserTraits {
851 public: 1073 public:
852 struct Type { 1074 struct Type {
853 // TODO(marja): To be removed. The Traits object should contain all the data 1075 // TODO(marja): To be removed. The Traits object should contain all the data
854 // it needs. 1076 // it needs.
855 typedef PreParser* Parser; 1077 typedef PreParser* Parser;
856 1078
857 // Used by FunctionState and BlockState. 1079 // Used by FunctionState and BlockState.
858 typedef PreParserScope Scope; 1080 typedef PreParserScope Scope;
1081 typedef PreParserScope ScopePtr;
1082
859 // PreParser doesn't need to store generator variables. 1083 // PreParser doesn't need to store generator variables.
860 typedef void GeneratorVariable; 1084 typedef void GeneratorVariable;
861 // No interaction with Zones. 1085 // No interaction with Zones.
862 typedef void Zone; 1086 typedef void Zone;
863 1087
1088 typedef int AstProperties;
1089 typedef Vector<PreParserIdentifier> ParameterIdentifierVector;
1090
864 // Return types for traversing functions. 1091 // Return types for traversing functions.
865 typedef PreParserIdentifier Identifier; 1092 typedef PreParserIdentifier Identifier;
866 typedef PreParserExpression Expression; 1093 typedef PreParserExpression Expression;
867 typedef PreParserExpression YieldExpression; 1094 typedef PreParserExpression YieldExpression;
868 typedef PreParserExpression FunctionLiteral; 1095 typedef PreParserExpression FunctionLiteral;
869 typedef PreParserExpression ObjectLiteralProperty; 1096 typedef PreParserExpression ObjectLiteralProperty;
870 typedef PreParserExpression Literal; 1097 typedef PreParserExpression Literal;
871 typedef PreParserExpressionList ExpressionList; 1098 typedef PreParserExpressionList ExpressionList;
872 typedef PreParserExpressionList PropertyList; 1099 typedef PreParserExpressionList PropertyList;
873 typedef PreParserStatementList StatementList; 1100 typedef PreParserStatementList StatementList;
(...skipping 22 matching lines...) Expand all
896 } 1123 }
897 1124
898 static bool IsIdentifier(PreParserExpression expression) { 1125 static bool IsIdentifier(PreParserExpression expression) {
899 return expression.IsIdentifier(); 1126 return expression.IsIdentifier();
900 } 1127 }
901 1128
902 static PreParserIdentifier AsIdentifier(PreParserExpression expression) { 1129 static PreParserIdentifier AsIdentifier(PreParserExpression expression) {
903 return expression.AsIdentifier(); 1130 return expression.AsIdentifier();
904 } 1131 }
905 1132
1133 static bool IsFutureStrictReserved(PreParserIdentifier identifier) {
1134 return identifier.IsYield() || identifier.IsFutureStrictReserved();
1135 }
1136
906 static bool IsBoilerplateProperty(PreParserExpression property) { 1137 static bool IsBoilerplateProperty(PreParserExpression property) {
907 // PreParser doesn't count boilerplate properties. 1138 // PreParser doesn't count boilerplate properties.
908 return false; 1139 return false;
909 } 1140 }
910 1141
911 static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) { 1142 static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) {
912 return false; 1143 return false;
913 } 1144 }
914 1145
915 // Functions for encapsulating the differences between parsing and preparsing; 1146 // Functions for encapsulating the differences between parsing and preparsing;
916 // operations interleaved with the recursive descent. 1147 // operations interleaved with the recursive descent.
917 static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) { 1148 static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) {
918 // PreParser should not use FuncNameInferrer. 1149 // PreParser should not use FuncNameInferrer.
919 UNREACHABLE(); 1150 UNREACHABLE();
920 } 1151 }
921 static void PushPropertyName(FuncNameInferrer* fni, 1152 static void PushPropertyName(FuncNameInferrer* fni,
922 PreParserExpression expression) { 1153 PreParserExpression expression) {
923 // PreParser should not use FuncNameInferrer. 1154 // PreParser should not use FuncNameInferrer.
924 UNREACHABLE(); 1155 UNREACHABLE();
925 } 1156 }
1157 static void InferFunctionName(FuncNameInferrer* fni,
1158 PreParserExpression expression) {
1159 // PreParser should not use FuncNameInferrer.
1160 UNREACHABLE();
1161 }
926 1162
927 static void CheckFunctionLiteralInsideTopLevelObjectLiteral( 1163 static void CheckFunctionLiteralInsideTopLevelObjectLiteral(
928 PreParserScope* scope, PreParserExpression value, bool* has_function) {} 1164 PreParserScope* scope, PreParserExpression value, bool* has_function) {}
929 1165
930 static void CheckAssigningFunctionLiteralToProperty( 1166 static void CheckAssigningFunctionLiteralToProperty(
931 PreParserExpression left, PreParserExpression right) {} 1167 PreParserExpression left, PreParserExpression right) {}
932 1168
933 // PreParser doesn't need to keep track of eval calls. 1169 // PreParser doesn't need to keep track of eval calls.
934 static void CheckPossibleEvalCall(PreParserExpression expression, 1170 static void CheckPossibleEvalCall(PreParserExpression expression,
935 PreParserScope* scope) {} 1171 PreParserScope* scope) {}
936 1172
937 static PreParserExpression MarkExpressionAsLValue( 1173 static PreParserExpression MarkExpressionAsLValue(
938 PreParserExpression expression) { 1174 PreParserExpression expression) {
939 // TODO(marja): To be able to produce the same errors, the preparser needs 1175 // TODO(marja): To be able to produce the same errors, the preparser needs
940 // to start tracking which expressions are variables and which are lvalues. 1176 // to start tracking which expressions are variables and which are lvalues.
941 return expression; 1177 return expression;
942 } 1178 }
943 1179
1180 static AstValueFactory* ast_value_factory() { return NULL; }
1181
944 bool ShortcutNumericLiteralBinaryExpression(PreParserExpression* x, 1182 bool ShortcutNumericLiteralBinaryExpression(PreParserExpression* x,
945 PreParserExpression y, 1183 PreParserExpression y,
946 Token::Value op, 1184 Token::Value op,
947 int pos, 1185 int pos,
948 PreParserFactory* factory) { 1186 PreParserFactory* factory) {
949 return false; 1187 return false;
950 } 1188 }
951 1189
952 PreParserExpression BuildUnaryExpression(PreParserExpression expression, 1190 PreParserExpression BuildUnaryExpression(PreParserExpression expression,
953 Token::Value op, int pos, 1191 Token::Value op, int pos,
954 PreParserFactory* factory) { 1192 PreParserFactory* factory) {
955 return PreParserExpression::Default(); 1193 return PreParserExpression::Default();
956 } 1194 }
957 1195
958 PreParserExpression NewThrowReferenceError(const char* type, int pos) { 1196 PreParserExpression NewThrowReferenceError(const char* type, int pos) {
959 return PreParserExpression::Default(); 1197 return PreParserExpression::Default();
960 } 1198 }
961 PreParserExpression NewThrowSyntaxError( 1199 PreParserExpression NewThrowSyntaxError(
962 const char* type, Handle<Object> arg, int pos) { 1200 const char* type, Handle<Object> arg, int pos) {
963 return PreParserExpression::Default(); 1201 return PreParserExpression::Default();
964 } 1202 }
965 PreParserExpression NewThrowTypeError( 1203 PreParserExpression NewThrowTypeError(
966 const char* type, Handle<Object> arg, int pos) { 1204 const char* type, Handle<Object> arg, int pos) {
967 return PreParserExpression::Default(); 1205 return PreParserExpression::Default();
968 } 1206 }
1207 PreParserScope NewScope(PreParserScope* outer_scope,
1208 ScopeType scope_type) {
1209 return PreParserScope(outer_scope, scope_type);
1210 }
969 1211
970 // Reporting errors. 1212 // Reporting errors.
971 void ReportMessageAt(Scanner::Location location, 1213 void ReportMessageAt(Scanner::Location location,
972 const char* message, 1214 const char* message,
973 const char* arg = NULL, 1215 const char* arg = NULL,
974 bool is_reference_error = false); 1216 bool is_reference_error = false);
975 void ReportMessageAt(int start_pos, 1217 void ReportMessageAt(int start_pos,
976 int end_pos, 1218 int end_pos,
977 const char* message, 1219 const char* message,
978 const char* arg = NULL, 1220 const char* arg = NULL,
979 bool is_reference_error = false); 1221 bool is_reference_error = false);
980 1222
981 // "null" return type creators. 1223 // "null" return type creators.
982 static PreParserIdentifier EmptyIdentifier() { 1224 static PreParserIdentifier EmptyIdentifier() {
983 return PreParserIdentifier::Default(); 1225 return PreParserIdentifier::Default();
984 } 1226 }
1227 static PreParserIdentifier EmptyIdentifierString() {
1228 return PreParserIdentifier::Default();
1229 }
985 static PreParserExpression EmptyExpression() { 1230 static PreParserExpression EmptyExpression() {
986 return PreParserExpression::Default(); 1231 return PreParserExpression::Default();
987 } 1232 }
988 static PreParserExpression EmptyLiteral() { 1233 static PreParserExpression EmptyLiteral() {
989 return PreParserExpression::Default(); 1234 return PreParserExpression::Default();
990 } 1235 }
991 static PreParserExpressionList NullExpressionList() { 1236 static PreParserExpressionList NullExpressionList() {
992 return PreParserExpressionList(); 1237 return PreParserExpressionList();
993 } 1238 }
994 1239
995 // Odd-ball literal creators. 1240 // Odd-ball literal creators.
996 static PreParserExpression GetLiteralTheHole(int position, 1241 static PreParserExpression GetLiteralTheHole(int position,
997 PreParserFactory* factory) { 1242 PreParserFactory* factory) {
998 return PreParserExpression::Default(); 1243 return PreParserExpression::Default();
999 } 1244 }
1000 1245
1001 // Producing data during the recursive descent. 1246 // Producing data during the recursive descent.
1002 PreParserIdentifier GetSymbol(Scanner* scanner); 1247 PreParserIdentifier GetSymbol(Scanner* scanner);
1003 1248
1004 static PreParserIdentifier GetNextSymbol(Scanner* scanner) { 1249 static PreParserIdentifier GetNextSymbol(Scanner* scanner) {
1005 return PreParserIdentifier::Default(); 1250 return PreParserIdentifier::Default();
1006 } 1251 }
1007 1252
1008 static PreParserExpression ThisExpression(PreParserScope* scope, 1253 static PreParserExpression ThisExpression(PreParserScope* scope,
1009 PreParserFactory* factory) { 1254 PreParserFactory* factory,
1255 int pos) {
1010 return PreParserExpression::This(); 1256 return PreParserExpression::This();
1011 } 1257 }
1012 1258
1013 static PreParserExpression ExpressionFromLiteral( 1259 static PreParserExpression ExpressionFromLiteral(
1014 Token::Value token, int pos, Scanner* scanner, 1260 Token::Value token, int pos, Scanner* scanner,
1015 PreParserFactory* factory) { 1261 PreParserFactory* factory) {
1016 return PreParserExpression::Default(); 1262 return PreParserExpression::Default();
1017 } 1263 }
1018 1264
1019 static PreParserExpression ExpressionFromIdentifier( 1265 static PreParserExpression ExpressionFromIdentifier(
(...skipping 11 matching lines...) Expand all
1031 } 1277 }
1032 1278
1033 static PreParserStatementList NewStatementList(int size, void* zone) { 1279 static PreParserStatementList NewStatementList(int size, void* zone) {
1034 return PreParserStatementList(); 1280 return PreParserStatementList();
1035 } 1281 }
1036 1282
1037 static PreParserExpressionList NewPropertyList(int size, void* zone) { 1283 static PreParserExpressionList NewPropertyList(int size, void* zone) {
1038 return PreParserExpressionList(); 1284 return PreParserExpressionList();
1039 } 1285 }
1040 1286
1287 V8_INLINE void SkipLazyFunctionBody(
1288 PreParserIdentifier function_name,
1289 int* materialized_literal_count,
1290 int* expected_property_count,
1291 bool* ok) {
1292 UNREACHABLE();
1293 }
1294
1295 V8_INLINE PreParserStatementList ParseEagerFunctionBody(
1296 PreParserIdentifier function_name,
1297 int pos,
1298 Variable* fvar,
1299 Token::Value fvar_init_op,
1300 bool is_generator,
1301 bool* ok);
1302
1303 // Utility functions
1304 V8_INLINE Vector<PreParserIdentifier> ParameterListFromExpression(
1305 PreParserExpression expression, bool* ok);
1306
1307 void CheckConflictingVarDeclarations(
1308 PreParserScope scope,
1309 bool* ok) {}
1310
1041 // Temporary glue; these functions will move to ParserBase. 1311 // Temporary glue; these functions will move to ParserBase.
1042 PreParserExpression ParseV8Intrinsic(bool* ok); 1312 PreParserExpression ParseV8Intrinsic(bool* ok);
1043 PreParserExpression ParseFunctionLiteral( 1313 PreParserExpression ParseFunctionLiteral(
1044 PreParserIdentifier name, 1314 PreParserIdentifier name,
1045 Scanner::Location function_name_location, 1315 Scanner::Location function_name_location,
1046 bool name_is_strict_reserved, 1316 bool name_is_strict_reserved,
1047 bool is_generator, 1317 bool is_generator,
1048 int function_token_position, 1318 int function_token_position,
1049 FunctionLiteral::FunctionType type, 1319 FunctionLiteral::FunctionType type,
1050 FunctionLiteral::ArityRestriction arity_restriction, 1320 FunctionLiteral::ArityRestriction arity_restriction,
(...skipping 30 matching lines...) Expand all
1081 PreParser(Scanner* scanner, ParserRecorder* log, uintptr_t stack_limit) 1351 PreParser(Scanner* scanner, ParserRecorder* log, uintptr_t stack_limit)
1082 : ParserBase<PreParserTraits>(scanner, stack_limit, NULL, log, NULL, 1352 : ParserBase<PreParserTraits>(scanner, stack_limit, NULL, log, NULL,
1083 this) {} 1353 this) {}
1084 1354
1085 // Pre-parse the program from the character stream; returns true on 1355 // Pre-parse the program from the character stream; returns true on
1086 // success (even if parsing failed, the pre-parse data successfully 1356 // success (even if parsing failed, the pre-parse data successfully
1087 // captured the syntax error), and false if a stack-overflow happened 1357 // captured the syntax error), and false if a stack-overflow happened
1088 // during parsing. 1358 // during parsing.
1089 PreParseResult PreParseProgram() { 1359 PreParseResult PreParseProgram() {
1090 PreParserScope scope(scope_, GLOBAL_SCOPE); 1360 PreParserScope scope(scope_, GLOBAL_SCOPE);
1091 FunctionState top_scope(&function_state_, &scope_, &scope, NULL); 1361 FunctionState top_scope(&function_state_, &scope_, &scope, NULL, NULL);
1092 bool ok = true; 1362 bool ok = true;
1093 int start_position = scanner()->peek_location().beg_pos; 1363 int start_position = scanner()->peek_location().beg_pos;
1094 ParseSourceElements(Token::EOS, &ok); 1364 ParseSourceElements(Token::EOS, &ok);
1095 if (stack_overflow()) return kPreParseStackOverflow; 1365 if (stack_overflow()) return kPreParseStackOverflow;
1096 if (!ok) { 1366 if (!ok) {
1097 ReportUnexpectedToken(scanner()->current_token()); 1367 ReportUnexpectedToken(scanner()->current_token());
1098 } else if (scope_->strict_mode() == STRICT) { 1368 } else if (scope_->strict_mode() == STRICT) {
1099 CheckOctalLiteral(start_position, scanner()->location().end_pos, &ok); 1369 CheckOctalLiteral(start_position, scanner()->location().end_pos, &ok);
1100 } 1370 }
1101 return kPreParseSuccess; 1371 return kPreParseSuccess;
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1163 Statement ParseDoWhileStatement(bool* ok); 1433 Statement ParseDoWhileStatement(bool* ok);
1164 Statement ParseWhileStatement(bool* ok); 1434 Statement ParseWhileStatement(bool* ok);
1165 Statement ParseForStatement(bool* ok); 1435 Statement ParseForStatement(bool* ok);
1166 Statement ParseThrowStatement(bool* ok); 1436 Statement ParseThrowStatement(bool* ok);
1167 Statement ParseTryStatement(bool* ok); 1437 Statement ParseTryStatement(bool* ok);
1168 Statement ParseDebuggerStatement(bool* ok); 1438 Statement ParseDebuggerStatement(bool* ok);
1169 Expression ParseConditionalExpression(bool accept_IN, bool* ok); 1439 Expression ParseConditionalExpression(bool accept_IN, bool* ok);
1170 Expression ParseObjectLiteral(bool* ok); 1440 Expression ParseObjectLiteral(bool* ok);
1171 Expression ParseV8Intrinsic(bool* ok); 1441 Expression ParseV8Intrinsic(bool* ok);
1172 1442
1443 V8_INLINE void SkipLazyFunctionBody(
1444 PreParserIdentifier function_name,
1445 int* materialized_literal_count,
1446 int* expected_property_count,
1447 bool* ok);
1448 V8_INLINE PreParserStatementList ParseEagerFunctionBody(
1449 PreParserIdentifier function_name,
1450 int pos,
1451 Variable* fvar,
1452 Token::Value fvar_init_op,
1453 bool is_generator,
1454 bool* ok);
1455
1173 Expression ParseFunctionLiteral( 1456 Expression ParseFunctionLiteral(
1174 Identifier name, 1457 Identifier name,
1175 Scanner::Location function_name_location, 1458 Scanner::Location function_name_location,
1176 bool name_is_strict_reserved, 1459 bool name_is_strict_reserved,
1177 bool is_generator, 1460 bool is_generator,
1178 int function_token_pos, 1461 int function_token_pos,
1179 FunctionLiteral::FunctionType function_type, 1462 FunctionLiteral::FunctionType function_type,
1180 FunctionLiteral::ArityRestriction arity_restriction, 1463 FunctionLiteral::ArityRestriction arity_restriction,
1181 bool* ok); 1464 bool* ok);
1182 void ParseLazyFunctionLiteralBody(bool* ok); 1465 void ParseLazyFunctionLiteralBody(bool* ok);
1183 1466
1184 bool CheckInOrOf(bool accept_OF); 1467 bool CheckInOrOf(bool accept_OF);
1185 }; 1468 };
1186 1469
1470
1471 PreParserStatementList PreParser::ParseEagerFunctionBody(
1472 PreParserIdentifier function_name,
1473 int pos,
1474 Variable* fvar,
1475 Token::Value fvar_init_op,
1476 bool is_generator,
1477 bool* ok) {
1478 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
1479
1480 ParseSourceElements(Token::RBRACE, ok);
1481 if (!*ok) return PreParserStatementList();
1482
1483 Expect(Token::RBRACE, ok);
1484 return PreParserStatementList();
1485 }
1486
1487
1488 PreParserStatementList PreParserTraits::ParseEagerFunctionBody(
1489 PreParserIdentifier function_name,
1490 int pos,
1491 Variable* fvar,
1492 Token::Value fvar_init_op,
1493 bool is_generator,
1494 bool* ok) {
1495 return pre_parser_->ParseEagerFunctionBody(function_name,
1496 pos, fvar, fvar_init_op, is_generator, ok);
1497 }
1498
1499
1500 Vector<PreParserIdentifier> PreParserTraits::ParameterListFromExpression(
1501 PreParserExpression expression, bool* ok) {
1502 Collector<PreParserIdentifier> collector;
1503
1504 if (expression.HasEval())
1505 collector.Add(PreParserIdentifier::Eval());
1506 if (expression.HasArguments())
1507 collector.Add(PreParserIdentifier::Arguments());
1508 if (expression.HasFutureStrictReserved())
1509 collector.Add(PreParserIdentifier::FutureStrictReserved());
1510
1511 if (expression.HasDuplicatedIdentifier() ||
1512 pre_parser_->scanner()->parameter_list()->HasDuplicateIdentifiers()) {
1513 collector.Add(PreParserIdentifier::Default());
1514 collector.Add(PreParserIdentifier::Default());
1515 }
1516
1517 return collector.ToVector();
1518 }
1519
1520
1187 template<class Traits> 1521 template<class Traits>
1188 ParserBase<Traits>::FunctionState::FunctionState( 1522 ParserBase<Traits>::FunctionState::FunctionState(
1189 FunctionState** function_state_stack, 1523 FunctionState** function_state_stack,
1190 typename Traits::Type::Scope** scope_stack, 1524 typename Traits::Type::Scope** scope_stack,
1191 typename Traits::Type::Scope* scope, 1525 typename Traits::Type::Scope* scope,
1192 typename Traits::Type::Zone* extra_param, 1526 typename Traits::Type::Zone* extra_param,
1193 AstValueFactory* ast_value_factory) 1527 AstValueFactory* ast_value_factory)
1194 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize), 1528 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize),
1195 next_handler_index_(0), 1529 next_handler_index_(0),
1196 expected_property_count_(0), 1530 expected_property_count_(0),
1197 is_generator_(false), 1531 is_generator_(false),
1198 generator_object_variable_(NULL), 1532 generator_object_variable_(NULL),
1199 function_state_stack_(function_state_stack), 1533 function_state_stack_(function_state_stack),
1200 outer_function_state_(*function_state_stack), 1534 outer_function_state_(*function_state_stack),
1201 scope_stack_(scope_stack), 1535 scope_stack_(scope_stack),
1202 outer_scope_(*scope_stack), 1536 outer_scope_(*scope_stack),
1203 saved_ast_node_id_(0), 1537 saved_ast_node_id_(0),
1204 extra_param_(extra_param), 1538 extra_param_(extra_param),
1205 factory_(extra_param, ast_value_factory) { 1539 factory_(extra_param, ast_value_factory) {
1206 *scope_stack_ = scope; 1540 *scope_stack_ = scope;
1207 *function_state_stack = this; 1541 *function_state_stack = this;
1208 Traits::SetUpFunctionState(this, extra_param); 1542 Traits::SetUpFunctionState(this, extra_param);
1209 } 1543 }
1210 1544
1211 1545
1212 template<class Traits> 1546 template<class Traits>
1547 ParserBase<Traits>::FunctionState::FunctionState(
1548 FunctionState** function_state_stack,
1549 typename Traits::Type::Scope** scope_stack,
1550 typename Traits::Type::Scope** scope,
1551 typename Traits::Type::Zone* extra_param,
1552 AstValueFactory* ast_value_factory)
1553 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize),
1554 next_handler_index_(0),
1555 expected_property_count_(0),
1556 is_generator_(false),
1557 generator_object_variable_(NULL),
1558 function_state_stack_(function_state_stack),
1559 outer_function_state_(*function_state_stack),
1560 scope_stack_(scope_stack),
1561 outer_scope_(*scope_stack),
1562 saved_ast_node_id_(0),
1563 extra_param_(extra_param),
1564 factory_(extra_param, ast_value_factory) {
1565 *scope_stack_ = *scope;
1566 *function_state_stack = this;
1567 Traits::SetUpFunctionState(this, extra_param);
1568 }
1569
1570
1571 template<class Traits>
1213 ParserBase<Traits>::FunctionState::~FunctionState() { 1572 ParserBase<Traits>::FunctionState::~FunctionState() {
1214 *scope_stack_ = outer_scope_; 1573 *scope_stack_ = outer_scope_;
1215 *function_state_stack_ = outer_function_state_; 1574 *function_state_stack_ = outer_function_state_;
1216 Traits::TearDownFunctionState(this, extra_param_); 1575 Traits::TearDownFunctionState(this, extra_param_);
1217 } 1576 }
1218 1577
1219 1578
1220 template<class Traits> 1579 template<class Traits>
1221 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) { 1580 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) {
1222 Scanner::Location source_location = scanner()->location(); 1581 Scanner::Location source_location = scanner()->location();
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
1369 // ObjectLiteral 1728 // ObjectLiteral
1370 // RegExpLiteral 1729 // RegExpLiteral
1371 // '(' Expression ')' 1730 // '(' Expression ')'
1372 1731
1373 int pos = peek_position(); 1732 int pos = peek_position();
1374 ExpressionT result = this->EmptyExpression(); 1733 ExpressionT result = this->EmptyExpression();
1375 Token::Value token = peek(); 1734 Token::Value token = peek();
1376 switch (token) { 1735 switch (token) {
1377 case Token::THIS: { 1736 case Token::THIS: {
1378 Consume(Token::THIS); 1737 Consume(Token::THIS);
1379 result = this->ThisExpression(scope_, factory()); 1738 result = this->ThisExpression(scope_, factory(), position());
1380 break; 1739 break;
1381 } 1740 }
1382 1741
1383 case Token::NULL_LITERAL: 1742 case Token::NULL_LITERAL:
1384 case Token::TRUE_LITERAL: 1743 case Token::TRUE_LITERAL:
1385 case Token::FALSE_LITERAL: 1744 case Token::FALSE_LITERAL:
1386 case Token::NUMBER: 1745 case Token::NUMBER:
1387 Next(); 1746 Next();
1388 result = this->ExpressionFromLiteral(token, pos, scanner(), factory()); 1747 result = this->ExpressionFromLiteral(token, pos, scanner(), factory());
1389 break; 1748 break;
(...skipping 24 matching lines...) Expand all
1414 case Token::LBRACK: 1773 case Token::LBRACK:
1415 result = this->ParseArrayLiteral(CHECK_OK); 1774 result = this->ParseArrayLiteral(CHECK_OK);
1416 break; 1775 break;
1417 1776
1418 case Token::LBRACE: 1777 case Token::LBRACE:
1419 result = this->ParseObjectLiteral(CHECK_OK); 1778 result = this->ParseObjectLiteral(CHECK_OK);
1420 break; 1779 break;
1421 1780
1422 case Token::LPAREN: 1781 case Token::LPAREN:
1423 Consume(Token::LPAREN); 1782 Consume(Token::LPAREN);
1424 // Heuristically try to detect immediately called functions before 1783 if (allow_arrow_functions() && peek() == Token::RPAREN) {
1425 // seeing the call parentheses. 1784 // Arrow functions are the only expression type constructions
1426 parenthesized_function_ = (peek() == Token::FUNCTION); 1785 // for which an empty parameter list "()" is valid input.
1427 result = this->ParseExpression(true, CHECK_OK); 1786 Consume(Token::RPAREN);
1428 Expect(Token::RPAREN, CHECK_OK); 1787 return this->ParseArrowFunctionLiteral(pos,
1788 this->EmptyExpression(),
1789 CHECK_OK);
1790 } else {
1791 // Heuristically try to detect immediately called functions before
1792 // seeing the call parentheses.
1793 parenthesized_function_ = (peek() == Token::FUNCTION);
1794 result = this->ParseExpression(true, CHECK_OK);
1795 Expect(Token::RPAREN, CHECK_OK);
1796 }
1429 break; 1797 break;
1430 1798
1431 case Token::MOD: 1799 case Token::MOD:
1432 if (allow_natives_syntax() || extension_ != NULL) { 1800 if (allow_natives_syntax() || extension_ != NULL) {
1433 result = this->ParseV8Intrinsic(CHECK_OK); 1801 result = this->ParseV8Intrinsic(CHECK_OK);
1434 break; 1802 break;
1435 } 1803 }
1436 // If we're not allowing special syntax we fall-through to the 1804 // If we're not allowing special syntax we fall-through to the
1437 // default case. 1805 // default case.
1438 1806
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
1687 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList)); 2055 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList));
1688 return result; 2056 return result;
1689 } 2057 }
1690 2058
1691 // Precedence = 2 2059 // Precedence = 2
1692 template <class Traits> 2060 template <class Traits>
1693 typename ParserBase<Traits>::ExpressionT 2061 typename ParserBase<Traits>::ExpressionT
1694 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) { 2062 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) {
1695 // AssignmentExpression :: 2063 // AssignmentExpression ::
1696 // ConditionalExpression 2064 // ConditionalExpression
2065 // ArrowFunction
1697 // YieldExpression 2066 // YieldExpression
1698 // LeftHandSideExpression AssignmentOperator AssignmentExpression 2067 // LeftHandSideExpression AssignmentOperator AssignmentExpression
1699 2068
1700 Scanner::Location lhs_location = scanner()->peek_location(); 2069 Scanner::Location lhs_location = scanner()->peek_location();
1701 2070
1702 if (peek() == Token::YIELD && is_generator()) { 2071 if (peek() == Token::YIELD && is_generator()) {
1703 return this->ParseYieldExpression(ok); 2072 return this->ParseYieldExpression(ok);
1704 } 2073 }
1705 2074
1706 if (fni_ != NULL) fni_->Enter(); 2075 if (fni_ != NULL) fni_->Enter();
1707 ExpressionT expression = 2076 ExpressionT expression =
1708 this->ParseConditionalExpression(accept_IN, CHECK_OK); 2077 this->ParseConditionalExpression(accept_IN, CHECK_OK);
1709 2078
2079 if (allow_arrow_functions() && peek() == Token::ARROW)
2080 return this->ParseArrowFunctionLiteral(lhs_location.beg_pos,
2081 expression,
2082 CHECK_OK);
2083
1710 if (!Token::IsAssignmentOp(peek())) { 2084 if (!Token::IsAssignmentOp(peek())) {
1711 if (fni_ != NULL) fni_->Leave(); 2085 if (fni_ != NULL) fni_->Leave();
1712 // Parsed conditional expression only (no assignment). 2086 // Parsed conditional expression only (no assignment).
1713 return expression; 2087 return expression;
1714 } 2088 }
1715 2089
1716 expression = this->CheckAndRewriteReferenceExpression( 2090 expression = this->CheckAndRewriteReferenceExpression(
1717 expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK); 2091 expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK);
1718 expression = this->MarkExpressionAsLValue(expression); 2092 expression = this->MarkExpressionAsLValue(expression);
1719 2093
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after
2105 } 2479 }
2106 default: 2480 default:
2107 return expression; 2481 return expression;
2108 } 2482 }
2109 } 2483 }
2110 ASSERT(false); 2484 ASSERT(false);
2111 return this->EmptyExpression(); 2485 return this->EmptyExpression();
2112 } 2486 }
2113 2487
2114 2488
2489 template <class Traits>
2490 typename ParserBase<Traits>::ExpressionT
2491 ParserBase<Traits>::ParseArrowFunctionLiteralBody(
2492 FunctionState* function_state,
2493 typename Traits::Type::ScopePtr scope,
2494 int num_parameters,
2495 const Scanner::Location& eval_args_error_loc,
2496 const Scanner::Location& dupe_error_loc,
2497 const Scanner::Location& reserved_loc,
2498 FunctionLiteral::IsParenthesizedFlag parenthesized,
2499 int start_pos,
2500 bool* ok) {
2501
2502 typename Traits::Type::StatementList body;
2503 int materialized_literal_count = -1;
2504 int expected_property_count = -1;
2505
2506 Expect(Token::ARROW, CHECK_OK);
2507
2508 if (peek() == Token::LBRACE) {
2509 // Multiple statemente body
2510 Consume(Token::LBRACE);
2511
2512 bool is_lazily_parsed = (mode() == PARSE_LAZILY &&
2513 scope_->AllowsLazyCompilation() &&
2514 !parenthesized_function_);
2515 parenthesized_function_ = false; // This Was set for this funciton only.
2516
2517 if (is_lazily_parsed) {
2518 this->SkipLazyFunctionBody(this->EmptyIdentifier(),
2519 &materialized_literal_count,
2520 &expected_property_count,
2521 CHECK_OK);
2522 } else {
2523 body = this->ParseEagerFunctionBody(this->EmptyIdentifier(),
2524 RelocInfo::kNoPosition,
2525 NULL,
2526 Token::INIT_VAR,
2527 false, // Not a generator.
2528 CHECK_OK);
2529 }
2530 } else {
2531 // Single-expression body
2532 parenthesized_function_ = false;
2533 ParseAssignmentExpression(true, CHECK_OK);
2534 }
2535
2536 scope->set_start_position(start_pos);
2537 scope->set_end_position(scanner()->location().end_pos);
2538
2539 // Validate strict mode.
2540 if (strict_mode() == STRICT) {
2541 CheckStrictFunctionNameAndParameters(this->EmptyIdentifierString(),
2542 false,
2543 Scanner::Location::invalid(),
2544 eval_args_error_loc,
2545 dupe_error_loc,
2546 reserved_loc,
2547 CHECK_OK);
2548 CheckOctalLiteral(start_pos,
2549 scanner()->location().end_pos,
2550 CHECK_OK);
2551 }
2552
2553 if (allow_harmony_scoping() && strict_mode() == STRICT)
2554 this->CheckConflictingVarDeclarations(scope, CHECK_OK);
2555
2556 return this->EmptyExpression();
2557 }
2558
2559
2560 template <class Traits>
2561 typename ParserBase<Traits>::ExpressionT
2562 ParserBase<Traits>::ParseArrowFunctionLiteral(bool* ok) {
2563 // TODO(aperez): Change this to use ARROW_SCOPE
2564 typename Traits::Type::ScopePtr scope =
2565 this->NewScope(scope_, FUNCTION_SCOPE);
2566
2567 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_
2568 ? FunctionLiteral::kIsParenthesized
2569 : FunctionLiteral::kNotParenthesized;
2570 parenthesized_function_ = false;
2571
2572 int start_pos = position();
2573 int num_parameters = 0;
2574 FunctionState function_state(&function_state_, &scope_, &scope, zone(),
2575 this->ast_value_factory());
2576
2577 Scanner::Location eval_args_error_loc = Scanner::Location::invalid();
2578 Scanner::Location dupe_error_loc = Scanner::Location::invalid();
2579 Scanner::Location reserved_loc = Scanner::Location::invalid();
2580
2581 if (peek() == Token::LPAREN) {
2582 // Parse a parenthesized parameter list.
2583 Consume(Token::LPAREN);
2584 bool done = (peek() == Token::RPAREN);
2585 while (!done) {
2586 bool is_strict_reserved = false;
2587 IdentifierT param_name =
2588 ParseIdentifierOrStrictReservedWord(&is_strict_reserved,
2589 CHECK_OK);
2590
2591 // Store locations for possible future error reports.
2592 if (!eval_args_error_loc.IsValid() &&
2593 this->IsEvalOrArguments(param_name)) {
2594 eval_args_error_loc = scanner()->location();
2595 }
2596 if (!reserved_loc.IsValid() && is_strict_reserved) {
2597 reserved_loc = scanner()->location();
2598 }
2599 if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) {
2600 dupe_error_loc = scanner()->location();
2601 }
2602
2603 scope_->DeclareParameter(param_name, VAR);
2604 num_parameters++;
2605 if (num_parameters > Code::kMaxArguments) {
2606 this->ReportMessageAt(scanner()->location(), "too_many_parameters");
2607 *ok = false;
2608 return this->EmptyExpression();
2609 }
2610 done = (peek() == Token::RPAREN);
2611 if (!done) Expect(Token::COMMA, CHECK_OK);
2612 }
2613 Expect(Token::RPAREN, CHECK_OK);
2614 } else {
2615 // Parse a single parameter identifier.
2616 bool is_strict_reserved = false;
2617 IdentifierT param_name =
2618 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
2619
2620 // Store locations for possible future error reports.
2621 if (this->IsEvalOrArguments(param_name))
2622 eval_args_error_loc = scanner()->location();
2623 if (is_strict_reserved)
2624 reserved_loc = scanner()->location();
2625
2626 scope_->DeclareParameter(param_name, VAR);
2627 }
2628
2629 ExpressionT literal = ParseArrowFunctionLiteralBody(&function_state,
2630 scope,
2631 num_parameters,
2632 eval_args_error_loc,
2633 dupe_error_loc,
2634 reserved_loc,
2635 parenthesized,
2636 start_pos,
2637 CHECK_OK);
2638 return literal;
2639 }
2640
2641
2642 template <class Traits>
2643 typename ParserBase<Traits>::ExpressionT
2644 ParserBase<Traits>::ParseArrowFunctionLiteral(int start_pos,
2645 ExpressionT params_ast,
2646 bool* ok) {
2647 // TODO(aperez): Change this to use ARROW_SCOPE
2648 typename Traits::Type::ScopePtr scope =
2649 this->NewScope(scope_, FUNCTION_SCOPE);
2650
2651 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_
2652 ? FunctionLiteral::kIsParenthesized
2653 : FunctionLiteral::kNotParenthesized;
2654 parenthesized_function_ = false;
2655
2656 FunctionState function_state(&function_state_, &scope_, &scope, zone(),
2657 this->ast_value_factory());
2658
2659 Scanner::Location eval_args_error_loc = Scanner::Location::invalid();
2660 Scanner::Location dupe_error_loc = Scanner::Location::invalid();
2661 Scanner::Location reserved_loc = Scanner::Location::invalid();
2662
2663 if (!scanner()->parameter_list()->IsValid(start_pos)) {
2664 ReportMessageAt(Scanner::Location(start_pos, position()),
2665 "malformed_parameter_list");
2666 *ok = false;
2667 return this->EmptyExpression();
2668 }
2669
2670 // Function parameters are already parsed into an AST
2671 typename Traits::Type::ParameterIdentifierVector params =
2672 Traits::ParameterListFromExpression(params_ast, CHECK_OK);
2673
2674 if (params.length() > Code::kMaxArguments) {
2675 ReportMessageAt(Scanner::Location(params_ast->position(), position()),
2676 "too_many_parameters");
2677 *ok = false;
2678 return this->EmptyExpression();
2679 }
2680
2681 // The vector has the items in reverse order.
2682 for (int i = params.length() - 1; i >= 0; --i) {
2683 IdentifierT param_name = params.at(i)->raw_name();
2684 int param_pos = params.at(i)->position();
2685
2686 // Store locations for possible future error reports.
2687 if (!eval_args_error_loc.IsValid() && this->IsEvalOrArguments(param_name)) {
2688 eval_args_error_loc =
2689 Scanner::Location(param_pos, param_pos + param_name->length());
2690 }
2691 if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) {
2692 dupe_error_loc =
2693 Scanner::Location(param_pos, param_pos + param_name->length());
2694 }
2695 if (!reserved_loc.IsValid() && this->IsFutureStrictReserved(param_name)) {
2696 reserved_loc =
2697 Scanner::Location(param_pos, param_pos + param_name->length());
2698 }
2699
2700 scope_->DeclareParameter(param_name, VAR);
2701 }
2702
2703 ExpressionT literal = ParseArrowFunctionLiteralBody(&function_state,
2704 scope,
2705 params.length(),
2706 eval_args_error_loc,
2707 dupe_error_loc,
2708 reserved_loc,
2709 parenthesized,
2710 start_pos,
2711 CHECK_OK);
2712 return literal;
2713 }
2714
2715
2115 template <typename Traits> 2716 template <typename Traits>
2116 typename ParserBase<Traits>::ExpressionT 2717 typename ParserBase<Traits>::ExpressionT
2117 ParserBase<Traits>::CheckAndRewriteReferenceExpression( 2718 ParserBase<Traits>::CheckAndRewriteReferenceExpression(
2118 ExpressionT expression, 2719 ExpressionT expression,
2119 Scanner::Location location, const char* message, bool* ok) { 2720 Scanner::Location location, const char* message, bool* ok) {
2120 if (strict_mode() == STRICT && this->IsIdentifier(expression) && 2721 if (strict_mode() == STRICT && this->IsIdentifier(expression) &&
2121 this->IsEvalOrArguments(this->AsIdentifier(expression))) { 2722 this->IsEvalOrArguments(this->AsIdentifier(expression))) {
2122 this->ReportMessageAt(location, "strict_eval_arguments", false); 2723 this->ReportMessageAt(location, "strict_eval_arguments", false);
2123 *ok = false; 2724 *ok = false;
2124 return this->EmptyExpression(); 2725 return this->EmptyExpression();
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
2168 parser()->ReportMessage("accessor_get_set"); 2769 parser()->ReportMessage("accessor_get_set");
2169 } 2770 }
2170 *ok = false; 2771 *ok = false;
2171 } 2772 }
2172 } 2773 }
2173 2774
2174 2775
2175 } } // v8::internal 2776 } } // v8::internal
2176 2777
2177 #endif // V8_PREPARSER_H 2778 #endif // V8_PREPARSER_H
OLDNEW
« no previous file with comments | « src/parser.cc ('k') | src/scanner.h » ('j') | src/scanner.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698