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

Side by Side Diff: src/preparser.h

Issue 372983003: Revert "Implement handling of arrow functions in the parser" (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: 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;
66 65
67 ParserBase(Scanner* scanner, uintptr_t stack_limit, v8::Extension* extension, 66 ParserBase(Scanner* scanner, uintptr_t stack_limit,
68 ParserRecorder* log, typename Traits::Type::Zone* zone, 67 v8::Extension* extension,
68 ParserRecorder* log,
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),
85 allow_arrow_functions_(false), 86 zone_(zone) { }
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_; }
95 bool allow_modules() const { return scanner()->HarmonyModules(); } 94 bool allow_modules() const { return scanner()->HarmonyModules(); }
96 bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); } 95 bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); }
97 bool allow_harmony_numeric_literals() const { 96 bool allow_harmony_numeric_literals() const {
98 return scanner()->HarmonyNumericLiterals(); 97 return scanner()->HarmonyNumericLiterals();
99 } 98 }
100 99
101 // Setters that determine whether certain syntactical constructs are 100 // Setters that determine whether certain syntactical constructs are
102 // allowed to be parsed by this instance of the parser. 101 // allowed to be parsed by this instance of the parser.
103 void set_allow_lazy(bool allow) { allow_lazy_ = allow; } 102 void set_allow_lazy(bool allow) { allow_lazy_ = allow; }
104 void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; } 103 void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; }
105 void set_allow_generators(bool allow) { allow_generators_ = allow; } 104 void set_allow_generators(bool allow) { allow_generators_ = allow; }
106 void set_allow_for_of(bool allow) { allow_for_of_ = allow; } 105 void set_allow_for_of(bool allow) { allow_for_of_ = allow; }
107 void set_allow_arrow_functions(bool allow) { allow_arrow_functions_ = allow; }
108 void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); } 106 void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); }
109 void set_allow_harmony_scoping(bool allow) { 107 void set_allow_harmony_scoping(bool allow) {
110 scanner()->SetHarmonyScoping(allow); 108 scanner()->SetHarmonyScoping(allow);
111 } 109 }
112 void set_allow_harmony_numeric_literals(bool allow) { 110 void set_allow_harmony_numeric_literals(bool allow) {
113 scanner()->SetHarmonyNumericLiterals(allow); 111 scanner()->SetHarmonyNumericLiterals(allow);
114 } 112 }
115 113
116 protected: 114 protected:
117 enum AllowEvalOrArgumentsAsIdentifier { 115 enum AllowEvalOrArgumentsAsIdentifier {
(...skipping 29 matching lines...) Expand all
147 }; 145 };
148 146
149 class FunctionState BASE_EMBEDDED { 147 class FunctionState BASE_EMBEDDED {
150 public: 148 public:
151 FunctionState( 149 FunctionState(
152 FunctionState** function_state_stack, 150 FunctionState** function_state_stack,
153 typename Traits::Type::Scope** scope_stack, 151 typename Traits::Type::Scope** scope_stack,
154 typename Traits::Type::Scope* scope, 152 typename Traits::Type::Scope* scope,
155 typename Traits::Type::Zone* zone = NULL, 153 typename Traits::Type::Zone* zone = NULL,
156 AstValueFactory* ast_value_factory = NULL); 154 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);
162 ~FunctionState(); 155 ~FunctionState();
163 156
164 int NextMaterializedLiteralIndex() { 157 int NextMaterializedLiteralIndex() {
165 return next_materialized_literal_index_++; 158 return next_materialized_literal_index_++;
166 } 159 }
167 int materialized_literal_count() { 160 int materialized_literal_count() {
168 return next_materialized_literal_index_ - JSFunction::kLiteralsPrefixSize; 161 return next_materialized_literal_index_ - JSFunction::kLiteralsPrefixSize;
169 } 162 }
170 163
171 int NextHandlerIndex() { return next_handler_index_++; } 164 int NextHandlerIndex() { return next_handler_index_++; }
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
441 ExpressionT ParseYieldExpression(bool* ok); 434 ExpressionT ParseYieldExpression(bool* ok);
442 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); 435 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok);
443 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); 436 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok);
444 ExpressionT ParseUnaryExpression(bool* ok); 437 ExpressionT ParseUnaryExpression(bool* ok);
445 ExpressionT ParsePostfixExpression(bool* ok); 438 ExpressionT ParsePostfixExpression(bool* ok);
446 ExpressionT ParseLeftHandSideExpression(bool* ok); 439 ExpressionT ParseLeftHandSideExpression(bool* ok);
447 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); 440 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok);
448 ExpressionT ParseMemberExpression(bool* ok); 441 ExpressionT ParseMemberExpression(bool* ok);
449 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, 442 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression,
450 bool* ok); 443 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);
460 444
461 // Checks if the expression is a valid reference expression (e.g., on the 445 // Checks if the expression is a valid reference expression (e.g., on the
462 // left-hand side of assignments). Although ruled out by ECMA as early errors, 446 // left-hand side of assignments). Although ruled out by ECMA as early errors,
463 // we allow calls for web compatibility and rewrite them to a runtime throw. 447 // we allow calls for web compatibility and rewrite them to a runtime throw.
464 ExpressionT CheckAndRewriteReferenceExpression( 448 ExpressionT CheckAndRewriteReferenceExpression(
465 ExpressionT expression, 449 ExpressionT expression,
466 Scanner::Location location, const char* message, bool* ok); 450 Scanner::Location location, const char* message, bool* ok);
467 451
468 // Used to detect duplicates in object literals. Each of the values 452 // Used to detect duplicates in object literals. Each of the values
469 // kGetterProperty, kSetterProperty and kValueProperty represents 453 // kGetterProperty, kSetterProperty and kValueProperty represents
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
534 518
535 private: 519 private:
536 Scanner* scanner_; 520 Scanner* scanner_;
537 uintptr_t stack_limit_; 521 uintptr_t stack_limit_;
538 bool stack_overflow_; 522 bool stack_overflow_;
539 523
540 bool allow_lazy_; 524 bool allow_lazy_;
541 bool allow_natives_syntax_; 525 bool allow_natives_syntax_;
542 bool allow_generators_; 526 bool allow_generators_;
543 bool allow_for_of_; 527 bool allow_for_of_;
544 bool allow_arrow_functions_;
545 528
546 typename Traits::Type::Zone* zone_; // Only used by Parser. 529 typename Traits::Type::Zone* zone_; // Only used by Parser.
547 }; 530 };
548 531
549 532
550 class PreParserIdentifier { 533 class PreParserIdentifier {
551 public: 534 public:
552 PreParserIdentifier() : type_(kUnknownIdentifier) {} 535 PreParserIdentifier() : type_(kUnknownIdentifier) {}
553 static PreParserIdentifier Default() { 536 static PreParserIdentifier Default() {
554 return PreParserIdentifier(kUnknownIdentifier); 537 return PreParserIdentifier(kUnknownIdentifier);
555 } 538 }
556 static PreParserIdentifier Eval() { 539 static PreParserIdentifier Eval() {
557 return PreParserIdentifier(kEvalIdentifier); 540 return PreParserIdentifier(kEvalIdentifier);
558 } 541 }
559 static PreParserIdentifier Arguments() { 542 static PreParserIdentifier Arguments() {
560 return PreParserIdentifier(kArgumentsIdentifier); 543 return PreParserIdentifier(kArgumentsIdentifier);
561 } 544 }
562 static PreParserIdentifier FutureReserved() { 545 static PreParserIdentifier FutureReserved() {
563 return PreParserIdentifier(kFutureReservedIdentifier); 546 return PreParserIdentifier(kFutureReservedIdentifier);
564 } 547 }
565 static PreParserIdentifier FutureStrictReserved() { 548 static PreParserIdentifier FutureStrictReserved() {
566 return PreParserIdentifier(kFutureStrictReservedIdentifier); 549 return PreParserIdentifier(kFutureStrictReservedIdentifier);
567 } 550 }
568 static PreParserIdentifier Yield() { 551 static PreParserIdentifier Yield() {
569 return PreParserIdentifier(kYieldIdentifier); 552 return PreParserIdentifier(kYieldIdentifier);
570 } 553 }
571 bool IsEval() const { return type_ == kEvalIdentifier; } 554 bool IsEval() { return type_ == kEvalIdentifier; }
572 bool IsArguments() const { return type_ == kArgumentsIdentifier; } 555 bool IsArguments() { return type_ == kArgumentsIdentifier; }
573 bool IsEvalOrArguments() const { return type_ >= kEvalIdentifier; } 556 bool IsEvalOrArguments() { return type_ >= kEvalIdentifier; }
574 bool IsYield() const { return type_ == kYieldIdentifier; } 557 bool IsYield() { return type_ == kYieldIdentifier; }
575 bool IsFutureReserved() const { return type_ == kFutureReservedIdentifier; } 558 bool IsFutureReserved() { return type_ == kFutureReservedIdentifier; }
576 bool IsFutureStrictReserved() const { 559 bool IsFutureStrictReserved() {
577 return type_ == kFutureStrictReservedIdentifier; 560 return type_ == kFutureStrictReservedIdentifier;
578 } 561 }
579 bool IsValidStrictVariable() const { return type_ == kUnknownIdentifier; } 562 bool IsValidStrictVariable() { 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; }
588 563
589 private: 564 private:
590 enum Type { 565 enum Type {
591 kUnknownIdentifier, 566 kUnknownIdentifier,
592 kFutureReservedIdentifier, 567 kFutureReservedIdentifier,
593 kFutureStrictReservedIdentifier, 568 kFutureStrictReservedIdentifier,
594 kYieldIdentifier, 569 kYieldIdentifier,
595 kEvalIdentifier, 570 kEvalIdentifier,
596 kArgumentsIdentifier 571 kArgumentsIdentifier
597 }; 572 };
598 explicit PreParserIdentifier(Type type) : type_(type) {} 573 explicit PreParserIdentifier(Type type) : type_(type) {}
599 Type type_; 574 Type type_;
600 575
601 friend class PreParserExpression; 576 friend class PreParserExpression;
602 friend class PreParserScope;
603 }; 577 };
604 578
605 579
606 // Bits 0 and 1 are used to identify the type of expression: 580 // Bits 0 and 1 are used to identify the type of expression:
607 // If bit 0 is set, it's an identifier. 581 // If bit 0 is set, it's an identifier.
608 // if bit 1 is set, it's a string literal. 582 // if bit 1 is set, it's a string literal.
609 // If neither is set, it's no particular type, and both set isn't 583 // If neither is set, it's no particular type, and both set isn't
610 // use yet. 584 // use yet.
611 class PreParserExpression { 585 class PreParserExpression {
612 public: 586 public:
613 static PreParserExpression Default() { 587 static PreParserExpression Default() {
614 return PreParserExpression(kUnknownExpression); 588 return PreParserExpression(kUnknownExpression);
615 } 589 }
616 590
617 static PreParserExpression FromIdentifier(PreParserIdentifier id) { 591 static PreParserExpression FromIdentifier(PreParserIdentifier id) {
618 return PreParserExpression(kTypeIdentifier | 592 return PreParserExpression(kIdentifierFlag |
619 (id.type_ << kIdentifierShift)); 593 (id.type_ << kIdentifierShift));
620 } 594 }
621 595
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
638 static PreParserExpression StringLiteral() { 596 static PreParserExpression StringLiteral() {
639 return PreParserExpression(kUnknownStringLiteral); 597 return PreParserExpression(kUnknownStringLiteral);
640 } 598 }
641 599
642 static PreParserExpression UseStrictStringLiteral() { 600 static PreParserExpression UseStrictStringLiteral() {
643 return PreParserExpression(kUseStrictString); 601 return PreParserExpression(kUseStrictString);
644 } 602 }
645 603
646 static PreParserExpression This() { 604 static PreParserExpression This() {
647 return PreParserExpression(kThisExpression); 605 return PreParserExpression(kThisExpression);
648 } 606 }
649 607
650 static PreParserExpression ThisProperty() { 608 static PreParserExpression ThisProperty() {
651 return PreParserExpression(kThisPropertyExpression); 609 return PreParserExpression(kThisPropertyExpression);
652 } 610 }
653 611
654 static PreParserExpression Property() { 612 static PreParserExpression Property() {
655 return PreParserExpression(kPropertyExpression); 613 return PreParserExpression(kPropertyExpression);
656 } 614 }
657 615
658 static PreParserExpression Call() { 616 static PreParserExpression Call() {
659 return PreParserExpression(kCallExpression); 617 return PreParserExpression(kCallExpression);
660 } 618 }
661 619
662 bool IsIdentifier() const { return (code_ & kTypeMask) == kTypeIdentifier; } 620 bool IsIdentifier() { return (code_ & kIdentifierFlag) != 0; }
663 621
664 PreParserIdentifier AsIdentifier() const { 622 PreParserIdentifier AsIdentifier() {
665 ASSERT(IsIdentifier()); 623 ASSERT(IsIdentifier());
666 return PreParserIdentifier( 624 return PreParserIdentifier(
667 static_cast<PreParserIdentifier::Type>(code_ >> kIdentifierShift)); 625 static_cast<PreParserIdentifier::Type>(code_ >> kIdentifierShift));
668 } 626 }
669 627
670 bool IsStringLiteral() const { 628 bool IsStringLiteral() { return (code_ & kStringLiteralFlag) != 0; }
671 return (code_ & kTypeMask) == kTypeStringLiteral;
672 }
673 629
674 bool IsUseStrictLiteral() { 630 bool IsUseStrictLiteral() {
675 return (code_ & kUseStrictString) == kUseStrictString; 631 return (code_ & kStringLiteralMask) == kUseStrictString;
676 } 632 }
677 633
678 bool IsThis() { return code_ == kThisExpression; } 634 bool IsThis() { return code_ == kThisExpression; }
679 635
680 bool IsThisProperty() { return code_ == kThisPropertyExpression; } 636 bool IsThisProperty() { return code_ == kThisPropertyExpression; }
681 637
682 bool IsProperty() { 638 bool IsProperty() {
683 return code_ == kPropertyExpression || code_ == kThisPropertyExpression; 639 return code_ == kPropertyExpression || code_ == kThisPropertyExpression;
684 } 640 }
685 641
686 bool IsCall() { return code_ == kCallExpression; } 642 bool IsCall() { return code_ == kCallExpression; }
687 643
688 bool IsValidReferenceExpression() { 644 bool IsValidReferenceExpression() {
689 return IsIdentifier() || IsProperty(); 645 return IsIdentifier() || IsProperty();
690 } 646 }
691 647
692 bool IsValidArrowParamList() const {
693 return (ArrowParamListBit() & kBinaryOperationArrowParamList) != 0 &&
694 (code_ & kMultiParenthesizedExpression) == 0;
695 }
696
697 // At the moment PreParser doesn't track these expression types. 648 // At the moment PreParser doesn't track these expression types.
698 bool IsFunctionLiteral() const { return false; } 649 bool IsFunctionLiteral() const { return false; }
699 bool IsCallNew() const { return false; } 650 bool IsCallNew() const { return false; }
700 651
701 PreParserExpression AsFunctionLiteral() { return *this; } 652 PreParserExpression AsFunctionLiteral() { return *this; }
702 653
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
716 // Dummy implementation for making expression->somefunc() work in both Parser 654 // Dummy implementation for making expression->somefunc() work in both Parser
717 // and PreParser. 655 // and PreParser.
718 PreParserExpression* operator->() { return this; } 656 PreParserExpression* operator->() { return this; }
719 657
720 // More dummy implementations of things PreParser doesn't need to track: 658 // More dummy implementations of things PreParser doesn't need to track:
721 void set_index(int index) {} // For YieldExpressions 659 void set_index(int index) {} // For YieldExpressions
722 void set_parenthesized() {} 660 void set_parenthesized() {}
723 661
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
736 private: 662 private:
737 // Least significant 2 bits are used as expression type. The third least 663 // Least significant 2 bits are used as flags. Bits 0 and 1 represent
738 // significant bit tracks whether an expression is parenthesized. If the 664 // identifiers or strings literals, and are mutually exclusive, but can both
739 // expression is an identifier or a string literal, the other bits 665 // be absent. If the expression is an identifier or a string literal, the
740 // describe the type/ (see PreParserIdentifier::Type and string literal 666 // other bits describe the type (see PreParserIdentifier::Type and string
741 // constants below). For binary operations, the other bits are flags 667 // literal constants below).
742 // which further describe the contents of the expression.
743 enum { 668 enum {
744 kUnknownExpression = 0, 669 kUnknownExpression = 0,
745 kTypeMask = 1 | 2, 670 // Identifiers
746 kParenthesizedExpression = (1 << 2), 671 kIdentifierFlag = 1, // Used to detect labels.
747 kMultiParenthesizedExpression = (1 << 3), 672 kIdentifierShift = 3,
748 673
749 // Identifiers 674 kStringLiteralFlag = 2, // Used to detect directive prologue.
750 kTypeIdentifier = 1, // Used to detect labels. 675 kUnknownStringLiteral = kStringLiteralFlag,
751 kIdentifierShift = 5, 676 kUseStrictString = kStringLiteralFlag | 8,
752 kTypeStringLiteral = 2, // Used to detect directive prologue.
753 kUnknownStringLiteral = kTypeStringLiteral,
754 kUseStrictString = kTypeStringLiteral | 32,
755 kStringLiteralMask = kUseStrictString, 677 kStringLiteralMask = kUseStrictString,
756 678
757 // Binary operations. Those are needed to detect certain keywords and
758 // duplicated identifier in parameter lists for arrow functions, because
759 // they are initially parsed as comma-separated expressions.
760 kTypeBinaryOperation = 3,
761 kBinaryOperationArrowParamList = (1 << 4),
762
763 // Below here applies if neither identifier nor string literal. Reserve the 679 // Below here applies if neither identifier nor string literal. Reserve the
764 // 2 least significant bits for flags. 680 // 2 least significant bits for flags.
765 kThisExpression = (1 << 4), 681 kThisExpression = 1 << 2,
766 kThisPropertyExpression = (2 << 4), 682 kThisPropertyExpression = 2 << 2,
767 kPropertyExpression = (3 << 4), 683 kPropertyExpression = 3 << 2,
768 kCallExpression = (4 << 4) 684 kCallExpression = 4 << 2
769 }; 685 };
770 686
771 explicit PreParserExpression(int expression_code) : code_(expression_code) {} 687 explicit PreParserExpression(int expression_code) : code_(expression_code) {}
772 688
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
787 int code_; 689 int code_;
788 }; 690 };
789 691
790 692
791 // PreParserExpressionList doesn't actually store the expressions because 693 // PreParserExpressionList doesn't actually store the expressions because
792 // PreParser doesn't need to. 694 // PreParser doesn't need to.
793 class PreParserExpressionList { 695 class PreParserExpressionList {
794 public: 696 public:
795 // These functions make list->Add(some_expression) work (and do nothing). 697 // These functions make list->Add(some_expression) work (and do nothing).
796 PreParserExpressionList() : length_(0) {} 698 PreParserExpressionList() : length_(0) {}
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
858 public: 760 public:
859 // These functions make list->Add(some_expression) work as no-ops. 761 // These functions make list->Add(some_expression) work as no-ops.
860 PreParserStatementList() {} 762 PreParserStatementList() {}
861 PreParserStatementList* operator->() { return this; } 763 PreParserStatementList* operator->() { return this; }
862 void Add(PreParserStatement, void*) {} 764 void Add(PreParserStatement, void*) {}
863 }; 765 };
864 766
865 767
866 class PreParserScope { 768 class PreParserScope {
867 public: 769 public:
868 explicit PreParserScope(PreParserScope* outer_scope, ScopeType scope_type, 770 explicit PreParserScope(PreParserScope* outer_scope, ScopeType scope_type)
869 void* = NULL)
870 : scope_type_(scope_type) { 771 : scope_type_(scope_type) {
871 strict_mode_ = outer_scope ? outer_scope->strict_mode() : SLOPPY; 772 strict_mode_ = outer_scope ? outer_scope->strict_mode() : SLOPPY;
872 } 773 }
873 774
874 ScopeType type() { return scope_type_; } 775 ScopeType type() { return scope_type_; }
875 StrictMode strict_mode() const { return strict_mode_; } 776 StrictMode strict_mode() const { return strict_mode_; }
876 void SetStrictMode(StrictMode strict_mode) { strict_mode_ = strict_mode; } 777 void SetStrictMode(StrictMode strict_mode) { strict_mode_ = strict_mode; }
877 778
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
891 private: 779 private:
892 ScopeType scope_type_; 780 ScopeType scope_type_;
893 StrictMode strict_mode_; 781 StrictMode strict_mode_;
894 }; 782 };
895 783
896 784
897 class PreParserFactory { 785 class PreParserFactory {
898 public: 786 public:
899 explicit PreParserFactory(void* extra_param1, void* extra_param2) {} 787 explicit PreParserFactory(void* extra_param1, void* extra_param2) {}
900 PreParserExpression NewStringLiteral(PreParserIdentifier identifier, 788 PreParserExpression NewStringLiteral(PreParserIdentifier identifier,
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
944 return PreParserExpression::Property(); 832 return PreParserExpression::Property();
945 } 833 }
946 PreParserExpression NewUnaryOperation(Token::Value op, 834 PreParserExpression NewUnaryOperation(Token::Value op,
947 PreParserExpression expression, 835 PreParserExpression expression,
948 int pos) { 836 int pos) {
949 return PreParserExpression::Default(); 837 return PreParserExpression::Default();
950 } 838 }
951 PreParserExpression NewBinaryOperation(Token::Value op, 839 PreParserExpression NewBinaryOperation(Token::Value op,
952 PreParserExpression left, 840 PreParserExpression left,
953 PreParserExpression right, int pos) { 841 PreParserExpression right, int pos) {
954 return PreParserExpression::BinaryOperation(left, op, right); 842 return PreParserExpression::Default();
955 } 843 }
956 PreParserExpression NewCompareOperation(Token::Value op, 844 PreParserExpression NewCompareOperation(Token::Value op,
957 PreParserExpression left, 845 PreParserExpression left,
958 PreParserExpression right, int pos) { 846 PreParserExpression right, int pos) {
959 return PreParserExpression::Default(); 847 return PreParserExpression::Default();
960 } 848 }
961 PreParserExpression NewAssignment(Token::Value op, 849 PreParserExpression NewAssignment(Token::Value op,
962 PreParserExpression left, 850 PreParserExpression left,
963 PreParserExpression right, 851 PreParserExpression right,
964 int pos) { 852 int pos) {
(...skipping 20 matching lines...) Expand all
985 PreParserExpression NewCall(PreParserExpression expression, 873 PreParserExpression NewCall(PreParserExpression expression,
986 PreParserExpressionList arguments, 874 PreParserExpressionList arguments,
987 int pos) { 875 int pos) {
988 return PreParserExpression::Call(); 876 return PreParserExpression::Call();
989 } 877 }
990 PreParserExpression NewCallNew(PreParserExpression expression, 878 PreParserExpression NewCallNew(PreParserExpression expression,
991 PreParserExpressionList arguments, 879 PreParserExpressionList arguments,
992 int pos) { 880 int pos) {
993 return PreParserExpression::Default(); 881 return PreParserExpression::Default();
994 } 882 }
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 }
1020 }; 883 };
1021 884
1022 885
1023 class PreParser; 886 class PreParser;
1024 887
1025 class PreParserTraits { 888 class PreParserTraits {
1026 public: 889 public:
1027 struct Type { 890 struct Type {
1028 // TODO(marja): To be removed. The Traits object should contain all the data 891 // TODO(marja): To be removed. The Traits object should contain all the data
1029 // it needs. 892 // it needs.
1030 typedef PreParser* Parser; 893 typedef PreParser* Parser;
1031 894
1032 // Used by FunctionState and BlockState. 895 // Used by FunctionState and BlockState.
1033 typedef PreParserScope Scope; 896 typedef PreParserScope Scope;
1034 typedef PreParserScope ScopePtr;
1035
1036 // PreParser doesn't need to store generator variables. 897 // PreParser doesn't need to store generator variables.
1037 typedef void GeneratorVariable; 898 typedef void GeneratorVariable;
1038 // No interaction with Zones. 899 // No interaction with Zones.
1039 typedef void Zone; 900 typedef void Zone;
1040 901
1041 typedef int AstProperties;
1042 typedef Vector<PreParserIdentifier> ParameterIdentifierVector;
1043
1044 // Return types for traversing functions. 902 // Return types for traversing functions.
1045 typedef PreParserIdentifier Identifier; 903 typedef PreParserIdentifier Identifier;
1046 typedef PreParserExpression Expression; 904 typedef PreParserExpression Expression;
1047 typedef PreParserExpression YieldExpression; 905 typedef PreParserExpression YieldExpression;
1048 typedef PreParserExpression FunctionLiteral; 906 typedef PreParserExpression FunctionLiteral;
1049 typedef PreParserExpression ObjectLiteralProperty; 907 typedef PreParserExpression ObjectLiteralProperty;
1050 typedef PreParserExpression Literal; 908 typedef PreParserExpression Literal;
1051 typedef PreParserExpressionList ExpressionList; 909 typedef PreParserExpressionList ExpressionList;
1052 typedef PreParserExpressionList PropertyList; 910 typedef PreParserExpressionList PropertyList;
1053 typedef PreParserStatementList StatementList; 911 typedef PreParserStatementList StatementList;
(...skipping 22 matching lines...) Expand all
1076 } 934 }
1077 935
1078 static bool IsIdentifier(PreParserExpression expression) { 936 static bool IsIdentifier(PreParserExpression expression) {
1079 return expression.IsIdentifier(); 937 return expression.IsIdentifier();
1080 } 938 }
1081 939
1082 static PreParserIdentifier AsIdentifier(PreParserExpression expression) { 940 static PreParserIdentifier AsIdentifier(PreParserExpression expression) {
1083 return expression.AsIdentifier(); 941 return expression.AsIdentifier();
1084 } 942 }
1085 943
1086 static bool IsFutureStrictReserved(PreParserIdentifier identifier) {
1087 return identifier.IsYield() || identifier.IsFutureStrictReserved();
1088 }
1089
1090 static bool IsBoilerplateProperty(PreParserExpression property) { 944 static bool IsBoilerplateProperty(PreParserExpression property) {
1091 // PreParser doesn't count boilerplate properties. 945 // PreParser doesn't count boilerplate properties.
1092 return false; 946 return false;
1093 } 947 }
1094 948
1095 static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) { 949 static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) {
1096 return false; 950 return false;
1097 } 951 }
1098 952
1099 // Functions for encapsulating the differences between parsing and preparsing; 953 // Functions for encapsulating the differences between parsing and preparsing;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1143 return PreParserExpression::Default(); 997 return PreParserExpression::Default();
1144 } 998 }
1145 PreParserExpression NewThrowSyntaxError( 999 PreParserExpression NewThrowSyntaxError(
1146 const char* type, Handle<Object> arg, int pos) { 1000 const char* type, Handle<Object> arg, int pos) {
1147 return PreParserExpression::Default(); 1001 return PreParserExpression::Default();
1148 } 1002 }
1149 PreParserExpression NewThrowTypeError( 1003 PreParserExpression NewThrowTypeError(
1150 const char* type, Handle<Object> arg, int pos) { 1004 const char* type, Handle<Object> arg, int pos) {
1151 return PreParserExpression::Default(); 1005 return PreParserExpression::Default();
1152 } 1006 }
1153 PreParserScope NewScope(PreParserScope* outer_scope, ScopeType scope_type) {
1154 return PreParserScope(outer_scope, scope_type);
1155 }
1156 1007
1157 // Reporting errors. 1008 // Reporting errors.
1158 void ReportMessageAt(Scanner::Location location, 1009 void ReportMessageAt(Scanner::Location location,
1159 const char* message, 1010 const char* message,
1160 const char* arg = NULL, 1011 const char* arg = NULL,
1161 bool is_reference_error = false); 1012 bool is_reference_error = false);
1162 void ReportMessageAt(int start_pos, 1013 void ReportMessageAt(int start_pos,
1163 int end_pos, 1014 int end_pos,
1164 const char* message, 1015 const char* message,
1165 const char* arg = NULL, 1016 const char* arg = NULL,
1166 bool is_reference_error = false); 1017 bool is_reference_error = false);
1167 1018
1168 // "null" return type creators. 1019 // "null" return type creators.
1169 static PreParserIdentifier EmptyIdentifier() { 1020 static PreParserIdentifier EmptyIdentifier() {
1170 return PreParserIdentifier::Default(); 1021 return PreParserIdentifier::Default();
1171 } 1022 }
1172 static PreParserIdentifier EmptyIdentifierString() {
1173 return PreParserIdentifier::Default();
1174 }
1175 static PreParserExpression EmptyExpression() { 1023 static PreParserExpression EmptyExpression() {
1176 return PreParserExpression::Default(); 1024 return PreParserExpression::Default();
1177 } 1025 }
1178 static PreParserExpression EmptyArrowParamList() {
1179 return PreParserExpression::EmptyArrowParamList();
1180 }
1181 static PreParserExpression EmptyLiteral() { 1026 static PreParserExpression EmptyLiteral() {
1182 return PreParserExpression::Default(); 1027 return PreParserExpression::Default();
1183 } 1028 }
1184 static PreParserExpressionList NullExpressionList() { 1029 static PreParserExpressionList NullExpressionList() {
1185 return PreParserExpressionList(); 1030 return PreParserExpressionList();
1186 } 1031 }
1187 1032
1188 // Odd-ball literal creators. 1033 // Odd-ball literal creators.
1189 static PreParserExpression GetLiteralTheHole(int position, 1034 static PreParserExpression GetLiteralTheHole(int position,
1190 PreParserFactory* factory) { 1035 PreParserFactory* factory) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1224 } 1069 }
1225 1070
1226 static PreParserStatementList NewStatementList(int size, void* zone) { 1071 static PreParserStatementList NewStatementList(int size, void* zone) {
1227 return PreParserStatementList(); 1072 return PreParserStatementList();
1228 } 1073 }
1229 1074
1230 static PreParserExpressionList NewPropertyList(int size, void* zone) { 1075 static PreParserExpressionList NewPropertyList(int size, void* zone) {
1231 return PreParserExpressionList(); 1076 return PreParserExpressionList();
1232 } 1077 }
1233 1078
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
1257 // Temporary glue; these functions will move to ParserBase. 1079 // Temporary glue; these functions will move to ParserBase.
1258 PreParserExpression ParseV8Intrinsic(bool* ok); 1080 PreParserExpression ParseV8Intrinsic(bool* ok);
1259 PreParserExpression ParseFunctionLiteral( 1081 PreParserExpression ParseFunctionLiteral(
1260 PreParserIdentifier name, 1082 PreParserIdentifier name,
1261 Scanner::Location function_name_location, 1083 Scanner::Location function_name_location,
1262 bool name_is_strict_reserved, 1084 bool name_is_strict_reserved,
1263 bool is_generator, 1085 bool is_generator,
1264 int function_token_position, 1086 int function_token_position,
1265 FunctionLiteral::FunctionType type, 1087 FunctionLiteral::FunctionType type,
1266 FunctionLiteral::ArityRestriction arity_restriction, 1088 FunctionLiteral::ArityRestriction arity_restriction,
(...skipping 30 matching lines...) Expand all
1297 PreParser(Scanner* scanner, ParserRecorder* log, uintptr_t stack_limit) 1119 PreParser(Scanner* scanner, ParserRecorder* log, uintptr_t stack_limit)
1298 : ParserBase<PreParserTraits>(scanner, stack_limit, NULL, log, NULL, 1120 : ParserBase<PreParserTraits>(scanner, stack_limit, NULL, log, NULL,
1299 this) {} 1121 this) {}
1300 1122
1301 // Pre-parse the program from the character stream; returns true on 1123 // Pre-parse the program from the character stream; returns true on
1302 // success (even if parsing failed, the pre-parse data successfully 1124 // success (even if parsing failed, the pre-parse data successfully
1303 // captured the syntax error), and false if a stack-overflow happened 1125 // captured the syntax error), and false if a stack-overflow happened
1304 // during parsing. 1126 // during parsing.
1305 PreParseResult PreParseProgram() { 1127 PreParseResult PreParseProgram() {
1306 PreParserScope scope(scope_, GLOBAL_SCOPE); 1128 PreParserScope scope(scope_, GLOBAL_SCOPE);
1307 FunctionState top_scope(&function_state_, &scope_, &scope); 1129 FunctionState top_scope(&function_state_, &scope_, &scope, NULL);
1308 bool ok = true; 1130 bool ok = true;
1309 int start_position = scanner()->peek_location().beg_pos; 1131 int start_position = scanner()->peek_location().beg_pos;
1310 ParseSourceElements(Token::EOS, &ok); 1132 ParseSourceElements(Token::EOS, &ok);
1311 if (stack_overflow()) return kPreParseStackOverflow; 1133 if (stack_overflow()) return kPreParseStackOverflow;
1312 if (!ok) { 1134 if (!ok) {
1313 ReportUnexpectedToken(scanner()->current_token()); 1135 ReportUnexpectedToken(scanner()->current_token());
1314 } else if (scope_->strict_mode() == STRICT) { 1136 } else if (scope_->strict_mode() == STRICT) {
1315 CheckOctalLiteral(start_position, scanner()->location().end_pos, &ok); 1137 CheckOctalLiteral(start_position, scanner()->location().end_pos, &ok);
1316 } 1138 }
1317 return kPreParseSuccess; 1139 return kPreParseSuccess;
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1379 Statement ParseDoWhileStatement(bool* ok); 1201 Statement ParseDoWhileStatement(bool* ok);
1380 Statement ParseWhileStatement(bool* ok); 1202 Statement ParseWhileStatement(bool* ok);
1381 Statement ParseForStatement(bool* ok); 1203 Statement ParseForStatement(bool* ok);
1382 Statement ParseThrowStatement(bool* ok); 1204 Statement ParseThrowStatement(bool* ok);
1383 Statement ParseTryStatement(bool* ok); 1205 Statement ParseTryStatement(bool* ok);
1384 Statement ParseDebuggerStatement(bool* ok); 1206 Statement ParseDebuggerStatement(bool* ok);
1385 Expression ParseConditionalExpression(bool accept_IN, bool* ok); 1207 Expression ParseConditionalExpression(bool accept_IN, bool* ok);
1386 Expression ParseObjectLiteral(bool* ok); 1208 Expression ParseObjectLiteral(bool* ok);
1387 Expression ParseV8Intrinsic(bool* ok); 1209 Expression ParseV8Intrinsic(bool* ok);
1388 1210
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
1397 Expression ParseFunctionLiteral( 1211 Expression ParseFunctionLiteral(
1398 Identifier name, 1212 Identifier name,
1399 Scanner::Location function_name_location, 1213 Scanner::Location function_name_location,
1400 bool name_is_strict_reserved, 1214 bool name_is_strict_reserved,
1401 bool is_generator, 1215 bool is_generator,
1402 int function_token_pos, 1216 int function_token_pos,
1403 FunctionLiteral::FunctionType function_type, 1217 FunctionLiteral::FunctionType function_type,
1404 FunctionLiteral::ArityRestriction arity_restriction, 1218 FunctionLiteral::ArityRestriction arity_restriction,
1405 bool* ok); 1219 bool* ok);
1406 void ParseLazyFunctionLiteralBody(bool* ok); 1220 void ParseLazyFunctionLiteralBody(bool* ok);
1407 1221
1408 bool CheckInOrOf(bool accept_OF); 1222 bool CheckInOrOf(bool accept_OF);
1409 }; 1223 };
1410 1224
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
1433 template<class Traits> 1225 template<class Traits>
1434 ParserBase<Traits>::FunctionState::FunctionState( 1226 ParserBase<Traits>::FunctionState::FunctionState(
1435 FunctionState** function_state_stack, 1227 FunctionState** function_state_stack,
1436 typename Traits::Type::Scope** scope_stack, 1228 typename Traits::Type::Scope** scope_stack,
1437 typename Traits::Type::Scope* scope, 1229 typename Traits::Type::Scope* scope,
1438 typename Traits::Type::Zone* extra_param, 1230 typename Traits::Type::Zone* extra_param,
1439 AstValueFactory* ast_value_factory) 1231 AstValueFactory* ast_value_factory)
1440 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize), 1232 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize),
1441 next_handler_index_(0), 1233 next_handler_index_(0),
1442 expected_property_count_(0), 1234 expected_property_count_(0),
1443 is_generator_(false), 1235 is_generator_(false),
1444 generator_object_variable_(NULL), 1236 generator_object_variable_(NULL),
1445 function_state_stack_(function_state_stack), 1237 function_state_stack_(function_state_stack),
1446 outer_function_state_(*function_state_stack), 1238 outer_function_state_(*function_state_stack),
1447 scope_stack_(scope_stack), 1239 scope_stack_(scope_stack),
1448 outer_scope_(*scope_stack), 1240 outer_scope_(*scope_stack),
1449 saved_ast_node_id_(0), 1241 saved_ast_node_id_(0),
1450 extra_param_(extra_param), 1242 extra_param_(extra_param),
1451 factory_(extra_param, ast_value_factory) { 1243 factory_(extra_param, ast_value_factory) {
1452 *scope_stack_ = scope; 1244 *scope_stack_ = scope;
1453 *function_state_stack = this; 1245 *function_state_stack = this;
1454 Traits::SetUpFunctionState(this, extra_param); 1246 Traits::SetUpFunctionState(this, extra_param);
1455 } 1247 }
1456 1248
1457 1249
1458 template <class Traits> 1250 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>
1484 ParserBase<Traits>::FunctionState::~FunctionState() { 1251 ParserBase<Traits>::FunctionState::~FunctionState() {
1485 *scope_stack_ = outer_scope_; 1252 *scope_stack_ = outer_scope_;
1486 *function_state_stack_ = outer_function_state_; 1253 *function_state_stack_ = outer_function_state_;
1487 Traits::TearDownFunctionState(this, extra_param_); 1254 Traits::TearDownFunctionState(this, extra_param_);
1488 } 1255 }
1489 1256
1490 1257
1491 template<class Traits> 1258 template<class Traits>
1492 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) { 1259 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) {
1493 Scanner::Location source_location = scanner()->location(); 1260 Scanner::Location source_location = scanner()->location();
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
1685 case Token::LBRACK: 1452 case Token::LBRACK:
1686 result = this->ParseArrayLiteral(CHECK_OK); 1453 result = this->ParseArrayLiteral(CHECK_OK);
1687 break; 1454 break;
1688 1455
1689 case Token::LBRACE: 1456 case Token::LBRACE:
1690 result = this->ParseObjectLiteral(CHECK_OK); 1457 result = this->ParseObjectLiteral(CHECK_OK);
1691 break; 1458 break;
1692 1459
1693 case Token::LPAREN: 1460 case Token::LPAREN:
1694 Consume(Token::LPAREN); 1461 Consume(Token::LPAREN);
1695 if (allow_arrow_functions() && peek() == Token::RPAREN) { 1462 // Heuristically try to detect immediately called functions before
1696 // Arrow functions are the only expression type constructions 1463 // seeing the call parentheses.
1697 // for which an empty parameter list "()" is valid input. 1464 parenthesized_function_ = (peek() == Token::FUNCTION);
1698 Consume(Token::RPAREN); 1465 result = this->ParseExpression(true, CHECK_OK);
1699 return this->ParseArrowFunctionLiteral(pos, this->EmptyArrowParamList(), 1466 Expect(Token::RPAREN, CHECK_OK);
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 }
1709 break; 1467 break;
1710 1468
1711 case Token::MOD: 1469 case Token::MOD:
1712 if (allow_natives_syntax() || extension_ != NULL) { 1470 if (allow_natives_syntax() || extension_ != NULL) {
1713 result = this->ParseV8Intrinsic(CHECK_OK); 1471 result = this->ParseV8Intrinsic(CHECK_OK);
1714 break; 1472 break;
1715 } 1473 }
1716 // If we're not allowing special syntax we fall-through to the 1474 // If we're not allowing special syntax we fall-through to the
1717 // default case. 1475 // default case.
1718 1476
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
1966 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList)); 1724 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList));
1967 return result; 1725 return result;
1968 } 1726 }
1969 1727
1970 // Precedence = 2 1728 // Precedence = 2
1971 template <class Traits> 1729 template <class Traits>
1972 typename ParserBase<Traits>::ExpressionT 1730 typename ParserBase<Traits>::ExpressionT
1973 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) { 1731 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) {
1974 // AssignmentExpression :: 1732 // AssignmentExpression ::
1975 // ConditionalExpression 1733 // ConditionalExpression
1976 // ArrowFunction
1977 // YieldExpression 1734 // YieldExpression
1978 // LeftHandSideExpression AssignmentOperator AssignmentExpression 1735 // LeftHandSideExpression AssignmentOperator AssignmentExpression
1979 1736
1980 Scanner::Location lhs_location = scanner()->peek_location(); 1737 Scanner::Location lhs_location = scanner()->peek_location();
1981 1738
1982 if (peek() == Token::YIELD && is_generator()) { 1739 if (peek() == Token::YIELD && is_generator()) {
1983 return this->ParseYieldExpression(ok); 1740 return this->ParseYieldExpression(ok);
1984 } 1741 }
1985 1742
1986 if (fni_ != NULL) fni_->Enter(); 1743 if (fni_ != NULL) fni_->Enter();
1987 ExpressionT expression = 1744 ExpressionT expression =
1988 this->ParseConditionalExpression(accept_IN, CHECK_OK); 1745 this->ParseConditionalExpression(accept_IN, CHECK_OK);
1989 1746
1990 if (allow_arrow_functions() && peek() == Token::ARROW)
1991 return this->ParseArrowFunctionLiteral(lhs_location.beg_pos, expression,
1992 CHECK_OK);
1993
1994 if (!Token::IsAssignmentOp(peek())) { 1747 if (!Token::IsAssignmentOp(peek())) {
1995 if (fni_ != NULL) fni_->Leave(); 1748 if (fni_ != NULL) fni_->Leave();
1996 // Parsed conditional expression only (no assignment). 1749 // Parsed conditional expression only (no assignment).
1997 return expression; 1750 return expression;
1998 } 1751 }
1999 1752
2000 expression = this->CheckAndRewriteReferenceExpression( 1753 expression = this->CheckAndRewriteReferenceExpression(
2001 expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK); 1754 expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK);
2002 expression = this->MarkExpressionAsAssigned(expression); 1755 expression = this->MarkExpressionAsAssigned(expression);
2003 1756
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after
2410 } 2163 }
2411 default: 2164 default:
2412 return expression; 2165 return expression;
2413 } 2166 }
2414 } 2167 }
2415 ASSERT(false); 2168 ASSERT(false);
2416 return this->EmptyExpression(); 2169 return this->EmptyExpression();
2417 } 2170 }
2418 2171
2419 2172
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
2531 template <typename Traits> 2173 template <typename Traits>
2532 typename ParserBase<Traits>::ExpressionT 2174 typename ParserBase<Traits>::ExpressionT
2533 ParserBase<Traits>::CheckAndRewriteReferenceExpression( 2175 ParserBase<Traits>::CheckAndRewriteReferenceExpression(
2534 ExpressionT expression, 2176 ExpressionT expression,
2535 Scanner::Location location, const char* message, bool* ok) { 2177 Scanner::Location location, const char* message, bool* ok) {
2536 if (strict_mode() == STRICT && this->IsIdentifier(expression) && 2178 if (strict_mode() == STRICT && this->IsIdentifier(expression) &&
2537 this->IsEvalOrArguments(this->AsIdentifier(expression))) { 2179 this->IsEvalOrArguments(this->AsIdentifier(expression))) {
2538 this->ReportMessageAt(location, "strict_eval_arguments", false); 2180 this->ReportMessageAt(location, "strict_eval_arguments", false);
2539 *ok = false; 2181 *ok = false;
2540 return this->EmptyExpression(); 2182 return this->EmptyExpression();
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
2584 parser()->ReportMessage("accessor_get_set"); 2226 parser()->ReportMessage("accessor_get_set");
2585 } 2227 }
2586 *ok = false; 2228 *ok = false;
2587 } 2229 }
2588 } 2230 }
2589 2231
2590 2232
2591 } } // v8::internal 2233 } } // v8::internal
2592 2234
2593 #endif // V8_PREPARSER_H 2235 #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