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

Side by Side Diff: src/preparser.h

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