tor-browser

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

SpiderMonkeyInterface.h (3509B)


      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 file,
      5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef mozilla_dom_SpiderMonkeyInterface_h
      8 #define mozilla_dom_SpiderMonkeyInterface_h
      9 
     10 #include "js/RootingAPI.h"
     11 #include "js/TracingAPI.h"
     12 #include "jsapi.h"
     13 
     14 namespace mozilla::dom {
     15 
     16 /*
     17 * Class that just handles the JSObject storage and tracing for spidermonkey
     18 * interfaces
     19 */
     20 struct SpiderMonkeyInterfaceObjectStorage {
     21 protected:
     22  JSObject* mImplObj;
     23  JSObject* mWrappedObj;
     24 
     25  SpiderMonkeyInterfaceObjectStorage()
     26      : mImplObj(nullptr), mWrappedObj(nullptr) {}
     27 
     28  SpiderMonkeyInterfaceObjectStorage(
     29      SpiderMonkeyInterfaceObjectStorage&& aOther)
     30      : mImplObj(aOther.mImplObj), mWrappedObj(aOther.mWrappedObj) {
     31    aOther.mImplObj = nullptr;
     32    aOther.mWrappedObj = nullptr;
     33  }
     34 
     35 public:
     36  inline void TraceSelf(JSTracer* trc) {
     37    JS::TraceRoot(trc, &mImplObj,
     38                  "SpiderMonkeyInterfaceObjectStorage.mImplObj");
     39    JS::TraceRoot(trc, &mWrappedObj,
     40                  "SpiderMonkeyInterfaceObjectStorage.mWrappedObj");
     41  }
     42 
     43  inline bool inited() const { return !!mImplObj; }
     44 
     45  inline bool WrapIntoNewCompartment(JSContext* cx) {
     46    return JS_WrapObject(
     47        cx, JS::MutableHandle<JSObject*>::fromMarkedLocation(&mWrappedObj));
     48  }
     49 
     50  inline JSObject* Obj() const {
     51    MOZ_ASSERT(inited());
     52    return mWrappedObj;
     53  }
     54 
     55 private:
     56  SpiderMonkeyInterfaceObjectStorage(
     57      const SpiderMonkeyInterfaceObjectStorage&) = delete;
     58 };
     59 
     60 // A class for rooting an existing SpiderMonkey Interface struct
     61 template <typename InterfaceType>
     62 class MOZ_RAII SpiderMonkeyInterfaceRooter : private JS::CustomAutoRooter {
     63 public:
     64  template <typename CX>
     65  SpiderMonkeyInterfaceRooter(const CX& cx, InterfaceType* aInterface)
     66      : JS::CustomAutoRooter(cx), mInterface(aInterface) {}
     67 
     68  virtual void trace(JSTracer* trc) override { mInterface->TraceSelf(trc); }
     69 
     70 private:
     71  SpiderMonkeyInterfaceObjectStorage* const mInterface;
     72 };
     73 
     74 // And a specialization for dealing with nullable SpiderMonkey interfaces
     75 template <typename Inner>
     76 struct Nullable;
     77 template <typename InterfaceType>
     78 class MOZ_RAII SpiderMonkeyInterfaceRooter<Nullable<InterfaceType>>
     79    : private JS::CustomAutoRooter {
     80 public:
     81  template <typename CX>
     82  SpiderMonkeyInterfaceRooter(const CX& cx, Nullable<InterfaceType>* aInterface)
     83      : JS::CustomAutoRooter(cx), mInterface(aInterface) {}
     84 
     85  virtual void trace(JSTracer* trc) override {
     86    if (!mInterface->IsNull()) {
     87      mInterface->Value().TraceSelf(trc);
     88    }
     89  }
     90 
     91 private:
     92  Nullable<InterfaceType>* const mInterface;
     93 };
     94 
     95 // Class for easily setting up a rooted SpiderMonkey interface object on the
     96 // stack
     97 template <typename InterfaceType>
     98 class MOZ_RAII RootedSpiderMonkeyInterface final
     99    : public InterfaceType,
    100      private SpiderMonkeyInterfaceRooter<InterfaceType> {
    101 public:
    102  template <typename CX>
    103  explicit RootedSpiderMonkeyInterface(const CX& cx)
    104      : InterfaceType(), SpiderMonkeyInterfaceRooter<InterfaceType>(cx, this) {}
    105 
    106  template <typename CX>
    107  RootedSpiderMonkeyInterface(const CX& cx, JSObject* obj)
    108      : InterfaceType(obj),
    109        SpiderMonkeyInterfaceRooter<InterfaceType>(cx, this) {}
    110 };
    111 
    112 }  // namespace mozilla::dom
    113 
    114 #endif /* mozilla_dom_SpiderMonkeyInterface_h */