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

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: Removed ParamListFinder Created 6 years, 6 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 27 matching lines...) Expand all
143 typename Traits::Type::Scope* outer_scope_; 147 typename Traits::Type::Scope* outer_scope_;
144 typename Traits::Type::Scope* scope_; 148 typename Traits::Type::Scope* scope_;
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,
154 AstValueFactory* ast_value_factory = NULL); 158 AstValueFactory* ast_value_factory);
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,
164 AstValueFactory* ast_value_factory);
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 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
436 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); 446 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok);
437 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); 447 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok);
438 ExpressionT ParseUnaryExpression(bool* ok); 448 ExpressionT ParseUnaryExpression(bool* ok);
439 ExpressionT ParsePostfixExpression(bool* ok); 449 ExpressionT ParsePostfixExpression(bool* ok);
440 ExpressionT ParseLeftHandSideExpression(bool* ok); 450 ExpressionT ParseLeftHandSideExpression(bool* ok);
441 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); 451 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok);
442 ExpressionT ParseMemberExpression(bool* ok); 452 ExpressionT ParseMemberExpression(bool* ok);
443 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, 453 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression,
444 bool* ok); 454 bool* ok);
445 455
456 // There are two ways of parsing arrow functions: if the beginning of an
457 // arrow function can be determined prior to process the parameter list
458 // (e.g. the current scanning position is known to be an arrow function
459 // and not an AssignmentExpression) then the first version is used. In
460 // most cases, we parse the parameter list as an AssignmentExpression
461 // and interpret the AST when the arrow "=>" token is found, using the
462 // second version.
463 // The overloaded ParseArrowFunctionLiteral() functions mainly deal with
464 // parsing/interpreting the parameter list, and then they both call
465 // ParseArrowFunctionLiteralBody() before consuming the arrow token.
466 ExpressionT ParseArrowFunctionLiteral(bool* ok);
marja 2014/06/26 14:38:13 Isn't this one dead code? (And isn't the comment a
467 ExpressionT ParseArrowFunctionLiteral(int start_pos,
468 ExpressionT params_ast,
469 bool* ok);
470 ExpressionT ParseArrowFunctionLiteralBody(
471 FunctionState* function_state,
472 typename Traits::Type::ScopePtr scope,
473 int num_parameters,
474 const Scanner::Location& eval_args_error_loc,
475 const Scanner::Location& dupe_error_loc,
476 const Scanner::Location& reserved_loc,
477 FunctionLiteral::IsParenthesizedFlag parenthesized,
478 int start_pos,
479 bool* ok);
480
446 // Checks if the expression is a valid reference expression (e.g., on the 481 // Checks if the expression is a valid reference expression (e.g., on the
447 // left-hand side of assignments). Although ruled out by ECMA as early errors, 482 // left-hand side of assignments). Although ruled out by ECMA as early errors,
448 // we allow calls for web compatibility and rewrite them to a runtime throw. 483 // we allow calls for web compatibility and rewrite them to a runtime throw.
449 ExpressionT CheckAndRewriteReferenceExpression( 484 ExpressionT CheckAndRewriteReferenceExpression(
450 ExpressionT expression, 485 ExpressionT expression,
451 Scanner::Location location, const char* message, bool* ok); 486 Scanner::Location location, const char* message, bool* ok);
452 487
453 // Used to detect duplicates in object literals. Each of the values 488 // Used to detect duplicates in object literals. Each of the values
454 // kGetterProperty, kSetterProperty and kValueProperty represents 489 // kGetterProperty, kSetterProperty and kValueProperty represents
455 // a type of object literal property. When parsing a property, its 490 // a type of object literal property. When parsing a property, its
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
519 554
520 private: 555 private:
521 Scanner* scanner_; 556 Scanner* scanner_;
522 uintptr_t stack_limit_; 557 uintptr_t stack_limit_;
523 bool stack_overflow_; 558 bool stack_overflow_;
524 559
525 bool allow_lazy_; 560 bool allow_lazy_;
526 bool allow_natives_syntax_; 561 bool allow_natives_syntax_;
527 bool allow_generators_; 562 bool allow_generators_;
528 bool allow_for_of_; 563 bool allow_for_of_;
564 bool allow_arrow_functions_;
529 565
530 typename Traits::Type::Zone* zone_; // Only used by Parser. 566 typename Traits::Type::Zone* zone_; // Only used by Parser.
531 }; 567 };
532 568
533 569
534 class PreParserIdentifier { 570 class PreParserIdentifier {
535 public: 571 public:
536 PreParserIdentifier() : type_(kUnknownIdentifier) {} 572 PreParserIdentifier() : type_(kUnknownIdentifier) {}
537 static PreParserIdentifier Default() { 573 static PreParserIdentifier Default() {
538 return PreParserIdentifier(kUnknownIdentifier); 574 return PreParserIdentifier(kUnknownIdentifier);
539 } 575 }
540 static PreParserIdentifier Eval() { 576 static PreParserIdentifier Eval() {
541 return PreParserIdentifier(kEvalIdentifier); 577 return PreParserIdentifier(kEvalIdentifier);
542 } 578 }
543 static PreParserIdentifier Arguments() { 579 static PreParserIdentifier Arguments() {
544 return PreParserIdentifier(kArgumentsIdentifier); 580 return PreParserIdentifier(kArgumentsIdentifier);
545 } 581 }
546 static PreParserIdentifier FutureReserved() { 582 static PreParserIdentifier FutureReserved() {
547 return PreParserIdentifier(kFutureReservedIdentifier); 583 return PreParserIdentifier(kFutureReservedIdentifier);
548 } 584 }
549 static PreParserIdentifier FutureStrictReserved() { 585 static PreParserIdentifier FutureStrictReserved() {
550 return PreParserIdentifier(kFutureStrictReservedIdentifier); 586 return PreParserIdentifier(kFutureStrictReservedIdentifier);
551 } 587 }
552 static PreParserIdentifier Yield() { 588 static PreParserIdentifier Yield() {
553 return PreParserIdentifier(kYieldIdentifier); 589 return PreParserIdentifier(kYieldIdentifier);
554 } 590 }
555 bool IsEval() { return type_ == kEvalIdentifier; } 591 bool IsEval() const { return type_ == kEvalIdentifier; }
556 bool IsArguments() { return type_ == kArgumentsIdentifier; } 592 bool IsArguments() const { return type_ == kArgumentsIdentifier; }
557 bool IsEvalOrArguments() { return type_ >= kEvalIdentifier; } 593 bool IsEvalOrArguments() { return type_ >= kEvalIdentifier; }
558 bool IsYield() { return type_ == kYieldIdentifier; } 594 bool IsYield() const { return type_ == kYieldIdentifier; }
559 bool IsFutureReserved() { return type_ == kFutureReservedIdentifier; } 595 bool IsFutureReserved() { return type_ == kFutureReservedIdentifier; }
560 bool IsFutureStrictReserved() { 596 bool IsFutureStrictReserved() const {
561 return type_ == kFutureStrictReservedIdentifier; 597 return type_ == kFutureStrictReservedIdentifier;
562 } 598 }
563 bool IsValidStrictVariable() { return type_ == kUnknownIdentifier; } 599 bool IsValidStrictVariable() { return type_ == kUnknownIdentifier; }
564 600
601 // Allow identifier->name()[->length()] to work. The preparser
602 // does not need the actual positions/lengths of the identifiers.
603 const PreParserIdentifier* operator->() const { return this; }
604 const PreParserIdentifier raw_name() const { return *this; }
605
606 int position() const {
607 return 0;
608 }
609
610 int length() const {
marja 2014/06/26 14:38:13 This is used for duplicate parameter error message
611 if (IsEval()) return 4;
612 if (IsArguments()) return 9;
613 if (IsYield()) return 5;
614 return 0;
615 }
616
565 private: 617 private:
566 enum Type { 618 enum Type {
567 kUnknownIdentifier, 619 kUnknownIdentifier,
568 kFutureReservedIdentifier, 620 kFutureReservedIdentifier,
569 kFutureStrictReservedIdentifier, 621 kFutureStrictReservedIdentifier,
570 kYieldIdentifier, 622 kYieldIdentifier,
571 kEvalIdentifier, 623 kEvalIdentifier,
572 kArgumentsIdentifier 624 kArgumentsIdentifier
573 }; 625 };
574 explicit PreParserIdentifier(Type type) : type_(type) {} 626 explicit PreParserIdentifier(Type type) : type_(type) {}
575 Type type_; 627 Type type_;
576 628
577 friend class PreParserExpression; 629 friend class PreParserExpression;
630 friend class PreParserScope;
578 }; 631 };
579 632
580 633
581 // Bits 0 and 1 are used to identify the type of expression: 634 // Bits 0 and 1 are used to identify the type of expression:
582 // If bit 0 is set, it's an identifier. 635 // If bit 0 is set, it's an identifier.
583 // if bit 1 is set, it's a string literal. 636 // if bit 1 is set, it's a string literal.
584 // If neither is set, it's no particular type, and both set isn't 637 // If neither is set, it's no particular type, and both set isn't
585 // use yet. 638 // use yet.
586 class PreParserExpression { 639 class PreParserExpression {
587 public: 640 public:
588 static PreParserExpression Default() { 641 static PreParserExpression Default() {
589 return PreParserExpression(kUnknownExpression); 642 return PreParserExpression(kUnknownExpression);
590 } 643 }
591 644
592 static PreParserExpression FromIdentifier(PreParserIdentifier id) { 645 static PreParserExpression FromIdentifier(PreParserIdentifier id) {
593 return PreParserExpression(kIdentifierFlag | 646 return PreParserExpression(kTypeIdentifier |
594 (id.type_ << kIdentifierShift)); 647 (id.type_ << kIdentifierShift));
595 } 648 }
596 649
650 static PreParserExpression BinaryOperation(PreParserExpression left,
651 Token::Value op,
652 PreParserExpression right) {
653 int code = ((op == Token::COMMA) &&
654 !left.is_parenthesized() &&
655 !right.is_parenthesized())
656 ? left.ArrowParamListBit() & right.ArrowParamListBit() : 0;
657 return PreParserExpression(kTypeBinaryOperation | code);
658 }
659
660 static PreParserExpression EmptyArrowParamList() {
661 // Any expression for which IsValidArrowParamList() returns true
662 // will work here.
663 return FromIdentifier(PreParserIdentifier::Default());
664 }
665
597 static PreParserExpression StringLiteral() { 666 static PreParserExpression StringLiteral() {
598 return PreParserExpression(kUnknownStringLiteral); 667 return PreParserExpression(kUnknownStringLiteral);
599 } 668 }
600 669
601 static PreParserExpression UseStrictStringLiteral() { 670 static PreParserExpression UseStrictStringLiteral() {
602 return PreParserExpression(kUseStrictString); 671 return PreParserExpression(kUseStrictString);
603 } 672 }
604 673
605 static PreParserExpression This() { 674 static PreParserExpression This() {
606 return PreParserExpression(kThisExpression); 675 return PreParserExpression(kThisExpression);
607 } 676 }
608 677
609 static PreParserExpression ThisProperty() { 678 static PreParserExpression ThisProperty() {
610 return PreParserExpression(kThisPropertyExpression); 679 return PreParserExpression(kThisPropertyExpression);
611 } 680 }
612 681
613 static PreParserExpression Property() { 682 static PreParserExpression Property() {
614 return PreParserExpression(kPropertyExpression); 683 return PreParserExpression(kPropertyExpression);
615 } 684 }
616 685
617 static PreParserExpression Call() { 686 static PreParserExpression Call() {
618 return PreParserExpression(kCallExpression); 687 return PreParserExpression(kCallExpression);
619 } 688 }
620 689
621 bool IsIdentifier() { return (code_ & kIdentifierFlag) != 0; } 690 bool IsIdentifier() const {
691 return (code_ & kTypeMask) == kTypeIdentifier;
692 }
622 693
623 PreParserIdentifier AsIdentifier() { 694 PreParserIdentifier AsIdentifier() const {
624 ASSERT(IsIdentifier()); 695 ASSERT(IsIdentifier());
625 return PreParserIdentifier( 696 return PreParserIdentifier(
626 static_cast<PreParserIdentifier::Type>(code_ >> kIdentifierShift)); 697 static_cast<PreParserIdentifier::Type>(code_ >> kIdentifierShift));
627 } 698 }
628 699
629 bool IsStringLiteral() { return (code_ & kStringLiteralFlag) != 0; } 700 bool IsStringLiteral() const {
701 return (code_ & kTypeMask) == kTypeStringLiteral;
702 }
630 703
631 bool IsUseStrictLiteral() { 704 bool IsUseStrictLiteral() {
632 return (code_ & kStringLiteralMask) == kUseStrictString; 705 return (code_ & kUseStrictString) == kUseStrictString;
633 } 706 }
634 707
635 bool IsThis() { return code_ == kThisExpression; } 708 bool IsThis() { return code_ == kThisExpression; }
636 709
637 bool IsThisProperty() { return code_ == kThisPropertyExpression; } 710 bool IsThisProperty() { return code_ == kThisPropertyExpression; }
638 711
639 bool IsProperty() { 712 bool IsProperty() {
640 return code_ == kPropertyExpression || code_ == kThisPropertyExpression; 713 return code_ == kPropertyExpression || code_ == kThisPropertyExpression;
641 } 714 }
642 715
643 bool IsCall() { return code_ == kCallExpression; } 716 bool IsCall() { return code_ == kCallExpression; }
644 717
645 bool IsValidReferenceExpression() { 718 bool IsValidReferenceExpression() {
646 return IsIdentifier() || IsProperty(); 719 return IsIdentifier() || IsProperty();
647 } 720 }
648 721
722 bool IsValidArrowParamList() const {
723 return (ArrowParamListBit() & kBinaryOperationArrowParamList) != 0
724 && (code_ & kMultiParenthesizedExpression) == 0;
725 }
726
649 // At the moment PreParser doesn't track these expression types. 727 // At the moment PreParser doesn't track these expression types.
650 bool IsFunctionLiteral() const { return false; } 728 bool IsFunctionLiteral() const { return false; }
651 bool IsCallNew() const { return false; } 729 bool IsCallNew() const { return false; }
652 730
653 PreParserExpression AsFunctionLiteral() { return *this; } 731 PreParserExpression AsFunctionLiteral() { return *this; }
654 732
733 bool IsBinaryOperation() const {
734 return (code_ & kTypeMask) == kTypeBinaryOperation;
735 }
736
737 bool is_parenthesized() const {
738 return (code_ & kParenthesizedExpression) != 0;
739 }
740 void set_is_parenthesized(bool value) {
741 if (value) {
742 code_ |= is_parenthesized()
743 ? kMultiParenthesizedExpression
744 : kParenthesizedExpression;
745 } else {
746 code_ &= ~kParenthesizedExpression;
747 }
748 }
749
655 // Dummy implementation for making expression->somefunc() work in both Parser 750 // Dummy implementation for making expression->somefunc() work in both Parser
656 // and PreParser. 751 // and PreParser.
657 PreParserExpression* operator->() { return this; } 752 PreParserExpression* operator->() { return this; }
658 753
659 // More dummy implementations of things PreParser doesn't need to track: 754 // More dummy implementations of things PreParser doesn't need to track:
660 void set_index(int index) {} // For YieldExpressions 755 void set_index(int index) {} // For YieldExpressions
661 void set_parenthesized() {} 756 void set_parenthesized() {}
662 757
758 int position() const { return RelocInfo::kNoPosition; }
759 void set_function_token_position(int position) {}
760 void set_ast_properties(int* ast_properties) {}
761 void set_dont_optimize_reason(BailoutReason dont_optimize_reason) {}
762
763 bool operator==(const PreParserExpression& other) const {
764 return code_ == other.code_;
765 }
766 bool operator!=(const PreParserExpression& other) const {
767 return code_ != other.code_;
768 }
769
663 private: 770 private:
664 // Least significant 2 bits are used as flags. Bits 0 and 1 represent 771 // Least significant 2 bits are used as expression type. The third least
665 // identifiers or strings literals, and are mutually exclusive, but can both 772 // significant bit tracks whether an expression is parenthesized. If the
666 // be absent. If the expression is an identifier or a string literal, the 773 // expression is an identifier or a string literal, the other bits
667 // other bits describe the type (see PreParserIdentifier::Type and string 774 // describe the type/ (see PreParserIdentifier::Type and string literal
668 // literal constants below). 775 // constants below). For binary operations, the other bits are flags
776 // which further describe the contents of the expression.
669 enum { 777 enum {
670 kUnknownExpression = 0, 778 kUnknownExpression = 0,
779
780 kTypeMask = 1 | 2,
781 kParenthesizedExpression = (1 << 2),
782 kMultiParenthesizedExpression = (1 << 3),
783
671 // Identifiers 784 // Identifiers
672 kIdentifierFlag = 1, // Used to detect labels. 785 kTypeIdentifier = 1, // Used to detect labels.
673 kIdentifierShift = 3, 786 kIdentifierShift = 5,
674 787
675 kStringLiteralFlag = 2, // Used to detect directive prologue. 788 kTypeStringLiteral = 2, // Used to detect directive prologue.
676 kUnknownStringLiteral = kStringLiteralFlag, 789 kUnknownStringLiteral = kTypeStringLiteral,
677 kUseStrictString = kStringLiteralFlag | 8, 790 kUseStrictString = kTypeStringLiteral | 32,
678 kStringLiteralMask = kUseStrictString, 791 kStringLiteralMask = kUseStrictString,
679 792
793 // Binary operations. Those are needed to detect certain keywords and
794 // duplicated identifier in parameter lists for arrow functions, because
795 // they are initially parsed as comma-separated expressions.
796 kTypeBinaryOperation = 3,
797 kBinaryOperationArrowParamList = (1 << 4),
798
680 // Below here applies if neither identifier nor string literal. Reserve the 799 // Below here applies if neither identifier nor string literal. Reserve the
681 // 2 least significant bits for flags. 800 // 2 least significant bits for flags.
682 kThisExpression = 1 << 2, 801 kThisExpression = (1 << 4),
683 kThisPropertyExpression = 2 << 2, 802 kThisPropertyExpression = (2 << 4),
684 kPropertyExpression = 3 << 2, 803 kPropertyExpression = (3 << 4),
685 kCallExpression = 4 << 2 804 kCallExpression = (4 << 4)
686 }; 805 };
687 806
688 explicit PreParserExpression(int expression_code) : code_(expression_code) {} 807 explicit PreParserExpression(int expression_code) : code_(expression_code) {}
689 808
809 V8_INLINE int ArrowParamListBit() const {
810 if (IsBinaryOperation())
811 return code_ & kBinaryOperationArrowParamList;
812 if (IsIdentifier()) {
813 const PreParserIdentifier ident = AsIdentifier();
814 // A valid identifier can be an arrow function parameter list
815 // except for eval, arguments, yield, and reserved keywords.
816 if (ident.IsEval() || ident.IsArguments() || ident.IsYield()
817 || ident.IsFutureStrictReserved())
818 return 0;
819 return kBinaryOperationArrowParamList;
820 }
821 return 0;
822 }
823
690 int code_; 824 int code_;
691 }; 825 };
692 826
693 827
694 // PreParserExpressionList doesn't actually store the expressions because 828 // PreParserExpressionList doesn't actually store the expressions because
695 // PreParser doesn't need to. 829 // PreParser doesn't need to.
696 class PreParserExpressionList { 830 class PreParserExpressionList {
697 public: 831 public:
698 // These functions make list->Add(some_expression) work (and do nothing). 832 // These functions make list->Add(some_expression) work (and do nothing).
699 PreParserExpressionList() : length_(0) {} 833 PreParserExpressionList() : length_(0) {}
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
761 public: 895 public:
762 // These functions make list->Add(some_expression) work as no-ops. 896 // These functions make list->Add(some_expression) work as no-ops.
763 PreParserStatementList() {} 897 PreParserStatementList() {}
764 PreParserStatementList* operator->() { return this; } 898 PreParserStatementList* operator->() { return this; }
765 void Add(PreParserStatement, void*) {} 899 void Add(PreParserStatement, void*) {}
766 }; 900 };
767 901
768 902
769 class PreParserScope { 903 class PreParserScope {
770 public: 904 public:
771 explicit PreParserScope(PreParserScope* outer_scope, ScopeType scope_type) 905 explicit PreParserScope(PreParserScope* outer_scope,
772 : scope_type_(scope_type) { 906 ScopeType scope_type,
907 void* = NULL)
908 : scope_type_(scope_type), declared_parameters_(0) {
773 strict_mode_ = outer_scope ? outer_scope->strict_mode() : SLOPPY; 909 strict_mode_ = outer_scope ? outer_scope->strict_mode() : SLOPPY;
774 } 910 }
775 911
776 ScopeType type() { return scope_type_; } 912 ScopeType type() { return scope_type_; }
777 StrictMode strict_mode() const { return strict_mode_; } 913 StrictMode strict_mode() const { return strict_mode_; }
778 void SetStrictMode(StrictMode strict_mode) { strict_mode_ = strict_mode; } 914 void SetStrictMode(StrictMode strict_mode) { strict_mode_ = strict_mode; }
779 915
916 // TODO(aperezdc): Would allowing lazy compilation in preparser make sense?
917 bool AllowsLazyCompilation() const { return false; }
918
919 void set_start_position(int position) {}
920 void set_end_position(int position) {}
921
922 bool IsDeclared(const PreParserIdentifier& identifier) const {
923 return (declared_parameters_ & (1 << identifier.type_)) != 0;
924 }
925
926 void DeclareParameter(const PreParserIdentifier& identifier, VariableMode) {
927 declared_parameters_ |= (1 << identifier.type_);
928 }
929
930 // Allow scope->Foo() to work.
931 PreParserScope* operator->() { return this; }
932
780 private: 933 private:
781 ScopeType scope_type_; 934 ScopeType scope_type_;
782 StrictMode strict_mode_; 935 StrictMode strict_mode_;
936 int declared_parameters_;
783 }; 937 };
784 938
785 939
786 class PreParserFactory { 940 class PreParserFactory {
787 public: 941 public:
788 explicit PreParserFactory(void* extra_param1, void* extra_param2) {} 942 explicit PreParserFactory(void* extra_param1, void* extra_param2) {}
789 PreParserExpression NewStringLiteral(PreParserIdentifier identifier, 943 PreParserExpression NewStringLiteral(PreParserIdentifier identifier,
790 int pos) { 944 int pos) {
791 return PreParserExpression::Default(); 945 return PreParserExpression::Default();
792 } 946 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
833 return PreParserExpression::Property(); 987 return PreParserExpression::Property();
834 } 988 }
835 PreParserExpression NewUnaryOperation(Token::Value op, 989 PreParserExpression NewUnaryOperation(Token::Value op,
836 PreParserExpression expression, 990 PreParserExpression expression,
837 int pos) { 991 int pos) {
838 return PreParserExpression::Default(); 992 return PreParserExpression::Default();
839 } 993 }
840 PreParserExpression NewBinaryOperation(Token::Value op, 994 PreParserExpression NewBinaryOperation(Token::Value op,
841 PreParserExpression left, 995 PreParserExpression left,
842 PreParserExpression right, int pos) { 996 PreParserExpression right, int pos) {
843 return PreParserExpression::Default(); 997 return PreParserExpression::BinaryOperation(left, op, right);
844 } 998 }
845 PreParserExpression NewCompareOperation(Token::Value op, 999 PreParserExpression NewCompareOperation(Token::Value op,
846 PreParserExpression left, 1000 PreParserExpression left,
847 PreParserExpression right, int pos) { 1001 PreParserExpression right, int pos) {
848 return PreParserExpression::Default(); 1002 return PreParserExpression::Default();
849 } 1003 }
850 PreParserExpression NewAssignment(Token::Value op, 1004 PreParserExpression NewAssignment(Token::Value op,
851 PreParserExpression left, 1005 PreParserExpression left,
852 PreParserExpression right, 1006 PreParserExpression right,
853 int pos) { 1007 int pos) {
(...skipping 20 matching lines...) Expand all
874 PreParserExpression NewCall(PreParserExpression expression, 1028 PreParserExpression NewCall(PreParserExpression expression,
875 PreParserExpressionList arguments, 1029 PreParserExpressionList arguments,
876 int pos) { 1030 int pos) {
877 return PreParserExpression::Call(); 1031 return PreParserExpression::Call();
878 } 1032 }
879 PreParserExpression NewCallNew(PreParserExpression expression, 1033 PreParserExpression NewCallNew(PreParserExpression expression,
880 PreParserExpressionList arguments, 1034 PreParserExpressionList arguments,
881 int pos) { 1035 int pos) {
882 return PreParserExpression::Default(); 1036 return PreParserExpression::Default();
883 } 1037 }
1038 PreParserStatement NewReturnStatement(PreParserExpression expression,
1039 int pos) {
1040 return PreParserStatement::Default();
1041 }
1042 PreParserExpression
1043 NewFunctionLiteral(PreParserIdentifier name,
1044 PreParserScope& scope,
1045 PreParserStatementList body,
1046 int materialized_literal_count,
1047 int expected_property_count,
1048 int handler_count,
1049 int parameter_count,
1050 FunctionLiteral::ParameterFlag has_duplicate_parameters,
1051 FunctionLiteral::FunctionType function_type,
1052 FunctionLiteral::IsFunctionFlag is_function,
1053 FunctionLiteral::IsParenthesizedFlag is_parenthesized,
1054 FunctionLiteral::IsGeneratorFlag is_generator,
1055 int position) {
1056 return PreParserExpression::Default();
1057 }
1058
1059 // Return the object itself as AstVisitor and implement the needed
1060 // dummy method right in this class.
1061 PreParserFactory* visitor() { return this; }
1062 BailoutReason dont_optimize_reason() { return kNoReason; }
1063 int* ast_properties() { static int dummy = 42; return &dummy; }
884 }; 1064 };
885 1065
886 1066
887 class PreParser; 1067 class PreParser;
888 1068
889 class PreParserTraits { 1069 class PreParserTraits {
890 public: 1070 public:
891 struct Type { 1071 struct Type {
892 // TODO(marja): To be removed. The Traits object should contain all the data 1072 // TODO(marja): To be removed. The Traits object should contain all the data
893 // it needs. 1073 // it needs.
894 typedef PreParser* Parser; 1074 typedef PreParser* Parser;
895 1075
896 // Used by FunctionState and BlockState. 1076 // Used by FunctionState and BlockState.
897 typedef PreParserScope Scope; 1077 typedef PreParserScope Scope;
1078 typedef PreParserScope ScopePtr;
1079
898 // PreParser doesn't need to store generator variables. 1080 // PreParser doesn't need to store generator variables.
899 typedef void GeneratorVariable; 1081 typedef void GeneratorVariable;
900 // No interaction with Zones. 1082 // No interaction with Zones.
901 typedef void Zone; 1083 typedef void Zone;
902 1084
1085 typedef int AstProperties;
1086 typedef Vector<PreParserIdentifier> ParameterIdentifierVector;
1087
903 // Return types for traversing functions. 1088 // Return types for traversing functions.
904 typedef PreParserIdentifier Identifier; 1089 typedef PreParserIdentifier Identifier;
905 typedef PreParserExpression Expression; 1090 typedef PreParserExpression Expression;
906 typedef PreParserExpression YieldExpression; 1091 typedef PreParserExpression YieldExpression;
907 typedef PreParserExpression FunctionLiteral; 1092 typedef PreParserExpression FunctionLiteral;
908 typedef PreParserExpression ObjectLiteralProperty; 1093 typedef PreParserExpression ObjectLiteralProperty;
909 typedef PreParserExpression Literal; 1094 typedef PreParserExpression Literal;
910 typedef PreParserExpressionList ExpressionList; 1095 typedef PreParserExpressionList ExpressionList;
911 typedef PreParserExpressionList PropertyList; 1096 typedef PreParserExpressionList PropertyList;
912 typedef PreParserStatementList StatementList; 1097 typedef PreParserStatementList StatementList;
(...skipping 22 matching lines...) Expand all
935 } 1120 }
936 1121
937 static bool IsIdentifier(PreParserExpression expression) { 1122 static bool IsIdentifier(PreParserExpression expression) {
938 return expression.IsIdentifier(); 1123 return expression.IsIdentifier();
939 } 1124 }
940 1125
941 static PreParserIdentifier AsIdentifier(PreParserExpression expression) { 1126 static PreParserIdentifier AsIdentifier(PreParserExpression expression) {
942 return expression.AsIdentifier(); 1127 return expression.AsIdentifier();
943 } 1128 }
944 1129
1130 static bool IsFutureStrictReserved(PreParserIdentifier identifier) {
1131 return identifier.IsYield() || identifier.IsFutureStrictReserved();
1132 }
1133
945 static bool IsBoilerplateProperty(PreParserExpression property) { 1134 static bool IsBoilerplateProperty(PreParserExpression property) {
946 // PreParser doesn't count boilerplate properties. 1135 // PreParser doesn't count boilerplate properties.
947 return false; 1136 return false;
948 } 1137 }
949 1138
950 static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) { 1139 static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) {
951 return false; 1140 return false;
952 } 1141 }
953 1142
954 // Functions for encapsulating the differences between parsing and preparsing; 1143 // Functions for encapsulating the differences between parsing and preparsing;
955 // operations interleaved with the recursive descent. 1144 // operations interleaved with the recursive descent.
956 static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) { 1145 static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) {
957 // PreParser should not use FuncNameInferrer. 1146 // PreParser should not use FuncNameInferrer.
958 UNREACHABLE(); 1147 UNREACHABLE();
959 } 1148 }
960 static void PushPropertyName(FuncNameInferrer* fni, 1149 static void PushPropertyName(FuncNameInferrer* fni,
961 PreParserExpression expression) { 1150 PreParserExpression expression) {
962 // PreParser should not use FuncNameInferrer. 1151 // PreParser should not use FuncNameInferrer.
963 UNREACHABLE(); 1152 UNREACHABLE();
964 } 1153 }
1154 static void InferFunctionName(FuncNameInferrer* fni,
1155 PreParserExpression expression) {
1156 // PreParser should not use FuncNameInferrer.
1157 UNREACHABLE();
1158 }
965 1159
966 static void CheckFunctionLiteralInsideTopLevelObjectLiteral( 1160 static void CheckFunctionLiteralInsideTopLevelObjectLiteral(
967 PreParserScope* scope, PreParserExpression value, bool* has_function) {} 1161 PreParserScope* scope, PreParserExpression value, bool* has_function) {}
968 1162
969 static void CheckAssigningFunctionLiteralToProperty( 1163 static void CheckAssigningFunctionLiteralToProperty(
970 PreParserExpression left, PreParserExpression right) {} 1164 PreParserExpression left, PreParserExpression right) {}
971 1165
972 // PreParser doesn't need to keep track of eval calls. 1166 // PreParser doesn't need to keep track of eval calls.
973 static void CheckPossibleEvalCall(PreParserExpression expression, 1167 static void CheckPossibleEvalCall(PreParserExpression expression,
974 PreParserScope* scope) {} 1168 PreParserScope* scope) {}
(...skipping 23 matching lines...) Expand all
998 return PreParserExpression::Default(); 1192 return PreParserExpression::Default();
999 } 1193 }
1000 PreParserExpression NewThrowSyntaxError( 1194 PreParserExpression NewThrowSyntaxError(
1001 const char* type, Handle<Object> arg, int pos) { 1195 const char* type, Handle<Object> arg, int pos) {
1002 return PreParserExpression::Default(); 1196 return PreParserExpression::Default();
1003 } 1197 }
1004 PreParserExpression NewThrowTypeError( 1198 PreParserExpression NewThrowTypeError(
1005 const char* type, Handle<Object> arg, int pos) { 1199 const char* type, Handle<Object> arg, int pos) {
1006 return PreParserExpression::Default(); 1200 return PreParserExpression::Default();
1007 } 1201 }
1202 PreParserScope NewScope(PreParserScope* outer_scope,
1203 ScopeType scope_type) {
1204 return PreParserScope(outer_scope, scope_type);
1205 }
1008 1206
1009 // Reporting errors. 1207 // Reporting errors.
1010 void ReportMessageAt(Scanner::Location location, 1208 void ReportMessageAt(Scanner::Location location,
1011 const char* message, 1209 const char* message,
1012 const char* arg = NULL, 1210 const char* arg = NULL,
1013 bool is_reference_error = false); 1211 bool is_reference_error = false);
1014 void ReportMessageAt(int start_pos, 1212 void ReportMessageAt(int start_pos,
1015 int end_pos, 1213 int end_pos,
1016 const char* message, 1214 const char* message,
1017 const char* arg = NULL, 1215 const char* arg = NULL,
1018 bool is_reference_error = false); 1216 bool is_reference_error = false);
1019 1217
1020 // "null" return type creators. 1218 // "null" return type creators.
1021 static PreParserIdentifier EmptyIdentifier() { 1219 static PreParserIdentifier EmptyIdentifier() {
1022 return PreParserIdentifier::Default(); 1220 return PreParserIdentifier::Default();
1023 } 1221 }
1222 static PreParserIdentifier EmptyIdentifierString() {
1223 return PreParserIdentifier::Default();
1224 }
1024 static PreParserExpression EmptyExpression() { 1225 static PreParserExpression EmptyExpression() {
1025 return PreParserExpression::Default(); 1226 return PreParserExpression::Default();
1026 } 1227 }
1228 static PreParserExpression EmptyArrowParamList() {
1229 return PreParserExpression::EmptyArrowParamList();
1230 }
1027 static PreParserExpression EmptyLiteral() { 1231 static PreParserExpression EmptyLiteral() {
1028 return PreParserExpression::Default(); 1232 return PreParserExpression::Default();
1029 } 1233 }
1030 static PreParserExpressionList NullExpressionList() { 1234 static PreParserExpressionList NullExpressionList() {
1031 return PreParserExpressionList(); 1235 return PreParserExpressionList();
1032 } 1236 }
1033 1237
1034 // Odd-ball literal creators. 1238 // Odd-ball literal creators.
1035 static PreParserExpression GetLiteralTheHole(int position, 1239 static PreParserExpression GetLiteralTheHole(int position,
1036 PreParserFactory* factory) { 1240 PreParserFactory* factory) {
1037 return PreParserExpression::Default(); 1241 return PreParserExpression::Default();
1038 } 1242 }
1039 1243
1040 // Producing data during the recursive descent. 1244 // Producing data during the recursive descent.
1041 PreParserIdentifier GetSymbol(Scanner* scanner); 1245 PreParserIdentifier GetSymbol(Scanner* scanner);
1042 1246
1043 static PreParserIdentifier GetNextSymbol(Scanner* scanner) { 1247 static PreParserIdentifier GetNextSymbol(Scanner* scanner) {
1044 return PreParserIdentifier::Default(); 1248 return PreParserIdentifier::Default();
1045 } 1249 }
1046 1250
1047 static PreParserExpression ThisExpression(PreParserScope* scope, 1251 static PreParserExpression ThisExpression(PreParserScope* scope,
1048 PreParserFactory* factory) { 1252 PreParserFactory* factory,
1253 int pos) {
1049 return PreParserExpression::This(); 1254 return PreParserExpression::This();
1050 } 1255 }
1051 1256
1052 static PreParserExpression ExpressionFromLiteral( 1257 static PreParserExpression ExpressionFromLiteral(
1053 Token::Value token, int pos, Scanner* scanner, 1258 Token::Value token, int pos, Scanner* scanner,
1054 PreParserFactory* factory) { 1259 PreParserFactory* factory) {
1055 return PreParserExpression::Default(); 1260 return PreParserExpression::Default();
1056 } 1261 }
1057 1262
1058 static PreParserExpression ExpressionFromIdentifier( 1263 static PreParserExpression ExpressionFromIdentifier(
(...skipping 11 matching lines...) Expand all
1070 } 1275 }
1071 1276
1072 static PreParserStatementList NewStatementList(int size, void* zone) { 1277 static PreParserStatementList NewStatementList(int size, void* zone) {
1073 return PreParserStatementList(); 1278 return PreParserStatementList();
1074 } 1279 }
1075 1280
1076 static PreParserExpressionList NewPropertyList(int size, void* zone) { 1281 static PreParserExpressionList NewPropertyList(int size, void* zone) {
1077 return PreParserExpressionList(); 1282 return PreParserExpressionList();
1078 } 1283 }
1079 1284
1285 V8_INLINE void SkipLazyFunctionBody(
1286 PreParserIdentifier function_name,
1287 int* materialized_literal_count,
1288 int* expected_property_count,
1289 bool* ok) {
1290 UNREACHABLE();
1291 }
1292
1293 V8_INLINE PreParserStatementList ParseEagerFunctionBody(
1294 PreParserIdentifier function_name,
1295 int pos,
1296 Variable* fvar,
1297 Token::Value fvar_init_op,
1298 bool is_generator,
1299 bool* ok);
1300
1301 // Utility functions
1302 Vector<PreParserIdentifier> ParameterListFromExpression(
1303 PreParserExpression expression) {
1304 return Vector<PreParserIdentifier>::empty();
1305 }
1306 bool IsValidArrowFunctionParameterList(PreParserExpression expression) {
1307 // TODO(aperez): Detect duplicated identifiers in paramlists.
1308 return expression.IsValidArrowParamList();
1309 }
1310 static AstValueFactory* ast_value_factory() { return NULL; }
1311
1312 void CheckConflictingVarDeclarations(
1313 PreParserScope scope,
1314 bool* ok) {}
1315
1080 // Temporary glue; these functions will move to ParserBase. 1316 // Temporary glue; these functions will move to ParserBase.
1081 PreParserExpression ParseV8Intrinsic(bool* ok); 1317 PreParserExpression ParseV8Intrinsic(bool* ok);
1082 PreParserExpression ParseFunctionLiteral( 1318 PreParserExpression ParseFunctionLiteral(
1083 PreParserIdentifier name, 1319 PreParserIdentifier name,
1084 Scanner::Location function_name_location, 1320 Scanner::Location function_name_location,
1085 bool name_is_strict_reserved, 1321 bool name_is_strict_reserved,
1086 bool is_generator, 1322 bool is_generator,
1087 int function_token_position, 1323 int function_token_position,
1088 FunctionLiteral::FunctionType type, 1324 FunctionLiteral::FunctionType type,
1089 FunctionLiteral::ArityRestriction arity_restriction, 1325 FunctionLiteral::ArityRestriction arity_restriction,
(...skipping 30 matching lines...) Expand all
1120 PreParser(Scanner* scanner, ParserRecorder* log, uintptr_t stack_limit) 1356 PreParser(Scanner* scanner, ParserRecorder* log, uintptr_t stack_limit)
1121 : ParserBase<PreParserTraits>(scanner, stack_limit, NULL, log, NULL, 1357 : ParserBase<PreParserTraits>(scanner, stack_limit, NULL, log, NULL,
1122 this) {} 1358 this) {}
1123 1359
1124 // Pre-parse the program from the character stream; returns true on 1360 // Pre-parse the program from the character stream; returns true on
1125 // success (even if parsing failed, the pre-parse data successfully 1361 // success (even if parsing failed, the pre-parse data successfully
1126 // captured the syntax error), and false if a stack-overflow happened 1362 // captured the syntax error), and false if a stack-overflow happened
1127 // during parsing. 1363 // during parsing.
1128 PreParseResult PreParseProgram() { 1364 PreParseResult PreParseProgram() {
1129 PreParserScope scope(scope_, GLOBAL_SCOPE); 1365 PreParserScope scope(scope_, GLOBAL_SCOPE);
1130 FunctionState top_scope(&function_state_, &scope_, &scope, NULL); 1366 FunctionState top_scope(&function_state_, &scope_, &scope,
1367 zone(), this->ast_value_factory());
1131 bool ok = true; 1368 bool ok = true;
1132 int start_position = scanner()->peek_location().beg_pos; 1369 int start_position = scanner()->peek_location().beg_pos;
1133 ParseSourceElements(Token::EOS, &ok); 1370 ParseSourceElements(Token::EOS, &ok);
1134 if (stack_overflow()) return kPreParseStackOverflow; 1371 if (stack_overflow()) return kPreParseStackOverflow;
1135 if (!ok) { 1372 if (!ok) {
1136 ReportUnexpectedToken(scanner()->current_token()); 1373 ReportUnexpectedToken(scanner()->current_token());
1137 } else if (scope_->strict_mode() == STRICT) { 1374 } else if (scope_->strict_mode() == STRICT) {
1138 CheckOctalLiteral(start_position, scanner()->location().end_pos, &ok); 1375 CheckOctalLiteral(start_position, scanner()->location().end_pos, &ok);
1139 } 1376 }
1140 return kPreParseSuccess; 1377 return kPreParseSuccess;
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1202 Statement ParseDoWhileStatement(bool* ok); 1439 Statement ParseDoWhileStatement(bool* ok);
1203 Statement ParseWhileStatement(bool* ok); 1440 Statement ParseWhileStatement(bool* ok);
1204 Statement ParseForStatement(bool* ok); 1441 Statement ParseForStatement(bool* ok);
1205 Statement ParseThrowStatement(bool* ok); 1442 Statement ParseThrowStatement(bool* ok);
1206 Statement ParseTryStatement(bool* ok); 1443 Statement ParseTryStatement(bool* ok);
1207 Statement ParseDebuggerStatement(bool* ok); 1444 Statement ParseDebuggerStatement(bool* ok);
1208 Expression ParseConditionalExpression(bool accept_IN, bool* ok); 1445 Expression ParseConditionalExpression(bool accept_IN, bool* ok);
1209 Expression ParseObjectLiteral(bool* ok); 1446 Expression ParseObjectLiteral(bool* ok);
1210 Expression ParseV8Intrinsic(bool* ok); 1447 Expression ParseV8Intrinsic(bool* ok);
1211 1448
1449 V8_INLINE void SkipLazyFunctionBody(
1450 PreParserIdentifier function_name,
1451 int* materialized_literal_count,
1452 int* expected_property_count,
1453 bool* ok);
1454 V8_INLINE PreParserStatementList ParseEagerFunctionBody(
1455 PreParserIdentifier function_name,
1456 int pos,
1457 Variable* fvar,
1458 Token::Value fvar_init_op,
1459 bool is_generator,
1460 bool* ok);
1461
1212 Expression ParseFunctionLiteral( 1462 Expression ParseFunctionLiteral(
1213 Identifier name, 1463 Identifier name,
1214 Scanner::Location function_name_location, 1464 Scanner::Location function_name_location,
1215 bool name_is_strict_reserved, 1465 bool name_is_strict_reserved,
1216 bool is_generator, 1466 bool is_generator,
1217 int function_token_pos, 1467 int function_token_pos,
1218 FunctionLiteral::FunctionType function_type, 1468 FunctionLiteral::FunctionType function_type,
1219 FunctionLiteral::ArityRestriction arity_restriction, 1469 FunctionLiteral::ArityRestriction arity_restriction,
1220 bool* ok); 1470 bool* ok);
1221 void ParseLazyFunctionLiteralBody(bool* ok); 1471 void ParseLazyFunctionLiteralBody(bool* ok);
1222 1472
1223 bool CheckInOrOf(bool accept_OF); 1473 bool CheckInOrOf(bool accept_OF);
1224 }; 1474 };
1225 1475
1476
1477 PreParserStatementList PreParser::ParseEagerFunctionBody(
1478 PreParserIdentifier function_name,
1479 int pos,
1480 Variable* fvar,
1481 Token::Value fvar_init_op,
1482 bool is_generator,
1483 bool* ok) {
1484 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
1485
1486 ParseSourceElements(Token::RBRACE, ok);
1487 if (!*ok) return PreParserStatementList();
1488
1489 Expect(Token::RBRACE, ok);
1490 return PreParserStatementList();
1491 }
1492
1493
1494 PreParserStatementList PreParserTraits::ParseEagerFunctionBody(
1495 PreParserIdentifier function_name,
1496 int pos,
1497 Variable* fvar,
1498 Token::Value fvar_init_op,
1499 bool is_generator,
1500 bool* ok) {
1501 return pre_parser_->ParseEagerFunctionBody(function_name,
1502 pos, fvar, fvar_init_op, is_generator, ok);
1503 }
1504
1505
1226 template<class Traits> 1506 template<class Traits>
1227 ParserBase<Traits>::FunctionState::FunctionState( 1507 ParserBase<Traits>::FunctionState::FunctionState(
1228 FunctionState** function_state_stack, 1508 FunctionState** function_state_stack,
1229 typename Traits::Type::Scope** scope_stack, 1509 typename Traits::Type::Scope** scope_stack,
1230 typename Traits::Type::Scope* scope, 1510 typename Traits::Type::Scope* scope,
1231 typename Traits::Type::Zone* extra_param, 1511 typename Traits::Type::Zone* extra_param,
1232 AstValueFactory* ast_value_factory) 1512 AstValueFactory* ast_value_factory)
1233 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize), 1513 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize),
1234 next_handler_index_(0), 1514 next_handler_index_(0),
1235 expected_property_count_(0), 1515 expected_property_count_(0),
1236 is_generator_(false), 1516 is_generator_(false),
1237 generator_object_variable_(NULL), 1517 generator_object_variable_(NULL),
1238 function_state_stack_(function_state_stack), 1518 function_state_stack_(function_state_stack),
1239 outer_function_state_(*function_state_stack), 1519 outer_function_state_(*function_state_stack),
1240 scope_stack_(scope_stack), 1520 scope_stack_(scope_stack),
1241 outer_scope_(*scope_stack), 1521 outer_scope_(*scope_stack),
1242 saved_ast_node_id_(0), 1522 saved_ast_node_id_(0),
1243 extra_param_(extra_param), 1523 extra_param_(extra_param),
1244 factory_(extra_param, ast_value_factory) { 1524 factory_(extra_param, ast_value_factory) {
1245 *scope_stack_ = scope; 1525 *scope_stack_ = scope;
1246 *function_state_stack = this; 1526 *function_state_stack = this;
1247 Traits::SetUpFunctionState(this, extra_param); 1527 Traits::SetUpFunctionState(this, extra_param);
1248 } 1528 }
1249 1529
1250 1530
1251 template<class Traits> 1531 template<class Traits>
1532 ParserBase<Traits>::FunctionState::FunctionState(
1533 FunctionState** function_state_stack,
1534 typename Traits::Type::Scope** scope_stack,
1535 typename Traits::Type::Scope** scope,
1536 typename Traits::Type::Zone* extra_param,
1537 AstValueFactory* ast_value_factory)
1538 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize),
1539 next_handler_index_(0),
1540 expected_property_count_(0),
1541 is_generator_(false),
1542 generator_object_variable_(NULL),
1543 function_state_stack_(function_state_stack),
1544 outer_function_state_(*function_state_stack),
1545 scope_stack_(scope_stack),
1546 outer_scope_(*scope_stack),
1547 saved_ast_node_id_(0),
1548 extra_param_(extra_param),
1549 factory_(extra_param, ast_value_factory) {
1550 *scope_stack_ = *scope;
1551 *function_state_stack = this;
1552 Traits::SetUpFunctionState(this, extra_param);
1553 }
1554
1555
1556 template<class Traits>
1252 ParserBase<Traits>::FunctionState::~FunctionState() { 1557 ParserBase<Traits>::FunctionState::~FunctionState() {
1253 *scope_stack_ = outer_scope_; 1558 *scope_stack_ = outer_scope_;
1254 *function_state_stack_ = outer_function_state_; 1559 *function_state_stack_ = outer_function_state_;
1255 Traits::TearDownFunctionState(this, extra_param_); 1560 Traits::TearDownFunctionState(this, extra_param_);
1256 } 1561 }
1257 1562
1258 1563
1259 template<class Traits> 1564 template<class Traits>
1260 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) { 1565 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) {
1261 Scanner::Location source_location = scanner()->location(); 1566 Scanner::Location source_location = scanner()->location();
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
1408 // ObjectLiteral 1713 // ObjectLiteral
1409 // RegExpLiteral 1714 // RegExpLiteral
1410 // '(' Expression ')' 1715 // '(' Expression ')'
1411 1716
1412 int pos = peek_position(); 1717 int pos = peek_position();
1413 ExpressionT result = this->EmptyExpression(); 1718 ExpressionT result = this->EmptyExpression();
1414 Token::Value token = peek(); 1719 Token::Value token = peek();
1415 switch (token) { 1720 switch (token) {
1416 case Token::THIS: { 1721 case Token::THIS: {
1417 Consume(Token::THIS); 1722 Consume(Token::THIS);
1418 result = this->ThisExpression(scope_, factory()); 1723 result = this->ThisExpression(scope_, factory(), position());
1419 break; 1724 break;
1420 } 1725 }
1421 1726
1422 case Token::NULL_LITERAL: 1727 case Token::NULL_LITERAL:
1423 case Token::TRUE_LITERAL: 1728 case Token::TRUE_LITERAL:
1424 case Token::FALSE_LITERAL: 1729 case Token::FALSE_LITERAL:
1425 case Token::NUMBER: 1730 case Token::NUMBER:
1426 Next(); 1731 Next();
1427 result = this->ExpressionFromLiteral(token, pos, scanner(), factory()); 1732 result = this->ExpressionFromLiteral(token, pos, scanner(), factory());
1428 break; 1733 break;
(...skipping 24 matching lines...) Expand all
1453 case Token::LBRACK: 1758 case Token::LBRACK:
1454 result = this->ParseArrayLiteral(CHECK_OK); 1759 result = this->ParseArrayLiteral(CHECK_OK);
1455 break; 1760 break;
1456 1761
1457 case Token::LBRACE: 1762 case Token::LBRACE:
1458 result = this->ParseObjectLiteral(CHECK_OK); 1763 result = this->ParseObjectLiteral(CHECK_OK);
1459 break; 1764 break;
1460 1765
1461 case Token::LPAREN: 1766 case Token::LPAREN:
1462 Consume(Token::LPAREN); 1767 Consume(Token::LPAREN);
1463 // Heuristically try to detect immediately called functions before 1768 if (allow_arrow_functions() && peek() == Token::RPAREN) {
1464 // seeing the call parentheses. 1769 // Arrow functions are the only expression type constructions
1465 parenthesized_function_ = (peek() == Token::FUNCTION); 1770 // for which an empty parameter list "()" is valid input.
1466 result = this->ParseExpression(true, CHECK_OK); 1771 Consume(Token::RPAREN);
1467 Expect(Token::RPAREN, CHECK_OK); 1772 return this->ParseArrowFunctionLiteral(pos,
1773 this->EmptyArrowParamList(),
1774 CHECK_OK);
1775 } else {
1776 // Heuristically try to detect immediately called functions before
1777 // seeing the call parentheses.
1778 parenthesized_function_ = (peek() == Token::FUNCTION);
1779 result = this->ParseExpression(true, CHECK_OK);
1780 result->set_is_parenthesized(true);
1781 Expect(Token::RPAREN, CHECK_OK);
1782 }
1468 break; 1783 break;
1469 1784
1470 case Token::MOD: 1785 case Token::MOD:
1471 if (allow_natives_syntax() || extension_ != NULL) { 1786 if (allow_natives_syntax() || extension_ != NULL) {
1472 result = this->ParseV8Intrinsic(CHECK_OK); 1787 result = this->ParseV8Intrinsic(CHECK_OK);
1473 break; 1788 break;
1474 } 1789 }
1475 // If we're not allowing special syntax we fall-through to the 1790 // If we're not allowing special syntax we fall-through to the
1476 // default case. 1791 // default case.
1477 1792
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
1725 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList)); 2040 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList));
1726 return result; 2041 return result;
1727 } 2042 }
1728 2043
1729 // Precedence = 2 2044 // Precedence = 2
1730 template <class Traits> 2045 template <class Traits>
1731 typename ParserBase<Traits>::ExpressionT 2046 typename ParserBase<Traits>::ExpressionT
1732 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) { 2047 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) {
1733 // AssignmentExpression :: 2048 // AssignmentExpression ::
1734 // ConditionalExpression 2049 // ConditionalExpression
2050 // ArrowFunction
1735 // YieldExpression 2051 // YieldExpression
1736 // LeftHandSideExpression AssignmentOperator AssignmentExpression 2052 // LeftHandSideExpression AssignmentOperator AssignmentExpression
1737 2053
1738 Scanner::Location lhs_location = scanner()->peek_location(); 2054 Scanner::Location lhs_location = scanner()->peek_location();
1739 2055
1740 if (peek() == Token::YIELD && is_generator()) { 2056 if (peek() == Token::YIELD && is_generator()) {
1741 return this->ParseYieldExpression(ok); 2057 return this->ParseYieldExpression(ok);
1742 } 2058 }
1743 2059
1744 if (fni_ != NULL) fni_->Enter(); 2060 if (fni_ != NULL) fni_->Enter();
1745 ExpressionT expression = 2061 ExpressionT expression =
1746 this->ParseConditionalExpression(accept_IN, CHECK_OK); 2062 this->ParseConditionalExpression(accept_IN, CHECK_OK);
1747 2063
2064 if (allow_arrow_functions() && peek() == Token::ARROW)
2065 return this->ParseArrowFunctionLiteral(lhs_location.beg_pos,
2066 expression,
2067 CHECK_OK);
2068
1748 if (!Token::IsAssignmentOp(peek())) { 2069 if (!Token::IsAssignmentOp(peek())) {
1749 if (fni_ != NULL) fni_->Leave(); 2070 if (fni_ != NULL) fni_->Leave();
1750 // Parsed conditional expression only (no assignment). 2071 // Parsed conditional expression only (no assignment).
1751 return expression; 2072 return expression;
1752 } 2073 }
1753 2074
1754 expression = this->CheckAndRewriteReferenceExpression( 2075 expression = this->CheckAndRewriteReferenceExpression(
1755 expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK); 2076 expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK);
1756 expression = this->MarkExpressionAsLValue(expression); 2077 expression = this->MarkExpressionAsLValue(expression);
1757 2078
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after
2143 } 2464 }
2144 default: 2465 default:
2145 return expression; 2466 return expression;
2146 } 2467 }
2147 } 2468 }
2148 ASSERT(false); 2469 ASSERT(false);
2149 return this->EmptyExpression(); 2470 return this->EmptyExpression();
2150 } 2471 }
2151 2472
2152 2473
2474 template <class Traits>
2475 typename ParserBase<Traits>::ExpressionT
2476 ParserBase<Traits>::ParseArrowFunctionLiteralBody(
marja 2014/06/26 14:38:13 Nit: reorder the functions here to match the order
2477 FunctionState* function_state,
2478 typename Traits::Type::ScopePtr scope,
2479 int num_parameters,
2480 const Scanner::Location& eval_args_error_loc,
2481 const Scanner::Location& dupe_error_loc,
2482 const Scanner::Location& reserved_loc,
2483 FunctionLiteral::IsParenthesizedFlag parenthesized,
2484 int start_pos,
2485 bool* ok) {
2486
2487 typename Traits::Type::StatementList body;
2488 int materialized_literal_count = -1;
2489 int expected_property_count = -1;
2490
2491 Expect(Token::ARROW, CHECK_OK);
2492
2493 if (peek() == Token::LBRACE) {
2494 // Multiple statemente body
2495 Consume(Token::LBRACE);
2496
2497 bool is_lazily_parsed = (mode() == PARSE_LAZILY &&
2498 scope_->AllowsLazyCompilation() &&
2499 !parenthesized_function_);
2500 parenthesized_function_ = false; // This Was set for this funciton only.
marja 2014/06/26 14:38:13 1) Why do you need to set parenthesized_function_
2501
2502 if (is_lazily_parsed) {
2503 this->SkipLazyFunctionBody(this->EmptyIdentifier(),
2504 &materialized_literal_count,
2505 &expected_property_count,
2506 CHECK_OK);
2507 } else {
2508 body = this->ParseEagerFunctionBody(this->EmptyIdentifier(),
2509 RelocInfo::kNoPosition,
2510 NULL,
2511 Token::INIT_VAR,
2512 false, // Not a generator.
2513 CHECK_OK);
2514 }
2515 } else {
2516 // Single-expression body
2517 parenthesized_function_ = false;
2518 ParseAssignmentExpression(true, CHECK_OK);
2519 }
2520
2521 scope->set_start_position(start_pos);
2522 scope->set_end_position(scanner()->location().end_pos);
2523
2524 this->CheckStrictFunctionNameAndParameters(this->EmptyIdentifier(),
2525 false,
2526 Scanner::Location::invalid(),
2527 Scanner::Location::invalid(),
2528 dupe_error_loc,
2529 Scanner::Location::invalid(),
2530 CHECK_OK);
2531
2532 // Validate strict mode.
2533 if (strict_mode() == STRICT) {
2534 CheckOctalLiteral(start_pos,
2535 scanner()->location().end_pos,
2536 CHECK_OK);
2537 }
2538
2539 if (allow_harmony_scoping() && strict_mode() == STRICT)
2540 this->CheckConflictingVarDeclarations(scope, CHECK_OK);
2541
2542 return this->EmptyExpression();
2543 }
2544
2545
2546 template <class Traits>
2547 typename ParserBase<Traits>::ExpressionT
2548 ParserBase<Traits>::ParseArrowFunctionLiteral(bool* ok) {
2549 // TODO(aperez): Change this to use ARROW_SCOPE
2550 typename Traits::Type::ScopePtr scope =
2551 this->NewScope(scope_, FUNCTION_SCOPE);
2552
2553 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_
2554 ? FunctionLiteral::kIsParenthesized
2555 : FunctionLiteral::kNotParenthesized;
2556 parenthesized_function_ = false;
2557
2558 int start_pos = position();
2559 int num_parameters = 0;
2560 FunctionState function_state(&function_state_, &scope_, &scope,
2561 zone(), this->ast_value_factory());
2562
2563 Scanner::Location eval_args_error_loc = Scanner::Location::invalid();
2564 Scanner::Location dupe_error_loc = Scanner::Location::invalid();
2565 Scanner::Location reserved_loc = Scanner::Location::invalid();
2566
2567 if (peek() == Token::LPAREN) {
2568 // Parse a parenthesized parameter list.
2569 Consume(Token::LPAREN);
2570 bool done = (peek() == Token::RPAREN);
2571 while (!done) {
2572 bool is_strict_reserved = false;
2573 IdentifierT param_name =
2574 ParseIdentifierOrStrictReservedWord(&is_strict_reserved,
2575 CHECK_OK);
2576
2577 // Store locations for possible future error reports.
2578 if (!eval_args_error_loc.IsValid() &&
2579 this->IsEvalOrArguments(param_name)) {
2580 eval_args_error_loc = scanner()->location();
2581 }
2582 if (!reserved_loc.IsValid() && is_strict_reserved) {
2583 reserved_loc = scanner()->location();
2584 }
2585 if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) {
2586 dupe_error_loc = scanner()->location();
2587 }
2588
2589 scope_->DeclareParameter(param_name, VAR);
2590 num_parameters++;
2591 if (num_parameters > Code::kMaxArguments) {
2592 this->ReportMessageAt(scanner()->location(), "too_many_parameters");
2593 *ok = false;
2594 return this->EmptyExpression();
2595 }
2596 done = (peek() == Token::RPAREN);
2597 if (!done) Expect(Token::COMMA, CHECK_OK);
2598 }
2599 Expect(Token::RPAREN, CHECK_OK);
2600 } else {
2601 // Parse a single parameter identifier.
2602 bool is_strict_reserved = false;
2603 IdentifierT param_name =
2604 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
2605
2606 // Store locations for possible future error reports.
2607 if (this->IsEvalOrArguments(param_name))
2608 eval_args_error_loc = scanner()->location();
2609 if (is_strict_reserved)
2610 reserved_loc = scanner()->location();
2611
2612 scope_->DeclareParameter(param_name, VAR);
2613 }
2614
2615 return ParseArrowFunctionLiteralBody(&function_state,
2616 scope,
2617 num_parameters,
2618 eval_args_error_loc,
2619 dupe_error_loc,
2620 reserved_loc,
2621 parenthesized,
2622 start_pos,
2623 CHECK_OK);
2624 }
2625
2626
2627 template <class Traits>
2628 typename ParserBase<Traits>::ExpressionT
2629 ParserBase<Traits>::ParseArrowFunctionLiteral(int start_pos,
2630 ExpressionT params_ast,
2631 bool* ok) {
2632 if (!this->IsValidArrowFunctionParameterList(params_ast)) {
2633 ReportMessageAt(
2634 Scanner::Location(start_pos, scanner()->location().beg_pos),
2635 "strict_parameter_list");
2636 *ok = false;
2637 return this->EmptyExpression();
2638 }
2639
2640 // TODO(aperez): Change this to use ARROW_SCOPE
2641 typename Traits::Type::ScopePtr scope =
2642 this->NewScope(scope_, FUNCTION_SCOPE);
2643
2644 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_
2645 ? FunctionLiteral::kIsParenthesized
2646 : FunctionLiteral::kNotParenthesized;
2647 parenthesized_function_ = false;
2648 FunctionState function_state(&function_state_, &scope_, &scope,
2649 zone(), this->ast_value_factory());
2650 typename Traits::Type::ParameterIdentifierVector params =
2651 Traits::ParameterListFromExpression(params_ast);
2652 Scanner::Location dupe_error_loc = Scanner::Location::invalid();
2653
2654 if (params.length() > Code::kMaxArguments) {
2655 ReportMessageAt(Scanner::Location(params_ast->position(), position()),
2656 "too_many_parameters");
2657 *ok = false;
2658 return this->EmptyExpression();
2659 }
2660
2661 // The vector has the items in reverse order.
2662 for (int i = params.length() - 1; i >= 0; --i) {
2663 const IdentifierT param_name = params.at(i)->raw_name();
2664 if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) {
2665 int param_pos = params.at(i)->position();
2666 dupe_error_loc = Scanner::Location(param_pos,
2667 param_pos + param_name->length());
2668 }
2669 scope_->DeclareParameter(param_name, VAR);
2670 }
2671
2672 return ParseArrowFunctionLiteralBody(&function_state,
2673 scope,
2674 params.length(),
2675 Scanner::Location::invalid(),
2676 dupe_error_loc,
2677 Scanner::Location::invalid(),
2678 parenthesized,
2679 start_pos,
2680 CHECK_OK);
2681 }
2682
2683
2153 template <typename Traits> 2684 template <typename Traits>
2154 typename ParserBase<Traits>::ExpressionT 2685 typename ParserBase<Traits>::ExpressionT
2155 ParserBase<Traits>::CheckAndRewriteReferenceExpression( 2686 ParserBase<Traits>::CheckAndRewriteReferenceExpression(
2156 ExpressionT expression, 2687 ExpressionT expression,
2157 Scanner::Location location, const char* message, bool* ok) { 2688 Scanner::Location location, const char* message, bool* ok) {
2158 if (strict_mode() == STRICT && this->IsIdentifier(expression) && 2689 if (strict_mode() == STRICT && this->IsIdentifier(expression) &&
2159 this->IsEvalOrArguments(this->AsIdentifier(expression))) { 2690 this->IsEvalOrArguments(this->AsIdentifier(expression))) {
2160 this->ReportMessageAt(location, "strict_eval_arguments", false); 2691 this->ReportMessageAt(location, "strict_eval_arguments", false);
2161 *ok = false; 2692 *ok = false;
2162 return this->EmptyExpression(); 2693 return this->EmptyExpression();
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
2206 parser()->ReportMessage("accessor_get_set"); 2737 parser()->ReportMessage("accessor_get_set");
2207 } 2738 }
2208 *ok = false; 2739 *ok = false;
2209 } 2740 }
2210 } 2741 }
2211 2742
2212 2743
2213 } } // v8::internal 2744 } } // v8::internal
2214 2745
2215 #endif // V8_PREPARSER_H 2746 #endif // V8_PREPARSER_H
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698