[parser] Drop is_get and is_set parameters in ParsePropertyName

The two bool parameters are used for DCHECks in most places. By
introducing more specialized enumes kAccessorGetterProperty and
kAccessorSetterProperty we can simplify the checks.

Bug: v8:7926
Change-Id: I61023f2da0d96ca5a4fba65c6ead309567144786
Reviewed-on: https://chromium-review.googlesource.com/1202822
Commit-Queue: Camillo Bruni <cbruni@chromium.org>
Reviewed-by: Georg Neis <neis@chromium.org>
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55648}
This commit is contained in:
Camillo Bruni 2018-09-05 13:14:21 +02:00 committed by Commit Bot
parent 25d06d8b01
commit ea518290d3
4 changed files with 56 additions and 52 deletions

View File

@ -1102,7 +1102,8 @@ class ParserBase {
ExpressionT ParseArrayLiteral(bool* ok);
enum class PropertyKind {
kAccessorProperty,
kAccessorGetterProperty,
kAccessorSetterProperty,
kValueProperty,
kShorthandProperty,
kMethodProperty,
@ -1111,11 +1112,15 @@ class ParserBase {
kNotSet
};
inline static bool IsAccessor(PropertyKind kind) {
return IsInRange(kind, PropertyKind::kAccessorGetterProperty,
PropertyKind::kAccessorSetterProperty);
}
bool SetPropertyKindFromToken(Token::Value token, PropertyKind* kind);
ExpressionT ParsePropertyName(IdentifierT* name, PropertyKind* kind,
bool* is_generator, bool* is_get, bool* is_set,
bool* is_async, bool* is_computed_name,
bool* ok);
bool* is_generator, bool* is_async,
bool* is_computed_name, bool* ok);
ExpressionT ParseObjectLiteral(bool* ok);
ClassLiteralPropertyT ParseClassPropertyDefinition(
ClassLiteralChecker* checker, ClassInfo* class_info,
@ -2158,12 +2163,10 @@ bool ParserBase<Impl>::SetPropertyKindFromToken(Token::Value token,
template <class Impl>
typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePropertyName(
IdentifierT* name, PropertyKind* kind, bool* is_generator, bool* is_get,
bool* is_set, bool* is_async, bool* is_computed_name, bool* ok) {
IdentifierT* name, PropertyKind* kind, bool* is_generator, bool* is_async,
bool* is_computed_name, bool* ok) {
DCHECK_EQ(*kind, PropertyKind::kNotSet);
DCHECK(!*is_generator);
DCHECK(!*is_get);
DCHECK(!*is_set);
DCHECK(!*is_async);
DCHECK(!*is_computed_name);
@ -2197,14 +2200,20 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePropertyName(
// This is checking for 'get' and 'set' in particular.
Consume(Token::IDENTIFIER);
token = peek();
if (SetPropertyKindFromToken(token, kind) ||
!scanner()->IsGetOrSet(is_get, is_set)) {
bool previous_token_was_name = SetPropertyKindFromToken(token, kind);
Token::Value contextual_token = scanner()->current_contextual_token();
if (!previous_token_was_name && Token::IsGetOrSet(contextual_token)) {
if (contextual_token == Token::GET) {
*kind = PropertyKind::kAccessorGetterProperty;
} else {
*kind = PropertyKind::kAccessorSetterProperty;
}
pos = peek_position();
} else {
*name = impl()->GetSymbol();
impl()->PushLiteralName(*name);
return factory()->NewStringLiteral(*name, pos);
}
*kind = PropertyKind::kAccessorProperty;
pos = peek_position();
}
// For non computed property names we normalize the name a bit:
@ -2246,7 +2255,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePropertyName(
}
case Token::ELLIPSIS:
if (!*is_generator && !*is_async && !*is_get && !*is_set) {
if (!*is_generator && !*is_async && !IsAccessor(*kind)) {
*name = impl()->NullIdentifier();
Consume(Token::ELLIPSIS);
expression = ParseAssignmentExpression(true, CHECK_OK);
@ -2300,8 +2309,6 @@ ParserBase<Impl>::ParseClassPropertyDefinition(
bool has_extends, bool* is_computed_name,
ClassLiteralProperty::Kind* property_kind, bool* is_static, bool* ok) {
DCHECK_NOT_NULL(class_info);
bool is_get = false;
bool is_set = false;
bool is_generator = false;
bool is_async = false;
*is_static = false;
@ -2334,8 +2341,8 @@ ParserBase<Impl>::ParseClassPropertyDefinition(
return impl()->NullLiteralProperty();
} else {
*is_static = true;
name_expression = ParsePropertyName(name, &kind, &is_generator, &is_get,
&is_set, &is_async, is_computed_name,
name_expression = ParsePropertyName(name, &kind, &is_generator, &is_async,
is_computed_name,
CHECK_OK_CUSTOM(NullLiteralProperty));
}
} else if (name_token == Token::PRIVATE_NAME) {
@ -2343,8 +2350,8 @@ ParserBase<Impl>::ParseClassPropertyDefinition(
*name = impl()->GetSymbol();
name_expression = factory()->NewStringLiteral(*name, position());
} else {
name_expression = ParsePropertyName(name, &kind, &is_generator, &is_get,
&is_set, &is_async, is_computed_name,
name_expression = ParsePropertyName(name, &kind, &is_generator, &is_async,
is_computed_name,
CHECK_OK_CUSTOM(NullLiteralProperty));
}
@ -2393,8 +2400,6 @@ ParserBase<Impl>::ParseClassPropertyDefinition(
}
case PropertyKind::kMethodProperty: {
DCHECK(!is_get && !is_set);
// MethodDefinition
// PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
// '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
@ -2432,13 +2437,15 @@ ParserBase<Impl>::ParseClassPropertyDefinition(
return result;
}
case PropertyKind::kAccessorProperty: {
DCHECK((is_get || is_set) && !is_generator && !is_async);
case PropertyKind::kAccessorGetterProperty:
case PropertyKind::kAccessorSetterProperty: {
DCHECK(!is_generator && !is_async);
bool is_get = kind == PropertyKind::kAccessorGetterProperty;
if (!*is_computed_name) {
checker->CheckClassMethodName(
name_token, PropertyKind::kAccessorProperty, false, false,
*is_static, CHECK_OK_CUSTOM(NullLiteralProperty));
checker->CheckClassMethodName(name_token, kind, false, false,
*is_static,
CHECK_OK_CUSTOM(NullLiteralProperty));
// Make sure the name expression is a string since we need a Name for
// Runtime_DefineAccessorPropertyUnchecked and since we can determine
// this statically we can skip the extra runtime check.
@ -2524,8 +2531,6 @@ ParserBase<Impl>::ParseObjectPropertyDefinition(ObjectLiteralChecker* checker,
bool* is_computed_name,
bool* is_rest_property,
bool* ok) {
bool is_get = false;
bool is_set = false;
bool is_generator = false;
bool is_async = false;
PropertyKind kind = PropertyKind::kNotSet;
@ -2535,14 +2540,13 @@ ParserBase<Impl>::ParseObjectPropertyDefinition(ObjectLiteralChecker* checker,
int next_beg_pos = scanner()->peek_location().beg_pos;
int next_end_pos = scanner()->peek_location().end_pos;
ExpressionT name_expression = ParsePropertyName(
&name, &kind, &is_generator, &is_get, &is_set, &is_async,
ExpressionT name_expression =
ParsePropertyName(&name, &kind, &is_generator, &is_async,
is_computed_name, CHECK_OK_CUSTOM(NullLiteralProperty));
switch (kind) {
case PropertyKind::kSpreadProperty:
DCHECK(!is_get && !is_set && !is_generator && !is_async &&
!*is_computed_name);
DCHECK(!is_generator && !is_async && !*is_computed_name);
DCHECK_EQ(Token::ELLIPSIS, name_token);
*is_computed_name = true;
@ -2553,7 +2557,7 @@ ParserBase<Impl>::ParseObjectPropertyDefinition(ObjectLiteralChecker* checker,
ObjectLiteralProperty::SPREAD, true);
case PropertyKind::kValueProperty: {
DCHECK(!is_get && !is_set && !is_generator && !is_async);
DCHECK(!is_generator && !is_async);
if (!*is_computed_name) {
checker->CheckDuplicateProto(name_token);
@ -2577,7 +2581,7 @@ ParserBase<Impl>::ParseObjectPropertyDefinition(ObjectLiteralChecker* checker,
//
// CoverInitializedName
// IdentifierReference Initializer?
DCHECK(!is_get && !is_set && !is_generator && !is_async);
DCHECK(!is_generator && !is_async);
if (!Token::IsIdentifier(name_token, language_mode(),
this->is_generator(),
@ -2640,8 +2644,6 @@ ParserBase<Impl>::ParseObjectPropertyDefinition(ObjectLiteralChecker* checker,
}
case PropertyKind::kMethodProperty: {
DCHECK(!is_get && !is_set);
// MethodDefinition
// PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
// '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
@ -2665,9 +2667,10 @@ ParserBase<Impl>::ParseObjectPropertyDefinition(ObjectLiteralChecker* checker,
return result;
}
case PropertyKind::kAccessorProperty: {
DCHECK((is_get || is_set) && !(is_set && is_get) && !is_generator &&
!is_async);
case PropertyKind::kAccessorGetterProperty:
case PropertyKind::kAccessorSetterProperty: {
DCHECK(!is_generator && !is_async);
bool is_get = kind == PropertyKind::kAccessorGetterProperty;
classifier()->RecordPatternError(
Scanner::Location(next_beg_pos, scanner()->location().end_pos),
@ -6189,8 +6192,7 @@ template <typename Impl>
void ParserBase<Impl>::ClassLiteralChecker::CheckClassMethodName(
Token::Value property, PropertyKind type, bool is_generator, bool is_async,
bool is_static, bool* ok) {
DCHECK(type == PropertyKind::kMethodProperty ||
type == PropertyKind::kAccessorProperty);
DCHECK(type == PropertyKind::kMethodProperty || IsAccessor(type));
if (property == Token::SMI || property == Token::NUMBER) return;
@ -6201,7 +6203,7 @@ void ParserBase<Impl>::ClassLiteralChecker::CheckClassMethodName(
return;
}
} else if (IsConstructor()) {
if (is_generator || is_async || type == PropertyKind::kAccessorProperty) {
if (is_generator || is_async || IsAccessor(type)) {
MessageTemplate::Template msg =
is_generator ? MessageTemplate::kConstructorIsGenerator
: is_async ? MessageTemplate::kConstructorIsAsync

View File

@ -297,7 +297,7 @@ class Scanner {
inline bool CurrentMatchesContextual(Token::Value token) const {
DCHECK(Token::IsContextualKeyword(token));
return current().contextual_token == token;
return current_contextual_token() == token;
}
// Match the token against the contextual keyword or literal buffer.
@ -308,7 +308,7 @@ class Scanner {
// (which was escape-processed already).
// Conveniently, !current().literal_chars.is_used() for all proper
// keywords, so this second condition should exit early in common cases.
return (current().contextual_token == token) ||
return (current_contextual_token() == token) ||
(current().literal_chars.is_used() &&
current().literal_chars.Equals(Vector<const char>(
Token::String(token), Token::StringLength(token))));
@ -320,11 +320,9 @@ class Scanner {
Vector<const char>("use strict", strlen("use strict")));
}
bool IsGetOrSet(bool* is_get, bool* is_set) const {
*is_get = CurrentMatchesContextual(Token::GET);
*is_set = CurrentMatchesContextual(Token::SET);
return *is_get || *is_set;
}
bool IsGet() { return CurrentMatchesContextual(Token::GET); }
bool IsSet() { return CurrentMatchesContextual(Token::SET); }
bool IsLet() const {
return CurrentMatches(Token::LET) ||

View File

@ -244,6 +244,7 @@ class Token {
static bool IsAssignmentOp(Value tok) {
return IsInRange(tok, INIT, ASSIGN_EXP);
}
static bool IsGetOrSet(Value op) { return IsInRange(op, GET, SET); }
static bool IsBinaryOp(Value op) { return IsInRange(op, COMMA, EXP); }

View File

@ -63,8 +63,11 @@ inline bool IsInRange(T value, U lower_limit, U higher_limit) {
DCHECK_LE(lower_limit, higher_limit);
STATIC_ASSERT(sizeof(U) <= sizeof(T));
typedef typename std::make_unsigned<T>::type unsigned_T;
return static_cast<unsigned_T>(value - lower_limit) <=
static_cast<unsigned_T>(higher_limit - lower_limit);
// Use static_cast to support enum classes.
return static_cast<unsigned_T>(static_cast<unsigned_T>(value) -
static_cast<unsigned_T>(lower_limit)) <=
static_cast<unsigned_T>(static_cast<unsigned_T>(higher_limit) -
static_cast<unsigned_T>(lower_limit));
}
// X must be a power of 2. Returns the number of trailing zeros.