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

Unified Diff: src/preparser.h

Issue 217823003: Make invalid LHSs that are calls late errors (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Comments 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/parser.cc ('k') | src/preparser.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/preparser.h
diff --git a/src/preparser.h b/src/preparser.h
index 38d12e11afa752c2eea349b76519d1d59ef1d885..3781631cca9e762ff3ec001351686ab0ace676ec 100644
--- a/src/preparser.h
+++ b/src/preparser.h
@@ -425,6 +425,13 @@ class ParserBase : public Traits {
ExpressionT ParseMemberExpressionContinuation(ExpressionT expression,
bool* ok);
+ // Checks if the expression is a valid reference expression (e.g., on the
+ // left-hand side of assignments). Although ruled out by ECMA as early errors,
+ // we allow calls for web compatibility and rewrite them to a runtime throw.
+ ExpressionT CheckAndRewriteReferenceExpression(
+ ExpressionT expression,
+ Scanner::Location location, const char* message, bool* ok);
+
// Used to detect duplicates in object literals. Each of the values
// kGetterProperty, kSetterProperty and kValueProperty represents
// a type of object literal property. When parsing a property, its
@@ -589,10 +596,14 @@ class PreParserExpression {
return PreParserExpression(kPropertyExpression);
}
+ static PreParserExpression Call() {
+ return PreParserExpression(kCallExpression);
+ }
+
bool IsIdentifier() { return (code_ & kIdentifierFlag) != 0; }
- // Only works corretly if it is actually an identifier expression.
PreParserIdentifier AsIdentifier() {
+ ASSERT(IsIdentifier());
return PreParserIdentifier(
static_cast<PreParserIdentifier::Type>(code_ >> kIdentifierShift));
}
@@ -611,13 +622,14 @@ class PreParserExpression {
return code_ == kPropertyExpression || code_ == kThisPropertyExpression;
}
- bool IsValidLeftHandSide() {
+ bool IsCall() { return code_ == kCallExpression; }
+
+ bool IsValidReferenceExpression() {
return IsIdentifier() || IsProperty();
}
// At the moment PreParser doesn't track these expression types.
bool IsFunctionLiteral() const { return false; }
- bool IsCall() const { return false; }
bool IsCallNew() const { return false; }
PreParserExpression AsFunctionLiteral() { return *this; }
@@ -651,7 +663,8 @@ class PreParserExpression {
// 2 least significant bits for flags.
kThisExpression = 1 << 2,
kThisPropertyExpression = 2 << 2,
- kPropertyExpression = 3 << 2
+ kPropertyExpression = 3 << 2,
+ kCallExpression = 4 << 2
};
explicit PreParserExpression(int expression_code) : code_(expression_code) {}
@@ -782,7 +795,7 @@ class PreParserFactory {
PreParserExpression NewCall(PreParserExpression expression,
PreParserExpressionList arguments,
int pos) {
- return PreParserExpression::Default();
+ return PreParserExpression::Call();
}
PreParserExpression NewCallNew(PreParserExpression expression,
PreParserExpressionList arguments,
@@ -845,6 +858,10 @@ class PreParserTraits {
return expression.IsIdentifier();
}
+ static PreParserIdentifier AsIdentifier(PreParserExpression expression) {
+ return expression.AsIdentifier();
+ }
+
static bool IsBoilerplateProperty(PreParserExpression property) {
// PreParser doesn't count boilerplate properties.
return false;
@@ -883,10 +900,6 @@ class PreParserTraits {
return expression;
}
- // Checks LHS expression for assignment and prefix/postfix increment/decrement
- // in strict mode.
- void CheckStrictModeLValue(PreParserExpression expression, bool* ok);
-
bool ShortcutNumericLiteralBinaryExpression(PreParserExpression* x,
PreParserExpression y,
Token::Value op,
@@ -901,6 +914,18 @@ class PreParserTraits {
return PreParserExpression::Default();
}
+ PreParserExpression NewThrowReferenceError(const char* type, int pos) {
+ return PreParserExpression::Default();
+ }
+ PreParserExpression NewThrowSyntaxError(
+ const char* type, Handle<Object> arg, int pos) {
+ return PreParserExpression::Default();
+ }
+ PreParserExpression NewThrowTypeError(
+ const char* type, Handle<Object> arg1, Handle<Object> arg2, int pos) {
+ return PreParserExpression::Default();
+ }
+
// Reporting errors.
void ReportMessageAt(Scanner::Location location,
const char* message,
@@ -1695,16 +1720,8 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) {
return expression;
}
- if (!expression->IsValidLeftHandSide()) {
- this->ReportMessageAt(lhs_location, "invalid_lhs_in_assignment", true);
- *ok = false;
- return this->EmptyExpression();
- }
-
- if (strict_mode() == STRICT) {
- // Assignment to eval or arguments is disallowed in strict mode.
- this->CheckStrictModeLValue(expression, CHECK_OK);
- }
+ expression = this->CheckAndRewriteReferenceExpression(
+ expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK);
expression = this->MarkExpressionAsLValue(expression);
Token::Value op = Next(); // Get assignment operator.
@@ -1864,17 +1881,9 @@ ParserBase<Traits>::ParseUnaryExpression(bool* ok) {
} else if (Token::IsCountOp(op)) {
op = Next();
Scanner::Location lhs_location = scanner()->peek_location();
- ExpressionT expression = ParseUnaryExpression(CHECK_OK);
- if (!expression->IsValidLeftHandSide()) {
- ReportMessageAt(lhs_location, "invalid_lhs_in_prefix_op", true);
- *ok = false;
- return this->EmptyExpression();
- }
-
- if (strict_mode() == STRICT) {
- // Prefix expression operand in strict mode may not be eval or arguments.
- this->CheckStrictModeLValue(expression, CHECK_OK);
- }
+ ExpressionT expression = this->ParseUnaryExpression(CHECK_OK);
+ expression = this->CheckAndRewriteReferenceExpression(
+ expression, lhs_location, "invalid_lhs_in_prefix_op", CHECK_OK);
this->MarkExpressionAsLValue(expression);
return factory()->NewCountOperation(op,
@@ -1898,16 +1907,8 @@ ParserBase<Traits>::ParsePostfixExpression(bool* ok) {
ExpressionT expression = this->ParseLeftHandSideExpression(CHECK_OK);
if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
Token::IsCountOp(peek())) {
- if (!expression->IsValidLeftHandSide()) {
- ReportMessageAt(lhs_location, "invalid_lhs_in_postfix_op", true);
- *ok = false;
- return this->EmptyExpression();
- }
-
- if (strict_mode() == STRICT) {
- // Postfix expression operand in strict mode may not be eval or arguments.
- this->CheckStrictModeLValue(expression, CHECK_OK);
- }
+ expression = this->CheckAndRewriteReferenceExpression(
+ expression, lhs_location, "invalid_lhs_in_postfix_op", CHECK_OK);
expression = this->MarkExpressionAsLValue(expression);
Token::Value next = Next();
@@ -2117,6 +2118,32 @@ ParserBase<Traits>::ParseMemberExpressionContinuation(ExpressionT expression,
}
+template <typename Traits>
+typename ParserBase<Traits>::ExpressionT
+ParserBase<Traits>::CheckAndRewriteReferenceExpression(
+ ExpressionT expression,
+ Scanner::Location location, const char* message, bool* ok) {
+ if (strict_mode() == STRICT && this->IsIdentifier(expression) &&
+ this->IsEvalOrArguments(this->AsIdentifier(expression))) {
+ this->ReportMessageAt(location, "strict_eval_arguments", false);
+ *ok = false;
+ return this->EmptyExpression();
+ } else if (expression->IsValidReferenceExpression()) {
+ return expression;
+ } else if (expression->IsCall()) {
+ // If it is a call, make it a runtime error for legacy web compatibility.
+ // Rewrite `expr' to `expr[throw ReferenceError]'.
+ int pos = location.beg_pos;
+ ExpressionT error = this->NewThrowReferenceError(message, pos);
+ return factory()->NewProperty(expression, error, pos);
+ } else {
+ this->ReportMessageAt(location, message, true);
+ *ok = false;
+ return this->EmptyExpression();
+ }
+}
+
+
#undef CHECK_OK
#undef CHECK_OK_CUSTOM
« 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