tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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