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

Side by Side Diff: src/preparser.h

Issue 200473003: Make invalid LHSs a parse-time (reference) error (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Comment Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/parser.cc ('k') | src/preparser.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/parser.cc ('k') | src/preparser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698