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

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: Same, plus a rebase and conflicts resolved 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
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,
67 v8::Extension* extension, 68 v8::Extension* extension,
68 ParserRecorder* log, 69 ParserRecorder* log,
69 typename Traits::Type::Zone* zone, 70 typename Traits::Type::Zone* zone,
70 typename Traits::Type::Parser this_object) 71 typename Traits::Type::Parser this_object)
71 : Traits(this_object), 72 : Traits(this_object),
72 parenthesized_function_(false), 73 parenthesized_function_(false),
73 scope_(NULL), 74 scope_(NULL),
74 function_state_(NULL), 75 function_state_(NULL),
75 extension_(extension), 76 extension_(extension),
76 fni_(NULL), 77 fni_(NULL),
77 log_(log), 78 log_(log),
78 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly. 79 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly.
79 scanner_(scanner), 80 scanner_(scanner),
80 stack_limit_(stack_limit), 81 stack_limit_(stack_limit),
81 stack_overflow_(false), 82 stack_overflow_(false),
82 allow_lazy_(false), 83 allow_lazy_(false),
83 allow_natives_syntax_(false), 84 allow_natives_syntax_(false),
84 allow_generators_(false), 85 allow_generators_(false),
85 allow_for_of_(false), 86 allow_for_of_(false),
87 allow_arrow_functions_(false),
86 zone_(zone) { } 88 zone_(zone) { }
87 89
88 // Getters that indicate whether certain syntactical constructs are 90 // Getters that indicate whether certain syntactical constructs are
89 // allowed to be parsed by this instance of the parser. 91 // allowed to be parsed by this instance of the parser.
90 bool allow_lazy() const { return allow_lazy_; } 92 bool allow_lazy() const { return allow_lazy_; }
91 bool allow_natives_syntax() const { return allow_natives_syntax_; } 93 bool allow_natives_syntax() const { return allow_natives_syntax_; }
92 bool allow_generators() const { return allow_generators_; } 94 bool allow_generators() const { return allow_generators_; }
93 bool allow_for_of() const { return allow_for_of_; } 95 bool allow_for_of() const { return allow_for_of_; }
96 bool allow_arrow_functions() const { return allow_arrow_functions_; }
94 bool allow_modules() const { return scanner()->HarmonyModules(); } 97 bool allow_modules() const { return scanner()->HarmonyModules(); }
95 bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); } 98 bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); }
96 bool allow_harmony_numeric_literals() const { 99 bool allow_harmony_numeric_literals() const {
97 return scanner()->HarmonyNumericLiterals(); 100 return scanner()->HarmonyNumericLiterals();
98 } 101 }
99 102
100 // Setters that determine whether certain syntactical constructs are 103 // Setters that determine whether certain syntactical constructs are
101 // allowed to be parsed by this instance of the parser. 104 // allowed to be parsed by this instance of the parser.
102 void set_allow_lazy(bool allow) { allow_lazy_ = allow; } 105 void set_allow_lazy(bool allow) { allow_lazy_ = allow; }
103 void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; } 106 void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; }
104 void set_allow_generators(bool allow) { allow_generators_ = allow; } 107 void set_allow_generators(bool allow) { allow_generators_ = allow; }
105 void set_allow_for_of(bool allow) { allow_for_of_ = allow; } 108 void set_allow_for_of(bool allow) { allow_for_of_ = allow; }
109 void set_allow_arrow_functions(bool allow) { allow_arrow_functions_ = allow; }
106 void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); } 110 void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); }
107 void set_allow_harmony_scoping(bool allow) { 111 void set_allow_harmony_scoping(bool allow) {
108 scanner()->SetHarmonyScoping(allow); 112 scanner()->SetHarmonyScoping(allow);
109 } 113 }
110 void set_allow_harmony_numeric_literals(bool allow) { 114 void set_allow_harmony_numeric_literals(bool allow) {
111 scanner()->SetHarmonyNumericLiterals(allow); 115 scanner()->SetHarmonyNumericLiterals(allow);
112 } 116 }
113 117
114 protected: 118 protected:
115 enum AllowEvalOrArgumentsAsIdentifier { 119 enum AllowEvalOrArgumentsAsIdentifier {
(...skipping 29 matching lines...) Expand all
145 }; 149 };
146 150
147 class FunctionState BASE_EMBEDDED { 151 class FunctionState BASE_EMBEDDED {
148 public: 152 public:
149 FunctionState( 153 FunctionState(
150 FunctionState** function_state_stack, 154 FunctionState** function_state_stack,
151 typename Traits::Type::Scope** scope_stack, 155 typename Traits::Type::Scope** scope_stack,
152 typename Traits::Type::Scope* scope, 156 typename Traits::Type::Scope* scope,
153 typename Traits::Type::Zone* zone = NULL, 157 typename Traits::Type::Zone* zone = NULL,
154 AstValueFactory* ast_value_factory = NULL); 158 AstValueFactory* ast_value_factory = NULL);
159 FunctionState(
160 FunctionState** function_state_stack,
161 typename Traits::Type::Scope** scope_stack,
162 typename Traits::Type::Scope** scope,
163 typename Traits::Type::Zone* zone = NULL,
164 AstValueFactory* ast_value_factory = NULL);
155 ~FunctionState(); 165 ~FunctionState();
156 166
157 int NextMaterializedLiteralIndex() { 167 int NextMaterializedLiteralIndex() {
158 return next_materialized_literal_index_++; 168 return next_materialized_literal_index_++;
159 } 169 }
160 int materialized_literal_count() { 170 int materialized_literal_count() {
161 return next_materialized_literal_index_ - JSFunction::kLiteralsPrefixSize; 171 return next_materialized_literal_index_ - JSFunction::kLiteralsPrefixSize;
162 } 172 }
163 173
164 int NextHandlerIndex() { return next_handler_index_++; } 174 int NextHandlerIndex() { return next_handler_index_++; }
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
435 ExpressionT ParseYieldExpression(bool* ok); 445 ExpressionT ParseYieldExpression(bool* ok);
436 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); 446 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok);
437 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); 447 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok);
438 ExpressionT ParseUnaryExpression(bool* ok); 448 ExpressionT ParseUnaryExpression(bool* ok);
439 ExpressionT ParsePostfixExpression(bool* ok); 449 ExpressionT ParsePostfixExpression(bool* ok);
440 ExpressionT ParseLeftHandSideExpression(bool* ok); 450 ExpressionT ParseLeftHandSideExpression(bool* ok);
441 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); 451 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok);
442 ExpressionT ParseMemberExpression(bool* ok); 452 ExpressionT ParseMemberExpression(bool* ok);
443 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, 453 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression,
444 bool* ok); 454 bool* ok);
455 ExpressionT ParseArrowFunctionLiteral(int start_pos,
456 ExpressionT params_ast,
457 bool* ok);
458 ExpressionT ParseArrowFunctionLiteralBody(
459 FunctionState* function_state,
460 typename Traits::Type::ScopePtr scope,
461 int num_parameters,
462 const Scanner::Location& eval_args_error_loc,
463 const Scanner::Location& dupe_error_loc,
464 const Scanner::Location& reserved_loc,
465 FunctionLiteral::IsParenthesizedFlag parenthesized,
466 int start_pos,
467 bool* ok);
445 468
446 // Checks if the expression is a valid reference expression (e.g., on the 469 // Checks if the expression is a valid reference expression (e.g., on the
447 // left-hand side of assignments). Although ruled out by ECMA as early errors, 470 // left-hand side of assignments). Although ruled out by ECMA as early errors,
448 // we allow calls for web compatibility and rewrite them to a runtime throw. 471 // we allow calls for web compatibility and rewrite them to a runtime throw.
449 ExpressionT CheckAndRewriteReferenceExpression( 472 ExpressionT CheckAndRewriteReferenceExpression(
450 ExpressionT expression, 473 ExpressionT expression,
451 Scanner::Location location, const char* message, bool* ok); 474 Scanner::Location location, const char* message, bool* ok);
452 475
453 // Used to detect duplicates in object literals. Each of the values 476 // Used to detect duplicates in object literals. Each of the values
454 // kGetterProperty, kSetterProperty and kValueProperty represents 477 // kGetterProperty, kSetterProperty and kValueProperty represents
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
519 542
520 private: 543 private:
521 Scanner* scanner_; 544 Scanner* scanner_;
522 uintptr_t stack_limit_; 545 uintptr_t stack_limit_;
523 bool stack_overflow_; 546 bool stack_overflow_;
524 547
525 bool allow_lazy_; 548 bool allow_lazy_;
526 bool allow_natives_syntax_; 549 bool allow_natives_syntax_;
527 bool allow_generators_; 550 bool allow_generators_;
528 bool allow_for_of_; 551 bool allow_for_of_;
552 bool allow_arrow_functions_;
529 553
530 typename Traits::Type::Zone* zone_; // Only used by Parser. 554 typename Traits::Type::Zone* zone_; // Only used by Parser.
531 }; 555 };
532 556
533 557
534 class PreParserIdentifier { 558 class PreParserIdentifier {
535 public: 559 public:
536 PreParserIdentifier() : type_(kUnknownIdentifier) {} 560 PreParserIdentifier() : type_(kUnknownIdentifier) {}
537 static PreParserIdentifier Default() { 561 static PreParserIdentifier Default() {
538 return PreParserIdentifier(kUnknownIdentifier); 562 return PreParserIdentifier(kUnknownIdentifier);
539 } 563 }
540 static PreParserIdentifier Eval() { 564 static PreParserIdentifier Eval() {
541 return PreParserIdentifier(kEvalIdentifier); 565 return PreParserIdentifier(kEvalIdentifier);
542 } 566 }
543 static PreParserIdentifier Arguments() { 567 static PreParserIdentifier Arguments() {
544 return PreParserIdentifier(kArgumentsIdentifier); 568 return PreParserIdentifier(kArgumentsIdentifier);
545 } 569 }
546 static PreParserIdentifier FutureReserved() { 570 static PreParserIdentifier FutureReserved() {
547 return PreParserIdentifier(kFutureReservedIdentifier); 571 return PreParserIdentifier(kFutureReservedIdentifier);
548 } 572 }
549 static PreParserIdentifier FutureStrictReserved() { 573 static PreParserIdentifier FutureStrictReserved() {
550 return PreParserIdentifier(kFutureStrictReservedIdentifier); 574 return PreParserIdentifier(kFutureStrictReservedIdentifier);
551 } 575 }
552 static PreParserIdentifier Yield() { 576 static PreParserIdentifier Yield() {
553 return PreParserIdentifier(kYieldIdentifier); 577 return PreParserIdentifier(kYieldIdentifier);
554 } 578 }
555 bool IsEval() { return type_ == kEvalIdentifier; } 579 bool IsEval() const { return type_ == kEvalIdentifier; }
556 bool IsArguments() { return type_ == kArgumentsIdentifier; } 580 bool IsArguments() const { return type_ == kArgumentsIdentifier; }
557 bool IsEvalOrArguments() { return type_ >= kEvalIdentifier; } 581 bool IsEvalOrArguments() const { return type_ >= kEvalIdentifier; }
558 bool IsYield() { return type_ == kYieldIdentifier; } 582 bool IsYield() const { return type_ == kYieldIdentifier; }
559 bool IsFutureReserved() { return type_ == kFutureReservedIdentifier; } 583 bool IsFutureReserved() const { return type_ == kFutureReservedIdentifier; }
560 bool IsFutureStrictReserved() { 584 bool IsFutureStrictReserved() const {
561 return type_ == kFutureStrictReservedIdentifier; 585 return type_ == kFutureStrictReservedIdentifier;
562 } 586 }
563 bool IsValidStrictVariable() { return type_ == kUnknownIdentifier; } 587 bool IsValidStrictVariable() const { return type_ == kUnknownIdentifier; }
588
589 // Allow identifier->name()[->length()] to work. The preparser
590 // does not need the actual positions/lengths of the identifiers.
591 const PreParserIdentifier* operator->() const { return this; }
592 const PreParserIdentifier raw_name() const { return *this; }
593
594 int position() const { return 0; }
595 int length() const { return 0; }
564 596
565 private: 597 private:
566 enum Type { 598 enum Type {
567 kUnknownIdentifier, 599 kUnknownIdentifier,
568 kFutureReservedIdentifier, 600 kFutureReservedIdentifier,
569 kFutureStrictReservedIdentifier, 601 kFutureStrictReservedIdentifier,
570 kYieldIdentifier, 602 kYieldIdentifier,
571 kEvalIdentifier, 603 kEvalIdentifier,
572 kArgumentsIdentifier 604 kArgumentsIdentifier
573 }; 605 };
574 explicit PreParserIdentifier(Type type) : type_(type) {} 606 explicit PreParserIdentifier(Type type) : type_(type) {}
575 Type type_; 607 Type type_;
576 608
577 friend class PreParserExpression; 609 friend class PreParserExpression;
610 friend class PreParserScope;
578 }; 611 };
579 612
580 613
581 // Bits 0 and 1 are used to identify the type of expression: 614 // Bits 0 and 1 are used to identify the type of expression:
582 // If bit 0 is set, it's an identifier. 615 // If bit 0 is set, it's an identifier.
583 // if bit 1 is set, it's a string literal. 616 // if bit 1 is set, it's a string literal.
584 // If neither is set, it's no particular type, and both set isn't 617 // If neither is set, it's no particular type, and both set isn't
585 // use yet. 618 // use yet.
586 class PreParserExpression { 619 class PreParserExpression {
587 public: 620 public:
588 static PreParserExpression Default() { 621 static PreParserExpression Default() {
589 return PreParserExpression(kUnknownExpression); 622 return PreParserExpression(kUnknownExpression);
590 } 623 }
591 624
592 static PreParserExpression FromIdentifier(PreParserIdentifier id) { 625 static PreParserExpression FromIdentifier(PreParserIdentifier id) {
593 return PreParserExpression(kIdentifierFlag | 626 return PreParserExpression(kTypeIdentifier |
594 (id.type_ << kIdentifierShift)); 627 (id.type_ << kIdentifierShift));
595 } 628 }
596 629
630 static PreParserExpression BinaryOperation(PreParserExpression left,
631 Token::Value op,
632 PreParserExpression right) {
633 int code = ((op == Token::COMMA) &&
634 !left.is_parenthesized() &&
635 !right.is_parenthesized())
636 ? left.ArrowParamListBit() & right.ArrowParamListBit() : 0;
637 return PreParserExpression(kTypeBinaryOperation | code);
638 }
639
640 static PreParserExpression EmptyArrowParamList() {
641 // Any expression for which IsValidArrowParamList() returns true
642 // will work here.
643 return FromIdentifier(PreParserIdentifier::Default());
644 }
645
597 static PreParserExpression StringLiteral() { 646 static PreParserExpression StringLiteral() {
598 return PreParserExpression(kUnknownStringLiteral); 647 return PreParserExpression(kUnknownStringLiteral);
599 } 648 }
600 649
601 static PreParserExpression UseStrictStringLiteral() { 650 static PreParserExpression UseStrictStringLiteral() {
602 return PreParserExpression(kUseStrictString); 651 return PreParserExpression(kUseStrictString);
603 } 652 }
604 653
605 static PreParserExpression This() { 654 static PreParserExpression This() {
606 return PreParserExpression(kThisExpression); 655 return PreParserExpression(kThisExpression);
607 } 656 }
608 657
609 static PreParserExpression ThisProperty() { 658 static PreParserExpression ThisProperty() {
610 return PreParserExpression(kThisPropertyExpression); 659 return PreParserExpression(kThisPropertyExpression);
611 } 660 }
612 661
613 static PreParserExpression Property() { 662 static PreParserExpression Property() {
614 return PreParserExpression(kPropertyExpression); 663 return PreParserExpression(kPropertyExpression);
615 } 664 }
616 665
617 static PreParserExpression Call() { 666 static PreParserExpression Call() {
618 return PreParserExpression(kCallExpression); 667 return PreParserExpression(kCallExpression);
619 } 668 }
620 669
621 bool IsIdentifier() { return (code_ & kIdentifierFlag) != 0; } 670 bool IsIdentifier() const {
671 return (code_ & kTypeMask) == kTypeIdentifier;
672 }
622 673
623 PreParserIdentifier AsIdentifier() { 674 PreParserIdentifier AsIdentifier() const {
624 ASSERT(IsIdentifier()); 675 ASSERT(IsIdentifier());
625 return PreParserIdentifier( 676 return PreParserIdentifier(
626 static_cast<PreParserIdentifier::Type>(code_ >> kIdentifierShift)); 677 static_cast<PreParserIdentifier::Type>(code_ >> kIdentifierShift));
627 } 678 }
628 679
629 bool IsStringLiteral() { return (code_ & kStringLiteralFlag) != 0; } 680 bool IsStringLiteral() const {
681 return (code_ & kTypeMask) == kTypeStringLiteral;
682 }
630 683
631 bool IsUseStrictLiteral() { 684 bool IsUseStrictLiteral() {
632 return (code_ & kStringLiteralMask) == kUseStrictString; 685 return (code_ & kUseStrictString) == kUseStrictString;
633 } 686 }
634 687
635 bool IsThis() { return code_ == kThisExpression; } 688 bool IsThis() { return code_ == kThisExpression; }
636 689
637 bool IsThisProperty() { return code_ == kThisPropertyExpression; } 690 bool IsThisProperty() { return code_ == kThisPropertyExpression; }
638 691
639 bool IsProperty() { 692 bool IsProperty() {
640 return code_ == kPropertyExpression || code_ == kThisPropertyExpression; 693 return code_ == kPropertyExpression || code_ == kThisPropertyExpression;
641 } 694 }
642 695
643 bool IsCall() { return code_ == kCallExpression; } 696 bool IsCall() { return code_ == kCallExpression; }
644 697
645 bool IsValidReferenceExpression() { 698 bool IsValidReferenceExpression() {
646 return IsIdentifier() || IsProperty(); 699 return IsIdentifier() || IsProperty();
647 } 700 }
648 701
702 bool IsValidArrowParamList() const {
703 return (ArrowParamListBit() & kBinaryOperationArrowParamList) != 0
704 && (code_ & kMultiParenthesizedExpression) == 0;
705 }
706
649 // At the moment PreParser doesn't track these expression types. 707 // At the moment PreParser doesn't track these expression types.
650 bool IsFunctionLiteral() const { return false; } 708 bool IsFunctionLiteral() const { return false; }
651 bool IsCallNew() const { return false; } 709 bool IsCallNew() const { return false; }
652 710
653 PreParserExpression AsFunctionLiteral() { return *this; } 711 PreParserExpression AsFunctionLiteral() { return *this; }
654 712
713 bool IsBinaryOperation() const {
714 return (code_ & kTypeMask) == kTypeBinaryOperation;
715 }
716
717 bool is_parenthesized() const {
718 return (code_ & kParenthesizedExpression) != 0;
719 }
720
721 void increase_parenthesization_level() {
722 code_ |= is_parenthesized()
723 ? kMultiParenthesizedExpression
724 : kParenthesizedExpression;
725 }
726
655 // Dummy implementation for making expression->somefunc() work in both Parser 727 // Dummy implementation for making expression->somefunc() work in both Parser
656 // and PreParser. 728 // and PreParser.
657 PreParserExpression* operator->() { return this; } 729 PreParserExpression* operator->() { return this; }
658 730
659 // More dummy implementations of things PreParser doesn't need to track: 731 // More dummy implementations of things PreParser doesn't need to track:
660 void set_index(int index) {} // For YieldExpressions 732 void set_index(int index) {} // For YieldExpressions
661 void set_parenthesized() {} 733 void set_parenthesized() {}
662 734
735 int position() const { return RelocInfo::kNoPosition; }
736 void set_function_token_position(int position) {}
737 void set_ast_properties(int* ast_properties) {}
738 void set_dont_optimize_reason(BailoutReason dont_optimize_reason) {}
739
740 bool operator==(const PreParserExpression& other) const {
741 return code_ == other.code_;
742 }
743 bool operator!=(const PreParserExpression& other) const {
744 return code_ != other.code_;
745 }
746
663 private: 747 private:
664 // Least significant 2 bits are used as flags. Bits 0 and 1 represent 748 // Least significant 2 bits are used as expression type. The third least
665 // identifiers or strings literals, and are mutually exclusive, but can both 749 // significant bit tracks whether an expression is parenthesized. If the
666 // be absent. If the expression is an identifier or a string literal, the 750 // expression is an identifier or a string literal, the other bits
667 // other bits describe the type (see PreParserIdentifier::Type and string 751 // describe the type/ (see PreParserIdentifier::Type and string literal
668 // literal constants below). 752 // constants below). For binary operations, the other bits are flags
753 // which further describe the contents of the expression.
669 enum { 754 enum {
670 kUnknownExpression = 0, 755 kUnknownExpression = 0,
756
757 kTypeMask = 1 | 2,
758 kParenthesizedExpression = (1 << 2),
759 kMultiParenthesizedExpression = (1 << 3),
760
671 // Identifiers 761 // Identifiers
672 kIdentifierFlag = 1, // Used to detect labels. 762 kTypeIdentifier = 1, // Used to detect labels.
673 kIdentifierShift = 3, 763 kIdentifierShift = 5,
674 764
675 kStringLiteralFlag = 2, // Used to detect directive prologue. 765 kTypeStringLiteral = 2, // Used to detect directive prologue.
676 kUnknownStringLiteral = kStringLiteralFlag, 766 kUnknownStringLiteral = kTypeStringLiteral,
677 kUseStrictString = kStringLiteralFlag | 8, 767 kUseStrictString = kTypeStringLiteral | 32,
678 kStringLiteralMask = kUseStrictString, 768 kStringLiteralMask = kUseStrictString,
679 769
770 // Binary operations. Those are needed to detect certain keywords and
771 // duplicated identifier in parameter lists for arrow functions, because
772 // they are initially parsed as comma-separated expressions.
773 kTypeBinaryOperation = 3,
774 kBinaryOperationArrowParamList = (1 << 4),
775
680 // Below here applies if neither identifier nor string literal. Reserve the 776 // Below here applies if neither identifier nor string literal. Reserve the
681 // 2 least significant bits for flags. 777 // 2 least significant bits for flags.
682 kThisExpression = 1 << 2, 778 kThisExpression = (1 << 4),
683 kThisPropertyExpression = 2 << 2, 779 kThisPropertyExpression = (2 << 4),
684 kPropertyExpression = 3 << 2, 780 kPropertyExpression = (3 << 4),
685 kCallExpression = 4 << 2 781 kCallExpression = (4 << 4)
686 }; 782 };
687 783
688 explicit PreParserExpression(int expression_code) : code_(expression_code) {} 784 explicit PreParserExpression(int expression_code) : code_(expression_code) {}
689 785
786 V8_INLINE int ArrowParamListBit() const {
787 if (IsBinaryOperation())
788 return code_ & kBinaryOperationArrowParamList;
789 if (IsIdentifier()) {
790 const PreParserIdentifier ident = AsIdentifier();
791 // A valid identifier can be an arrow function parameter list
792 // except for eval, arguments, yield, and reserved keywords.
793 if (ident.IsEval() || ident.IsArguments() || ident.IsYield()
794 || ident.IsFutureStrictReserved())
795 return 0;
796 return kBinaryOperationArrowParamList;
797 }
798 return 0;
799 }
800
690 int code_; 801 int code_;
691 }; 802 };
692 803
693 804
694 // PreParserExpressionList doesn't actually store the expressions because 805 // PreParserExpressionList doesn't actually store the expressions because
695 // PreParser doesn't need to. 806 // PreParser doesn't need to.
696 class PreParserExpressionList { 807 class PreParserExpressionList {
697 public: 808 public:
698 // These functions make list->Add(some_expression) work (and do nothing). 809 // These functions make list->Add(some_expression) work (and do nothing).
699 PreParserExpressionList() : length_(0) {} 810 PreParserExpressionList() : length_(0) {}
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
761 public: 872 public:
762 // These functions make list->Add(some_expression) work as no-ops. 873 // These functions make list->Add(some_expression) work as no-ops.
763 PreParserStatementList() {} 874 PreParserStatementList() {}
764 PreParserStatementList* operator->() { return this; } 875 PreParserStatementList* operator->() { return this; }
765 void Add(PreParserStatement, void*) {} 876 void Add(PreParserStatement, void*) {}
766 }; 877 };
767 878
768 879
769 class PreParserScope { 880 class PreParserScope {
770 public: 881 public:
771 explicit PreParserScope(PreParserScope* outer_scope, ScopeType scope_type) 882 explicit PreParserScope(PreParserScope* outer_scope,
772 : scope_type_(scope_type) { 883 ScopeType scope_type,
884 void* = NULL)
885 : scope_type_(scope_type), declared_parameters_(0) {
773 strict_mode_ = outer_scope ? outer_scope->strict_mode() : SLOPPY; 886 strict_mode_ = outer_scope ? outer_scope->strict_mode() : SLOPPY;
774 } 887 }
775 888
776 ScopeType type() { return scope_type_; } 889 ScopeType type() { return scope_type_; }
777 StrictMode strict_mode() const { return strict_mode_; } 890 StrictMode strict_mode() const { return strict_mode_; }
778 void SetStrictMode(StrictMode strict_mode) { strict_mode_ = strict_mode; } 891 void SetStrictMode(StrictMode strict_mode) { strict_mode_ = strict_mode; }
779 892
893 // TODO(aperezdc): Would allowing lazy compilation in preparser make sense?
marja 2014/07/01 07:23:40 Doesn't seem very sensemaking to me, when we are i
894 bool AllowsLazyCompilation() const { return false; }
895
896 void set_start_position(int position) {}
897 void set_end_position(int position) {}
898
899 bool IsDeclared(const PreParserIdentifier& identifier) const {
marja 2014/07/01 07:23:40 What cases does this IsDeclared actually detect? P
900 return (declared_parameters_ & (1 << identifier.type_)) != 0;
901 }
902
903 void DeclareParameter(const PreParserIdentifier& identifier, VariableMode) {
904 declared_parameters_ |= (1 << identifier.type_);
905 }
906
907 // Allow scope->Foo() to work.
908 PreParserScope* operator->() { return this; }
909
780 private: 910 private:
781 ScopeType scope_type_; 911 ScopeType scope_type_;
782 StrictMode strict_mode_; 912 StrictMode strict_mode_;
913 int declared_parameters_;
783 }; 914 };
784 915
785 916
786 class PreParserFactory { 917 class PreParserFactory {
787 public: 918 public:
788 explicit PreParserFactory(void* extra_param1, void* extra_param2) {} 919 explicit PreParserFactory(void* extra_param1, void* extra_param2) {}
789 PreParserExpression NewStringLiteral(PreParserIdentifier identifier, 920 PreParserExpression NewStringLiteral(PreParserIdentifier identifier,
790 int pos) { 921 int pos) {
791 return PreParserExpression::Default(); 922 return PreParserExpression::Default();
792 } 923 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
833 return PreParserExpression::Property(); 964 return PreParserExpression::Property();
834 } 965 }
835 PreParserExpression NewUnaryOperation(Token::Value op, 966 PreParserExpression NewUnaryOperation(Token::Value op,
836 PreParserExpression expression, 967 PreParserExpression expression,
837 int pos) { 968 int pos) {
838 return PreParserExpression::Default(); 969 return PreParserExpression::Default();
839 } 970 }
840 PreParserExpression NewBinaryOperation(Token::Value op, 971 PreParserExpression NewBinaryOperation(Token::Value op,
841 PreParserExpression left, 972 PreParserExpression left,
842 PreParserExpression right, int pos) { 973 PreParserExpression right, int pos) {
843 return PreParserExpression::Default(); 974 return PreParserExpression::BinaryOperation(left, op, right);
844 } 975 }
845 PreParserExpression NewCompareOperation(Token::Value op, 976 PreParserExpression NewCompareOperation(Token::Value op,
846 PreParserExpression left, 977 PreParserExpression left,
847 PreParserExpression right, int pos) { 978 PreParserExpression right, int pos) {
848 return PreParserExpression::Default(); 979 return PreParserExpression::Default();
849 } 980 }
850 PreParserExpression NewAssignment(Token::Value op, 981 PreParserExpression NewAssignment(Token::Value op,
851 PreParserExpression left, 982 PreParserExpression left,
852 PreParserExpression right, 983 PreParserExpression right,
853 int pos) { 984 int pos) {
(...skipping 20 matching lines...) Expand all
874 PreParserExpression NewCall(PreParserExpression expression, 1005 PreParserExpression NewCall(PreParserExpression expression,
875 PreParserExpressionList arguments, 1006 PreParserExpressionList arguments,
876 int pos) { 1007 int pos) {
877 return PreParserExpression::Call(); 1008 return PreParserExpression::Call();
878 } 1009 }
879 PreParserExpression NewCallNew(PreParserExpression expression, 1010 PreParserExpression NewCallNew(PreParserExpression expression,
880 PreParserExpressionList arguments, 1011 PreParserExpressionList arguments,
881 int pos) { 1012 int pos) {
882 return PreParserExpression::Default(); 1013 return PreParserExpression::Default();
883 } 1014 }
1015 PreParserStatement NewReturnStatement(PreParserExpression expression,
1016 int pos) {
1017 return PreParserStatement::Default();
1018 }
1019 PreParserExpression
1020 NewFunctionLiteral(PreParserIdentifier name,
1021 PreParserScope& scope,
1022 PreParserStatementList body,
1023 int materialized_literal_count,
1024 int expected_property_count,
1025 int handler_count,
1026 int parameter_count,
1027 FunctionLiteral::ParameterFlag has_duplicate_parameters,
1028 FunctionLiteral::FunctionType function_type,
1029 FunctionLiteral::IsFunctionFlag is_function,
1030 FunctionLiteral::IsParenthesizedFlag is_parenthesized,
1031 FunctionLiteral::IsGeneratorFlag is_generator,
1032 int position) {
1033 return PreParserExpression::Default();
1034 }
1035
1036 // Return the object itself as AstVisitor and implement the needed
1037 // dummy method right in this class.
1038 PreParserFactory* visitor() { return this; }
1039 BailoutReason dont_optimize_reason() { return kNoReason; }
1040 int* ast_properties() { static int dummy = 42; return &dummy; }
884 }; 1041 };
885 1042
886 1043
887 class PreParser; 1044 class PreParser;
888 1045
889 class PreParserTraits { 1046 class PreParserTraits {
890 public: 1047 public:
891 struct Type { 1048 struct Type {
892 // TODO(marja): To be removed. The Traits object should contain all the data 1049 // TODO(marja): To be removed. The Traits object should contain all the data
893 // it needs. 1050 // it needs.
894 typedef PreParser* Parser; 1051 typedef PreParser* Parser;
895 1052
896 // Used by FunctionState and BlockState. 1053 // Used by FunctionState and BlockState.
897 typedef PreParserScope Scope; 1054 typedef PreParserScope Scope;
1055 typedef PreParserScope ScopePtr;
1056
898 // PreParser doesn't need to store generator variables. 1057 // PreParser doesn't need to store generator variables.
899 typedef void GeneratorVariable; 1058 typedef void GeneratorVariable;
900 // No interaction with Zones. 1059 // No interaction with Zones.
901 typedef void Zone; 1060 typedef void Zone;
902 1061
1062 typedef int AstProperties;
1063 typedef Vector<PreParserIdentifier> ParameterIdentifierVector;
1064
903 // Return types for traversing functions. 1065 // Return types for traversing functions.
904 typedef PreParserIdentifier Identifier; 1066 typedef PreParserIdentifier Identifier;
905 typedef PreParserExpression Expression; 1067 typedef PreParserExpression Expression;
906 typedef PreParserExpression YieldExpression; 1068 typedef PreParserExpression YieldExpression;
907 typedef PreParserExpression FunctionLiteral; 1069 typedef PreParserExpression FunctionLiteral;
908 typedef PreParserExpression ObjectLiteralProperty; 1070 typedef PreParserExpression ObjectLiteralProperty;
909 typedef PreParserExpression Literal; 1071 typedef PreParserExpression Literal;
910 typedef PreParserExpressionList ExpressionList; 1072 typedef PreParserExpressionList ExpressionList;
911 typedef PreParserExpressionList PropertyList; 1073 typedef PreParserExpressionList PropertyList;
912 typedef PreParserStatementList StatementList; 1074 typedef PreParserStatementList StatementList;
(...skipping 22 matching lines...) Expand all
935 } 1097 }
936 1098
937 static bool IsIdentifier(PreParserExpression expression) { 1099 static bool IsIdentifier(PreParserExpression expression) {
938 return expression.IsIdentifier(); 1100 return expression.IsIdentifier();
939 } 1101 }
940 1102
941 static PreParserIdentifier AsIdentifier(PreParserExpression expression) { 1103 static PreParserIdentifier AsIdentifier(PreParserExpression expression) {
942 return expression.AsIdentifier(); 1104 return expression.AsIdentifier();
943 } 1105 }
944 1106
1107 static bool IsFutureStrictReserved(PreParserIdentifier identifier) {
1108 return identifier.IsYield() || identifier.IsFutureStrictReserved();
1109 }
1110
945 static bool IsBoilerplateProperty(PreParserExpression property) { 1111 static bool IsBoilerplateProperty(PreParserExpression property) {
946 // PreParser doesn't count boilerplate properties. 1112 // PreParser doesn't count boilerplate properties.
947 return false; 1113 return false;
948 } 1114 }
949 1115
950 static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) { 1116 static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) {
951 return false; 1117 return false;
952 } 1118 }
953 1119
954 // Functions for encapsulating the differences between parsing and preparsing; 1120 // Functions for encapsulating the differences between parsing and preparsing;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
998 return PreParserExpression::Default(); 1164 return PreParserExpression::Default();
999 } 1165 }
1000 PreParserExpression NewThrowSyntaxError( 1166 PreParserExpression NewThrowSyntaxError(
1001 const char* type, Handle<Object> arg, int pos) { 1167 const char* type, Handle<Object> arg, int pos) {
1002 return PreParserExpression::Default(); 1168 return PreParserExpression::Default();
1003 } 1169 }
1004 PreParserExpression NewThrowTypeError( 1170 PreParserExpression NewThrowTypeError(
1005 const char* type, Handle<Object> arg, int pos) { 1171 const char* type, Handle<Object> arg, int pos) {
1006 return PreParserExpression::Default(); 1172 return PreParserExpression::Default();
1007 } 1173 }
1174 PreParserScope NewScope(PreParserScope* outer_scope,
1175 ScopeType scope_type) {
1176 return PreParserScope(outer_scope, scope_type);
1177 }
1008 1178
1009 // Reporting errors. 1179 // Reporting errors.
1010 void ReportMessageAt(Scanner::Location location, 1180 void ReportMessageAt(Scanner::Location location,
1011 const char* message, 1181 const char* message,
1012 const char* arg = NULL, 1182 const char* arg = NULL,
1013 bool is_reference_error = false); 1183 bool is_reference_error = false);
1014 void ReportMessageAt(int start_pos, 1184 void ReportMessageAt(int start_pos,
1015 int end_pos, 1185 int end_pos,
1016 const char* message, 1186 const char* message,
1017 const char* arg = NULL, 1187 const char* arg = NULL,
1018 bool is_reference_error = false); 1188 bool is_reference_error = false);
1019 1189
1020 // "null" return type creators. 1190 // "null" return type creators.
1021 static PreParserIdentifier EmptyIdentifier() { 1191 static PreParserIdentifier EmptyIdentifier() {
1022 return PreParserIdentifier::Default(); 1192 return PreParserIdentifier::Default();
1023 } 1193 }
1024 static PreParserExpression EmptyExpression() { 1194 static PreParserExpression EmptyExpression() {
1025 return PreParserExpression::Default(); 1195 return PreParserExpression::Default();
1026 } 1196 }
1197 static PreParserExpression EmptyArrowParamList() {
1198 return PreParserExpression::EmptyArrowParamList();
1199 }
1027 static PreParserExpression EmptyLiteral() { 1200 static PreParserExpression EmptyLiteral() {
1028 return PreParserExpression::Default(); 1201 return PreParserExpression::Default();
1029 } 1202 }
1030 static PreParserExpressionList NullExpressionList() { 1203 static PreParserExpressionList NullExpressionList() {
1031 return PreParserExpressionList(); 1204 return PreParserExpressionList();
1032 } 1205 }
1033 1206
1034 // Odd-ball literal creators. 1207 // Odd-ball literal creators.
1035 static PreParserExpression GetLiteralTheHole(int position, 1208 static PreParserExpression GetLiteralTheHole(int position,
1036 PreParserFactory* factory) { 1209 PreParserFactory* factory) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1070 } 1243 }
1071 1244
1072 static PreParserStatementList NewStatementList(int size, void* zone) { 1245 static PreParserStatementList NewStatementList(int size, void* zone) {
1073 return PreParserStatementList(); 1246 return PreParserStatementList();
1074 } 1247 }
1075 1248
1076 static PreParserExpressionList NewPropertyList(int size, void* zone) { 1249 static PreParserExpressionList NewPropertyList(int size, void* zone) {
1077 return PreParserExpressionList(); 1250 return PreParserExpressionList();
1078 } 1251 }
1079 1252
1253 V8_INLINE void SkipLazyFunctionBody(
1254 PreParserIdentifier function_name,
1255 int* materialized_literal_count,
1256 int* expected_property_count,
1257 bool* ok) {
1258 UNREACHABLE();
1259 }
1260
1261 V8_INLINE PreParserStatementList ParseEagerFunctionBody(
1262 PreParserIdentifier function_name,
1263 int pos,
1264 Variable* fvar,
1265 Token::Value fvar_init_op,
1266 bool is_generator,
1267 bool* ok);
1268
1269 // Utility functions
1270 Vector<PreParserIdentifier> ParameterListFromExpression(
1271 PreParserExpression expression) {
1272 return Vector<PreParserIdentifier>::empty();
1273 }
1274 bool IsValidArrowFunctionParameterList(PreParserExpression expression) {
marja 2014/07/01 07:23:40 Pls reorder these functions so that they're in the
1275 // TODO(aperez): Detect duplicated identifiers in paramlists.
1276 return expression.IsValidArrowParamList();
1277 }
1278 static AstValueFactory* ast_value_factory() { return NULL; }
1279
1280 void CheckConflictingVarDeclarations(
marja 2014/07/01 07:23:40 Nit: formatting. You'd probably want to have a lo
1281 PreParserScope scope,
1282 bool* ok) {}
1283
1080 // Temporary glue; these functions will move to ParserBase. 1284 // Temporary glue; these functions will move to ParserBase.
1081 PreParserExpression ParseV8Intrinsic(bool* ok); 1285 PreParserExpression ParseV8Intrinsic(bool* ok);
1082 PreParserExpression ParseFunctionLiteral( 1286 PreParserExpression ParseFunctionLiteral(
1083 PreParserIdentifier name, 1287 PreParserIdentifier name,
1084 Scanner::Location function_name_location, 1288 Scanner::Location function_name_location,
1085 bool name_is_strict_reserved, 1289 bool name_is_strict_reserved,
1086 bool is_generator, 1290 bool is_generator,
1087 int function_token_position, 1291 int function_token_position,
1088 FunctionLiteral::FunctionType type, 1292 FunctionLiteral::FunctionType type,
1089 FunctionLiteral::ArityRestriction arity_restriction, 1293 FunctionLiteral::ArityRestriction arity_restriction,
(...skipping 30 matching lines...) Expand all
1120 PreParser(Scanner* scanner, ParserRecorder* log, uintptr_t stack_limit) 1324 PreParser(Scanner* scanner, ParserRecorder* log, uintptr_t stack_limit)
1121 : ParserBase<PreParserTraits>(scanner, stack_limit, NULL, log, NULL, 1325 : ParserBase<PreParserTraits>(scanner, stack_limit, NULL, log, NULL,
1122 this) {} 1326 this) {}
1123 1327
1124 // Pre-parse the program from the character stream; returns true on 1328 // Pre-parse the program from the character stream; returns true on
1125 // success (even if parsing failed, the pre-parse data successfully 1329 // success (even if parsing failed, the pre-parse data successfully
1126 // captured the syntax error), and false if a stack-overflow happened 1330 // captured the syntax error), and false if a stack-overflow happened
1127 // during parsing. 1331 // during parsing.
1128 PreParseResult PreParseProgram() { 1332 PreParseResult PreParseProgram() {
1129 PreParserScope scope(scope_, GLOBAL_SCOPE); 1333 PreParserScope scope(scope_, GLOBAL_SCOPE);
1130 FunctionState top_scope(&function_state_, &scope_, &scope, NULL); 1334 FunctionState top_scope(&function_state_, &scope_, &scope);
1131 bool ok = true; 1335 bool ok = true;
1132 int start_position = scanner()->peek_location().beg_pos; 1336 int start_position = scanner()->peek_location().beg_pos;
1133 ParseSourceElements(Token::EOS, &ok); 1337 ParseSourceElements(Token::EOS, &ok);
1134 if (stack_overflow()) return kPreParseStackOverflow; 1338 if (stack_overflow()) return kPreParseStackOverflow;
1135 if (!ok) { 1339 if (!ok) {
1136 ReportUnexpectedToken(scanner()->current_token()); 1340 ReportUnexpectedToken(scanner()->current_token());
1137 } else if (scope_->strict_mode() == STRICT) { 1341 } else if (scope_->strict_mode() == STRICT) {
1138 CheckOctalLiteral(start_position, scanner()->location().end_pos, &ok); 1342 CheckOctalLiteral(start_position, scanner()->location().end_pos, &ok);
1139 } 1343 }
1140 return kPreParseSuccess; 1344 return kPreParseSuccess;
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1202 Statement ParseDoWhileStatement(bool* ok); 1406 Statement ParseDoWhileStatement(bool* ok);
1203 Statement ParseWhileStatement(bool* ok); 1407 Statement ParseWhileStatement(bool* ok);
1204 Statement ParseForStatement(bool* ok); 1408 Statement ParseForStatement(bool* ok);
1205 Statement ParseThrowStatement(bool* ok); 1409 Statement ParseThrowStatement(bool* ok);
1206 Statement ParseTryStatement(bool* ok); 1410 Statement ParseTryStatement(bool* ok);
1207 Statement ParseDebuggerStatement(bool* ok); 1411 Statement ParseDebuggerStatement(bool* ok);
1208 Expression ParseConditionalExpression(bool accept_IN, bool* ok); 1412 Expression ParseConditionalExpression(bool accept_IN, bool* ok);
1209 Expression ParseObjectLiteral(bool* ok); 1413 Expression ParseObjectLiteral(bool* ok);
1210 Expression ParseV8Intrinsic(bool* ok); 1414 Expression ParseV8Intrinsic(bool* ok);
1211 1415
1416 V8_INLINE void SkipLazyFunctionBody(
1417 PreParserIdentifier function_name,
1418 int* materialized_literal_count,
1419 int* expected_property_count,
1420 bool* ok);
1421 V8_INLINE PreParserStatementList ParseEagerFunctionBody(
1422 PreParserIdentifier function_name,
1423 int pos,
1424 Variable* fvar,
1425 Token::Value fvar_init_op,
1426 bool is_generator,
1427 bool* ok);
1428
1212 Expression ParseFunctionLiteral( 1429 Expression ParseFunctionLiteral(
1213 Identifier name, 1430 Identifier name,
1214 Scanner::Location function_name_location, 1431 Scanner::Location function_name_location,
1215 bool name_is_strict_reserved, 1432 bool name_is_strict_reserved,
1216 bool is_generator, 1433 bool is_generator,
1217 int function_token_pos, 1434 int function_token_pos,
1218 FunctionLiteral::FunctionType function_type, 1435 FunctionLiteral::FunctionType function_type,
1219 FunctionLiteral::ArityRestriction arity_restriction, 1436 FunctionLiteral::ArityRestriction arity_restriction,
1220 bool* ok); 1437 bool* ok);
1221 void ParseLazyFunctionLiteralBody(bool* ok); 1438 void ParseLazyFunctionLiteralBody(bool* ok);
1222 1439
1223 bool CheckInOrOf(bool accept_OF); 1440 bool CheckInOrOf(bool accept_OF);
1224 }; 1441 };
1225 1442
1443
1444 PreParserStatementList PreParser::ParseEagerFunctionBody(
1445 PreParserIdentifier function_name,
1446 int pos,
1447 Variable* fvar,
1448 Token::Value fvar_init_op,
1449 bool is_generator,
1450 bool* ok) {
1451 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
1452
1453 ParseSourceElements(Token::RBRACE, ok);
1454 if (!*ok) return PreParserStatementList();
1455
1456 Expect(Token::RBRACE, ok);
1457 return PreParserStatementList();
1458 }
1459
1460
1461 PreParserStatementList PreParserTraits::ParseEagerFunctionBody(
1462 PreParserIdentifier function_name,
1463 int pos,
1464 Variable* fvar,
1465 Token::Value fvar_init_op,
1466 bool is_generator,
1467 bool* ok) {
1468 return pre_parser_->ParseEagerFunctionBody(function_name,
1469 pos, fvar, fvar_init_op, is_generator, ok);
1470 }
1471
1472
1226 template<class Traits> 1473 template<class Traits>
1227 ParserBase<Traits>::FunctionState::FunctionState( 1474 ParserBase<Traits>::FunctionState::FunctionState(
1228 FunctionState** function_state_stack, 1475 FunctionState** function_state_stack,
1229 typename Traits::Type::Scope** scope_stack, 1476 typename Traits::Type::Scope** scope_stack,
1230 typename Traits::Type::Scope* scope, 1477 typename Traits::Type::Scope* scope,
1231 typename Traits::Type::Zone* extra_param, 1478 typename Traits::Type::Zone* extra_param,
1232 AstValueFactory* ast_value_factory) 1479 AstValueFactory* ast_value_factory)
1233 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize), 1480 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize),
1234 next_handler_index_(0), 1481 next_handler_index_(0),
1235 expected_property_count_(0), 1482 expected_property_count_(0),
1236 is_generator_(false), 1483 is_generator_(false),
1237 generator_object_variable_(NULL), 1484 generator_object_variable_(NULL),
1238 function_state_stack_(function_state_stack), 1485 function_state_stack_(function_state_stack),
1239 outer_function_state_(*function_state_stack), 1486 outer_function_state_(*function_state_stack),
1240 scope_stack_(scope_stack), 1487 scope_stack_(scope_stack),
1241 outer_scope_(*scope_stack), 1488 outer_scope_(*scope_stack),
1242 saved_ast_node_id_(0), 1489 saved_ast_node_id_(0),
1243 extra_param_(extra_param), 1490 extra_param_(extra_param),
1244 factory_(extra_param, ast_value_factory) { 1491 factory_(extra_param, ast_value_factory) {
1245 *scope_stack_ = scope; 1492 *scope_stack_ = scope;
1246 *function_state_stack = this; 1493 *function_state_stack = this;
1247 Traits::SetUpFunctionState(this, extra_param); 1494 Traits::SetUpFunctionState(this, extra_param);
1248 } 1495 }
1249 1496
1250 1497
1251 template<class Traits> 1498 template<class Traits>
1499 ParserBase<Traits>::FunctionState::FunctionState(
1500 FunctionState** function_state_stack,
1501 typename Traits::Type::Scope** scope_stack,
1502 typename Traits::Type::Scope** scope,
1503 typename Traits::Type::Zone* extra_param,
1504 AstValueFactory* ast_value_factory)
1505 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize),
1506 next_handler_index_(0),
1507 expected_property_count_(0),
1508 is_generator_(false),
1509 generator_object_variable_(NULL),
1510 function_state_stack_(function_state_stack),
1511 outer_function_state_(*function_state_stack),
1512 scope_stack_(scope_stack),
1513 outer_scope_(*scope_stack),
1514 saved_ast_node_id_(0),
1515 extra_param_(extra_param),
1516 factory_(extra_param, ast_value_factory) {
1517 *scope_stack_ = *scope;
1518 *function_state_stack = this;
1519 Traits::SetUpFunctionState(this, extra_param);
1520 }
1521
1522
1523 template<class Traits>
1252 ParserBase<Traits>::FunctionState::~FunctionState() { 1524 ParserBase<Traits>::FunctionState::~FunctionState() {
1253 *scope_stack_ = outer_scope_; 1525 *scope_stack_ = outer_scope_;
1254 *function_state_stack_ = outer_function_state_; 1526 *function_state_stack_ = outer_function_state_;
1255 Traits::TearDownFunctionState(this, extra_param_); 1527 Traits::TearDownFunctionState(this, extra_param_);
1256 } 1528 }
1257 1529
1258 1530
1259 template<class Traits> 1531 template<class Traits>
1260 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) { 1532 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) {
1261 Scanner::Location source_location = scanner()->location(); 1533 Scanner::Location source_location = scanner()->location();
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
1453 case Token::LBRACK: 1725 case Token::LBRACK:
1454 result = this->ParseArrayLiteral(CHECK_OK); 1726 result = this->ParseArrayLiteral(CHECK_OK);
1455 break; 1727 break;
1456 1728
1457 case Token::LBRACE: 1729 case Token::LBRACE:
1458 result = this->ParseObjectLiteral(CHECK_OK); 1730 result = this->ParseObjectLiteral(CHECK_OK);
1459 break; 1731 break;
1460 1732
1461 case Token::LPAREN: 1733 case Token::LPAREN:
1462 Consume(Token::LPAREN); 1734 Consume(Token::LPAREN);
1463 // Heuristically try to detect immediately called functions before 1735 if (allow_arrow_functions() && peek() == Token::RPAREN) {
1464 // seeing the call parentheses. 1736 // Arrow functions are the only expression type constructions
1465 parenthesized_function_ = (peek() == Token::FUNCTION); 1737 // for which an empty parameter list "()" is valid input.
1466 result = this->ParseExpression(true, CHECK_OK); 1738 Consume(Token::RPAREN);
1467 Expect(Token::RPAREN, CHECK_OK); 1739 return this->ParseArrowFunctionLiteral(pos,
1740 this->EmptyArrowParamList(),
1741 CHECK_OK);
1742 } else {
1743 // Heuristically try to detect immediately called functions before
1744 // seeing the call parentheses.
1745 parenthesized_function_ = (peek() == Token::FUNCTION);
1746 result = this->ParseExpression(true, CHECK_OK);
1747 result->increase_parenthesization_level();
1748 Expect(Token::RPAREN, CHECK_OK);
1749 }
1468 break; 1750 break;
1469 1751
1470 case Token::MOD: 1752 case Token::MOD:
1471 if (allow_natives_syntax() || extension_ != NULL) { 1753 if (allow_natives_syntax() || extension_ != NULL) {
1472 result = this->ParseV8Intrinsic(CHECK_OK); 1754 result = this->ParseV8Intrinsic(CHECK_OK);
1473 break; 1755 break;
1474 } 1756 }
1475 // If we're not allowing special syntax we fall-through to the 1757 // If we're not allowing special syntax we fall-through to the
1476 // default case. 1758 // default case.
1477 1759
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
1725 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList)); 2007 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList));
1726 return result; 2008 return result;
1727 } 2009 }
1728 2010
1729 // Precedence = 2 2011 // Precedence = 2
1730 template <class Traits> 2012 template <class Traits>
1731 typename ParserBase<Traits>::ExpressionT 2013 typename ParserBase<Traits>::ExpressionT
1732 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) { 2014 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) {
1733 // AssignmentExpression :: 2015 // AssignmentExpression ::
1734 // ConditionalExpression 2016 // ConditionalExpression
2017 // ArrowFunction
1735 // YieldExpression 2018 // YieldExpression
1736 // LeftHandSideExpression AssignmentOperator AssignmentExpression 2019 // LeftHandSideExpression AssignmentOperator AssignmentExpression
1737 2020
1738 Scanner::Location lhs_location = scanner()->peek_location(); 2021 Scanner::Location lhs_location = scanner()->peek_location();
1739 2022
1740 if (peek() == Token::YIELD && is_generator()) { 2023 if (peek() == Token::YIELD && is_generator()) {
1741 return this->ParseYieldExpression(ok); 2024 return this->ParseYieldExpression(ok);
1742 } 2025 }
1743 2026
1744 if (fni_ != NULL) fni_->Enter(); 2027 if (fni_ != NULL) fni_->Enter();
1745 ExpressionT expression = 2028 ExpressionT expression =
1746 this->ParseConditionalExpression(accept_IN, CHECK_OK); 2029 this->ParseConditionalExpression(accept_IN, CHECK_OK);
1747 2030
2031 if (allow_arrow_functions() && peek() == Token::ARROW)
2032 return this->ParseArrowFunctionLiteral(lhs_location.beg_pos,
2033 expression,
2034 CHECK_OK);
2035
1748 if (!Token::IsAssignmentOp(peek())) { 2036 if (!Token::IsAssignmentOp(peek())) {
1749 if (fni_ != NULL) fni_->Leave(); 2037 if (fni_ != NULL) fni_->Leave();
1750 // Parsed conditional expression only (no assignment). 2038 // Parsed conditional expression only (no assignment).
1751 return expression; 2039 return expression;
1752 } 2040 }
1753 2041
1754 expression = this->CheckAndRewriteReferenceExpression( 2042 expression = this->CheckAndRewriteReferenceExpression(
1755 expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK); 2043 expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK);
1756 expression = this->MarkExpressionAsAssigned(expression); 2044 expression = this->MarkExpressionAsAssigned(expression);
1757 2045
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after
2143 } 2431 }
2144 default: 2432 default:
2145 return expression; 2433 return expression;
2146 } 2434 }
2147 } 2435 }
2148 ASSERT(false); 2436 ASSERT(false);
2149 return this->EmptyExpression(); 2437 return this->EmptyExpression();
2150 } 2438 }
2151 2439
2152 2440
2441 template <class Traits>
2442 typename ParserBase<Traits>::ExpressionT
2443 ParserBase<Traits>::ParseArrowFunctionLiteral(int start_pos,
2444 ExpressionT params_ast,
2445 bool* ok) {
2446 if (!this->IsValidArrowFunctionParameterList(params_ast)) {
2447 ReportMessageAt(
2448 Scanner::Location(start_pos, scanner()->location().beg_pos),
2449 "malformed_arrow_function_parameter_list");
2450 *ok = false;
2451 return this->EmptyExpression();
2452 }
2453
2454 // TODO(aperez): Change this to use ARROW_SCOPE
2455 typename Traits::Type::ScopePtr scope =
2456 this->NewScope(scope_, FUNCTION_SCOPE);
2457
2458 FunctionState function_state(&function_state_, &scope_, &scope,
2459 zone(), this->ast_value_factory());
2460 typename Traits::Type::ParameterIdentifierVector params =
2461 Traits::ParameterListFromExpression(params_ast);
2462 Scanner::Location dupe_error_loc = Scanner::Location::invalid();
2463
2464 if (params.length() > Code::kMaxArguments) {
2465 ReportMessageAt(Scanner::Location(params_ast->position(), position()),
2466 "too_many_parameters");
2467 *ok = false;
2468 return this->EmptyExpression();
2469 }
2470
2471 // The vector has the items in reverse order.
2472 for (int i = params.length() - 1; i >= 0; --i) {
2473 const IdentifierT param_name = params.at(i)->raw_name();
2474 if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) {
2475 int param_pos = params.at(i)->position();
2476 dupe_error_loc = Scanner::Location(param_pos,
2477 param_pos + param_name->length());
2478 }
2479 scope_->DeclareParameter(param_name, VAR);
2480 }
2481
2482 return ParseArrowFunctionLiteralBody(&function_state,
2483 scope,
2484 params.length(),
2485 Scanner::Location::invalid(),
2486 dupe_error_loc,
2487 Scanner::Location::invalid(),
2488 FunctionLiteral::kNotParenthesized,
2489 start_pos,
2490 CHECK_OK);
2491 }
2492
2493
2494 template <class Traits>
2495 typename ParserBase<Traits>::ExpressionT
2496 ParserBase<Traits>::ParseArrowFunctionLiteralBody(
2497 FunctionState* function_state,
2498 typename Traits::Type::ScopePtr scope,
2499 int num_parameters,
2500 const Scanner::Location& eval_args_error_loc,
2501 const Scanner::Location& dupe_error_loc,
2502 const Scanner::Location& reserved_loc,
2503 FunctionLiteral::IsParenthesizedFlag parenthesized,
2504 int start_pos,
2505 bool* ok) {
2506
2507 typename Traits::Type::StatementList body;
2508 int materialized_literal_count = -1;
2509 int expected_property_count = -1;
2510
2511 Expect(Token::ARROW, CHECK_OK);
2512
2513 if (peek() == Token::LBRACE) {
2514 // Multiple statemente body
2515 Consume(Token::LBRACE);
2516 bool is_lazily_parsed = (mode() == PARSE_LAZILY &&
2517 scope_->AllowsLazyCompilation());
2518 if (is_lazily_parsed) {
2519 this->SkipLazyFunctionBody(this->EmptyIdentifier(),
2520 &materialized_literal_count,
2521 &expected_property_count,
2522 CHECK_OK);
2523 } else {
2524 body = this->ParseEagerFunctionBody(this->EmptyIdentifier(),
2525 RelocInfo::kNoPosition,
2526 NULL,
2527 Token::INIT_VAR,
2528 false, // Not a generator.
2529 CHECK_OK);
2530 }
2531 } else {
2532 // Single-expression body
2533 ParseAssignmentExpression(true, CHECK_OK);
2534 }
2535
2536 scope->set_start_position(start_pos);
2537 scope->set_end_position(scanner()->location().end_pos);
2538
2539 this->CheckStrictFunctionNameAndParameters(this->EmptyIdentifier(),
marja 2014/07/01 07:23:40 This is not inside if (strict_mode() == STRICT) be
2540 false,
2541 Scanner::Location::invalid(),
2542 Scanner::Location::invalid(),
2543 dupe_error_loc,
2544 Scanner::Location::invalid(),
2545 CHECK_OK);
2546
2547 // Validate strict mode.
2548 if (strict_mode() == STRICT) {
2549 CheckOctalLiteral(start_pos,
2550 scanner()->location().end_pos,
2551 CHECK_OK);
2552 }
2553
2554 if (allow_harmony_scoping() && strict_mode() == STRICT)
2555 this->CheckConflictingVarDeclarations(scope, CHECK_OK);
2556
2557 return this->EmptyExpression();
marja 2014/07/01 07:23:40 This will change when you start generating the arr
2558 }
2559
2560
2153 template <typename Traits> 2561 template <typename Traits>
2154 typename ParserBase<Traits>::ExpressionT 2562 typename ParserBase<Traits>::ExpressionT
2155 ParserBase<Traits>::CheckAndRewriteReferenceExpression( 2563 ParserBase<Traits>::CheckAndRewriteReferenceExpression(
2156 ExpressionT expression, 2564 ExpressionT expression,
2157 Scanner::Location location, const char* message, bool* ok) { 2565 Scanner::Location location, const char* message, bool* ok) {
2158 if (strict_mode() == STRICT && this->IsIdentifier(expression) && 2566 if (strict_mode() == STRICT && this->IsIdentifier(expression) &&
2159 this->IsEvalOrArguments(this->AsIdentifier(expression))) { 2567 this->IsEvalOrArguments(this->AsIdentifier(expression))) {
2160 this->ReportMessageAt(location, "strict_eval_arguments", false); 2568 this->ReportMessageAt(location, "strict_eval_arguments", false);
2161 *ok = false; 2569 *ok = false;
2162 return this->EmptyExpression(); 2570 return this->EmptyExpression();
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
2206 parser()->ReportMessage("accessor_get_set"); 2614 parser()->ReportMessage("accessor_get_set");
2207 } 2615 }
2208 *ok = false; 2616 *ok = false;
2209 } 2617 }
2210 } 2618 }
2211 2619
2212 2620
2213 } } // v8::internal 2621 } } // v8::internal
2214 2622
2215 #endif // V8_PREPARSER_H 2623 #endif // V8_PREPARSER_H
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698