Line data Source code
1 : /* THIS FILE IS AUTOGENERATED FROM HTMLSourceElement.webidl BY Codegen.py - DO NOT EDIT */
2 :
3 : #include "HTMLElementBinding.h"
4 : #include "HTMLSourceElementBinding.h"
5 : #include "WrapperFactory.h"
6 : #include "mozilla/OwningNonNull.h"
7 : #include "mozilla/dom/BindingUtils.h"
8 : #include "mozilla/dom/CustomElementRegistry.h"
9 : #include "mozilla/dom/DOMJSClass.h"
10 : #include "mozilla/dom/HTMLSourceElement.h"
11 : #include "mozilla/dom/NonRefcountedDOMObject.h"
12 : #include "mozilla/dom/XrayExpandoClass.h"
13 :
14 : namespace mozilla {
15 : namespace dom {
16 :
17 : namespace HTMLSourceElementBinding {
18 :
19 : static_assert(IsRefcounted<NativeType>::value == IsRefcounted<HTMLElementBinding::NativeType>::value,
20 : "Can't inherit from an interface with a different ownership model.");
21 :
22 : static bool
23 0 : get_src(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::HTMLSourceElement* self, JSJitGetterCallArgs args)
24 : {
25 0 : DOMString result;
26 0 : self->GetSrc(result);
27 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
28 0 : if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
29 0 : return false;
30 : }
31 0 : return true;
32 : }
33 :
34 : static bool
35 0 : set_src(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::HTMLSourceElement* self, JSJitSetterCallArgs args)
36 : {
37 0 : binding_detail::FakeString arg0;
38 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
39 0 : return false;
40 : }
41 0 : CustomElementReactionsStack* reactionsStack = GetCustomElementReactionsStack(obj);
42 0 : Maybe<AutoCEReaction> ceReaction;
43 0 : if (reactionsStack) {
44 0 : ceReaction.emplace(reactionsStack);
45 : }
46 0 : binding_detail::FastErrorResult rv;
47 0 : self->SetSrc(NonNullHelper(Constify(arg0)), rv);
48 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
49 0 : return false;
50 : }
51 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
52 :
53 0 : return true;
54 : }
55 :
56 : static const JSJitInfo src_getterinfo = {
57 : { (JSJitGetterOp)get_src },
58 : { prototypes::id::HTMLSourceElement },
59 : { PrototypeTraits<prototypes::id::HTMLSourceElement>::Depth },
60 : JSJitInfo::Getter,
61 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
62 : JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
63 : false, /* isInfallible. False in setters. */
64 : false, /* isMovable. Not relevant for setters. */
65 : false, /* isEliminatable. Not relevant for setters. */
66 : false, /* isAlwaysInSlot. Only relevant for getters. */
67 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
68 : false, /* isTypedMethod. Only relevant for methods. */
69 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
70 : };
71 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
72 : static_assert(0 < 1, "There is no slot for us");
73 : static const JSJitInfo src_setterinfo = {
74 : { (JSJitGetterOp)set_src },
75 : { prototypes::id::HTMLSourceElement },
76 : { PrototypeTraits<prototypes::id::HTMLSourceElement>::Depth },
77 : JSJitInfo::Setter,
78 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
79 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
80 : false, /* isInfallible. False in setters. */
81 : false, /* isMovable. Not relevant for setters. */
82 : false, /* isEliminatable. Not relevant for setters. */
83 : false, /* isAlwaysInSlot. Only relevant for getters. */
84 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
85 : false, /* isTypedMethod. Only relevant for methods. */
86 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
87 : };
88 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
89 : static_assert(0 < 1, "There is no slot for us");
90 :
91 : static bool
92 0 : get_type(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::HTMLSourceElement* self, JSJitGetterCallArgs args)
93 : {
94 0 : DOMString result;
95 0 : self->GetType(result);
96 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
97 0 : if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
98 0 : return false;
99 : }
100 0 : return true;
101 : }
102 :
103 : static bool
104 0 : set_type(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::HTMLSourceElement* self, JSJitSetterCallArgs args)
105 : {
106 0 : binding_detail::FakeString arg0;
107 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
108 0 : return false;
109 : }
110 0 : CustomElementReactionsStack* reactionsStack = GetCustomElementReactionsStack(obj);
111 0 : Maybe<AutoCEReaction> ceReaction;
112 0 : if (reactionsStack) {
113 0 : ceReaction.emplace(reactionsStack);
114 : }
115 0 : binding_detail::FastErrorResult rv;
116 0 : self->SetType(NonNullHelper(Constify(arg0)), rv);
117 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
118 0 : return false;
119 : }
120 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
121 :
122 0 : return true;
123 : }
124 :
125 : static const JSJitInfo type_getterinfo = {
126 : { (JSJitGetterOp)get_type },
127 : { prototypes::id::HTMLSourceElement },
128 : { PrototypeTraits<prototypes::id::HTMLSourceElement>::Depth },
129 : JSJitInfo::Getter,
130 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
131 : JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
132 : false, /* isInfallible. False in setters. */
133 : false, /* isMovable. Not relevant for setters. */
134 : false, /* isEliminatable. Not relevant for setters. */
135 : false, /* isAlwaysInSlot. Only relevant for getters. */
136 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
137 : false, /* isTypedMethod. Only relevant for methods. */
138 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
139 : };
140 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
141 : static_assert(0 < 1, "There is no slot for us");
142 : static const JSJitInfo type_setterinfo = {
143 : { (JSJitGetterOp)set_type },
144 : { prototypes::id::HTMLSourceElement },
145 : { PrototypeTraits<prototypes::id::HTMLSourceElement>::Depth },
146 : JSJitInfo::Setter,
147 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
148 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
149 : false, /* isInfallible. False in setters. */
150 : false, /* isMovable. Not relevant for setters. */
151 : false, /* isEliminatable. Not relevant for setters. */
152 : false, /* isAlwaysInSlot. Only relevant for getters. */
153 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
154 : false, /* isTypedMethod. Only relevant for methods. */
155 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
156 : };
157 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
158 : static_assert(0 < 1, "There is no slot for us");
159 :
160 : static bool
161 0 : get_srcset(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::HTMLSourceElement* self, JSJitGetterCallArgs args)
162 : {
163 0 : DOMString result;
164 0 : self->GetSrcset(result);
165 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
166 0 : if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
167 0 : return false;
168 : }
169 0 : return true;
170 : }
171 :
172 : static bool
173 0 : set_srcset(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::HTMLSourceElement* self, JSJitSetterCallArgs args)
174 : {
175 0 : binding_detail::FakeString arg0;
176 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
177 0 : return false;
178 : }
179 0 : CustomElementReactionsStack* reactionsStack = GetCustomElementReactionsStack(obj);
180 0 : Maybe<AutoCEReaction> ceReaction;
181 0 : if (reactionsStack) {
182 0 : ceReaction.emplace(reactionsStack);
183 : }
184 0 : binding_detail::FastErrorResult rv;
185 0 : self->SetSrcset(NonNullHelper(Constify(arg0)), rv);
186 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
187 0 : return false;
188 : }
189 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
190 :
191 0 : return true;
192 : }
193 :
194 : static const JSJitInfo srcset_getterinfo = {
195 : { (JSJitGetterOp)get_srcset },
196 : { prototypes::id::HTMLSourceElement },
197 : { PrototypeTraits<prototypes::id::HTMLSourceElement>::Depth },
198 : JSJitInfo::Getter,
199 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
200 : JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
201 : false, /* isInfallible. False in setters. */
202 : false, /* isMovable. Not relevant for setters. */
203 : false, /* isEliminatable. Not relevant for setters. */
204 : false, /* isAlwaysInSlot. Only relevant for getters. */
205 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
206 : false, /* isTypedMethod. Only relevant for methods. */
207 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
208 : };
209 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
210 : static_assert(0 < 1, "There is no slot for us");
211 : static const JSJitInfo srcset_setterinfo = {
212 : { (JSJitGetterOp)set_srcset },
213 : { prototypes::id::HTMLSourceElement },
214 : { PrototypeTraits<prototypes::id::HTMLSourceElement>::Depth },
215 : JSJitInfo::Setter,
216 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
217 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
218 : false, /* isInfallible. False in setters. */
219 : false, /* isMovable. Not relevant for setters. */
220 : false, /* isEliminatable. Not relevant for setters. */
221 : false, /* isAlwaysInSlot. Only relevant for getters. */
222 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
223 : false, /* isTypedMethod. Only relevant for methods. */
224 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
225 : };
226 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
227 : static_assert(0 < 1, "There is no slot for us");
228 :
229 : static bool
230 0 : get_sizes(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::HTMLSourceElement* self, JSJitGetterCallArgs args)
231 : {
232 0 : DOMString result;
233 0 : self->GetSizes(result);
234 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
235 0 : if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
236 0 : return false;
237 : }
238 0 : return true;
239 : }
240 :
241 : static bool
242 0 : set_sizes(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::HTMLSourceElement* self, JSJitSetterCallArgs args)
243 : {
244 0 : binding_detail::FakeString arg0;
245 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
246 0 : return false;
247 : }
248 0 : CustomElementReactionsStack* reactionsStack = GetCustomElementReactionsStack(obj);
249 0 : Maybe<AutoCEReaction> ceReaction;
250 0 : if (reactionsStack) {
251 0 : ceReaction.emplace(reactionsStack);
252 : }
253 0 : binding_detail::FastErrorResult rv;
254 0 : self->SetSizes(NonNullHelper(Constify(arg0)), rv);
255 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
256 0 : return false;
257 : }
258 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
259 :
260 0 : return true;
261 : }
262 :
263 : static const JSJitInfo sizes_getterinfo = {
264 : { (JSJitGetterOp)get_sizes },
265 : { prototypes::id::HTMLSourceElement },
266 : { PrototypeTraits<prototypes::id::HTMLSourceElement>::Depth },
267 : JSJitInfo::Getter,
268 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
269 : JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
270 : false, /* isInfallible. False in setters. */
271 : false, /* isMovable. Not relevant for setters. */
272 : false, /* isEliminatable. Not relevant for setters. */
273 : false, /* isAlwaysInSlot. Only relevant for getters. */
274 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
275 : false, /* isTypedMethod. Only relevant for methods. */
276 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
277 : };
278 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
279 : static_assert(0 < 1, "There is no slot for us");
280 : static const JSJitInfo sizes_setterinfo = {
281 : { (JSJitGetterOp)set_sizes },
282 : { prototypes::id::HTMLSourceElement },
283 : { PrototypeTraits<prototypes::id::HTMLSourceElement>::Depth },
284 : JSJitInfo::Setter,
285 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
286 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
287 : false, /* isInfallible. False in setters. */
288 : false, /* isMovable. Not relevant for setters. */
289 : false, /* isEliminatable. Not relevant for setters. */
290 : false, /* isAlwaysInSlot. Only relevant for getters. */
291 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
292 : false, /* isTypedMethod. Only relevant for methods. */
293 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
294 : };
295 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
296 : static_assert(0 < 1, "There is no slot for us");
297 :
298 : static bool
299 0 : get_media(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::HTMLSourceElement* self, JSJitGetterCallArgs args)
300 : {
301 0 : DOMString result;
302 0 : self->GetMedia(result);
303 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
304 0 : if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
305 0 : return false;
306 : }
307 0 : return true;
308 : }
309 :
310 : static bool
311 0 : set_media(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::HTMLSourceElement* self, JSJitSetterCallArgs args)
312 : {
313 0 : binding_detail::FakeString arg0;
314 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
315 0 : return false;
316 : }
317 0 : CustomElementReactionsStack* reactionsStack = GetCustomElementReactionsStack(obj);
318 0 : Maybe<AutoCEReaction> ceReaction;
319 0 : if (reactionsStack) {
320 0 : ceReaction.emplace(reactionsStack);
321 : }
322 0 : binding_detail::FastErrorResult rv;
323 0 : self->SetMedia(NonNullHelper(Constify(arg0)), rv);
324 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
325 0 : return false;
326 : }
327 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
328 :
329 0 : return true;
330 : }
331 :
332 : static const JSJitInfo media_getterinfo = {
333 : { (JSJitGetterOp)get_media },
334 : { prototypes::id::HTMLSourceElement },
335 : { PrototypeTraits<prototypes::id::HTMLSourceElement>::Depth },
336 : JSJitInfo::Getter,
337 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
338 : JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
339 : false, /* isInfallible. False in setters. */
340 : false, /* isMovable. Not relevant for setters. */
341 : false, /* isEliminatable. Not relevant for setters. */
342 : false, /* isAlwaysInSlot. Only relevant for getters. */
343 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
344 : false, /* isTypedMethod. Only relevant for methods. */
345 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
346 : };
347 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
348 : static_assert(0 < 1, "There is no slot for us");
349 : static const JSJitInfo media_setterinfo = {
350 : { (JSJitGetterOp)set_media },
351 : { prototypes::id::HTMLSourceElement },
352 : { PrototypeTraits<prototypes::id::HTMLSourceElement>::Depth },
353 : JSJitInfo::Setter,
354 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
355 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
356 : false, /* isInfallible. False in setters. */
357 : false, /* isMovable. Not relevant for setters. */
358 : false, /* isEliminatable. Not relevant for setters. */
359 : false, /* isAlwaysInSlot. Only relevant for getters. */
360 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
361 : false, /* isTypedMethod. Only relevant for methods. */
362 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
363 : };
364 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
365 : static_assert(0 < 1, "There is no slot for us");
366 :
367 : static bool
368 0 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
369 : {
370 0 : mozilla::dom::HTMLSourceElement* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::HTMLSourceElement>(obj);
371 : // We don't want to preserve if we don't have a wrapper, and we
372 : // obviously can't preserve if we're not initialized.
373 0 : if (self && self->GetWrapperPreserveColor()) {
374 0 : PreserveWrapper(self);
375 : }
376 0 : return true;
377 : }
378 :
379 : static void
380 0 : _finalize(js::FreeOp* fop, JSObject* obj)
381 : {
382 0 : mozilla::dom::HTMLSourceElement* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::HTMLSourceElement>(obj);
383 0 : if (self) {
384 0 : ClearWrapper(self, self, obj);
385 0 : AddForDeferredFinalization<mozilla::dom::HTMLSourceElement>(self);
386 : }
387 0 : }
388 :
389 : static void
390 0 : _objectMoved(JSObject* obj, const JSObject* old)
391 : {
392 0 : mozilla::dom::HTMLSourceElement* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::HTMLSourceElement>(obj);
393 0 : if (self) {
394 0 : UpdateWrapper(self, self, obj, old);
395 : }
396 0 : }
397 :
398 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
399 : #if defined(__clang__)
400 : #pragma clang diagnostic push
401 : #pragma clang diagnostic ignored "-Wmissing-braces"
402 : #endif
403 : static const JSPropertySpec sAttributes_specs[] = {
404 : { "src", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &src_getterinfo, GenericBindingSetter, &src_setterinfo },
405 : { "type", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &type_getterinfo, GenericBindingSetter, &type_setterinfo },
406 : { "srcset", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &srcset_getterinfo, GenericBindingSetter, &srcset_setterinfo },
407 : { "sizes", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &sizes_getterinfo, GenericBindingSetter, &sizes_setterinfo },
408 : { "media", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &media_getterinfo, GenericBindingSetter, &media_setterinfo },
409 : { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
410 : };
411 : #if defined(__clang__)
412 : #pragma clang diagnostic pop
413 : #endif
414 :
415 :
416 : // Can't be const because the pref-enabled boolean needs to be writable
417 : static Prefable<const JSPropertySpec> sAttributes[] = {
418 : { nullptr, &sAttributes_specs[0] },
419 : { nullptr, nullptr }
420 : };
421 :
422 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
423 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
424 : static_assert(5 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
425 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
426 :
427 :
428 : static uint16_t sNativeProperties_sortedPropertyIndices[5];
429 : static PropertyInfo sNativeProperties_propertyInfos[5];
430 :
431 : static const NativePropertiesN<1> sNativeProperties = {
432 : false, 0,
433 : false, 0,
434 : false, 0,
435 : true, 0 /* sAttributes */,
436 : false, 0,
437 : false, 0,
438 : false, 0,
439 : -1,
440 : 5,
441 : sNativeProperties_sortedPropertyIndices,
442 : {
443 : { sAttributes, &sNativeProperties_propertyInfos[0] }
444 : }
445 : };
446 : static_assert(5 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
447 : "We have a property info count that is oversized");
448 :
449 : static bool
450 0 : _constructor(JSContext* cx, unsigned argc, JS::Value* vp)
451 : {
452 0 : JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
453 0 : JS::Rooted<JSObject*> obj(cx, &args.callee());
454 0 : if (!args.isConstructing()) {
455 : // XXXbz wish I could get the name from the callee instead of
456 : // Adding more relocations
457 0 : return ThrowConstructorWithoutNew(cx, "HTMLSourceElement");
458 : }
459 :
460 0 : GlobalObject global(cx, obj);
461 0 : if (global.Failed()) {
462 0 : return false;
463 : }
464 :
465 : // The newTarget might be a cross-compartment wrapper. Get the underlying object
466 : // so we can do the spec's object-identity checks.
467 0 : JS::Rooted<JSObject*> newTarget(cx, js::CheckedUnwrap(&args.newTarget().toObject()));
468 0 : if (!newTarget) {
469 0 : return ThrowErrorMessage(cx, MSG_ILLEGAL_CONSTRUCTOR);
470 : }
471 :
472 : // Step 2 of https://html.spec.whatwg.org/multipage/dom.html#htmlconstructor.
473 : // Enter the compartment of our underlying newTarget object, so we end
474 : // up comparing to the constructor object for our interface from that global.
475 : {
476 0 : JSAutoCompartment ac(cx, newTarget);
477 0 : JS::Handle<JSObject*> constructor(GetConstructorObjectHandle(cx));
478 0 : if (!constructor) {
479 0 : return false;
480 : }
481 0 : if (newTarget == constructor) {
482 0 : return ThrowErrorMessage(cx, MSG_ILLEGAL_CONSTRUCTOR);
483 : }
484 : }
485 :
486 0 : JS::Rooted<JSObject*> desiredProto(cx);
487 0 : if (!GetDesiredProto(cx, args, &desiredProto)) {
488 0 : return false;
489 : }
490 0 : if (!desiredProto) {
491 : // Step 7 of https://html.spec.whatwg.org/multipage/dom.html#htmlconstructor.
492 : // This fallback behavior is designed to match analogous behavior for the
493 : // JavaScript built-ins. So we enter the compartment of our underlying
494 : // newTarget object and fall back to the prototype object from that global.
495 : // XXX The spec says to use GetFunctionRealm(), which is not actually
496 : // the same thing as what we have here (e.g. in the case of scripted callable proxies
497 : // whose target is not same-compartment with the proxy, or bound functions, etc).
498 : // https://bugzilla.mozilla.org/show_bug.cgi?id=1317658
499 : {
500 0 : JSAutoCompartment ac(cx, newTarget);
501 0 : desiredProto = GetProtoObjectHandle(cx);
502 0 : if (!desiredProto) {
503 0 : return false;
504 : }
505 : }
506 :
507 : // desiredProto is in the compartment of the underlying newTarget object.
508 : // Wrap it into the context compartment.
509 0 : if (!JS_WrapObject(cx, &desiredProto)) {
510 0 : return false;
511 : }
512 : }
513 :
514 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
515 0 : Maybe<JSAutoCompartment> ac;
516 0 : if (objIsXray) {
517 0 : obj = js::CheckedUnwrap(obj);
518 0 : if (!obj) {
519 0 : return false;
520 : }
521 0 : ac.emplace(cx, obj);
522 0 : if (!JS_WrapObject(cx, &desiredProto)) {
523 0 : return false;
524 : }
525 : }
526 0 : binding_detail::FastErrorResult rv;
527 0 : auto result(StrongOrRawPtr<mozilla::dom::HTMLSourceElement>(CreateHTMLElement(global, args, rv)));
528 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
529 0 : return false;
530 : }
531 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
532 : static_assert(!IsPointer<decltype(result)>::value,
533 : "NewObject implies that we need to keep the object alive with a strong reference.");
534 0 : if (!GetOrCreateDOMReflector(cx, result, args.rval(), desiredProto)) {
535 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
536 0 : return false;
537 : }
538 0 : return true;
539 : }
540 :
541 : static const js::ClassOps sInterfaceObjectClassOps = {
542 : nullptr, /* addProperty */
543 : nullptr, /* delProperty */
544 : nullptr, /* getProperty */
545 : nullptr, /* setProperty */
546 : nullptr, /* enumerate */
547 : nullptr, /* newEnumerate */
548 : nullptr, /* resolve */
549 : nullptr, /* mayResolve */
550 : nullptr, /* finalize */
551 : _constructor, /* call */
552 : nullptr, /* hasInstance */
553 : _constructor, /* construct */
554 : nullptr, /* trace */
555 : };
556 :
557 : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
558 : {
559 : "Function",
560 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
561 : &sInterfaceObjectClassOps,
562 : JS_NULL_CLASS_SPEC,
563 : JS_NULL_CLASS_EXT,
564 : &sInterfaceObjectClassObjectOps
565 : },
566 : eInterface,
567 : true,
568 : prototypes::id::HTMLSourceElement,
569 : PrototypeTraits<prototypes::id::HTMLSourceElement>::Depth,
570 : sNativePropertyHooks,
571 : "function HTMLSourceElement() {\n [native code]\n}",
572 : HTMLElementBinding::GetConstructorObject
573 : };
574 :
575 : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
576 : {
577 : "HTMLSourceElementPrototype",
578 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
579 : JS_NULL_CLASS_OPS,
580 : JS_NULL_CLASS_SPEC,
581 : JS_NULL_CLASS_EXT,
582 : JS_NULL_OBJECT_OPS
583 : },
584 : eInterfacePrototype,
585 : false,
586 : prototypes::id::HTMLSourceElement,
587 : PrototypeTraits<prototypes::id::HTMLSourceElement>::Depth,
588 : sNativePropertyHooks,
589 : "[object HTMLSourceElementPrototype]",
590 : HTMLElementBinding::GetProtoObject
591 : };
592 :
593 : JSObject*
594 0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
595 : {
596 0 : return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
597 : }
598 :
599 : static const js::ClassOps sClassOps = {
600 : _addProperty, /* addProperty */
601 : nullptr, /* delProperty */
602 : nullptr, /* getProperty */
603 : nullptr, /* setProperty */
604 : nullptr, /* enumerate */
605 : nullptr, /* newEnumerate */
606 : nullptr, /* resolve */
607 : nullptr, /* mayResolve */
608 : _finalize, /* finalize */
609 : nullptr, /* call */
610 : nullptr, /* hasInstance */
611 : nullptr, /* construct */
612 : nullptr, /* trace */
613 : };
614 :
615 : static const js::ClassExtension sClassExtension = {
616 : nullptr, /* weakmapKeyDelegateOp */
617 : _objectMoved /* objectMovedOp */
618 : };
619 :
620 : static const DOMJSClass sClass = {
621 : { "HTMLSourceElement",
622 : JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
623 : &sClassOps,
624 : JS_NULL_CLASS_SPEC,
625 : &sClassExtension,
626 : JS_NULL_OBJECT_OPS
627 : },
628 : { prototypes::id::EventTarget, prototypes::id::Node, prototypes::id::Element, prototypes::id::HTMLElement, prototypes::id::HTMLSourceElement, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
629 : IsBaseOf<nsISupports, mozilla::dom::HTMLSourceElement >::value,
630 : sNativePropertyHooks,
631 : FindAssociatedGlobalForNative<mozilla::dom::HTMLSourceElement>::Get,
632 : GetProtoObjectHandle,
633 : GetCCParticipant<mozilla::dom::HTMLSourceElement>::Get()
634 : };
635 : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
636 : "Must have the right minimal number of reserved slots.");
637 : static_assert(1 >= 1,
638 : "Must have enough reserved slots.");
639 :
640 : const JSClass*
641 0 : GetJSClass()
642 : {
643 0 : return sClass.ToJSClass();
644 : }
645 :
646 : bool
647 0 : Wrap(JSContext* aCx, mozilla::dom::HTMLSourceElement* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
648 : {
649 : MOZ_ASSERT(static_cast<mozilla::dom::HTMLSourceElement*>(aObject) ==
650 : reinterpret_cast<mozilla::dom::HTMLSourceElement*>(aObject),
651 : "Multiple inheritance for mozilla::dom::HTMLSourceElement is broken.");
652 : MOZ_ASSERT(static_cast<nsGenericHTMLElement*>(aObject) ==
653 : reinterpret_cast<nsGenericHTMLElement*>(aObject),
654 : "Multiple inheritance for nsGenericHTMLElement is broken.");
655 : MOZ_ASSERT(static_cast<mozilla::dom::Element*>(aObject) ==
656 : reinterpret_cast<mozilla::dom::Element*>(aObject),
657 : "Multiple inheritance for mozilla::dom::Element is broken.");
658 : MOZ_ASSERT(static_cast<nsINode*>(aObject) ==
659 : reinterpret_cast<nsINode*>(aObject),
660 : "Multiple inheritance for nsINode is broken.");
661 : MOZ_ASSERT(static_cast<mozilla::dom::EventTarget*>(aObject) ==
662 : reinterpret_cast<mozilla::dom::EventTarget*>(aObject),
663 : "Multiple inheritance for mozilla::dom::EventTarget is broken.");
664 0 : MOZ_ASSERT(ToSupportsIsCorrect(aObject));
665 0 : MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
666 0 : MOZ_ASSERT(!aCache->GetWrapper(),
667 : "You should probably not be using Wrap() directly; use "
668 : "GetOrCreateDOMReflector instead");
669 :
670 0 : MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
671 : "nsISupports must be on our primary inheritance chain");
672 :
673 0 : JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
674 0 : if (!global) {
675 0 : return false;
676 : }
677 0 : MOZ_ASSERT(JS_IsGlobalObject(global));
678 0 : MOZ_ASSERT(JS::ObjectIsNotGray(global));
679 :
680 : // That might have ended up wrapping us already, due to the wonders
681 : // of XBL. Check for that, and bail out as needed.
682 0 : aReflector.set(aCache->GetWrapper());
683 0 : if (aReflector) {
684 : #ifdef DEBUG
685 0 : binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
686 : #endif // DEBUG
687 0 : return true;
688 : }
689 :
690 0 : JSAutoCompartment ac(aCx, global);
691 0 : JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
692 0 : if (!canonicalProto) {
693 0 : return false;
694 : }
695 0 : JS::Rooted<JSObject*> proto(aCx);
696 0 : if (aGivenProto) {
697 0 : proto = aGivenProto;
698 : // Unfortunately, while aGivenProto was in the compartment of aCx
699 : // coming in, we changed compartments to that of "parent" so may need
700 : // to wrap the proto here.
701 0 : if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
702 0 : if (!JS_WrapObject(aCx, &proto)) {
703 0 : return false;
704 : }
705 : }
706 : } else {
707 0 : proto = canonicalProto;
708 : }
709 :
710 0 : BindingJSObjectCreator<mozilla::dom::HTMLSourceElement> creator(aCx);
711 0 : creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
712 0 : if (!aReflector) {
713 0 : return false;
714 : }
715 :
716 0 : aCache->SetWrapper(aReflector);
717 0 : creator.InitializationSucceeded();
718 :
719 0 : MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
720 : aCache->GetWrapperPreserveColor() == aReflector);
721 : // If proto != canonicalProto, we have to preserve our wrapper;
722 : // otherwise we won't be able to properly recreate it later, since
723 : // we won't know what proto to use. Note that we don't check
724 : // aGivenProto here, since it's entirely possible (and even
725 : // somewhat common) to have a non-null aGivenProto which is the
726 : // same as canonicalProto.
727 0 : if (proto != canonicalProto) {
728 0 : PreserveWrapper(aObject);
729 : }
730 :
731 0 : return true;
732 : }
733 :
734 : const NativePropertyHooks sNativePropertyHooks[] = { {
735 : nullptr,
736 : nullptr,
737 : nullptr,
738 : { sNativeProperties.Upcast(), nullptr },
739 : prototypes::id::HTMLSourceElement,
740 : constructors::id::HTMLSourceElement,
741 : HTMLElementBinding::sNativePropertyHooks,
742 : &DefaultXrayExpandoObjectClass
743 : } };
744 :
745 : void
746 0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
747 : {
748 0 : JS::Handle<JSObject*> parentProto(HTMLElementBinding::GetProtoObjectHandle(aCx));
749 0 : if (!parentProto) {
750 0 : return;
751 : }
752 :
753 0 : JS::Handle<JSObject*> constructorProto(HTMLElementBinding::GetConstructorObjectHandle(aCx));
754 0 : if (!constructorProto) {
755 0 : return;
756 : }
757 :
758 : static bool sIdsInited = false;
759 0 : if (!sIdsInited && NS_IsMainThread()) {
760 0 : if (!InitIds(aCx, sNativeProperties.Upcast())) {
761 0 : return;
762 : }
763 0 : sIdsInited = true;
764 : }
765 :
766 0 : JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::HTMLSourceElement);
767 0 : JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::HTMLSourceElement);
768 0 : dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
769 : &sPrototypeClass.mBase, protoCache,
770 : constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
771 : interfaceCache,
772 : sNativeProperties.Upcast(),
773 : nullptr,
774 : "HTMLSourceElement", aDefineOnGlobal,
775 : nullptr,
776 0 : false);
777 : }
778 :
779 : JS::Handle<JSObject*>
780 0 : GetProtoObjectHandle(JSContext* aCx)
781 : {
782 : /* Get the interface prototype object for this class. This will create the
783 : object as needed. */
784 0 : bool aDefineOnGlobal = true;
785 :
786 : /* Make sure our global is sane. Hopefully we can remove this sometime */
787 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
788 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
789 0 : return nullptr;
790 : }
791 :
792 : /* Check to see whether the interface objects are already installed */
793 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
794 0 : if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::HTMLSourceElement)) {
795 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
796 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
797 : }
798 :
799 : /*
800 : * The object might _still_ be null, but that's OK.
801 : *
802 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
803 : * traced by TraceProtoAndIfaceCache() and its contents are never
804 : * changed after they have been set.
805 : *
806 : * Calling address() avoids the read read barrier that does gray
807 : * unmarking, but it's not possible for the object to be gray here.
808 : */
809 :
810 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::HTMLSourceElement);
811 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
812 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
813 : }
814 :
815 : JS::Handle<JSObject*>
816 0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
817 : {
818 : /* Get the interface object for this class. This will create the object as
819 : needed. */
820 :
821 : /* Make sure our global is sane. Hopefully we can remove this sometime */
822 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
823 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
824 0 : return nullptr;
825 : }
826 :
827 : /* Check to see whether the interface objects are already installed */
828 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
829 0 : if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::HTMLSourceElement)) {
830 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
831 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
832 : }
833 :
834 : /*
835 : * The object might _still_ be null, but that's OK.
836 : *
837 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
838 : * traced by TraceProtoAndIfaceCache() and its contents are never
839 : * changed after they have been set.
840 : *
841 : * Calling address() avoids the read read barrier that does gray
842 : * unmarking, but it's not possible for the object to be gray here.
843 : */
844 :
845 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::HTMLSourceElement);
846 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
847 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
848 : }
849 :
850 : JSObject*
851 0 : GetConstructorObject(JSContext* aCx)
852 : {
853 0 : return GetConstructorObjectHandle(aCx);
854 : }
855 :
856 : } // namespace HTMLSourceElementBinding
857 :
858 :
859 :
860 : } // namespace dom
861 : } // namespace mozilla
|