[parser] Drop name, prototype, constructor as contextual tokens

Change-Id: I19e23a1e91631a21d55bb5a42f1f538a655478f8
Reviewed-on: https://chromium-review.googlesource.com/c/1332233
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Reviewed-by: Sathya Gunasekaran <gsathya@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57467}
This commit is contained in:
Toon Verwaest 2018-11-13 13:30:03 +01:00 committed by Commit Bot
parent aab18a4c3e
commit 66b9fedcb4
7 changed files with 83 additions and 121 deletions

View File

@ -225,6 +225,7 @@ class AstBigInt {
F(next, "next") \
F(number, "number") \
F(object, "object") \
F(private_constructor, "#constructor") \
F(proto, "__proto__") \
F(prototype, "prototype") \
F(return, "return") \

View File

@ -219,6 +219,7 @@
V(_, percent_string, "percent") \
V(_, position_string, "position") \
V(_, preventExtensions_string, "preventExtensions") \
V(_, private_constructor_string, "#constructor") \
V(_, Promise_string, "Promise") \
V(_, promise_string, "promise") \
V(_, proto_string, "__proto__") \

View File

@ -1011,10 +1011,13 @@ class ParserBase {
bool* is_computed_name, bool* is_private);
ExpressionT ParseObjectLiteral();
ClassLiteralPropertyT ParseClassPropertyDefinition(
ClassLiteralChecker* checker, ClassInfo* class_info,
IdentifierT* property_name, bool has_extends, bool* is_computed_name,
ClassLiteralProperty::Kind* property_kind, bool* is_static,
bool* is_private);
ClassInfo* class_info, IdentifierT* property_name, bool has_extends,
bool* is_computed_name, ClassLiteralProperty::Kind* property_kind,
bool* is_static, bool* is_private);
void CheckClassFieldName(IdentifierT name, bool is_static);
void CheckClassMethodName(IdentifierT name, ParsePropertyKind type,
ParseFunctionFlags flags, bool is_static,
bool* has_seen_constructor);
ExpressionT ParseMemberInitializer(ClassInfo* class_info, int beg_pos,
bool is_static);
ObjectLiteralPropertyT ParseObjectPropertyDefinition(bool* has_seen_proto,
@ -1312,36 +1315,6 @@ class ParserBase {
return factory()->NewReturnStatement(expr, pos, end_pos);
}
// Validation per ES6 class literals.
class ClassLiteralChecker {
public:
explicit ClassLiteralChecker(ParserBase* parser)
: parser_(parser), has_seen_constructor_(false) {}
void CheckClassMethodName(Token::Value property, ParsePropertyKind type,
ParseFunctionFlags flags, bool is_static);
void CheckClassFieldName(bool is_static);
private:
bool IsConstructor() {
return this->scanner()->CurrentMatchesContextualEscaped(
Token::CONSTRUCTOR);
}
bool IsPrivateConstructor() {
return this->scanner()->CurrentMatchesContextualEscaped(
Token::PRIVATE_CONSTRUCTOR);
}
bool IsPrototype() {
return this->scanner()->CurrentMatchesContextualEscaped(Token::PROTOTYPE);
}
ParserBase* parser() const { return parser_; }
Scanner* scanner() const { return parser_->scanner(); }
ParserBase* parser_;
bool has_seen_constructor_;
};
ModuleDescriptor* module() const {
return scope()->AsModuleScope()->module();
}
@ -2116,10 +2089,9 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePropertyName(
template <typename Impl>
typename ParserBase<Impl>::ClassLiteralPropertyT
ParserBase<Impl>::ParseClassPropertyDefinition(
ClassLiteralChecker* checker, ClassInfo* class_info, IdentifierT* name,
bool has_extends, bool* is_computed_name,
ClassLiteralProperty::Kind* property_kind, bool* is_static,
bool* is_private) {
ClassInfo* class_info, IdentifierT* name, bool has_extends,
bool* is_computed_name, ClassLiteralProperty::Kind* property_kind,
bool* is_static, bool* is_private) {
DCHECK_NOT_NULL(class_info);
ParseFunctionFlags function_flags = ParseFunctionFlag::kIsNormal;
*is_static = false;
@ -2190,7 +2162,7 @@ ParserBase<Impl>::ParseClassPropertyDefinition(
return impl()->NullLiteralProperty();
}
if (!*is_computed_name) {
checker->CheckClassFieldName(*is_static);
CheckClassFieldName(*name, *is_static);
}
ExpressionT initializer =
ParseMemberInitializer(class_info, property_beg_pos, *is_static);
@ -2216,8 +2188,8 @@ ParserBase<Impl>::ParseClassPropertyDefinition(
// '{' FunctionBody '}'
if (!*is_computed_name) {
checker->CheckClassMethodName(name_token, ParsePropertyKind::kMethod,
function_flags, *is_static);
CheckClassMethodName(*name, ParsePropertyKind::kMethod, function_flags,
*is_static, &class_info->has_seen_constructor);
}
FunctionKind kind = MethodKindFor(function_flags);
@ -2247,8 +2219,8 @@ ParserBase<Impl>::ParseClassPropertyDefinition(
bool is_get = kind == ParsePropertyKind::kAccessorGetter;
if (!*is_computed_name) {
checker->CheckClassMethodName(name_token, kind,
ParseFunctionFlag::kIsNormal, *is_static);
CheckClassMethodName(*name, kind, ParseFunctionFlag::kIsNormal,
*is_static, &class_info->has_seen_constructor);
// 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.
@ -2368,7 +2340,6 @@ ParserBase<Impl>::ParseObjectPropertyDefinition(bool* has_seen_proto,
DCHECK_EQ(function_flags, ParseFunctionFlag::kIsNormal);
if (!*is_computed_name &&
(name_token == Token::IDENTIFIER || name_token == Token::STRING) &&
impl()->IdentifierEquals(name, ast_value_factory()->proto_string())) {
if (*has_seen_proto) {
classifier()->RecordExpressionError(scanner()->location(),
@ -4248,8 +4219,6 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseClassLiteral(
AccumulateFormalParameterContainmentErrors();
}
ClassLiteralChecker checker(this);
Expect(Token::LBRACE);
const bool has_extends = !impl()->IsNull(class_info.extends);
@ -4267,7 +4236,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseClassLiteral(
// property.
bool is_constructor = !class_info.has_seen_constructor;
ClassLiteralPropertyT property = ParseClassPropertyDefinition(
&checker, &class_info, &property_name, has_extends, &is_computed_name,
&class_info, &property_name, has_extends, &is_computed_name,
&property_kind, &is_static, &is_private);
if (!class_info.has_static_computed_names && is_static &&
is_computed_name) {
@ -5847,47 +5816,50 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseForAwaitStatement(
}
template <typename Impl>
void ParserBase<Impl>::ClassLiteralChecker::CheckClassMethodName(
Token::Value property, ParsePropertyKind type, ParseFunctionFlags flags,
bool is_static) {
void ParserBase<Impl>::CheckClassMethodName(IdentifierT name,
ParsePropertyKind type,
ParseFunctionFlags flags,
bool is_static,
bool* has_seen_constructor) {
DCHECK(type == ParsePropertyKind::kMethod || IsAccessor(type));
if (property == Token::SMI || property == Token::NUMBER) return;
AstValueFactory* avf = ast_value_factory();
if (is_static) {
if (IsPrototype()) {
this->parser()->ReportMessage(MessageTemplate::kStaticPrototype);
if (impl()->IdentifierEquals(name, avf->prototype_string())) {
ReportMessage(MessageTemplate::kStaticPrototype);
return;
}
} else if (IsConstructor()) {
} else if (impl()->IdentifierEquals(name, avf->constructor_string())) {
if (flags != ParseFunctionFlag::kIsNormal || IsAccessor(type)) {
MessageTemplate msg = (flags & ParseFunctionFlag::kIsGenerator) != 0
? MessageTemplate::kConstructorIsGenerator
: (flags & ParseFunctionFlag::kIsAsync) != 0
? MessageTemplate::kConstructorIsAsync
: MessageTemplate::kConstructorIsAccessor;
this->parser()->ReportMessage(msg);
ReportMessage(msg);
return;
}
if (has_seen_constructor_) {
this->parser()->ReportMessage(MessageTemplate::kDuplicateConstructor);
if (*has_seen_constructor) {
ReportMessage(MessageTemplate::kDuplicateConstructor);
return;
}
has_seen_constructor_ = true;
*has_seen_constructor = true;
return;
}
}
template <typename Impl>
void ParserBase<Impl>::ClassLiteralChecker::CheckClassFieldName(
bool is_static) {
if (is_static && IsPrototype()) {
this->parser()->ReportMessage(MessageTemplate::kStaticPrototype);
void ParserBase<Impl>::CheckClassFieldName(IdentifierT name, bool is_static) {
AstValueFactory* avf = ast_value_factory();
if (is_static && impl()->IdentifierEquals(name, avf->prototype_string())) {
ReportMessage(MessageTemplate::kStaticPrototype);
return;
}
if (IsConstructor() || IsPrivateConstructor()) {
this->parser()->ReportMessage(MessageTemplate::kConstructorClassField);
if (impl()->IdentifierEquals(name, avf->constructor_string()) ||
impl()->IdentifierEquals(name, avf->private_constructor_string())) {
ReportMessage(MessageTemplate::kConstructorClassField);
return;
}
}

View File

@ -37,13 +37,11 @@ PreParserIdentifier GetSymbolHelper(Scanner* scanner,
default:
break;
}
switch (scanner->current_contextual_token()) {
case Token::CONSTRUCTOR:
return PreParserIdentifier::Constructor();
case Token::NAME:
return PreParserIdentifier::Name();
default:
break;
if (string == avf->constructor_string()) {
return PreParserIdentifier::Constructor();
}
if (string == avf->name_string()) {
return PreParserIdentifier::Name();
}
if (scanner->literal_contains_escapes()) {
return PreParserIdentifier::Default();
@ -390,7 +388,6 @@ PreParserStatement PreParser::BuildParameterInitializationBlock(
bool PreParser::IdentifierEquals(const PreParserIdentifier& identifier,
const AstRawString* other) {
DCHECK_EQ(identifier.string_ == nullptr, has_error());
return identifier.string_ == other;
}

View File

@ -164,7 +164,6 @@ static const Token::Value one_char_tokens[] = {
KEYWORD("catch", Token::CATCH) \
KEYWORD("class", Token::CLASS) \
KEYWORD("const", Token::CONST) \
KEYWORD("constructor", Token::CONSTRUCTOR) \
KEYWORD("continue", Token::CONTINUE) \
KEYWORD_GROUP('d') \
KEYWORD("debugger", Token::DEBUGGER) \
@ -196,7 +195,6 @@ static const Token::Value one_char_tokens[] = {
KEYWORD_GROUP('m') \
KEYWORD("meta", Token::META) \
KEYWORD_GROUP('n') \
KEYWORD("name", Token::NAME) \
KEYWORD("new", Token::NEW) \
KEYWORD("null", Token::NULL_LITERAL) \
KEYWORD_GROUP('o') \
@ -205,7 +203,6 @@ static const Token::Value one_char_tokens[] = {
KEYWORD("package", Token::FUTURE_STRICT_RESERVED_WORD) \
KEYWORD("private", Token::FUTURE_STRICT_RESERVED_WORD) \
KEYWORD("protected", Token::FUTURE_STRICT_RESERVED_WORD) \
KEYWORD("prototype", Token::PROTOTYPE) \
KEYWORD("public", Token::FUTURE_STRICT_RESERVED_WORD) \
KEYWORD_GROUP('r') \
KEYWORD("return", Token::RETURN) \
@ -228,15 +225,13 @@ static const Token::Value one_char_tokens[] = {
KEYWORD("while", Token::WHILE) \
KEYWORD("with", Token::WITH) \
KEYWORD_GROUP('y') \
KEYWORD("yield", Token::YIELD) \
KEYWORD_GROUP('#') \
KEYWORD("#constructor", Token::PRIVATE_CONSTRUCTOR)
KEYWORD("yield", Token::YIELD)
V8_INLINE Token::Value KeywordOrIdentifierToken(const uint8_t* input,
int input_length) {
DCHECK_GE(input_length, 1);
const int kMinLength = 2;
const int kMaxLength = 12;
const int kMaxLength = 10;
if (input_length < kMinLength || input_length > kMaxLength) {
return Token::IDENTIFIER;
}

View File

@ -202,11 +202,7 @@ namespace internal {
C(TARGET, "target", 0) \
C(META, "meta", 0) \
C(AS, "as", 0) \
C(FROM, "from", 0) \
C(NAME, "name", 0) \
C(CONSTRUCTOR, "constructor", 0) \
C(PRIVATE_CONSTRUCTOR, "#constructor", 0) \
C(PROTOTYPE, "prototype", 0)
C(FROM, "from", 0)
class Token {
public:
@ -227,7 +223,7 @@ class Token {
// Predicates
static bool IsKeyword(Value token) { return token_type[token] == 'K'; }
static bool IsContextualKeyword(Value token) {
return IsInRange(token, GET, PROTOTYPE);
return IsInRange(token, GET, FROM);
}
static bool IsIdentifier(Value token, LanguageMode language_mode,

View File

@ -302,42 +302,42 @@ KNOWN_MAPS = {
("RO_SPACE", 0x02739): (171, "Tuple2Map"),
("RO_SPACE", 0x027d9): (173, "ArrayBoilerplateDescriptionMap"),
("RO_SPACE", 0x02b19): (161, "InterceptorInfoMap"),
("RO_SPACE", 0x04fa1): (153, "AccessCheckInfoMap"),
("RO_SPACE", 0x04ff1): (154, "AccessorInfoMap"),
("RO_SPACE", 0x05041): (155, "AccessorPairMap"),
("RO_SPACE", 0x05091): (156, "AliasedArgumentsEntryMap"),
("RO_SPACE", 0x050e1): (157, "AllocationMementoMap"),
("RO_SPACE", 0x05131): (158, "AsyncGeneratorRequestMap"),
("RO_SPACE", 0x05181): (159, "DebugInfoMap"),
("RO_SPACE", 0x051d1): (160, "FunctionTemplateInfoMap"),
("RO_SPACE", 0x05221): (162, "InterpreterDataMap"),
("RO_SPACE", 0x05271): (163, "ModuleInfoEntryMap"),
("RO_SPACE", 0x052c1): (164, "ModuleMap"),
("RO_SPACE", 0x05311): (165, "ObjectTemplateInfoMap"),
("RO_SPACE", 0x05361): (166, "PromiseCapabilityMap"),
("RO_SPACE", 0x053b1): (167, "PromiseReactionMap"),
("RO_SPACE", 0x05401): (168, "PrototypeInfoMap"),
("RO_SPACE", 0x05451): (169, "ScriptMap"),
("RO_SPACE", 0x054a1): (170, "StackFrameInfoMap"),
("RO_SPACE", 0x054f1): (172, "Tuple3Map"),
("RO_SPACE", 0x05541): (174, "WasmDebugInfoMap"),
("RO_SPACE", 0x05591): (175, "WasmExportedFunctionDataMap"),
("RO_SPACE", 0x055e1): (176, "CallableTaskMap"),
("RO_SPACE", 0x05631): (177, "CallbackTaskMap"),
("RO_SPACE", 0x05681): (178, "PromiseFulfillReactionJobTaskMap"),
("RO_SPACE", 0x056d1): (179, "PromiseRejectReactionJobTaskMap"),
("RO_SPACE", 0x05721): (180, "PromiseResolveThenableJobTaskMap"),
("RO_SPACE", 0x05771): (181, "WeakFactoryCleanupJobTaskMap"),
("RO_SPACE", 0x057c1): (182, "MicrotaskQueueMap"),
("RO_SPACE", 0x05811): (183, "AllocationSiteWithWeakNextMap"),
("RO_SPACE", 0x05861): (183, "AllocationSiteWithoutWeakNextMap"),
("RO_SPACE", 0x058b1): (216, "LoadHandler1Map"),
("RO_SPACE", 0x05901): (216, "LoadHandler2Map"),
("RO_SPACE", 0x05951): (216, "LoadHandler3Map"),
("RO_SPACE", 0x059a1): (224, "StoreHandler0Map"),
("RO_SPACE", 0x059f1): (224, "StoreHandler1Map"),
("RO_SPACE", 0x05a41): (224, "StoreHandler2Map"),
("RO_SPACE", 0x05a91): (224, "StoreHandler3Map"),
("RO_SPACE", 0x04fc1): (153, "AccessCheckInfoMap"),
("RO_SPACE", 0x05011): (154, "AccessorInfoMap"),
("RO_SPACE", 0x05061): (155, "AccessorPairMap"),
("RO_SPACE", 0x050b1): (156, "AliasedArgumentsEntryMap"),
("RO_SPACE", 0x05101): (157, "AllocationMementoMap"),
("RO_SPACE", 0x05151): (158, "AsyncGeneratorRequestMap"),
("RO_SPACE", 0x051a1): (159, "DebugInfoMap"),
("RO_SPACE", 0x051f1): (160, "FunctionTemplateInfoMap"),
("RO_SPACE", 0x05241): (162, "InterpreterDataMap"),
("RO_SPACE", 0x05291): (163, "ModuleInfoEntryMap"),
("RO_SPACE", 0x052e1): (164, "ModuleMap"),
("RO_SPACE", 0x05331): (165, "ObjectTemplateInfoMap"),
("RO_SPACE", 0x05381): (166, "PromiseCapabilityMap"),
("RO_SPACE", 0x053d1): (167, "PromiseReactionMap"),
("RO_SPACE", 0x05421): (168, "PrototypeInfoMap"),
("RO_SPACE", 0x05471): (169, "ScriptMap"),
("RO_SPACE", 0x054c1): (170, "StackFrameInfoMap"),
("RO_SPACE", 0x05511): (172, "Tuple3Map"),
("RO_SPACE", 0x05561): (174, "WasmDebugInfoMap"),
("RO_SPACE", 0x055b1): (175, "WasmExportedFunctionDataMap"),
("RO_SPACE", 0x05601): (176, "CallableTaskMap"),
("RO_SPACE", 0x05651): (177, "CallbackTaskMap"),
("RO_SPACE", 0x056a1): (178, "PromiseFulfillReactionJobTaskMap"),
("RO_SPACE", 0x056f1): (179, "PromiseRejectReactionJobTaskMap"),
("RO_SPACE", 0x05741): (180, "PromiseResolveThenableJobTaskMap"),
("RO_SPACE", 0x05791): (181, "WeakFactoryCleanupJobTaskMap"),
("RO_SPACE", 0x057e1): (182, "MicrotaskQueueMap"),
("RO_SPACE", 0x05831): (183, "AllocationSiteWithWeakNextMap"),
("RO_SPACE", 0x05881): (183, "AllocationSiteWithoutWeakNextMap"),
("RO_SPACE", 0x058d1): (216, "LoadHandler1Map"),
("RO_SPACE", 0x05921): (216, "LoadHandler2Map"),
("RO_SPACE", 0x05971): (216, "LoadHandler3Map"),
("RO_SPACE", 0x059c1): (224, "StoreHandler0Map"),
("RO_SPACE", 0x05a11): (224, "StoreHandler1Map"),
("RO_SPACE", 0x05a61): (224, "StoreHandler2Map"),
("RO_SPACE", 0x05ab1): (224, "StoreHandler3Map"),
("MAP_SPACE", 0x00139): (1057, "ExternalMap"),
("MAP_SPACE", 0x00189): (1073, "JSMessageObjectMap"),
}