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 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 71 // typedef ObjectLiteralProperty; | 71 // typedef ObjectLiteralProperty; |
| 72 // typedef Literal; | 72 // typedef Literal; |
| 73 // typedef ExpressionList; | 73 // typedef ExpressionList; |
| 74 // typedef PropertyList; | 74 // typedef PropertyList; |
| 75 // // For constructing objects returned by the traversing functions. | 75 // // For constructing objects returned by the traversing functions. |
| 76 // typedef Factory; | 76 // typedef Factory; |
| 77 // }; | 77 // }; |
| 78 // // ... | 78 // // ... |
| 79 // }; | 79 // }; |
| 80 | 80 |
| 81 | |
| 81 template <typename Traits> | 82 template <typename Traits> |
| 82 class ParserBase : public Traits { | 83 class ParserBase : public Traits { |
| 83 public: | 84 public: |
| 84 // Shorten type names defined by Traits. | 85 // Shorten type names defined by Traits. |
| 85 typedef typename Traits::Type::Expression ExpressionT; | 86 typedef typename Traits::Type::Expression ExpressionT; |
| 86 typedef typename Traits::Type::Identifier IdentifierT; | 87 typedef typename Traits::Type::Identifier IdentifierT; |
| 88 typedef typename Traits::Type::FunctionLiteral FunctionLiteralT; | |
| 87 | 89 |
| 88 ParserBase(Scanner* scanner, uintptr_t stack_limit, | 90 ParserBase(Scanner* scanner, uintptr_t stack_limit, |
| 89 v8::Extension* extension, | 91 v8::Extension* extension, |
| 90 ParserRecorder* log, | 92 ParserRecorder* log, |
| 91 typename Traits::Type::Zone* zone, | 93 typename Traits::Type::Zone* zone, |
| 92 typename Traits::Type::Parser this_object) | 94 typename Traits::Type::Parser this_object) |
| 93 : Traits(this_object), | 95 : Traits(this_object), |
| 94 parenthesized_function_(false), | 96 parenthesized_function_(false), |
| 95 scope_(NULL), | 97 scope_(NULL), |
| 96 function_state_(NULL), | 98 function_state_(NULL), |
| 97 extension_(extension), | 99 extension_(extension), |
| 98 fni_(NULL), | 100 fni_(NULL), |
| 99 log_(log), | 101 log_(log), |
| 100 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly. | 102 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly. |
| 101 scanner_(scanner), | 103 scanner_(scanner), |
| 102 stack_limit_(stack_limit), | 104 stack_limit_(stack_limit), |
| 103 stack_overflow_(false), | 105 stack_overflow_(false), |
| 104 allow_lazy_(false), | 106 allow_lazy_(false), |
| 105 allow_natives_syntax_(false), | 107 allow_natives_syntax_(false), |
| 106 allow_generators_(false), | 108 allow_generators_(false), |
| 107 allow_for_of_(false), | 109 allow_for_of_(false), |
| 110 allow_arrow_functions_(false), | |
| 108 zone_(zone) { } | 111 zone_(zone) { } |
| 109 | 112 |
| 110 // Getters that indicate whether certain syntactical constructs are | 113 // Getters that indicate whether certain syntactical constructs are |
| 111 // allowed to be parsed by this instance of the parser. | 114 // allowed to be parsed by this instance of the parser. |
| 112 bool allow_lazy() const { return allow_lazy_; } | 115 bool allow_lazy() const { return allow_lazy_; } |
| 113 bool allow_natives_syntax() const { return allow_natives_syntax_; } | 116 bool allow_natives_syntax() const { return allow_natives_syntax_; } |
| 114 bool allow_generators() const { return allow_generators_; } | 117 bool allow_generators() const { return allow_generators_; } |
| 115 bool allow_for_of() const { return allow_for_of_; } | 118 bool allow_for_of() const { return allow_for_of_; } |
| 119 bool allow_arrow_functions() const { return allow_arrow_functions_; } | |
| 116 bool allow_modules() const { return scanner()->HarmonyModules(); } | 120 bool allow_modules() const { return scanner()->HarmonyModules(); } |
| 117 bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); } | 121 bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); } |
| 118 bool allow_harmony_numeric_literals() const { | 122 bool allow_harmony_numeric_literals() const { |
| 119 return scanner()->HarmonyNumericLiterals(); | 123 return scanner()->HarmonyNumericLiterals(); |
| 120 } | 124 } |
| 121 | 125 |
| 122 // Setters that determine whether certain syntactical constructs are | 126 // Setters that determine whether certain syntactical constructs are |
| 123 // allowed to be parsed by this instance of the parser. | 127 // allowed to be parsed by this instance of the parser. |
| 124 void set_allow_lazy(bool allow) { allow_lazy_ = allow; } | 128 void set_allow_lazy(bool allow) { allow_lazy_ = allow; } |
| 125 void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; } | 129 void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; } |
| 126 void set_allow_generators(bool allow) { allow_generators_ = allow; } | 130 void set_allow_generators(bool allow) { allow_generators_ = allow; } |
| 127 void set_allow_for_of(bool allow) { allow_for_of_ = allow; } | 131 void set_allow_for_of(bool allow) { allow_for_of_ = allow; } |
| 132 void set_allow_arrow_functions(bool allow) { allow_arrow_functions_ = allow; } | |
| 128 void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); } | 133 void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); } |
| 129 void set_allow_harmony_scoping(bool allow) { | 134 void set_allow_harmony_scoping(bool allow) { |
| 130 scanner()->SetHarmonyScoping(allow); | 135 scanner()->SetHarmonyScoping(allow); |
| 131 } | 136 } |
| 132 void set_allow_harmony_numeric_literals(bool allow) { | 137 void set_allow_harmony_numeric_literals(bool allow) { |
| 133 scanner()->SetHarmonyNumericLiterals(allow); | 138 scanner()->SetHarmonyNumericLiterals(allow); |
| 134 } | 139 } |
| 135 | 140 |
| 136 protected: | 141 protected: |
| 137 enum AllowEvalOrArgumentsAsIdentifier { | 142 enum AllowEvalOrArgumentsAsIdentifier { |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 166 typename Traits::Type::Scope* scope_; | 171 typename Traits::Type::Scope* scope_; |
| 167 }; | 172 }; |
| 168 | 173 |
| 169 class FunctionState BASE_EMBEDDED { | 174 class FunctionState BASE_EMBEDDED { |
| 170 public: | 175 public: |
| 171 FunctionState( | 176 FunctionState( |
| 172 FunctionState** function_state_stack, | 177 FunctionState** function_state_stack, |
| 173 typename Traits::Type::Scope** scope_stack, | 178 typename Traits::Type::Scope** scope_stack, |
| 174 typename Traits::Type::Scope* scope, | 179 typename Traits::Type::Scope* scope, |
| 175 typename Traits::Type::Zone* zone = NULL); | 180 typename Traits::Type::Zone* zone = NULL); |
| 181 FunctionState( | |
| 182 FunctionState** function_state_stack, | |
| 183 typename Traits::Type::Scope** scope_stack, | |
| 184 typename Traits::Type::Scope** scope, | |
| 185 typename Traits::Type::Zone* zone = NULL); | |
| 176 ~FunctionState(); | 186 ~FunctionState(); |
| 177 | 187 |
| 178 int NextMaterializedLiteralIndex() { | 188 int NextMaterializedLiteralIndex() { |
| 179 return next_materialized_literal_index_++; | 189 return next_materialized_literal_index_++; |
| 180 } | 190 } |
| 181 int materialized_literal_count() { | 191 int materialized_literal_count() { |
| 182 return next_materialized_literal_index_ - JSFunction::kLiteralsPrefixSize; | 192 return next_materialized_literal_index_ - JSFunction::kLiteralsPrefixSize; |
| 183 } | 193 } |
| 184 | 194 |
| 185 int NextHandlerIndex() { return next_handler_index_++; } | 195 int NextHandlerIndex() { return next_handler_index_++; } |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 417 ExpressionT ParseYieldExpression(bool* ok); | 427 ExpressionT ParseYieldExpression(bool* ok); |
| 418 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); | 428 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); |
| 419 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); | 429 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); |
| 420 ExpressionT ParseUnaryExpression(bool* ok); | 430 ExpressionT ParseUnaryExpression(bool* ok); |
| 421 ExpressionT ParsePostfixExpression(bool* ok); | 431 ExpressionT ParsePostfixExpression(bool* ok); |
| 422 ExpressionT ParseLeftHandSideExpression(bool* ok); | 432 ExpressionT ParseLeftHandSideExpression(bool* ok); |
| 423 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); | 433 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); |
| 424 ExpressionT ParseMemberExpression(bool* ok); | 434 ExpressionT ParseMemberExpression(bool* ok); |
| 425 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, | 435 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, |
| 426 bool* ok); | 436 bool* ok); |
| 437 ExpressionT ParseArrowFunctionLiteral(int start_pos, | |
| 438 ExpressionT params_ast, | |
| 439 bool* ok); | |
| 427 | 440 |
| 428 // Checks if the expression is a valid reference expression (e.g., on the | 441 // Checks if the expression is a valid reference expression (e.g., on the |
| 429 // left-hand side of assignments). Although ruled out by ECMA as early errors, | 442 // left-hand side of assignments). Although ruled out by ECMA as early errors, |
| 430 // we allow calls for web compatibility and rewrite them to a runtime throw. | 443 // we allow calls for web compatibility and rewrite them to a runtime throw. |
| 431 ExpressionT CheckAndRewriteReferenceExpression( | 444 ExpressionT CheckAndRewriteReferenceExpression( |
| 432 ExpressionT expression, | 445 ExpressionT expression, |
| 433 Scanner::Location location, const char* message, bool* ok); | 446 Scanner::Location location, const char* message, bool* ok); |
| 434 | 447 |
| 435 // Used to detect duplicates in object literals. Each of the values | 448 // Used to detect duplicates in object literals. Each of the values |
| 436 // kGetterProperty, kSetterProperty and kValueProperty represents | 449 // kGetterProperty, kSetterProperty and kValueProperty represents |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 501 | 514 |
| 502 private: | 515 private: |
| 503 Scanner* scanner_; | 516 Scanner* scanner_; |
| 504 uintptr_t stack_limit_; | 517 uintptr_t stack_limit_; |
| 505 bool stack_overflow_; | 518 bool stack_overflow_; |
| 506 | 519 |
| 507 bool allow_lazy_; | 520 bool allow_lazy_; |
| 508 bool allow_natives_syntax_; | 521 bool allow_natives_syntax_; |
| 509 bool allow_generators_; | 522 bool allow_generators_; |
| 510 bool allow_for_of_; | 523 bool allow_for_of_; |
| 524 bool allow_arrow_functions_; | |
| 511 | 525 |
| 512 typename Traits::Type::Zone* zone_; // Only used by Parser. | 526 typename Traits::Type::Zone* zone_; // Only used by Parser. |
| 513 }; | 527 }; |
| 514 | 528 |
| 515 | 529 |
| 516 class PreParserIdentifier { | 530 class PreParserIdentifier { |
| 517 public: | 531 public: |
| 518 PreParserIdentifier() : type_(kUnknownIdentifier) {} | 532 PreParserIdentifier() : type_(kUnknownIdentifier) {} |
| 519 static PreParserIdentifier Default() { | 533 static PreParserIdentifier Default(int pos) { |
| 520 return PreParserIdentifier(kUnknownIdentifier); | 534 return PreParserIdentifier(kUnknownIdentifier, pos); |
| 521 } | 535 } |
| 522 static PreParserIdentifier Eval() { | 536 static PreParserIdentifier Eval(int pos) { |
| 523 return PreParserIdentifier(kEvalIdentifier); | 537 return PreParserIdentifier(kEvalIdentifier, pos); |
| 524 } | 538 } |
| 525 static PreParserIdentifier Arguments() { | 539 static PreParserIdentifier Arguments(int pos) { |
| 526 return PreParserIdentifier(kArgumentsIdentifier); | 540 return PreParserIdentifier(kArgumentsIdentifier, pos); |
| 527 } | 541 } |
| 528 static PreParserIdentifier FutureReserved() { | 542 static PreParserIdentifier FutureReserved(int pos) { |
| 529 return PreParserIdentifier(kFutureReservedIdentifier); | 543 return PreParserIdentifier(kFutureReservedIdentifier, pos); |
| 530 } | 544 } |
| 531 static PreParserIdentifier FutureStrictReserved() { | 545 static PreParserIdentifier FutureStrictReserved(int pos) { |
| 532 return PreParserIdentifier(kFutureStrictReservedIdentifier); | 546 return PreParserIdentifier(kFutureStrictReservedIdentifier, pos); |
| 533 } | 547 } |
| 534 static PreParserIdentifier Yield() { | 548 static PreParserIdentifier Yield(int pos) { |
| 535 return PreParserIdentifier(kYieldIdentifier); | 549 return PreParserIdentifier(kYieldIdentifier, pos); |
| 536 } | 550 } |
| 537 bool IsEval() { return type_ == kEvalIdentifier; } | 551 bool IsEval() const { return type_ == kEvalIdentifier; } |
| 538 bool IsArguments() { return type_ == kArgumentsIdentifier; } | 552 bool IsArguments() const { return type_ == kArgumentsIdentifier; } |
| 539 bool IsEvalOrArguments() { return type_ >= kEvalIdentifier; } | 553 bool IsEvalOrArguments() { return type_ >= kEvalIdentifier; } |
| 540 bool IsYield() { return type_ == kYieldIdentifier; } | 554 bool IsYield() const { return type_ == kYieldIdentifier; } |
| 541 bool IsFutureReserved() { return type_ == kFutureReservedIdentifier; } | 555 bool IsFutureReserved() { return type_ == kFutureReservedIdentifier; } |
| 542 bool IsFutureStrictReserved() { | 556 bool IsFutureStrictReserved() { |
| 543 return type_ == kFutureStrictReservedIdentifier; | 557 return type_ == kFutureStrictReservedIdentifier; |
| 544 } | 558 } |
| 545 bool IsValidStrictVariable() { return type_ == kUnknownIdentifier; } | 559 bool IsValidStrictVariable() { return type_ == kUnknownIdentifier; } |
| 546 | 560 |
| 561 // Allow identifier->name()[->length()] to work | |
| 562 const PreParserIdentifier* operator->() const { return this; } | |
| 563 const PreParserIdentifier name() const { return *this; } | |
| 564 int position() const { return pos_; } | |
| 565 int length() const { | |
| 566 if (IsEval()) return 4; | |
| 567 if (IsArguments()) return 9; | |
| 568 if (IsYield()) return 5; | |
| 569 | |
| 570 // TODO(aperez): Is this correct? | |
| 571 return 0; | |
| 572 } | |
| 573 | |
| 547 private: | 574 private: |
| 548 enum Type { | 575 enum Type { |
| 549 kUnknownIdentifier, | 576 kUnknownIdentifier, |
| 550 kFutureReservedIdentifier, | 577 kFutureReservedIdentifier, |
| 551 kFutureStrictReservedIdentifier, | 578 kFutureStrictReservedIdentifier, |
| 552 kYieldIdentifier, | 579 kYieldIdentifier, |
| 553 kEvalIdentifier, | 580 kEvalIdentifier, |
| 554 kArgumentsIdentifier | 581 kArgumentsIdentifier |
| 555 }; | 582 }; |
| 556 explicit PreParserIdentifier(Type type) : type_(type) {} | 583 explicit PreParserIdentifier(Type type, int pos) : type_(type), pos_(pos) {} |
| 557 Type type_; | 584 Type type_; |
| 585 int pos_; | |
| 558 | 586 |
| 559 friend class PreParserExpression; | 587 friend class PreParserExpression; |
| 560 }; | 588 }; |
| 561 | 589 |
| 562 | 590 |
| 563 // Bits 0 and 1 are used to identify the type of expression: | 591 // Bits 0 and 1 are used to identify the type of expression: |
| 564 // If bit 0 is set, it's an identifier. | 592 // If bit 0 is set, it's an identifier. |
| 565 // if bit 1 is set, it's a string literal. | 593 // if bit 1 is set, it's a string literal. |
| 566 // If neither is set, it's no particular type, and both set isn't | 594 // If neither is set, it's no particular type, and both set isn't |
| 567 // use yet. | 595 // use yet. |
| 568 class PreParserExpression { | 596 class PreParserExpression { |
| 569 public: | 597 public: |
| 570 static PreParserExpression Default() { | 598 static PreParserExpression Default(int pos = RelocInfo::kNoPosition) { |
| 571 return PreParserExpression(kUnknownExpression); | 599 return PreParserExpression(kUnknownExpression, pos); |
| 572 } | 600 } |
| 573 | 601 |
| 574 static PreParserExpression FromIdentifier(PreParserIdentifier id) { | 602 static PreParserExpression FromIdentifier(PreParserIdentifier id, |
| 603 int pos = RelocInfo::kNoPosition) { | |
| 575 return PreParserExpression(kIdentifierFlag | | 604 return PreParserExpression(kIdentifierFlag | |
| 576 (id.type_ << kIdentifierShift)); | 605 (id.type_ << kIdentifierShift), pos); |
| 577 } | 606 } |
| 578 | 607 |
| 579 static PreParserExpression StringLiteral() { | 608 static PreParserExpression StringLiteral(int pos = RelocInfo::kNoPosition) { |
| 580 return PreParserExpression(kUnknownStringLiteral); | 609 return PreParserExpression(kUnknownStringLiteral, pos); |
| 581 } | 610 } |
| 582 | 611 |
| 583 static PreParserExpression UseStrictStringLiteral() { | 612 static PreParserExpression UseStrictStringLiteral( |
| 584 return PreParserExpression(kUseStrictString); | 613 int pos = RelocInfo::kNoPosition) { |
| 614 return PreParserExpression(kUseStrictString, pos); | |
| 585 } | 615 } |
| 586 | 616 |
| 587 static PreParserExpression This() { | 617 static PreParserExpression This(int pos = RelocInfo::kNoPosition) { |
| 588 return PreParserExpression(kThisExpression); | 618 return PreParserExpression(kThisExpression, pos); |
| 589 } | 619 } |
| 590 | 620 |
| 591 static PreParserExpression ThisProperty() { | 621 static PreParserExpression ThisProperty(int pos = RelocInfo::kNoPosition) { |
| 592 return PreParserExpression(kThisPropertyExpression); | 622 return PreParserExpression(kThisPropertyExpression, pos); |
| 593 } | 623 } |
| 594 | 624 |
| 595 static PreParserExpression Property() { | 625 static PreParserExpression Property(int pos = RelocInfo::kNoPosition) { |
| 596 return PreParserExpression(kPropertyExpression); | 626 return PreParserExpression(kPropertyExpression, pos); |
| 597 } | 627 } |
| 598 | 628 |
| 599 static PreParserExpression Call() { | 629 static PreParserExpression Call(int pos = RelocInfo::kNoPosition) { |
| 600 return PreParserExpression(kCallExpression); | 630 return PreParserExpression(kCallExpression, pos); |
| 601 } | 631 } |
| 602 | 632 |
| 603 bool IsIdentifier() { return (code_ & kIdentifierFlag) != 0; } | 633 bool IsIdentifier() { return (code_ & kIdentifierFlag) != 0; } |
| 604 | 634 |
| 605 PreParserIdentifier AsIdentifier() { | 635 PreParserIdentifier AsIdentifier() { |
| 606 ASSERT(IsIdentifier()); | 636 ASSERT(IsIdentifier()); |
| 607 return PreParserIdentifier( | 637 return PreParserIdentifier( |
| 608 static_cast<PreParserIdentifier::Type>(code_ >> kIdentifierShift)); | 638 static_cast<PreParserIdentifier::Type>(code_ >> kIdentifierShift), |
| 639 pos_); | |
| 609 } | 640 } |
| 610 | 641 |
| 611 bool IsStringLiteral() { return (code_ & kStringLiteralFlag) != 0; } | 642 bool IsStringLiteral() { return (code_ & kStringLiteralFlag) != 0; } |
| 612 | 643 |
| 613 bool IsUseStrictLiteral() { | 644 bool IsUseStrictLiteral() { |
| 614 return (code_ & kStringLiteralMask) == kUseStrictString; | 645 return (code_ & kStringLiteralMask) == kUseStrictString; |
| 615 } | 646 } |
| 616 | 647 |
| 617 bool IsThis() { return code_ == kThisExpression; } | 648 bool IsThis() { return code_ == kThisExpression; } |
| 618 | 649 |
| 619 bool IsThisProperty() { return code_ == kThisPropertyExpression; } | 650 bool IsThisProperty() { return code_ == kThisPropertyExpression; } |
| 620 | 651 |
| 621 bool IsProperty() { | 652 bool IsProperty() { |
| 622 return code_ == kPropertyExpression || code_ == kThisPropertyExpression; | 653 return code_ == kPropertyExpression || code_ == kThisPropertyExpression; |
| 623 } | 654 } |
| 624 | 655 |
| 625 bool IsCall() { return code_ == kCallExpression; } | 656 bool IsCall() { return code_ == kCallExpression; } |
| 626 | 657 |
| 627 bool IsValidReferenceExpression() { | 658 bool IsValidReferenceExpression() { |
| 628 return IsIdentifier() || IsProperty(); | 659 return IsIdentifier() || IsProperty(); |
| 629 } | 660 } |
| 630 | 661 |
| 631 // At the moment PreParser doesn't track these expression types. | 662 // At the moment PreParser doesn't track these expression types. |
| 632 bool IsFunctionLiteral() const { return false; } | 663 bool IsFunctionLiteral() const { return false; } |
| 633 bool IsCallNew() const { return false; } | 664 bool IsCallNew() const { return false; } |
| 634 | 665 |
| 635 PreParserExpression AsFunctionLiteral() { return *this; } | 666 PreParserExpression AsFunctionLiteral() { return *this; } |
| 636 | 667 |
| 668 int position() const { return pos_; } | |
| 669 | |
| 637 // Dummy implementation for making expression->somefunc() work in both Parser | 670 // Dummy implementation for making expression->somefunc() work in both Parser |
| 638 // and PreParser. | 671 // and PreParser. |
| 639 PreParserExpression* operator->() { return this; } | 672 PreParserExpression* operator->() { return this; } |
| 640 | 673 |
| 641 // More dummy implementations of things PreParser doesn't need to track: | 674 // More dummy implementations of things PreParser doesn't need to track: |
| 642 void set_index(int index) {} // For YieldExpressions | 675 void set_index(int index) {} // For YieldExpressions |
| 643 void set_parenthesized() {} | 676 void set_parenthesized() {} |
| 644 | 677 |
| 678 void set_function_token_position(int position) { pos_ = position; } | |
| 679 void set_ast_properties(int* ast_properties) {} | |
| 680 void set_slot_processor(int* slot_processor) {} | |
| 681 void set_dont_optimize_reason(BailoutReason dont_optimize_reason) {} | |
| 682 | |
| 683 bool operator==(const PreParserExpression& other) const { | |
| 684 return code_ == other.code_; | |
| 685 } | |
| 686 bool operator!=(const PreParserExpression& other) const { | |
| 687 return code_ != other.code_; | |
| 688 } | |
| 689 | |
| 645 private: | 690 private: |
| 646 // Least significant 2 bits are used as flags. Bits 0 and 1 represent | 691 // Least significant 2 bits are used as flags. Bits 0 and 1 represent |
| 647 // identifiers or strings literals, and are mutually exclusive, but can both | 692 // identifiers or strings literals, and are mutually exclusive, but can both |
| 648 // be absent. If the expression is an identifier or a string literal, the | 693 // be absent. If the expression is an identifier or a string literal, the |
| 649 // other bits describe the type (see PreParserIdentifier::Type and string | 694 // other bits describe the type (see PreParserIdentifier::Type and string |
| 650 // literal constants below). | 695 // literal constants below). |
| 651 enum { | 696 enum { |
| 652 kUnknownExpression = 0, | 697 kUnknownExpression = 0, |
| 653 // Identifiers | 698 // Identifiers |
| 654 kIdentifierFlag = 1, // Used to detect labels. | 699 kIdentifierFlag = 1, // Used to detect labels. |
| 655 kIdentifierShift = 3, | 700 kIdentifierShift = 3, |
| 656 | 701 |
| 657 kStringLiteralFlag = 2, // Used to detect directive prologue. | 702 kStringLiteralFlag = 2, // Used to detect directive prologue. |
| 658 kUnknownStringLiteral = kStringLiteralFlag, | 703 kUnknownStringLiteral = kStringLiteralFlag, |
| 659 kUseStrictString = kStringLiteralFlag | 8, | 704 kUseStrictString = kStringLiteralFlag | 8, |
| 660 kStringLiteralMask = kUseStrictString, | 705 kStringLiteralMask = kUseStrictString, |
| 661 | 706 |
| 662 // Below here applies if neither identifier nor string literal. Reserve the | 707 // Below here applies if neither identifier nor string literal. Reserve the |
| 663 // 2 least significant bits for flags. | 708 // 2 least significant bits for flags. |
| 664 kThisExpression = 1 << 2, | 709 kThisExpression = 1 << 2, |
| 665 kThisPropertyExpression = 2 << 2, | 710 kThisPropertyExpression = 2 << 2, |
| 666 kPropertyExpression = 3 << 2, | 711 kPropertyExpression = 3 << 2, |
| 667 kCallExpression = 4 << 2 | 712 kCallExpression = 4 << 2 |
| 668 }; | 713 }; |
| 669 | 714 |
| 670 explicit PreParserExpression(int expression_code) : code_(expression_code) {} | 715 explicit PreParserExpression(int expression_code, int pos) |
| 716 : code_(expression_code), pos_(pos) {} | |
| 671 | 717 |
| 672 int code_; | 718 int code_; |
| 719 int pos_; | |
| 673 }; | 720 }; |
| 674 | 721 |
| 675 | 722 |
| 676 // PreParserExpressionList doesn't actually store the expressions because | 723 // PreParserExpressionList doesn't actually store the expressions because |
| 677 // PreParser doesn't need to. | 724 // PreParser doesn't need to. |
| 678 class PreParserExpressionList { | 725 class PreParserExpressionList { |
| 679 public: | 726 public: |
| 680 // These functions make list->Add(some_expression) work (and do nothing). | 727 // These functions make list->Add(some_expression) work (and do nothing). |
| 681 PreParserExpressionList() : length_(0) {} | 728 PreParserExpressionList() : length_(0) {} |
| 682 PreParserExpressionList* operator->() { return this; } | 729 PreParserExpressionList* operator->() { return this; } |
| 683 void Add(PreParserExpression, void*) { ++length_; } | 730 void Add(PreParserExpression, void*) { ++length_; } |
| 684 int length() const { return length_; } | 731 int length() const { return length_; } |
| 685 private: | 732 private: |
| 686 int length_; | 733 int length_; |
| 687 }; | 734 }; |
| 688 | 735 |
| 736 class PreParserStatement { | |
|
marja
2014/04/24 08:08:06
I'd be more than willing to take this kind of chan
aperez
2014/04/24 12:38:37
Fortunately I have this locally as a separate comm
| |
| 737 public: | |
| 738 static PreParserStatement Default() { | |
| 739 return PreParserStatement(kUnknownStatement); | |
| 740 } | |
| 741 | |
| 742 static PreParserStatement FunctionDeclaration() { | |
| 743 return PreParserStatement(kFunctionDeclaration); | |
| 744 } | |
| 745 | |
| 746 // Creates expression statement from expression. | |
| 747 // Preserves being an unparenthesized string literal, possibly | |
| 748 // "use strict". | |
| 749 static PreParserStatement ExpressionStatement( | |
| 750 PreParserExpression expression) { | |
| 751 if (expression.IsUseStrictLiteral()) { | |
| 752 return PreParserStatement(kUseStrictExpressionStatement); | |
| 753 } | |
| 754 if (expression.IsStringLiteral()) { | |
| 755 return PreParserStatement(kStringLiteralExpressionStatement); | |
| 756 } | |
| 757 return Default(); | |
| 758 } | |
| 759 | |
| 760 bool IsStringLiteral() { | |
| 761 return code_ == kStringLiteralExpressionStatement; | |
| 762 } | |
| 763 | |
| 764 bool IsUseStrictLiteral() { | |
| 765 return code_ == kUseStrictExpressionStatement; | |
| 766 } | |
| 767 | |
| 768 bool IsFunctionDeclaration() { | |
| 769 return code_ == kFunctionDeclaration; | |
| 770 } | |
| 771 | |
| 772 private: | |
| 773 enum Type { | |
| 774 kUnknownStatement, | |
| 775 kStringLiteralExpressionStatement, | |
| 776 kUseStrictExpressionStatement, | |
| 777 kFunctionDeclaration | |
| 778 }; | |
| 779 | |
| 780 explicit PreParserStatement(Type code) : code_(code) {} | |
| 781 Type code_; | |
| 782 }; | |
| 783 | |
| 784 | |
| 785 // PreParserStatementList doesn't actually store the statements because | |
| 786 // PreParser doesn't need to. | |
| 787 class PreParserStatementList { | |
| 788 public: | |
| 789 // These functions make list->Add(some_expression) work (and do nothing). | |
| 790 PreParserStatementList() {} | |
| 791 PreParserStatementList* operator->() { return this; } | |
| 792 void Add(PreParserStatement, void*) {} | |
| 793 }; | |
| 794 | |
| 689 | 795 |
| 690 class PreParserScope { | 796 class PreParserScope { |
| 691 public: | 797 public: |
| 692 explicit PreParserScope(PreParserScope* outer_scope, ScopeType scope_type) | 798 explicit PreParserScope(PreParserScope* outer_scope, |
| 799 ScopeType scope_type, | |
| 800 void* = NULL) | |
| 693 : scope_type_(scope_type) { | 801 : scope_type_(scope_type) { |
| 694 strict_mode_ = outer_scope ? outer_scope->strict_mode() : SLOPPY; | 802 strict_mode_ = outer_scope ? outer_scope->strict_mode() : SLOPPY; |
| 695 } | 803 } |
| 696 | 804 |
| 697 ScopeType type() { return scope_type_; } | 805 ScopeType type() { return scope_type_; } |
| 698 StrictMode strict_mode() const { return strict_mode_; } | 806 StrictMode strict_mode() const { return strict_mode_; } |
| 699 void SetStrictMode(StrictMode strict_mode) { strict_mode_ = strict_mode; } | 807 void SetStrictMode(StrictMode strict_mode) { strict_mode_ = strict_mode; } |
| 808 bool AllowsLazyCompilation() const { return true; } | |
| 809 | |
| 810 void set_start_position(int position) {} | |
| 811 void set_end_position(int position) {} | |
| 812 | |
| 813 bool IsDeclared(const PreParserIdentifier&) const { return false; } | |
| 814 void DeclareParameter(const PreParserIdentifier&, VariableMode) {} | |
| 815 | |
| 816 // Allow scope->Foo() to work. | |
| 817 PreParserScope* operator->() { return this; } | |
| 700 | 818 |
| 701 private: | 819 private: |
| 702 ScopeType scope_type_; | 820 ScopeType scope_type_; |
| 703 StrictMode strict_mode_; | 821 StrictMode strict_mode_; |
| 704 }; | 822 }; |
| 705 | 823 |
| 706 | 824 |
| 707 class PreParserFactory { | 825 class PreParserFactory { |
| 708 public: | 826 public: |
| 709 explicit PreParserFactory(void* extra_param) {} | 827 explicit PreParserFactory(void* extra_param) {} |
| 710 PreParserExpression NewLiteral(PreParserIdentifier identifier, | 828 PreParserExpression NewLiteral(PreParserIdentifier identifier, |
| 711 int pos) { | 829 int pos) { |
| 712 return PreParserExpression::Default(); | 830 return PreParserExpression::Default(pos); |
| 713 } | 831 } |
| 714 PreParserExpression NewNumberLiteral(double number, | 832 PreParserExpression NewNumberLiteral(double number, |
| 715 int pos) { | 833 int pos) { |
| 716 return PreParserExpression::Default(); | 834 return PreParserExpression::Default(pos); |
| 717 } | 835 } |
| 718 PreParserExpression NewRegExpLiteral(PreParserIdentifier js_pattern, | 836 PreParserExpression NewRegExpLiteral(PreParserIdentifier js_pattern, |
| 719 PreParserIdentifier js_flags, | 837 PreParserIdentifier js_flags, |
| 720 int literal_index, | 838 int literal_index, |
| 721 int pos) { | 839 int pos) { |
| 722 return PreParserExpression::Default(); | 840 return PreParserExpression::Default(pos); |
| 723 } | 841 } |
| 724 PreParserExpression NewArrayLiteral(PreParserExpressionList values, | 842 PreParserExpression NewArrayLiteral(PreParserExpressionList values, |
| 725 int literal_index, | 843 int literal_index, |
| 726 int pos) { | 844 int pos) { |
| 727 return PreParserExpression::Default(); | 845 return PreParserExpression::Default(pos); |
| 728 } | 846 } |
| 729 PreParserExpression NewObjectLiteralProperty(bool is_getter, | 847 PreParserExpression NewObjectLiteralProperty(bool is_getter, |
| 730 PreParserExpression value, | 848 PreParserExpression value, |
| 731 int pos) { | 849 int pos) { |
| 732 return PreParserExpression::Default(); | 850 return PreParserExpression::Default(); |
| 733 } | 851 } |
| 734 PreParserExpression NewObjectLiteralProperty(PreParserExpression key, | 852 PreParserExpression NewObjectLiteralProperty(PreParserExpression key, |
| 735 PreParserExpression value) { | 853 PreParserExpression value) { |
| 736 return PreParserExpression::Default(); | 854 return PreParserExpression::Default(); |
| 737 } | 855 } |
| 738 PreParserExpression NewObjectLiteral(PreParserExpressionList properties, | 856 PreParserExpression NewObjectLiteral(PreParserExpressionList properties, |
| 739 int literal_index, | 857 int literal_index, |
| 740 int boilerplate_properties, | 858 int boilerplate_properties, |
| 741 bool has_function, | 859 bool has_function, |
| 742 int pos) { | 860 int pos) { |
| 743 return PreParserExpression::Default(); | 861 return PreParserExpression::Default(pos); |
| 744 } | 862 } |
| 745 PreParserExpression NewVariableProxy(void* generator_variable) { | 863 PreParserExpression NewVariableProxy(void* generator_variable, int pos) { |
| 746 return PreParserExpression::Default(); | 864 return PreParserExpression::Default(pos); |
| 747 } | 865 } |
| 748 PreParserExpression NewProperty(PreParserExpression obj, | 866 PreParserExpression NewProperty(PreParserExpression obj, |
| 749 PreParserExpression key, | 867 PreParserExpression key, |
| 750 int pos) { | 868 int pos) { |
| 751 if (obj.IsThis()) { | 869 if (obj.IsThis()) { |
| 752 return PreParserExpression::ThisProperty(); | 870 return PreParserExpression::ThisProperty(pos); |
| 753 } | 871 } |
| 754 return PreParserExpression::Property(); | 872 return PreParserExpression::Property(pos); |
| 755 } | 873 } |
| 756 PreParserExpression NewUnaryOperation(Token::Value op, | 874 PreParserExpression NewUnaryOperation(Token::Value op, |
| 757 PreParserExpression expression, | 875 PreParserExpression expression, |
| 758 int pos) { | 876 int pos) { |
| 759 return PreParserExpression::Default(); | 877 return PreParserExpression::Default(pos); |
| 760 } | 878 } |
| 761 PreParserExpression NewBinaryOperation(Token::Value op, | 879 PreParserExpression NewBinaryOperation(Token::Value op, |
| 762 PreParserExpression left, | 880 PreParserExpression left, |
| 763 PreParserExpression right, int pos) { | 881 PreParserExpression right, int pos) { |
| 764 return PreParserExpression::Default(); | 882 return PreParserExpression::Default(pos); |
| 765 } | 883 } |
| 766 PreParserExpression NewCompareOperation(Token::Value op, | 884 PreParserExpression NewCompareOperation(Token::Value op, |
| 767 PreParserExpression left, | 885 PreParserExpression left, |
| 768 PreParserExpression right, int pos) { | 886 PreParserExpression right, int pos) { |
| 769 return PreParserExpression::Default(); | 887 return PreParserExpression::Default(pos); |
| 770 } | 888 } |
| 771 PreParserExpression NewAssignment(Token::Value op, | 889 PreParserExpression NewAssignment(Token::Value op, |
| 772 PreParserExpression left, | 890 PreParserExpression left, |
| 773 PreParserExpression right, | 891 PreParserExpression right, |
| 774 int pos) { | 892 int pos) { |
| 775 return PreParserExpression::Default(); | 893 return PreParserExpression::Default(pos); |
| 776 } | 894 } |
| 777 PreParserExpression NewYield(PreParserExpression generator_object, | 895 PreParserExpression NewYield(PreParserExpression generator_object, |
| 778 PreParserExpression expression, | 896 PreParserExpression expression, |
| 779 Yield::Kind yield_kind, | 897 Yield::Kind yield_kind, |
| 780 int pos) { | 898 int pos) { |
| 781 return PreParserExpression::Default(); | 899 return PreParserExpression::Default(pos); |
| 782 } | 900 } |
| 783 PreParserExpression NewConditional(PreParserExpression condition, | 901 PreParserExpression NewConditional(PreParserExpression condition, |
| 784 PreParserExpression then_expression, | 902 PreParserExpression then_expression, |
| 785 PreParserExpression else_expression, | 903 PreParserExpression else_expression, |
| 786 int pos) { | 904 int pos) { |
| 787 return PreParserExpression::Default(); | 905 return PreParserExpression::Default(pos); |
| 788 } | 906 } |
| 789 PreParserExpression NewCountOperation(Token::Value op, | 907 PreParserExpression NewCountOperation(Token::Value op, |
| 790 bool is_prefix, | 908 bool is_prefix, |
| 791 PreParserExpression expression, | 909 PreParserExpression expression, |
| 792 int pos) { | 910 int pos) { |
| 793 return PreParserExpression::Default(); | 911 return PreParserExpression::Default(pos); |
| 794 } | 912 } |
| 795 PreParserExpression NewCall(PreParserExpression expression, | 913 PreParserExpression NewCall(PreParserExpression expression, |
| 796 PreParserExpressionList arguments, | 914 PreParserExpressionList arguments, |
| 797 int pos) { | 915 int pos) { |
| 798 return PreParserExpression::Call(); | 916 return PreParserExpression::Call(pos); |
| 799 } | 917 } |
| 800 PreParserExpression NewCallNew(PreParserExpression expression, | 918 PreParserExpression NewCallNew(PreParserExpression expression, |
| 801 PreParserExpressionList arguments, | 919 PreParserExpressionList arguments, |
| 802 int pos) { | 920 int pos) { |
| 803 return PreParserExpression::Default(); | 921 return PreParserExpression::Default(pos); |
| 804 } | 922 } |
| 923 PreParserStatement NewReturnStatement(PreParserExpression expression, | |
| 924 int pos) { | |
| 925 return PreParserStatement::Default(); | |
| 926 } | |
| 927 PreParserExpression | |
| 928 NewFunctionLiteral(PreParserIdentifier name, | |
| 929 PreParserScope& scope, | |
| 930 PreParserStatementList body, | |
| 931 int materialized_literal_count, | |
| 932 int expected_property_count, | |
| 933 int handler_count, | |
| 934 int parameter_count, | |
| 935 FunctionLiteral::ParameterFlag has_duplicate_parameters, | |
| 936 FunctionLiteral::FunctionType function_type, | |
| 937 FunctionLiteral::IsFunctionFlag is_function, | |
| 938 FunctionLiteral::IsParenthesizedFlag is_parenthesized, | |
| 939 FunctionLiteral::IsGeneratorFlag is_generator, | |
|
marja
2014/04/24 08:08:06
Instead of IsGeneratorFlag and IsArrowFlag you sho
aperez
2014/04/24 12:38:37
Okay.
| |
| 940 FunctionLiteral::IsArrowFlag is_arrow, | |
| 941 int position) { | |
| 942 return PreParserExpression::Default(position); | |
| 943 } | |
| 944 | |
| 945 // Return the object itself as AstVisitor and implement the needed | |
| 946 // dummy method right in this class. | |
| 947 PreParserFactory* visitor() { return this; } | |
| 948 BailoutReason dont_optimize_reason() { return kNoReason; } | |
| 949 int* ast_properties() { return NULL; } | |
| 950 int* slot_processor() { return NULL; } | |
| 805 }; | 951 }; |
| 806 | 952 |
| 807 | 953 |
| 808 class PreParser; | 954 class PreParser; |
| 809 | 955 |
| 810 class PreParserTraits { | 956 class PreParserTraits { |
| 811 public: | 957 public: |
| 812 struct Type { | 958 struct Type { |
| 813 // TODO(marja): To be removed. The Traits object should contain all the data | 959 // TODO(marja): To be removed. The Traits object should contain all the data |
| 814 // it needs. | 960 // it needs. |
| 815 typedef PreParser* Parser; | 961 typedef PreParser* Parser; |
| 816 | 962 |
| 817 // Used by FunctionState and BlockState. | 963 // Used by FunctionState and BlockState. |
| 818 typedef PreParserScope Scope; | 964 typedef PreParserScope Scope; |
| 965 typedef PreParserScope ScopePtr; | |
| 966 | |
| 819 // PreParser doesn't need to store generator variables. | 967 // PreParser doesn't need to store generator variables. |
| 820 typedef void GeneratorVariable; | 968 typedef void GeneratorVariable; |
| 821 // No interaction with Zones. | 969 // No interaction with Zones. |
| 822 typedef void Zone; | 970 typedef void Zone; |
| 823 | 971 |
| 972 typedef int AstProperties; | |
| 973 typedef int DeferredFeedbackSlotProcessor; | |
| 974 typedef Vector<const PreParserIdentifier> ParameterIdentifierVector; | |
| 975 | |
| 824 // Return types for traversing functions. | 976 // Return types for traversing functions. |
| 825 typedef PreParserIdentifier Identifier; | 977 typedef PreParserIdentifier Identifier; |
| 826 typedef PreParserExpression Expression; | 978 typedef PreParserExpression Expression; |
| 827 typedef PreParserExpression YieldExpression; | 979 typedef PreParserExpression YieldExpression; |
| 828 typedef PreParserExpression FunctionLiteral; | 980 typedef PreParserExpression FunctionLiteral; |
| 829 typedef PreParserExpression ObjectLiteralProperty; | 981 typedef PreParserExpression ObjectLiteralProperty; |
| 830 typedef PreParserExpression Literal; | 982 typedef PreParserExpression Literal; |
| 831 typedef PreParserExpressionList ExpressionList; | 983 typedef PreParserExpressionList ExpressionList; |
| 832 typedef PreParserExpressionList PropertyList; | 984 typedef PreParserExpressionList PropertyList; |
| 985 typedef PreParserStatementList StatementList; | |
| 833 | 986 |
| 834 // For constructing objects returned by the traversing functions. | 987 // For constructing objects returned by the traversing functions. |
| 835 typedef PreParserFactory Factory; | 988 typedef PreParserFactory Factory; |
| 836 }; | 989 }; |
| 837 | 990 |
| 838 explicit PreParserTraits(PreParser* pre_parser) : pre_parser_(pre_parser) {} | 991 explicit PreParserTraits(PreParser* pre_parser) : pre_parser_(pre_parser) {} |
| 839 | 992 |
| 840 // Custom operations executed when FunctionStates are created and | 993 // Custom operations executed when FunctionStates are created and |
| 841 // destructed. (The PreParser doesn't need to do anything.) | 994 // destructed. (The PreParser doesn't need to do anything.) |
| 842 template<typename FunctionState> | 995 template<typename FunctionState> |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 875 // operations interleaved with the recursive descent. | 1028 // operations interleaved with the recursive descent. |
| 876 static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) { | 1029 static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) { |
| 877 // PreParser should not use FuncNameInferrer. | 1030 // PreParser should not use FuncNameInferrer. |
| 878 UNREACHABLE(); | 1031 UNREACHABLE(); |
| 879 } | 1032 } |
| 880 static void PushPropertyName(FuncNameInferrer* fni, | 1033 static void PushPropertyName(FuncNameInferrer* fni, |
| 881 PreParserExpression expression) { | 1034 PreParserExpression expression) { |
| 882 // PreParser should not use FuncNameInferrer. | 1035 // PreParser should not use FuncNameInferrer. |
| 883 UNREACHABLE(); | 1036 UNREACHABLE(); |
| 884 } | 1037 } |
| 1038 static void InferFunctionName(FuncNameInferrer* fni, | |
| 1039 PreParserExpression expression) { | |
| 1040 // PreParser should not use FuncNameInferrer. | |
| 1041 UNREACHABLE(); | |
| 1042 } | |
| 885 | 1043 |
| 886 static void CheckFunctionLiteralInsideTopLevelObjectLiteral( | 1044 static void CheckFunctionLiteralInsideTopLevelObjectLiteral( |
| 887 PreParserScope* scope, PreParserExpression value, bool* has_function) {} | 1045 PreParserScope* scope, PreParserExpression value, bool* has_function) {} |
| 888 | 1046 |
| 889 static void CheckAssigningFunctionLiteralToProperty( | 1047 static void CheckAssigningFunctionLiteralToProperty( |
| 890 PreParserExpression left, PreParserExpression right) {} | 1048 PreParserExpression left, PreParserExpression right) {} |
| 891 | 1049 |
| 892 // PreParser doesn't need to keep track of eval calls. | 1050 // PreParser doesn't need to keep track of eval calls. |
| 893 static void CheckPossibleEvalCall(PreParserExpression expression, | 1051 static void CheckPossibleEvalCall(PreParserExpression expression, |
| 894 PreParserScope* scope) {} | 1052 PreParserScope* scope) {} |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 918 return PreParserExpression::Default(); | 1076 return PreParserExpression::Default(); |
| 919 } | 1077 } |
| 920 PreParserExpression NewThrowSyntaxError( | 1078 PreParserExpression NewThrowSyntaxError( |
| 921 const char* type, Handle<Object> arg, int pos) { | 1079 const char* type, Handle<Object> arg, int pos) { |
| 922 return PreParserExpression::Default(); | 1080 return PreParserExpression::Default(); |
| 923 } | 1081 } |
| 924 PreParserExpression NewThrowTypeError( | 1082 PreParserExpression NewThrowTypeError( |
| 925 const char* type, Handle<Object> arg, int pos) { | 1083 const char* type, Handle<Object> arg, int pos) { |
| 926 return PreParserExpression::Default(); | 1084 return PreParserExpression::Default(); |
| 927 } | 1085 } |
| 1086 PreParserScope NewScope(PreParserScope* outer_scope, | |
| 1087 ScopeType scope_type) { | |
| 1088 return PreParserScope(outer_scope, scope_type); | |
| 1089 } | |
| 928 | 1090 |
| 929 // Reporting errors. | 1091 // Reporting errors. |
| 930 void ReportMessageAt(Scanner::Location location, | 1092 void ReportMessageAt(Scanner::Location location, |
| 931 const char* message, | 1093 const char* message, |
| 932 Vector<const char*> args, | 1094 Vector<const char*> args, |
| 933 bool is_reference_error = false); | 1095 bool is_reference_error = false); |
| 934 void ReportMessageAt(Scanner::Location location, | 1096 void ReportMessageAt(Scanner::Location location, |
| 935 const char* type, | 1097 const char* type, |
| 936 const char* name_opt, | 1098 const char* name_opt, |
| 937 bool is_reference_error = false); | 1099 bool is_reference_error = false); |
| 938 void ReportMessageAt(int start_pos, | 1100 void ReportMessageAt(int start_pos, |
| 939 int end_pos, | 1101 int end_pos, |
| 940 const char* type, | 1102 const char* type, |
| 941 const char* name_opt, | 1103 const char* name_opt, |
| 942 bool is_reference_error = false); | 1104 bool is_reference_error = false); |
| 943 | 1105 |
| 944 // "null" return type creators. | 1106 // "null" return type creators. |
| 945 static PreParserIdentifier EmptyIdentifier() { | 1107 static PreParserIdentifier EmptyIdentifier() { |
| 946 return PreParserIdentifier::Default(); | 1108 return PreParserIdentifier::Default(RelocInfo::kNoPosition); |
| 1109 } | |
| 1110 static PreParserIdentifier EmptyIdentifierString() { | |
| 1111 return PreParserIdentifier::Default(RelocInfo::kNoPosition); | |
| 947 } | 1112 } |
| 948 static PreParserExpression EmptyExpression() { | 1113 static PreParserExpression EmptyExpression() { |
| 949 return PreParserExpression::Default(); | 1114 return PreParserExpression::Default(); |
| 950 } | 1115 } |
| 951 static PreParserExpression EmptyLiteral() { | 1116 static PreParserExpression EmptyLiteral() { |
| 952 return PreParserExpression::Default(); | 1117 return PreParserExpression::Default(); |
| 953 } | 1118 } |
| 954 static PreParserExpressionList NullExpressionList() { | 1119 static PreParserExpressionList NullExpressionList() { |
| 955 return PreParserExpressionList(); | 1120 return PreParserExpressionList(); |
| 956 } | 1121 } |
| 957 | 1122 |
| 958 // Odd-ball literal creators. | 1123 // Odd-ball literal creators. |
| 959 static PreParserExpression GetLiteralTheHole(int position, | 1124 static PreParserExpression GetLiteralTheHole(int position, |
| 960 PreParserFactory* factory) { | 1125 PreParserFactory* factory) { |
| 961 return PreParserExpression::Default(); | 1126 return PreParserExpression::Default(); |
| 962 } | 1127 } |
| 963 | 1128 |
| 964 // Producing data during the recursive descent. | 1129 // Producing data during the recursive descent. |
| 965 PreParserIdentifier GetSymbol(Scanner* scanner); | 1130 PreParserIdentifier GetSymbol(Scanner* scanner); |
| 966 static PreParserIdentifier NextLiteralString(Scanner* scanner, | 1131 static PreParserIdentifier NextLiteralString(Scanner* scanner, |
| 967 PretenureFlag tenured) { | 1132 PretenureFlag tenured) { |
| 968 return PreParserIdentifier::Default(); | 1133 // This is used by the regexp parsing, which does not use the |
| 1134 // positions of items from the preparser mini-AST. | |
| 1135 return PreParserIdentifier::Default(RelocInfo::kNoPosition); | |
| 969 } | 1136 } |
| 970 | 1137 |
| 971 static PreParserExpression ThisExpression(PreParserScope* scope, | 1138 static PreParserExpression ThisExpression(PreParserScope* scope, |
| 972 PreParserFactory* factory) { | 1139 PreParserFactory* factory, |
| 973 return PreParserExpression::This(); | 1140 int pos = RelocInfo::kNoPosition) { |
| 1141 return PreParserExpression::This(pos); | |
| 974 } | 1142 } |
| 975 | 1143 |
| 976 static PreParserExpression ExpressionFromLiteral( | 1144 static PreParserExpression ExpressionFromLiteral( |
| 977 Token::Value token, int pos, Scanner* scanner, | 1145 Token::Value token, int pos, Scanner* scanner, |
| 978 PreParserFactory* factory) { | 1146 PreParserFactory* factory) { |
| 979 return PreParserExpression::Default(); | 1147 return PreParserExpression::Default(); |
| 980 } | 1148 } |
| 981 | 1149 |
| 982 static PreParserExpression ExpressionFromIdentifier( | 1150 static PreParserExpression ExpressionFromIdentifier( |
| 983 PreParserIdentifier name, int pos, PreParserScope* scope, | 1151 PreParserIdentifier name, int pos, PreParserScope* scope, |
| 984 PreParserFactory* factory) { | 1152 PreParserFactory* factory) { |
| 985 return PreParserExpression::FromIdentifier(name); | 1153 return PreParserExpression::FromIdentifier(name); |
| 986 } | 1154 } |
| 987 | 1155 |
| 988 PreParserExpression ExpressionFromString(int pos, | 1156 PreParserExpression ExpressionFromString(int pos, |
| 989 Scanner* scanner, | 1157 Scanner* scanner, |
| 990 PreParserFactory* factory = NULL); | 1158 PreParserFactory* factory = NULL); |
| 991 | 1159 |
| 992 static PreParserExpressionList NewExpressionList(int size, void* zone) { | 1160 static PreParserExpressionList NewExpressionList(int size, void* zone) { |
| 993 return PreParserExpressionList(); | 1161 return PreParserExpressionList(); |
| 994 } | 1162 } |
| 995 | 1163 |
| 1164 static PreParserStatementList NewStatementList(int size, void* zone) { | |
| 1165 return PreParserStatementList(); | |
| 1166 } | |
| 1167 | |
| 996 static PreParserExpressionList NewPropertyList(int size, void* zone) { | 1168 static PreParserExpressionList NewPropertyList(int size, void* zone) { |
| 997 return PreParserExpressionList(); | 1169 return PreParserExpressionList(); |
| 998 } | 1170 } |
| 999 | 1171 |
| 1172 V8_INLINE void SkipLazyFunctionBody( | |
| 1173 PreParserIdentifier function_name, | |
| 1174 int* materialized_literal_count, | |
| 1175 int* expected_property_count, | |
| 1176 bool* ok); | |
| 1177 V8_INLINE PreParserStatementList ParseEagerFunctionBody( | |
| 1178 PreParserIdentifier function_name, | |
| 1179 int pos, | |
| 1180 Variable* fvar, | |
| 1181 Token::Value fvar_init_op, | |
| 1182 bool is_generator, | |
| 1183 bool* ok); | |
| 1184 | |
| 1185 // Utility functions | |
| 1186 Vector<const PreParserIdentifier> ParameterListFromExpression( | |
| 1187 PreParserExpression expression, bool* ok) { | |
| 1188 return Vector<const PreParserIdentifier>::empty(); | |
|
marja
2014/04/24 08:08:06
This makes PreParser accept a different language t
aperez
2014/04/24 12:38:37
That is actually a neat idea, I will give it a try
| |
| 1189 } | |
| 1190 | |
| 1191 void CheckConflictingVarDeclarations( | |
| 1192 PreParserScope scope, | |
| 1193 bool* ok) {} | |
| 1194 | |
| 1000 // Temporary glue; these functions will move to ParserBase. | 1195 // Temporary glue; these functions will move to ParserBase. |
| 1001 PreParserExpression ParseV8Intrinsic(bool* ok); | 1196 PreParserExpression ParseV8Intrinsic(bool* ok); |
| 1002 PreParserExpression ParseFunctionLiteral( | 1197 PreParserExpression ParseFunctionLiteral( |
| 1003 PreParserIdentifier name, | 1198 PreParserIdentifier name, |
| 1004 Scanner::Location function_name_location, | 1199 Scanner::Location function_name_location, |
| 1005 bool name_is_strict_reserved, | 1200 bool name_is_strict_reserved, |
| 1006 bool is_generator, | 1201 bool is_generator, |
| 1007 int function_token_position, | 1202 int function_token_position, |
| 1008 FunctionLiteral::FunctionType type, | 1203 FunctionLiteral::FunctionType type, |
| 1009 bool* ok); | 1204 bool* ok); |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 1022 // The grammar check is only performed in order to understand the program | 1217 // The grammar check is only performed in order to understand the program |
| 1023 // sufficiently to deduce some information about it, that can be used | 1218 // sufficiently to deduce some information about it, that can be used |
| 1024 // to speed up later parsing. Finding errors is not the goal of pre-parsing, | 1219 // to speed up later parsing. Finding errors is not the goal of pre-parsing, |
| 1025 // rather it is to speed up properly written and correct programs. | 1220 // rather it is to speed up properly written and correct programs. |
| 1026 // That means that contextual checks (like a label being declared where | 1221 // That means that contextual checks (like a label being declared where |
| 1027 // it is used) are generally omitted. | 1222 // it is used) are generally omitted. |
| 1028 class PreParser : public ParserBase<PreParserTraits> { | 1223 class PreParser : public ParserBase<PreParserTraits> { |
| 1029 public: | 1224 public: |
| 1030 typedef PreParserIdentifier Identifier; | 1225 typedef PreParserIdentifier Identifier; |
| 1031 typedef PreParserExpression Expression; | 1226 typedef PreParserExpression Expression; |
| 1227 typedef PreParserStatement Statement; | |
| 1032 | 1228 |
| 1033 enum PreParseResult { | 1229 enum PreParseResult { |
| 1034 kPreParseStackOverflow, | 1230 kPreParseStackOverflow, |
| 1035 kPreParseSuccess | 1231 kPreParseSuccess |
| 1036 }; | 1232 }; |
| 1037 | 1233 |
| 1038 PreParser(Scanner* scanner, ParserRecorder* log, uintptr_t stack_limit) | 1234 PreParser(Scanner* scanner, ParserRecorder* log, uintptr_t stack_limit) |
| 1039 : ParserBase<PreParserTraits>(scanner, stack_limit, NULL, log, NULL, | 1235 : ParserBase<PreParserTraits>(scanner, stack_limit, NULL, log, NULL, |
| 1040 this) {} | 1236 this) {} |
| 1041 | 1237 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1083 kStatement, | 1279 kStatement, |
| 1084 kForStatement | 1280 kForStatement |
| 1085 }; | 1281 }; |
| 1086 | 1282 |
| 1087 // If a list of variable declarations includes any initializers. | 1283 // If a list of variable declarations includes any initializers. |
| 1088 enum VariableDeclarationProperties { | 1284 enum VariableDeclarationProperties { |
| 1089 kHasInitializers, | 1285 kHasInitializers, |
| 1090 kHasNoInitializers | 1286 kHasNoInitializers |
| 1091 }; | 1287 }; |
| 1092 | 1288 |
| 1093 class Statement { | |
| 1094 public: | |
| 1095 static Statement Default() { | |
| 1096 return Statement(kUnknownStatement); | |
| 1097 } | |
| 1098 | |
| 1099 static Statement FunctionDeclaration() { | |
| 1100 return Statement(kFunctionDeclaration); | |
| 1101 } | |
| 1102 | |
| 1103 // Creates expression statement from expression. | |
| 1104 // Preserves being an unparenthesized string literal, possibly | |
| 1105 // "use strict". | |
| 1106 static Statement ExpressionStatement(Expression expression) { | |
| 1107 if (expression.IsUseStrictLiteral()) { | |
| 1108 return Statement(kUseStrictExpressionStatement); | |
| 1109 } | |
| 1110 if (expression.IsStringLiteral()) { | |
| 1111 return Statement(kStringLiteralExpressionStatement); | |
| 1112 } | |
| 1113 return Default(); | |
| 1114 } | |
| 1115 | |
| 1116 bool IsStringLiteral() { | |
| 1117 return code_ == kStringLiteralExpressionStatement; | |
| 1118 } | |
| 1119 | |
| 1120 bool IsUseStrictLiteral() { | |
| 1121 return code_ == kUseStrictExpressionStatement; | |
| 1122 } | |
| 1123 | |
| 1124 bool IsFunctionDeclaration() { | |
| 1125 return code_ == kFunctionDeclaration; | |
| 1126 } | |
| 1127 | |
| 1128 private: | |
| 1129 enum Type { | |
| 1130 kUnknownStatement, | |
| 1131 kStringLiteralExpressionStatement, | |
| 1132 kUseStrictExpressionStatement, | |
| 1133 kFunctionDeclaration | |
| 1134 }; | |
| 1135 | |
| 1136 explicit Statement(Type code) : code_(code) {} | |
| 1137 Type code_; | |
| 1138 }; | |
| 1139 | |
| 1140 enum SourceElements { | 1289 enum SourceElements { |
| 1141 kUnknownSourceElements | 1290 kUnknownSourceElements |
| 1142 }; | 1291 }; |
| 1143 | 1292 |
| 1144 // All ParseXXX functions take as the last argument an *ok parameter | 1293 // All ParseXXX functions take as the last argument an *ok parameter |
| 1145 // which is set to false if parsing failed; it is unchanged otherwise. | 1294 // which is set to false if parsing failed; it is unchanged otherwise. |
| 1146 // By making the 'exception handling' explicit, we are forced to check | 1295 // By making the 'exception handling' explicit, we are forced to check |
| 1147 // for failure at the call sites. | 1296 // for failure at the call sites. |
| 1148 Statement ParseSourceElement(bool* ok); | 1297 Statement ParseSourceElement(bool* ok); |
| 1149 SourceElements ParseSourceElements(int end_token, bool* ok); | 1298 SourceElements ParseSourceElements(int end_token, bool* ok); |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 1179 bool name_is_strict_reserved, | 1328 bool name_is_strict_reserved, |
| 1180 bool is_generator, | 1329 bool is_generator, |
| 1181 int function_token_pos, | 1330 int function_token_pos, |
| 1182 FunctionLiteral::FunctionType function_type, | 1331 FunctionLiteral::FunctionType function_type, |
| 1183 bool* ok); | 1332 bool* ok); |
| 1184 void ParseLazyFunctionLiteralBody(bool* ok); | 1333 void ParseLazyFunctionLiteralBody(bool* ok); |
| 1185 | 1334 |
| 1186 bool CheckInOrOf(bool accept_OF); | 1335 bool CheckInOrOf(bool accept_OF); |
| 1187 }; | 1336 }; |
| 1188 | 1337 |
| 1338 | |
| 1339 void PreParserTraits::SkipLazyFunctionBody( | |
| 1340 PreParserIdentifier function_name, | |
| 1341 int* materialized_literal_count, | |
| 1342 int* expected_property_count, | |
| 1343 bool* ok) { | |
| 1344 pre_parser_->SkipLazyFunctionBody(function_name, | |
| 1345 materialized_literal_count, expected_property_count, ok); | |
| 1346 } | |
| 1347 | |
| 1348 | |
| 1349 PreParserStatementList PreParserTraits::ParseEagerFunctionBody( | |
| 1350 PreParserIdentifier function_name, | |
| 1351 int pos, | |
| 1352 Variable* fvar, | |
| 1353 Token::Value fvar_init_op, | |
| 1354 bool is_generator, | |
| 1355 bool* ok) { | |
| 1356 return pre_parser_->ParseEagerFunctionBody(function_name, | |
| 1357 pos, fvar, fvar_init_op, is_generator, ok); | |
| 1358 } | |
| 1359 | |
| 1360 | |
| 1189 template<class Traits> | 1361 template<class Traits> |
| 1190 ParserBase<Traits>::FunctionState::FunctionState( | 1362 ParserBase<Traits>::FunctionState::FunctionState( |
| 1191 FunctionState** function_state_stack, | 1363 FunctionState** function_state_stack, |
| 1192 typename Traits::Type::Scope** scope_stack, | 1364 typename Traits::Type::Scope** scope_stack, |
| 1193 typename Traits::Type::Scope* scope, | 1365 typename Traits::Type::Scope* scope, |
| 1194 typename Traits::Type::Zone* extra_param) | 1366 typename Traits::Type::Zone* extra_param) |
| 1195 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize), | 1367 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize), |
| 1196 next_handler_index_(0), | 1368 next_handler_index_(0), |
| 1197 expected_property_count_(0), | 1369 expected_property_count_(0), |
| 1198 is_generator_(false), | 1370 is_generator_(false), |
| 1199 generator_object_variable_(NULL), | 1371 generator_object_variable_(NULL), |
| 1200 function_state_stack_(function_state_stack), | 1372 function_state_stack_(function_state_stack), |
| 1201 outer_function_state_(*function_state_stack), | 1373 outer_function_state_(*function_state_stack), |
| 1202 scope_stack_(scope_stack), | 1374 scope_stack_(scope_stack), |
| 1203 outer_scope_(*scope_stack), | 1375 outer_scope_(*scope_stack), |
| 1204 saved_ast_node_id_(0), | 1376 saved_ast_node_id_(0), |
| 1205 extra_param_(extra_param), | 1377 extra_param_(extra_param), |
| 1206 factory_(extra_param) { | 1378 factory_(extra_param) { |
| 1207 *scope_stack_ = scope; | 1379 *scope_stack_ = scope; |
| 1208 *function_state_stack = this; | 1380 *function_state_stack = this; |
| 1209 Traits::SetUpFunctionState(this, extra_param); | 1381 Traits::SetUpFunctionState(this, extra_param); |
| 1210 } | 1382 } |
| 1211 | 1383 |
| 1212 | 1384 |
| 1213 template<class Traits> | 1385 template<class Traits> |
| 1386 ParserBase<Traits>::FunctionState::FunctionState( | |
| 1387 FunctionState** function_state_stack, | |
| 1388 typename Traits::Type::Scope** scope_stack, | |
| 1389 typename Traits::Type::Scope** scope, | |
| 1390 typename Traits::Type::Zone* extra_param) | |
| 1391 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize), | |
| 1392 next_handler_index_(0), | |
| 1393 expected_property_count_(0), | |
| 1394 is_generator_(false), | |
| 1395 generator_object_variable_(NULL), | |
| 1396 function_state_stack_(function_state_stack), | |
| 1397 outer_function_state_(*function_state_stack), | |
| 1398 scope_stack_(scope_stack), | |
| 1399 outer_scope_(*scope_stack), | |
| 1400 saved_ast_node_id_(0), | |
| 1401 extra_param_(extra_param), | |
| 1402 factory_(extra_param) { | |
| 1403 *scope_stack_ = *scope; | |
| 1404 *function_state_stack = this; | |
| 1405 Traits::SetUpFunctionState(this, extra_param); | |
| 1406 } | |
| 1407 | |
| 1408 | |
| 1409 template<class Traits> | |
| 1214 ParserBase<Traits>::FunctionState::~FunctionState() { | 1410 ParserBase<Traits>::FunctionState::~FunctionState() { |
| 1215 *scope_stack_ = outer_scope_; | 1411 *scope_stack_ = outer_scope_; |
| 1216 *function_state_stack_ = outer_function_state_; | 1412 *function_state_stack_ = outer_function_state_; |
| 1217 Traits::TearDownFunctionState(this, extra_param_); | 1413 Traits::TearDownFunctionState(this, extra_param_); |
| 1218 } | 1414 } |
| 1219 | 1415 |
| 1220 | 1416 |
| 1221 template<class Traits> | 1417 template<class Traits> |
| 1222 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) { | 1418 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) { |
| 1223 Scanner::Location source_location = scanner()->location(); | 1419 Scanner::Location source_location = scanner()->location(); |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1371 // ObjectLiteral | 1567 // ObjectLiteral |
| 1372 // RegExpLiteral | 1568 // RegExpLiteral |
| 1373 // '(' Expression ')' | 1569 // '(' Expression ')' |
| 1374 | 1570 |
| 1375 int pos = peek_position(); | 1571 int pos = peek_position(); |
| 1376 ExpressionT result = this->EmptyExpression(); | 1572 ExpressionT result = this->EmptyExpression(); |
| 1377 Token::Value token = peek(); | 1573 Token::Value token = peek(); |
| 1378 switch (token) { | 1574 switch (token) { |
| 1379 case Token::THIS: { | 1575 case Token::THIS: { |
| 1380 Consume(Token::THIS); | 1576 Consume(Token::THIS); |
| 1381 result = this->ThisExpression(scope_, factory()); | 1577 result = this->ThisExpression(scope_, factory(), pos); |
| 1382 break; | 1578 break; |
| 1383 } | 1579 } |
| 1384 | 1580 |
| 1385 case Token::NULL_LITERAL: | 1581 case Token::NULL_LITERAL: |
| 1386 case Token::TRUE_LITERAL: | 1582 case Token::TRUE_LITERAL: |
| 1387 case Token::FALSE_LITERAL: | 1583 case Token::FALSE_LITERAL: |
| 1388 case Token::NUMBER: | 1584 case Token::NUMBER: |
| 1389 Next(); | 1585 Next(); |
| 1390 result = this->ExpressionFromLiteral(token, pos, scanner(), factory()); | 1586 result = this->ExpressionFromLiteral(token, pos, scanner(), factory()); |
| 1391 break; | 1587 break; |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1449 } | 1645 } |
| 1450 | 1646 |
| 1451 // Precedence = 1 | 1647 // Precedence = 1 |
| 1452 template <class Traits> | 1648 template <class Traits> |
| 1453 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( | 1649 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( |
| 1454 bool accept_IN, bool* ok) { | 1650 bool accept_IN, bool* ok) { |
| 1455 // Expression :: | 1651 // Expression :: |
| 1456 // AssignmentExpression | 1652 // AssignmentExpression |
| 1457 // Expression ',' AssignmentExpression | 1653 // Expression ',' AssignmentExpression |
| 1458 | 1654 |
| 1655 if (allow_arrow_functions() && peek() == Token::RPAREN && | |
| 1656 scanner()->current_token() == Token::LPAREN) { | |
| 1657 // Empty argument list for arrow functions: () => ... | |
| 1658 return this->EmptyExpression(); | |
| 1659 } | |
| 1660 | |
| 1459 ExpressionT result = this->ParseAssignmentExpression(accept_IN, CHECK_OK); | 1661 ExpressionT result = this->ParseAssignmentExpression(accept_IN, CHECK_OK); |
| 1460 while (peek() == Token::COMMA) { | 1662 while (peek() == Token::COMMA) { |
| 1461 Expect(Token::COMMA, CHECK_OK); | 1663 Expect(Token::COMMA, CHECK_OK); |
| 1462 int pos = position(); | 1664 int pos = position(); |
| 1463 ExpressionT right = this->ParseAssignmentExpression(accept_IN, CHECK_OK); | 1665 ExpressionT right = this->ParseAssignmentExpression(accept_IN, CHECK_OK); |
| 1464 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); | 1666 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); |
| 1465 } | 1667 } |
| 1466 return result; | 1668 return result; |
| 1467 } | 1669 } |
| 1468 | 1670 |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1689 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList)); | 1891 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList)); |
| 1690 return result; | 1892 return result; |
| 1691 } | 1893 } |
| 1692 | 1894 |
| 1693 // Precedence = 2 | 1895 // Precedence = 2 |
| 1694 template <class Traits> | 1896 template <class Traits> |
| 1695 typename ParserBase<Traits>::ExpressionT | 1897 typename ParserBase<Traits>::ExpressionT |
| 1696 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) { | 1898 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) { |
| 1697 // AssignmentExpression :: | 1899 // AssignmentExpression :: |
| 1698 // ConditionalExpression | 1900 // ConditionalExpression |
| 1901 // ArrowFunction | |
| 1699 // YieldExpression | 1902 // YieldExpression |
| 1700 // LeftHandSideExpression AssignmentOperator AssignmentExpression | 1903 // LeftHandSideExpression AssignmentOperator AssignmentExpression |
| 1701 | 1904 |
| 1702 Scanner::Location lhs_location = scanner()->peek_location(); | 1905 Scanner::Location lhs_location = scanner()->peek_location(); |
| 1703 | 1906 |
| 1704 if (peek() == Token::YIELD && is_generator()) { | 1907 if (peek() == Token::YIELD && is_generator()) { |
| 1705 return this->ParseYieldExpression(ok); | 1908 return this->ParseYieldExpression(ok); |
| 1706 } | 1909 } |
| 1707 | 1910 |
| 1708 if (fni_ != NULL) fni_->Enter(); | 1911 if (fni_ != NULL) fni_->Enter(); |
| 1709 ExpressionT expression = | 1912 ExpressionT expression = |
| 1710 this->ParseConditionalExpression(accept_IN, CHECK_OK); | 1913 this->ParseConditionalExpression(accept_IN, CHECK_OK); |
| 1711 | 1914 |
| 1915 if (allow_arrow_functions() && peek() == Token::ARROW) | |
| 1916 return this->ParseArrowFunctionLiteral(lhs_location.beg_pos, | |
| 1917 expression, | |
| 1918 CHECK_OK); | |
| 1919 | |
| 1712 if (!Token::IsAssignmentOp(peek())) { | 1920 if (!Token::IsAssignmentOp(peek())) { |
| 1713 if (fni_ != NULL) fni_->Leave(); | 1921 if (fni_ != NULL) fni_->Leave(); |
| 1714 // Parsed conditional expression only (no assignment). | 1922 // Parsed conditional expression only (no assignment). |
| 1715 return expression; | 1923 return expression; |
| 1716 } | 1924 } |
| 1717 | 1925 |
| 1718 expression = this->CheckAndRewriteReferenceExpression( | 1926 expression = this->CheckAndRewriteReferenceExpression( |
| 1719 expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK); | 1927 expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK); |
| 1720 expression = this->MarkExpressionAsLValue(expression); | 1928 expression = this->MarkExpressionAsLValue(expression); |
| 1721 | 1929 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1755 template <class Traits> | 1963 template <class Traits> |
| 1756 typename ParserBase<Traits>::ExpressionT | 1964 typename ParserBase<Traits>::ExpressionT |
| 1757 ParserBase<Traits>::ParseYieldExpression(bool* ok) { | 1965 ParserBase<Traits>::ParseYieldExpression(bool* ok) { |
| 1758 // YieldExpression :: | 1966 // YieldExpression :: |
| 1759 // 'yield' '*'? AssignmentExpression | 1967 // 'yield' '*'? AssignmentExpression |
| 1760 int pos = peek_position(); | 1968 int pos = peek_position(); |
| 1761 Expect(Token::YIELD, CHECK_OK); | 1969 Expect(Token::YIELD, CHECK_OK); |
| 1762 Yield::Kind kind = | 1970 Yield::Kind kind = |
| 1763 Check(Token::MUL) ? Yield::DELEGATING : Yield::SUSPEND; | 1971 Check(Token::MUL) ? Yield::DELEGATING : Yield::SUSPEND; |
| 1764 ExpressionT generator_object = | 1972 ExpressionT generator_object = |
| 1765 factory()->NewVariableProxy(function_state_->generator_object_variable()); | 1973 factory()->NewVariableProxy(function_state_->generator_object_variable(), |
| 1974 pos); | |
| 1766 ExpressionT expression = | 1975 ExpressionT expression = |
| 1767 ParseAssignmentExpression(false, CHECK_OK); | 1976 ParseAssignmentExpression(false, CHECK_OK); |
| 1768 typename Traits::Type::YieldExpression yield = | 1977 typename Traits::Type::YieldExpression yield = |
| 1769 factory()->NewYield(generator_object, expression, kind, pos); | 1978 factory()->NewYield(generator_object, expression, kind, pos); |
| 1770 if (kind == Yield::DELEGATING) { | 1979 if (kind == Yield::DELEGATING) { |
| 1771 yield->set_index(function_state_->NextHandlerIndex()); | 1980 yield->set_index(function_state_->NextHandlerIndex()); |
| 1772 } | 1981 } |
| 1773 return yield; | 1982 return yield; |
| 1774 } | 1983 } |
| 1775 | 1984 |
| (...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2106 } | 2315 } |
| 2107 default: | 2316 default: |
| 2108 return expression; | 2317 return expression; |
| 2109 } | 2318 } |
| 2110 } | 2319 } |
| 2111 ASSERT(false); | 2320 ASSERT(false); |
| 2112 return this->EmptyExpression(); | 2321 return this->EmptyExpression(); |
| 2113 } | 2322 } |
| 2114 | 2323 |
| 2115 | 2324 |
| 2325 template <class Traits> | |
| 2326 typename ParserBase<Traits>::ExpressionT | |
| 2327 ParserBase<Traits>::ParseArrowFunctionLiteral(int start_pos, | |
| 2328 ExpressionT params_ast, | |
| 2329 bool* ok) { | |
| 2330 // TODO(aperez): Change this to use ARROW_SCOPE | |
| 2331 typename Traits::Type::ScopePtr scope = | |
| 2332 this->NewScope(scope_, FUNCTION_SCOPE); | |
| 2333 | |
| 2334 typename Traits::Type::StatementList body; | |
| 2335 typename Traits::Type::AstProperties ast_properties; | |
| 2336 typename Traits::Type::DeferredFeedbackSlotProcessor* slot_processor; | |
| 2337 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_ | |
| 2338 ? FunctionLiteral::kIsParenthesized | |
| 2339 : FunctionLiteral::kNotParenthesized; | |
| 2340 FunctionLiteral::ParameterFlag duplicate_parameters; | |
| 2341 BailoutReason dont_optimize_reason = kNoReason; | |
| 2342 int materialized_literal_count = -1; | |
| 2343 int expected_property_count = -1; | |
| 2344 int handler_count = 0; | |
| 2345 int num_parameters = 0; | |
| 2346 | |
| 2347 { FunctionState function_state(&function_state_, &scope_, &scope, zone()); | |
| 2348 scope->set_start_position(start_pos); | |
| 2349 | |
| 2350 Scanner::Location eval_args_error_loc = Scanner::Location::invalid(); | |
| 2351 Scanner::Location dupe_error_loc = Scanner::Location::invalid(); | |
| 2352 Scanner::Location reserved_loc = Scanner::Location::invalid(); | |
| 2353 | |
| 2354 if (peek() == Token::ARROW) { | |
| 2355 // Function parameters are already parsed into an AST | |
| 2356 typename Traits::Type::ParameterIdentifierVector params = | |
| 2357 Traits::ParameterListFromExpression(params_ast, CHECK_OK); | |
| 2358 | |
| 2359 if ((num_parameters = params.length()) > Code::kMaxArguments) { | |
| 2360 ReportMessageAt(Scanner::Location(params_ast->position(), position()), | |
| 2361 "too_many_parameters"); | |
| 2362 *ok = false; | |
| 2363 return this->EmptyExpression(); | |
| 2364 } | |
| 2365 | |
| 2366 // The vector has the items in reverse order. | |
| 2367 for (int i = params.length() - 1; i >= 0; --i) { | |
| 2368 const IdentifierT param_name = params.at(i)->name(); | |
| 2369 int param_pos = params.at(i)->position(); | |
| 2370 | |
| 2371 // Store locations for possible future error reports. | |
| 2372 if (!eval_args_error_loc.IsValid() && | |
| 2373 this->IsEvalOrArguments(param_name)) { | |
| 2374 eval_args_error_loc = | |
| 2375 Scanner::Location(param_pos, param_pos + param_name->length()); | |
| 2376 } | |
| 2377 if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) { | |
| 2378 dupe_error_loc = | |
| 2379 Scanner::Location(param_pos, param_pos + param_name->length()); | |
| 2380 } | |
| 2381 | |
| 2382 scope_->DeclareParameter(param_name, VAR); | |
| 2383 } | |
| 2384 } else { | |
| 2385 if (peek() == Token::LPAREN) { | |
|
marja
2014/04/24 08:08:06
Hmm, so this function can be called in two ways, f
aperez
2014/04/24 12:38:37
Correct. In that case we know exactly where the pa
| |
| 2386 // Parse a parenthesized parameter list. | |
| 2387 Consume(Token::LPAREN); | |
| 2388 bool done = (peek() == Token::RPAREN); | |
| 2389 while (!done) { | |
| 2390 bool is_strict_reserved = false; | |
| 2391 IdentifierT param_name = | |
| 2392 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, | |
| 2393 CHECK_OK); | |
| 2394 | |
| 2395 // Store locations for possible future error reports. | |
| 2396 if (!eval_args_error_loc.IsValid() && | |
| 2397 this->IsEvalOrArguments(param_name)) { | |
| 2398 eval_args_error_loc = scanner()->location(); | |
| 2399 } | |
| 2400 if (!reserved_loc.IsValid() && is_strict_reserved) { | |
| 2401 reserved_loc = scanner()->location(); | |
| 2402 } | |
| 2403 if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) { | |
| 2404 dupe_error_loc = scanner()->location(); | |
| 2405 } | |
| 2406 | |
| 2407 scope_->DeclareParameter(param_name, VAR); | |
| 2408 num_parameters++; | |
| 2409 if (num_parameters > Code::kMaxArguments) { | |
| 2410 this->ReportMessageAt(scanner()->location(), "too_many_parameters"); | |
| 2411 *ok = false; | |
| 2412 return this->EmptyExpression(); | |
| 2413 } | |
| 2414 done = (peek() == Token::RPAREN); | |
| 2415 if (!done) Expect(Token::COMMA, CHECK_OK); | |
| 2416 } | |
| 2417 Expect(Token::RPAREN, CHECK_OK); | |
| 2418 } else { | |
| 2419 // Parse a single parameter identifier. | |
| 2420 bool is_strict_reserved = false; | |
| 2421 IdentifierT param_name = | |
| 2422 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); | |
| 2423 | |
| 2424 // Store locations for possible future error reports. | |
| 2425 if (this->IsEvalOrArguments(param_name)) | |
| 2426 eval_args_error_loc = scanner()->location(); | |
| 2427 if (is_strict_reserved) | |
| 2428 reserved_loc = scanner()->location(); | |
| 2429 | |
| 2430 scope_->DeclareParameter(param_name, VAR); | |
| 2431 } | |
| 2432 } | |
| 2433 | |
| 2434 Expect(Token::ARROW, CHECK_OK); | |
| 2435 | |
| 2436 if (peek() == Token::LBRACE) { | |
| 2437 // Multiple statemente body | |
| 2438 Consume(Token::LBRACE); | |
| 2439 | |
| 2440 bool is_lazily_parsed = (mode() == PARSE_LAZILY && | |
| 2441 scope_->AllowsLazyCompilation() && | |
| 2442 !parenthesized_function_); | |
| 2443 parenthesized_function_ = false; // This Was set for this funciton only. | |
| 2444 | |
| 2445 if (is_lazily_parsed) { | |
| 2446 this->SkipLazyFunctionBody(this->EmptyIdentifier(), | |
| 2447 &materialized_literal_count, | |
| 2448 &expected_property_count, | |
| 2449 CHECK_OK); | |
| 2450 } else { | |
| 2451 body = this->ParseEagerFunctionBody(this->EmptyIdentifier(), | |
| 2452 RelocInfo::kNoPosition, | |
| 2453 NULL, | |
| 2454 Token::INIT_VAR, | |
| 2455 false, // Not a generator. | |
| 2456 CHECK_OK); | |
| 2457 materialized_literal_count = | |
| 2458 function_state.materialized_literal_count(); | |
| 2459 expected_property_count = function_state.expected_property_count(); | |
| 2460 handler_count = function_state.handler_count(); | |
| 2461 } | |
| 2462 } else { | |
| 2463 // Single-expression body | |
| 2464 int pos = position(); | |
| 2465 parenthesized_function_ = false; | |
| 2466 ExpressionT expression = ParseAssignmentExpression(true, CHECK_OK); | |
| 2467 body = this->NewStatementList(1, zone()); | |
| 2468 body->Add(factory()->NewReturnStatement(expression, pos), zone()); | |
| 2469 scope->set_end_position(scanner()->location().end_pos); | |
| 2470 materialized_literal_count = function_state.materialized_literal_count(); | |
| 2471 expected_property_count = function_state.expected_property_count(); | |
| 2472 handler_count = function_state.handler_count(); | |
| 2473 } | |
| 2474 | |
| 2475 // Validate strict mode. | |
| 2476 if (strict_mode() == STRICT) { | |
| 2477 if (eval_args_error_loc.IsValid()) { | |
| 2478 this->ReportMessageAt(eval_args_error_loc, "strict_eval_arguments"); | |
| 2479 *ok = false; | |
| 2480 return this->EmptyExpression(); | |
| 2481 } | |
| 2482 if (dupe_error_loc.IsValid()) { | |
| 2483 this->ReportMessageAt(dupe_error_loc, "strict_param_dupe"); | |
| 2484 *ok = false; | |
| 2485 return this->EmptyExpression(); | |
| 2486 } | |
| 2487 if (reserved_loc.IsValid()) { | |
| 2488 this->ReportMessageAt(reserved_loc, "unexpected_strict_reserved"); | |
| 2489 *ok = false; | |
| 2490 return this->EmptyExpression(); | |
| 2491 } | |
| 2492 CheckOctalLiteral(start_pos, | |
| 2493 scanner()->location().end_pos, | |
| 2494 CHECK_OK); | |
| 2495 } | |
| 2496 | |
| 2497 duplicate_parameters = dupe_error_loc.IsValid() | |
| 2498 ? FunctionLiteral::kHasDuplicateParameters | |
| 2499 : FunctionLiteral::kNoDuplicateParameters; | |
| 2500 ast_properties = *factory()->visitor()->ast_properties(); | |
| 2501 slot_processor = factory()->visitor()->slot_processor(); | |
| 2502 dont_optimize_reason = factory()->visitor()->dont_optimize_reason(); | |
| 2503 } | |
| 2504 | |
| 2505 if (allow_harmony_scoping() && strict_mode() == STRICT) | |
| 2506 this->CheckConflictingVarDeclarations(scope, CHECK_OK); | |
| 2507 | |
| 2508 FunctionLiteralT function_literal = | |
| 2509 factory()->NewFunctionLiteral(this->EmptyIdentifierString(), | |
| 2510 scope, | |
| 2511 body, | |
| 2512 materialized_literal_count, | |
| 2513 expected_property_count, | |
| 2514 handler_count, | |
| 2515 num_parameters, | |
| 2516 duplicate_parameters, | |
| 2517 FunctionLiteral::ANONYMOUS_EXPRESSION, | |
| 2518 FunctionLiteral::kIsFunction, | |
| 2519 parenthesized, | |
| 2520 FunctionLiteral::kNotGenerator, | |
| 2521 FunctionLiteral::kIsArrow, | |
| 2522 start_pos); | |
| 2523 function_literal->set_function_token_position(start_pos); | |
| 2524 function_literal->set_ast_properties(&ast_properties); | |
| 2525 function_literal->set_slot_processor(slot_processor); | |
| 2526 function_literal->set_dont_optimize_reason(dont_optimize_reason); | |
| 2527 | |
| 2528 if (fni_ != NULL) this->InferFunctionName(fni_, function_literal); | |
| 2529 | |
| 2530 return function_literal; | |
| 2531 } | |
| 2532 | |
| 2533 | |
| 2116 template <typename Traits> | 2534 template <typename Traits> |
| 2117 typename ParserBase<Traits>::ExpressionT | 2535 typename ParserBase<Traits>::ExpressionT |
| 2118 ParserBase<Traits>::CheckAndRewriteReferenceExpression( | 2536 ParserBase<Traits>::CheckAndRewriteReferenceExpression( |
| 2119 ExpressionT expression, | 2537 ExpressionT expression, |
| 2120 Scanner::Location location, const char* message, bool* ok) { | 2538 Scanner::Location location, const char* message, bool* ok) { |
| 2121 if (strict_mode() == STRICT && this->IsIdentifier(expression) && | 2539 if (strict_mode() == STRICT && this->IsIdentifier(expression) && |
| 2122 this->IsEvalOrArguments(this->AsIdentifier(expression))) { | 2540 this->IsEvalOrArguments(this->AsIdentifier(expression))) { |
| 2123 this->ReportMessageAt(location, "strict_eval_arguments", false); | 2541 this->ReportMessageAt(location, "strict_eval_arguments", false); |
| 2124 *ok = false; | 2542 *ok = false; |
| 2125 return this->EmptyExpression(); | 2543 return this->EmptyExpression(); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2172 "accessor_get_set"); | 2590 "accessor_get_set"); |
| 2173 } | 2591 } |
| 2174 *ok = false; | 2592 *ok = false; |
| 2175 } | 2593 } |
| 2176 } | 2594 } |
| 2177 | 2595 |
| 2178 | 2596 |
| 2179 } } // v8::internal | 2597 } } // v8::internal |
| 2180 | 2598 |
| 2181 #endif // V8_PREPARSER_H | 2599 #endif // V8_PREPARSER_H |
| OLD | NEW |