Coverage Report

Created: 2018-09-25 14:53

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