5#ifndef V8_AST_SCOPES_H_
6#define V8_AST_SCOPES_H_
41class PreparseDataBuilder;
42class SloppyBlockFunctionStatement;
60 static_cast<ZoneHashMap&
>(*this) = std::move(other);
100 scope_name_ = scope_name;
107 int UniqueIdInScript()
const;
120 void RewriteReplGlobalVariables();
132 if (sloppy_eval_can_extend_vars_) {
133 declaration_scope_->sloppy_eval_can_extend_vars_ =
true;
136 outer_scope_->calls_eval_ =
true;
160 template <
typename IsolateT>
162 static Scope* DeserializeScopeChain(IsolateT* isolate,
Zone* zone,
166 DeserializationMode deserialization_mode,
169 template <
typename IsolateT>
171 static void SetScriptScopeInfo(IsolateT* isolate,
177 Scope* FinalizeBlockScope();
182 if (must_use_preparsed_scope_data_) {
185 must_use_preparsed_scope_data_ =
true;
187 outer_scope_->SetMustUsePreparseData();
192 return must_use_preparsed_scope_data_;
202 return variables_.Lookup(name);
216 bool* sloppy_mode_block_scope_function_redefinition,
237 DCHECK_IMPLIES(already_resolved_, reparsing_for_class_initializer_);
240 AddUnresolved(proxy);
276 inline void RecordEvalCall();
279 inner_scope_calls_eval_ =
true;
280 for (
Scope* scope = outer_scope(); scope !=
nullptr;
282 if (scope->inner_scope_calls_eval_)
return;
283 scope->inner_scope_calls_eval_ =
true;
290 set_language_mode(language_mode);
340 start_position_ = statement_pos;
350 DCHECK(!already_resolved_);
351 force_context_allocation_for_parameters_ =
true;
354 return force_context_allocation_for_parameters_;
375 return is_class_scope() ||
376 (is_block_scope() && is_block_scope_for_object_literal_);
379 DCHECK_IMPLIES(is_block_scope_for_object_literal_, is_block_scope());
380 return is_block_scope_for_object_literal_;
384 is_block_scope_for_object_literal_ =
true;
389 return private_name_lookup_skips_outer_class_;
394 return has_await_using_declaration_;
399 return is_wrapped_function_;
402 DCHECK(is_function_scope());
403 is_wrapped_function_ =
true;
406#if V8_ENABLE_WEBASSEMBLY
407 bool IsAsmModule()
const;
410 bool ContainsAsmModule()
const;
426 return (language_mode() > outer_scope_->language_mode());
434 DCHECK_IMPLIES(ForceContextForLanguageMode(), num_heap_slots() > 0);
435 return num_heap_slots() > 0;
455 template <
typename FunctionType>
465 bool IsConstructorScope()
const;
468 bool IsOuterScopeOf(
Scope* other)
const;
478 return is_strict_ ? LanguageMode::kStrict : LanguageMode::kSloppy;
493 return static_cast<Variable*
>(variables_.Start()->value);
496 bool ShouldBanArguments();
506 switch (scope_type_) {
517 DCHECK_IMPLIES(sloppy_eval_can_extend_vars_, is_declaration_scope());
518 return sloppy_eval_can_extend_vars_;
523 return HasContextExtensionSlot() ? Context::MIN_CONTEXT_EXTENDED_SLOTS
524 : Context::MIN_CONTEXT_SLOTS;
527 int ContextLocalCount()
const;
531 bool AllowsLazyParsingWithoutUnresolvedVariables(
const Scope* outer)
const;
534 int ContextChainLength(
Scope* scope)
const;
538 int ContextChainLengthUntilOutermostSloppyEval()
const;
571 Scope* GetHomeObjectScope();
576 Scope* GetOuterScopeWithContext();
578 bool HasReceiverToDeserialize()
const;
579 bool HasThisReference()
const;
586 int num_var()
const {
return variables_.occupancy(); }
592 void Print(
int n = 0);
595 void CheckScopePositions();
600 void MarkReparsingForClassInitializer() {
601 reparsing_for_class_initializer_ =
true;
606 bool HasSimpleParameters();
609 bool IsSkippableFunctionScope();
613 DCHECK(is_home_object_scope());
614 return needs_home_object_;
618 DCHECK(is_home_object_scope());
619 needs_home_object_ =
true;
624 if (inner_scope == inner_scope_) {
625 inner_scope_ = inner_scope_->sibling_;
628 for (
Scope* scope = inner_scope_; scope !=
nullptr;
630 if (scope->sibling_ == inner_scope) {
631 scope->sibling_ = scope->sibling_->sibling_;
639 Variable* var = variables_.Lookup(name);
640 if (var !=
nullptr ||
scope_info_.is_null())
return var;
641 return LookupInScopeInfo(name, cache);
646 Variable* var = scope->LookupInScopeOrScopeInfo(name, scope);
647 if (var !=
nullptr)
return var;
667 zone,
this, name, mode,
kind, initialization_flag, maybe_assigned_flag,
668 IsStaticFlag::kNotStatic, was_added);
669 if (mode == VariableMode::kUsing) has_using_declaration_ =
true;
670 if (mode == VariableMode::kAwaitUsing) has_await_using_declaration_ =
true;
679 bool NeedsScopeInfo()
const;
686 void SavePreparseData(
Parser* parser);
702 template <ScopeLookupMode mode>
704 Scope* outer_scope_end,
Scope* cache_scope =
nullptr,
705 bool force_context_allocation =
false);
708 bool force_context_allocation);
711 bool force_context_allocation);
723 bool maybe_in_arrowhead);
727 bool MustAllocateInContext(
Variable* var);
730 void AllocateStackSlot(
Variable* var);
732 void AllocateNonParameterLocal(
Variable* var);
734 V8_INLINE void AllocateNonParameterLocalsAndDeclaredGlobals();
735 void AllocateVariablesRecursively();
737 template <
typename IsolateT>
751 inner_scope->
sibling_ = inner_scope_;
752 inner_scope_ = inner_scope;
760 friend class ScopeTestHelper;
791 bool already_resolved_;
792 bool reparsing_for_class_initializer_;
795 bool needs_migration_;
812 static_assert(LanguageModeSize == 2);
855 FunctionKind function_kind = FunctionKind::kNormalFunction);
861 REPLMode repl_mode = REPLMode::kNo);
870 uses_super_property_ =
true;
871 Scope* home_object_scope = GetHomeObjectScope();
878 void TakeUnresolvedReferencesFromParent();
894 if (is_script_scope())
return;
898 if (is_eval_scope()) {
923 sloppy_eval_can_extend_vars_ =
true;
927 return sloppy_eval_can_extend_vars_;
933 DCHECK(is_module_scope());
934 Variable* var = variables_.Lookup(name);
942 void set_is_being_lazily_parsed(
bool is_being_lazily_parsed) {
943 is_being_lazily_parsed_ = is_being_lazily_parsed;
945 bool is_being_lazily_parsed()
const {
return is_being_lazily_parsed_; }
950 needs_migration_ =
true;
963 bool* allowed_catch_binding_var_redeclaration);
966 has_checked_syntax_ = has_checked_syntax;
971 return force_eager_compilation_ || should_eager_compile_;
974 void set_should_eager_compile();
977 DCHECK(is_script_scope());
982#if V8_ENABLE_WEBASSEMBLY
983 bool is_asm_module()
const {
return is_asm_module_; }
984 void set_is_asm_module();
993 function_kind_ = FunctionKind::kModuleWithTopLevelAwait;
998 void DeclareDefaultFunctionVariables(
AstValueFactory* ast_value_factory);
1009 Scope* cache =
nullptr);
1019 bool is_optional,
bool is_rest,
1023 void RecordParameter(
bool is_rest);
1034 DCHECK(has_this_declaration() || is_script_scope());
1052 DCHECK(is_function_scope() || is_module_scope() || is_repl_mode_scope());
1053 return GetRareVariable(RareVariable::kGeneratorObject);
1059 DCHECK(is_function_scope() || is_module_scope());
1060 DCHECK(!is_being_lazily_parsed_);
1061 return params_[
index];
1073 return has_rest_ ? params_[params_.length() - 1] :
nullptr;
1084 DCHECK(is_function_scope());
1085 has_simple_parameters_ =
false;
1089 SetHasNonSimpleParameters();
1091 p = variables_.Next(p)) {
1099 DCHECK(is_function_scope());
1100 DCHECK(!is_arrow_scope());
1102 return is_sloppy(language_mode()) && has_simple_parameters()
1103 ? CreateArgumentsType::kMappedArguments
1104 : CreateArgumentsType::kUnmappedArguments;
1115 Variable* this_function = GetRareVariable(RareVariable::kThisFunction);
1118 DCHECK(this_function ==
nullptr ||
1122 return this_function;
1130 void DeclareSloppyBlockFunction(
1153 bool maybe_in_arrowhead);
1157 template <
typename IsolateT>
1163 bool AllowsLazyCompilation()
const;
1169 for (s =
this; !s->is_script_scope();
1170 s = s->outer_scope()->GetClosureScope()) {
1171 s->force_eager_compilation_ =
true;
1177 void PrintParameters();
1181 V8_INLINE void AllocateParameterLocals();
1184 void ResetAfterPreparsing(
AstValueFactory* ast_value_factory,
bool aborted);
1188 is_skipped_function_ = is_skipped_function;
1192 return has_inferred_function_name_;
1195 DCHECK(is_function_scope());
1196 has_inferred_function_name_ =
value;
1202 void SavePreparseDataForDeclarationScope(
Parser* parser);
1205 preparse_data_builder_ = preparse_data_builder;
1209 return preparse_data_builder_;
1215 set_has_this_reference();
1216 GetReceiverScope()->receiver()->ForceContextAllocation();
1220 return needs_private_name_context_chain_recalc_;
1222 void RecordNeedsPrivateNameContextChainRecalc();
1225 class_scope_has_private_brand_ =
value;
1228 return class_scope_has_private_brand_;
1244 bool AllocateVariables(
ParseInfo* info);
1255#if V8_ENABLE_WEBASSEMBLY
1257 bool is_asm_module_ : 1;
1270 bool is_being_lazily_parsed_ : 1;
1282 int num_parameters_ = 0;
1310 kThisFunction = offsetof(
RareData, this_function),
1311 kGeneratorObject = offsetof(
RareData, generator_object),
1315 if (rare_data_ ==
nullptr) {
1322 if (rare_data_ ==
nullptr)
return nullptr;
1323 return *
reinterpret_cast<Variable**
>(
1324 reinterpret_cast<uint8_t*
>(rare_data_) +
static_cast<ptrdiff_t
>(id));
1329 template <
typename Predicate>
1331 if (
V8_LIKELY(rare_data_ ==
nullptr))
return;
1333 reinterpret_cast<uint8_t*
>(rare_data_) +
static_cast<ptrdiff_t
>(id));
1334 if (*var && predicate(*var)) *var =
nullptr;
1357 : outer_scope_(scope),
1358 declaration_scope_(scope->GetDeclarationScope()),
1359 top_inner_scope_(scope->inner_scope_),
1360 top_unresolved_(scope->unresolved_list_.
end()),
1361 top_local_(scope->GetClosureScope()->
locals_.
end()),
1362 calls_eval_(outer_scope_->calls_eval_),
1363 sloppy_eval_can_extend_vars_(
1364 declaration_scope_->sloppy_eval_can_extend_vars_) {
1383 void AllocateModuleVariables();
1393 template <
typename IsolateT>
1399 : class_scope_(class_scope) {
1400 class_scope_->SetIsParsingHeritage(
true);
1440 void MigrateUnresolvedPrivateNameTail(
AstNodeFactory* ast_node_factory,
1444 int class_token_pos);
1450 return GetRareData() ==
nullptr ?
nullptr : GetRareData()->brand;
1456 return rare_data_and_is_parsing_heritage_.GetPayload();
1462 return has_static_private_methods_;
1473 return should_save_class_variable_index_ ||
1474 has_explicit_static_private_methods_access_ ||
1475 (has_static_private_methods_ && inner_scope_calls_eval_);
1483 should_save_class_variable_index_ =
true;
1508 return rare_data_and_is_parsing_heritage_.GetPointer();
1511 if (GetRareData() ==
nullptr) {
1512 rare_data_and_is_parsing_heritage_.SetPointer(
1513 zone()->New<RareData>(zone()));
1515 return GetRareData();
1518 rare_data_and_is_parsing_heritage_.SetPayload(v);
1540 bool Done()
const {
return current_scope_ ==
nullptr; }
1548 return current_scope_->AsClassScope();
1552 bool skipped_any_scopes_ =
false;
AllocationPolicy allocator() const
VariableProxy * NewVariableProxy(Variable *var, int start_position=kNoSourcePosition)
V8_INLINE RareData * EnsureRareData()
bool has_static_private_methods_
bool should_save_class_variable_index() const
bool has_static_private_methods() const
bool has_explicit_static_private_methods_access_
V8_INLINE void SetIsParsingHeritage(bool v)
bool is_anonymous_class() const
Variable * class_variable()
bool should_save_class_variable_index_
base::PointerWithPayload< RareData, bool, 1 > rare_data_and_is_parsing_heritage_
void set_should_save_class_variable_index()
V8_INLINE RareData * GetRareData()
V8_INLINE bool IsParsingHeritage()
Variable * RedeclareSyntheticContextVariable(const AstRawString *name)
bool is_arrow_scope() const
void SetScriptScopeInfo(Handle< ScopeInfo > scope_info)
void SetHasNonSimpleParameters()
bool class_scope_has_private_brand_
static V8_EXPORT_PRIVATE void AllocateScopeInfos(ParseInfo *info, DirectHandle< Script > script, IsolateT *isolate)
bool uses_super_property() const
Variable * this_function_var() const
void set_is_skipped_function(bool is_skipped_function)
FunctionKind function_kind() const
void RecordDeclarationScopeEvalCall()
bool should_ban_arguments() const
bool force_eager_compilation_
bool class_scope_has_private_brand() const
V8_INLINE RareData * EnsureRareData()
CreateArgumentsType GetArgumentsType() const
Variable * function_var() const
bool ShouldEagerCompile() const
void ForceEagerCompilation()
Variable * new_target_var()
bool uses_super_property_
void MakeParametersNonSimple()
FunctionKind function_kind_
bool needs_private_name_context_chain_recalc() const
void RecordSuperPropertyUsage()
bool has_this_reference() const
void RecalcPrivateNameContextChain()
void set_zone(Zone *zone)
bool has_inferred_function_name_
bool has_simple_parameters_
bool has_this_declaration_
bool has_arguments_parameter_
V8_INLINE Variable * GetRareVariable(RareVariable id) const
Variable * LookupInModule(const AstRawString *name)
bool has_checked_syntax() const
void set_has_inferred_function_name(bool value)
Variable * parameter(int index) const
bool should_eager_compile_
bool is_skipped_function() const
void set_has_checked_syntax(bool has_checked_syntax)
void set_class_scope_has_private_brand(bool value)
bool is_skipped_function_
Variable * arguments() const
bool needs_private_name_context_chain_recalc_
int num_parameters() const
PreparseDataBuilder * preparse_data_builder() const
void set_has_this_reference()
bool has_inferred_function_name() const
bool sloppy_eval_can_extend_vars() const
Variable * generator_object_var() const
bool was_lazily_parsed() const
bool has_this_declaration() const
PreparseDataBuilder * preparse_data_builder_
void set_preparse_data_builder(PreparseDataBuilder *preparse_data_builder)
base::ThreadedList< SloppyBlockFunctionStatement > sloppy_block_functions_
Variable * rest_parameter() const
V8_INLINE void NullifyRareVariableIf(RareVariable id, Predicate predicate)
void set_module_has_toplevel_await()
ZonePtrList< Variable > params_
bool has_simple_parameters() const
SourceTextModuleDescriptor *const module_descriptor_
SourceTextModuleDescriptor * module() const
ClassScope * GetScope() const
Scope * declaration_scope_
bool sloppy_eval_can_extend_vars_
base::ThreadedList< Variable >::Iterator top_local_
Snapshot(Snapshot &&)=delete
Snapshot(const Snapshot &)=delete
UnresolvedList::Iterator top_unresolved_
bool HasContextExtensionSlot() const
int num_heap_slots() const
void RecordInnerScopeEvalCall()
void set_is_block_scope_for_object_literal()
void SetLanguageMode(LanguageMode language_mode)
bool is_wrapped_function_
void set_language_mode(LanguageMode language_mode)
bool is_repl_mode_scope() const
void set_end_position(int statement_pos)
bool has_using_declaration_
Variable * Declare(Zone *zone, const AstRawString *name, VariableMode mode, VariableKind kind, InitializationFlag initialization_flag, MaybeAssignedFlag maybe_assigned_flag, bool *was_added)
void ForceContextAllocationForParameters()
void AllocateScopeInfosRecursively(IsolateT *isolate, MaybeHandle< ScopeInfo > outer_scope, std::unordered_map< int, IndirectHandle< ScopeInfo > > &scope_infos_to_reuse)
bool private_name_lookup_skips_outer_class() const
base::ThreadedList< Declaration > * declarations()
Variable * catch_variable() const
Variable * LookupForTesting(const AstRawString *name)
Scope * outer_scope() const
bool is_debug_evaluate_scope_
DeclarationScope * AsDeclarationScope()
VariableProxy * NewUnresolved(AstNodeFactory *factory, const AstRawString *name, int start_pos, VariableKind kind=NORMAL_VARIABLE)
base::ThreadedList< Variable > * locals()
base::ThreadedList< Declaration > decls_
bool is_block_scope_for_object_literal() const
bool is_home_object_scope() const
base::ThreadedList< Variable > locals_
bool is_script_scope() const
bool private_name_lookup_skips_outer_class_
const ScopeType scope_type_
bool must_use_preparsed_scope_data() const
bool RemoveInnerScope(Scope *inner_scope)
int ContextHeaderLength() const
DeclarationScope * GetReceiverScope()
bool is_declaration_scope_
bool is_debug_evaluate_scope() const
bool is_class_scope() const
void AddInnerScope(Scope *inner_scope)
Handle< ScopeInfo > scope_info() const
bool has_forced_context_allocation_for_parameters() const
bool is_eval_scope() const
bool is_function_scope() const
void SetMustUsePreparseData()
ScopeType scope_type() const
bool inner_scope_calls_eval() const
bool force_context_allocation_for_parameters_
bool has_await_using_declaration_
Scope * inner_scope() const
bool has_using_declaration() const
void set_needs_home_object()
UnresolvedList unresolved_list_
bool has_await_using_declaration() const
void set_is_wrapped_function()
bool NeedsContext() const
bool needs_home_object() const
bool is_wrapped_function() const
bool is_block_scope_for_object_literal_
bool is_nonlinear() const
void AllocateDeclaredGlobal(Variable *var)
bool inner_scope_calls_eval_
bool is_with_scope() const
void set_start_position(int statement_pos)
bool is_block_scope() const
int num_stack_slots() const
void set_is_debug_evaluate_scope()
bool must_use_preparsed_scope_data_
V8_INLINE void ForEach(FunctionType callback)
DeclarationScope * GetDeclarationScope()
bool sloppy_eval_can_extend_vars_
LanguageMode language_mode() const
Variable * LookupInScopeOrScopeInfo(const AstRawString *name, Scope *cache)
bool is_catch_scope() const
int start_position() const
bool is_module_scope() const
IndirectHandle< ScopeInfo > scope_info_
bool ForceContextForLanguageMode() const
bool is_declaration_scope() const
Variable * LookupLocal(const AstRawString *name)
V8_EXPORT_PRIVATE Variable * Lookup(const AstRawString *name)
VariableMap & operator=(VariableMap &&other) V8_NOEXCEPT
void Remove(Variable *var)
Variable * Declare(Zone *zone, Scope *scope, const AstRawString *name, VariableMode mode, VariableKind kind, InitializationFlag initialization_flag, MaybeAssignedFlag maybe_assigned_flag, IsStaticFlag is_static_flag, bool *was_added)
VariableMap(VariableMap &&other) V8_NOEXCEPT
bool is_parameter() const
void MakeParameterNonSimple()
const JSFunctionRef function_
const ScopeInfoRef scope_info_
#define EXPORT_TEMPLATE_DECLARE(export)
refactor address components for immediate indexing make OptimizeMaglevOnNextCall optimize to turbofan instead of maglev filter for tracing turbofan compilation nullptr
ZoneVector< RpoNumber > & result
bool IsArrowFunction(FunctionKind kind)
bool is_sloppy(LanguageMode language_mode)
bool IsClassConstructor(FunctionKind kind)
bool IsConciseMethod(FunctionKind kind)
bool IsAccessorFunction(FunctionKind kind)
bool IsModule(FunctionKind kind)
bool BindsSuper(FunctionKind kind)
bool is_strict(LanguageMode language_mode)
bool IsClassMembersInitializerFunction(FunctionKind kind)
base::PointerTemplateHashMapImpl< ZoneAllocationPolicy > ZoneHashMap
std::vector< ValueType > locals_
#define NON_EXPORTED_BASE(code)
#define DCHECK_NOT_NULL(val)
#define DCHECK_IMPLIES(v1, v2)
#define DCHECK(condition)
#define DCHECK_EQ(v1, v2)
#define V8_EXPORT_PRIVATE
static constexpr int kAvailableBits
ClassScope * class_scope_
HeritageParsingScope(ClassScope *class_scope)
VariableMap private_name_map
UnresolvedList unresolved_private_names
#define V8_LIKELY(condition)
#define V8_WARN_UNUSED_RESULT
std::unique_ptr< ValueMirror > value