summaryrefslogtreecommitdiff
path: root/deps/v8/src/parsing/parser-base.h
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/parsing/parser-base.h')
-rw-r--r--deps/v8/src/parsing/parser-base.h74
1 files changed, 55 insertions, 19 deletions
diff --git a/deps/v8/src/parsing/parser-base.h b/deps/v8/src/parsing/parser-base.h
index 1b3bd64cdd..847774910a 100644
--- a/deps/v8/src/parsing/parser-base.h
+++ b/deps/v8/src/parsing/parser-base.h
@@ -267,6 +267,7 @@ class ParserBase {
allow_harmony_dynamic_import_(false),
allow_harmony_import_meta_(false),
allow_harmony_private_methods_(false),
+ allow_harmony_top_level_await_(false),
allow_eval_cache_(true) {
pointer_buffer_.reserve(32);
variable_buffer_.reserve(32);
@@ -280,6 +281,7 @@ class ParserBase {
ALLOW_ACCESSORS(harmony_dynamic_import)
ALLOW_ACCESSORS(harmony_import_meta)
ALLOW_ACCESSORS(harmony_private_methods)
+ ALLOW_ACCESSORS(harmony_top_level_await)
ALLOW_ACCESSORS(eval_cache)
#undef ALLOW_ACCESSORS
@@ -527,9 +529,9 @@ class ParserBase {
struct ClassInfo {
public:
explicit ClassInfo(ParserBase* parser)
- : variable(nullptr),
- extends(parser->impl()->NullExpression()),
- properties(parser->impl()->NewClassPropertyList(4)),
+ : extends(parser->impl()->NullExpression()),
+ public_members(parser->impl()->NewClassPropertyList(4)),
+ private_members(parser->impl()->NewClassPropertyList(4)),
static_fields(parser->impl()->NewClassPropertyList(4)),
instance_fields(parser->impl()->NewClassPropertyList(4)),
constructor(parser->impl()->NullExpression()),
@@ -540,12 +542,13 @@ class ParserBase {
has_instance_members(false),
requires_brand(false),
is_anonymous(false),
+ has_private_methods(false),
static_fields_scope(nullptr),
instance_members_scope(nullptr),
computed_field_count(0) {}
- Variable* variable;
ExpressionT extends;
- ClassPropertyListT properties;
+ ClassPropertyListT public_members;
+ ClassPropertyListT private_members;
ClassPropertyListT static_fields;
ClassPropertyListT instance_fields;
FunctionLiteralT constructor;
@@ -557,6 +560,7 @@ class ParserBase {
bool has_instance_members;
bool requires_brand;
bool is_anonymous;
+ bool has_private_methods;
DeclarationScope* static_fields_scope;
DeclarationScope* instance_members_scope;
int computed_field_count;
@@ -670,8 +674,8 @@ class ParserBase {
return new (zone()) DeclarationScope(zone(), parent, EVAL_SCOPE);
}
- ClassScope* NewClassScope(Scope* parent) const {
- return new (zone()) ClassScope(zone(), parent);
+ ClassScope* NewClassScope(Scope* parent, bool is_anonymous) const {
+ return new (zone()) ClassScope(zone(), parent, is_anonymous);
}
Scope* NewScope(ScopeType scope_type) const {
@@ -942,7 +946,10 @@ class ParserBase {
bool is_resumable() const {
return IsResumableFunction(function_state_->kind());
}
-
+ bool is_await_allowed() const {
+ return is_async_function() || (allow_harmony_top_level_await() &&
+ IsModule(function_state_->kind()));
+ }
const PendingCompilationErrorHandler* pending_error_handler() const {
return pending_error_handler_;
}
@@ -1456,6 +1463,7 @@ class ParserBase {
bool allow_harmony_dynamic_import_;
bool allow_harmony_import_meta_;
bool allow_harmony_private_methods_;
+ bool allow_harmony_top_level_await_;
bool allow_eval_cache_;
};
@@ -1582,16 +1590,17 @@ ParserBase<Impl>::ParsePropertyOrPrivatePropertyName() {
//
// Here, we check if this is a new private name reference in a top
// level function and throw an error if so.
- ClassScope* class_scope = scope()->GetClassScope();
+ PrivateNameScopeIterator private_name_scope_iter(scope());
// Parse the identifier so that we can display it in the error message
name = impl()->GetIdentifier();
- if (class_scope == nullptr) {
+ if (private_name_scope_iter.Done()) {
impl()->ReportMessageAt(Scanner::Location(pos, pos + 1),
MessageTemplate::kInvalidPrivateFieldResolution,
impl()->GetRawNameFromIdentifier(name));
return impl()->FailureExpression();
}
- key = impl()->ExpressionFromPrivateName(class_scope, name, pos);
+ key =
+ impl()->ExpressionFromPrivateName(&private_name_scope_iter, name, pos);
} else {
ReportUnexpectedToken(next);
return impl()->FailureExpression();
@@ -3062,7 +3071,7 @@ ParserBase<Impl>::ParseUnaryExpression() {
Token::Value op = peek();
if (Token::IsUnaryOrCountOp(op)) return ParseUnaryOrPrefixExpression();
- if (is_async_function() && op == Token::AWAIT) {
+ if (is_await_allowed() && op == Token::AWAIT) {
return ParseAwaitExpression();
}
return ParsePostfixExpression();
@@ -3577,7 +3586,19 @@ void ParserBase<Impl>::ParseFormalParameter(FormalParametersT* parameters) {
auto declaration_end = scope()->declarations()->end();
int initializer_end = end_position();
for (; declaration_it != declaration_end; ++declaration_it) {
- declaration_it->var()->set_initializer_position(initializer_end);
+ Variable* var = declaration_it->var();
+
+ // The first time a variable is initialized (i.e. when the initializer
+ // position is unset), clear its maybe_assigned flag as it is not a true
+ // assignment. Since this is done directly on the Variable objects, it has
+ // no effect on VariableProxy objects appearing on the left-hand side of
+ // true assignments, so x will be still be marked as maybe_assigned for:
+ // (x = 1, y = (x = 2)) => {}
+ // and even:
+ // (x = (x = 2)) => {}.
+ if (var->initializer_position() == kNoSourcePosition)
+ var->clear_maybe_assigned();
+ var->set_initializer_position(initializer_end);
}
impl()->AddFormalParameter(parameters, pattern, initializer, end_position(),
@@ -4355,16 +4376,16 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseClassLiteral(
}
}
- ClassScope* class_scope = NewClassScope(scope());
+ ClassScope* class_scope = NewClassScope(scope(), is_anonymous);
BlockState block_state(&scope_, class_scope);
RaiseLanguageMode(LanguageMode::kStrict);
ClassInfo class_info(this);
class_info.is_anonymous = is_anonymous;
- impl()->DeclareClassVariable(name, &class_info, class_token_pos);
scope()->set_start_position(end_position());
if (Check(Token::EXTENDS)) {
+ ClassScope::HeritageParsingScope heritage(class_scope);
FuncNameInferrerState fni_state(&fni_);
ExpressionParsingScope scope(impl());
class_info.extends = ParseLeftHandSideExpression();
@@ -4399,7 +4420,9 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseClassLiteral(
if (V8_UNLIKELY(prop_info.is_private)) {
DCHECK(!is_constructor);
- class_info.requires_brand |= !is_field;
+ class_info.requires_brand |= (!is_field && !prop_info.is_static);
+ class_info.has_private_methods |=
+ property_kind == ClassLiteralProperty::METHOD;
impl()->DeclarePrivateClassMember(class_scope, prop_info.name, property,
property_kind, prop_info.is_static,
&class_info);
@@ -4438,7 +4461,20 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseClassLiteral(
}
if (class_info.requires_brand) {
- class_scope->DeclareBrandVariable(ast_value_factory(), kNoSourcePosition);
+ // TODO(joyee): implement static brand checking
+ class_scope->DeclareBrandVariable(
+ ast_value_factory(), IsStaticFlag::kNotStatic, kNoSourcePosition);
+ }
+
+ bool should_save_class_variable_index =
+ class_scope->should_save_class_variable_index();
+ if (!is_anonymous || should_save_class_variable_index) {
+ impl()->DeclareClassVariable(class_scope, name, &class_info,
+ class_token_pos);
+ if (should_save_class_variable_index) {
+ class_scope->class_variable()->set_is_used();
+ class_scope->class_variable()->ForceContextAllocation();
+ }
}
return impl()->RewriteClassLiteral(class_scope, name, &class_info,
@@ -4861,7 +4897,7 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseStatement(
case Token::WHILE:
return ParseWhileStatement(labels, own_labels);
case Token::FOR:
- if (V8_UNLIKELY(is_async_function() && PeekAhead() == Token::AWAIT)) {
+ if (V8_UNLIKELY(is_await_allowed() && PeekAhead() == Token::AWAIT)) {
return ParseForAwaitStatement(labels, own_labels);
}
return ParseForStatement(labels, own_labels);
@@ -5921,7 +5957,7 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseForAwaitStatement(
ZonePtrList<const AstRawString>* labels,
ZonePtrList<const AstRawString>* own_labels) {
// for await '(' ForDeclaration of AssignmentExpression ')'
- DCHECK(is_async_function());
+ DCHECK(is_await_allowed());
typename FunctionState::LoopScope loop_scope(function_state_);
int stmt_pos = peek_position();