AbstractScopePtr.h (2587B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 * vim: set ts=8 sts=2 et sw=2 tw=80: 3 * This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef frontend_AbstractScopePtr_h 8 #define frontend_AbstractScopePtr_h 9 10 #include <type_traits> 11 12 #include "frontend/ScopeIndex.h" 13 #include "vm/ScopeKind.h" // For ScopeKind 14 15 namespace js { 16 class Scope; 17 class GlobalScope; 18 class EvalScope; 19 20 namespace frontend { 21 struct CompilationState; 22 class ScopeStencil; 23 } // namespace frontend 24 25 // An interface class to support Scope queries in the frontend without requiring 26 // a GC Allocated scope to necessarily exist. 27 // 28 // This abstracts Scope* and a ScopeStencil type used within the frontend before 29 // the Scope is allocated. 30 // 31 // Queries to GC Scope should be pre-calculated and stored into ScopeContext. 32 class AbstractScopePtr { 33 private: 34 // ScopeIndex::invalid() if this points CompilationInput.enclosingScope. 35 ScopeIndex index_; 36 37 frontend::CompilationState& compilationState_; 38 39 public: 40 friend class js::Scope; 41 42 AbstractScopePtr(frontend::CompilationState& compilationState, 43 ScopeIndex index) 44 : index_(index), compilationState_(compilationState) {} 45 46 static AbstractScopePtr compilationEnclosingScope( 47 frontend::CompilationState& compilationState) { 48 return AbstractScopePtr(compilationState, ScopeIndex::invalid()); 49 } 50 51 private: 52 bool isScopeStencil() const { return index_.isValid(); } 53 54 frontend::ScopeStencil& scopeData() const; 55 56 public: 57 // This allows us to check whether or not this provider wraps 58 // or otherwise would reify to a particular scope type. 59 template <typename T> 60 bool is() const { 61 static_assert(std::is_base_of_v<Scope, T>, 62 "Trying to ask about non-Scope type"); 63 return kind() == T::classScopeKind_; 64 } 65 66 ScopeKind kind() const; 67 AbstractScopePtr enclosing() const; 68 bool hasEnvironment() const; 69 // Valid iff is<FunctionScope> 70 bool isArrow() const; 71 72 #ifdef DEBUG 73 bool hasNonSyntacticScopeOnChain() const; 74 #endif 75 }; 76 77 // Specializations of AbstractScopePtr::is 78 template <> 79 inline bool AbstractScopePtr::is<GlobalScope>() const { 80 return kind() == ScopeKind::Global || kind() == ScopeKind::NonSyntactic; 81 } 82 83 template <> 84 inline bool AbstractScopePtr::is<EvalScope>() const { 85 return kind() == ScopeKind::Eval || kind() == ScopeKind::StrictEval; 86 } 87 88 } // namespace js 89 90 #endif // frontend_AbstractScopePtr_h