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 |