summaryrefslogtreecommitdiff
path: root/deps/v8/src/ast/scopes.h
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/ast/scopes.h')
-rw-r--r--deps/v8/src/ast/scopes.h151
1 files changed, 131 insertions, 20 deletions
diff --git a/deps/v8/src/ast/scopes.h b/deps/v8/src/ast/scopes.h
index 73e6e8fd89..30838db28b 100644
--- a/deps/v8/src/ast/scopes.h
+++ b/deps/v8/src/ast/scopes.h
@@ -44,7 +44,7 @@ class VariableMap : public ZoneHashMap {
VariableMode mode, VariableKind kind,
InitializationFlag initialization_flag,
MaybeAssignedFlag maybe_assigned_flag,
- bool* was_added);
+ IsStaticFlag is_static_flag, bool* was_added);
V8_EXPORT_PRIVATE Variable* Lookup(const AstRawString* name);
void Remove(Variable* var);
@@ -360,6 +360,9 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) {
bool is_class_scope() const { return scope_type_ == CLASS_SCOPE; }
bool inner_scope_calls_eval() const { return inner_scope_calls_eval_; }
+ bool private_name_lookup_skips_outer_class() const {
+ return private_name_lookup_skips_outer_class_;
+ }
bool IsAsmModule() const;
// Returns true if this scope or any inner scopes that might be eagerly
// compiled are asm modules.
@@ -464,10 +467,6 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) {
// sloppy eval call. One if this->sloppy_eval_can_extend_vars().
int ContextChainLengthUntilOutermostSloppyEval() const;
- // Find the closest class scope in the current scope and outer scopes. If no
- // class scope is found, nullptr will be returned.
- ClassScope* GetClassScope();
-
// Find the first function, script, eval or (declaration) block scope. This is
// the scope where var declarations will be hoisted to in the implementation.
DeclarationScope* GetDeclarationScope();
@@ -557,9 +556,10 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) {
Variable* Declare(Zone* zone, const AstRawString* name, VariableMode mode,
VariableKind kind, InitializationFlag initialization_flag,
MaybeAssignedFlag maybe_assigned_flag, bool* was_added) {
- Variable* result =
- variables_.Declare(zone, this, name, mode, kind, initialization_flag,
- maybe_assigned_flag, was_added);
+ // Static variables can only be declared using ClassScope methods.
+ Variable* result = variables_.Declare(
+ zone, this, name, mode, kind, initialization_flag, maybe_assigned_flag,
+ IsStaticFlag::kNotStatic, was_added);
if (*was_added) locals_.Add(result);
return result;
}
@@ -713,7 +713,8 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) {
// This scope's declarations might not be executed in order (e.g., switch).
bool scope_nonlinear_ : 1;
bool is_hidden_ : 1;
- // Temporary workaround that allows masking of 'this' in debug-evalute scopes.
+ // Temporary workaround that allows masking of 'this' in debug-evaluate
+ // scopes.
bool is_debug_evaluate_scope_ : 1;
// True if one of the inner scopes or the scope itself calls eval.
@@ -723,6 +724,11 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) {
// True if it holds 'var' declarations.
bool is_declaration_scope_ : 1;
+ // True if the outer scope is a class scope and should be skipped when
+ // resolving private names, i.e. if the scope is in a class heritage
+ // expression.
+ bool private_name_lookup_skips_outer_class_ : 1;
+
bool must_use_preparsed_scope_data_ : 1;
};
@@ -859,6 +865,11 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope {
return IsClassMembersInitializerFunction(function_kind());
}
+ void set_is_async_module() {
+ DCHECK(IsModule(function_kind_));
+ function_kind_ = kAsyncModule;
+ }
+
void DeclareThis(AstValueFactory* ast_value_factory);
void DeclareArguments(AstValueFactory* ast_value_factory);
void DeclareDefaultFunctionVariables(AstValueFactory* ast_value_factory);
@@ -1082,6 +1093,11 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope {
GetReceiverScope()->receiver()->ForceContextAllocation();
}
+ bool needs_private_name_context_chain_recalc() const {
+ return needs_private_name_context_chain_recalc_;
+ }
+ void RecordNeedsPrivateNameContextChainRecalc();
+
private:
V8_INLINE void AllocateParameter(Variable* var, int index);
@@ -1099,6 +1115,12 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope {
void SetDefaults();
+ // Recalculate the private name context chain from the existing skip bit in
+ // preparation for AllocateScopeInfos. Because the private name scope is
+ // implemented with a skip bit for scopes in heritage position, that bit may
+ // need to be recomputed due scopes that do not need contexts.
+ void RecalcPrivateNameContextChain();
+
bool has_simple_parameters_ : 1;
// This scope contains an "use asm" annotation.
bool is_asm_module_ : 1;
@@ -1120,9 +1142,10 @@ class V8_EXPORT_PRIVATE DeclarationScope : public Scope {
bool has_checked_syntax_ : 1;
bool has_this_reference_ : 1;
bool has_this_declaration_ : 1;
+ bool needs_private_name_context_chain_recalc_ : 1;
// If the scope is a function scope, this is the function kind.
- const FunctionKind function_kind_;
+ FunctionKind function_kind_;
int num_parameters_ = 0;
@@ -1220,17 +1243,26 @@ class ModuleScope final : public DeclarationScope {
class V8_EXPORT_PRIVATE ClassScope : public Scope {
public:
- ClassScope(Zone* zone, Scope* outer_scope);
+ ClassScope(Zone* zone, Scope* outer_scope, bool is_anonymous);
// Deserialization.
- ClassScope(Zone* zone, AstValueFactory* ast_value_factory,
+ ClassScope(Isolate* isolate, Zone* zone, AstValueFactory* ast_value_factory,
Handle<ScopeInfo> scope_info);
+ struct HeritageParsingScope {
+ explicit HeritageParsingScope(ClassScope* class_scope)
+ : class_scope_(class_scope) {
+ class_scope_->SetIsParsingHeritage(true);
+ }
+ ~HeritageParsingScope() { class_scope_->SetIsParsingHeritage(false); }
+
+ private:
+ ClassScope* class_scope_;
+ };
+
// Declare a private name in the private name map and add it to the
// local variables of this scope.
Variable* DeclarePrivateName(const AstRawString* name, VariableMode mode,
- bool* was_added);
-
- void AddUnresolvedPrivateName(VariableProxy* proxy);
+ IsStaticFlag is_static_flag, bool* was_added);
// Try resolving all unresolved private names found in the current scope.
// Called from DeclarationScope::AllocateVariables() when reparsing a
@@ -1261,13 +1293,53 @@ class V8_EXPORT_PRIVATE ClassScope : public Scope {
void MigrateUnresolvedPrivateNameTail(AstNodeFactory* ast_node_factory,
UnresolvedList::Iterator tail);
Variable* DeclareBrandVariable(AstValueFactory* ast_value_factory,
+ IsStaticFlag is_static_flag,
int class_token_pos);
+
+ Variable* DeclareClassVariable(AstValueFactory* ast_value_factory,
+ const AstRawString* name, int class_token_pos);
+
Variable* brand() {
- return rare_data_ == nullptr ? nullptr : rare_data_->brand;
+ return GetRareData() == nullptr ? nullptr : GetRareData()->brand;
+ }
+
+ Variable* class_variable() { return class_variable_; }
+
+ V8_INLINE bool IsParsingHeritage() {
+ return rare_data_and_is_parsing_heritage_.GetPayload();
+ }
+
+ // Only maintained when the scope is parsed, not when the scope is
+ // deserialized.
+ bool has_static_private_methods() const {
+ return has_static_private_methods_;
+ }
+
+ // Returns whether the index of class variable of this class scope should be
+ // recorded in the ScopeInfo.
+ // If any inner scope accesses static private names directly, the class
+ // variable will be forced to be context-allocated.
+ // The inner scope may also calls eval which may results in access to
+ // static private names.
+ // Only maintained when the scope is parsed.
+ bool should_save_class_variable_index() const {
+ return should_save_class_variable_index_ ||
+ has_explicit_static_private_methods_access_ ||
+ (has_static_private_methods_ && inner_scope_calls_eval_);
+ }
+
+ // Only maintained when the scope is parsed.
+ bool is_anonymous_class() const { return is_anonymous_class_; }
+
+ // Overriden during reparsing
+ void set_should_save_class_variable_index() {
+ should_save_class_variable_index_ = true;
}
private:
friend class Scope;
+ friend class PrivateNameScopeIterator;
+
// Find the private name declared in the private name map first,
// if it cannot be found there, try scope info if there is any.
// Returns nullptr if it cannot be found.
@@ -1285,14 +1357,53 @@ class V8_EXPORT_PRIVATE ClassScope : public Scope {
Variable* brand = nullptr;
};
+ V8_INLINE RareData* GetRareData() {
+ return rare_data_and_is_parsing_heritage_.GetPointer();
+ }
V8_INLINE RareData* EnsureRareData() {
- if (rare_data_ == nullptr) {
- rare_data_ = new (zone_) RareData(zone_);
+ if (GetRareData() == nullptr) {
+ rare_data_and_is_parsing_heritage_.SetPointer(new (zone_)
+ RareData(zone_));
}
- return rare_data_;
+ return GetRareData();
+ }
+ V8_INLINE void SetIsParsingHeritage(bool v) {
+ rare_data_and_is_parsing_heritage_.SetPayload(v);
}
- RareData* rare_data_ = nullptr;
+ PointerWithPayload<RareData, bool, 1> rare_data_and_is_parsing_heritage_;
+ Variable* class_variable_ = nullptr;
+ // These are only maintained when the scope is parsed, not when the
+ // scope is deserialized.
+ bool has_static_private_methods_ = false;
+ bool has_explicit_static_private_methods_access_ = false;
+ bool is_anonymous_class_ = false;
+ // This is only maintained during reparsing, restored from the
+ // preparsed data.
+ bool should_save_class_variable_index_ = false;
+};
+
+// Iterate over the private name scope chain. The iteration proceeds from the
+// innermost private name scope outwards.
+class PrivateNameScopeIterator {
+ public:
+ explicit PrivateNameScopeIterator(Scope* start);
+
+ bool Done() const { return current_scope_ == nullptr; }
+ void Next();
+
+ // Add an unresolved private name to the current scope.
+ void AddUnresolvedPrivateName(VariableProxy* proxy);
+
+ ClassScope* GetScope() const {
+ DCHECK(!Done());
+ return current_scope_->AsClassScope();
+ }
+
+ private:
+ bool skipped_any_scopes_ = false;
+ Scope* start_scope_;
+ Scope* current_scope_;
};
} // namespace internal