diff options
Diffstat (limited to 'deps/v8/src/parsing/parser-base.h')
-rw-r--r-- | deps/v8/src/parsing/parser-base.h | 74 |
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(); |