Reviewers: adamk, rossberg,
Message:
Hi, PTAL, I wanted to take on a smaller bug since it's been a few weeks.
Going to add a 2nd patch shortly to address the self-review I've done
https://codereview.chromium.org/1292393002/diff/1/src/preparser.h
File src/preparser.h (right):
https://codereview.chromium.org/1292393002/diff/1/src/preparser.h#newcode3982
src/preparser.h:3982: : this->NewThrowSyntaxError(message, pos);
I'm not sure if this distinction is necessary or good here --- getting
rid of this does make the patch a lot smaller.
SpiderMonkey does not make the distinction, at any rate.
Description:
[parser] make kInvalidLhsInFor a SyntaxError
Second item in section 13.7.5.1 states that the error should be a
SyntaxError, when previously CheckAndRewriteReferenceExpression
would always emit a ReferenceError.
BUG=v8:4373
R=adamk, rossberg
LOG=N
Please review this at https://codereview.chromium.org/1292393002/
Base URL: https://chromium.googlesource.com/v8/v8.git@master
Affected files (+40, -13 lines):
M src/parser.h
M src/parser.cc
M src/preparser.h
M src/preparser.cc
M test/message/for-loop-invalid-lhs.out
M test/message/new-target-for-loop.out
M test/mjsunit/harmony/new-target.js
M test/mjsunit/invalid-lhs.js
Index: src/parser.cc
diff --git a/src/parser.cc b/src/parser.cc
index
301bda94c4011987aff1a704a5f2e6f84d79c137..b7ccff4dd03d0d316e7aa106ba54b2dcbf2eb7a5
100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -658,6 +658,13 @@ Expression*
ParserTraits::NewThrowSyntaxError(MessageTemplate::Template message,
}
+Expression* ParserTraits::NewThrowSyntaxError(MessageTemplate::Template
message,
+ int pos) {
+ return NewThrowError(Runtime::kNewSyntaxError, message,
+ parser_->ast_value_factory()->empty_string(), pos);
+}
+
+
Expression* ParserTraits::NewThrowTypeError(MessageTemplate::Template
message,
const AstRawString* arg, int
pos) {
return NewThrowError(Runtime::kNewTypeError, message, arg, pos);
@@ -3693,7 +3700,7 @@ Statement* Parser::ParseForStatement(ZoneList<const
AstRawString*>* labels,
if (!*ok) return nullptr;
expression = this->CheckAndRewriteReferenceExpression(
expression, lhs_beg_pos, lhs_end_pos,
- MessageTemplate::kInvalidLhsInFor, CHECK_OK);
+ MessageTemplate::kInvalidLhsInFor, kSyntaxError, CHECK_OK);
ForEachStatement* loop =
factory()->NewForEachStatement(mode, labels, stmt_pos);
Index: src/parser.h
diff --git a/src/parser.h b/src/parser.h
index
4a77d91b0ac859aeb6b938c40c36e4b00d5d37f1..81ddf73482ff77da4ff8d5229db548489660aea8
100644
--- a/src/parser.h
+++ b/src/parser.h
@@ -688,6 +688,7 @@ class ParserTraits {
// which case no arguments are passed to the constructor.
Expression* NewThrowSyntaxError(MessageTemplate::Template message,
const AstRawString* arg, int pos);
+ Expression* NewThrowSyntaxError(MessageTemplate::Template message, int
pos);
// Generate AST node that throws a TypeError with the given
// type. Both arguments must be non-null (in the handle sense).
Index: src/preparser.cc
diff --git a/src/preparser.cc b/src/preparser.cc
index
9a30ca58cc71b18031b17ff9cd152e95826a50f1..b1541f616afe133554881e99aec4f71a9f5e45e0
100644
--- a/src/preparser.cc
+++ b/src/preparser.cc
@@ -922,7 +922,7 @@ PreParser::Statement PreParser::ParseForStatement(bool*
ok) {
if (!*ok) return Statement::Default();
lhs = CheckAndRewriteReferenceExpression(
lhs, lhs_beg_pos, lhs_end_pos,
MessageTemplate::kInvalidLhsInFor,
- CHECK_OK);
+ kSyntaxError, CHECK_OK);
ParseExpression(true, CHECK_OK);
Expect(Token::RPAREN, CHECK_OK);
ParseSubStatement(CHECK_OK);
Index: src/preparser.h
diff --git a/src/preparser.h b/src/preparser.h
index
249eed983c4f4c08485073b60f67651f5a3cb407..1051f97b8af2554510dc0ffd6fe589958511a1b3
100644
--- a/src/preparser.h
+++ b/src/preparser.h
@@ -714,6 +714,9 @@ class ParserBase : public Traits {
ExpressionT CheckAndRewriteReferenceExpression(
ExpressionT expression, int beg_pos, int end_pos,
MessageTemplate::Template message, bool* ok);
+ ExpressionT CheckAndRewriteReferenceExpression(
+ ExpressionT expression, int beg_pos, int end_pos,
+ MessageTemplate::Template message, ParseErrorType type, bool* ok);
// Used to validate property names in object literals and class literals
enum PropertyKind {
@@ -1473,6 +1476,10 @@ class PreParserTraits {
Handle<Object> arg, int pos) {
return PreParserExpression::Default();
}
+ PreParserExpression NewThrowSyntaxError(MessageTemplate::Template
message,
+ int pos) {
+ return PreParserExpression::Default();
+ }
PreParserExpression NewThrowTypeError(MessageTemplate::Template message,
Handle<Object> arg, int pos) {
return PreParserExpression::Default();
@@ -3937,6 +3944,16 @@ typename ParserBase<Traits>::ExpressionT
ParserBase<Traits>::CheckAndRewriteReferenceExpression(
ExpressionT expression, int beg_pos, int end_pos,
MessageTemplate::Template message, bool* ok) {
+ return this->CheckAndRewriteReferenceExpression(expression, beg_pos,
end_pos,
+ message,
kReferenceError, ok);
+}
+
+
+template <typename Traits>
+typename ParserBase<Traits>::ExpressionT
+ParserBase<Traits>::CheckAndRewriteReferenceExpression(
+ ExpressionT expression, int beg_pos, int end_pos,
+ MessageTemplate::Template message, ParseErrorType type, bool* ok) {
Scanner::Location location(beg_pos, end_pos);
if (this->IsIdentifier(expression)) {
if (is_strict(language_mode()) &&
@@ -3960,10 +3977,12 @@
ParserBase<Traits>::CheckAndRewriteReferenceExpression(
// 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);
+ ExpressionT error = type == kReferenceError
+ ? this->NewThrowReferenceError(message, pos)
+ : this->NewThrowSyntaxError(message, pos);
return factory()->NewProperty(expression, error, pos);
} else {
- this->ReportMessageAt(location, message, kReferenceError);
+ this->ReportMessageAt(location, message, type);
*ok = false;
return this->EmptyExpression();
}
Index: test/message/for-loop-invalid-lhs.out
diff --git a/test/message/for-loop-invalid-lhs.out
b/test/message/for-loop-invalid-lhs.out
index
105eb6461cb11e54f4e8f5c8176eea4b70a520ef..441ba3b60c680a729d986ae92312326b874852be
100644
--- a/test/message/for-loop-invalid-lhs.out
+++ b/test/message/for-loop-invalid-lhs.out
@@ -1,5 +1,5 @@
-*%(basename)s:9: ReferenceError: Invalid left-hand side in for-loop
+*%(basename)s:9: SyntaxError: Invalid left-hand side in for-loop
function f() { for ("unassignable" in {}); }
^^^^^^^^^^^^^^
-ReferenceError: Invalid left-hand side in for-loop
+SyntaxError: Invalid left-hand side in for-loop
Index: test/message/new-target-for-loop.out
diff --git a/test/message/new-target-for-loop.out
b/test/message/new-target-for-loop.out
index
30f1f75d7e33b048904cf242b32f14e510a1ed1a..342b1315e999897bccbf857c872f1eba531cc6e6
100644
--- a/test/message/new-target-for-loop.out
+++ b/test/message/new-target-for-loop.out
@@ -1,4 +1,4 @@
-*%(basename)s:7: ReferenceError: Invalid left-hand side in for-loop
+*%(basename)s:7: SyntaxError: Invalid left-hand side in for-loop
function f() { for (new.target in {}); }
^^^^^^^^^^
-ReferenceError: Invalid left-hand side in for-loop
+SyntaxError: Invalid left-hand side in for-loop
Index: test/mjsunit/harmony/new-target.js
diff --git a/test/mjsunit/harmony/new-target.js
b/test/mjsunit/harmony/new-target.js
index
a1f020b00546bfa54c740fb17da35261aec8231d..d98f5f809860d2e9854aeb18326593ec6af1fce9
100644
--- a/test/mjsunit/harmony/new-target.js
+++ b/test/mjsunit/harmony/new-target.js
@@ -394,5 +394,5 @@
assertThrows(function() { Function("--new.target"); }, ReferenceError);
assertThrows(function() { Function("(new.target)++"); }, ReferenceError);
assertThrows(function() { Function("++(new.target)"); }, ReferenceError);
- assertThrows(function() { Function("for (new.target of {});"); },
ReferenceError);
+ assertThrows(function() { Function("for (new.target of {});"); },
SyntaxError);
})();
Index: test/mjsunit/invalid-lhs.js
diff --git a/test/mjsunit/invalid-lhs.js b/test/mjsunit/invalid-lhs.js
index
52ee89582a4d059bbf3b92cb05a627ed36a39aa0..61636f5e7eb7d72f636a6f4dd1d95b56ec29e410
100644
--- a/test/mjsunit/invalid-lhs.js
+++ b/test/mjsunit/invalid-lhs.js
@@ -50,9 +50,9 @@ assertDoesNotThrow("if (false) ++(eval('12'))",
ReferenceError);
assertDoesNotThrow("if (false) (eval('12'))++", ReferenceError);
// For in:
-assertThrows("for (12 in [1]) print(12);", ReferenceError);
-assertThrows("for (eval('var x') in [1]) print(12);", ReferenceError);
-assertThrows("if (false) for (12 in [1]) print(12);", ReferenceError);
+assertThrows("for (12 in [1]) print(12);", SyntaxError);
+assertThrows("for (eval('var x') in [1]) print(12);", SyntaxError);
+assertThrows("if (false) for (12 in [1]) print(12);", SyntaxError);
assertDoesNotThrow("if (false) for (eval('0') in [1]) print(12);",
ReferenceError);
// For:
@@ -64,7 +64,7 @@ assertDoesNotThrow("if (false) for (eval('var x') = 1;;)
print(12);", ReferenceE
// Assignments to 'this'.
assertThrows("this = 42", ReferenceError);
assertThrows("function f() { this = 12; }", ReferenceError);
-assertThrows("for (this in {x:3, y:4, z:5}) ;", ReferenceError);
+assertThrows("for (this in {x:3, y:4, z:5}) ;", SyntaxError);
assertThrows("for (this = 0;;) ;", ReferenceError);
assertThrows("this++", ReferenceError);
assertThrows("++this", ReferenceError);
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.