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"
15 #include "nsISupports.h"
17 #include "nsWrapperCache.h"
22 // If ToJSValue returns false, it must set an exception on the
26 MOZ_WARN_UNUSED_RESULT
bool
27 ToJSValue(JSContext
* aCx
,
28 const nsAString
& aArgument
,
29 JS::MutableHandle
<JS::Value
> aValue
);
32 MOZ_WARN_UNUSED_RESULT
inline bool
33 ToJSValue(JSContext
* aCx
,
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
);
44 // Accept integer types
46 ToJSValue(JSContext
* aCx
,
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
);
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....
66 ToJSValue(JSContext
* aCx
,
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
);
79 ToJSValue(JSContext
* aCx
,
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
));
91 ToJSValue(JSContext
* aCx
,
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
));
102 // accept floating point types
104 ToJSValue(JSContext
* aCx
,
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
);
116 ToJSValue(JSContext
* aCx
,
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
);
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
144 MOZ_WARN_UNUSED_RESULT
145 typename EnableIf
<IsBaseOf
<nsWrapperCache
, T
>::value
, bool>::Type
146 ToJSValue(JSContext
* aCx
,
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
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
);
173 aValue
.setObject(*obj
);
177 // We don't want to include nsContentUtils here, so use a helper
178 // function for the nsISupports case.
179 namespace tojsvalue_detail
{
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.
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
,
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
224 MOZ_WARN_UNUSED_RESULT
225 typename EnableIf
<IsBaseOf
<DictionaryBase
, T
>::value
, bool>::Type
226 ToJSValue(JSContext
* aCx
,
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
,
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
,
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
,
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
)) {
301 for (size_t i
= 0; i
< aLength
; ++i
) {
302 if (!ToJSValue(aCx
, aArguments
[i
], v
[i
])) {
306 JSObject
* arrayObj
= JS_NewArrayObject(aCx
, v
);
310 aValue
.setObject(*arrayObj
);
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
);
344 } // namespace mozilla
346 #endif /* mozilla_dom_ToJSValue_h */