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

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: Extra parens in parameter lists now recognized, no longer segfaults on "()" Created 6 years, 7 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 "func-name-inferrer.h" 8 #include "func-name-inferrer.h"
9 #include "hashmap.h" 9 #include "hashmap.h"
10 #include "scopes.h" 10 #include "scopes.h"
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
54 // }; 54 // };
55 // // ... 55 // // ...
56 // }; 56 // };
57 57
58 template <typename Traits> 58 template <typename Traits>
59 class ParserBase : public Traits { 59 class ParserBase : public Traits {
60 public: 60 public:
61 // Shorten type names defined by Traits. 61 // Shorten type names defined by Traits.
62 typedef typename Traits::Type::Expression ExpressionT; 62 typedef typename Traits::Type::Expression ExpressionT;
63 typedef typename Traits::Type::Identifier IdentifierT; 63 typedef typename Traits::Type::Identifier IdentifierT;
64 typedef typename Traits::Type::FunctionLiteral FunctionLiteralT;
64 65
65 ParserBase(Scanner* scanner, uintptr_t stack_limit, 66 ParserBase(Scanner* scanner, uintptr_t stack_limit,
66 v8::Extension* extension, 67 v8::Extension* extension,
67 ParserRecorder* log, 68 ParserRecorder* log,
68 typename Traits::Type::Zone* zone, 69 typename Traits::Type::Zone* zone,
69 typename Traits::Type::Parser this_object) 70 typename Traits::Type::Parser this_object)
70 : Traits(this_object), 71 : Traits(this_object),
71 parenthesized_function_(false), 72 parenthesized_function_(false),
72 scope_(NULL), 73 scope_(NULL),
73 function_state_(NULL), 74 function_state_(NULL),
74 extension_(extension), 75 extension_(extension),
75 fni_(NULL), 76 fni_(NULL),
76 log_(log), 77 log_(log),
77 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly. 78 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly.
78 scanner_(scanner), 79 scanner_(scanner),
79 stack_limit_(stack_limit), 80 stack_limit_(stack_limit),
80 stack_overflow_(false), 81 stack_overflow_(false),
81 allow_lazy_(false), 82 allow_lazy_(false),
82 allow_natives_syntax_(false), 83 allow_natives_syntax_(false),
83 allow_generators_(false), 84 allow_generators_(false),
84 allow_for_of_(false), 85 allow_for_of_(false),
86 allow_arrow_functions_(false),
85 zone_(zone) { } 87 zone_(zone) { }
86 88
87 // Getters that indicate whether certain syntactical constructs are 89 // Getters that indicate whether certain syntactical constructs are
88 // allowed to be parsed by this instance of the parser. 90 // allowed to be parsed by this instance of the parser.
89 bool allow_lazy() const { return allow_lazy_; } 91 bool allow_lazy() const { return allow_lazy_; }
90 bool allow_natives_syntax() const { return allow_natives_syntax_; } 92 bool allow_natives_syntax() const { return allow_natives_syntax_; }
91 bool allow_generators() const { return allow_generators_; } 93 bool allow_generators() const { return allow_generators_; }
92 bool allow_for_of() const { return allow_for_of_; } 94 bool allow_for_of() const { return allow_for_of_; }
95 bool allow_arrow_functions() const { return allow_arrow_functions_; }
93 bool allow_modules() const { return scanner()->HarmonyModules(); } 96 bool allow_modules() const { return scanner()->HarmonyModules(); }
94 bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); } 97 bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); }
95 bool allow_harmony_numeric_literals() const { 98 bool allow_harmony_numeric_literals() const {
96 return scanner()->HarmonyNumericLiterals(); 99 return scanner()->HarmonyNumericLiterals();
97 } 100 }
98 101
99 // Setters that determine whether certain syntactical constructs are 102 // Setters that determine whether certain syntactical constructs are
100 // allowed to be parsed by this instance of the parser. 103 // allowed to be parsed by this instance of the parser.
101 void set_allow_lazy(bool allow) { allow_lazy_ = allow; } 104 void set_allow_lazy(bool allow) { allow_lazy_ = allow; }
102 void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; } 105 void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; }
103 void set_allow_generators(bool allow) { allow_generators_ = allow; } 106 void set_allow_generators(bool allow) { allow_generators_ = allow; }
104 void set_allow_for_of(bool allow) { allow_for_of_ = allow; } 107 void set_allow_for_of(bool allow) { allow_for_of_ = allow; }
108 void set_allow_arrow_functions(bool allow) { allow_arrow_functions_ = allow; }
105 void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); } 109 void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); }
106 void set_allow_harmony_scoping(bool allow) { 110 void set_allow_harmony_scoping(bool allow) {
107 scanner()->SetHarmonyScoping(allow); 111 scanner()->SetHarmonyScoping(allow);
108 } 112 }
109 void set_allow_harmony_numeric_literals(bool allow) { 113 void set_allow_harmony_numeric_literals(bool allow) {
110 scanner()->SetHarmonyNumericLiterals(allow); 114 scanner()->SetHarmonyNumericLiterals(allow);
111 } 115 }
112 116
113 protected: 117 protected:
114 enum AllowEvalOrArgumentsAsIdentifier { 118 enum AllowEvalOrArgumentsAsIdentifier {
(...skipping 28 matching lines...) Expand all
143 typename Traits::Type::Scope* scope_; 147 typename Traits::Type::Scope* scope_;
144 }; 148 };
145 149
146 class FunctionState BASE_EMBEDDED { 150 class FunctionState BASE_EMBEDDED {
147 public: 151 public:
148 FunctionState( 152 FunctionState(
149 FunctionState** function_state_stack, 153 FunctionState** function_state_stack,
150 typename Traits::Type::Scope** scope_stack, 154 typename Traits::Type::Scope** scope_stack,
151 typename Traits::Type::Scope* scope, 155 typename Traits::Type::Scope* scope,
152 typename Traits::Type::Zone* zone = NULL); 156 typename Traits::Type::Zone* zone = NULL);
157 FunctionState(
158 FunctionState** function_state_stack,
159 typename Traits::Type::Scope** scope_stack,
160 typename Traits::Type::Scope** scope,
161 typename Traits::Type::Zone* zone = NULL);
153 ~FunctionState(); 162 ~FunctionState();
154 163
155 int NextMaterializedLiteralIndex() { 164 int NextMaterializedLiteralIndex() {
156 return next_materialized_literal_index_++; 165 return next_materialized_literal_index_++;
157 } 166 }
158 int materialized_literal_count() { 167 int materialized_literal_count() {
159 return next_materialized_literal_index_ - JSFunction::kLiteralsPrefixSize; 168 return next_materialized_literal_index_ - JSFunction::kLiteralsPrefixSize;
160 } 169 }
161 170
162 int NextHandlerIndex() { return next_handler_index_++; } 171 int NextHandlerIndex() { return next_handler_index_++; }
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); 403 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok);
395 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); 404 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok);
396 ExpressionT ParseUnaryExpression(bool* ok); 405 ExpressionT ParseUnaryExpression(bool* ok);
397 ExpressionT ParsePostfixExpression(bool* ok); 406 ExpressionT ParsePostfixExpression(bool* ok);
398 ExpressionT ParseLeftHandSideExpression(bool* ok); 407 ExpressionT ParseLeftHandSideExpression(bool* ok);
399 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); 408 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok);
400 ExpressionT ParseMemberExpression(bool* ok); 409 ExpressionT ParseMemberExpression(bool* ok);
401 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, 410 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression,
402 bool* ok); 411 bool* ok);
403 412
413 // There are two ways of parsing arrow functions: if the beginning of an
414 // arrow function can be determined prior to process the parameter list
415 // (e.g. the current scanning position is known to be an arrow function
416 // and not an AssignmentExpression) then the first version is used. In
417 // most cases, we parse the parameter list as an AssignmentExpression
418 // and interpret the AST when the arrow "=>" token is found, using the
419 // second version.
420 // The overloaded ParseArrowFunctionLiteral() functions mainly deal with
421 // parsing/interpreting the parameter list, and then they both call
422 // ParseArrowFunctionLiteralBody() before consuming the arrow token.
423 ExpressionT ParseArrowFunctionLiteral(bool* ok);
424 ExpressionT ParseArrowFunctionLiteral(int start_pos,
425 ExpressionT params_ast,
426 bool* ok);
427 ExpressionT ParseArrowFunctionLiteralBody(
428 FunctionState* function_state,
429 typename Traits::Type::ScopePtr scope,
430 int num_parameters,
431 const Scanner::Location& eval_args_error_loc,
432 const Scanner::Location& dupe_error_loc,
433 const Scanner::Location& reserved_loc,
434 FunctionLiteral::IsParenthesizedFlag parenthesized,
435 int start_pos,
436 bool* ok);
437
404 // Checks if the expression is a valid reference expression (e.g., on the 438 // Checks if the expression is a valid reference expression (e.g., on the
405 // left-hand side of assignments). Although ruled out by ECMA as early errors, 439 // left-hand side of assignments). Although ruled out by ECMA as early errors,
406 // we allow calls for web compatibility and rewrite them to a runtime throw. 440 // we allow calls for web compatibility and rewrite them to a runtime throw.
407 ExpressionT CheckAndRewriteReferenceExpression( 441 ExpressionT CheckAndRewriteReferenceExpression(
408 ExpressionT expression, 442 ExpressionT expression,
409 Scanner::Location location, const char* message, bool* ok); 443 Scanner::Location location, const char* message, bool* ok);
410 444
411 // Used to detect duplicates in object literals. Each of the values 445 // Used to detect duplicates in object literals. Each of the values
412 // kGetterProperty, kSetterProperty and kValueProperty represents 446 // kGetterProperty, kSetterProperty and kValueProperty represents
413 // a type of object literal property. When parsing a property, its 447 // a type of object literal property. When parsing a property, its
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
477 511
478 private: 512 private:
479 Scanner* scanner_; 513 Scanner* scanner_;
480 uintptr_t stack_limit_; 514 uintptr_t stack_limit_;
481 bool stack_overflow_; 515 bool stack_overflow_;
482 516
483 bool allow_lazy_; 517 bool allow_lazy_;
484 bool allow_natives_syntax_; 518 bool allow_natives_syntax_;
485 bool allow_generators_; 519 bool allow_generators_;
486 bool allow_for_of_; 520 bool allow_for_of_;
521 bool allow_arrow_functions_;
487 522
488 typename Traits::Type::Zone* zone_; // Only used by Parser. 523 typename Traits::Type::Zone* zone_; // Only used by Parser.
489 }; 524 };
490 525
491 526
492 class PreParserIdentifier { 527 class PreParserIdentifier {
493 public: 528 public:
494 PreParserIdentifier() : type_(kUnknownIdentifier) {} 529 PreParserIdentifier() : type_(kUnknownIdentifier) {}
495 static PreParserIdentifier Default() { 530 static PreParserIdentifier Default() {
496 return PreParserIdentifier(kUnknownIdentifier); 531 return PreParserIdentifier(kUnknownIdentifier);
497 } 532 }
498 static PreParserIdentifier Eval() { 533 static PreParserIdentifier Eval() {
499 return PreParserIdentifier(kEvalIdentifier); 534 return PreParserIdentifier(kEvalIdentifier);
500 } 535 }
501 static PreParserIdentifier Arguments() { 536 static PreParserIdentifier Arguments() {
502 return PreParserIdentifier(kArgumentsIdentifier); 537 return PreParserIdentifier(kArgumentsIdentifier);
503 } 538 }
504 static PreParserIdentifier FutureReserved() { 539 static PreParserIdentifier FutureReserved() {
505 return PreParserIdentifier(kFutureReservedIdentifier); 540 return PreParserIdentifier(kFutureReservedIdentifier);
506 } 541 }
507 static PreParserIdentifier FutureStrictReserved() { 542 static PreParserIdentifier FutureStrictReserved() {
508 return PreParserIdentifier(kFutureStrictReservedIdentifier); 543 return PreParserIdentifier(kFutureStrictReservedIdentifier);
509 } 544 }
510 static PreParserIdentifier Yield() { 545 static PreParserIdentifier Yield() {
511 return PreParserIdentifier(kYieldIdentifier); 546 return PreParserIdentifier(kYieldIdentifier);
512 } 547 }
513 bool IsEval() { return type_ == kEvalIdentifier; } 548 bool IsEval() const { return type_ == kEvalIdentifier; }
514 bool IsArguments() { return type_ == kArgumentsIdentifier; } 549 bool IsArguments() const { return type_ == kArgumentsIdentifier; }
515 bool IsEvalOrArguments() { return type_ >= kEvalIdentifier; } 550 bool IsEvalOrArguments() { return type_ >= kEvalIdentifier; }
516 bool IsYield() { return type_ == kYieldIdentifier; } 551 bool IsYield() const { return type_ == kYieldIdentifier; }
517 bool IsFutureReserved() { return type_ == kFutureReservedIdentifier; } 552 bool IsFutureReserved() { return type_ == kFutureReservedIdentifier; }
518 bool IsFutureStrictReserved() { 553 bool IsFutureStrictReserved() {
519 return type_ == kFutureStrictReservedIdentifier; 554 return type_ == kFutureStrictReservedIdentifier;
520 } 555 }
521 bool IsValidStrictVariable() { return type_ == kUnknownIdentifier; } 556 bool IsValidStrictVariable() { return type_ == kUnknownIdentifier; }
522 557
558 // Allow identifier->name()[->length()] to work. The preparser
559 // does not need the actual positions/lengths of the identifiers.
560 const PreParserIdentifier* operator->() const { return this; }
561 const PreParserIdentifier name() const { return *this; }
562 int position() const { return RelocInfo::kNoPosition; }
563 int length() const { return 0; }
564
523 private: 565 private:
524 enum Type { 566 enum Type {
525 kUnknownIdentifier, 567 kUnknownIdentifier,
526 kFutureReservedIdentifier, 568 kFutureReservedIdentifier,
527 kFutureStrictReservedIdentifier, 569 kFutureStrictReservedIdentifier,
528 kYieldIdentifier, 570 kYieldIdentifier,
529 kEvalIdentifier, 571 kEvalIdentifier,
530 kArgumentsIdentifier 572 kArgumentsIdentifier
531 }; 573 };
532 explicit PreParserIdentifier(Type type) : type_(type) {} 574 explicit PreParserIdentifier(Type type) : type_(type) {}
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
611 PreParserExpression AsFunctionLiteral() { return *this; } 653 PreParserExpression AsFunctionLiteral() { return *this; }
612 654
613 // Dummy implementation for making expression->somefunc() work in both Parser 655 // Dummy implementation for making expression->somefunc() work in both Parser
614 // and PreParser. 656 // and PreParser.
615 PreParserExpression* operator->() { return this; } 657 PreParserExpression* operator->() { return this; }
616 658
617 // More dummy implementations of things PreParser doesn't need to track: 659 // More dummy implementations of things PreParser doesn't need to track:
618 void set_index(int index) {} // For YieldExpressions 660 void set_index(int index) {} // For YieldExpressions
619 void set_parenthesized() {} 661 void set_parenthesized() {}
620 662
663 int position() const { return RelocInfo::kNoPosition; }
664 void set_function_token_position(int position) {}
665 void set_ast_properties(int* ast_properties) {}
666 void set_dont_optimize_reason(BailoutReason dont_optimize_reason) {}
667
668 bool operator==(const PreParserExpression& other) const {
669 return code_ == other.code_;
670 }
671 bool operator!=(const PreParserExpression& other) const {
672 return code_ != other.code_;
673 }
674
621 private: 675 private:
622 // Least significant 2 bits are used as flags. Bits 0 and 1 represent 676 // Least significant 2 bits are used as flags. Bits 0 and 1 represent
623 // identifiers or strings literals, and are mutually exclusive, but can both 677 // identifiers or strings literals, and are mutually exclusive, but can both
624 // be absent. If the expression is an identifier or a string literal, the 678 // be absent. If the expression is an identifier or a string literal, the
625 // other bits describe the type (see PreParserIdentifier::Type and string 679 // other bits describe the type (see PreParserIdentifier::Type and string
626 // literal constants below). 680 // literal constants below).
627 enum { 681 enum {
628 kUnknownExpression = 0, 682 kUnknownExpression = 0,
629 // Identifiers 683 // Identifiers
630 kIdentifierFlag = 1, // Used to detect labels. 684 kIdentifierFlag = 1, // Used to detect labels.
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
719 public: 773 public:
720 // These functions make list->Add(some_expression) work as no-ops. 774 // These functions make list->Add(some_expression) work as no-ops.
721 PreParserStatementList() {} 775 PreParserStatementList() {}
722 PreParserStatementList* operator->() { return this; } 776 PreParserStatementList* operator->() { return this; }
723 void Add(PreParserStatement, void*) {} 777 void Add(PreParserStatement, void*) {}
724 }; 778 };
725 779
726 780
727 class PreParserScope { 781 class PreParserScope {
728 public: 782 public:
729 explicit PreParserScope(PreParserScope* outer_scope, ScopeType scope_type) 783 explicit PreParserScope(PreParserScope* outer_scope,
784 ScopeType scope_type,
785 void* = NULL)
730 : scope_type_(scope_type) { 786 : scope_type_(scope_type) {
731 strict_mode_ = outer_scope ? outer_scope->strict_mode() : SLOPPY; 787 strict_mode_ = outer_scope ? outer_scope->strict_mode() : SLOPPY;
732 } 788 }
733 789
734 ScopeType type() { return scope_type_; } 790 ScopeType type() { return scope_type_; }
735 StrictMode strict_mode() const { return strict_mode_; } 791 StrictMode strict_mode() const { return strict_mode_; }
736 void SetStrictMode(StrictMode strict_mode) { strict_mode_ = strict_mode; } 792 void SetStrictMode(StrictMode strict_mode) { strict_mode_ = strict_mode; }
793 bool AllowsLazyCompilation() const { return true; }
794
795 void set_start_position(int position) {}
796 void set_end_position(int position) {}
797
798 bool IsDeclared(const PreParserIdentifier&) const { return false; }
799 void DeclareParameter(const PreParserIdentifier&, VariableMode) {}
800
801 // Allow scope->Foo() to work.
802 PreParserScope* operator->() { return this; }
737 803
738 private: 804 private:
739 ScopeType scope_type_; 805 ScopeType scope_type_;
740 StrictMode strict_mode_; 806 StrictMode strict_mode_;
741 }; 807 };
742 808
743 809
744 class PreParserFactory { 810 class PreParserFactory {
745 public: 811 public:
746 explicit PreParserFactory(void* extra_param) {} 812 explicit PreParserFactory(void* extra_param) {}
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
832 PreParserExpression NewCall(PreParserExpression expression, 898 PreParserExpression NewCall(PreParserExpression expression,
833 PreParserExpressionList arguments, 899 PreParserExpressionList arguments,
834 int pos) { 900 int pos) {
835 return PreParserExpression::Call(); 901 return PreParserExpression::Call();
836 } 902 }
837 PreParserExpression NewCallNew(PreParserExpression expression, 903 PreParserExpression NewCallNew(PreParserExpression expression,
838 PreParserExpressionList arguments, 904 PreParserExpressionList arguments,
839 int pos) { 905 int pos) {
840 return PreParserExpression::Default(); 906 return PreParserExpression::Default();
841 } 907 }
908 PreParserStatement NewReturnStatement(PreParserExpression expression,
909 int pos) {
910 return PreParserStatement::Default();
911 }
912 PreParserExpression
913 NewFunctionLiteral(PreParserIdentifier name,
914 PreParserScope& scope,
915 PreParserStatementList body,
916 int materialized_literal_count,
917 int expected_property_count,
918 int handler_count,
919 int parameter_count,
920 FunctionLiteral::ParameterFlag has_duplicate_parameters,
921 FunctionLiteral::FunctionType function_type,
922 FunctionLiteral::IsFunctionFlag is_function,
923 FunctionLiteral::IsParenthesizedFlag is_parenthesized,
924 FunctionLiteral::KindFlag kind,
925 int position) {
926 return PreParserExpression::Default();
927 }
928
929 // Return the object itself as AstVisitor and implement the needed
930 // dummy method right in this class.
931 PreParserFactory* visitor() { return this; }
932 BailoutReason dont_optimize_reason() { return kNoReason; }
933 int* ast_properties() { return NULL; }
842 }; 934 };
843 935
844 936
845 class PreParser; 937 class PreParser;
846 938
847 class PreParserTraits { 939 class PreParserTraits {
848 public: 940 public:
849 struct Type { 941 struct Type {
850 // TODO(marja): To be removed. The Traits object should contain all the data 942 // TODO(marja): To be removed. The Traits object should contain all the data
851 // it needs. 943 // it needs.
852 typedef PreParser* Parser; 944 typedef PreParser* Parser;
853 945
854 // Used by FunctionState and BlockState. 946 // Used by FunctionState and BlockState.
855 typedef PreParserScope Scope; 947 typedef PreParserScope Scope;
948 typedef PreParserScope ScopePtr;
949
856 // PreParser doesn't need to store generator variables. 950 // PreParser doesn't need to store generator variables.
857 typedef void GeneratorVariable; 951 typedef void GeneratorVariable;
858 // No interaction with Zones. 952 // No interaction with Zones.
859 typedef void Zone; 953 typedef void Zone;
860 954
955 typedef int AstProperties;
956 typedef Vector<const PreParserIdentifier> ParameterIdentifierVector;
957
861 // Return types for traversing functions. 958 // Return types for traversing functions.
862 typedef PreParserIdentifier Identifier; 959 typedef PreParserIdentifier Identifier;
863 typedef PreParserExpression Expression; 960 typedef PreParserExpression Expression;
864 typedef PreParserExpression YieldExpression; 961 typedef PreParserExpression YieldExpression;
865 typedef PreParserExpression FunctionLiteral; 962 typedef PreParserExpression FunctionLiteral;
866 typedef PreParserExpression ObjectLiteralProperty; 963 typedef PreParserExpression ObjectLiteralProperty;
867 typedef PreParserExpression Literal; 964 typedef PreParserExpression Literal;
868 typedef PreParserExpressionList ExpressionList; 965 typedef PreParserExpressionList ExpressionList;
869 typedef PreParserExpressionList PropertyList; 966 typedef PreParserExpressionList PropertyList;
870 typedef PreParserStatementList StatementList; 967 typedef PreParserStatementList StatementList;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
913 // operations interleaved with the recursive descent. 1010 // operations interleaved with the recursive descent.
914 static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) { 1011 static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) {
915 // PreParser should not use FuncNameInferrer. 1012 // PreParser should not use FuncNameInferrer.
916 UNREACHABLE(); 1013 UNREACHABLE();
917 } 1014 }
918 static void PushPropertyName(FuncNameInferrer* fni, 1015 static void PushPropertyName(FuncNameInferrer* fni,
919 PreParserExpression expression) { 1016 PreParserExpression expression) {
920 // PreParser should not use FuncNameInferrer. 1017 // PreParser should not use FuncNameInferrer.
921 UNREACHABLE(); 1018 UNREACHABLE();
922 } 1019 }
1020 static void InferFunctionName(FuncNameInferrer* fni,
1021 PreParserExpression expression) {
1022 // PreParser should not use FuncNameInferrer.
1023 UNREACHABLE();
1024 }
923 1025
924 static void CheckFunctionLiteralInsideTopLevelObjectLiteral( 1026 static void CheckFunctionLiteralInsideTopLevelObjectLiteral(
925 PreParserScope* scope, PreParserExpression value, bool* has_function) {} 1027 PreParserScope* scope, PreParserExpression value, bool* has_function) {}
926 1028
927 static void CheckAssigningFunctionLiteralToProperty( 1029 static void CheckAssigningFunctionLiteralToProperty(
928 PreParserExpression left, PreParserExpression right) {} 1030 PreParserExpression left, PreParserExpression right) {}
929 1031
930 // PreParser doesn't need to keep track of eval calls. 1032 // PreParser doesn't need to keep track of eval calls.
931 static void CheckPossibleEvalCall(PreParserExpression expression, 1033 static void CheckPossibleEvalCall(PreParserExpression expression,
932 PreParserScope* scope) {} 1034 PreParserScope* scope) {}
(...skipping 23 matching lines...) Expand all
956 return PreParserExpression::Default(); 1058 return PreParserExpression::Default();
957 } 1059 }
958 PreParserExpression NewThrowSyntaxError( 1060 PreParserExpression NewThrowSyntaxError(
959 const char* type, Handle<Object> arg, int pos) { 1061 const char* type, Handle<Object> arg, int pos) {
960 return PreParserExpression::Default(); 1062 return PreParserExpression::Default();
961 } 1063 }
962 PreParserExpression NewThrowTypeError( 1064 PreParserExpression NewThrowTypeError(
963 const char* type, Handle<Object> arg, int pos) { 1065 const char* type, Handle<Object> arg, int pos) {
964 return PreParserExpression::Default(); 1066 return PreParserExpression::Default();
965 } 1067 }
1068 PreParserScope NewScope(PreParserScope* outer_scope,
1069 ScopeType scope_type) {
1070 return PreParserScope(outer_scope, scope_type);
1071 }
966 1072
967 // Reporting errors. 1073 // Reporting errors.
968 void ReportMessageAt(Scanner::Location location, 1074 void ReportMessageAt(Scanner::Location location,
969 const char* message, 1075 const char* message,
970 const char* arg = NULL, 1076 const char* arg = NULL,
971 bool is_reference_error = false); 1077 bool is_reference_error = false);
972 void ReportMessageAt(int start_pos, 1078 void ReportMessageAt(int start_pos,
973 int end_pos, 1079 int end_pos,
974 const char* message, 1080 const char* message,
975 const char* arg = NULL, 1081 const char* arg = NULL,
976 bool is_reference_error = false); 1082 bool is_reference_error = false);
977 1083
978 // "null" return type creators. 1084 // "null" return type creators.
979 static PreParserIdentifier EmptyIdentifier() { 1085 static PreParserIdentifier EmptyIdentifier() {
980 return PreParserIdentifier::Default(); 1086 return PreParserIdentifier::Default();
981 } 1087 }
1088 static PreParserIdentifier EmptyIdentifierString() {
1089 return PreParserIdentifier::Default();
1090 }
982 static PreParserExpression EmptyExpression() { 1091 static PreParserExpression EmptyExpression() {
983 return PreParserExpression::Default(); 1092 return PreParserExpression::Default();
984 } 1093 }
985 static PreParserExpression EmptyLiteral() { 1094 static PreParserExpression EmptyLiteral() {
986 return PreParserExpression::Default(); 1095 return PreParserExpression::Default();
987 } 1096 }
988 static PreParserExpressionList NullExpressionList() { 1097 static PreParserExpressionList NullExpressionList() {
989 return PreParserExpressionList(); 1098 return PreParserExpressionList();
990 } 1099 }
991 1100
992 // Odd-ball literal creators. 1101 // Odd-ball literal creators.
993 static PreParserExpression GetLiteralTheHole(int position, 1102 static PreParserExpression GetLiteralTheHole(int position,
994 PreParserFactory* factory) { 1103 PreParserFactory* factory) {
995 return PreParserExpression::Default(); 1104 return PreParserExpression::Default();
996 } 1105 }
997 1106
998 // Producing data during the recursive descent. 1107 // Producing data during the recursive descent.
999 PreParserIdentifier GetSymbol(Scanner* scanner); 1108 PreParserIdentifier GetSymbol(Scanner* scanner);
1000 static PreParserIdentifier NextLiteralString(Scanner* scanner, 1109 static PreParserIdentifier NextLiteralString(Scanner* scanner,
1001 PretenureFlag tenured) { 1110 PretenureFlag tenured) {
1111 // This is used by the regexp parsing, which does not use the
1112 // positions of items from the preparser mini-AST.
1002 return PreParserIdentifier::Default(); 1113 return PreParserIdentifier::Default();
1003 } 1114 }
1004 1115
1005 static PreParserExpression ThisExpression(PreParserScope* scope, 1116 static PreParserExpression ThisExpression(PreParserScope* scope,
1006 PreParserFactory* factory) { 1117 PreParserFactory* factory,
1118 int pos) {
1007 return PreParserExpression::This(); 1119 return PreParserExpression::This();
1008 } 1120 }
1009 1121
1010 static PreParserExpression ExpressionFromLiteral( 1122 static PreParserExpression ExpressionFromLiteral(
1011 Token::Value token, int pos, Scanner* scanner, 1123 Token::Value token, int pos, Scanner* scanner,
1012 PreParserFactory* factory) { 1124 PreParserFactory* factory) {
1013 return PreParserExpression::Default(); 1125 return PreParserExpression::Default();
1014 } 1126 }
1015 1127
1016 static PreParserExpression ExpressionFromIdentifier( 1128 static PreParserExpression ExpressionFromIdentifier(
(...skipping 11 matching lines...) Expand all
1028 } 1140 }
1029 1141
1030 static PreParserStatementList NewStatementList(int size, void* zone) { 1142 static PreParserStatementList NewStatementList(int size, void* zone) {
1031 return PreParserStatementList(); 1143 return PreParserStatementList();
1032 } 1144 }
1033 1145
1034 static PreParserExpressionList NewPropertyList(int size, void* zone) { 1146 static PreParserExpressionList NewPropertyList(int size, void* zone) {
1035 return PreParserExpressionList(); 1147 return PreParserExpressionList();
1036 } 1148 }
1037 1149
1150 V8_INLINE void SkipLazyFunctionBody(
1151 PreParserIdentifier function_name,
1152 int* materialized_literal_count,
1153 int* expected_property_count,
1154 bool* ok);
1155 V8_INLINE PreParserStatementList ParseEagerFunctionBody(
1156 PreParserIdentifier function_name,
1157 int pos,
1158 Variable* fvar,
1159 Token::Value fvar_init_op,
1160 bool is_generator,
1161 bool* ok);
1162
1163 // Utility functions
1164 Vector<const PreParserIdentifier> ParameterListFromExpression(
1165 PreParserExpression expression, bool* ok) {
1166 return Vector<const PreParserIdentifier>::empty();
1167 }
1168
1169 void CheckConflictingVarDeclarations(
1170 PreParserScope scope,
1171 bool* ok) {}
1172
1038 // Temporary glue; these functions will move to ParserBase. 1173 // Temporary glue; these functions will move to ParserBase.
1039 PreParserExpression ParseV8Intrinsic(bool* ok); 1174 PreParserExpression ParseV8Intrinsic(bool* ok);
1040 PreParserExpression ParseFunctionLiteral( 1175 PreParserExpression ParseFunctionLiteral(
1041 PreParserIdentifier name, 1176 PreParserIdentifier name,
1042 Scanner::Location function_name_location, 1177 Scanner::Location function_name_location,
1043 bool name_is_strict_reserved, 1178 bool name_is_strict_reserved,
1044 bool is_generator, 1179 bool is_generator,
1045 int function_token_position, 1180 int function_token_position,
1046 FunctionLiteral::FunctionType type, 1181 FunctionLiteral::FunctionType type,
1047 bool* ok); 1182 bool* ok);
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
1172 bool name_is_strict_reserved, 1307 bool name_is_strict_reserved,
1173 bool is_generator, 1308 bool is_generator,
1174 int function_token_pos, 1309 int function_token_pos,
1175 FunctionLiteral::FunctionType function_type, 1310 FunctionLiteral::FunctionType function_type,
1176 bool* ok); 1311 bool* ok);
1177 void ParseLazyFunctionLiteralBody(bool* ok); 1312 void ParseLazyFunctionLiteralBody(bool* ok);
1178 1313
1179 bool CheckInOrOf(bool accept_OF); 1314 bool CheckInOrOf(bool accept_OF);
1180 }; 1315 };
1181 1316
1317
1318 void PreParserTraits::SkipLazyFunctionBody(
1319 PreParserIdentifier function_name,
1320 int* materialized_literal_count,
1321 int* expected_property_count,
1322 bool* ok) {
1323 pre_parser_->SkipLazyFunctionBody(function_name,
1324 materialized_literal_count, expected_property_count, ok);
1325 }
1326
1327
1328 PreParserStatementList PreParserTraits::ParseEagerFunctionBody(
1329 PreParserIdentifier function_name,
1330 int pos,
1331 Variable* fvar,
1332 Token::Value fvar_init_op,
1333 bool is_generator,
1334 bool* ok) {
1335 return pre_parser_->ParseEagerFunctionBody(function_name,
1336 pos, fvar, fvar_init_op, is_generator, ok);
1337 }
1338
1339
1182 template<class Traits> 1340 template<class Traits>
1183 ParserBase<Traits>::FunctionState::FunctionState( 1341 ParserBase<Traits>::FunctionState::FunctionState(
1184 FunctionState** function_state_stack, 1342 FunctionState** function_state_stack,
1185 typename Traits::Type::Scope** scope_stack, 1343 typename Traits::Type::Scope** scope_stack,
1186 typename Traits::Type::Scope* scope, 1344 typename Traits::Type::Scope* scope,
1187 typename Traits::Type::Zone* extra_param) 1345 typename Traits::Type::Zone* extra_param)
1188 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize), 1346 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize),
1189 next_handler_index_(0), 1347 next_handler_index_(0),
1190 expected_property_count_(0), 1348 expected_property_count_(0),
1191 is_generator_(false), 1349 is_generator_(false),
1192 generator_object_variable_(NULL), 1350 generator_object_variable_(NULL),
1193 function_state_stack_(function_state_stack), 1351 function_state_stack_(function_state_stack),
1194 outer_function_state_(*function_state_stack), 1352 outer_function_state_(*function_state_stack),
1195 scope_stack_(scope_stack), 1353 scope_stack_(scope_stack),
1196 outer_scope_(*scope_stack), 1354 outer_scope_(*scope_stack),
1197 saved_ast_node_id_(0), 1355 saved_ast_node_id_(0),
1198 extra_param_(extra_param), 1356 extra_param_(extra_param),
1199 factory_(extra_param) { 1357 factory_(extra_param) {
1200 *scope_stack_ = scope; 1358 *scope_stack_ = scope;
1201 *function_state_stack = this; 1359 *function_state_stack = this;
1202 Traits::SetUpFunctionState(this, extra_param); 1360 Traits::SetUpFunctionState(this, extra_param);
1203 } 1361 }
1204 1362
1205 1363
1206 template<class Traits> 1364 template<class Traits>
1365 ParserBase<Traits>::FunctionState::FunctionState(
1366 FunctionState** function_state_stack,
1367 typename Traits::Type::Scope** scope_stack,
1368 typename Traits::Type::Scope** scope,
1369 typename Traits::Type::Zone* extra_param)
1370 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize),
1371 next_handler_index_(0),
1372 expected_property_count_(0),
1373 is_generator_(false),
1374 generator_object_variable_(NULL),
1375 function_state_stack_(function_state_stack),
1376 outer_function_state_(*function_state_stack),
1377 scope_stack_(scope_stack),
1378 outer_scope_(*scope_stack),
1379 saved_ast_node_id_(0),
1380 extra_param_(extra_param),
1381 factory_(extra_param) {
1382 *scope_stack_ = *scope;
1383 *function_state_stack = this;
1384 Traits::SetUpFunctionState(this, extra_param);
1385 }
1386
1387
1388 template<class Traits>
1207 ParserBase<Traits>::FunctionState::~FunctionState() { 1389 ParserBase<Traits>::FunctionState::~FunctionState() {
1208 *scope_stack_ = outer_scope_; 1390 *scope_stack_ = outer_scope_;
1209 *function_state_stack_ = outer_function_state_; 1391 *function_state_stack_ = outer_function_state_;
1210 Traits::TearDownFunctionState(this, extra_param_); 1392 Traits::TearDownFunctionState(this, extra_param_);
1211 } 1393 }
1212 1394
1213 1395
1214 template<class Traits> 1396 template<class Traits>
1215 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) { 1397 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) {
1216 Scanner::Location source_location = scanner()->location(); 1398 Scanner::Location source_location = scanner()->location();
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
1364 // ObjectLiteral 1546 // ObjectLiteral
1365 // RegExpLiteral 1547 // RegExpLiteral
1366 // '(' Expression ')' 1548 // '(' Expression ')'
1367 1549
1368 int pos = peek_position(); 1550 int pos = peek_position();
1369 ExpressionT result = this->EmptyExpression(); 1551 ExpressionT result = this->EmptyExpression();
1370 Token::Value token = peek(); 1552 Token::Value token = peek();
1371 switch (token) { 1553 switch (token) {
1372 case Token::THIS: { 1554 case Token::THIS: {
1373 Consume(Token::THIS); 1555 Consume(Token::THIS);
1374 result = this->ThisExpression(scope_, factory()); 1556 result = this->ThisExpression(scope_, factory(), position());
1375 break; 1557 break;
1376 } 1558 }
1377 1559
1378 case Token::NULL_LITERAL: 1560 case Token::NULL_LITERAL:
1379 case Token::TRUE_LITERAL: 1561 case Token::TRUE_LITERAL:
1380 case Token::FALSE_LITERAL: 1562 case Token::FALSE_LITERAL:
1381 case Token::NUMBER: 1563 case Token::NUMBER:
1382 Next(); 1564 Next();
1383 result = this->ExpressionFromLiteral(token, pos, scanner(), factory()); 1565 result = this->ExpressionFromLiteral(token, pos, scanner(), factory());
1384 break; 1566 break;
(...skipping 24 matching lines...) Expand all
1409 case Token::LBRACK: 1591 case Token::LBRACK:
1410 result = this->ParseArrayLiteral(CHECK_OK); 1592 result = this->ParseArrayLiteral(CHECK_OK);
1411 break; 1593 break;
1412 1594
1413 case Token::LBRACE: 1595 case Token::LBRACE:
1414 result = this->ParseObjectLiteral(CHECK_OK); 1596 result = this->ParseObjectLiteral(CHECK_OK);
1415 break; 1597 break;
1416 1598
1417 case Token::LPAREN: 1599 case Token::LPAREN:
1418 Consume(Token::LPAREN); 1600 Consume(Token::LPAREN);
1419 // Heuristically try to detect immediately called functions before 1601 if (allow_arrow_functions() && peek() == Token::RPAREN) {
1420 // seeing the call parentheses. 1602 // Arrow functions are the only expression type constructions
1421 parenthesized_function_ = (peek() == Token::FUNCTION); 1603 // for which an empty parameter list "()" is valid input.
1422 result = this->ParseExpression(true, CHECK_OK); 1604 Consume(Token::RPAREN);
1423 Expect(Token::RPAREN, CHECK_OK); 1605 return this->ParseArrowFunctionLiteral(pos,
1606 this->EmptyExpression(),
1607 CHECK_OK);
marja 2014/05/26 12:46:06 I think there is a bug here. So if we're here...
1608 } else {
1609 // Heuristically try to detect immediately called functions before
1610 // seeing the call parentheses.
1611 parenthesized_function_ = (peek() == Token::FUNCTION);
1612 result = this->ParseExpression(true, CHECK_OK);
1613 Expect(Token::RPAREN, CHECK_OK);
1614 }
1424 break; 1615 break;
1425 1616
1426 case Token::MOD: 1617 case Token::MOD:
1427 if (allow_natives_syntax() || extension_ != NULL) { 1618 if (allow_natives_syntax() || extension_ != NULL) {
1428 result = this->ParseV8Intrinsic(CHECK_OK); 1619 result = this->ParseV8Intrinsic(CHECK_OK);
1429 break; 1620 break;
1430 } 1621 }
1431 // If we're not allowing special syntax we fall-through to the 1622 // If we're not allowing special syntax we fall-through to the
1432 // default case. 1623 // default case.
1433 1624
1434 default: { 1625 default: {
1435 Next(); 1626 Next();
1436 ReportUnexpectedToken(token); 1627 ReportUnexpectedToken(token);
1437 *ok = false; 1628 *ok = false;
1438 } 1629 }
1439 } 1630 }
1440 1631
1441 return result; 1632 return result;
1442 } 1633 }
1443 1634
1444 // Precedence = 1 1635 // Precedence = 1
1445 template <class Traits> 1636 template <class Traits>
1446 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( 1637 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression(
1447 bool accept_IN, bool* ok) { 1638 bool accept_IN, bool* ok) {
1448 // Expression :: 1639 // Expression ::
1449 // AssignmentExpression 1640 // AssignmentExpression
1450 // Expression ',' AssignmentExpression 1641 // Expression ',' AssignmentExpression
1451 1642
1643 if (allow_arrow_functions() && peek() == Token::RPAREN &&
marja 2014/05/26 12:46:06 Pls add a test where this code path is taken but i
1644 scanner()->current_token() == Token::LPAREN) {
1645 // Empty argument list for arrow functions: () => ...
1646 return this->EmptyExpression();
1647 }
1648
1452 ExpressionT result = this->ParseAssignmentExpression(accept_IN, CHECK_OK); 1649 ExpressionT result = this->ParseAssignmentExpression(accept_IN, CHECK_OK);
1453 while (peek() == Token::COMMA) { 1650 while (peek() == Token::COMMA) {
1454 Expect(Token::COMMA, CHECK_OK); 1651 Expect(Token::COMMA, CHECK_OK);
1455 int pos = position(); 1652 int pos = position();
1456 ExpressionT right = this->ParseAssignmentExpression(accept_IN, CHECK_OK); 1653 ExpressionT right = this->ParseAssignmentExpression(accept_IN, CHECK_OK);
1457 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); 1654 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos);
1458 } 1655 }
1459 return result; 1656 return result;
1460 } 1657 }
1461 1658
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
1682 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList)); 1879 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList));
1683 return result; 1880 return result;
1684 } 1881 }
1685 1882
1686 // Precedence = 2 1883 // Precedence = 2
1687 template <class Traits> 1884 template <class Traits>
1688 typename ParserBase<Traits>::ExpressionT 1885 typename ParserBase<Traits>::ExpressionT
1689 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) { 1886 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) {
1690 // AssignmentExpression :: 1887 // AssignmentExpression ::
1691 // ConditionalExpression 1888 // ConditionalExpression
1889 // ArrowFunction
1692 // YieldExpression 1890 // YieldExpression
1693 // LeftHandSideExpression AssignmentOperator AssignmentExpression 1891 // LeftHandSideExpression AssignmentOperator AssignmentExpression
1694 1892
1695 Scanner::Location lhs_location = scanner()->peek_location(); 1893 Scanner::Location lhs_location = scanner()->peek_location();
1696 1894
1697 if (peek() == Token::YIELD && is_generator()) { 1895 if (peek() == Token::YIELD && is_generator()) {
1698 return this->ParseYieldExpression(ok); 1896 return this->ParseYieldExpression(ok);
1699 } 1897 }
1700 1898
1701 if (fni_ != NULL) fni_->Enter(); 1899 if (fni_ != NULL) fni_->Enter();
1702 ExpressionT expression = 1900 ExpressionT expression =
1703 this->ParseConditionalExpression(accept_IN, CHECK_OK); 1901 this->ParseConditionalExpression(accept_IN, CHECK_OK);
1704 1902
1903 if (allow_arrow_functions() && peek() == Token::ARROW)
1904 return this->ParseArrowFunctionLiteral(lhs_location.beg_pos,
1905 expression,
1906 CHECK_OK);
1907
1705 if (!Token::IsAssignmentOp(peek())) { 1908 if (!Token::IsAssignmentOp(peek())) {
1706 if (fni_ != NULL) fni_->Leave(); 1909 if (fni_ != NULL) fni_->Leave();
1707 // Parsed conditional expression only (no assignment). 1910 // Parsed conditional expression only (no assignment).
1708 return expression; 1911 return expression;
1709 } 1912 }
1710 1913
1711 expression = this->CheckAndRewriteReferenceExpression( 1914 expression = this->CheckAndRewriteReferenceExpression(
1712 expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK); 1915 expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK);
1713 expression = this->MarkExpressionAsLValue(expression); 1916 expression = this->MarkExpressionAsLValue(expression);
1714 1917
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after
2099 } 2302 }
2100 default: 2303 default:
2101 return expression; 2304 return expression;
2102 } 2305 }
2103 } 2306 }
2104 ASSERT(false); 2307 ASSERT(false);
2105 return this->EmptyExpression(); 2308 return this->EmptyExpression();
2106 } 2309 }
2107 2310
2108 2311
2312 template <class Traits>
2313 typename ParserBase<Traits>::ExpressionT
2314 ParserBase<Traits>::ParseArrowFunctionLiteralBody(
marja 2014/05/26 12:46:06 A lot of this function (starting from strict mode
2315 FunctionState* function_state,
2316 typename Traits::Type::ScopePtr scope,
2317 int num_parameters,
2318 const Scanner::Location& eval_args_error_loc,
2319 const Scanner::Location& dupe_error_loc,
2320 const Scanner::Location& reserved_loc,
2321 FunctionLiteral::IsParenthesizedFlag parenthesized,
2322 int start_pos,
2323 bool* ok) {
2324
2325 typename Traits::Type::StatementList body;
2326 typename Traits::Type::AstProperties ast_properties;
2327 FunctionLiteral::ParameterFlag duplicate_parameters = dupe_error_loc.IsValid()
2328 ? FunctionLiteral::kHasDuplicateParameters
2329 : FunctionLiteral::kNoDuplicateParameters;
2330 BailoutReason dont_optimize_reason = kNoReason;
2331 int materialized_literal_count = -1;
2332 int expected_property_count = -1;
2333 int handler_count = 0;
2334
2335 Expect(Token::ARROW, CHECK_OK);
2336
2337 if (peek() == Token::LBRACE) {
2338 // Multiple statemente body
2339 Consume(Token::LBRACE);
2340
2341 bool is_lazily_parsed = (mode() == PARSE_LAZILY &&
2342 scope_->AllowsLazyCompilation() &&
2343 !parenthesized_function_);
2344 parenthesized_function_ = false; // This Was set for this funciton only.
2345
2346 if (is_lazily_parsed) {
2347 this->SkipLazyFunctionBody(this->EmptyIdentifier(),
2348 &materialized_literal_count,
2349 &expected_property_count,
2350 CHECK_OK);
2351 } else {
2352 body = this->ParseEagerFunctionBody(this->EmptyIdentifier(),
2353 RelocInfo::kNoPosition,
2354 NULL,
2355 Token::INIT_VAR,
2356 false, // Not a generator.
2357 CHECK_OK);
2358 materialized_literal_count =
2359 function_state->materialized_literal_count();
2360 expected_property_count = function_state->expected_property_count();
2361 handler_count = function_state->handler_count();
2362 }
2363 } else {
2364 // Single-expression body
2365 int pos = position();
2366 parenthesized_function_ = false;
2367 ExpressionT expression = ParseAssignmentExpression(true, CHECK_OK);
2368 body = this->NewStatementList(1, zone());
2369 body->Add(factory()->NewReturnStatement(expression, pos), zone());
2370 materialized_literal_count = function_state->materialized_literal_count();
2371 expected_property_count = function_state->expected_property_count();
2372 handler_count = function_state->handler_count();
2373 }
2374
2375 scope->set_start_position(start_pos);
2376 scope->set_end_position(scanner()->location().end_pos);
2377
2378 // Validate strict mode.
2379 if (strict_mode() == STRICT) {
2380 if (eval_args_error_loc.IsValid()) {
2381 this->ReportMessageAt(eval_args_error_loc, "strict_eval_arguments");
2382 *ok = false;
2383 return this->EmptyExpression();
2384 }
2385 if (dupe_error_loc.IsValid()) {
2386 this->ReportMessageAt(dupe_error_loc, "strict_param_dupe");
2387 *ok = false;
2388 return this->EmptyExpression();
2389 }
2390 if (reserved_loc.IsValid()) {
2391 this->ReportMessageAt(reserved_loc, "unexpected_strict_reserved");
2392 *ok = false;
2393 return this->EmptyExpression();
2394 }
2395 CheckOctalLiteral(start_pos,
2396 scanner()->location().end_pos,
2397 CHECK_OK);
2398 }
2399
2400 if (allow_harmony_scoping() && strict_mode() == STRICT)
2401 this->CheckConflictingVarDeclarations(scope, CHECK_OK);
2402
2403 ast_properties = *factory()->visitor()->ast_properties();
2404 dont_optimize_reason = factory()->visitor()->dont_optimize_reason();
2405
2406 FunctionLiteralT function_literal =
2407 factory()->NewFunctionLiteral(this->EmptyIdentifierString(),
2408 scope,
2409 body,
2410 materialized_literal_count,
2411 expected_property_count,
2412 handler_count,
2413 num_parameters,
2414 duplicate_parameters,
2415 FunctionLiteral::ANONYMOUS_EXPRESSION,
2416 FunctionLiteral::kIsFunction,
2417 parenthesized,
2418 FunctionLiteral::kArrowFunction,
2419 start_pos);
2420 function_literal->set_function_token_position(start_pos);
2421 function_literal->set_ast_properties(&ast_properties);
2422 function_literal->set_dont_optimize_reason(dont_optimize_reason);
2423
2424 if (fni_ != NULL) this->InferFunctionName(fni_, function_literal);
2425
2426 return function_literal;
2427 }
2428
2429
2430 template <class Traits>
2431 typename ParserBase<Traits>::ExpressionT
2432 ParserBase<Traits>::ParseArrowFunctionLiteral(bool* ok) {
2433 // TODO(aperez): Change this to use ARROW_SCOPE
2434 typename Traits::Type::ScopePtr scope =
2435 this->NewScope(scope_, FUNCTION_SCOPE);
2436
2437 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_
2438 ? FunctionLiteral::kIsParenthesized
2439 : FunctionLiteral::kNotParenthesized;
2440 parenthesized_function_ = false;
2441
2442 int start_pos = position();
2443 int num_parameters = 0;
2444 FunctionState function_state(&function_state_, &scope_, &scope, zone());
2445
2446 Scanner::Location eval_args_error_loc = Scanner::Location::invalid();
2447 Scanner::Location dupe_error_loc = Scanner::Location::invalid();
2448 Scanner::Location reserved_loc = Scanner::Location::invalid();
2449
2450 if (peek() == Token::LPAREN) {
2451 // Parse a parenthesized parameter list.
2452 Consume(Token::LPAREN);
2453 bool done = (peek() == Token::RPAREN);
2454 while (!done) {
2455 bool is_strict_reserved = false;
2456 IdentifierT param_name =
2457 ParseIdentifierOrStrictReservedWord(&is_strict_reserved,
2458 CHECK_OK);
2459
2460 // Store locations for possible future error reports.
2461 if (!eval_args_error_loc.IsValid() &&
2462 this->IsEvalOrArguments(param_name)) {
2463 eval_args_error_loc = scanner()->location();
2464 }
2465 if (!reserved_loc.IsValid() && is_strict_reserved) {
2466 reserved_loc = scanner()->location();
2467 }
2468 if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) {
2469 dupe_error_loc = scanner()->location();
2470 }
2471
2472 scope_->DeclareParameter(param_name, VAR);
2473 num_parameters++;
2474 if (num_parameters > Code::kMaxArguments) {
2475 this->ReportMessageAt(scanner()->location(), "too_many_parameters");
2476 *ok = false;
2477 return this->EmptyExpression();
2478 }
2479 done = (peek() == Token::RPAREN);
2480 if (!done) Expect(Token::COMMA, CHECK_OK);
2481 }
2482 Expect(Token::RPAREN, CHECK_OK);
2483 } else {
2484 // Parse a single parameter identifier.
2485 bool is_strict_reserved = false;
2486 IdentifierT param_name =
2487 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
2488
2489 // Store locations for possible future error reports.
2490 if (this->IsEvalOrArguments(param_name))
2491 eval_args_error_loc = scanner()->location();
2492 if (is_strict_reserved)
2493 reserved_loc = scanner()->location();
2494
2495 scope_->DeclareParameter(param_name, VAR);
2496 }
2497
2498 ExpressionT literal = ParseArrowFunctionLiteralBody(&function_state,
2499 scope,
2500 num_parameters,
2501 eval_args_error_loc,
2502 dupe_error_loc,
2503 reserved_loc,
2504 parenthesized,
2505 start_pos,
2506 CHECK_OK);
2507 return literal;
2508 }
2509
2510
2511 template <class Traits>
2512 typename ParserBase<Traits>::ExpressionT
2513 ParserBase<Traits>::ParseArrowFunctionLiteral(int start_pos,
2514 ExpressionT params_ast,
2515 bool* ok) {
2516 // TODO(aperez): Change this to use ARROW_SCOPE
2517 typename Traits::Type::ScopePtr scope =
2518 this->NewScope(scope_, FUNCTION_SCOPE);
2519
2520 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_
2521 ? FunctionLiteral::kIsParenthesized
2522 : FunctionLiteral::kNotParenthesized;
2523 parenthesized_function_ = false;
2524
2525 FunctionState function_state(&function_state_, &scope_, &scope, zone());
2526
2527 Scanner::Location eval_args_error_loc = Scanner::Location::invalid();
2528 Scanner::Location dupe_error_loc = Scanner::Location::invalid();
2529 Scanner::Location reserved_loc = Scanner::Location::invalid();
2530
2531 // Function parameters are already parsed into an AST
2532 typename Traits::Type::ParameterIdentifierVector params =
2533 Traits::ParameterListFromExpression(params_ast, CHECK_OK);
2534
2535 if ((params.length() != 1 || start_pos < params.last()->position()) &&
2536 !scanner()->IsValidParameterList(start_pos)) {
2537 ReportMessageAt(Scanner::Location(start_pos, position()),
2538 "malformed_parameter_list");
2539 *ok = false;
2540 return this->EmptyExpression();
2541 }
2542
2543 if (params.length() > Code::kMaxArguments) {
2544 ReportMessageAt(Scanner::Location(params_ast->position(), position()),
2545 "too_many_parameters");
2546 *ok = false;
2547 return this->EmptyExpression();
2548 }
2549
2550 // The vector has the items in reverse order.
2551 for (int i = params.length() - 1; i >= 0; --i) {
2552 const IdentifierT param_name = params.at(i)->name();
2553 int param_pos = params.at(i)->position();
2554
2555 // Store locations for possible future error reports.
2556 if (!eval_args_error_loc.IsValid() &&
2557 this->IsEvalOrArguments(param_name)) {
2558 eval_args_error_loc =
2559 Scanner::Location(param_pos, param_pos + param_name->length());
2560 }
2561 if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) {
2562 dupe_error_loc =
2563 Scanner::Location(param_pos, param_pos + param_name->length());
2564 }
2565
2566 scope_->DeclareParameter(param_name, VAR);
2567 }
2568
2569 ExpressionT literal = ParseArrowFunctionLiteralBody(&function_state,
2570 scope,
2571 params.length(),
2572 eval_args_error_loc,
2573 dupe_error_loc,
2574 reserved_loc,
2575 parenthesized,
2576 start_pos,
2577 CHECK_OK);
2578 return literal;
2579 }
2580
2581
2109 template <typename Traits> 2582 template <typename Traits>
2110 typename ParserBase<Traits>::ExpressionT 2583 typename ParserBase<Traits>::ExpressionT
2111 ParserBase<Traits>::CheckAndRewriteReferenceExpression( 2584 ParserBase<Traits>::CheckAndRewriteReferenceExpression(
2112 ExpressionT expression, 2585 ExpressionT expression,
2113 Scanner::Location location, const char* message, bool* ok) { 2586 Scanner::Location location, const char* message, bool* ok) {
2114 if (strict_mode() == STRICT && this->IsIdentifier(expression) && 2587 if (strict_mode() == STRICT && this->IsIdentifier(expression) &&
2115 this->IsEvalOrArguments(this->AsIdentifier(expression))) { 2588 this->IsEvalOrArguments(this->AsIdentifier(expression))) {
2116 this->ReportMessageAt(location, "strict_eval_arguments", false); 2589 this->ReportMessageAt(location, "strict_eval_arguments", false);
2117 *ok = false; 2590 *ok = false;
2118 return this->EmptyExpression(); 2591 return this->EmptyExpression();
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
2165 "accessor_get_set"); 2638 "accessor_get_set");
2166 } 2639 }
2167 *ok = false; 2640 *ok = false;
2168 } 2641 }
2169 } 2642 }
2170 2643
2171 2644
2172 } } // v8::internal 2645 } } // v8::internal
2173 2646
2174 #endif // V8_PREPARSER_H 2647 #endif // V8_PREPARSER_H
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698