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

Side by Side Diff: src/preparser.h

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