LCOV - code coverage report
Current view: top level - dom/bindings - BindingDeclarations.h (source / functions) Hit Total Coverage
Test: output.info Lines: 72 122 59.0 %
Date: 2017-07-14 16:53:18 Functions: 142 1819 7.8 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : /**
       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__
      15             : 
      16             : #include "js/RootingAPI.h"
      17             : #include "js/Value.h"
      18             : 
      19             : #include "mozilla/Maybe.h"
      20             : #include "mozilla/RootedOwningNonNull.h"
      21             : #include "mozilla/RootedRefPtr.h"
      22             : 
      23             : #include "mozilla/dom/DOMString.h"
      24             : 
      25             : #include "nsCOMPtr.h"
      26             : #include "nsStringGlue.h"
      27             : #include "nsTArray.h"
      28             : 
      29             : class nsIPrincipal;
      30             : class nsWrapperCache;
      31             : 
      32             : namespace mozilla {
      33             : namespace dom {
      34             : 
      35             : // Struct that serves as a base class for all dictionaries.  Particularly useful
      36             : // so we can use IsBaseOf to detect dictionary template arguments.
      37        2905 : struct DictionaryBase
      38             : {
      39             : protected:
      40             :   bool ParseJSON(JSContext* aCx, const nsAString& aJSON,
      41             :                  JS::MutableHandle<JS::Value> aVal);
      42             : 
      43             :   bool StringifyToJSON(JSContext* aCx,
      44             :                        JS::Handle<JSObject*> aObj,
      45             :                        nsAString& aJSON) const;
      46             : 
      47             :   // Struct used as a way to force a dictionary constructor to not init the
      48             :   // dictionary (via constructing from a pointer to this class).  We're putting
      49             :   // it here so that all the dictionaries will have access to it, but outside
      50             :   // code will not.
      51             :   struct FastDictionaryInitializer {
      52             :   };
      53             : 
      54             :   bool mIsAnyMemberPresent = false;
      55             : 
      56             : private:
      57             :   // aString is expected to actually be an nsAString*.  Should only be
      58             :   // called from StringifyToJSON.
      59             :   static bool AppendJSONToString(const char16_t* aJSONData,
      60             :                                  uint32_t aDataLength, void* aString);
      61             : 
      62             : public:
      63           2 :   bool IsAnyMemberPresent() const
      64             :   {
      65           2 :     return mIsAnyMemberPresent;
      66             :   }
      67             : };
      68             : 
      69             : // Struct that serves as a base class for all typed arrays and array buffers and
      70             : // array buffer views.  Particularly useful so we can use IsBaseOf to detect
      71             : // typed array/buffer/view template arguments.
      72           0 : struct AllTypedArraysBase {
      73             : };
      74             : 
      75             : // Struct that serves as a base class for all owning unions.
      76             : // Particularly useful so we can use IsBaseOf to detect owning union
      77             : // template arguments.
      78           2 : struct AllOwningUnionBase {
      79             : };
      80             : 
      81             : 
      82             : struct EnumEntry {
      83             :   const char* value;
      84             :   size_t length;
      85             : };
      86             : 
      87             : enum class CallerType : uint32_t;
      88             : 
      89          19 : class MOZ_STACK_CLASS GlobalObject
      90             : {
      91             : public:
      92             :   GlobalObject(JSContext* aCx, JSObject* aObject);
      93             : 
      94          18 :   JSObject* Get() const
      95             :   {
      96          18 :     return mGlobalJSObject;
      97             :   }
      98             : 
      99             :   nsISupports* GetAsSupports() const;
     100             : 
     101             :   // The context that this returns is not guaranteed to be in the compartment of
     102             :   // the object returned from Get(), in fact it's generally in the caller's
     103             :   // compartment.
     104          23 :   JSContext* Context() const
     105             :   {
     106          23 :     return mCx;
     107             :   }
     108             : 
     109          18 :   bool Failed() const
     110             :   {
     111          18 :     return !Get();
     112             :   }
     113             : 
     114             :   // It returns the subjectPrincipal if called on the main-thread, otherwise
     115             :   // a nullptr is returned.
     116             :   nsIPrincipal* GetSubjectPrincipal() const;
     117             : 
     118             :   // Get the caller type.  Note that this needs to be called before anyone has
     119             :   // had a chance to mess with the JSContext.
     120             :   dom::CallerType CallerType() const;
     121             : 
     122             : protected:
     123             :   JS::Rooted<JSObject*> mGlobalJSObject;
     124             :   JSContext* mCx;
     125             :   mutable nsISupports* MOZ_UNSAFE_REF("Valid because GlobalObject is a stack "
     126             :                                       "class, and mGlobalObject points to the "
     127             :                                       "global, so it won't be destroyed as long "
     128             :                                       "as GlobalObject lives on the stack") mGlobalObject;
     129             : };
     130             : 
     131             : // Class for representing optional arguments.
     132             : template<typename T, typename InternalType>
     133         159 : class Optional_base
     134             : {
     135             : public:
     136         159 :   Optional_base()
     137         159 :   {}
     138             : 
     139           0 :   explicit Optional_base(const T& aValue)
     140           0 :   {
     141           0 :     mImpl.emplace(aValue);
     142           0 :   }
     143             : 
     144             :   bool operator==(const Optional_base<T, InternalType>& aOther) const
     145             :   {
     146             :     return mImpl == aOther.mImpl;
     147             :   }
     148             : 
     149             :   template<typename T1, typename T2>
     150             :   explicit Optional_base(const T1& aValue1, const T2& aValue2)
     151             :   {
     152             :     mImpl.emplace(aValue1, aValue2);
     153             :   }
     154             : 
     155          88 :   bool WasPassed() const
     156             :   {
     157          88 :     return mImpl.isSome();
     158             :   }
     159             : 
     160             :   // Return InternalType here so we can work with it usefully.
     161             :   template<typename... Args>
     162           8 :   InternalType& Construct(Args&&... aArgs)
     163             :   {
     164           8 :     mImpl.emplace(Forward<Args>(aArgs)...);
     165           8 :     return *mImpl;
     166             :   }
     167             : 
     168           1 :   void Reset()
     169             :   {
     170           1 :     mImpl.reset();
     171           1 :   }
     172             : 
     173           2 :   const T& Value() const
     174             :   {
     175           2 :     return *mImpl;
     176             :   }
     177             : 
     178             :   // Return InternalType here so we can work with it usefully.
     179          10 :   InternalType& Value()
     180             :   {
     181          10 :     return *mImpl;
     182             :   }
     183             : 
     184             :   // And an explicit way to get the InternalType even if we're const.
     185           4 :   const InternalType& InternalValue() const
     186             :   {
     187           4 :     return *mImpl;
     188             :   }
     189             : 
     190             :   // If we ever decide to add conversion operators for optional arrays
     191             :   // like the ones Nullable has, we'll need to ensure that Maybe<> has
     192             :   // the boolean before the actual data.
     193             : 
     194             : private:
     195             :   // Forbid copy-construction and assignment
     196             :   Optional_base(const Optional_base& other) = delete;
     197             :   const Optional_base &operator=(const Optional_base &other) = delete;
     198             : 
     199             : protected:
     200             :   Maybe<InternalType> mImpl;
     201             : };
     202             : 
     203             : template<typename T>
     204         157 : class Optional : public Optional_base<T, T>
     205             : {
     206             : public:
     207         157 :   Optional() :
     208         157 :     Optional_base<T, T>()
     209         157 :   {}
     210             : 
     211           0 :   explicit Optional(const T& aValue) :
     212           0 :     Optional_base<T, T>(aValue)
     213           0 :   {}
     214             : };
     215             : 
     216             : template<typename T>
     217           0 : class Optional<JS::Handle<T> > :
     218             :   public Optional_base<JS::Handle<T>, JS::Rooted<T> >
     219             : {
     220             : public:
     221           0 :   Optional() :
     222           0 :     Optional_base<JS::Handle<T>, JS::Rooted<T> >()
     223           0 :   {}
     224             : 
     225             :   explicit Optional(JSContext* cx) :
     226             :     Optional_base<JS::Handle<T>, JS::Rooted<T> >()
     227             :   {
     228             :     this->Construct(cx);
     229             :   }
     230             : 
     231             :   Optional(JSContext* cx, const T& aValue) :
     232             :     Optional_base<JS::Handle<T>, JS::Rooted<T> >(cx, aValue)
     233             :   {}
     234             : 
     235             :   // Override the const Value() to return the right thing so we're not
     236             :   // returning references to temporaries.
     237           0 :   JS::Handle<T> Value() const
     238             :   {
     239           0 :     return *this->mImpl;
     240             :   }
     241             : 
     242             :   // And we have to override the non-const one too, since we're
     243             :   // shadowing the one on the superclass.
     244           0 :   JS::Rooted<T>& Value()
     245             :   {
     246           0 :     return *this->mImpl;
     247             :   }
     248             : };
     249             : 
     250             : // A specialization of Optional for JSObject* to make sure that when someone
     251             : // calls Construct() on it we will pre-initialized the JSObject* to nullptr so
     252             : // it can be traced safely.
     253             : template<>
     254           0 : class Optional<JSObject*> : public Optional_base<JSObject*, JSObject*>
     255             : {
     256             : public:
     257           0 :   Optional() :
     258           0 :     Optional_base<JSObject*, JSObject*>()
     259           0 :   {}
     260             : 
     261             :   explicit Optional(JSObject* aValue) :
     262             :     Optional_base<JSObject*, JSObject*>(aValue)
     263             :   {}
     264             : 
     265             :   // Don't allow us to have an uninitialized JSObject*
     266           0 :   JSObject*& Construct()
     267             :   {
     268             :     // The Android compiler sucks and thinks we're trying to construct
     269             :     // a JSObject* from an int if we don't cast here.  :(
     270             :     return Optional_base<JSObject*, JSObject*>::Construct(
     271           0 :       static_cast<JSObject*>(nullptr));
     272             :   }
     273             : 
     274             :   template <class T1>
     275             :   JSObject*& Construct(const T1& t1)
     276             :   {
     277             :     return Optional_base<JSObject*, JSObject*>::Construct(t1);
     278             :   }
     279             : };
     280             : 
     281             : // A specialization of Optional for JS::Value to make sure no one ever uses it.
     282             : template<>
     283             : class Optional<JS::Value>
     284             : {
     285             : private:
     286             :   Optional() = delete;
     287             : 
     288             :   explicit Optional(const JS::Value& aValue) = delete;
     289             : };
     290             : 
     291             : // A specialization of Optional for NonNull that lets us get a T& from Value()
     292             : template<typename U> class NonNull;
     293             : template<typename T>
     294           0 : class Optional<NonNull<T> > : public Optional_base<T, NonNull<T> >
     295             : {
     296             : public:
     297             :   // We want our Value to actually return a non-const reference, even
     298             :   // if we're const.  At least for things that are normally pointer
     299             :   // types...
     300           0 :   T& Value() const
     301             :   {
     302           0 :     return *this->mImpl->get();
     303             :   }
     304             : 
     305             :   // And we have to override the non-const one too, since we're
     306             :   // shadowing the one on the superclass.
     307           0 :   NonNull<T>& Value()
     308             :   {
     309           0 :     return *this->mImpl;
     310             :   }
     311             : };
     312             : 
     313             : // A specialization of Optional for OwningNonNull that lets us get a
     314             : // T& from Value()
     315             : template<typename T>
     316           4 : class Optional<OwningNonNull<T> > : public Optional_base<T, OwningNonNull<T> >
     317             : {
     318             : public:
     319             :   // We want our Value to actually return a non-const reference, even
     320             :   // if we're const.  At least for things that are normally pointer
     321             :   // types...
     322           0 :   T& Value() const
     323             :   {
     324           0 :     return *this->mImpl->get();
     325             :   }
     326             : 
     327             :   // And we have to override the non-const one too, since we're
     328             :   // shadowing the one on the superclass.
     329           0 :   OwningNonNull<T>& Value()
     330             :   {
     331           0 :     return *this->mImpl;
     332             :   }
     333             : };
     334             : 
     335             : // Specialization for strings.
     336             : // XXXbz we can't pull in FakeString here, because it depends on internal
     337             : // strings.  So we just have to forward-declare it and reimplement its
     338             : // ToAStringPtr.
     339             : 
     340             : namespace binding_detail {
     341             : struct FakeString;
     342             : } // namespace binding_detail
     343             : 
     344             : template<>
     345             : class Optional<nsAString>
     346             : {
     347             : public:
     348          15 :   Optional() : mPassed(false) {}
     349             : 
     350          27 :   bool WasPassed() const
     351             :   {
     352          27 :     return mPassed;
     353             :   }
     354             : 
     355          12 :   void operator=(const nsAString* str)
     356             :   {
     357          12 :     MOZ_ASSERT(str);
     358          12 :     mStr = str;
     359          12 :     mPassed = true;
     360          12 :   }
     361             : 
     362             :   // If this code ever goes away, remove the comment pointing to it in the
     363             :   // FakeString class in BindingUtils.h.
     364           0 :   void operator=(const binding_detail::FakeString* str)
     365             :   {
     366           0 :     MOZ_ASSERT(str);
     367           0 :     mStr = reinterpret_cast<const nsString*>(str);
     368           0 :     mPassed = true;
     369           0 :   }
     370             : 
     371          12 :   const nsAString& Value() const
     372             :   {
     373          12 :     MOZ_ASSERT(WasPassed());
     374          12 :     return *mStr;
     375             :   }
     376             : 
     377             : private:
     378             :   // Forbid copy-construction and assignment
     379             :   Optional(const Optional& other) = delete;
     380             :   const Optional &operator=(const Optional &other) = delete;
     381             : 
     382             :   bool mPassed;
     383             :   const nsAString* mStr;
     384             : };
     385             : 
     386             : template<class T>
     387             : class NonNull
     388             : {
     389             : public:
     390         117 :   NonNull()
     391             : #ifdef DEBUG
     392         117 :     : inited(false)
     393             : #endif
     394         117 :   {}
     395             : 
     396             :   // This is no worse than get() in terms of const handling.
     397         117 :   operator T&() const {
     398         117 :     MOZ_ASSERT(inited);
     399         117 :     MOZ_ASSERT(ptr, "NonNull<T> was set to null");
     400         117 :     return *ptr;
     401             :   }
     402             : 
     403             :   operator T*() const {
     404             :     MOZ_ASSERT(inited);
     405             :     MOZ_ASSERT(ptr, "NonNull<T> was set to null");
     406             :     return ptr;
     407             :   }
     408             : 
     409         117 :   void operator=(T* t) {
     410         117 :     ptr = t;
     411         117 :     MOZ_ASSERT(ptr);
     412             : #ifdef DEBUG
     413         117 :     inited = true;
     414             : #endif
     415         117 :   }
     416             : 
     417             :   template<typename U>
     418             :   void operator=(U* t) {
     419             :     ptr = t->ToAStringPtr();
     420             :     MOZ_ASSERT(ptr);
     421             : #ifdef DEBUG
     422             :     inited = true;
     423             : #endif
     424             :   }
     425             : 
     426             :   T** Slot() {
     427             : #ifdef DEBUG
     428             :     inited = true;
     429             : #endif
     430             :     return &ptr;
     431             :   }
     432             : 
     433             :   T* Ptr() {
     434             :     MOZ_ASSERT(inited);
     435             :     MOZ_ASSERT(ptr, "NonNull<T> was set to null");
     436             :     return ptr;
     437             :   }
     438             : 
     439             :   // Make us work with smart-ptr helpers that expect a get()
     440           0 :   T* get() const {
     441           0 :     MOZ_ASSERT(inited);
     442           0 :     MOZ_ASSERT(ptr);
     443           0 :     return ptr;
     444             :   }
     445             : 
     446             : protected:
     447             :   T* ptr;
     448             : #ifdef DEBUG
     449             :   bool inited;
     450             : #endif
     451             : };
     452             : 
     453             : // Class for representing sequences in arguments.  We use a non-auto array
     454             : // because that allows us to use sequences of sequences and the like.  This
     455             : // needs to be fallible because web content controls the length of the array,
     456             : // and can easily try to create very large lengths.
     457             : template<typename T>
     458           2 : class Sequence : public FallibleTArray<T>
     459             : {
     460             : public:
     461           2 :   Sequence() : FallibleTArray<T>()
     462           2 :   {}
     463             : };
     464             : 
     465             : inline nsWrapperCache*
     466         459 : GetWrapperCache(nsWrapperCache* cache)
     467             : {
     468         459 :   return cache;
     469             : }
     470             : 
     471             : inline nsWrapperCache*
     472        2286 : GetWrapperCache(void* p)
     473             : {
     474        2286 :   return nullptr;
     475             : }
     476             : 
     477             : // Helper template for smart pointers to resolve ambiguity between
     478             : // GetWrappeCache(void*) and GetWrapperCache(const ParentObject&).
     479             : template <template <typename> class SmartPtr, typename T>
     480             : inline nsWrapperCache*
     481           0 : GetWrapperCache(const SmartPtr<T>& aObject)
     482             : {
     483           0 :   return GetWrapperCache(aObject.get());
     484             : }
     485             : 
     486             : struct MOZ_STACK_CLASS ParentObject {
     487             :   template<class T>
     488         400 :   MOZ_IMPLICIT ParentObject(T* aObject) :
     489             :     mObject(aObject),
     490         400 :     mWrapperCache(GetWrapperCache(aObject)),
     491         800 :     mUseXBLScope(false)
     492         400 :   {}
     493             : 
     494             :   template<class T, template<typename> class SmartPtr>
     495           0 :   MOZ_IMPLICIT ParentObject(const SmartPtr<T>& aObject) :
     496             :     mObject(aObject.get()),
     497           0 :     mWrapperCache(GetWrapperCache(aObject.get())),
     498           0 :     mUseXBLScope(false)
     499           0 :   {}
     500             : 
     501           0 :   ParentObject(nsISupports* aObject, nsWrapperCache* aCache) :
     502             :     mObject(aObject),
     503             :     mWrapperCache(aCache),
     504           0 :     mUseXBLScope(false)
     505           0 :   {}
     506             : 
     507             :   // We don't want to make this an nsCOMPtr because of performance reasons, but
     508             :   // it's safe because ParentObject is a stack class.
     509             :   nsISupports* const MOZ_NON_OWNING_REF mObject;
     510             :   nsWrapperCache* const mWrapperCache;
     511             :   bool mUseXBLScope;
     512             : };
     513             : 
     514             : namespace binding_detail {
     515             : 
     516             : // Class for simple sequence arguments, only used internally by codegen.
     517             : template<typename T>
     518          23 : class AutoSequence : public AutoTArray<T, 16>
     519             : {
     520             : public:
     521          25 :   AutoSequence() : AutoTArray<T, 16>()
     522          25 :   {}
     523             : 
     524             :   // Allow converting to const sequences as needed
     525          17 :   operator const Sequence<T>&() const {
     526          17 :     return *reinterpret_cast<const Sequence<T>*>(this);
     527             :   }
     528             : };
     529             : 
     530             : } // namespace binding_detail
     531             : 
     532             : // Enum to represent a system or non-system caller type.
     533             : enum class CallerType : uint32_t {
     534             :   System,
     535             :   NonSystem
     536             : };
     537             : 
     538             : // A class that can be passed (by value or const reference) to indicate that the
     539             : // caller is always a system caller.  This can be used as the type of an
     540             : // argument to force only system callers to call a function.
     541             : class SystemCallerGuarantee {
     542             : public:
     543           0 :   operator CallerType() const { return CallerType::System; }
     544             : };
     545             : 
     546             : } // namespace dom
     547             : } // namespace mozilla
     548             : 
     549             : #endif // mozilla_dom_BindingDeclarations_h__

Generated by: LCOV version 1.13