tor-browser

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

MaybeRooted.h (3679B)


      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 /*
      8 * Template types for use in generic code: to use Rooted/Handle/MutableHandle in
      9 * cases where GC may occur, or to use mock versions of those types that perform
     10 * no rooting or root list manipulation when GC cannot occur.
     11 */
     12 
     13 #ifndef gc_MaybeRooted_h
     14 #define gc_MaybeRooted_h
     15 
     16 #include "mozilla/Attributes.h"  // MOZ_IMPLICIT, MOZ_RAII
     17 
     18 #include <type_traits>  // std::true_type
     19 
     20 #include "gc/GCEnum.h"               // js::AllowGC, js::CanGC, js::NoGC
     21 #include "js/ComparisonOperators.h"  // JS::detail::DefineComparisonOps
     22 #include "js/RootingAPI.h"  // js::{Rooted,MutableHandle}Base, JS::SafelyInitialized, DECLARE_POINTER_{CONSTREF,ASSIGN}_OPS, DECLARE_NONPOINTER_{,MUTABLE_}ACCESSOR_METHODS, JS::Rooted, JS::{,Mutable}Handle
     23 
     24 namespace js {
     25 
     26 /**
     27 * Interface substitute for Rooted<T> which does not root the variable's
     28 * memory.
     29 */
     30 template <typename T>
     31 class MOZ_RAII FakeRooted : public RootedOperations<T, FakeRooted<T>> {
     32 public:
     33  using ElementType = T;
     34 
     35  explicit FakeRooted(JSContext* cx)
     36      : ptr(JS::SafelyInitialized<T>::create()) {}
     37 
     38  FakeRooted(JSContext* cx, const T& initial) : ptr(initial) {}
     39 
     40  FakeRooted(const FakeRooted&) = delete;
     41 
     42  DECLARE_POINTER_CONSTREF_OPS(T);
     43  DECLARE_POINTER_ASSIGN_OPS(FakeRooted, T);
     44  DECLARE_NONPOINTER_ACCESSOR_METHODS(ptr);
     45  DECLARE_NONPOINTER_MUTABLE_ACCESSOR_METHODS(ptr);
     46 
     47  operator JS::Handle<T>() { return JS::Handle<T>::fromMarkedLocation(&ptr); }
     48 
     49 private:
     50  T ptr;
     51 
     52  void set(const T& value) { ptr = value; }
     53 };
     54 
     55 }  // namespace js
     56 
     57 namespace JS::detail {
     58 template <typename T>
     59 struct DefineComparisonOps<js::FakeRooted<T>> : std::true_type {
     60  static const T& get(const js::FakeRooted<T>& v) { return v.get(); }
     61 };
     62 }  // namespace JS::detail
     63 
     64 namespace js {
     65 
     66 /**
     67 * Interface substitute for MutableHandle<T> which is not required to point to
     68 * rooted memory.
     69 */
     70 template <typename T>
     71 class FakeMutableHandle
     72    : public js::MutableHandleOperations<T, FakeMutableHandle<T>> {
     73 public:
     74  using ElementType = T;
     75 
     76  MOZ_IMPLICIT FakeMutableHandle(T* t) : ptr(t) {}
     77 
     78  MOZ_IMPLICIT FakeMutableHandle(FakeRooted<T>* root) : ptr(root->address()) {}
     79 
     80  void set(const T& v) { *ptr = v; }
     81 
     82  DECLARE_POINTER_CONSTREF_OPS(T);
     83  DECLARE_NONPOINTER_ACCESSOR_METHODS(*ptr);
     84  DECLARE_NONPOINTER_MUTABLE_ACCESSOR_METHODS(*ptr);
     85 
     86 private:
     87  FakeMutableHandle() : ptr(nullptr) {}
     88  DELETE_ASSIGNMENT_OPS(FakeMutableHandle, T);
     89 
     90  T* ptr;
     91 };
     92 
     93 }  // namespace js
     94 
     95 namespace JS::detail {
     96 template <typename T>
     97 struct DefineComparisonOps<js::FakeMutableHandle<T>> : std::true_type {
     98  static const T& get(const js::FakeMutableHandle<T>& v) { return v.get(); }
     99 };
    100 }  // namespace JS::detail
    101 
    102 namespace js {
    103 
    104 /**
    105 * Types for a variable that either should or shouldn't be rooted, depending on
    106 * the template parameter allowGC. Used for implementing functions that can
    107 * operate on either rooted or unrooted data.
    108 */
    109 
    110 template <typename T, AllowGC allowGC>
    111 class MaybeRooted;
    112 
    113 template <typename T>
    114 class MaybeRooted<T, CanGC> {
    115 public:
    116  using HandleType = JS::Handle<T>;
    117  using RootType = JS::Rooted<T>;
    118  using MutableHandleType = JS::MutableHandle<T>;
    119 };
    120 
    121 template <typename T>
    122 class MaybeRooted<T, NoGC> {
    123 public:
    124  using HandleType = const T&;
    125  using RootType = FakeRooted<T>;
    126  using MutableHandleType = FakeMutableHandle<T>;
    127 };
    128 
    129 }  // namespace js
    130 
    131 #endif  // gc_MaybeRooted_h