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

Side by Side Diff: src/preparser.h

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

Powered by Google App Engine
This is Rietveld 408576698