Line data Source code
1 : /* THIS FILE IS AUTOGENERATED FROM ImageDocument.webidl BY Codegen.py - DO NOT EDIT */
2 :
3 : #include "HTMLDocumentBinding.h"
4 : #include "ImageDocumentBinding.h"
5 : #include "WrapperFactory.h"
6 : #include "imgIRequest.h"
7 : #include "mozilla/OwningNonNull.h"
8 : #include "mozilla/dom/BindingUtils.h"
9 : #include "mozilla/dom/DOMJSClass.h"
10 : #include "mozilla/dom/DOMJSProxyHandler.h"
11 : #include "mozilla/dom/ImageDocument.h"
12 : #include "mozilla/dom/Location.h"
13 : #include "mozilla/dom/NonRefcountedDOMObject.h"
14 : #include "mozilla/dom/Nullable.h"
15 : #include "mozilla/dom/PrimitiveConversions.h"
16 : #include "mozilla/dom/XrayExpandoClass.h"
17 : #include "nsContentUtils.h"
18 :
19 : namespace mozilla {
20 : namespace dom {
21 :
22 : namespace ImageDocumentBinding {
23 :
24 : static_assert(IsRefcounted<NativeType>::value == IsRefcounted<HTMLDocumentBinding::NativeType>::value,
25 : "Can't inherit from an interface with a different ownership model.");
26 :
27 : static bool
28 0 : get_imageIsOverflowing(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::ImageDocument* self, JSJitGetterCallArgs args)
29 : {
30 0 : bool result(self->ImageIsOverflowing());
31 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
32 0 : args.rval().setBoolean(result);
33 0 : return true;
34 : }
35 :
36 : static const JSJitInfo imageIsOverflowing_getterinfo = {
37 : { (JSJitGetterOp)get_imageIsOverflowing },
38 : { prototypes::id::ImageDocument },
39 : { PrototypeTraits<prototypes::id::ImageDocument>::Depth },
40 : JSJitInfo::Getter,
41 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
42 : JSVAL_TYPE_BOOLEAN, /* returnType. Not relevant for setters. */
43 : true, /* isInfallible. False in setters. */
44 : false, /* isMovable. Not relevant for setters. */
45 : false, /* isEliminatable. Not relevant for setters. */
46 : false, /* isAlwaysInSlot. Only relevant for getters. */
47 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
48 : false, /* isTypedMethod. Only relevant for methods. */
49 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
50 : };
51 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
52 : static_assert(0 < 1, "There is no slot for us");
53 :
54 : static bool
55 0 : get_imageIsResized(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::ImageDocument* self, JSJitGetterCallArgs args)
56 : {
57 0 : bool result(self->ImageIsResized());
58 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
59 0 : args.rval().setBoolean(result);
60 0 : return true;
61 : }
62 :
63 : static const JSJitInfo imageIsResized_getterinfo = {
64 : { (JSJitGetterOp)get_imageIsResized },
65 : { prototypes::id::ImageDocument },
66 : { PrototypeTraits<prototypes::id::ImageDocument>::Depth },
67 : JSJitInfo::Getter,
68 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
69 : JSVAL_TYPE_BOOLEAN, /* returnType. Not relevant for setters. */
70 : true, /* isInfallible. False in setters. */
71 : false, /* isMovable. Not relevant for setters. */
72 : false, /* isEliminatable. Not relevant for setters. */
73 : false, /* isAlwaysInSlot. Only relevant for getters. */
74 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
75 : false, /* isTypedMethod. Only relevant for methods. */
76 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
77 : };
78 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
79 : static_assert(0 < 1, "There is no slot for us");
80 :
81 : static bool
82 0 : get_imageRequest(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::ImageDocument* self, JSJitGetterCallArgs args)
83 : {
84 0 : binding_detail::FastErrorResult rv;
85 0 : auto result(StrongOrRawPtr<imgIRequest>(self->GetImageRequest(rv)));
86 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
87 0 : return false;
88 : }
89 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
90 0 : if (!result) {
91 0 : args.rval().setNull();
92 0 : return true;
93 : }
94 0 : if (!WrapObject(cx, result, &NS_GET_IID(imgIRequest), args.rval())) {
95 0 : return false;
96 : }
97 0 : return true;
98 : }
99 :
100 : static const JSJitInfo imageRequest_getterinfo = {
101 : { (JSJitGetterOp)get_imageRequest },
102 : { prototypes::id::ImageDocument },
103 : { PrototypeTraits<prototypes::id::ImageDocument>::Depth },
104 : JSJitInfo::Getter,
105 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
106 : JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */
107 : false, /* isInfallible. False in setters. */
108 : false, /* isMovable. Not relevant for setters. */
109 : false, /* isEliminatable. Not relevant for setters. */
110 : false, /* isAlwaysInSlot. Only relevant for getters. */
111 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
112 : false, /* isTypedMethod. Only relevant for methods. */
113 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
114 : };
115 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
116 : static_assert(0 < 1, "There is no slot for us");
117 :
118 : static bool
119 0 : shrinkToFit(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::ImageDocument* self, const JSJitMethodCallArgs& args)
120 : {
121 0 : self->ShrinkToFit();
122 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
123 0 : args.rval().setUndefined();
124 0 : return true;
125 : }
126 :
127 : static const JSJitInfo shrinkToFit_methodinfo = {
128 : { (JSJitGetterOp)shrinkToFit },
129 : { prototypes::id::ImageDocument },
130 : { PrototypeTraits<prototypes::id::ImageDocument>::Depth },
131 : JSJitInfo::Method,
132 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
133 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
134 : true, /* isInfallible. False in setters. */
135 : false, /* isMovable. Not relevant for setters. */
136 : false, /* isEliminatable. Not relevant for setters. */
137 : false, /* isAlwaysInSlot. Only relevant for getters. */
138 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
139 : false, /* isTypedMethod. Only relevant for methods. */
140 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
141 : };
142 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
143 : static_assert(0 < 1, "There is no slot for us");
144 :
145 : static bool
146 0 : restoreImage(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::ImageDocument* self, const JSJitMethodCallArgs& args)
147 : {
148 0 : self->RestoreImage();
149 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
150 0 : args.rval().setUndefined();
151 0 : return true;
152 : }
153 :
154 : static const JSJitInfo restoreImage_methodinfo = {
155 : { (JSJitGetterOp)restoreImage },
156 : { prototypes::id::ImageDocument },
157 : { PrototypeTraits<prototypes::id::ImageDocument>::Depth },
158 : JSJitInfo::Method,
159 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
160 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
161 : true, /* isInfallible. False in setters. */
162 : false, /* isMovable. Not relevant for setters. */
163 : false, /* isEliminatable. Not relevant for setters. */
164 : false, /* isAlwaysInSlot. Only relevant for getters. */
165 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
166 : false, /* isTypedMethod. Only relevant for methods. */
167 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
168 : };
169 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
170 : static_assert(0 < 1, "There is no slot for us");
171 :
172 : static bool
173 0 : restoreImageTo(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::ImageDocument* self, const JSJitMethodCallArgs& args)
174 : {
175 0 : if (MOZ_UNLIKELY(args.length() < 2)) {
176 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "ImageDocument.restoreImageTo");
177 : }
178 : int32_t arg0;
179 0 : if (!ValueToPrimitive<int32_t, eDefault>(cx, args[0], &arg0)) {
180 0 : return false;
181 : }
182 : int32_t arg1;
183 0 : if (!ValueToPrimitive<int32_t, eDefault>(cx, args[1], &arg1)) {
184 0 : return false;
185 : }
186 0 : self->RestoreImageTo(arg0, arg1);
187 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
188 0 : args.rval().setUndefined();
189 0 : return true;
190 : }
191 :
192 : static const JSJitInfo restoreImageTo_methodinfo = {
193 : { (JSJitGetterOp)restoreImageTo },
194 : { prototypes::id::ImageDocument },
195 : { PrototypeTraits<prototypes::id::ImageDocument>::Depth },
196 : JSJitInfo::Method,
197 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
198 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
199 : false, /* isInfallible. False in setters. */
200 : false, /* isMovable. Not relevant for setters. */
201 : false, /* isEliminatable. Not relevant for setters. */
202 : false, /* isAlwaysInSlot. Only relevant for getters. */
203 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
204 : false, /* isTypedMethod. Only relevant for methods. */
205 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
206 : };
207 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
208 : static_assert(0 < 1, "There is no slot for us");
209 :
210 : static bool
211 0 : toggleImageSize(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::ImageDocument* self, const JSJitMethodCallArgs& args)
212 : {
213 0 : self->ToggleImageSize();
214 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
215 0 : args.rval().setUndefined();
216 0 : return true;
217 : }
218 :
219 : static const JSJitInfo toggleImageSize_methodinfo = {
220 : { (JSJitGetterOp)toggleImageSize },
221 : { prototypes::id::ImageDocument },
222 : { PrototypeTraits<prototypes::id::ImageDocument>::Depth },
223 : JSJitInfo::Method,
224 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
225 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
226 : true, /* isInfallible. False in setters. */
227 : false, /* isMovable. Not relevant for setters. */
228 : false, /* isEliminatable. Not relevant for setters. */
229 : false, /* isAlwaysInSlot. Only relevant for getters. */
230 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
231 : false, /* isTypedMethod. Only relevant for methods. */
232 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
233 : };
234 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
235 : static_assert(0 < 1, "There is no slot for us");
236 :
237 : static bool
238 0 : get_location(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::ImageDocument* self, JSJitGetterCallArgs args)
239 : {
240 0 : auto result(StrongOrRawPtr<mozilla::dom::Location>(self->GetLocation()));
241 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
242 0 : if (!result) {
243 0 : args.rval().setNull();
244 0 : return true;
245 : }
246 0 : if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
247 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
248 0 : return false;
249 : }
250 0 : return true;
251 : }
252 :
253 : static bool
254 0 : set_location(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::ImageDocument* self, JSJitSetterCallArgs args)
255 : {
256 0 : JS::Rooted<JS::Value> v(cx);
257 0 : if (!JS_GetProperty(cx, obj, "location", &v)) {
258 0 : return false;
259 : }
260 :
261 0 : if (!v.isObject()) {
262 0 : return ThrowErrorMessage(cx, MSG_NOT_OBJECT, "ImageDocument.location");
263 : }
264 :
265 0 : JS::Rooted<JSObject*> targetObj(cx, &v.toObject());
266 0 : return JS_SetProperty(cx, targetObj, "href", args[0]);
267 : }
268 :
269 : static const JSJitInfo location_getterinfo = {
270 : { (JSJitGetterOp)get_location },
271 : { prototypes::id::ImageDocument },
272 : { PrototypeTraits<prototypes::id::ImageDocument>::Depth },
273 : JSJitInfo::Getter,
274 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
275 : JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */
276 : false, /* isInfallible. False in setters. */
277 : false, /* isMovable. Not relevant for setters. */
278 : false, /* isEliminatable. Not relevant for setters. */
279 : false, /* isAlwaysInSlot. Only relevant for getters. */
280 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
281 : false, /* isTypedMethod. Only relevant for methods. */
282 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
283 : };
284 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
285 : static_assert(0 < 1, "There is no slot for us");
286 : static const JSJitInfo location_setterinfo = {
287 : { (JSJitGetterOp)set_location },
288 : { prototypes::id::ImageDocument },
289 : { PrototypeTraits<prototypes::id::ImageDocument>::Depth },
290 : JSJitInfo::Setter,
291 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
292 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
293 : false, /* isInfallible. False in setters. */
294 : false, /* isMovable. Not relevant for setters. */
295 : false, /* isEliminatable. Not relevant for setters. */
296 : false, /* isAlwaysInSlot. Only relevant for getters. */
297 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
298 : false, /* isTypedMethod. Only relevant for methods. */
299 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
300 : };
301 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
302 : static_assert(0 < 1, "There is no slot for us");
303 :
304 : static void
305 0 : _objectMoved(JSObject* obj, const JSObject* old)
306 : {
307 0 : mozilla::dom::ImageDocument* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::ImageDocument>(obj);
308 0 : if (self) {
309 0 : UpdateWrapper(self, self, obj, old);
310 : }
311 0 : }
312 :
313 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
314 : #if defined(__clang__)
315 : #pragma clang diagnostic push
316 : #pragma clang diagnostic ignored "-Wmissing-braces"
317 : #endif
318 : static const JSFunctionSpec sMethods_specs[] = {
319 : JS_FNSPEC("shrinkToFit", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&shrinkToFit_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
320 : JS_FNSPEC("restoreImage", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&restoreImage_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
321 : JS_FNSPEC("restoreImageTo", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&restoreImageTo_methodinfo), 2, JSPROP_ENUMERATE, nullptr),
322 : JS_FNSPEC("toggleImageSize", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&toggleImageSize_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
323 : JS_FS_END
324 : };
325 : #if defined(__clang__)
326 : #pragma clang diagnostic pop
327 : #endif
328 :
329 :
330 : // Can't be const because the pref-enabled boolean needs to be writable
331 : static Prefable<const JSFunctionSpec> sMethods[] = {
332 : { nullptr, &sMethods_specs[0] },
333 : { nullptr, nullptr }
334 : };
335 :
336 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
337 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
338 : static_assert(4 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
339 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
340 :
341 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
342 : #if defined(__clang__)
343 : #pragma clang diagnostic push
344 : #pragma clang diagnostic ignored "-Wmissing-braces"
345 : #endif
346 : static const JSPropertySpec sAttributes_specs[] = {
347 : { "imageIsOverflowing", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &imageIsOverflowing_getterinfo, nullptr, nullptr },
348 : { "imageIsResized", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &imageIsResized_getterinfo, nullptr, nullptr },
349 : { "imageRequest", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &imageRequest_getterinfo, nullptr, nullptr },
350 : { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
351 : };
352 : #if defined(__clang__)
353 : #pragma clang diagnostic pop
354 : #endif
355 :
356 :
357 : // Can't be const because the pref-enabled boolean needs to be writable
358 : static Prefable<const JSPropertySpec> sAttributes[] = {
359 : { nullptr, &sAttributes_specs[0] },
360 : { nullptr, nullptr }
361 : };
362 :
363 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
364 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
365 : static_assert(3 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
366 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
367 :
368 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
369 : #if defined(__clang__)
370 : #pragma clang diagnostic push
371 : #pragma clang diagnostic ignored "-Wmissing-braces"
372 : #endif
373 : static const JSPropertySpec sUnforgeableAttributes_specs[] = {
374 : { "location", JSPROP_SHARED | JSPROP_ENUMERATE | JSPROP_PERMANENT, GenericBindingGetter, &location_getterinfo, GenericBindingSetter, &location_setterinfo },
375 : { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
376 : };
377 : #if defined(__clang__)
378 : #pragma clang diagnostic pop
379 : #endif
380 :
381 :
382 : // Can't be const because the pref-enabled boolean needs to be writable
383 : static Prefable<const JSPropertySpec> sUnforgeableAttributes[] = {
384 : { nullptr, &sUnforgeableAttributes_specs[0] },
385 : { nullptr, nullptr }
386 : };
387 :
388 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
389 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
390 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
391 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
392 :
393 :
394 : static uint16_t sNativeProperties_sortedPropertyIndices[8];
395 : static PropertyInfo sNativeProperties_propertyInfos[8];
396 :
397 : static const NativePropertiesN<3> sNativeProperties = {
398 : false, 0,
399 : false, 0,
400 : true, 0 /* sMethods */,
401 : true, 1 /* sAttributes */,
402 : false, 0,
403 : true, 2 /* sUnforgeableAttributes */,
404 : false, 0,
405 : -1,
406 : 8,
407 : sNativeProperties_sortedPropertyIndices,
408 : {
409 : { sMethods, &sNativeProperties_propertyInfos[0] },
410 : { sAttributes, &sNativeProperties_propertyInfos[4] },
411 : { sUnforgeableAttributes, &sNativeProperties_propertyInfos[7] }
412 : }
413 : };
414 : static_assert(8 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
415 : "We have a property info count that is oversized");
416 :
417 : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
418 : {
419 : "Function",
420 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
421 : &sBoringInterfaceObjectClassClassOps,
422 : JS_NULL_CLASS_SPEC,
423 : JS_NULL_CLASS_EXT,
424 : &sInterfaceObjectClassObjectOps
425 : },
426 : eInterface,
427 : true,
428 : prototypes::id::ImageDocument,
429 : PrototypeTraits<prototypes::id::ImageDocument>::Depth,
430 : sNativePropertyHooks,
431 : "function ImageDocument() {\n [native code]\n}",
432 : HTMLDocumentBinding::GetConstructorObject
433 : };
434 :
435 : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
436 : {
437 : "ImageDocumentPrototype",
438 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE + 1 /* slot for the JSObject holding the unforgeable properties */),
439 : JS_NULL_CLASS_OPS,
440 : JS_NULL_CLASS_SPEC,
441 : JS_NULL_CLASS_EXT,
442 : JS_NULL_OBJECT_OPS
443 : },
444 : eInterfacePrototype,
445 : false,
446 : prototypes::id::ImageDocument,
447 : PrototypeTraits<prototypes::id::ImageDocument>::Depth,
448 : sNativePropertyHooks,
449 : "[object ImageDocumentPrototype]",
450 : HTMLDocumentBinding::GetProtoObject
451 : };
452 :
453 : bool
454 0 : ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
455 : {
456 0 : return nsContentUtils::ThreadsafeIsSystemCaller(aCx);
457 : }
458 :
459 : JSObject*
460 0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
461 : {
462 0 : return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
463 : }
464 :
465 : static_assert(IsBaseOf<nsISupports, mozilla::dom::ImageDocument >::value,
466 : "We don't support non-nsISupports native classes for "
467 : "proxy-based bindings yet");
468 :
469 :
470 : class DOMProxyHandler : public ShadowingDOMProxyHandler
471 : {
472 : public:
473 : explicit constexpr DOMProxyHandler()
474 : {
475 : }
476 :
477 : virtual bool
478 : getOwnPropDescriptor(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool ignoreNamedProps, JS::MutableHandle<JS::PropertyDescriptor> desc) const override;
479 :
480 : virtual bool
481 : defineProperty(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, JS::Handle<JS::PropertyDescriptor> desc, JS::ObjectOpResult& opresult, bool* defined) const override;
482 :
483 : using mozilla::dom::DOMProxyHandler::defineProperty;
484 :
485 : virtual bool
486 : ownPropNames(JSContext* cx, JS::Handle<JSObject*> proxy, unsigned flags, JS::AutoIdVector& props) const override;
487 :
488 : virtual bool
489 : hasOwn(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool* bp) const override;
490 :
491 : virtual bool
492 : get(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<JS::Value> receiver, JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp) const override;
493 :
494 : virtual const char*
495 : className(JSContext* cx, JS::Handle<JSObject*> proxy) const override;
496 :
497 : virtual bool
498 : finalizeInBackground(const JS::Value& priv) const override;
499 :
500 : virtual void
501 : finalize(JSFreeOp* fop, JSObject* proxy) const override;
502 :
503 : static const DOMProxyHandler*
504 : getInstance();
505 :
506 : virtual bool
507 : delete_(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, JS::ObjectOpResult& opresult) const override;
508 : };
509 :
510 : MOZ_ALWAYS_INLINE bool
511 0 : IsProxy(JSObject* obj)
512 : {
513 0 : return js::IsProxy(obj) && js::GetProxyHandler(obj) == DOMProxyHandler::getInstance();
514 : }
515 :
516 : MOZ_ALWAYS_INLINE mozilla::dom::ImageDocument*
517 0 : UnwrapProxy(JSObject* obj)
518 : {
519 0 : MOZ_ASSERT(js::IsProxy(obj));
520 0 : if (js::GetProxyHandler(obj) != DOMProxyHandler::getInstance()) {
521 0 : MOZ_ASSERT(xpc::WrapperFactory::IsXrayWrapper(obj));
522 0 : obj = js::UncheckedUnwrap(obj);
523 : }
524 0 : MOZ_ASSERT(IsProxy(obj));
525 0 : return static_cast<mozilla::dom::ImageDocument*>(js::GetProxyReservedSlot(obj, DOM_OBJECT_SLOT).toPrivate());
526 : }
527 :
528 : bool
529 0 : DOMProxyHandler::getOwnPropDescriptor(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool ignoreNamedProps, JS::MutableHandle<JS::PropertyDescriptor> desc) const
530 : {
531 0 : bool isXray = xpc::WrapperFactory::IsXrayWrapper(proxy);
532 0 : JS::Rooted<JSObject*> expando(cx);
533 0 : if (!isXray && (expando = GetExpandoObject(proxy))) {
534 0 : if (!JS_GetOwnPropertyDescriptorById(cx, expando, id, desc)) {
535 0 : return false;
536 : }
537 0 : if (desc.object()) {
538 : // Pretend the property lives on the wrapper.
539 0 : desc.object().set(proxy);
540 0 : return true;
541 : }
542 : }
543 :
544 0 : bool callNamedGetter = false;
545 0 : if (!ignoreNamedProps) {
546 0 : if (!isXray) {
547 0 : callNamedGetter = true;
548 : } else {
549 : bool hasOnProto;
550 0 : if (!HasPropertyOnPrototype(cx, proxy, id, &hasOnProto)) {
551 0 : return false;
552 : }
553 0 : callNamedGetter = !hasOnProto;
554 : }
555 : }
556 0 : if (callNamedGetter) {
557 0 : binding_detail::FakeString name;
558 : bool isSymbol;
559 0 : if (!ConvertIdToString(cx, id, name, isSymbol)) {
560 0 : return false;
561 : }
562 0 : if (!isSymbol) {
563 0 : mozilla::dom::ImageDocument* self = UnwrapProxy(proxy);
564 0 : bool found = false;
565 0 : binding_detail::FastErrorResult rv;
566 0 : JS::Rooted<JSObject*> result(cx);
567 0 : self->NamedGetter(cx, NonNullHelper(Constify(name)), found, &result, rv);
568 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
569 0 : return false;
570 : }
571 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
572 :
573 0 : if (found) {
574 0 : JS::ExposeObjectToActiveJS(result);
575 0 : desc.value().setObject(*result);
576 0 : if (!MaybeWrapObjectValue(cx, desc.value())) {
577 0 : return false;
578 : }
579 0 : FillPropertyDescriptor(desc, proxy, true, true);
580 0 : return true;
581 : }
582 : }
583 : }
584 :
585 0 : desc.object().set(nullptr);
586 0 : return true;
587 : }
588 :
589 : bool
590 0 : DOMProxyHandler::defineProperty(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, JS::Handle<JS::PropertyDescriptor> desc, JS::ObjectOpResult& opresult, bool* defined) const
591 : {
592 0 : bool found = false;
593 0 : binding_detail::FakeString name;
594 : bool isSymbol;
595 0 : if (!ConvertIdToString(cx, id, name, isSymbol)) {
596 0 : return false;
597 : }
598 0 : if (!isSymbol) {
599 0 : mozilla::dom::ImageDocument* self = UnwrapProxy(proxy);
600 0 : binding_detail::FastErrorResult rv;
601 0 : JS::Rooted<JSObject*> result(cx);
602 0 : self->NamedGetter(cx, NonNullHelper(Constify(name)), found, &result, rv);
603 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
604 0 : return false;
605 : }
606 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
607 : (void)result;
608 : }
609 :
610 0 : if (found) {
611 0 : *defined = true;
612 0 : return opresult.failNoNamedSetter();
613 : }
614 0 : return mozilla::dom::DOMProxyHandler::defineProperty(cx, proxy, id, desc, opresult, defined);
615 : }
616 :
617 :
618 : bool
619 0 : DOMProxyHandler::ownPropNames(JSContext* cx, JS::Handle<JSObject*> proxy, unsigned flags, JS::AutoIdVector& props) const
620 : {
621 0 : bool isXray = xpc::WrapperFactory::IsXrayWrapper(proxy);
622 :
623 0 : nsTArray<nsString> names;
624 0 : UnwrapProxy(proxy)->GetSupportedNames(names);
625 0 : if (!AppendNamedPropertyIds(cx, proxy, names, !isXray, props)) {
626 0 : return false;
627 : }
628 :
629 0 : JS::Rooted<JSObject*> expando(cx);
630 0 : if (!isXray && (expando = DOMProxyHandler::GetExpandoObject(proxy)) &&
631 0 : !js::GetPropertyKeys(cx, expando, flags, &props)) {
632 0 : return false;
633 : }
634 :
635 0 : return true;
636 : }
637 :
638 : bool
639 0 : DOMProxyHandler::hasOwn(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool* bp) const
640 : {
641 0 : MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
642 : "Should not have a XrayWrapper here");
643 :
644 :
645 0 : JS::Rooted<JSObject*> expando(cx, GetExpandoObject(proxy));
646 0 : if (expando) {
647 0 : bool b = true;
648 0 : bool ok = JS_HasPropertyById(cx, expando, id, &b);
649 0 : *bp = !!b;
650 0 : if (!ok || *bp) {
651 0 : return ok;
652 : }
653 : }
654 :
655 0 : bool found = false;
656 0 : binding_detail::FakeString name;
657 : bool isSymbol;
658 0 : if (!ConvertIdToString(cx, id, name, isSymbol)) {
659 0 : return false;
660 : }
661 0 : if (!isSymbol) {
662 0 : mozilla::dom::ImageDocument* self = UnwrapProxy(proxy);
663 0 : binding_detail::FastErrorResult rv;
664 0 : JS::Rooted<JSObject*> result(cx);
665 0 : self->NamedGetter(cx, NonNullHelper(Constify(name)), found, &result, rv);
666 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
667 0 : return false;
668 : }
669 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
670 : (void)result;
671 : }
672 :
673 0 : *bp = found;
674 :
675 0 : return true;
676 : }
677 :
678 : bool
679 0 : DOMProxyHandler::get(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<JS::Value> receiver, JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp) const
680 : {
681 0 : MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
682 : "Should not have a XrayWrapper here");
683 :
684 : { // Scope for expando
685 0 : JS::Rooted<JSObject*> expando(cx, DOMProxyHandler::GetExpandoObject(proxy));
686 0 : if (expando) {
687 : bool hasProp;
688 0 : if (!JS_HasPropertyById(cx, expando, id, &hasProp)) {
689 0 : return false;
690 : }
691 :
692 0 : if (hasProp) {
693 : // Forward the get to the expando object, but our receiver is whatever our
694 : // receiver is.
695 0 : return JS_ForwardGetPropertyTo(cx, expando, id, receiver, vp);
696 : }
697 : }
698 : }
699 :
700 0 : binding_detail::FakeString name;
701 : bool isSymbol;
702 0 : if (!ConvertIdToString(cx, id, name, isSymbol)) {
703 0 : return false;
704 : }
705 0 : if (!isSymbol) {
706 0 : mozilla::dom::ImageDocument* self = UnwrapProxy(proxy);
707 0 : bool found = false;
708 0 : binding_detail::FastErrorResult rv;
709 0 : JS::Rooted<JSObject*> result(cx);
710 0 : self->NamedGetter(cx, NonNullHelper(Constify(name)), found, &result, rv);
711 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
712 0 : return false;
713 : }
714 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
715 :
716 0 : if (found) {
717 0 : JS::ExposeObjectToActiveJS(result);
718 0 : vp.setObject(*result);
719 0 : if (!MaybeWrapObjectValue(cx, vp)) {
720 0 : return false;
721 : }
722 0 : return true;
723 : }
724 : }
725 :
726 : bool foundOnPrototype;
727 0 : if (!GetPropertyOnPrototype(cx, proxy, receiver, id, &foundOnPrototype, vp)) {
728 0 : return false;
729 : }
730 :
731 0 : if (foundOnPrototype) {
732 0 : return true;
733 : }
734 :
735 0 : vp.setUndefined();
736 0 : return true;
737 : }
738 :
739 : const char*
740 0 : DOMProxyHandler::className(JSContext* cx, JS::Handle<JSObject*> proxy) const
741 : {
742 0 : return "ImageDocument";
743 : }
744 :
745 : bool
746 0 : DOMProxyHandler::finalizeInBackground(const JS::Value& priv) const
747 : {
748 0 : return false;
749 : }
750 :
751 : void
752 0 : DOMProxyHandler::finalize(JSFreeOp* fop, JSObject* proxy) const
753 : {
754 0 : mozilla::dom::ImageDocument* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::ImageDocument>(proxy);
755 0 : if (self) {
756 : // Either our proxy created an expando object or not. If it did,
757 : // then we would have preserved ourselves, and hence if we're going
758 : // away so is our C++ object and we should reset its expando value.
759 : // It's possible that in this situation the C++ object's reflector
760 : // pointer has been nulled out, but if not it's pointing to us. If
761 : // our proxy did _not_ create an expando object then it's possible
762 : // that we're no longer the reflector for our C++ object (and
763 : // incremental finalization is finally getting to us), and that in
764 : // the meantime the new reflector has created an expando object.
765 : // In that case we do NOT want to clear the expando pointer in the
766 : // C++ object.
767 : //
768 : // It's important to do this before we ClearWrapper, of course.
769 0 : JSObject* reflector = self->GetWrapperMaybeDead();
770 0 : if (!reflector || reflector == proxy) {
771 0 : self->mExpandoAndGeneration.expando = JS::UndefinedValue();
772 : }
773 0 : ClearWrapper(self, self, proxy);
774 0 : AddForDeferredFinalization<mozilla::dom::ImageDocument>(self);
775 : }
776 0 : }
777 :
778 : const DOMProxyHandler*
779 0 : DOMProxyHandler::getInstance()
780 : {
781 : static const DOMProxyHandler instance;
782 0 : return &instance;
783 : }
784 :
785 : bool
786 0 : DOMProxyHandler::delete_(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, JS::ObjectOpResult& opresult) const
787 : {
788 0 : MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
789 : "Should not have a XrayWrapper here");
790 :
791 : // Try named delete only if the named property visibility
792 : // algorithm says the property is visible.
793 0 : bool tryNamedDelete = true;
794 : { // Scope for expando
795 0 : JS::Rooted<JSObject*> expando(cx, DOMProxyHandler::GetExpandoObject(proxy));
796 0 : if (expando) {
797 : bool hasProp;
798 0 : if (!JS_HasPropertyById(cx, expando, id, &hasProp)) {
799 0 : return false;
800 : }
801 0 : tryNamedDelete = !hasProp;
802 : }
803 : }
804 0 : if (tryNamedDelete) {
805 0 : bool found = false;
806 : bool deleteSucceeded;
807 0 : binding_detail::FakeString name;
808 : bool isSymbol;
809 0 : if (!ConvertIdToString(cx, id, name, isSymbol)) {
810 0 : return false;
811 : }
812 0 : if (!isSymbol) {
813 0 : mozilla::dom::ImageDocument* self = UnwrapProxy(proxy);
814 0 : binding_detail::FastErrorResult rv;
815 0 : JS::Rooted<JSObject*> result(cx);
816 0 : self->NamedGetter(cx, NonNullHelper(Constify(name)), found, &result, rv);
817 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
818 0 : return false;
819 : }
820 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
821 : (void)result;
822 : }
823 0 : deleteSucceeded = !found;
824 0 : if (found) {
825 0 : return deleteSucceeded ? opresult.succeed() : opresult.failCantDelete();
826 : }
827 : }
828 :
829 0 : return dom::DOMProxyHandler::delete_(cx, proxy, id, opresult);
830 : }
831 :
832 : static const js::ClassExtension sClassExtension = PROXY_MAKE_EXT(
833 : _objectMoved
834 : );
835 :
836 : static const DOMJSClass sClass = {
837 : PROXY_CLASS_WITH_EXT("ImageDocument",
838 : JSCLASS_IS_DOMJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(1),
839 : &sClassExtension),
840 : { prototypes::id::EventTarget, prototypes::id::Node, prototypes::id::Document, prototypes::id::HTMLDocument, prototypes::id::ImageDocument, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
841 : IsBaseOf<nsISupports, mozilla::dom::ImageDocument >::value,
842 : sNativePropertyHooks,
843 : FindAssociatedGlobalForNative<mozilla::dom::ImageDocument>::Get,
844 : GetProtoObjectHandle,
845 : GetCCParticipant<mozilla::dom::ImageDocument>::Get()
846 : };
847 :
848 : bool
849 0 : Wrap(JSContext* aCx, mozilla::dom::ImageDocument* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
850 : {
851 : MOZ_ASSERT(static_cast<mozilla::dom::ImageDocument*>(aObject) ==
852 : reinterpret_cast<mozilla::dom::ImageDocument*>(aObject),
853 : "Multiple inheritance for mozilla::dom::ImageDocument is broken.");
854 : MOZ_ASSERT(static_cast<nsHTMLDocument*>(aObject) ==
855 : reinterpret_cast<nsHTMLDocument*>(aObject),
856 : "Multiple inheritance for nsHTMLDocument is broken.");
857 : MOZ_ASSERT(static_cast<nsIDocument*>(aObject) ==
858 : reinterpret_cast<nsIDocument*>(aObject),
859 : "Multiple inheritance for nsIDocument is broken.");
860 : MOZ_ASSERT(static_cast<nsINode*>(aObject) ==
861 : reinterpret_cast<nsINode*>(aObject),
862 : "Multiple inheritance for nsINode is broken.");
863 : MOZ_ASSERT(static_cast<mozilla::dom::EventTarget*>(aObject) ==
864 : reinterpret_cast<mozilla::dom::EventTarget*>(aObject),
865 : "Multiple inheritance for mozilla::dom::EventTarget is broken.");
866 0 : MOZ_ASSERT(ToSupportsIsCorrect(aObject));
867 0 : MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
868 0 : MOZ_ASSERT(!aCache->GetWrapper(),
869 : "You should probably not be using Wrap() directly; use "
870 : "GetOrCreateDOMReflector instead");
871 :
872 0 : MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
873 : "nsISupports must be on our primary inheritance chain");
874 :
875 0 : JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
876 0 : if (!global) {
877 0 : return false;
878 : }
879 0 : MOZ_ASSERT(JS_IsGlobalObject(global));
880 0 : MOZ_ASSERT(JS::ObjectIsNotGray(global));
881 :
882 : // That might have ended up wrapping us already, due to the wonders
883 : // of XBL. Check for that, and bail out as needed.
884 0 : aReflector.set(aCache->GetWrapper());
885 0 : if (aReflector) {
886 : #ifdef DEBUG
887 0 : binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
888 : #endif // DEBUG
889 0 : return true;
890 : }
891 :
892 0 : JSAutoCompartment ac(aCx, global);
893 0 : JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
894 0 : if (!canonicalProto) {
895 0 : return false;
896 : }
897 0 : JS::Rooted<JSObject*> proto(aCx);
898 0 : if (aGivenProto) {
899 0 : proto = aGivenProto;
900 : // Unfortunately, while aGivenProto was in the compartment of aCx
901 : // coming in, we changed compartments to that of "parent" so may need
902 : // to wrap the proto here.
903 0 : if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
904 0 : if (!JS_WrapObject(aCx, &proto)) {
905 0 : return false;
906 : }
907 : }
908 : } else {
909 0 : proto = canonicalProto;
910 : }
911 :
912 0 : BindingJSObjectCreator<mozilla::dom::ImageDocument> creator(aCx);
913 0 : JS::Rooted<JS::Value> expandoValue(aCx, JS::PrivateValue(&aObject->mExpandoAndGeneration));
914 0 : creator.CreateProxyObject(aCx, &sClass.mBase, DOMProxyHandler::getInstance(),
915 0 : proto, aObject, expandoValue, aReflector);
916 0 : if (!aReflector) {
917 0 : return false;
918 : }
919 :
920 :
921 0 : aCache->SetWrapper(aReflector);
922 :
923 : // Important: do unforgeable property setup after we have handed
924 : // over ownership of the C++ object to obj as needed, so that if
925 : // we fail and it ends up GCed it won't have problems in the
926 : // finalizer trying to drop its ownership of the C++ object.
927 : JS::Rooted<JSObject*> expando(aCx,
928 0 : DOMProxyHandler::EnsureExpandoObject(aCx, aReflector));
929 0 : if (!expando) {
930 0 : aCache->ReleaseWrapper(aObject);
931 0 : aCache->ClearWrapper();
932 0 : return false;
933 : }
934 : JS::Rooted<JSObject*> unforgeableHolder(aCx,
935 0 : &js::GetReservedSlot(canonicalProto, DOM_INTERFACE_PROTO_SLOTS_BASE).toObject());
936 0 : if (!JS_InitializePropertiesFromCompatibleNativeObject(aCx, expando, unforgeableHolder)) {
937 0 : aCache->ReleaseWrapper(aObject);
938 0 : aCache->ClearWrapper();
939 0 : return false;
940 : }
941 0 : creator.InitializationSucceeded();
942 :
943 0 : MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
944 : aCache->GetWrapperPreserveColor() == aReflector);
945 : // If proto != canonicalProto, we have to preserve our wrapper;
946 : // otherwise we won't be able to properly recreate it later, since
947 : // we won't know what proto to use. Note that we don't check
948 : // aGivenProto here, since it's entirely possible (and even
949 : // somewhat common) to have a non-null aGivenProto which is the
950 : // same as canonicalProto.
951 0 : if (proto != canonicalProto) {
952 0 : PreserveWrapper(aObject);
953 : }
954 :
955 0 : return true;
956 : }
957 :
958 : static bool
959 0 : ResolveOwnProperty(JSContext* cx, JS::Handle<JSObject*> wrapper, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::MutableHandle<JS::PropertyDescriptor> desc)
960 : {
961 0 : return js::GetProxyHandler(obj)->getOwnPropertyDescriptor(cx, wrapper, id, desc);
962 : }
963 :
964 : static bool
965 0 : EnumerateOwnProperties(JSContext* cx, JS::Handle<JSObject*> wrapper, JS::Handle<JSObject*> obj, JS::AutoIdVector& props)
966 : {
967 0 : return js::GetProxyHandler(obj)->ownPropertyKeys(cx, wrapper, props);
968 : }
969 :
970 : const NativePropertyHooks sNativePropertyHooks[] = { {
971 : ResolveOwnProperty,
972 : EnumerateOwnProperties,
973 : nullptr,
974 : { sNativeProperties.Upcast(), nullptr },
975 : prototypes::id::ImageDocument,
976 : constructors::id::ImageDocument,
977 : HTMLDocumentBinding::sNativePropertyHooks,
978 : &DefaultXrayExpandoObjectClass
979 : } };
980 :
981 : void
982 0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
983 : {
984 0 : JS::Handle<JSObject*> parentProto(HTMLDocumentBinding::GetProtoObjectHandle(aCx));
985 0 : if (!parentProto) {
986 0 : return;
987 : }
988 :
989 0 : JS::Handle<JSObject*> constructorProto(HTMLDocumentBinding::GetConstructorObjectHandle(aCx));
990 0 : if (!constructorProto) {
991 0 : return;
992 : }
993 :
994 : static bool sIdsInited = false;
995 0 : if (!sIdsInited && NS_IsMainThread()) {
996 0 : if (!InitIds(aCx, sNativeProperties.Upcast())) {
997 0 : return;
998 : }
999 0 : sIdsInited = true;
1000 : }
1001 :
1002 0 : JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::ImageDocument);
1003 0 : JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::ImageDocument);
1004 0 : dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
1005 : &sPrototypeClass.mBase, protoCache,
1006 : constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
1007 : interfaceCache,
1008 : sNativeProperties.Upcast(),
1009 : nullptr,
1010 : "ImageDocument", aDefineOnGlobal,
1011 : nullptr,
1012 0 : false);
1013 :
1014 0 : JS::Rooted<JSObject*> unforgeableHolder(aCx);
1015 : {
1016 0 : JS::Rooted<JSObject*> holderProto(aCx, nullptr);
1017 0 : unforgeableHolder = JS_NewObjectWithoutMetadata(aCx, nullptr, holderProto);
1018 0 : if (!unforgeableHolder) {
1019 0 : *protoCache = nullptr;
1020 0 : if (interfaceCache) {
1021 0 : *interfaceCache = nullptr;
1022 : }
1023 0 : return;
1024 : }
1025 : }
1026 :
1027 0 : if (!DefineUnforgeableAttributes(aCx, unforgeableHolder, sUnforgeableAttributes)) {
1028 0 : *protoCache = nullptr;
1029 0 : if (interfaceCache) {
1030 0 : *interfaceCache = nullptr;
1031 : }
1032 0 : return;
1033 : }
1034 :
1035 0 : if (*protoCache) {
1036 0 : js::SetReservedSlot(*protoCache, DOM_INTERFACE_PROTO_SLOTS_BASE,
1037 0 : JS::ObjectValue(*unforgeableHolder));
1038 : }
1039 : }
1040 :
1041 : JS::Handle<JSObject*>
1042 0 : GetProtoObjectHandle(JSContext* aCx)
1043 : {
1044 : /* Get the interface prototype object for this class. This will create the
1045 : object as needed. */
1046 0 : bool aDefineOnGlobal = true;
1047 :
1048 : /* Make sure our global is sane. Hopefully we can remove this sometime */
1049 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
1050 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
1051 0 : return nullptr;
1052 : }
1053 :
1054 : /* Check to see whether the interface objects are already installed */
1055 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
1056 0 : if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::ImageDocument)) {
1057 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
1058 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
1059 : }
1060 :
1061 : /*
1062 : * The object might _still_ be null, but that's OK.
1063 : *
1064 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
1065 : * traced by TraceProtoAndIfaceCache() and its contents are never
1066 : * changed after they have been set.
1067 : *
1068 : * Calling address() avoids the read read barrier that does gray
1069 : * unmarking, but it's not possible for the object to be gray here.
1070 : */
1071 :
1072 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::ImageDocument);
1073 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
1074 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
1075 : }
1076 :
1077 : JS::Handle<JSObject*>
1078 0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
1079 : {
1080 : /* Get the interface object for this class. This will create the object as
1081 : needed. */
1082 :
1083 : /* Make sure our global is sane. Hopefully we can remove this sometime */
1084 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
1085 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
1086 0 : return nullptr;
1087 : }
1088 :
1089 : /* Check to see whether the interface objects are already installed */
1090 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
1091 0 : if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::ImageDocument)) {
1092 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
1093 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
1094 : }
1095 :
1096 : /*
1097 : * The object might _still_ be null, but that's OK.
1098 : *
1099 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
1100 : * traced by TraceProtoAndIfaceCache() and its contents are never
1101 : * changed after they have been set.
1102 : *
1103 : * Calling address() avoids the read read barrier that does gray
1104 : * unmarking, but it's not possible for the object to be gray here.
1105 : */
1106 :
1107 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::ImageDocument);
1108 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
1109 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
1110 : }
1111 :
1112 : JSObject*
1113 0 : GetConstructorObject(JSContext* aCx)
1114 : {
1115 0 : return GetConstructorObjectHandle(aCx);
1116 : }
1117 :
1118 : } // namespace ImageDocumentBinding
1119 :
1120 :
1121 :
1122 : } // namespace dom
1123 : } // namespace mozilla
|