dom/bindings/ToJSValue.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     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 #ifndef mozilla_dom_ToJSValue_h
     8 #define mozilla_dom_ToJSValue_h
    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"
    19 namespace mozilla {
    20 namespace dom {
    22 // If ToJSValue returns false, it must set an exception on the
    23 // JSContext.
    25 // Accept strings.
    26 bool
    27 ToJSValue(JSContext* aCx,
    28           const nsAString& aArgument,
    29           JS::MutableHandle<JS::Value> aValue);
    31 // Accept booleans.
    32 inline bool
    33 ToJSValue(JSContext* aCx,
    34           bool aArgument,
    35           JS::MutableHandle<JS::Value> aValue)
    36 {
    37   // Make sure we're called in a compartment
    38   MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
    40   aValue.setBoolean(aArgument);
    41   return true;
    42 }
    44 // Accept integer types
    45 inline bool
    46 ToJSValue(JSContext* aCx,
    47           int32_t aArgument,
    48           JS::MutableHandle<JS::Value> aValue)
    49 {
    50   // Make sure we're called in a compartment
    51   MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
    53   aValue.setInt32(aArgument);
    54   return true;
    55 }
    57 // The uint32_t version is disabled for now because on the super-old b2g
    58 // compiler nsresult and uint32_t are the same type.  If someone needs this at
    59 // some point we'll need to figure out how to make it work (e.g. by switching to
    60 // traits structs and using the trick IPC's ParamTraits uses, where a traits
    61 // struct templated on the type inherits from a base traits struct of some sort,
    62 // templated on the same type, or something).  Maybe b2g will update to a modern
    63 // compiler before that happens....
    64 #if 0
    65 inline bool
    66 ToJSValue(JSContext* aCx,
    67           uint32_t aArgument,
    68           JS::MutableHandle<JS::Value> aValue)
    69 {
    70   // Make sure we're called in a compartment
    71   MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
    73   aValue.setNumber(aArgument);
    74   return true;
    75 }
    76 #endif
    78 inline bool
    79 ToJSValue(JSContext* aCx,
    80           int64_t aArgument,
    81           JS::MutableHandle<JS::Value> aValue)
    82 {
    83   // Make sure we're called in a compartment
    84   MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
    86   aValue.setNumber(double(aArgument));
    87   return true;
    88 }
    90 inline bool
    91 ToJSValue(JSContext* aCx,
    92           uint64_t aArgument,
    93           JS::MutableHandle<JS::Value> aValue)
    94 {
    95   // Make sure we're called in a compartment
    96   MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
    98   aValue.setNumber(double(aArgument));
    99   return true;
   100 }
   102 // accept floating point types
   103 inline bool
   104 ToJSValue(JSContext* aCx,
   105           float aArgument,
   106           JS::MutableHandle<JS::Value> aValue)
   107 {
   108   // Make sure we're called in a compartment
   109   MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
   111   aValue.setNumber(aArgument);
   112   return true;
   113 }
   115 inline bool
   116 ToJSValue(JSContext* aCx,
   117           double aArgument,
   118           JS::MutableHandle<JS::Value> aValue)
   119 {
   120   // Make sure we're called in a compartment
   121   MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
   123   aValue.setNumber(aArgument);
   124   return true;
   125 }
   127 // Accept objects that inherit from nsWrapperCache and nsISupports (e.g. most
   128 // DOM objects).
   129 template <class T>
   130 typename EnableIf<IsBaseOf<nsWrapperCache, T>::value &&
   131                   IsBaseOf<nsISupports, T>::value, bool>::Type
   132 ToJSValue(JSContext* aCx,
   133           T& aArgument,
   134           JS::MutableHandle<JS::Value> aValue)
   135 {
   136   // Make sure we're called in a compartment
   137   MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
   138   // Make sure non-webidl objects don't sneak in here
   139   MOZ_ASSERT(aArgument.IsDOMBinding());
   141   return WrapNewBindingObject(aCx, aArgument, aValue);
   142 }
   144 // Accept typed arrays built from appropriate nsTArray values
   145 template<typename T>
   146 typename EnableIf<IsBaseOf<AllTypedArraysBase, T>::value, bool>::Type
   147 ToJSValue(JSContext* aCx,
   148           const TypedArrayCreator<T>& aArgument,
   149           JS::MutableHandle<JS::Value> aValue)
   150 {
   151   // Make sure we're called in a compartment
   152   MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
   154   JSObject* obj = aArgument.Create(aCx);
   155   if (!obj) {
   156     return false;
   157   }
   158   aValue.setObject(*obj);
   159   return true;
   160 }
   162 // We don't want to include nsContentUtils here, so use a helper
   163 // function for the nsISupports case.
   164 namespace tojsvalue_detail {
   165 bool
   166 ISupportsToJSValue(JSContext* aCx,
   167                    nsISupports* aArgument,
   168                    JS::MutableHandle<JS::Value> aValue);
   169 } // namespace tojsvalue_detail
   171 // Accept objects that inherit from nsISupports but not nsWrapperCache (e.g.
   172 // nsIDOMFile).
   173 template <class T>
   174 typename EnableIf<!IsBaseOf<nsWrapperCache, T>::value &&
   175                   IsBaseOf<nsISupports, T>::value, bool>::Type
   176 ToJSValue(JSContext* aCx,
   177           T& aArgument,
   178           JS::MutableHandle<JS::Value> aValue)
   179 {
   180   // Make sure we're called in a compartment
   181   MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
   183   return tojsvalue_detail::ISupportsToJSValue(aCx, &aArgument, aValue);
   184 }
   186 // Accept nsRefPtr/nsCOMPtr
   187 template <typename T>
   188 bool
   189 ToJSValue(JSContext* aCx,
   190           const nsCOMPtr<T>& aArgument,
   191           JS::MutableHandle<JS::Value> aValue)
   192 {
   193   return ToJSValue(aCx, *aArgument.get(), aValue);
   194 }
   196 template <typename T>
   197 bool
   198 ToJSValue(JSContext* aCx,
   199           const nsRefPtr<T>& aArgument,
   200           JS::MutableHandle<JS::Value> aValue)
   201 {
   202   return ToJSValue(aCx, *aArgument.get(), aValue);
   203 }
   205 // Accept WebIDL dictionaries
   206 template <class T>
   207 typename EnableIf<IsBaseOf<DictionaryBase, T>::value, bool>::Type
   208 ToJSValue(JSContext* aCx,
   209           const T& aArgument,
   210           JS::MutableHandle<JS::Value> aValue)
   211 {
   212   return aArgument.ToObject(aCx, aValue);
   213 }
   215 // Accept existing JS values (which may not be same-compartment with us
   216 inline bool
   217 ToJSValue(JSContext* aCx, JS::Handle<JS::Value> aArgument,
   218           JS::MutableHandle<JS::Value> aValue)
   219 {
   220   aValue.set(aArgument);
   221   return MaybeWrapValue(aCx, aValue);
   222 }
   224 // Accept nsresult, for use in rejections, and create an XPCOM
   225 // exception object representing that nsresult.
   226 bool
   227 ToJSValue(JSContext* aCx,
   228           nsresult aArgument,
   229           JS::MutableHandle<JS::Value> aValue);
   231 // Accept arrays of other things we accept
   232 template <typename T>
   233 bool
   234 ToJSValue(JSContext* aCx,
   235           T* aArguments,
   236           size_t aLength,
   237           JS::MutableHandle<JS::Value> aValue)
   238 {
   239   // Make sure we're called in a compartment
   240   MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
   242   JS::AutoValueVector v(aCx);
   243   if (!v.resize(aLength)) {
   244     return false;
   245   }
   246   for (size_t i = 0; i < aLength; ++i) {
   247     if (!ToJSValue(aCx, aArguments[i], v.handleAt(i))) {
   248       return false;
   249     }
   250   }
   251   JSObject* arrayObj = JS_NewArrayObject(aCx, v);
   252   if (!arrayObj) {
   253     return false;
   254   }
   255   aValue.setObject(*arrayObj);
   256   return true;
   257 }
   259 template <typename T>
   260 bool
   261 ToJSValue(JSContext* aCx,
   262           const nsTArray<T>& aArgument,
   263           JS::MutableHandle<JS::Value> aValue)
   264 {
   265   return ToJSValue(aCx, aArgument.Elements(),
   266                    aArgument.Length(), aValue);
   267 }
   269 template <typename T>
   270 bool
   271 ToJSValue(JSContext* aCx,
   272           const FallibleTArray<T>& aArgument,
   273           JS::MutableHandle<JS::Value> aValue)
   274 {
   275   return ToJSValue(aCx, aArgument.Elements(),
   276                    aArgument.Length(), aValue);
   277 }
   279 template <typename T, int N>
   280 bool
   281 ToJSValue(JSContext* aCx,
   282           const T(&aArgument)[N],
   283           JS::MutableHandle<JS::Value> aValue)
   284 {
   285   return ToJSValue(aCx, aArgument, N, aValue);
   286 }
   288 } // namespace dom
   289 } // namespace mozilla
   291 #endif /* mozilla_dom_ToJSValue_h */

mercurial