Commit 236b8e9c authored by Toon Verwaest's avatar Toon Verwaest Committed by Commit Bot

[parser] Refactor ParseMemberExpression

- Use token-range checks
- Delay ValidateExpression until after the loop
- Only queue classifier errors at the beginning
- Only inline Token-range check rather than the entire
  ParseMemberExpressionContinuation to reduce binary size.

Change-Id: Ib81ce071851fe5c13b4bb405cd883df7a82c84c9
Reviewed-on: https://chromium-review.googlesource.com/c/1286677
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
Reviewed-by: 's avatarCamillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56783}
parent b95614a5
......@@ -1106,7 +1106,12 @@ class ParserBase {
ExpressionT ParseFunctionExpression(bool* ok);
V8_INLINE ExpressionT ParseMemberExpression(bool* ok);
V8_INLINE ExpressionT
ParseMemberExpressionContinuation(ExpressionT expression, bool* ok);
ParseMemberExpressionContinuation(ExpressionT expression, bool* ok) {
if (!Token::IsProperty(peek())) return expression;
return DoParseMemberExpressionContinuation(expression, ok);
}
ExpressionT DoParseMemberExpressionContinuation(ExpressionT expression,
bool* ok);
// `rewritable_length`: length of the destructuring_assignments_to_rewrite()
// queue in the parent function state, prior to parsing of formal parameters.
......@@ -3213,10 +3218,10 @@ ParserBase<Impl>::ParseLeftHandSideExpression(bool* ok) {
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParseLeftHandSideContinuation(ExpressionT result, bool* ok) {
DCHECK(Token::IsPropertyOrCall(peek()));
BindingPatternUnexpectedToken();
do {
ValidateExpression(CHECK_OK);
switch (peek()) {
case Token::LBRACK: {
ArrowFormalParametersUnexpectedToken();
......@@ -3311,17 +3316,15 @@ ParserBase<Impl>::ParseLeftHandSideContinuation(ExpressionT result, bool* ok) {
break;
}
case Token::TEMPLATE_SPAN:
case Token::TEMPLATE_TAIL: {
default:
DCHECK(peek() == Token::TEMPLATE_SPAN ||
peek() == Token::TEMPLATE_TAIL);
ArrowFormalParametersUnexpectedToken();
result = ParseTemplateLiteral(result, position(), true, CHECK_OK);
break;
}
default:
UNREACHABLE();
}
} while (Token::IsPropertyOrCall(peek()));
ValidateExpression(CHECK_OK);
return result;
}
......@@ -3563,42 +3566,34 @@ ParserBase<Impl>::ParseNewTargetExpression(bool* ok) {
template <typename Impl>
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParseMemberExpressionContinuation(ExpressionT expression,
ParserBase<Impl>::DoParseMemberExpressionContinuation(ExpressionT expression,
bool* ok) {
DCHECK(Token::IsProperty(peek()));
BindingPatternUnexpectedToken();
ArrowFormalParametersUnexpectedToken();
// Parses this part of MemberExpression:
// ('[' Expression ']' | '.' Identifier | TemplateLiteral)*
while (true) {
do {
switch (peek()) {
case Token::LBRACK: {
ValidateExpression(CHECK_OK);
BindingPatternUnexpectedToken();
ArrowFormalParametersUnexpectedToken();
Consume(Token::LBRACK);
int pos = position();
ExpressionT index = ParseExpressionCoverGrammar(true, CHECK_OK);
ValidateExpression(CHECK_OK);
expression = factory()->NewProperty(expression, index, pos);
impl()->PushPropertyName(index);
Expect(Token::RBRACK, CHECK_OK);
break;
}
case Token::PERIOD: {
ValidateExpression(CHECK_OK);
BindingPatternUnexpectedToken();
ArrowFormalParametersUnexpectedToken();
Consume(Token::PERIOD);
int pos = peek_position();
ExpressionT key = ParseIdentifierNameOrPrivateName(CHECK_OK);
expression = factory()->NewProperty(expression, key, pos);
break;
}
case Token::TEMPLATE_SPAN:
case Token::TEMPLATE_TAIL: {
ValidateExpression(CHECK_OK);
BindingPatternUnexpectedToken();
ArrowFormalParametersUnexpectedToken();
default: {
DCHECK(peek() == Token::TEMPLATE_SPAN ||
peek() == Token::TEMPLATE_TAIL);
int pos;
if (scanner()->current_token() == Token::IDENTIFIER) {
pos = position();
......@@ -3613,17 +3608,10 @@ ParserBase<Impl>::ParseMemberExpressionContinuation(ExpressionT expression,
expression = ParseTemplateLiteral(expression, pos, true, CHECK_OK);
break;
}
case Token::ILLEGAL: {
ReportUnexpectedTokenAt(scanner()->peek_location(), Token::ILLEGAL);
*ok = false;
return impl()->NullExpression();
}
default:
} while (Token::IsProperty(peek()));
ValidateExpression(CHECK_OK);
return expression;
}
}
DCHECK(false);
return impl()->NullExpression();
}
template <typename Impl>
......
......@@ -56,6 +56,7 @@ namespace internal {
#define TOKEN_LIST(T, K, C) \
\
/* BEGIN Property */ \
/* BEGIN PropertyOrCall */ \
/* ES6 Template Literals */ \
T(TEMPLATE_SPAN, nullptr, 0) \
......@@ -63,8 +64,9 @@ namespace internal {
\
/* Punctuators (ECMA-262, section 7.7, page 15). */ \
T(PERIOD, ".", 0) \
T(LPAREN, "(", 0) \
T(LBRACK, "[", 0) \
/* END Property */ \
T(LPAREN, "(", 0) \
/* END PropertyOrCall */ \
T(RPAREN, ")", 0) \
T(RBRACK, "]", 0) \
......@@ -259,10 +261,14 @@ class Token {
return IsInRange(token, NULL_LITERAL, STRING);
}
static bool IsPropertyOrCall(Value token) {
static bool IsProperty(Value token) {
return IsInRange(token, TEMPLATE_SPAN, LBRACK);
}
static bool IsPropertyOrCall(Value token) {
return IsInRange(token, TEMPLATE_SPAN, LPAREN);
}
static bool IsAssignmentOp(Value token) {
return IsInRange(token, INIT, ASSIGN_EXP);
}
......
......@@ -379,8 +379,8 @@ bool TokenIsPropertyOrCall(Token::Value token) {
case Token::TEMPLATE_SPAN:
case Token::TEMPLATE_TAIL:
case Token::PERIOD:
case Token::LPAREN:
case Token::LBRACK:
case Token::LPAREN:
return true;
default:
return false;
......@@ -394,6 +394,25 @@ TEST(IsPropertyOrCall) {
}
}
bool TokenIsProperty(Token::Value token) {
switch (token) {
case Token::TEMPLATE_SPAN:
case Token::TEMPLATE_TAIL:
case Token::PERIOD:
case Token::LBRACK:
return true;
default:
return false;
}
}
TEST(IsProperty) {
for (int i = 0; i < Token::NUM_TOKENS; i++) {
Token::Value token = static_cast<Token::Value>(i);
CHECK_EQ(TokenIsProperty(token), Token::IsProperty(token));
}
}
bool TokenIsCountOp(Token::Value token) {
switch (token) {
case Token::INC:
......
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