Line data Source code
1 : /* THIS FILE IS AUTOGENERATED FROM MediaList.webidl BY Codegen.py - DO NOT EDIT */
2 :
3 : #include "MediaListBinding.h"
4 : #include "WrapperFactory.h"
5 : #include "mozilla/OwningNonNull.h"
6 : #include "mozilla/dom/BindingUtils.h"
7 : #include "mozilla/dom/DOMJSClass.h"
8 : #include "mozilla/dom/DOMJSProxyHandler.h"
9 : #include "mozilla/dom/MediaList.h"
10 : #include "mozilla/dom/NonRefcountedDOMObject.h"
11 : #include "mozilla/dom/Nullable.h"
12 : #include "mozilla/dom/PrimitiveConversions.h"
13 : #include "mozilla/dom/XrayExpandoClass.h"
14 :
15 : namespace mozilla {
16 : namespace dom {
17 :
18 : namespace MediaListBinding {
19 :
20 : static bool
21 0 : get_mediaText(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::MediaList* self, JSJitGetterCallArgs args)
22 : {
23 0 : DOMString result;
24 0 : self->GetMediaText(result);
25 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
26 0 : if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
27 0 : return false;
28 : }
29 0 : return true;
30 : }
31 :
32 : static bool
33 0 : set_mediaText(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::MediaList* self, JSJitSetterCallArgs args)
34 : {
35 0 : binding_detail::FakeString arg0;
36 0 : if (!ConvertJSValueToString(cx, args[0], eEmpty, eStringify, arg0)) {
37 0 : return false;
38 : }
39 0 : self->SetMediaText(NonNullHelper(Constify(arg0)));
40 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
41 :
42 0 : return true;
43 : }
44 :
45 : static const JSJitInfo mediaText_getterinfo = {
46 : { (JSJitGetterOp)get_mediaText },
47 : { prototypes::id::MediaList },
48 : { PrototypeTraits<prototypes::id::MediaList>::Depth },
49 : JSJitInfo::Getter,
50 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
51 : JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
52 : false, /* isInfallible. False in setters. */
53 : false, /* isMovable. Not relevant for setters. */
54 : false, /* isEliminatable. Not relevant for setters. */
55 : false, /* isAlwaysInSlot. Only relevant for getters. */
56 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
57 : false, /* isTypedMethod. Only relevant for methods. */
58 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
59 : };
60 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
61 : static_assert(0 < 1, "There is no slot for us");
62 : static const JSJitInfo mediaText_setterinfo = {
63 : { (JSJitGetterOp)set_mediaText },
64 : { prototypes::id::MediaList },
65 : { PrototypeTraits<prototypes::id::MediaList>::Depth },
66 : JSJitInfo::Setter,
67 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
68 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
69 : false, /* isInfallible. False in setters. */
70 : false, /* isMovable. Not relevant for setters. */
71 : false, /* isEliminatable. Not relevant for setters. */
72 : false, /* isAlwaysInSlot. Only relevant for getters. */
73 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
74 : false, /* isTypedMethod. Only relevant for methods. */
75 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
76 : };
77 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
78 : static_assert(0 < 1, "There is no slot for us");
79 :
80 : static bool
81 0 : get_length(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::MediaList* self, JSJitGetterCallArgs args)
82 : {
83 0 : uint32_t result(self->Length());
84 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
85 0 : args.rval().setNumber(result);
86 0 : return true;
87 : }
88 :
89 : static const JSJitInfo length_getterinfo = {
90 : { (JSJitGetterOp)get_length },
91 : { prototypes::id::MediaList },
92 : { PrototypeTraits<prototypes::id::MediaList>::Depth },
93 : JSJitInfo::Getter,
94 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
95 : JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
96 : true, /* isInfallible. False in setters. */
97 : false, /* isMovable. Not relevant for setters. */
98 : false, /* isEliminatable. Not relevant for setters. */
99 : false, /* isAlwaysInSlot. Only relevant for getters. */
100 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
101 : false, /* isTypedMethod. Only relevant for methods. */
102 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
103 : };
104 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
105 : static_assert(0 < 1, "There is no slot for us");
106 :
107 : static bool
108 0 : item(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::MediaList* self, const JSJitMethodCallArgs& args)
109 : {
110 0 : if (MOZ_UNLIKELY(args.length() < 1)) {
111 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "MediaList.item");
112 : }
113 : uint32_t arg0;
114 0 : if (!ValueToPrimitive<uint32_t, eDefault>(cx, args[0], &arg0)) {
115 0 : return false;
116 : }
117 0 : DOMString result;
118 0 : self->Item(arg0, result);
119 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
120 0 : if (!xpc::StringToJsval(cx, result, args.rval())) {
121 0 : return false;
122 : }
123 0 : return true;
124 : }
125 :
126 : static const JSJitInfo item_methodinfo = {
127 : { (JSJitGetterOp)item },
128 : { prototypes::id::MediaList },
129 : { PrototypeTraits<prototypes::id::MediaList>::Depth },
130 : JSJitInfo::Method,
131 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
132 : JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */
133 : false, /* isInfallible. False in setters. */
134 : false, /* isMovable. Not relevant for setters. */
135 : false, /* isEliminatable. Not relevant for setters. */
136 : false, /* isAlwaysInSlot. Only relevant for getters. */
137 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
138 : false, /* isTypedMethod. Only relevant for methods. */
139 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
140 : };
141 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
142 : static_assert(0 < 1, "There is no slot for us");
143 :
144 : static bool
145 0 : deleteMedium(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::MediaList* self, const JSJitMethodCallArgs& args)
146 : {
147 0 : if (MOZ_UNLIKELY(args.length() < 1)) {
148 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "MediaList.deleteMedium");
149 : }
150 0 : binding_detail::FakeString arg0;
151 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
152 0 : return false;
153 : }
154 0 : binding_detail::FastErrorResult rv;
155 0 : self->DeleteMedium(NonNullHelper(Constify(arg0)), rv);
156 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
157 0 : return false;
158 : }
159 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
160 0 : args.rval().setUndefined();
161 0 : return true;
162 : }
163 :
164 : static const JSJitInfo deleteMedium_methodinfo = {
165 : { (JSJitGetterOp)deleteMedium },
166 : { prototypes::id::MediaList },
167 : { PrototypeTraits<prototypes::id::MediaList>::Depth },
168 : JSJitInfo::Method,
169 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
170 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
171 : false, /* isInfallible. False in setters. */
172 : false, /* isMovable. Not relevant for setters. */
173 : false, /* isEliminatable. Not relevant for setters. */
174 : false, /* isAlwaysInSlot. Only relevant for getters. */
175 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
176 : false, /* isTypedMethod. Only relevant for methods. */
177 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
178 : };
179 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
180 : static_assert(0 < 1, "There is no slot for us");
181 :
182 : static bool
183 0 : appendMedium(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::MediaList* self, const JSJitMethodCallArgs& args)
184 : {
185 0 : if (MOZ_UNLIKELY(args.length() < 1)) {
186 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "MediaList.appendMedium");
187 : }
188 0 : binding_detail::FakeString arg0;
189 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
190 0 : return false;
191 : }
192 0 : binding_detail::FastErrorResult rv;
193 0 : self->AppendMedium(NonNullHelper(Constify(arg0)), rv);
194 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
195 0 : return false;
196 : }
197 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
198 0 : args.rval().setUndefined();
199 0 : return true;
200 : }
201 :
202 : static const JSJitInfo appendMedium_methodinfo = {
203 : { (JSJitGetterOp)appendMedium },
204 : { prototypes::id::MediaList },
205 : { PrototypeTraits<prototypes::id::MediaList>::Depth },
206 : JSJitInfo::Method,
207 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
208 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
209 : false, /* isInfallible. False in setters. */
210 : false, /* isMovable. Not relevant for setters. */
211 : false, /* isEliminatable. Not relevant for setters. */
212 : false, /* isAlwaysInSlot. Only relevant for getters. */
213 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
214 : false, /* isTypedMethod. Only relevant for methods. */
215 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
216 : };
217 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
218 : static_assert(0 < 1, "There is no slot for us");
219 :
220 : static void
221 0 : _objectMoved(JSObject* obj, const JSObject* old)
222 : {
223 0 : mozilla::dom::MediaList* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::MediaList>(obj);
224 0 : if (self) {
225 0 : UpdateWrapper(self, self, obj, old);
226 : }
227 0 : }
228 :
229 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
230 : #if defined(__clang__)
231 : #pragma clang diagnostic push
232 : #pragma clang diagnostic ignored "-Wmissing-braces"
233 : #endif
234 : static const JSFunctionSpec sMethods_specs[] = {
235 : JS_FNSPEC("item", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&item_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
236 : JS_FNSPEC("deleteMedium", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&deleteMedium_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
237 : JS_FNSPEC("appendMedium", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&appendMedium_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
238 : JS_SYM_FNSPEC(iterator, nullptr, nullptr, 0, 0, "ArrayValues"),
239 : JS_FS_END
240 : };
241 : #if defined(__clang__)
242 : #pragma clang diagnostic pop
243 : #endif
244 :
245 :
246 : // Can't be const because the pref-enabled boolean needs to be writable
247 : static Prefable<const JSFunctionSpec> sMethods[] = {
248 : { nullptr, &sMethods_specs[0] },
249 : { nullptr, nullptr }
250 : };
251 :
252 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
253 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
254 : static_assert(4 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
255 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
256 :
257 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
258 : #if defined(__clang__)
259 : #pragma clang diagnostic push
260 : #pragma clang diagnostic ignored "-Wmissing-braces"
261 : #endif
262 : static const JSPropertySpec sAttributes_specs[] = {
263 : { "mediaText", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &mediaText_getterinfo, GenericBindingSetter, &mediaText_setterinfo },
264 : { "length", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &length_getterinfo, nullptr, nullptr },
265 : { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
266 : };
267 : #if defined(__clang__)
268 : #pragma clang diagnostic pop
269 : #endif
270 :
271 :
272 : // Can't be const because the pref-enabled boolean needs to be writable
273 : static Prefable<const JSPropertySpec> sAttributes[] = {
274 : { nullptr, &sAttributes_specs[0] },
275 : { nullptr, nullptr }
276 : };
277 :
278 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
279 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
280 : static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
281 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
282 :
283 :
284 : static uint16_t sNativeProperties_sortedPropertyIndices[6];
285 : static PropertyInfo sNativeProperties_propertyInfos[6];
286 :
287 : static const NativePropertiesN<2> sNativeProperties = {
288 : false, 0,
289 : false, 0,
290 : true, 0 /* sMethods */,
291 : true, 1 /* sAttributes */,
292 : false, 0,
293 : false, 0,
294 : false, 0,
295 : -1,
296 : 6,
297 : sNativeProperties_sortedPropertyIndices,
298 : {
299 : { sMethods, &sNativeProperties_propertyInfos[0] },
300 : { sAttributes, &sNativeProperties_propertyInfos[4] }
301 : }
302 : };
303 : static_assert(6 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
304 : "We have a property info count that is oversized");
305 :
306 : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
307 : {
308 : "Function",
309 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
310 : &sBoringInterfaceObjectClassClassOps,
311 : JS_NULL_CLASS_SPEC,
312 : JS_NULL_CLASS_EXT,
313 : &sInterfaceObjectClassObjectOps
314 : },
315 : eInterface,
316 : true,
317 : prototypes::id::MediaList,
318 : PrototypeTraits<prototypes::id::MediaList>::Depth,
319 : sNativePropertyHooks,
320 : "function MediaList() {\n [native code]\n}",
321 : JS::GetRealmFunctionPrototype
322 : };
323 :
324 : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
325 : {
326 : "MediaListPrototype",
327 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
328 : JS_NULL_CLASS_OPS,
329 : JS_NULL_CLASS_SPEC,
330 : JS_NULL_CLASS_EXT,
331 : JS_NULL_OBJECT_OPS
332 : },
333 : eInterfacePrototype,
334 : false,
335 : prototypes::id::MediaList,
336 : PrototypeTraits<prototypes::id::MediaList>::Depth,
337 : sNativePropertyHooks,
338 : "[object MediaListPrototype]",
339 : JS::GetRealmArrayPrototype
340 : };
341 :
342 : JSObject*
343 0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
344 : {
345 0 : return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
346 : }
347 :
348 : static_assert(IsBaseOf<nsISupports, mozilla::dom::MediaList >::value,
349 : "We don't support non-nsISupports native classes for "
350 : "proxy-based bindings yet");
351 :
352 :
353 : class DOMProxyHandler : public mozilla::dom::DOMProxyHandler
354 : {
355 : public:
356 : explicit constexpr DOMProxyHandler()
357 : {
358 : }
359 :
360 : virtual bool
361 : getOwnPropDescriptor(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool ignoreNamedProps, JS::MutableHandle<JS::PropertyDescriptor> desc) const override;
362 :
363 : virtual bool
364 : defineProperty(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, JS::Handle<JS::PropertyDescriptor> desc, JS::ObjectOpResult& opresult, bool* defined) const override;
365 :
366 : using mozilla::dom::DOMProxyHandler::defineProperty;
367 :
368 : virtual bool
369 : ownPropNames(JSContext* cx, JS::Handle<JSObject*> proxy, unsigned flags, JS::AutoIdVector& props) const override;
370 :
371 : virtual bool
372 : hasOwn(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool* bp) const override;
373 :
374 : virtual bool
375 : get(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<JS::Value> receiver, JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp) const override;
376 :
377 : virtual const char*
378 : className(JSContext* cx, JS::Handle<JSObject*> proxy) const override;
379 :
380 : virtual bool
381 : finalizeInBackground(const JS::Value& priv) const override;
382 :
383 : virtual void
384 : finalize(JSFreeOp* fop, JSObject* proxy) const override;
385 :
386 : static const DOMProxyHandler*
387 : getInstance();
388 :
389 : virtual bool
390 : delete_(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, JS::ObjectOpResult& opresult) const override;
391 :
392 : virtual bool
393 : getElements(JSContext* cx, JS::Handle<JSObject*> proxy, uint32_t begin, uint32_t end, js::ElementAdder* adder) const override;
394 : };
395 :
396 : MOZ_ALWAYS_INLINE bool
397 0 : IsProxy(JSObject* obj)
398 : {
399 0 : return js::IsProxy(obj) && js::GetProxyHandler(obj) == DOMProxyHandler::getInstance();
400 : }
401 :
402 : MOZ_ALWAYS_INLINE mozilla::dom::MediaList*
403 0 : UnwrapProxy(JSObject* obj)
404 : {
405 0 : MOZ_ASSERT(js::IsProxy(obj));
406 0 : if (js::GetProxyHandler(obj) != DOMProxyHandler::getInstance()) {
407 0 : MOZ_ASSERT(xpc::WrapperFactory::IsXrayWrapper(obj));
408 0 : obj = js::UncheckedUnwrap(obj);
409 : }
410 0 : MOZ_ASSERT(IsProxy(obj));
411 0 : return static_cast<mozilla::dom::MediaList*>(js::GetProxyReservedSlot(obj, DOM_OBJECT_SLOT).toPrivate());
412 : }
413 :
414 : bool
415 0 : DOMProxyHandler::getOwnPropDescriptor(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool ignoreNamedProps, JS::MutableHandle<JS::PropertyDescriptor> desc) const
416 : {
417 0 : bool isXray = xpc::WrapperFactory::IsXrayWrapper(proxy);
418 0 : uint32_t index = GetArrayIndexFromId(cx, id);
419 0 : if (IsArrayIndex(index)) {
420 0 : mozilla::dom::MediaList* self = UnwrapProxy(proxy);
421 0 : bool found = false;
422 0 : DOMString result;
423 0 : self->IndexedGetter(index, found, result);
424 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
425 :
426 0 : if (found) {
427 0 : if (!xpc::StringToJsval(cx, result, desc.value())) {
428 0 : return false;
429 : }
430 0 : FillPropertyDescriptor(desc, proxy, true);
431 0 : return true;
432 : }
433 : }
434 :
435 0 : JS::Rooted<JSObject*> expando(cx);
436 0 : if (!isXray && (expando = GetExpandoObject(proxy))) {
437 0 : if (!JS_GetOwnPropertyDescriptorById(cx, expando, id, desc)) {
438 0 : return false;
439 : }
440 0 : if (desc.object()) {
441 : // Pretend the property lives on the wrapper.
442 0 : desc.object().set(proxy);
443 0 : return true;
444 : }
445 : }
446 :
447 0 : desc.object().set(nullptr);
448 0 : return true;
449 : }
450 :
451 : bool
452 0 : DOMProxyHandler::defineProperty(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, JS::Handle<JS::PropertyDescriptor> desc, JS::ObjectOpResult& opresult, bool* defined) const
453 : {
454 0 : if (IsArrayIndex(GetArrayIndexFromId(cx, id))) {
455 0 : *defined = true;
456 0 : return opresult.failNoIndexedSetter();
457 : }
458 0 : return mozilla::dom::DOMProxyHandler::defineProperty(cx, proxy, id, desc, opresult, defined);
459 : }
460 :
461 :
462 : bool
463 0 : DOMProxyHandler::ownPropNames(JSContext* cx, JS::Handle<JSObject*> proxy, unsigned flags, JS::AutoIdVector& props) const
464 : {
465 0 : bool isXray = xpc::WrapperFactory::IsXrayWrapper(proxy);
466 :
467 0 : uint32_t length = UnwrapProxy(proxy)->Length();
468 0 : MOZ_ASSERT(int32_t(length) >= 0);
469 0 : for (int32_t i = 0; i < int32_t(length); ++i) {
470 0 : if (!props.append(INT_TO_JSID(i))) {
471 0 : return false;
472 : }
473 : }
474 :
475 0 : JS::Rooted<JSObject*> expando(cx);
476 0 : if (!isXray && (expando = DOMProxyHandler::GetExpandoObject(proxy)) &&
477 0 : !js::GetPropertyKeys(cx, expando, flags, &props)) {
478 0 : return false;
479 : }
480 :
481 0 : return true;
482 : }
483 :
484 : bool
485 0 : DOMProxyHandler::hasOwn(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool* bp) const
486 : {
487 0 : MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
488 : "Should not have a XrayWrapper here");
489 :
490 0 : uint32_t index = GetArrayIndexFromId(cx, id);
491 0 : if (IsArrayIndex(index)) {
492 0 : bool found = false;
493 0 : mozilla::dom::MediaList* self = UnwrapProxy(proxy);
494 0 : DOMString result;
495 0 : self->IndexedGetter(index, found, result);
496 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
497 : (void)result;
498 :
499 0 : *bp = found;
500 0 : return true;
501 : }
502 :
503 :
504 0 : JS::Rooted<JSObject*> expando(cx, GetExpandoObject(proxy));
505 0 : if (expando) {
506 0 : bool b = true;
507 0 : bool ok = JS_HasPropertyById(cx, expando, id, &b);
508 0 : *bp = !!b;
509 0 : if (!ok || *bp) {
510 0 : return ok;
511 : }
512 : }
513 :
514 0 : *bp = false;
515 0 : return true;
516 : }
517 :
518 : bool
519 0 : DOMProxyHandler::get(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<JS::Value> receiver, JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp) const
520 : {
521 0 : MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
522 : "Should not have a XrayWrapper here");
523 :
524 0 : uint32_t index = GetArrayIndexFromId(cx, id);
525 0 : if (IsArrayIndex(index)) {
526 0 : mozilla::dom::MediaList* self = UnwrapProxy(proxy);
527 0 : bool found = false;
528 0 : DOMString result;
529 0 : self->IndexedGetter(index, found, result);
530 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
531 :
532 0 : if (found) {
533 0 : if (!xpc::StringToJsval(cx, result, vp)) {
534 0 : return false;
535 : }
536 0 : return true;
537 : }
538 : // Even if we don't have this index, we don't forward the
539 : // get on to our expando object.
540 : } else {
541 : { // Scope for expando
542 0 : JS::Rooted<JSObject*> expando(cx, DOMProxyHandler::GetExpandoObject(proxy));
543 0 : if (expando) {
544 : bool hasProp;
545 0 : if (!JS_HasPropertyById(cx, expando, id, &hasProp)) {
546 0 : return false;
547 : }
548 :
549 0 : if (hasProp) {
550 : // Forward the get to the expando object, but our receiver is whatever our
551 : // receiver is.
552 0 : return JS_ForwardGetPropertyTo(cx, expando, id, receiver, vp);
553 : }
554 : }
555 : }
556 : }
557 :
558 : bool foundOnPrototype;
559 0 : if (!GetPropertyOnPrototype(cx, proxy, receiver, id, &foundOnPrototype, vp)) {
560 0 : return false;
561 : }
562 :
563 0 : if (foundOnPrototype) {
564 0 : return true;
565 : }
566 :
567 0 : vp.setUndefined();
568 0 : return true;
569 : }
570 :
571 : const char*
572 0 : DOMProxyHandler::className(JSContext* cx, JS::Handle<JSObject*> proxy) const
573 : {
574 0 : return "MediaList";
575 : }
576 :
577 : bool
578 0 : DOMProxyHandler::finalizeInBackground(const JS::Value& priv) const
579 : {
580 0 : return false;
581 : }
582 :
583 : void
584 0 : DOMProxyHandler::finalize(JSFreeOp* fop, JSObject* proxy) const
585 : {
586 0 : mozilla::dom::MediaList* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::MediaList>(proxy);
587 0 : if (self) {
588 0 : ClearWrapper(self, self, proxy);
589 0 : AddForDeferredFinalization<mozilla::dom::MediaList>(self);
590 : }
591 0 : }
592 :
593 : const DOMProxyHandler*
594 0 : DOMProxyHandler::getInstance()
595 : {
596 : static const DOMProxyHandler instance;
597 0 : return &instance;
598 : }
599 :
600 : bool
601 0 : DOMProxyHandler::delete_(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, JS::ObjectOpResult& opresult) const
602 : {
603 0 : MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
604 : "Should not have a XrayWrapper here");
605 :
606 0 : uint32_t index = GetArrayIndexFromId(cx, id);
607 0 : if (IsArrayIndex(index)) {
608 : bool deleteSucceeded;
609 0 : bool found = false;
610 0 : mozilla::dom::MediaList* self = UnwrapProxy(proxy);
611 0 : DOMString result;
612 0 : self->IndexedGetter(index, found, result);
613 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
614 : (void)result;
615 0 : deleteSucceeded = !found;
616 0 : return deleteSucceeded ? opresult.succeed() : opresult.failCantDelete();
617 : }
618 :
619 0 : return dom::DOMProxyHandler::delete_(cx, proxy, id, opresult);
620 : }
621 :
622 : bool
623 0 : DOMProxyHandler::getElements(JSContext* cx, JS::Handle<JSObject*> proxy, uint32_t begin, uint32_t end, js::ElementAdder* adder) const
624 : {
625 0 : JS::Rooted<JS::Value> temp(cx);
626 0 : MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
627 : "Should not have a XrayWrapper here");
628 :
629 0 : mozilla::dom::MediaList* self = UnwrapProxy(proxy);
630 0 : uint32_t length = self->Length();
631 : // Compute the end of the indices we'll get ourselves
632 0 : uint32_t ourEnd = std::max(begin, std::min(end, length));
633 :
634 0 : for (uint32_t index = begin; index < ourEnd; ++index) {
635 0 : bool found = false;
636 0 : DOMString result;
637 0 : self->IndexedGetter(index, found, result);
638 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
639 :
640 0 : MOZ_ASSERT(found);
641 0 : if (!xpc::StringToJsval(cx, result, &temp)) {
642 0 : return false;
643 : }
644 0 : if (!adder->append(cx, temp)) return false;
645 0 : continue;
646 : }
647 :
648 0 : if (end > ourEnd) {
649 0 : JS::Rooted<JSObject*> proto(cx);
650 0 : if (!js::GetObjectProto(cx, proxy, &proto)) {
651 0 : return false;
652 : }
653 0 : return js::GetElementsWithAdder(cx, proto, proxy, ourEnd, end, adder);
654 : }
655 :
656 0 : return true;
657 : }
658 :
659 : static const js::ClassExtension sClassExtension = PROXY_MAKE_EXT(
660 : _objectMoved
661 : );
662 :
663 : static const DOMJSClass sClass = {
664 : PROXY_CLASS_WITH_EXT("MediaList",
665 : JSCLASS_IS_DOMJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(1),
666 : &sClassExtension),
667 : { prototypes::id::MediaList, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
668 : IsBaseOf<nsISupports, mozilla::dom::MediaList >::value,
669 : sNativePropertyHooks,
670 : FindAssociatedGlobalForNative<mozilla::dom::MediaList>::Get,
671 : GetProtoObjectHandle,
672 : GetCCParticipant<mozilla::dom::MediaList>::Get()
673 : };
674 :
675 : bool
676 0 : Wrap(JSContext* aCx, mozilla::dom::MediaList* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
677 : {
678 : MOZ_ASSERT(static_cast<mozilla::dom::MediaList*>(aObject) ==
679 : reinterpret_cast<mozilla::dom::MediaList*>(aObject),
680 : "Multiple inheritance for mozilla::dom::MediaList is broken.");
681 0 : MOZ_ASSERT(ToSupportsIsCorrect(aObject));
682 0 : MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
683 0 : MOZ_ASSERT(!aCache->GetWrapper(),
684 : "You should probably not be using Wrap() directly; use "
685 : "GetOrCreateDOMReflector instead");
686 :
687 0 : MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
688 : "nsISupports must be on our primary inheritance chain");
689 :
690 0 : JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
691 0 : if (!global) {
692 0 : return false;
693 : }
694 0 : MOZ_ASSERT(JS_IsGlobalObject(global));
695 0 : MOZ_ASSERT(JS::ObjectIsNotGray(global));
696 :
697 : // That might have ended up wrapping us already, due to the wonders
698 : // of XBL. Check for that, and bail out as needed.
699 0 : aReflector.set(aCache->GetWrapper());
700 0 : if (aReflector) {
701 : #ifdef DEBUG
702 0 : binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
703 : #endif // DEBUG
704 0 : return true;
705 : }
706 :
707 0 : JSAutoCompartment ac(aCx, global);
708 0 : JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
709 0 : if (!canonicalProto) {
710 0 : return false;
711 : }
712 0 : JS::Rooted<JSObject*> proto(aCx);
713 0 : if (aGivenProto) {
714 0 : proto = aGivenProto;
715 : // Unfortunately, while aGivenProto was in the compartment of aCx
716 : // coming in, we changed compartments to that of "parent" so may need
717 : // to wrap the proto here.
718 0 : if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
719 0 : if (!JS_WrapObject(aCx, &proto)) {
720 0 : return false;
721 : }
722 : }
723 : } else {
724 0 : proto = canonicalProto;
725 : }
726 :
727 0 : BindingJSObjectCreator<mozilla::dom::MediaList> creator(aCx);
728 0 : JS::Rooted<JS::Value> expandoValue(aCx, JS::UndefinedValue());
729 0 : creator.CreateProxyObject(aCx, &sClass.mBase, DOMProxyHandler::getInstance(),
730 0 : proto, aObject, expandoValue, aReflector);
731 0 : if (!aReflector) {
732 0 : return false;
733 : }
734 :
735 :
736 0 : aCache->SetWrapper(aReflector);
737 0 : creator.InitializationSucceeded();
738 :
739 0 : MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
740 : aCache->GetWrapperPreserveColor() == aReflector);
741 : // If proto != canonicalProto, we have to preserve our wrapper;
742 : // otherwise we won't be able to properly recreate it later, since
743 : // we won't know what proto to use. Note that we don't check
744 : // aGivenProto here, since it's entirely possible (and even
745 : // somewhat common) to have a non-null aGivenProto which is the
746 : // same as canonicalProto.
747 0 : if (proto != canonicalProto) {
748 0 : PreserveWrapper(aObject);
749 : }
750 :
751 0 : return true;
752 : }
753 :
754 : static bool
755 0 : ResolveOwnProperty(JSContext* cx, JS::Handle<JSObject*> wrapper, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::MutableHandle<JS::PropertyDescriptor> desc)
756 : {
757 0 : return js::GetProxyHandler(obj)->getOwnPropertyDescriptor(cx, wrapper, id, desc);
758 : }
759 :
760 : static bool
761 0 : EnumerateOwnProperties(JSContext* cx, JS::Handle<JSObject*> wrapper, JS::Handle<JSObject*> obj, JS::AutoIdVector& props)
762 : {
763 0 : return js::GetProxyHandler(obj)->ownPropertyKeys(cx, wrapper, props);
764 : }
765 :
766 : const NativePropertyHooks sNativePropertyHooks[] = { {
767 : ResolveOwnProperty,
768 : EnumerateOwnProperties,
769 : nullptr,
770 : { sNativeProperties.Upcast(), nullptr },
771 : prototypes::id::MediaList,
772 : constructors::id::MediaList,
773 : nullptr,
774 : &DefaultXrayExpandoObjectClass
775 : } };
776 :
777 : void
778 0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
779 : {
780 0 : JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmArrayPrototype(aCx));
781 0 : if (!parentProto) {
782 0 : return;
783 : }
784 :
785 0 : JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
786 0 : if (!constructorProto) {
787 0 : return;
788 : }
789 :
790 : static bool sIdsInited = false;
791 0 : if (!sIdsInited && NS_IsMainThread()) {
792 0 : if (!InitIds(aCx, sNativeProperties.Upcast())) {
793 0 : return;
794 : }
795 0 : sIdsInited = true;
796 : }
797 :
798 0 : JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::MediaList);
799 0 : JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::MediaList);
800 0 : dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
801 : &sPrototypeClass.mBase, protoCache,
802 : constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
803 : interfaceCache,
804 : sNativeProperties.Upcast(),
805 : nullptr,
806 : "MediaList", aDefineOnGlobal,
807 : nullptr,
808 0 : false);
809 : }
810 :
811 : JS::Handle<JSObject*>
812 0 : GetProtoObjectHandle(JSContext* aCx)
813 : {
814 : /* Get the interface prototype object for this class. This will create the
815 : object as needed. */
816 0 : bool aDefineOnGlobal = true;
817 :
818 : /* Make sure our global is sane. Hopefully we can remove this sometime */
819 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
820 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
821 0 : return nullptr;
822 : }
823 :
824 : /* Check to see whether the interface objects are already installed */
825 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
826 0 : if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::MediaList)) {
827 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
828 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
829 : }
830 :
831 : /*
832 : * The object might _still_ be null, but that's OK.
833 : *
834 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
835 : * traced by TraceProtoAndIfaceCache() and its contents are never
836 : * changed after they have been set.
837 : *
838 : * Calling address() avoids the read read barrier that does gray
839 : * unmarking, but it's not possible for the object to be gray here.
840 : */
841 :
842 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::MediaList);
843 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
844 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
845 : }
846 :
847 : JS::Handle<JSObject*>
848 0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
849 : {
850 : /* Get the interface object for this class. This will create the object as
851 : needed. */
852 :
853 : /* Make sure our global is sane. Hopefully we can remove this sometime */
854 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
855 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
856 0 : return nullptr;
857 : }
858 :
859 : /* Check to see whether the interface objects are already installed */
860 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
861 0 : if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::MediaList)) {
862 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
863 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
864 : }
865 :
866 : /*
867 : * The object might _still_ be null, but that's OK.
868 : *
869 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
870 : * traced by TraceProtoAndIfaceCache() and its contents are never
871 : * changed after they have been set.
872 : *
873 : * Calling address() avoids the read read barrier that does gray
874 : * unmarking, but it's not possible for the object to be gray here.
875 : */
876 :
877 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::MediaList);
878 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
879 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
880 : }
881 :
882 : JSObject*
883 0 : GetConstructorObject(JSContext* aCx)
884 : {
885 0 : return GetConstructorObjectHandle(aCx);
886 : }
887 :
888 : } // namespace MediaListBinding
889 :
890 :
891 :
892 : } // namespace dom
893 : } // namespace mozilla
|