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

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: What "git cl format" produces Created 6 years, 5 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') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef V8_PREPARSER_H 5 #ifndef V8_PREPARSER_H
6 #define V8_PREPARSER_H 6 #define V8_PREPARSER_H
7 7
8 #include "src/v8.h" 8 #include "src/v8.h"
9 9
10 #include "src/func-name-inferrer.h" 10 #include "src/func-name-inferrer.h"
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 // }; 55 // };
56 // // ... 56 // // ...
57 // }; 57 // };
58 58
59 template <typename Traits> 59 template <typename Traits>
60 class ParserBase : public Traits { 60 class ParserBase : public Traits {
61 public: 61 public:
62 // Shorten type names defined by Traits. 62 // Shorten type names defined by Traits.
63 typedef typename Traits::Type::Expression ExpressionT; 63 typedef typename Traits::Type::Expression ExpressionT;
64 typedef typename Traits::Type::Identifier IdentifierT; 64 typedef typename Traits::Type::Identifier IdentifierT;
65 typedef typename Traits::Type::FunctionLiteral FunctionLiteralT;
65 66
66 ParserBase(Scanner* scanner, uintptr_t stack_limit, 67 ParserBase(Scanner* scanner, uintptr_t stack_limit, v8::Extension* extension,
67 v8::Extension* extension, 68 ParserRecorder* log, typename Traits::Type::Zone* zone,
68 ParserRecorder* log,
69 typename Traits::Type::Zone* zone,
70 typename Traits::Type::Parser this_object) 69 typename Traits::Type::Parser this_object)
71 : Traits(this_object), 70 : Traits(this_object),
72 parenthesized_function_(false), 71 parenthesized_function_(false),
73 scope_(NULL), 72 scope_(NULL),
74 function_state_(NULL), 73 function_state_(NULL),
75 extension_(extension), 74 extension_(extension),
76 fni_(NULL), 75 fni_(NULL),
77 log_(log), 76 log_(log),
78 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly. 77 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly.
79 scanner_(scanner), 78 scanner_(scanner),
80 stack_limit_(stack_limit), 79 stack_limit_(stack_limit),
81 stack_overflow_(false), 80 stack_overflow_(false),
82 allow_lazy_(false), 81 allow_lazy_(false),
83 allow_natives_syntax_(false), 82 allow_natives_syntax_(false),
84 allow_generators_(false), 83 allow_generators_(false),
85 allow_for_of_(false), 84 allow_for_of_(false),
86 zone_(zone) { } 85 allow_arrow_functions_(false),
86 zone_(zone) {}
87 87
88 // Getters that indicate whether certain syntactical constructs are 88 // Getters that indicate whether certain syntactical constructs are
89 // allowed to be parsed by this instance of the parser. 89 // allowed to be parsed by this instance of the parser.
90 bool allow_lazy() const { return allow_lazy_; } 90 bool allow_lazy() const { return allow_lazy_; }
91 bool allow_natives_syntax() const { return allow_natives_syntax_; } 91 bool allow_natives_syntax() const { return allow_natives_syntax_; }
92 bool allow_generators() const { return allow_generators_; } 92 bool allow_generators() const { return allow_generators_; }
93 bool allow_for_of() const { return allow_for_of_; } 93 bool allow_for_of() const { return allow_for_of_; }
94 bool allow_arrow_functions() const { return allow_arrow_functions_; }
94 bool allow_modules() const { return scanner()->HarmonyModules(); } 95 bool allow_modules() const { return scanner()->HarmonyModules(); }
95 bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); } 96 bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); }
96 bool allow_harmony_numeric_literals() const { 97 bool allow_harmony_numeric_literals() const {
97 return scanner()->HarmonyNumericLiterals(); 98 return scanner()->HarmonyNumericLiterals();
98 } 99 }
99 100
100 // Setters that determine whether certain syntactical constructs are 101 // Setters that determine whether certain syntactical constructs are
101 // allowed to be parsed by this instance of the parser. 102 // allowed to be parsed by this instance of the parser.
102 void set_allow_lazy(bool allow) { allow_lazy_ = allow; } 103 void set_allow_lazy(bool allow) { allow_lazy_ = allow; }
103 void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; } 104 void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; }
104 void set_allow_generators(bool allow) { allow_generators_ = allow; } 105 void set_allow_generators(bool allow) { allow_generators_ = allow; }
105 void set_allow_for_of(bool allow) { allow_for_of_ = allow; } 106 void set_allow_for_of(bool allow) { allow_for_of_ = allow; }
107 void set_allow_arrow_functions(bool allow) { allow_arrow_functions_ = allow; }
106 void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); } 108 void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); }
107 void set_allow_harmony_scoping(bool allow) { 109 void set_allow_harmony_scoping(bool allow) {
108 scanner()->SetHarmonyScoping(allow); 110 scanner()->SetHarmonyScoping(allow);
109 } 111 }
110 void set_allow_harmony_numeric_literals(bool allow) { 112 void set_allow_harmony_numeric_literals(bool allow) {
111 scanner()->SetHarmonyNumericLiterals(allow); 113 scanner()->SetHarmonyNumericLiterals(allow);
112 } 114 }
113 115
114 protected: 116 protected:
115 enum AllowEvalOrArgumentsAsIdentifier { 117 enum AllowEvalOrArgumentsAsIdentifier {
(...skipping 29 matching lines...) Expand all
145 }; 147 };
146 148
147 class FunctionState BASE_EMBEDDED { 149 class FunctionState BASE_EMBEDDED {
148 public: 150 public:
149 FunctionState( 151 FunctionState(
150 FunctionState** function_state_stack, 152 FunctionState** function_state_stack,
151 typename Traits::Type::Scope** scope_stack, 153 typename Traits::Type::Scope** scope_stack,
152 typename Traits::Type::Scope* scope, 154 typename Traits::Type::Scope* scope,
153 typename Traits::Type::Zone* zone = NULL, 155 typename Traits::Type::Zone* zone = NULL,
154 AstValueFactory* ast_value_factory = NULL); 156 AstValueFactory* ast_value_factory = NULL);
157 FunctionState(FunctionState** function_state_stack,
158 typename Traits::Type::Scope** scope_stack,
159 typename Traits::Type::Scope** scope,
160 typename Traits::Type::Zone* zone = NULL,
161 AstValueFactory* ast_value_factory = NULL);
155 ~FunctionState(); 162 ~FunctionState();
156 163
157 int NextMaterializedLiteralIndex() { 164 int NextMaterializedLiteralIndex() {
158 return next_materialized_literal_index_++; 165 return next_materialized_literal_index_++;
159 } 166 }
160 int materialized_literal_count() { 167 int materialized_literal_count() {
161 return next_materialized_literal_index_ - JSFunction::kLiteralsPrefixSize; 168 return next_materialized_literal_index_ - JSFunction::kLiteralsPrefixSize;
162 } 169 }
163 170
164 int NextHandlerIndex() { return next_handler_index_++; } 171 int NextHandlerIndex() { return next_handler_index_++; }
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
434 ExpressionT ParseYieldExpression(bool* ok); 441 ExpressionT ParseYieldExpression(bool* ok);
435 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); 442 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok);
436 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); 443 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok);
437 ExpressionT ParseUnaryExpression(bool* ok); 444 ExpressionT ParseUnaryExpression(bool* ok);
438 ExpressionT ParsePostfixExpression(bool* ok); 445 ExpressionT ParsePostfixExpression(bool* ok);
439 ExpressionT ParseLeftHandSideExpression(bool* ok); 446 ExpressionT ParseLeftHandSideExpression(bool* ok);
440 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); 447 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok);
441 ExpressionT ParseMemberExpression(bool* ok); 448 ExpressionT ParseMemberExpression(bool* ok);
442 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, 449 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression,
443 bool* ok); 450 bool* ok);
451 ExpressionT ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast,
452 bool* ok);
453 ExpressionT ParseArrowFunctionLiteralBody(
454 FunctionState* function_state, typename Traits::Type::ScopePtr scope,
455 int num_parameters, const Scanner::Location& eval_args_error_loc,
456 const Scanner::Location& dupe_error_loc,
457 const Scanner::Location& reserved_loc,
458 FunctionLiteral::IsParenthesizedFlag parenthesized, int start_pos,
459 bool* ok);
444 460
445 // Checks if the expression is a valid reference expression (e.g., on the 461 // Checks if the expression is a valid reference expression (e.g., on the
446 // left-hand side of assignments). Although ruled out by ECMA as early errors, 462 // left-hand side of assignments). Although ruled out by ECMA as early errors,
447 // we allow calls for web compatibility and rewrite them to a runtime throw. 463 // we allow calls for web compatibility and rewrite them to a runtime throw.
448 ExpressionT CheckAndRewriteReferenceExpression( 464 ExpressionT CheckAndRewriteReferenceExpression(
449 ExpressionT expression, 465 ExpressionT expression,
450 Scanner::Location location, const char* message, bool* ok); 466 Scanner::Location location, const char* message, bool* ok);
451 467
452 // Used to detect duplicates in object literals. Each of the values 468 // Used to detect duplicates in object literals. Each of the values
453 // kGetterProperty, kSetterProperty and kValueProperty represents 469 // kGetterProperty, kSetterProperty and kValueProperty represents
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
518 534
519 private: 535 private:
520 Scanner* scanner_; 536 Scanner* scanner_;
521 uintptr_t stack_limit_; 537 uintptr_t stack_limit_;
522 bool stack_overflow_; 538 bool stack_overflow_;
523 539
524 bool allow_lazy_; 540 bool allow_lazy_;
525 bool allow_natives_syntax_; 541 bool allow_natives_syntax_;
526 bool allow_generators_; 542 bool allow_generators_;
527 bool allow_for_of_; 543 bool allow_for_of_;
544 bool allow_arrow_functions_;
528 545
529 typename Traits::Type::Zone* zone_; // Only used by Parser. 546 typename Traits::Type::Zone* zone_; // Only used by Parser.
530 }; 547 };
531 548
532 549
533 class PreParserIdentifier { 550 class PreParserIdentifier {
534 public: 551 public:
535 PreParserIdentifier() : type_(kUnknownIdentifier) {} 552 PreParserIdentifier() : type_(kUnknownIdentifier) {}
536 static PreParserIdentifier Default() { 553 static PreParserIdentifier Default() {
537 return PreParserIdentifier(kUnknownIdentifier); 554 return PreParserIdentifier(kUnknownIdentifier);
538 } 555 }
539 static PreParserIdentifier Eval() { 556 static PreParserIdentifier Eval() {
540 return PreParserIdentifier(kEvalIdentifier); 557 return PreParserIdentifier(kEvalIdentifier);
541 } 558 }
542 static PreParserIdentifier Arguments() { 559 static PreParserIdentifier Arguments() {
543 return PreParserIdentifier(kArgumentsIdentifier); 560 return PreParserIdentifier(kArgumentsIdentifier);
544 } 561 }
545 static PreParserIdentifier FutureReserved() { 562 static PreParserIdentifier FutureReserved() {
546 return PreParserIdentifier(kFutureReservedIdentifier); 563 return PreParserIdentifier(kFutureReservedIdentifier);
547 } 564 }
548 static PreParserIdentifier FutureStrictReserved() { 565 static PreParserIdentifier FutureStrictReserved() {
549 return PreParserIdentifier(kFutureStrictReservedIdentifier); 566 return PreParserIdentifier(kFutureStrictReservedIdentifier);
550 } 567 }
551 static PreParserIdentifier Yield() { 568 static PreParserIdentifier Yield() {
552 return PreParserIdentifier(kYieldIdentifier); 569 return PreParserIdentifier(kYieldIdentifier);
553 } 570 }
554 bool IsEval() { return type_ == kEvalIdentifier; } 571 bool IsEval() const { return type_ == kEvalIdentifier; }
555 bool IsArguments() { return type_ == kArgumentsIdentifier; } 572 bool IsArguments() const { return type_ == kArgumentsIdentifier; }
556 bool IsEvalOrArguments() { return type_ >= kEvalIdentifier; } 573 bool IsEvalOrArguments() const { return type_ >= kEvalIdentifier; }
557 bool IsYield() { return type_ == kYieldIdentifier; } 574 bool IsYield() const { return type_ == kYieldIdentifier; }
558 bool IsFutureReserved() { return type_ == kFutureReservedIdentifier; } 575 bool IsFutureReserved() const { return type_ == kFutureReservedIdentifier; }
559 bool IsFutureStrictReserved() { 576 bool IsFutureStrictReserved() const {
560 return type_ == kFutureStrictReservedIdentifier; 577 return type_ == kFutureStrictReservedIdentifier;
561 } 578 }
562 bool IsValidStrictVariable() { return type_ == kUnknownIdentifier; } 579 bool IsValidStrictVariable() const { return type_ == kUnknownIdentifier; }
580
581 // Allow identifier->name()[->length()] to work. The preparser
582 // does not need the actual positions/lengths of the identifiers.
583 const PreParserIdentifier* operator->() const { return this; }
584 const PreParserIdentifier raw_name() const { return *this; }
585
586 int position() const { return 0; }
587 int length() const { return 0; }
563 588
564 private: 589 private:
565 enum Type { 590 enum Type {
566 kUnknownIdentifier, 591 kUnknownIdentifier,
567 kFutureReservedIdentifier, 592 kFutureReservedIdentifier,
568 kFutureStrictReservedIdentifier, 593 kFutureStrictReservedIdentifier,
569 kYieldIdentifier, 594 kYieldIdentifier,
570 kEvalIdentifier, 595 kEvalIdentifier,
571 kArgumentsIdentifier 596 kArgumentsIdentifier
572 }; 597 };
573 explicit PreParserIdentifier(Type type) : type_(type) {} 598 explicit PreParserIdentifier(Type type) : type_(type) {}
574 Type type_; 599 Type type_;
575 600
576 friend class PreParserExpression; 601 friend class PreParserExpression;
602 friend class PreParserScope;
577 }; 603 };
578 604
579 605
580 // Bits 0 and 1 are used to identify the type of expression: 606 // Bits 0 and 1 are used to identify the type of expression:
581 // If bit 0 is set, it's an identifier. 607 // If bit 0 is set, it's an identifier.
582 // if bit 1 is set, it's a string literal. 608 // if bit 1 is set, it's a string literal.
583 // If neither is set, it's no particular type, and both set isn't 609 // If neither is set, it's no particular type, and both set isn't
584 // use yet. 610 // use yet.
585 class PreParserExpression { 611 class PreParserExpression {
586 public: 612 public:
587 static PreParserExpression Default() { 613 static PreParserExpression Default() {
588 return PreParserExpression(kUnknownExpression); 614 return PreParserExpression(kUnknownExpression);
589 } 615 }
590 616
591 static PreParserExpression FromIdentifier(PreParserIdentifier id) { 617 static PreParserExpression FromIdentifier(PreParserIdentifier id) {
592 return PreParserExpression(kIdentifierFlag | 618 return PreParserExpression(kTypeIdentifier |
593 (id.type_ << kIdentifierShift)); 619 (id.type_ << kIdentifierShift));
594 } 620 }
595 621
622 static PreParserExpression BinaryOperation(PreParserExpression left,
623 Token::Value op,
624 PreParserExpression right) {
625 int code = ((op == Token::COMMA) && !left.is_parenthesized() &&
626 !right.is_parenthesized())
627 ? left.ArrowParamListBit() & right.ArrowParamListBit()
628 : 0;
629 return PreParserExpression(kTypeBinaryOperation | code);
630 }
631
632 static PreParserExpression EmptyArrowParamList() {
633 // Any expression for which IsValidArrowParamList() returns true
634 // will work here.
635 return FromIdentifier(PreParserIdentifier::Default());
636 }
637
596 static PreParserExpression StringLiteral() { 638 static PreParserExpression StringLiteral() {
597 return PreParserExpression(kUnknownStringLiteral); 639 return PreParserExpression(kUnknownStringLiteral);
598 } 640 }
599 641
600 static PreParserExpression UseStrictStringLiteral() { 642 static PreParserExpression UseStrictStringLiteral() {
601 return PreParserExpression(kUseStrictString); 643 return PreParserExpression(kUseStrictString);
602 } 644 }
603 645
604 static PreParserExpression This() { 646 static PreParserExpression This() {
605 return PreParserExpression(kThisExpression); 647 return PreParserExpression(kThisExpression);
606 } 648 }
607 649
608 static PreParserExpression ThisProperty() { 650 static PreParserExpression ThisProperty() {
609 return PreParserExpression(kThisPropertyExpression); 651 return PreParserExpression(kThisPropertyExpression);
610 } 652 }
611 653
612 static PreParserExpression Property() { 654 static PreParserExpression Property() {
613 return PreParserExpression(kPropertyExpression); 655 return PreParserExpression(kPropertyExpression);
614 } 656 }
615 657
616 static PreParserExpression Call() { 658 static PreParserExpression Call() {
617 return PreParserExpression(kCallExpression); 659 return PreParserExpression(kCallExpression);
618 } 660 }
619 661
620 bool IsIdentifier() { return (code_ & kIdentifierFlag) != 0; } 662 bool IsIdentifier() const { return (code_ & kTypeMask) == kTypeIdentifier; }
621 663
622 PreParserIdentifier AsIdentifier() { 664 PreParserIdentifier AsIdentifier() const {
623 ASSERT(IsIdentifier()); 665 ASSERT(IsIdentifier());
624 return PreParserIdentifier( 666 return PreParserIdentifier(
625 static_cast<PreParserIdentifier::Type>(code_ >> kIdentifierShift)); 667 static_cast<PreParserIdentifier::Type>(code_ >> kIdentifierShift));
626 } 668 }
627 669
628 bool IsStringLiteral() { return (code_ & kStringLiteralFlag) != 0; } 670 bool IsStringLiteral() const {
671 return (code_ & kTypeMask) == kTypeStringLiteral;
672 }
629 673
630 bool IsUseStrictLiteral() { 674 bool IsUseStrictLiteral() {
631 return (code_ & kStringLiteralMask) == kUseStrictString; 675 return (code_ & kUseStrictString) == kUseStrictString;
632 } 676 }
633 677
634 bool IsThis() { return code_ == kThisExpression; } 678 bool IsThis() { return code_ == kThisExpression; }
635 679
636 bool IsThisProperty() { return code_ == kThisPropertyExpression; } 680 bool IsThisProperty() { return code_ == kThisPropertyExpression; }
637 681
638 bool IsProperty() { 682 bool IsProperty() {
639 return code_ == kPropertyExpression || code_ == kThisPropertyExpression; 683 return code_ == kPropertyExpression || code_ == kThisPropertyExpression;
640 } 684 }
641 685
642 bool IsCall() { return code_ == kCallExpression; } 686 bool IsCall() { return code_ == kCallExpression; }
643 687
644 bool IsValidReferenceExpression() { 688 bool IsValidReferenceExpression() {
645 return IsIdentifier() || IsProperty(); 689 return IsIdentifier() || IsProperty();
646 } 690 }
647 691
692 bool IsValidArrowParamList() const {
693 return (ArrowParamListBit() & kBinaryOperationArrowParamList) != 0 &&
694 (code_ & kMultiParenthesizedExpression) == 0;
695 }
696
648 // At the moment PreParser doesn't track these expression types. 697 // At the moment PreParser doesn't track these expression types.
649 bool IsFunctionLiteral() const { return false; } 698 bool IsFunctionLiteral() const { return false; }
650 bool IsCallNew() const { return false; } 699 bool IsCallNew() const { return false; }
651 700
652 PreParserExpression AsFunctionLiteral() { return *this; } 701 PreParserExpression AsFunctionLiteral() { return *this; }
653 702
703 bool IsBinaryOperation() const {
704 return (code_ & kTypeMask) == kTypeBinaryOperation;
705 }
706
707 bool is_parenthesized() const {
708 return (code_ & kParenthesizedExpression) != 0;
709 }
710
711 void increase_parenthesization_level() {
712 code_ |= is_parenthesized() ? kMultiParenthesizedExpression
713 : kParenthesizedExpression;
714 }
715
654 // Dummy implementation for making expression->somefunc() work in both Parser 716 // Dummy implementation for making expression->somefunc() work in both Parser
655 // and PreParser. 717 // and PreParser.
656 PreParserExpression* operator->() { return this; } 718 PreParserExpression* operator->() { return this; }
657 719
658 // More dummy implementations of things PreParser doesn't need to track: 720 // More dummy implementations of things PreParser doesn't need to track:
659 void set_index(int index) {} // For YieldExpressions 721 void set_index(int index) {} // For YieldExpressions
660 void set_parenthesized() {} 722 void set_parenthesized() {}
661 723
724 int position() const { return RelocInfo::kNoPosition; }
725 void set_function_token_position(int position) {}
726 void set_ast_properties(int* ast_properties) {}
727 void set_dont_optimize_reason(BailoutReason dont_optimize_reason) {}
728
729 bool operator==(const PreParserExpression& other) const {
730 return code_ == other.code_;
731 }
732 bool operator!=(const PreParserExpression& other) const {
733 return code_ != other.code_;
734 }
735
662 private: 736 private:
663 // Least significant 2 bits are used as flags. Bits 0 and 1 represent 737 // Least significant 2 bits are used as expression type. The third least
664 // identifiers or strings literals, and are mutually exclusive, but can both 738 // significant bit tracks whether an expression is parenthesized. If the
665 // be absent. If the expression is an identifier or a string literal, the 739 // expression is an identifier or a string literal, the other bits
666 // other bits describe the type (see PreParserIdentifier::Type and string 740 // describe the type/ (see PreParserIdentifier::Type and string literal
667 // literal constants below). 741 // constants below). For binary operations, the other bits are flags
742 // which further describe the contents of the expression.
668 enum { 743 enum {
669 kUnknownExpression = 0, 744 kUnknownExpression = 0,
745 kTypeMask = 1 | 2,
746 kParenthesizedExpression = (1 << 2),
747 kMultiParenthesizedExpression = (1 << 3),
748
670 // Identifiers 749 // Identifiers
671 kIdentifierFlag = 1, // Used to detect labels. 750 kTypeIdentifier = 1, // Used to detect labels.
672 kIdentifierShift = 3, 751 kIdentifierShift = 5,
752 kTypeStringLiteral = 2, // Used to detect directive prologue.
753 kUnknownStringLiteral = kTypeStringLiteral,
754 kUseStrictString = kTypeStringLiteral | 32,
755 kStringLiteralMask = kUseStrictString,
673 756
674 kStringLiteralFlag = 2, // Used to detect directive prologue. 757 // Binary operations. Those are needed to detect certain keywords and
675 kUnknownStringLiteral = kStringLiteralFlag, 758 // duplicated identifier in parameter lists for arrow functions, because
676 kUseStrictString = kStringLiteralFlag | 8, 759 // they are initially parsed as comma-separated expressions.
677 kStringLiteralMask = kUseStrictString, 760 kTypeBinaryOperation = 3,
761 kBinaryOperationArrowParamList = (1 << 4),
678 762
679 // Below here applies if neither identifier nor string literal. Reserve the 763 // Below here applies if neither identifier nor string literal. Reserve the
680 // 2 least significant bits for flags. 764 // 2 least significant bits for flags.
681 kThisExpression = 1 << 2, 765 kThisExpression = (1 << 4),
682 kThisPropertyExpression = 2 << 2, 766 kThisPropertyExpression = (2 << 4),
683 kPropertyExpression = 3 << 2, 767 kPropertyExpression = (3 << 4),
684 kCallExpression = 4 << 2 768 kCallExpression = (4 << 4)
685 }; 769 };
686 770
687 explicit PreParserExpression(int expression_code) : code_(expression_code) {} 771 explicit PreParserExpression(int expression_code) : code_(expression_code) {}
688 772
773 V8_INLINE int ArrowParamListBit() const {
774 if (IsBinaryOperation()) return code_ & kBinaryOperationArrowParamList;
775 if (IsIdentifier()) {
776 const PreParserIdentifier ident = AsIdentifier();
777 // A valid identifier can be an arrow function parameter list
778 // except for eval, arguments, yield, and reserved keywords.
779 if (ident.IsEval() || ident.IsArguments() || ident.IsYield() ||
780 ident.IsFutureStrictReserved())
781 return 0;
782 return kBinaryOperationArrowParamList;
783 }
784 return 0;
785 }
786
689 int code_; 787 int code_;
690 }; 788 };
691 789
692 790
693 // PreParserExpressionList doesn't actually store the expressions because 791 // PreParserExpressionList doesn't actually store the expressions because
694 // PreParser doesn't need to. 792 // PreParser doesn't need to.
695 class PreParserExpressionList { 793 class PreParserExpressionList {
696 public: 794 public:
697 // These functions make list->Add(some_expression) work (and do nothing). 795 // These functions make list->Add(some_expression) work (and do nothing).
698 PreParserExpressionList() : length_(0) {} 796 PreParserExpressionList() : length_(0) {}
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
760 public: 858 public:
761 // These functions make list->Add(some_expression) work as no-ops. 859 // These functions make list->Add(some_expression) work as no-ops.
762 PreParserStatementList() {} 860 PreParserStatementList() {}
763 PreParserStatementList* operator->() { return this; } 861 PreParserStatementList* operator->() { return this; }
764 void Add(PreParserStatement, void*) {} 862 void Add(PreParserStatement, void*) {}
765 }; 863 };
766 864
767 865
768 class PreParserScope { 866 class PreParserScope {
769 public: 867 public:
770 explicit PreParserScope(PreParserScope* outer_scope, ScopeType scope_type) 868 explicit PreParserScope(PreParserScope* outer_scope, ScopeType scope_type,
869 void* = NULL)
771 : scope_type_(scope_type) { 870 : scope_type_(scope_type) {
772 strict_mode_ = outer_scope ? outer_scope->strict_mode() : SLOPPY; 871 strict_mode_ = outer_scope ? outer_scope->strict_mode() : SLOPPY;
773 } 872 }
774 873
775 ScopeType type() { return scope_type_; } 874 ScopeType type() { return scope_type_; }
776 StrictMode strict_mode() const { return strict_mode_; } 875 StrictMode strict_mode() const { return strict_mode_; }
777 void SetStrictMode(StrictMode strict_mode) { strict_mode_ = strict_mode; } 876 void SetStrictMode(StrictMode strict_mode) { strict_mode_ = strict_mode; }
778 877
878 // When PreParser is in use, lazy compilation is already being done,
879 // things cannot get lazier than that.
880 bool AllowsLazyCompilation() const { return false; }
881
882 void set_start_position(int position) {}
883 void set_end_position(int position) {}
884
885 bool IsDeclared(const PreParserIdentifier& identifier) const { return false; }
886 void DeclareParameter(const PreParserIdentifier& identifier, VariableMode) {}
887
888 // Allow scope->Foo() to work.
889 PreParserScope* operator->() { return this; }
890
779 private: 891 private:
780 ScopeType scope_type_; 892 ScopeType scope_type_;
781 StrictMode strict_mode_; 893 StrictMode strict_mode_;
782 }; 894 };
783 895
784 896
785 class PreParserFactory { 897 class PreParserFactory {
786 public: 898 public:
787 explicit PreParserFactory(void* extra_param1, void* extra_param2) {} 899 explicit PreParserFactory(void* extra_param1, void* extra_param2) {}
788 PreParserExpression NewStringLiteral(PreParserIdentifier identifier, 900 PreParserExpression NewStringLiteral(PreParserIdentifier identifier,
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
832 return PreParserExpression::Property(); 944 return PreParserExpression::Property();
833 } 945 }
834 PreParserExpression NewUnaryOperation(Token::Value op, 946 PreParserExpression NewUnaryOperation(Token::Value op,
835 PreParserExpression expression, 947 PreParserExpression expression,
836 int pos) { 948 int pos) {
837 return PreParserExpression::Default(); 949 return PreParserExpression::Default();
838 } 950 }
839 PreParserExpression NewBinaryOperation(Token::Value op, 951 PreParserExpression NewBinaryOperation(Token::Value op,
840 PreParserExpression left, 952 PreParserExpression left,
841 PreParserExpression right, int pos) { 953 PreParserExpression right, int pos) {
842 return PreParserExpression::Default(); 954 return PreParserExpression::BinaryOperation(left, op, right);
843 } 955 }
844 PreParserExpression NewCompareOperation(Token::Value op, 956 PreParserExpression NewCompareOperation(Token::Value op,
845 PreParserExpression left, 957 PreParserExpression left,
846 PreParserExpression right, int pos) { 958 PreParserExpression right, int pos) {
847 return PreParserExpression::Default(); 959 return PreParserExpression::Default();
848 } 960 }
849 PreParserExpression NewAssignment(Token::Value op, 961 PreParserExpression NewAssignment(Token::Value op,
850 PreParserExpression left, 962 PreParserExpression left,
851 PreParserExpression right, 963 PreParserExpression right,
852 int pos) { 964 int pos) {
(...skipping 20 matching lines...) Expand all
873 PreParserExpression NewCall(PreParserExpression expression, 985 PreParserExpression NewCall(PreParserExpression expression,
874 PreParserExpressionList arguments, 986 PreParserExpressionList arguments,
875 int pos) { 987 int pos) {
876 return PreParserExpression::Call(); 988 return PreParserExpression::Call();
877 } 989 }
878 PreParserExpression NewCallNew(PreParserExpression expression, 990 PreParserExpression NewCallNew(PreParserExpression expression,
879 PreParserExpressionList arguments, 991 PreParserExpressionList arguments,
880 int pos) { 992 int pos) {
881 return PreParserExpression::Default(); 993 return PreParserExpression::Default();
882 } 994 }
995 PreParserStatement NewReturnStatement(PreParserExpression expression,
996 int pos) {
997 return PreParserStatement::Default();
998 }
999 PreParserExpression NewFunctionLiteral(
1000 PreParserIdentifier name, AstValueFactory* ast_value_factory,
1001 const PreParserScope& scope, PreParserStatementList body,
1002 int materialized_literal_count, int expected_property_count,
1003 int handler_count, int parameter_count,
1004 FunctionLiteral::ParameterFlag has_duplicate_parameters,
1005 FunctionLiteral::FunctionType function_type,
1006 FunctionLiteral::IsFunctionFlag is_function,
1007 FunctionLiteral::IsParenthesizedFlag is_parenthesized,
1008 FunctionLiteral::IsGeneratorFlag is_generator, int position) {
1009 return PreParserExpression::Default();
1010 }
1011
1012 // Return the object itself as AstVisitor and implement the needed
1013 // dummy method right in this class.
1014 PreParserFactory* visitor() { return this; }
1015 BailoutReason dont_optimize_reason() { return kNoReason; }
1016 int* ast_properties() {
1017 static int dummy = 42;
1018 return &dummy;
1019 }
883 }; 1020 };
884 1021
885 1022
886 class PreParser; 1023 class PreParser;
887 1024
888 class PreParserTraits { 1025 class PreParserTraits {
889 public: 1026 public:
890 struct Type { 1027 struct Type {
891 // TODO(marja): To be removed. The Traits object should contain all the data 1028 // TODO(marja): To be removed. The Traits object should contain all the data
892 // it needs. 1029 // it needs.
893 typedef PreParser* Parser; 1030 typedef PreParser* Parser;
894 1031
895 // Used by FunctionState and BlockState. 1032 // Used by FunctionState and BlockState.
896 typedef PreParserScope Scope; 1033 typedef PreParserScope Scope;
1034 typedef PreParserScope ScopePtr;
1035
897 // PreParser doesn't need to store generator variables. 1036 // PreParser doesn't need to store generator variables.
898 typedef void GeneratorVariable; 1037 typedef void GeneratorVariable;
899 // No interaction with Zones. 1038 // No interaction with Zones.
900 typedef void Zone; 1039 typedef void Zone;
901 1040
1041 typedef int AstProperties;
1042 typedef Vector<PreParserIdentifier> ParameterIdentifierVector;
1043
902 // Return types for traversing functions. 1044 // Return types for traversing functions.
903 typedef PreParserIdentifier Identifier; 1045 typedef PreParserIdentifier Identifier;
904 typedef PreParserExpression Expression; 1046 typedef PreParserExpression Expression;
905 typedef PreParserExpression YieldExpression; 1047 typedef PreParserExpression YieldExpression;
906 typedef PreParserExpression FunctionLiteral; 1048 typedef PreParserExpression FunctionLiteral;
907 typedef PreParserExpression ObjectLiteralProperty; 1049 typedef PreParserExpression ObjectLiteralProperty;
908 typedef PreParserExpression Literal; 1050 typedef PreParserExpression Literal;
909 typedef PreParserExpressionList ExpressionList; 1051 typedef PreParserExpressionList ExpressionList;
910 typedef PreParserExpressionList PropertyList; 1052 typedef PreParserExpressionList PropertyList;
911 typedef PreParserStatementList StatementList; 1053 typedef PreParserStatementList StatementList;
(...skipping 22 matching lines...) Expand all
934 } 1076 }
935 1077
936 static bool IsIdentifier(PreParserExpression expression) { 1078 static bool IsIdentifier(PreParserExpression expression) {
937 return expression.IsIdentifier(); 1079 return expression.IsIdentifier();
938 } 1080 }
939 1081
940 static PreParserIdentifier AsIdentifier(PreParserExpression expression) { 1082 static PreParserIdentifier AsIdentifier(PreParserExpression expression) {
941 return expression.AsIdentifier(); 1083 return expression.AsIdentifier();
942 } 1084 }
943 1085
1086 static bool IsFutureStrictReserved(PreParserIdentifier identifier) {
1087 return identifier.IsYield() || identifier.IsFutureStrictReserved();
1088 }
1089
944 static bool IsBoilerplateProperty(PreParserExpression property) { 1090 static bool IsBoilerplateProperty(PreParserExpression property) {
945 // PreParser doesn't count boilerplate properties. 1091 // PreParser doesn't count boilerplate properties.
946 return false; 1092 return false;
947 } 1093 }
948 1094
949 static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) { 1095 static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) {
950 return false; 1096 return false;
951 } 1097 }
952 1098
953 // Functions for encapsulating the differences between parsing and preparsing; 1099 // Functions for encapsulating the differences between parsing and preparsing;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
997 return PreParserExpression::Default(); 1143 return PreParserExpression::Default();
998 } 1144 }
999 PreParserExpression NewThrowSyntaxError( 1145 PreParserExpression NewThrowSyntaxError(
1000 const char* type, Handle<Object> arg, int pos) { 1146 const char* type, Handle<Object> arg, int pos) {
1001 return PreParserExpression::Default(); 1147 return PreParserExpression::Default();
1002 } 1148 }
1003 PreParserExpression NewThrowTypeError( 1149 PreParserExpression NewThrowTypeError(
1004 const char* type, Handle<Object> arg, int pos) { 1150 const char* type, Handle<Object> arg, int pos) {
1005 return PreParserExpression::Default(); 1151 return PreParserExpression::Default();
1006 } 1152 }
1153 PreParserScope NewScope(PreParserScope* outer_scope, ScopeType scope_type) {
1154 return PreParserScope(outer_scope, scope_type);
1155 }
1007 1156
1008 // Reporting errors. 1157 // Reporting errors.
1009 void ReportMessageAt(Scanner::Location location, 1158 void ReportMessageAt(Scanner::Location location,
1010 const char* message, 1159 const char* message,
1011 const char* arg = NULL, 1160 const char* arg = NULL,
1012 bool is_reference_error = false); 1161 bool is_reference_error = false);
1013 void ReportMessageAt(int start_pos, 1162 void ReportMessageAt(int start_pos,
1014 int end_pos, 1163 int end_pos,
1015 const char* message, 1164 const char* message,
1016 const char* arg = NULL, 1165 const char* arg = NULL,
1017 bool is_reference_error = false); 1166 bool is_reference_error = false);
1018 1167
1019 // "null" return type creators. 1168 // "null" return type creators.
1020 static PreParserIdentifier EmptyIdentifier() { 1169 static PreParserIdentifier EmptyIdentifier() {
1021 return PreParserIdentifier::Default(); 1170 return PreParserIdentifier::Default();
1022 } 1171 }
1172 static PreParserIdentifier EmptyIdentifierString() {
1173 return PreParserIdentifier::Default();
1174 }
1023 static PreParserExpression EmptyExpression() { 1175 static PreParserExpression EmptyExpression() {
1024 return PreParserExpression::Default(); 1176 return PreParserExpression::Default();
1025 } 1177 }
1178 static PreParserExpression EmptyArrowParamList() {
1179 return PreParserExpression::EmptyArrowParamList();
1180 }
1026 static PreParserExpression EmptyLiteral() { 1181 static PreParserExpression EmptyLiteral() {
1027 return PreParserExpression::Default(); 1182 return PreParserExpression::Default();
1028 } 1183 }
1029 static PreParserExpressionList NullExpressionList() { 1184 static PreParserExpressionList NullExpressionList() {
1030 return PreParserExpressionList(); 1185 return PreParserExpressionList();
1031 } 1186 }
1032 1187
1033 // Odd-ball literal creators. 1188 // Odd-ball literal creators.
1034 static PreParserExpression GetLiteralTheHole(int position, 1189 static PreParserExpression GetLiteralTheHole(int position,
1035 PreParserFactory* factory) { 1190 PreParserFactory* factory) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1069 } 1224 }
1070 1225
1071 static PreParserStatementList NewStatementList(int size, void* zone) { 1226 static PreParserStatementList NewStatementList(int size, void* zone) {
1072 return PreParserStatementList(); 1227 return PreParserStatementList();
1073 } 1228 }
1074 1229
1075 static PreParserExpressionList NewPropertyList(int size, void* zone) { 1230 static PreParserExpressionList NewPropertyList(int size, void* zone) {
1076 return PreParserExpressionList(); 1231 return PreParserExpressionList();
1077 } 1232 }
1078 1233
1234 V8_INLINE void SkipLazyFunctionBody(PreParserIdentifier function_name,
1235 int* materialized_literal_count,
1236 int* expected_property_count, bool* ok) {
1237 UNREACHABLE();
1238 }
1239
1240 V8_INLINE PreParserStatementList
1241 ParseEagerFunctionBody(PreParserIdentifier function_name, int pos,
1242 Variable* fvar, Token::Value fvar_init_op,
1243 bool is_generator, bool* ok);
1244
1245 // Utility functions
1246 Vector<PreParserIdentifier> ParameterListFromExpression(
1247 PreParserExpression expression, bool* ok) {
1248 // TODO(aperez): Detect duplicated identifiers in paramlists.
1249 *ok = expression.IsValidArrowParamList();
1250 return Vector<PreParserIdentifier>::empty();
1251 }
1252
1253 static AstValueFactory* ast_value_factory() { return NULL; }
1254
1255 void CheckConflictingVarDeclarations(PreParserScope scope, bool* ok) {}
1256
1079 // Temporary glue; these functions will move to ParserBase. 1257 // Temporary glue; these functions will move to ParserBase.
1080 PreParserExpression ParseV8Intrinsic(bool* ok); 1258 PreParserExpression ParseV8Intrinsic(bool* ok);
1081 PreParserExpression ParseFunctionLiteral( 1259 PreParserExpression ParseFunctionLiteral(
1082 PreParserIdentifier name, 1260 PreParserIdentifier name,
1083 Scanner::Location function_name_location, 1261 Scanner::Location function_name_location,
1084 bool name_is_strict_reserved, 1262 bool name_is_strict_reserved,
1085 bool is_generator, 1263 bool is_generator,
1086 int function_token_position, 1264 int function_token_position,
1087 FunctionLiteral::FunctionType type, 1265 FunctionLiteral::FunctionType type,
1088 FunctionLiteral::ArityRestriction arity_restriction, 1266 FunctionLiteral::ArityRestriction arity_restriction,
(...skipping 30 matching lines...) Expand all
1119 PreParser(Scanner* scanner, ParserRecorder* log, uintptr_t stack_limit) 1297 PreParser(Scanner* scanner, ParserRecorder* log, uintptr_t stack_limit)
1120 : ParserBase<PreParserTraits>(scanner, stack_limit, NULL, log, NULL, 1298 : ParserBase<PreParserTraits>(scanner, stack_limit, NULL, log, NULL,
1121 this) {} 1299 this) {}
1122 1300
1123 // Pre-parse the program from the character stream; returns true on 1301 // Pre-parse the program from the character stream; returns true on
1124 // success (even if parsing failed, the pre-parse data successfully 1302 // success (even if parsing failed, the pre-parse data successfully
1125 // captured the syntax error), and false if a stack-overflow happened 1303 // captured the syntax error), and false if a stack-overflow happened
1126 // during parsing. 1304 // during parsing.
1127 PreParseResult PreParseProgram() { 1305 PreParseResult PreParseProgram() {
1128 PreParserScope scope(scope_, GLOBAL_SCOPE); 1306 PreParserScope scope(scope_, GLOBAL_SCOPE);
1129 FunctionState top_scope(&function_state_, &scope_, &scope, NULL); 1307 FunctionState top_scope(&function_state_, &scope_, &scope);
1130 bool ok = true; 1308 bool ok = true;
1131 int start_position = scanner()->peek_location().beg_pos; 1309 int start_position = scanner()->peek_location().beg_pos;
1132 ParseSourceElements(Token::EOS, &ok); 1310 ParseSourceElements(Token::EOS, &ok);
1133 if (stack_overflow()) return kPreParseStackOverflow; 1311 if (stack_overflow()) return kPreParseStackOverflow;
1134 if (!ok) { 1312 if (!ok) {
1135 ReportUnexpectedToken(scanner()->current_token()); 1313 ReportUnexpectedToken(scanner()->current_token());
1136 } else if (scope_->strict_mode() == STRICT) { 1314 } else if (scope_->strict_mode() == STRICT) {
1137 CheckOctalLiteral(start_position, scanner()->location().end_pos, &ok); 1315 CheckOctalLiteral(start_position, scanner()->location().end_pos, &ok);
1138 } 1316 }
1139 return kPreParseSuccess; 1317 return kPreParseSuccess;
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1201 Statement ParseDoWhileStatement(bool* ok); 1379 Statement ParseDoWhileStatement(bool* ok);
1202 Statement ParseWhileStatement(bool* ok); 1380 Statement ParseWhileStatement(bool* ok);
1203 Statement ParseForStatement(bool* ok); 1381 Statement ParseForStatement(bool* ok);
1204 Statement ParseThrowStatement(bool* ok); 1382 Statement ParseThrowStatement(bool* ok);
1205 Statement ParseTryStatement(bool* ok); 1383 Statement ParseTryStatement(bool* ok);
1206 Statement ParseDebuggerStatement(bool* ok); 1384 Statement ParseDebuggerStatement(bool* ok);
1207 Expression ParseConditionalExpression(bool accept_IN, bool* ok); 1385 Expression ParseConditionalExpression(bool accept_IN, bool* ok);
1208 Expression ParseObjectLiteral(bool* ok); 1386 Expression ParseObjectLiteral(bool* ok);
1209 Expression ParseV8Intrinsic(bool* ok); 1387 Expression ParseV8Intrinsic(bool* ok);
1210 1388
1389 V8_INLINE void SkipLazyFunctionBody(PreParserIdentifier function_name,
1390 int* materialized_literal_count,
1391 int* expected_property_count, bool* ok);
1392 V8_INLINE PreParserStatementList
1393 ParseEagerFunctionBody(PreParserIdentifier function_name, int pos,
1394 Variable* fvar, Token::Value fvar_init_op,
1395 bool is_generator, bool* ok);
1396
1211 Expression ParseFunctionLiteral( 1397 Expression ParseFunctionLiteral(
1212 Identifier name, 1398 Identifier name,
1213 Scanner::Location function_name_location, 1399 Scanner::Location function_name_location,
1214 bool name_is_strict_reserved, 1400 bool name_is_strict_reserved,
1215 bool is_generator, 1401 bool is_generator,
1216 int function_token_pos, 1402 int function_token_pos,
1217 FunctionLiteral::FunctionType function_type, 1403 FunctionLiteral::FunctionType function_type,
1218 FunctionLiteral::ArityRestriction arity_restriction, 1404 FunctionLiteral::ArityRestriction arity_restriction,
1219 bool* ok); 1405 bool* ok);
1220 void ParseLazyFunctionLiteralBody(bool* ok); 1406 void ParseLazyFunctionLiteralBody(bool* ok);
1221 1407
1222 bool CheckInOrOf(bool accept_OF); 1408 bool CheckInOrOf(bool accept_OF);
1223 }; 1409 };
1224 1410
1411
1412 PreParserStatementList PreParser::ParseEagerFunctionBody(
1413 PreParserIdentifier function_name, int pos, Variable* fvar,
1414 Token::Value fvar_init_op, bool is_generator, bool* ok) {
1415 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
1416
1417 ParseSourceElements(Token::RBRACE, ok);
1418 if (!*ok) return PreParserStatementList();
1419
1420 Expect(Token::RBRACE, ok);
1421 return PreParserStatementList();
1422 }
1423
1424
1425 PreParserStatementList PreParserTraits::ParseEagerFunctionBody(
1426 PreParserIdentifier function_name, int pos, Variable* fvar,
1427 Token::Value fvar_init_op, bool is_generator, bool* ok) {
1428 return pre_parser_->ParseEagerFunctionBody(function_name, pos, fvar,
1429 fvar_init_op, is_generator, ok);
1430 }
1431
1432
1225 template<class Traits> 1433 template<class Traits>
1226 ParserBase<Traits>::FunctionState::FunctionState( 1434 ParserBase<Traits>::FunctionState::FunctionState(
1227 FunctionState** function_state_stack, 1435 FunctionState** function_state_stack,
1228 typename Traits::Type::Scope** scope_stack, 1436 typename Traits::Type::Scope** scope_stack,
1229 typename Traits::Type::Scope* scope, 1437 typename Traits::Type::Scope* scope,
1230 typename Traits::Type::Zone* extra_param, 1438 typename Traits::Type::Zone* extra_param,
1231 AstValueFactory* ast_value_factory) 1439 AstValueFactory* ast_value_factory)
1232 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize), 1440 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize),
1233 next_handler_index_(0), 1441 next_handler_index_(0),
1234 expected_property_count_(0), 1442 expected_property_count_(0),
1235 is_generator_(false), 1443 is_generator_(false),
1236 generator_object_variable_(NULL), 1444 generator_object_variable_(NULL),
1237 function_state_stack_(function_state_stack), 1445 function_state_stack_(function_state_stack),
1238 outer_function_state_(*function_state_stack), 1446 outer_function_state_(*function_state_stack),
1239 scope_stack_(scope_stack), 1447 scope_stack_(scope_stack),
1240 outer_scope_(*scope_stack), 1448 outer_scope_(*scope_stack),
1241 saved_ast_node_id_(0), 1449 saved_ast_node_id_(0),
1242 extra_param_(extra_param), 1450 extra_param_(extra_param),
1243 factory_(extra_param, ast_value_factory) { 1451 factory_(extra_param, ast_value_factory) {
1244 *scope_stack_ = scope; 1452 *scope_stack_ = scope;
1245 *function_state_stack = this; 1453 *function_state_stack = this;
1246 Traits::SetUpFunctionState(this, extra_param); 1454 Traits::SetUpFunctionState(this, extra_param);
1247 } 1455 }
1248 1456
1249 1457
1250 template<class Traits> 1458 template <class Traits>
1459 ParserBase<Traits>::FunctionState::FunctionState(
1460 FunctionState** function_state_stack,
1461 typename Traits::Type::Scope** scope_stack,
1462 typename Traits::Type::Scope** scope,
1463 typename Traits::Type::Zone* extra_param,
1464 AstValueFactory* ast_value_factory)
1465 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize),
1466 next_handler_index_(0),
1467 expected_property_count_(0),
1468 is_generator_(false),
1469 generator_object_variable_(NULL),
1470 function_state_stack_(function_state_stack),
1471 outer_function_state_(*function_state_stack),
1472 scope_stack_(scope_stack),
1473 outer_scope_(*scope_stack),
1474 saved_ast_node_id_(0),
1475 extra_param_(extra_param),
1476 factory_(extra_param, ast_value_factory) {
1477 *scope_stack_ = *scope;
1478 *function_state_stack = this;
1479 Traits::SetUpFunctionState(this, extra_param);
1480 }
1481
1482
1483 template <class Traits>
1251 ParserBase<Traits>::FunctionState::~FunctionState() { 1484 ParserBase<Traits>::FunctionState::~FunctionState() {
1252 *scope_stack_ = outer_scope_; 1485 *scope_stack_ = outer_scope_;
1253 *function_state_stack_ = outer_function_state_; 1486 *function_state_stack_ = outer_function_state_;
1254 Traits::TearDownFunctionState(this, extra_param_); 1487 Traits::TearDownFunctionState(this, extra_param_);
1255 } 1488 }
1256 1489
1257 1490
1258 template<class Traits> 1491 template<class Traits>
1259 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) { 1492 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) {
1260 Scanner::Location source_location = scanner()->location(); 1493 Scanner::Location source_location = scanner()->location();
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
1452 case Token::LBRACK: 1685 case Token::LBRACK:
1453 result = this->ParseArrayLiteral(CHECK_OK); 1686 result = this->ParseArrayLiteral(CHECK_OK);
1454 break; 1687 break;
1455 1688
1456 case Token::LBRACE: 1689 case Token::LBRACE:
1457 result = this->ParseObjectLiteral(CHECK_OK); 1690 result = this->ParseObjectLiteral(CHECK_OK);
1458 break; 1691 break;
1459 1692
1460 case Token::LPAREN: 1693 case Token::LPAREN:
1461 Consume(Token::LPAREN); 1694 Consume(Token::LPAREN);
1462 // Heuristically try to detect immediately called functions before 1695 if (allow_arrow_functions() && peek() == Token::RPAREN) {
1463 // seeing the call parentheses. 1696 // Arrow functions are the only expression type constructions
1464 parenthesized_function_ = (peek() == Token::FUNCTION); 1697 // for which an empty parameter list "()" is valid input.
1465 result = this->ParseExpression(true, CHECK_OK); 1698 Consume(Token::RPAREN);
1466 Expect(Token::RPAREN, CHECK_OK); 1699 return this->ParseArrowFunctionLiteral(pos, this->EmptyArrowParamList(),
1700 CHECK_OK);
1701 } else {
1702 // Heuristically try to detect immediately called functions before
1703 // seeing the call parentheses.
1704 parenthesized_function_ = (peek() == Token::FUNCTION);
1705 result = this->ParseExpression(true, CHECK_OK);
1706 result->increase_parenthesization_level();
1707 Expect(Token::RPAREN, CHECK_OK);
1708 }
1467 break; 1709 break;
1468 1710
1469 case Token::MOD: 1711 case Token::MOD:
1470 if (allow_natives_syntax() || extension_ != NULL) { 1712 if (allow_natives_syntax() || extension_ != NULL) {
1471 result = this->ParseV8Intrinsic(CHECK_OK); 1713 result = this->ParseV8Intrinsic(CHECK_OK);
1472 break; 1714 break;
1473 } 1715 }
1474 // If we're not allowing special syntax we fall-through to the 1716 // If we're not allowing special syntax we fall-through to the
1475 // default case. 1717 // default case.
1476 1718
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
1724 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList)); 1966 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList));
1725 return result; 1967 return result;
1726 } 1968 }
1727 1969
1728 // Precedence = 2 1970 // Precedence = 2
1729 template <class Traits> 1971 template <class Traits>
1730 typename ParserBase<Traits>::ExpressionT 1972 typename ParserBase<Traits>::ExpressionT
1731 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) { 1973 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) {
1732 // AssignmentExpression :: 1974 // AssignmentExpression ::
1733 // ConditionalExpression 1975 // ConditionalExpression
1976 // ArrowFunction
1734 // YieldExpression 1977 // YieldExpression
1735 // LeftHandSideExpression AssignmentOperator AssignmentExpression 1978 // LeftHandSideExpression AssignmentOperator AssignmentExpression
1736 1979
1737 Scanner::Location lhs_location = scanner()->peek_location(); 1980 Scanner::Location lhs_location = scanner()->peek_location();
1738 1981
1739 if (peek() == Token::YIELD && is_generator()) { 1982 if (peek() == Token::YIELD && is_generator()) {
1740 return this->ParseYieldExpression(ok); 1983 return this->ParseYieldExpression(ok);
1741 } 1984 }
1742 1985
1743 if (fni_ != NULL) fni_->Enter(); 1986 if (fni_ != NULL) fni_->Enter();
1744 ExpressionT expression = 1987 ExpressionT expression =
1745 this->ParseConditionalExpression(accept_IN, CHECK_OK); 1988 this->ParseConditionalExpression(accept_IN, CHECK_OK);
1746 1989
1990 if (allow_arrow_functions() && peek() == Token::ARROW)
1991 return this->ParseArrowFunctionLiteral(lhs_location.beg_pos, expression,
1992 CHECK_OK);
1993
1747 if (!Token::IsAssignmentOp(peek())) { 1994 if (!Token::IsAssignmentOp(peek())) {
1748 if (fni_ != NULL) fni_->Leave(); 1995 if (fni_ != NULL) fni_->Leave();
1749 // Parsed conditional expression only (no assignment). 1996 // Parsed conditional expression only (no assignment).
1750 return expression; 1997 return expression;
1751 } 1998 }
1752 1999
1753 expression = this->CheckAndRewriteReferenceExpression( 2000 expression = this->CheckAndRewriteReferenceExpression(
1754 expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK); 2001 expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK);
1755 expression = this->MarkExpressionAsAssigned(expression); 2002 expression = this->MarkExpressionAsAssigned(expression);
1756 2003
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after
2163 } 2410 }
2164 default: 2411 default:
2165 return expression; 2412 return expression;
2166 } 2413 }
2167 } 2414 }
2168 ASSERT(false); 2415 ASSERT(false);
2169 return this->EmptyExpression(); 2416 return this->EmptyExpression();
2170 } 2417 }
2171 2418
2172 2419
2420 template <class Traits>
2421 typename ParserBase<Traits>::ExpressionT ParserBase<
2422 Traits>::ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast,
2423 bool* ok) {
2424 typename Traits::Type::ParameterIdentifierVector params =
2425 Traits::ParameterListFromExpression(params_ast, ok);
2426
2427 if (!*ok) {
2428 ReportMessageAt(Scanner::Location(start_pos, scanner()->location().beg_pos),
2429 "malformed_arrow_function_parameter_list");
2430 return this->EmptyExpression();
2431 }
2432
2433 // TODO(aperez): Change this to use ARROW_SCOPE
2434 typename Traits::Type::ScopePtr scope =
2435 this->NewScope(scope_, FUNCTION_SCOPE);
2436
2437 FunctionState function_state(&function_state_, &scope_, &scope, zone(),
2438 this->ast_value_factory());
2439 Scanner::Location dupe_error_loc = Scanner::Location::invalid();
2440
2441 if (params.length() > Code::kMaxArguments) {
2442 ReportMessageAt(Scanner::Location(params_ast->position(), position()),
2443 "too_many_parameters");
2444 *ok = false;
2445 return this->EmptyExpression();
2446 }
2447
2448 for (int i = 0; i < params.length(); ++i) {
2449 const IdentifierT param_name = params.at(i)->raw_name();
2450 if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) {
2451 int param_pos = params.at(i)->position();
2452 dupe_error_loc =
2453 Scanner::Location(param_pos, param_pos + param_name->length());
2454 }
2455 scope_->DeclareParameter(param_name, VAR);
2456 }
2457
2458 ExpressionT expression = ParseArrowFunctionLiteralBody(
2459 &function_state, scope, params.length(), Scanner::Location::invalid(),
2460 dupe_error_loc, Scanner::Location::invalid(),
2461 FunctionLiteral::kNotParenthesized, start_pos, CHECK_OK);
2462 return expression;
2463 }
2464
2465
2466 template <class Traits>
2467 typename ParserBase<Traits>::ExpressionT
2468 ParserBase<Traits>::ParseArrowFunctionLiteralBody(
2469 FunctionState* function_state, typename Traits::Type::ScopePtr scope,
2470 int num_parameters, const Scanner::Location& eval_args_error_loc,
2471 const Scanner::Location& dupe_error_loc,
2472 const Scanner::Location& reserved_loc,
2473 FunctionLiteral::IsParenthesizedFlag parenthesized, int start_pos,
2474 bool* ok) {
2475 int materialized_literal_count = -1;
2476 int expected_property_count = -1;
2477
2478 Expect(Token::ARROW, CHECK_OK);
2479
2480 if (peek() == Token::LBRACE) {
2481 // Multiple statemente body
2482 Consume(Token::LBRACE);
2483 bool is_lazily_parsed =
2484 (mode() == PARSE_LAZILY && scope_->AllowsLazyCompilation());
2485 if (is_lazily_parsed) {
2486 this->SkipLazyFunctionBody(this->EmptyIdentifier(),
2487 &materialized_literal_count,
2488 &expected_property_count, CHECK_OK);
2489 } else {
2490 this->ParseEagerFunctionBody(this->EmptyIdentifier(),
2491 RelocInfo::kNoPosition, NULL,
2492 Token::INIT_VAR, false, // Not a generator.
2493 CHECK_OK);
2494 }
2495 } else {
2496 // Single-expression body
2497 ParseAssignmentExpression(true, CHECK_OK);
2498 }
2499
2500 scope->set_start_position(start_pos);
2501 scope->set_end_position(scanner()->location().end_pos);
2502
2503 // Arrow function *parameter lists* are always checked as in strict mode.
2504 this->CheckStrictFunctionNameAndParameters(
2505 this->EmptyIdentifier(), false, Scanner::Location::invalid(),
2506 Scanner::Location::invalid(), dupe_error_loc,
2507 Scanner::Location::invalid(), CHECK_OK);
2508
2509 // Validate strict mode.
2510 if (strict_mode() == STRICT) {
2511 CheckOctalLiteral(start_pos, scanner()->location().end_pos, CHECK_OK);
2512 }
2513
2514 if (allow_harmony_scoping() && strict_mode() == STRICT)
2515 this->CheckConflictingVarDeclarations(scope, CHECK_OK);
2516
2517 // TODO(aperez): Generate a proper FunctionLiteral instead of
2518 // returning a dummy value.
2519 FunctionLiteralT function_literal = factory()->NewFunctionLiteral(
2520 this->EmptyIdentifierString(), this->ast_value_factory(), scope,
2521 this->NewStatementList(0, zone()), 0, 0, 0, num_parameters,
2522 FunctionLiteral::kNoDuplicateParameters,
2523 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kIsFunction,
2524 FunctionLiteral::kNotParenthesized, FunctionLiteral::kNotGenerator,
2525 start_pos);
2526 function_literal->set_function_token_position(start_pos);
2527 return function_literal;
2528 }
2529
2530
2173 template <typename Traits> 2531 template <typename Traits>
2174 typename ParserBase<Traits>::ExpressionT 2532 typename ParserBase<Traits>::ExpressionT
2175 ParserBase<Traits>::CheckAndRewriteReferenceExpression( 2533 ParserBase<Traits>::CheckAndRewriteReferenceExpression(
2176 ExpressionT expression, 2534 ExpressionT expression,
2177 Scanner::Location location, const char* message, bool* ok) { 2535 Scanner::Location location, const char* message, bool* ok) {
2178 if (strict_mode() == STRICT && this->IsIdentifier(expression) && 2536 if (strict_mode() == STRICT && this->IsIdentifier(expression) &&
2179 this->IsEvalOrArguments(this->AsIdentifier(expression))) { 2537 this->IsEvalOrArguments(this->AsIdentifier(expression))) {
2180 this->ReportMessageAt(location, "strict_eval_arguments", false); 2538 this->ReportMessageAt(location, "strict_eval_arguments", false);
2181 *ok = false; 2539 *ok = false;
2182 return this->EmptyExpression(); 2540 return this->EmptyExpression();
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
2226 parser()->ReportMessage("accessor_get_set"); 2584 parser()->ReportMessage("accessor_get_set");
2227 } 2585 }
2228 *ok = false; 2586 *ok = false;
2229 } 2587 }
2230 } 2588 }
2231 2589
2232 2590
2233 } } // v8::internal 2591 } } // v8::internal
2234 2592
2235 #endif // V8_PREPARSER_H 2593 #endif // V8_PREPARSER_H
OLDNEW
« no previous file with comments | « src/parser.cc ('k') | src/scanner.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698