Commit 0851de10 authored by Toon Verwaest's avatar Toon Verwaest Committed by Commit Bot

[parser] Combine UnaryExpression and CountExpression behind single range-check

Change-Id: I8704003f05e74d55e724d669f5bbcef5c2214bf4
Reviewed-on: https://chromium-review.googlesource.com/c/1351018Reviewed-by: 's avatarCamillo Bruni <cbruni@chromium.org>
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57867}
parent 7a3cb59f
...@@ -1035,9 +1035,8 @@ class ParserBase { ...@@ -1035,9 +1035,8 @@ class ParserBase {
ExpressionT ParseConditionalContinuation(ExpressionT expression, int pos); ExpressionT ParseConditionalContinuation(ExpressionT expression, int pos);
ExpressionT ParseBinaryContinuation(ExpressionT x, int prec, int prec1); ExpressionT ParseBinaryContinuation(ExpressionT x, int prec, int prec1);
V8_INLINE ExpressionT ParseBinaryExpression(int prec); V8_INLINE ExpressionT ParseBinaryExpression(int prec);
ExpressionT ParseUnaryOpExpression(); ExpressionT ParseUnaryOrPrefixExpression();
ExpressionT ParseAwaitExpression(); ExpressionT ParseAwaitExpression();
ExpressionT ParsePrefixExpression();
V8_INLINE ExpressionT ParseUnaryExpression(); V8_INLINE ExpressionT ParseUnaryExpression();
V8_INLINE ExpressionT ParsePostfixExpression(); V8_INLINE ExpressionT ParsePostfixExpression();
V8_INLINE ExpressionT ParseLeftHandSideExpression(); V8_INLINE ExpressionT ParseLeftHandSideExpression();
...@@ -2896,7 +2895,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseBinaryExpression( ...@@ -2896,7 +2895,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseBinaryExpression(
template <typename Impl> template <typename Impl>
typename ParserBase<Impl>::ExpressionT typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParseUnaryOpExpression() { ParserBase<Impl>::ParseUnaryOrPrefixExpression() {
Token::Value op = Next(); Token::Value op = Next();
int pos = position(); int pos = position();
...@@ -2909,40 +2908,34 @@ ParserBase<Impl>::ParseUnaryOpExpression() { ...@@ -2909,40 +2908,34 @@ ParserBase<Impl>::ParseUnaryOpExpression() {
ExpressionT expression = ParseUnaryExpression(); ExpressionT expression = ParseUnaryExpression();
if (op == Token::DELETE) { if (Token::IsUnaryOp(op)) {
if (impl()->IsIdentifier(expression) && is_strict(language_mode())) { if (op == Token::DELETE) {
// "delete identifier" is a syntax error in strict mode. if (impl()->IsIdentifier(expression) && is_strict(language_mode())) {
ReportMessage(MessageTemplate::kStrictDelete); // "delete identifier" is a syntax error in strict mode.
return impl()->FailureExpression(); ReportMessage(MessageTemplate::kStrictDelete);
return impl()->FailureExpression();
}
if (impl()->IsPropertyWithPrivateFieldKey(expression)) {
ReportMessage(MessageTemplate::kDeletePrivateField);
return impl()->FailureExpression();
}
} }
if (impl()->IsPropertyWithPrivateFieldKey(expression)) { if (peek() == Token::EXP) {
ReportMessage(MessageTemplate::kDeletePrivateField); ReportUnexpectedToken(Next());
return impl()->FailureExpression(); return impl()->FailureExpression();
} }
}
if (peek() == Token::EXP) { // Allow the parser's implementation to rewrite the expression.
ReportUnexpectedToken(Next()); return impl()->BuildUnaryExpression(expression, op, pos);
return impl()->FailureExpression();
} }
// Allow the parser's implementation to rewrite the expression. DCHECK(Token::IsCountOp(op));
return impl()->BuildUnaryExpression(expression, op, pos);
}
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParsePrefixExpression() {
Token::Value op = Next();
int beg_pos = peek_position();
CheckStackOverflow();
ExpressionT expression = ParseUnaryExpression();
if (V8_UNLIKELY(!IsValidReferenceExpression(expression))) { if (V8_UNLIKELY(!IsValidReferenceExpression(expression))) {
expression = RewriteInvalidReferenceExpression( expression = RewriteInvalidReferenceExpression(
expression, beg_pos, end_position(), expression, expression->position(), end_position(),
MessageTemplate::kInvalidLhsInPrefixOp); MessageTemplate::kInvalidLhsInPrefixOp);
} }
impl()->MarkExpressionAsAssigned(expression); impl()->MarkExpressionAsAssigned(expression);
...@@ -2987,8 +2980,7 @@ ParserBase<Impl>::ParseUnaryExpression() { ...@@ -2987,8 +2980,7 @@ ParserBase<Impl>::ParseUnaryExpression() {
// [+Await] AwaitExpression[?Yield] // [+Await] AwaitExpression[?Yield]
Token::Value op = peek(); Token::Value op = peek();
if (Token::IsUnaryOp(op)) return ParseUnaryOpExpression(); if (Token::IsUnaryOrCountOp(op)) return ParseUnaryOrPrefixExpression();
if (Token::IsCountOp(op)) return ParsePrefixExpression();
if (is_async_function() && op == Token::AWAIT) { if (is_async_function() && op == Token::AWAIT) {
return ParseAwaitExpression(); return ParseAwaitExpression();
} }
......
...@@ -27,7 +27,8 @@ namespace internal { ...@@ -27,7 +27,8 @@ namespace internal {
#define IGNORE_TOKEN(name, string, precedence) #define IGNORE_TOKEN(name, string, precedence)
/* Binary operators sorted by precedence */ /* Binary operators */
/* ADD and SUB are at the end since they are UnaryOp */
#define BINARY_OP_TOKEN_LIST(T, E) \ #define BINARY_OP_TOKEN_LIST(T, E) \
E(T, BIT_OR, "|", 6) \ E(T, BIT_OR, "|", 6) \
E(T, BIT_XOR, "^", 7) \ E(T, BIT_XOR, "^", 7) \
...@@ -35,12 +36,12 @@ namespace internal { ...@@ -35,12 +36,12 @@ namespace internal {
E(T, SHL, "<<", 11) \ E(T, SHL, "<<", 11) \
E(T, SAR, ">>", 11) \ E(T, SAR, ">>", 11) \
E(T, SHR, ">>>", 11) \ E(T, SHR, ">>>", 11) \
E(T, ADD, "+", 12) \
E(T, SUB, "-", 12) \
E(T, MUL, "*", 13) \ E(T, MUL, "*", 13) \
E(T, DIV, "/", 13) \ E(T, DIV, "/", 13) \
E(T, MOD, "%", 13) \ E(T, MOD, "%", 13) \
E(T, EXP, "**", 14) E(T, EXP, "**", 14) \
E(T, ADD, "+", 12) \
E(T, SUB, "-", 12)
#define EXPAND_BINOP_ASSIGN_TOKEN(T, name, string, precedence) \ #define EXPAND_BINOP_ASSIGN_TOKEN(T, name, string, precedence) \
T(ASSIGN_##name, string "=", 2) T(ASSIGN_##name, string "=", 2)
...@@ -68,8 +69,6 @@ namespace internal { ...@@ -68,8 +69,6 @@ namespace internal {
T(COLON, ":", 0) \ T(COLON, ":", 0) \
T(ELLIPSIS, "...", 0) \ T(ELLIPSIS, "...", 0) \
T(CONDITIONAL, "?", 3) \ T(CONDITIONAL, "?", 3) \
T(INC, "++", 0) \
T(DEC, "--", 0) \
/* BEGIN AutoSemicolon */ \ /* BEGIN AutoSemicolon */ \
T(SEMICOLON, ";", 0) \ T(SEMICOLON, ";", 0) \
T(RBRACE, "}", 0) \ T(RBRACE, "}", 0) \
...@@ -94,8 +93,24 @@ namespace internal { ...@@ -94,8 +93,24 @@ namespace internal {
T(COMMA, ",", 1) \ T(COMMA, ",", 1) \
T(OR, "||", 4) \ T(OR, "||", 4) \
T(AND, "&&", 5) \ T(AND, "&&", 5) \
\
/* Unary operators, starting at ADD in BINARY_OP_TOKEN_LIST */ \
/* IsUnaryOp() relies on this block of enum values */ \
/* being contiguous and sorted in the same order! */ \
BINARY_OP_TOKEN_LIST(T, EXPAND_BINOP_TOKEN) \ BINARY_OP_TOKEN_LIST(T, EXPAND_BINOP_TOKEN) \
\ \
T(NOT, "!", 0) \
T(BIT_NOT, "~", 0) \
K(DELETE, "delete", 0) \
K(TYPEOF, "typeof", 0) \
K(VOID, "void", 0) \
\
/* BEGIN IsCountOp */ \
T(INC, "++", 0) \
T(DEC, "--", 0) \
/* END IsCountOp */ \
/* END IsUnaryOrCountOp */ \
\
/* Compare operators sorted by precedence. */ \ /* Compare operators sorted by precedence. */ \
/* IsCompareOp() relies on this block of enum values */ \ /* IsCompareOp() relies on this block of enum values */ \
/* being contiguous and sorted in the same order! */ \ /* being contiguous and sorted in the same order! */ \
...@@ -110,15 +125,6 @@ namespace internal { ...@@ -110,15 +125,6 @@ namespace internal {
K(INSTANCEOF, "instanceof", 10) \ K(INSTANCEOF, "instanceof", 10) \
K(IN, "in", 10) \ K(IN, "in", 10) \
\ \
/* Unary operators. */ \
/* IsUnaryOp() relies on this block of enum values */ \
/* being contiguous and sorted in the same order! */ \
T(NOT, "!", 0) \
T(BIT_NOT, "~", 0) \
K(DELETE, "delete", 0) \
K(TYPEOF, "typeof", 0) \
K(VOID, "void", 0) \
\
/* Keywords (ECMA-262, section 7.5.2, page 13). */ \ /* Keywords (ECMA-262, section 7.5.2, page 13). */ \
K(BREAK, "break", 0) \ K(BREAK, "break", 0) \
K(CASE, "case", 0) \ K(CASE, "case", 0) \
...@@ -246,14 +252,14 @@ class Token { ...@@ -246,14 +252,14 @@ class Token {
} }
static bool IsArrowOrAssignmentOp(Value token) { static bool IsArrowOrAssignmentOp(Value token) {
return IsInRange(token, ARROW, ASSIGN_EXP); return IsInRange(token, ARROW, ASSIGN_SUB);
} }
static bool IsAssignmentOp(Value token) { static bool IsAssignmentOp(Value token) {
return IsInRange(token, INIT, ASSIGN_EXP); return IsInRange(token, INIT, ASSIGN_SUB);
} }
static bool IsBinaryOp(Value op) { return IsInRange(op, COMMA, EXP); } static bool IsBinaryOp(Value op) { return IsInRange(op, COMMA, SUB); }
static bool IsCompareOp(Value op) { return IsInRange(op, EQ, IN); } static bool IsCompareOp(Value op) { return IsInRange(op, EQ, IN); }
...@@ -264,7 +270,7 @@ class Token { ...@@ -264,7 +270,7 @@ class Token {
static bool IsEqualityOp(Value op) { return IsInRange(op, EQ, EQ_STRICT); } static bool IsEqualityOp(Value op) { return IsInRange(op, EQ, EQ_STRICT); }
static Value BinaryOpForAssignment(Value op) { static Value BinaryOpForAssignment(Value op) {
DCHECK(IsInRange(op, ASSIGN_BIT_OR, ASSIGN_EXP)); DCHECK(IsInRange(op, ASSIGN_BIT_OR, ASSIGN_SUB));
Value result = static_cast<Value>(op - ASSIGN_BIT_OR + BIT_OR); Value result = static_cast<Value>(op - ASSIGN_BIT_OR + BIT_OR);
DCHECK(IsBinaryOp(result)); DCHECK(IsBinaryOp(result));
return result; return result;
...@@ -274,12 +280,9 @@ class Token { ...@@ -274,12 +280,9 @@ class Token {
return IsInRange(op, BIT_OR, SHR) || op == BIT_NOT; return IsInRange(op, BIT_OR, SHR) || op == BIT_NOT;
} }
static bool IsUnaryOp(Value op) { static bool IsUnaryOp(Value op) { return IsInRange(op, ADD, VOID); }
return IsInRange(op, NOT, VOID) || IsInRange(op, ADD, SUB);
}
static bool IsCountOp(Value op) { return IsInRange(op, INC, DEC); } static bool IsCountOp(Value op) { return IsInRange(op, INC, DEC); }
static bool IsUnaryOrCountOp(Value op) { return IsInRange(op, ADD, DEC); }
static bool IsShiftOp(Value op) { return IsInRange(op, SHL, SHR); } static bool IsShiftOp(Value op) { return IsInRange(op, SHL, SHR); }
// Returns a string corresponding to the JS token string // Returns a string corresponding to the JS token string
......
...@@ -434,6 +434,14 @@ TEST(IsCountOp) { ...@@ -434,6 +434,14 @@ TEST(IsCountOp) {
} }
} }
TEST(IsUnaryOrCountOp) {
for (int i = 0; i < Token::NUM_TOKENS; i++) {
Token::Value token = static_cast<Token::Value>(i);
CHECK_EQ(TokenIsUnaryOp(token) || TokenIsCountOp(token),
Token::IsUnaryOrCountOp(token));
}
}
bool TokenIsShiftOp(Token::Value token) { bool TokenIsShiftOp(Token::Value token) {
switch (token) { switch (token) {
case Token::SHL: case Token::SHL:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment