dom/bindings/BindingDeclarations.h

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/
     2 /* vim: set ts=2 sw=2 et tw=79: */
     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/. */
     7 /**
     8  * A header for declaring various things that binding implementation headers
     9  * might need.  The idea is to make binding implementation headers safe to
    10  * include anywhere without running into include hell like we do with
    11  * BindingUtils.h
    12  */
    13 #ifndef mozilla_dom_BindingDeclarations_h__
    14 #define mozilla_dom_BindingDeclarations_h__
    16 #include "nsStringGlue.h"
    17 #include "js/Value.h"
    18 #include "js/RootingAPI.h"
    19 #include "mozilla/Maybe.h"
    20 #include "nsCOMPtr.h"
    21 #include "nsTArray.h"
    22 #include "nsAutoPtr.h" // for nsRefPtr member variables
    23 #include "mozilla/dom/DOMString.h"
    24 #include "mozilla/dom/OwningNonNull.h"
    26 class nsWrapperCache;
    28 namespace mozilla {
    29 namespace dom {
    31 // Struct that serves as a base class for all dictionaries.  Particularly useful
    32 // so we can use IsBaseOf to detect dictionary template arguments.
    33 struct DictionaryBase
    34 {
    35 protected:
    36   bool ParseJSON(JSContext* aCx, const nsAString& aJSON,
    37                  JS::MutableHandle<JS::Value> aVal);
    38 };
    40 // Struct that serves as a base class for all typed arrays and array buffers and
    41 // array buffer views.  Particularly useful so we can use IsBaseOf to detect
    42 // typed array/buffer/view template arguments.
    43 struct AllTypedArraysBase {
    44 };
    46 // Struct that serves as a base class for all owning unions.
    47 // Particularly useful so we can use IsBaseOf to detect owning union
    48 // template arguments.
    49 struct AllOwningUnionBase {
    50 };
    53 struct EnumEntry {
    54   const char* value;
    55   size_t length;
    56 };
    58 class MOZ_STACK_CLASS GlobalObject
    59 {
    60 public:
    61   GlobalObject(JSContext* aCx, JSObject* aObject);
    63   JSObject* Get() const
    64   {
    65     return mGlobalJSObject;
    66   }
    68   nsISupports* GetAsSupports() const;
    70   // The context that this returns is not guaranteed to be in the compartment of
    71   // the object returned from Get(), in fact it's generally in the caller's
    72   // compartment.
    73   JSContext* GetContext() const
    74   {
    75     return mCx;
    76   }
    78   bool Failed() const
    79   {
    80     return !Get();
    81   }
    83 protected:
    84   JS::Rooted<JSObject*> mGlobalJSObject;
    85   JSContext* mCx;
    86   mutable nsISupports* mGlobalObject;
    87   mutable nsCOMPtr<nsISupports> mGlobalObjectRef;
    88 };
    90 // Class for representing optional arguments.
    91 template<typename T, typename InternalType>
    92 class Optional_base
    93 {
    94 public:
    95   Optional_base()
    96   {}
    98   explicit Optional_base(const T& aValue)
    99   {
   100     mImpl.construct(aValue);
   101   }
   103   template<typename T1, typename T2>
   104   explicit Optional_base(const T1& aValue1, const T2& aValue2)
   105   {
   106     mImpl.construct(aValue1, aValue2);
   107   }
   109   bool WasPassed() const
   110   {
   111     return !mImpl.empty();
   112   }
   114   // Return InternalType here so we can work with it usefully.
   115   InternalType& Construct()
   116   {
   117     mImpl.construct();
   118     return mImpl.ref();
   119   }
   121   template <class T1>
   122   InternalType& Construct(const T1 &t1)
   123   {
   124     mImpl.construct(t1);
   125     return mImpl.ref();
   126   }
   128   template <class T1, class T2>
   129   InternalType& Construct(const T1 &t1, const T2 &t2)
   130   {
   131     mImpl.construct(t1, t2);
   132     return mImpl.ref();
   133   }
   135   void Reset()
   136   {
   137     if (WasPassed()) {
   138       mImpl.destroy();
   139     }
   140   }
   142   const T& Value() const
   143   {
   144     return mImpl.ref();
   145   }
   147   // Return InternalType here so we can work with it usefully.
   148   InternalType& Value()
   149   {
   150     return mImpl.ref();
   151   }
   153   // And an explicit way to get the InternalType even if we're const.
   154   const InternalType& InternalValue() const
   155   {
   156     return mImpl.ref();
   157   }
   159   // If we ever decide to add conversion operators for optional arrays
   160   // like the ones Nullable has, we'll need to ensure that Maybe<> has
   161   // the boolean before the actual data.
   163 private:
   164   // Forbid copy-construction and assignment
   165   Optional_base(const Optional_base& other) MOZ_DELETE;
   166   const Optional_base &operator=(const Optional_base &other) MOZ_DELETE;
   168 protected:
   169   Maybe<InternalType> mImpl;
   170 };
   172 template<typename T>
   173 class Optional : public Optional_base<T, T>
   174 {
   175 public:
   176   Optional() :
   177     Optional_base<T, T>()
   178   {}
   180   explicit Optional(const T& aValue) :
   181     Optional_base<T, T>(aValue)
   182   {}
   183 };
   185 template<typename T>
   186 class Optional<JS::Handle<T> > :
   187   public Optional_base<JS::Handle<T>, JS::Rooted<T> >
   188 {
   189 public:
   190   Optional() :
   191     Optional_base<JS::Handle<T>, JS::Rooted<T> >()
   192   {}
   194   Optional(JSContext* cx) :
   195     Optional_base<JS::Handle<T>, JS::Rooted<T> >()
   196   {
   197     this->Construct(cx);
   198   }
   200   Optional(JSContext* cx, const T& aValue) :
   201     Optional_base<JS::Handle<T>, JS::Rooted<T> >(cx, aValue)
   202   {}
   204   // Override the const Value() to return the right thing so we're not
   205   // returning references to temporaries.
   206   JS::Handle<T> Value() const
   207   {
   208     return this->mImpl.ref();
   209   }
   211   // And we have to override the non-const one too, since we're
   212   // shadowing the one on the superclass.
   213   JS::Rooted<T>& Value()
   214   {
   215     return this->mImpl.ref();
   216   }
   217 };
   219 // A specialization of Optional for JSObject* to make sure that when someone
   220 // calls Construct() on it we will pre-initialized the JSObject* to nullptr so
   221 // it can be traced safely.
   222 template<>
   223 class Optional<JSObject*> : public Optional_base<JSObject*, JSObject*>
   224 {
   225 public:
   226   Optional() :
   227     Optional_base<JSObject*, JSObject*>()
   228   {}
   230   explicit Optional(JSObject* aValue) :
   231     Optional_base<JSObject*, JSObject*>(aValue)
   232   {}
   234   // Don't allow us to have an uninitialized JSObject*
   235   JSObject*& Construct()
   236   {
   237     // The Android compiler sucks and thinks we're trying to construct
   238     // a JSObject* from an int if we don't cast here.  :(
   239     return Optional_base<JSObject*, JSObject*>::Construct(
   240       static_cast<JSObject*>(nullptr));
   241   }
   243   template <class T1>
   244   JSObject*& Construct(const T1& t1)
   245   {
   246     return Optional_base<JSObject*, JSObject*>::Construct(t1);
   247   }
   248 };
   250 // A specialization of Optional for JS::Value to make sure no one ever uses it.
   251 template<>
   252 class Optional<JS::Value>
   253 {
   254 private:
   255   Optional() MOZ_DELETE;
   257   explicit Optional(JS::Value aValue) MOZ_DELETE;
   258 };
   260 // A specialization of Optional for NonNull that lets us get a T& from Value()
   261 template<typename U> class NonNull;
   262 template<typename T>
   263 class Optional<NonNull<T> > : public Optional_base<T, NonNull<T> >
   264 {
   265 public:
   266   // We want our Value to actually return a non-const reference, even
   267   // if we're const.  At least for things that are normally pointer
   268   // types...
   269   T& Value() const
   270   {
   271     return *this->mImpl.ref().get();
   272   }
   274   // And we have to override the non-const one too, since we're
   275   // shadowing the one on the superclass.
   276   NonNull<T>& Value()
   277   {
   278     return this->mImpl.ref();
   279   }
   280 };
   282 // A specialization of Optional for OwningNonNull that lets us get a
   283 // T& from Value()
   284 template<typename T>
   285 class Optional<OwningNonNull<T> > : public Optional_base<T, OwningNonNull<T> >
   286 {
   287 public:
   288   // We want our Value to actually return a non-const reference, even
   289   // if we're const.  At least for things that are normally pointer
   290   // types...
   291   T& Value() const
   292   {
   293     return *this->mImpl.ref().get();
   294   }
   296   // And we have to override the non-const one too, since we're
   297   // shadowing the one on the superclass.
   298   OwningNonNull<T>& Value()
   299   {
   300     return this->mImpl.ref();
   301   }
   302 };
   304 // Specialization for strings.
   305 // XXXbz we can't pull in FakeDependentString here, because it depends on
   306 // internal strings.  So we just have to forward-declare it and reimplement its
   307 // ToAStringPtr.
   309 namespace binding_detail {
   310 struct FakeDependentString;
   311 } // namespace binding_detail
   313 template<>
   314 class Optional<nsAString>
   315 {
   316 public:
   317   Optional() : mPassed(false) {}
   319   bool WasPassed() const
   320   {
   321     return mPassed;
   322   }
   324   void operator=(const nsAString* str)
   325   {
   326     MOZ_ASSERT(str);
   327     mStr = str;
   328     mPassed = true;
   329   }
   331   // If this code ever goes away, remove the comment pointing to it in the
   332   // FakeDependentString class in BindingUtils.h.
   333   void operator=(const binding_detail::FakeDependentString* str)
   334   {
   335     MOZ_ASSERT(str);
   336     mStr = reinterpret_cast<const nsDependentString*>(str);
   337     mPassed = true;
   338   }
   340   const nsAString& Value() const
   341   {
   342     MOZ_ASSERT(WasPassed());
   343     return *mStr;
   344   }
   346 private:
   347   // Forbid copy-construction and assignment
   348   Optional(const Optional& other) MOZ_DELETE;
   349   const Optional &operator=(const Optional &other) MOZ_DELETE;
   351   bool mPassed;
   352   const nsAString* mStr;
   353 };
   355 template<class T>
   356 class NonNull
   357 {
   358 public:
   359   NonNull()
   360 #ifdef DEBUG
   361     : inited(false)
   362 #endif
   363   {}
   365   operator T&() {
   366     MOZ_ASSERT(inited);
   367     MOZ_ASSERT(ptr, "NonNull<T> was set to null");
   368     return *ptr;
   369   }
   371   operator const T&() const {
   372     MOZ_ASSERT(inited);
   373     MOZ_ASSERT(ptr, "NonNull<T> was set to null");
   374     return *ptr;
   375   }
   377   operator T*() {
   378     MOZ_ASSERT(inited);
   379     MOZ_ASSERT(ptr, "NonNull<T> was set to null");
   380     return ptr;
   381   }
   383   void operator=(T* t) {
   384     ptr = t;
   385     MOZ_ASSERT(ptr);
   386 #ifdef DEBUG
   387     inited = true;
   388 #endif
   389   }
   391   template<typename U>
   392   void operator=(U* t) {
   393     ptr = t->ToAStringPtr();
   394     MOZ_ASSERT(ptr);
   395 #ifdef DEBUG
   396     inited = true;
   397 #endif
   398   }
   400   T** Slot() {
   401 #ifdef DEBUG
   402     inited = true;
   403 #endif
   404     return &ptr;
   405   }
   407   T* Ptr() {
   408     MOZ_ASSERT(inited);
   409     MOZ_ASSERT(ptr, "NonNull<T> was set to null");
   410     return ptr;
   411   }
   413   // Make us work with smart-ptr helpers that expect a get()
   414   T* get() const {
   415     MOZ_ASSERT(inited);
   416     MOZ_ASSERT(ptr);
   417     return ptr;
   418   }
   420 protected:
   421   T* ptr;
   422 #ifdef DEBUG
   423   bool inited;
   424 #endif
   425 };
   427 // Class for representing sequences in arguments.  We use a non-auto array
   428 // because that allows us to use sequences of sequences and the like.  This
   429 // needs to be fallible because web content controls the length of the array,
   430 // and can easily try to create very large lengths.
   431 template<typename T>
   432 class Sequence : public FallibleTArray<T>
   433 {
   434 public:
   435   Sequence() : FallibleTArray<T>()
   436   {}
   437 };
   439 inline nsWrapperCache*
   440 GetWrapperCache(nsWrapperCache* cache)
   441 {
   442   return cache;
   443 }
   445 inline nsWrapperCache*
   446 GetWrapperCache(void* p)
   447 {
   448   return nullptr;
   449 }
   451 // Helper template for smart pointers to resolve ambiguity between
   452 // GetWrappeCache(void*) and GetWrapperCache(const ParentObject&).
   453 template <template <typename> class SmartPtr, typename T>
   454 inline nsWrapperCache*
   455 GetWrapperCache(const SmartPtr<T>& aObject)
   456 {
   457   return GetWrapperCache(aObject.get());
   458 }
   460 struct ParentObject {
   461   template<class T>
   462   ParentObject(T* aObject) :
   463     mObject(aObject),
   464     mWrapperCache(GetWrapperCache(aObject)),
   465     mUseXBLScope(false)
   466   {}
   468   template<class T, template<typename> class SmartPtr>
   469   ParentObject(const SmartPtr<T>& aObject) :
   470     mObject(aObject.get()),
   471     mWrapperCache(GetWrapperCache(aObject.get())),
   472     mUseXBLScope(false)
   473   {}
   475   ParentObject(nsISupports* aObject, nsWrapperCache* aCache) :
   476     mObject(aObject),
   477     mWrapperCache(aCache),
   478     mUseXBLScope(false)
   479   {}
   481   nsISupports* const mObject;
   482   nsWrapperCache* const mWrapperCache;
   483   bool mUseXBLScope;
   484 };
   486 } // namespace dom
   487 } // namespace mozilla
   489 #endif // mozilla_dom_BindingDeclarations_h__

mercurial