Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |