| 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 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 335 } | 335 } |
| 336 | 336 |
| 337 typename Traits::Type::Factory* factory() { | 337 typename Traits::Type::Factory* factory() { |
| 338 return function_state_->factory(); | 338 return function_state_->factory(); |
| 339 } | 339 } |
| 340 | 340 |
| 341 StrictMode strict_mode() { return scope_->strict_mode(); } | 341 StrictMode strict_mode() { return scope_->strict_mode(); } |
| 342 bool is_generator() const { return function_state_->is_generator(); } | 342 bool is_generator() const { return function_state_->is_generator(); } |
| 343 | 343 |
| 344 // Report syntax errors. | 344 // Report syntax errors. |
| 345 void ReportMessage(const char* message, Vector<const char*> args) { | 345 void ReportMessage(const char* message, Vector<const char*> args, |
| 346 bool is_reference_error = false) { |
| 346 Scanner::Location source_location = scanner()->location(); | 347 Scanner::Location source_location = scanner()->location(); |
| 347 Traits::ReportMessageAt(source_location, message, args); | 348 Traits::ReportMessageAt(source_location, message, args, is_reference_error); |
| 348 } | 349 } |
| 349 | 350 |
| 350 void ReportMessageAt(Scanner::Location location, const char* message) { | 351 void ReportMessageAt(Scanner::Location location, const char* message, |
| 351 Traits::ReportMessageAt(location, message, Vector<const char*>::empty()); | 352 bool is_reference_error = false) { |
| 353 Traits::ReportMessageAt(location, message, Vector<const char*>::empty(), |
| 354 is_reference_error); |
| 352 } | 355 } |
| 353 | 356 |
| 354 void ReportUnexpectedToken(Token::Value token); | 357 void ReportUnexpectedToken(Token::Value token); |
| 355 | 358 |
| 356 // Recursive descent functions: | 359 // Recursive descent functions: |
| 357 | 360 |
| 358 // Parses an identifier that is valid for the current scope, in particular it | 361 // Parses an identifier that is valid for the current scope, in particular it |
| 359 // fails on strict mode future reserved keywords in a strict scope. If | 362 // fails on strict mode future reserved keywords in a strict scope. If |
| 360 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or | 363 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or |
| 361 // "arguments" as identifier even in strict mode (this is needed in cases like | 364 // "arguments" as identifier even in strict mode (this is needed in cases like |
| (...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 782 // PreParser should not use FuncNameInferrer. | 785 // PreParser should not use FuncNameInferrer. |
| 783 ASSERT(false); | 786 ASSERT(false); |
| 784 } | 787 } |
| 785 | 788 |
| 786 static void CheckFunctionLiteralInsideTopLevelObjectLiteral( | 789 static void CheckFunctionLiteralInsideTopLevelObjectLiteral( |
| 787 PreParserScope* scope, PreParserExpression value, bool* has_function) {} | 790 PreParserScope* scope, PreParserExpression value, bool* has_function) {} |
| 788 | 791 |
| 789 static void CheckAssigningFunctionLiteralToProperty( | 792 static void CheckAssigningFunctionLiteralToProperty( |
| 790 PreParserExpression left, PreParserExpression right) {} | 793 PreParserExpression left, PreParserExpression right) {} |
| 791 | 794 |
| 792 | 795 // Determine whether the expression is a valid assignment left-hand side. |
| 793 static PreParserExpression ValidateAssignmentLeftHandSide( | 796 static bool IsValidLeftHandSide(PreParserExpression expression) { |
| 794 PreParserExpression expression) { | 797 // TODO(marja): check properly; for now, leave it to parser. |
| 795 // Parser generates a runtime error here if the left hand side is not valid. | 798 return true; |
| 796 // PreParser doesn't have to. | |
| 797 return expression; | |
| 798 } | 799 } |
| 799 | 800 |
| 800 static PreParserExpression MarkExpressionAsLValue( | 801 static PreParserExpression MarkExpressionAsLValue( |
| 801 PreParserExpression expression) { | 802 PreParserExpression expression) { |
| 802 // TODO(marja): To be able to produce the same errors, the preparser needs | 803 // TODO(marja): To be able to produce the same errors, the preparser needs |
| 803 // to start tracking which expressions are variables and which are lvalues. | 804 // to start tracking which expressions are variables and which are lvalues. |
| 804 return expression; | 805 return expression; |
| 805 } | 806 } |
| 806 | 807 |
| 807 // Checks LHS expression for assignment and prefix/postfix increment/decrement | 808 // Checks LHS expression for assignment and prefix/postfix increment/decrement |
| 808 // in strict mode. | 809 // in strict mode. |
| 809 void CheckStrictModeLValue(PreParserExpression expression, bool* ok); | 810 void CheckStrictModeLValue(PreParserExpression expression, bool* ok); |
| 810 | 811 |
| 811 | 812 |
| 812 // Reporting errors. | 813 // Reporting errors. |
| 813 void ReportMessageAt(Scanner::Location location, | 814 void ReportMessageAt(Scanner::Location location, |
| 814 const char* message, | 815 const char* message, |
| 815 Vector<const char*> args); | 816 Vector<const char*> args, |
| 817 bool is_reference_error = false); |
| 816 void ReportMessageAt(Scanner::Location location, | 818 void ReportMessageAt(Scanner::Location location, |
| 817 const char* type, | 819 const char* type, |
| 818 const char* name_opt); | 820 const char* name_opt, |
| 821 bool is_reference_error = false); |
| 819 void ReportMessageAt(int start_pos, | 822 void ReportMessageAt(int start_pos, |
| 820 int end_pos, | 823 int end_pos, |
| 821 const char* type, | 824 const char* type, |
| 822 const char* name_opt); | 825 const char* name_opt, |
| 826 bool is_reference_error = false); |
| 823 | 827 |
| 824 // "null" return type creators. | 828 // "null" return type creators. |
| 825 static PreParserIdentifier EmptyIdentifier() { | 829 static PreParserIdentifier EmptyIdentifier() { |
| 826 return PreParserIdentifier::Default(); | 830 return PreParserIdentifier::Default(); |
| 827 } | 831 } |
| 828 static PreParserExpression EmptyExpression() { | 832 static PreParserExpression EmptyExpression() { |
| 829 return PreParserExpression::Default(); | 833 return PreParserExpression::Default(); |
| 830 } | 834 } |
| 831 static PreParserExpression EmptyLiteral() { | 835 static PreParserExpression EmptyLiteral() { |
| 832 return PreParserExpression::Default(); | 836 return PreParserExpression::Default(); |
| (...skipping 766 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1599 | 1603 |
| 1600 // Precedence = 2 | 1604 // Precedence = 2 |
| 1601 template <class Traits> | 1605 template <class Traits> |
| 1602 typename Traits::Type::Expression ParserBase<Traits>::ParseAssignmentExpression( | 1606 typename Traits::Type::Expression ParserBase<Traits>::ParseAssignmentExpression( |
| 1603 bool accept_IN, bool* ok) { | 1607 bool accept_IN, bool* ok) { |
| 1604 // AssignmentExpression :: | 1608 // AssignmentExpression :: |
| 1605 // ConditionalExpression | 1609 // ConditionalExpression |
| 1606 // YieldExpression | 1610 // YieldExpression |
| 1607 // LeftHandSideExpression AssignmentOperator AssignmentExpression | 1611 // LeftHandSideExpression AssignmentOperator AssignmentExpression |
| 1608 | 1612 |
| 1613 Scanner::Location lhs_location = scanner()->peek_location(); |
| 1614 |
| 1609 if (peek() == Token::YIELD && is_generator()) { | 1615 if (peek() == Token::YIELD && is_generator()) { |
| 1610 return this->ParseYieldExpression(ok); | 1616 return this->ParseYieldExpression(ok); |
| 1611 } | 1617 } |
| 1612 | 1618 |
| 1613 if (fni_ != NULL) fni_->Enter(); | 1619 if (fni_ != NULL) fni_->Enter(); |
| 1614 typename Traits::Type::Expression expression = | 1620 typename Traits::Type::Expression expression = |
| 1615 this->ParseConditionalExpression(accept_IN, CHECK_OK); | 1621 this->ParseConditionalExpression(accept_IN, CHECK_OK); |
| 1616 | 1622 |
| 1617 if (!Token::IsAssignmentOp(peek())) { | 1623 if (!Token::IsAssignmentOp(peek())) { |
| 1618 if (fni_ != NULL) fni_->Leave(); | 1624 if (fni_ != NULL) fni_->Leave(); |
| 1619 // Parsed conditional expression only (no assignment). | 1625 // Parsed conditional expression only (no assignment). |
| 1620 return expression; | 1626 return expression; |
| 1621 } | 1627 } |
| 1622 | 1628 |
| 1623 // Signal a reference error if the expression is an invalid left-hand | 1629 if (!IsValidLeftHandSide(expression)) { |
| 1624 // side expression. We could report this as a syntax error here but | 1630 this->ReportMessageAt(lhs_location, "invalid_lhs_in_assignment", true); |
| 1625 // for compatibility with JSC we choose to report the error at | 1631 *ok = false; |
| 1626 // runtime. | 1632 return this->EmptyExpression(); |
| 1627 // TODO(ES5): Should change parsing for spec conformance. | 1633 } |
| 1628 expression = this->ValidateAssignmentLeftHandSide(expression); | |
| 1629 | 1634 |
| 1630 if (strict_mode() == STRICT) { | 1635 if (strict_mode() == STRICT) { |
| 1631 // Assignment to eval or arguments is disallowed in strict mode. | 1636 // Assignment to eval or arguments is disallowed in strict mode. |
| 1632 this->CheckStrictModeLValue(expression, CHECK_OK); | 1637 this->CheckStrictModeLValue(expression, CHECK_OK); |
| 1633 } | 1638 } |
| 1634 expression = this->MarkExpressionAsLValue(expression); | 1639 expression = this->MarkExpressionAsLValue(expression); |
| 1635 | 1640 |
| 1636 Token::Value op = Next(); // Get assignment operator. | 1641 Token::Value op = Next(); // Get assignment operator. |
| 1637 int pos = position(); | 1642 int pos = position(); |
| 1638 typename Traits::Type::Expression right = | 1643 typename Traits::Type::Expression right = |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1722 "accessor_get_set"); | 1727 "accessor_get_set"); |
| 1723 } | 1728 } |
| 1724 *ok = false; | 1729 *ok = false; |
| 1725 } | 1730 } |
| 1726 } | 1731 } |
| 1727 | 1732 |
| 1728 | 1733 |
| 1729 } } // v8::internal | 1734 } } // v8::internal |
| 1730 | 1735 |
| 1731 #endif // V8_PREPARSER_H | 1736 #endif // V8_PREPARSER_H |
| OLD | NEW |