Bumping manifests a=b2g-bump
[gecko.git] / dom / bindings / ToJSValue.h
blob0b82bb2fc7455c639085d443148a40b8fa0a4715
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 MOZ_WARN_UNUSED_RESULT bool
27 ToJSValue(JSContext* aCx,
28 const nsAString& aArgument,
29 JS::MutableHandle<JS::Value> aValue);
31 // Accept booleans.
32 MOZ_WARN_UNUSED_RESULT inline bool
33 ToJSValue(JSContext* aCx,
34 bool aArgument,
35 JS::MutableHandle<JS::Value> aValue)
37 // Make sure we're called in a compartment
38 MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
40 aValue.setBoolean(aArgument);
41 return true;
44 // Accept integer types
45 inline bool
46 ToJSValue(JSContext* aCx,
47 int32_t aArgument,
48 JS::MutableHandle<JS::Value> aValue)
50 // Make sure we're called in a compartment
51 MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
53 aValue.setInt32(aArgument);
54 return true;
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)
70 // Make sure we're called in a compartment
71 MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
73 aValue.setNumber(aArgument);
74 return true;
76 #endif
78 inline bool
79 ToJSValue(JSContext* aCx,
80 int64_t aArgument,
81 JS::MutableHandle<JS::Value> aValue)
83 // Make sure we're called in a compartment
84 MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
86 aValue.setNumber(double(aArgument));
87 return true;
90 inline bool
91 ToJSValue(JSContext* aCx,
92 uint64_t aArgument,
93 JS::MutableHandle<JS::Value> aValue)
95 // Make sure we're called in a compartment
96 MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
98 aValue.setNumber(double(aArgument));
99 return true;
102 // accept floating point types
103 inline bool
104 ToJSValue(JSContext* aCx,
105 float aArgument,
106 JS::MutableHandle<JS::Value> aValue)
108 // Make sure we're called in a compartment
109 MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
111 aValue.setNumber(aArgument);
112 return true;
115 inline bool
116 ToJSValue(JSContext* aCx,
117 double aArgument,
118 JS::MutableHandle<JS::Value> aValue)
120 // Make sure we're called in a compartment
121 MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
123 aValue.setNumber(aArgument);
124 return true;
127 // Accept CallbackObjects
128 MOZ_WARN_UNUSED_RESULT inline bool
129 ToJSValue(JSContext* aCx,
130 CallbackObject& aArgument,
131 JS::MutableHandle<JS::Value> aValue)
133 // Make sure we're called in a compartment
134 MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
136 aValue.setObject(*aArgument.Callback());
138 return MaybeWrapValue(aCx, aValue);
141 // Accept objects that inherit from nsWrapperCache (e.g. most
142 // DOM objects).
143 template <class T>
144 MOZ_WARN_UNUSED_RESULT
145 typename EnableIf<IsBaseOf<nsWrapperCache, T>::value, bool>::Type
146 ToJSValue(JSContext* aCx,
147 T& aArgument,
148 JS::MutableHandle<JS::Value> aValue)
150 // Make sure we're called in a compartment
151 MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
152 // Make sure non-webidl objects don't sneak in here
153 MOZ_ASSERT(aArgument.IsDOMBinding());
155 return GetOrCreateDOMReflector(aCx, aArgument, aValue);
158 // Accept typed arrays built from appropriate nsTArray values
159 template<typename T>
160 MOZ_WARN_UNUSED_RESULT
161 typename EnableIf<IsBaseOf<AllTypedArraysBase, T>::value, bool>::Type
162 ToJSValue(JSContext* aCx,
163 const TypedArrayCreator<T>& aArgument,
164 JS::MutableHandle<JS::Value> aValue)
166 // Make sure we're called in a compartment
167 MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
169 JSObject* obj = aArgument.Create(aCx);
170 if (!obj) {
171 return false;
173 aValue.setObject(*obj);
174 return true;
177 // We don't want to include nsContentUtils here, so use a helper
178 // function for the nsISupports case.
179 namespace tojsvalue_detail {
180 bool
181 ISupportsToJSValue(JSContext* aCx,
182 nsISupports* aArgument,
183 JS::MutableHandle<JS::Value> aValue);
184 } // namespace tojsvalue_detail
186 // Accept objects that inherit from nsISupports but not nsWrapperCache (e.g.
187 // nsIDOMFile).
188 template <class T>
189 MOZ_WARN_UNUSED_RESULT
190 typename EnableIf<!IsBaseOf<nsWrapperCache, T>::value &&
191 !IsBaseOf<CallbackObject, T>::value &&
192 IsBaseOf<nsISupports, T>::value, bool>::Type
193 ToJSValue(JSContext* aCx,
194 T& aArgument,
195 JS::MutableHandle<JS::Value> aValue)
197 // Make sure we're called in a compartment
198 MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
200 return tojsvalue_detail::ISupportsToJSValue(aCx, &aArgument, aValue);
203 // Accept nsRefPtr/nsCOMPtr
204 template <typename T>
205 MOZ_WARN_UNUSED_RESULT bool
206 ToJSValue(JSContext* aCx,
207 const nsCOMPtr<T>& aArgument,
208 JS::MutableHandle<JS::Value> aValue)
210 return ToJSValue(aCx, *aArgument.get(), aValue);
213 template <typename T>
214 MOZ_WARN_UNUSED_RESULT bool
215 ToJSValue(JSContext* aCx,
216 const nsRefPtr<T>& aArgument,
217 JS::MutableHandle<JS::Value> aValue)
219 return ToJSValue(aCx, *aArgument.get(), aValue);
222 // Accept WebIDL dictionaries
223 template <class T>
224 MOZ_WARN_UNUSED_RESULT
225 typename EnableIf<IsBaseOf<DictionaryBase, T>::value, bool>::Type
226 ToJSValue(JSContext* aCx,
227 const T& aArgument,
228 JS::MutableHandle<JS::Value> aValue)
230 return aArgument.ToObjectInternal(aCx, aValue);
233 // Accept existing JS values (which may not be same-compartment with us
234 MOZ_WARN_UNUSED_RESULT inline bool
235 ToJSValue(JSContext* aCx, JS::Handle<JS::Value> aArgument,
236 JS::MutableHandle<JS::Value> aValue)
238 aValue.set(aArgument);
239 return MaybeWrapValue(aCx, aValue);
242 // Accept existing JS values on the Heap (which may not be same-compartment with us
243 MOZ_WARN_UNUSED_RESULT inline bool
244 ToJSValue(JSContext* aCx, const JS::Heap<JS::Value>& aArgument,
245 JS::MutableHandle<JS::Value> aValue)
247 aValue.set(aArgument);
248 return MaybeWrapValue(aCx, aValue);
251 // Accept existing rooted JS values (which may not be same-compartment with us
252 MOZ_WARN_UNUSED_RESULT inline bool
253 ToJSValue(JSContext* aCx, const JS::Rooted<JS::Value>& aArgument,
254 JS::MutableHandle<JS::Value> aValue)
256 aValue.set(aArgument);
257 return MaybeWrapValue(aCx, aValue);
260 // Accept nsresult, for use in rejections, and create an XPCOM
261 // exception object representing that nsresult.
262 MOZ_WARN_UNUSED_RESULT bool
263 ToJSValue(JSContext* aCx,
264 nsresult aArgument,
265 JS::MutableHandle<JS::Value> aValue);
267 // Accept ErrorResult, for use in rejections, and create an exception
268 // representing the failure. Note, the ErrorResult must indicate a failure
269 // with aArgument.Failure() returning true.
270 MOZ_WARN_UNUSED_RESULT bool
271 ToJSValue(JSContext* aCx,
272 ErrorResult& aArgument,
273 JS::MutableHandle<JS::Value> aValue);
275 // Accept pointers to other things we accept
276 template <typename T>
277 MOZ_WARN_UNUSED_RESULT
278 typename EnableIf<IsPointer<T>::value, bool>::Type
279 ToJSValue(JSContext* aCx,
280 T aArgument,
281 JS::MutableHandle<JS::Value> aValue)
283 return ToJSValue(aCx, *aArgument, aValue);
286 // Accept arrays of other things we accept
287 template <typename T>
288 MOZ_WARN_UNUSED_RESULT bool
289 ToJSValue(JSContext* aCx,
290 T* aArguments,
291 size_t aLength,
292 JS::MutableHandle<JS::Value> aValue)
294 // Make sure we're called in a compartment
295 MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
297 JS::AutoValueVector v(aCx);
298 if (!v.resize(aLength)) {
299 return false;
301 for (size_t i = 0; i < aLength; ++i) {
302 if (!ToJSValue(aCx, aArguments[i], v[i])) {
303 return false;
306 JSObject* arrayObj = JS_NewArrayObject(aCx, v);
307 if (!arrayObj) {
308 return false;
310 aValue.setObject(*arrayObj);
311 return true;
314 template <typename T>
315 MOZ_WARN_UNUSED_RESULT bool
316 ToJSValue(JSContext* aCx,
317 const nsTArray<T>& aArgument,
318 JS::MutableHandle<JS::Value> aValue)
320 return ToJSValue(aCx, aArgument.Elements(),
321 aArgument.Length(), aValue);
324 template <typename T>
325 MOZ_WARN_UNUSED_RESULT bool
326 ToJSValue(JSContext* aCx,
327 const FallibleTArray<T>& aArgument,
328 JS::MutableHandle<JS::Value> aValue)
330 return ToJSValue(aCx, aArgument.Elements(),
331 aArgument.Length(), aValue);
334 template <typename T, int N>
335 MOZ_WARN_UNUSED_RESULT bool
336 ToJSValue(JSContext* aCx,
337 const T(&aArgument)[N],
338 JS::MutableHandle<JS::Value> aValue)
340 return ToJSValue(aCx, aArgument, N, aValue);
343 } // namespace dom
344 } // namespace mozilla
346 #endif /* mozilla_dom_ToJSValue_h */