LCOV - code coverage report
Current view: top level - dom/bindings - ToJSValue.h (source / functions) Hit Total Coverage
Test: output.info Lines: 29 78 37.2 %
Date: 2017-07-14 16:53:18 Functions: 12 214 5.6 %
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             : #ifndef mozilla_dom_ToJSValue_h
       8             : #define mozilla_dom_ToJSValue_h
       9             : 
      10             : #include "mozilla/TypeTraits.h"
      11             : #include "mozilla/Assertions.h"
      12             : #include "mozilla/dom/BindingUtils.h"
      13             : #include "mozilla/dom/TypedArray.h"
      14             : #include "jsapi.h"
      15             : #include "nsISupports.h"
      16             : #include "nsTArray.h"
      17             : #include "nsWrapperCache.h"
      18             : 
      19             : namespace mozilla {
      20             : namespace dom {
      21             : 
      22             : class Promise;
      23             : 
      24             : // If ToJSValue returns false, it must set an exception on the
      25             : // JSContext.
      26             : 
      27             : // Accept strings.
      28             : MOZ_MUST_USE bool
      29             : ToJSValue(JSContext* aCx,
      30             :           const nsAString& aArgument,
      31             :           JS::MutableHandle<JS::Value> aValue);
      32             : 
      33             : // Accept booleans.  But be careful here: if we just have a function that takes
      34             : // a boolean argument, then any pointer that doesn't match one of our other
      35             : // signatures/templates will get treated as a boolean, which is clearly not
      36             : // desirable.  So make this a template that only gets used if the argument type
      37             : // is actually boolean
      38             : template<typename T>
      39             : MOZ_MUST_USE
      40             : typename EnableIf<IsSame<T, bool>::value, bool>::Type
      41           0 : ToJSValue(JSContext* aCx,
      42             :           T aArgument,
      43             :           JS::MutableHandle<JS::Value> aValue)
      44             : {
      45             :   // Make sure we're called in a compartment
      46           0 :   MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
      47             : 
      48           0 :   aValue.setBoolean(aArgument);
      49           0 :   return true;
      50             : }
      51             : 
      52             : // Accept integer types
      53             : inline bool
      54           0 : ToJSValue(JSContext* aCx,
      55             :           int32_t aArgument,
      56             :           JS::MutableHandle<JS::Value> aValue)
      57             : {
      58             :   // Make sure we're called in a compartment
      59           0 :   MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
      60             : 
      61           0 :   aValue.setInt32(aArgument);
      62           0 :   return true;
      63             : }
      64             : 
      65             : inline bool
      66           0 : ToJSValue(JSContext* aCx,
      67             :           uint32_t aArgument,
      68             :           JS::MutableHandle<JS::Value> aValue)
      69             : {
      70             :   // Make sure we're called in a compartment
      71           0 :   MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
      72             : 
      73           0 :   aValue.setNumber(aArgument);
      74           0 :   return true;
      75             : }
      76             : 
      77             : inline bool
      78             : ToJSValue(JSContext* aCx,
      79             :           int64_t aArgument,
      80             :           JS::MutableHandle<JS::Value> aValue)
      81             : {
      82             :   // Make sure we're called in a compartment
      83             :   MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
      84             : 
      85             :   aValue.setNumber(double(aArgument));
      86             :   return true;
      87             : }
      88             : 
      89             : inline bool
      90             : ToJSValue(JSContext* aCx,
      91             :           uint64_t aArgument,
      92             :           JS::MutableHandle<JS::Value> aValue)
      93             : {
      94             :   // Make sure we're called in a compartment
      95             :   MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
      96             : 
      97             :   aValue.setNumber(double(aArgument));
      98             :   return true;
      99             : }
     100             : 
     101             : // accept floating point types
     102             : inline bool
     103             : ToJSValue(JSContext* aCx,
     104             :           float aArgument,
     105             :           JS::MutableHandle<JS::Value> aValue)
     106             : {
     107             :   // Make sure we're called in a compartment
     108             :   MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
     109             : 
     110             :   aValue.setNumber(aArgument);
     111             :   return true;
     112             : }
     113             : 
     114             : inline bool
     115           0 : ToJSValue(JSContext* aCx,
     116             :           double aArgument,
     117             :           JS::MutableHandle<JS::Value> aValue)
     118             : {
     119             :   // Make sure we're called in a compartment
     120           0 :   MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
     121             : 
     122           0 :   aValue.setNumber(aArgument);
     123           0 :   return true;
     124             : }
     125             : 
     126             : // Accept CallbackObjects
     127             : MOZ_MUST_USE inline bool
     128             : ToJSValue(JSContext* aCx,
     129             :           CallbackObject& aArgument,
     130             :           JS::MutableHandle<JS::Value> aValue)
     131             : {
     132             :   // Make sure we're called in a compartment
     133             :   MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
     134             : 
     135             :   aValue.setObjectOrNull(aArgument.CallbackOrNull());
     136             : 
     137             :   return MaybeWrapValue(aCx, aValue);
     138             : }
     139             : 
     140             : // Accept objects that inherit from nsWrapperCache (e.g. most
     141             : // DOM objects).
     142             : template <class T>
     143             : MOZ_MUST_USE
     144             : typename EnableIf<IsBaseOf<nsWrapperCache, T>::value, bool>::Type
     145          33 : ToJSValue(JSContext* aCx,
     146             :           T& aArgument,
     147             :           JS::MutableHandle<JS::Value> aValue)
     148             : {
     149             :   // Make sure we're called in a compartment
     150          33 :   MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
     151             :   // Make sure non-webidl objects don't sneak in here
     152          33 :   MOZ_ASSERT(aArgument.IsDOMBinding());
     153             : 
     154          33 :   return GetOrCreateDOMReflector(aCx, aArgument, aValue);
     155             : }
     156             : 
     157             : // Accept typed arrays built from appropriate nsTArray values
     158             : template<typename T>
     159             : MOZ_MUST_USE
     160             : typename EnableIf<IsBaseOf<AllTypedArraysBase, T>::value, bool>::Type
     161           0 : ToJSValue(JSContext* aCx,
     162             :           const TypedArrayCreator<T>& aArgument,
     163             :           JS::MutableHandle<JS::Value> aValue)
     164             : {
     165             :   // Make sure we're called in a compartment
     166           0 :   MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
     167             : 
     168           0 :   JSObject* obj = aArgument.Create(aCx);
     169           0 :   if (!obj) {
     170           0 :     return false;
     171             :   }
     172           0 :   aValue.setObject(*obj);
     173           0 :   return true;
     174             : }
     175             : 
     176             : // Accept objects that inherit from nsISupports but not nsWrapperCache (e.g.
     177             : // DOM File).
     178             : template <class T>
     179             : MOZ_MUST_USE
     180             : typename EnableIf<!IsBaseOf<nsWrapperCache, T>::value &&
     181             :                   !IsBaseOf<CallbackObject, T>::value &&
     182             :                   IsBaseOf<nsISupports, T>::value, bool>::Type
     183          22 : ToJSValue(JSContext* aCx,
     184             :           T& aArgument,
     185             :           JS::MutableHandle<JS::Value> aValue)
     186             : {
     187             :   // Make sure we're called in a compartment
     188          22 :   MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
     189             : 
     190          44 :   qsObjectHelper helper(ToSupports(&aArgument), nullptr);
     191          44 :   JS::Rooted<JSObject*> scope(aCx, JS::CurrentGlobalOrNull(aCx));
     192          44 :   return XPCOMObjectToJsval(aCx, scope, helper, nullptr, true, aValue);
     193             : }
     194             : 
     195             : // Accept nsRefPtr/nsCOMPtr
     196             : template <typename T>
     197             : MOZ_MUST_USE bool
     198           7 : ToJSValue(JSContext* aCx,
     199             :           const nsCOMPtr<T>& aArgument,
     200             :           JS::MutableHandle<JS::Value> aValue)
     201             : {
     202           7 :   return ToJSValue(aCx, *aArgument.get(), aValue);
     203             : }
     204             : 
     205             : template <typename T>
     206             : MOZ_MUST_USE bool
     207           2 : ToJSValue(JSContext* aCx,
     208             :           const RefPtr<T>& aArgument,
     209             :           JS::MutableHandle<JS::Value> aValue)
     210             : {
     211           2 :   return ToJSValue(aCx, *aArgument.get(), aValue);
     212             : }
     213             : 
     214             : template <typename T>
     215             : MOZ_MUST_USE bool
     216           0 : ToJSValue(JSContext* aCx,
     217             :           const NonNull<T>& aArgument,
     218             :           JS::MutableHandle<JS::Value> aValue)
     219             : {
     220           0 :   return ToJSValue(aCx, *aArgument.get(), aValue);
     221             : }
     222             : 
     223             : // Accept WebIDL dictionaries
     224             : template <class T>
     225             : MOZ_MUST_USE
     226             : typename EnableIf<IsBaseOf<DictionaryBase, T>::value, bool>::Type
     227           5 : ToJSValue(JSContext* aCx,
     228             :           const T& aArgument,
     229             :           JS::MutableHandle<JS::Value> aValue)
     230             : {
     231           5 :   return aArgument.ToObjectInternal(aCx, aValue);
     232             : }
     233             : 
     234             : // Accept existing JS values (which may not be same-compartment with us
     235             : MOZ_MUST_USE inline bool
     236           0 : ToJSValue(JSContext* aCx, JS::Handle<JS::Value> aArgument,
     237             :           JS::MutableHandle<JS::Value> aValue)
     238             : {
     239           0 :   aValue.set(aArgument);
     240           0 :   return MaybeWrapValue(aCx, aValue);
     241             : }
     242             : 
     243             : // Accept existing JS values on the Heap (which may not be same-compartment with us
     244             : MOZ_MUST_USE inline bool
     245           0 : ToJSValue(JSContext* aCx, const JS::Heap<JS::Value>& aArgument,
     246             :           JS::MutableHandle<JS::Value> aValue)
     247             : {
     248           0 :   aValue.set(aArgument);
     249           0 :   return MaybeWrapValue(aCx, aValue);
     250             : }
     251             : 
     252             : // Accept existing rooted JS values (which may not be same-compartment with us
     253             : MOZ_MUST_USE inline bool
     254           0 : ToJSValue(JSContext* aCx, const JS::Rooted<JS::Value>& aArgument,
     255             :           JS::MutableHandle<JS::Value> aValue)
     256             : {
     257           0 :   aValue.set(aArgument);
     258           0 :   return MaybeWrapValue(aCx, aValue);
     259             : }
     260             : 
     261             : // Accept existing rooted JS objects (which may not be same-compartment with
     262             : // us).
     263             : MOZ_MUST_USE inline bool
     264           0 : ToJSValue(JSContext* aCx, const JS::Rooted<JSObject*>& aArgument,
     265             :           JS::MutableHandle<JS::Value> aValue)
     266             : {
     267           0 :   aValue.setObjectOrNull(aArgument);
     268           0 :   return MaybeWrapObjectOrNullValue(aCx, aValue);
     269             : }
     270             : 
     271             : // Accept nsresult, for use in rejections, and create an XPCOM
     272             : // exception object representing that nsresult.
     273             : MOZ_MUST_USE bool
     274             : ToJSValue(JSContext* aCx,
     275             :           nsresult aArgument,
     276             :           JS::MutableHandle<JS::Value> aValue);
     277             : 
     278             : // Accept ErrorResult, for use in rejections, and create an exception
     279             : // representing the failure.  Note, the ErrorResult must indicate a failure
     280             : // with aArgument.Failure() returning true.
     281             : MOZ_MUST_USE bool
     282             : ToJSValue(JSContext* aCx,
     283             :           ErrorResult& aArgument,
     284             :           JS::MutableHandle<JS::Value> aValue);
     285             : 
     286             : // Accept owning WebIDL unions.
     287             : template <typename T>
     288             : MOZ_MUST_USE
     289             : typename EnableIf<IsBaseOf<AllOwningUnionBase, T>::value, bool>::Type
     290           0 : ToJSValue(JSContext* aCx,
     291             :           const T& aArgument,
     292             :           JS::MutableHandle<JS::Value> aValue)
     293             : {
     294           0 :   JS::Rooted<JSObject*> global(aCx, JS::CurrentGlobalOrNull(aCx));
     295           0 :   return aArgument.ToJSVal(aCx, global, aValue);
     296             : }
     297             : 
     298             : // Accept pointers to other things we accept
     299             : template <typename T>
     300             : MOZ_MUST_USE
     301             : typename EnableIf<IsPointer<T>::value, bool>::Type
     302          47 : ToJSValue(JSContext* aCx,
     303             :           T aArgument,
     304             :           JS::MutableHandle<JS::Value> aValue)
     305             : {
     306          47 :   return ToJSValue(aCx, *aArgument, aValue);
     307             : }
     308             : 
     309             : // Accept Promise objects, which need special handling.
     310             : MOZ_MUST_USE bool
     311             : ToJSValue(JSContext* aCx,
     312             :           Promise& aArgument,
     313             :           JS::MutableHandle<JS::Value> aValue);
     314             : 
     315             : // Accept arrays of other things we accept
     316             : template <typename T>
     317             : MOZ_MUST_USE bool
     318          46 : ToJSValue(JSContext* aCx,
     319             :           T* aArguments,
     320             :           size_t aLength,
     321             :           JS::MutableHandle<JS::Value> aValue)
     322             : {
     323             :   // Make sure we're called in a compartment
     324          46 :   MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
     325             : 
     326          92 :   JS::AutoValueVector v(aCx);
     327          46 :   if (!v.resize(aLength)) {
     328           0 :     return false;
     329             :   }
     330          46 :   for (size_t i = 0; i < aLength; ++i) {
     331           0 :     if (!ToJSValue(aCx, aArguments[i], v[i])) {
     332           0 :       return false;
     333             :     }
     334             :   }
     335          46 :   JSObject* arrayObj = JS_NewArrayObject(aCx, v);
     336          46 :   if (!arrayObj) {
     337           0 :     return false;
     338             :   }
     339          46 :   aValue.setObject(*arrayObj);
     340          46 :   return true;
     341             : }
     342             : 
     343             : template <typename T>
     344             : MOZ_MUST_USE bool
     345          46 : ToJSValue(JSContext* aCx,
     346             :           const nsTArray<T>& aArgument,
     347             :           JS::MutableHandle<JS::Value> aValue)
     348             : {
     349          46 :   return ToJSValue(aCx, aArgument.Elements(),
     350          46 :                    aArgument.Length(), aValue);
     351             : }
     352             : 
     353             : template <typename T>
     354             : MOZ_MUST_USE bool
     355           0 : ToJSValue(JSContext* aCx,
     356             :           const FallibleTArray<T>& aArgument,
     357             :           JS::MutableHandle<JS::Value> aValue)
     358             : {
     359           0 :   return ToJSValue(aCx, aArgument.Elements(),
     360           0 :                    aArgument.Length(), aValue);
     361             : }
     362             : 
     363             : template <typename T, int N>
     364             : MOZ_MUST_USE bool
     365           0 : ToJSValue(JSContext* aCx,
     366             :           const T(&aArgument)[N],
     367             :           JS::MutableHandle<JS::Value> aValue)
     368             : {
     369           0 :   return ToJSValue(aCx, aArgument, N, aValue);
     370             : }
     371             : 
     372             : } // namespace dom
     373             : } // namespace mozilla
     374             : 
     375             : #endif /* mozilla_dom_ToJSValue_h */

Generated by: LCOV version 1.13