Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dom/bindings/HTMLAllCollectionBinding.cpp
Line
Count
Source (jump to first uncovered line)
1
/* THIS FILE IS AUTOGENERATED FROM HTMLAllCollection.webidl BY Codegen.py - DO NOT EDIT */
2
3
#include "HTMLAllCollectionBinding.h"
4
#include "WrapperFactory.h"
5
#include "mozilla/OwningNonNull.h"
6
#include "mozilla/dom/BindingUtils.h"
7
#include "mozilla/dom/DOMJSClass.h"
8
#include "mozilla/dom/DOMJSProxyHandler.h"
9
#include "mozilla/dom/HTMLAllCollection.h"
10
#include "mozilla/dom/NonRefcountedDOMObject.h"
11
#include "mozilla/dom/Nullable.h"
12
#include "mozilla/dom/PrimitiveConversions.h"
13
#include "mozilla/dom/UnionConversions.h"
14
#include "mozilla/dom/XrayExpandoClass.h"
15
#include "nsContentList.h"
16
#include "nsINode.h"
17
18
namespace mozilla {
19
namespace dom {
20
21
namespace binding_detail {}; // Just to make sure it's known as a namespace
22
using namespace mozilla::dom::binding_detail;
23
24
25
void
26
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, OwningNodeOrHTMLCollection& aUnion, const char* aName, uint32_t aFlags)
27
0
{
28
0
  if (aUnion.IsNode()) {
29
0
    ImplCycleCollectionTraverse(aCallback, aUnion.GetAsNode(), "mNode", aFlags);
30
0
  } else if (aUnion.IsHTMLCollection()) {
31
0
    ImplCycleCollectionTraverse(aCallback, aUnion.GetAsHTMLCollection(), "mHTMLCollection", aFlags);
32
0
  }
33
0
}
34
35
36
void
37
ImplCycleCollectionUnlink(OwningNodeOrHTMLCollection& aUnion)
38
0
{
39
0
  aUnion.Uninit();
40
0
}
41
42
43
bool
44
NodeOrHTMLCollection::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
45
0
{
46
0
  switch (mType) {
47
0
    case eUninitialized: {
48
0
      return false;
49
0
      break;
50
0
    }
51
0
    case eNode: {
52
0
      if (!GetOrCreateDOMReflector(cx, mValue.mNode.Value(), rval)) {
53
0
        MOZ_ASSERT(JS_IsExceptionPending(cx));
54
0
        return false;
55
0
      }
56
0
      return true;
57
0
      break;
58
0
    }
59
0
    case eHTMLCollection: {
60
0
      if (!GetOrCreateDOMReflector(cx, mValue.mHTMLCollection.Value(), rval)) {
61
0
        MOZ_ASSERT(JS_IsExceptionPending(cx));
62
0
        return false;
63
0
      }
64
0
      return true;
65
0
      break;
66
0
    }
67
0
    default: {
68
0
      return false;
69
0
      break;
70
0
    }
71
0
  }
72
0
73
0
  return false;
74
0
}
75
76
77
OwningNonNull<nsINode>&
78
OwningNodeOrHTMLCollection::RawSetAsNode()
79
0
{
80
0
  if (mType == eNode) {
81
0
    return mValue.mNode.Value();
82
0
  }
83
0
  MOZ_ASSERT(mType == eUninitialized);
84
0
  mType = eNode;
85
0
  return mValue.mNode.SetValue();
86
0
}
87
88
OwningNonNull<nsINode>&
89
OwningNodeOrHTMLCollection::SetAsNode()
90
0
{
91
0
  if (mType == eNode) {
92
0
    return mValue.mNode.Value();
93
0
  }
94
0
  Uninit();
95
0
  mType = eNode;
96
0
  return mValue.mNode.SetValue();
97
0
}
98
99
bool
100
OwningNodeOrHTMLCollection::TrySetToNode(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
101
0
{
102
0
  tryNext = false;
103
0
  { // scope for memberSlot
104
0
    OwningNonNull<nsINode>& memberSlot = RawSetAsNode();
105
0
    static_assert(IsRefcounted<nsINode>::value, "We can only store refcounted classes.");{
106
0
      nsresult rv = UnwrapObject<prototypes::id::Node, nsINode>(value, memberSlot);
107
0
      if (NS_FAILED(rv)) {
108
0
        DestroyNode();
109
0
        tryNext = true;
110
0
        return true;
111
0
      }
112
0
    }
113
0
  }
114
0
  return true;
115
0
}
116
117
void
118
OwningNodeOrHTMLCollection::DestroyNode()
119
0
{
120
0
  MOZ_ASSERT(IsNode(), "Wrong type!");
121
0
  mValue.mNode.Destroy();
122
0
  mType = eUninitialized;
123
0
}
124
125
126
127
128
OwningNonNull<nsIHTMLCollection>&
129
OwningNodeOrHTMLCollection::RawSetAsHTMLCollection()
130
0
{
131
0
  if (mType == eHTMLCollection) {
132
0
    return mValue.mHTMLCollection.Value();
133
0
  }
134
0
  MOZ_ASSERT(mType == eUninitialized);
135
0
  mType = eHTMLCollection;
136
0
  return mValue.mHTMLCollection.SetValue();
137
0
}
138
139
OwningNonNull<nsIHTMLCollection>&
140
OwningNodeOrHTMLCollection::SetAsHTMLCollection()
141
0
{
142
0
  if (mType == eHTMLCollection) {
143
0
    return mValue.mHTMLCollection.Value();
144
0
  }
145
0
  Uninit();
146
0
  mType = eHTMLCollection;
147
0
  return mValue.mHTMLCollection.SetValue();
148
0
}
149
150
bool
151
OwningNodeOrHTMLCollection::TrySetToHTMLCollection(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
152
0
{
153
0
  tryNext = false;
154
0
  { // scope for memberSlot
155
0
    OwningNonNull<nsIHTMLCollection>& memberSlot = RawSetAsHTMLCollection();
156
0
    static_assert(IsRefcounted<nsIHTMLCollection>::value, "We can only store refcounted classes.");{
157
0
      nsresult rv = UnwrapObject<prototypes::id::HTMLCollection, nsIHTMLCollection>(value, memberSlot);
158
0
      if (NS_FAILED(rv)) {
159
0
        DestroyHTMLCollection();
160
0
        tryNext = true;
161
0
        return true;
162
0
      }
163
0
    }
164
0
  }
165
0
  return true;
166
0
}
167
168
void
169
OwningNodeOrHTMLCollection::DestroyHTMLCollection()
170
0
{
171
0
  MOZ_ASSERT(IsHTMLCollection(), "Wrong type!");
172
0
  mValue.mHTMLCollection.Destroy();
173
0
  mType = eUninitialized;
174
0
}
175
176
177
178
179
void
180
OwningNodeOrHTMLCollection::Uninit()
181
{
182
  switch (mType) {
183
    case eUninitialized: {
184
      break;
185
    }
186
    case eNode: {
187
      DestroyNode();
188
      break;
189
    }
190
    case eHTMLCollection: {
191
      DestroyHTMLCollection();
192
      break;
193
    }
194
  }
195
}
196
197
bool
198
OwningNodeOrHTMLCollection::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
199
0
{
200
0
  switch (mType) {
201
0
    case eUninitialized: {
202
0
      return false;
203
0
      break;
204
0
    }
205
0
    case eNode: {
206
0
      if (!GetOrCreateDOMReflector(cx, mValue.mNode.Value(), rval)) {
207
0
        MOZ_ASSERT(JS_IsExceptionPending(cx));
208
0
        return false;
209
0
      }
210
0
      return true;
211
0
      break;
212
0
    }
213
0
    case eHTMLCollection: {
214
0
      if (!GetOrCreateDOMReflector(cx, mValue.mHTMLCollection.Value(), rval)) {
215
0
        MOZ_ASSERT(JS_IsExceptionPending(cx));
216
0
        return false;
217
0
      }
218
0
      return true;
219
0
      break;
220
0
    }
221
0
    default: {
222
0
      return false;
223
0
      break;
224
0
    }
225
0
  }
226
0
227
0
  return false;
228
0
}
229
230
void
231
OwningNodeOrHTMLCollection::TraceUnion(JSTracer* trc)
232
0
{
233
0
}
234
235
OwningNodeOrHTMLCollection&
236
OwningNodeOrHTMLCollection::operator=(const OwningNodeOrHTMLCollection& aOther)
237
0
{
238
0
  switch (aOther.mType) {
239
0
    case eUninitialized: {
240
0
      MOZ_ASSERT(mType == eUninitialized,
241
0
                 "We need to destroy ourselves?");
242
0
      break;
243
0
    }
244
0
    case eNode: {
245
0
      SetAsNode() = aOther.GetAsNode();
246
0
      break;
247
0
    }
248
0
    case eHTMLCollection: {
249
0
      SetAsHTMLCollection() = aOther.GetAsHTMLCollection();
250
0
      break;
251
0
    }
252
0
  }
253
0
  return *this;
254
0
}
255
256
257
namespace HTMLAllCollection_Binding {
258
259
MOZ_CAN_RUN_SCRIPT static bool
260
get_length(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::HTMLAllCollection* self, JSJitGetterCallArgs args)
261
0
{
262
0
  AUTO_PROFILER_LABEL_FAST("get HTMLAllCollection.length", DOM, cx);
263
0
264
0
  uint32_t result(self->Length());
265
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
266
0
  args.rval().setNumber(result);
267
0
  return true;
268
0
}
269
270
static const JSJitInfo length_getterinfo = {
271
  { (JSJitGetterOp)get_length },
272
  { prototypes::id::HTMLAllCollection },
273
  { PrototypeTraits<prototypes::id::HTMLAllCollection>::Depth },
274
  JSJitInfo::Getter,
275
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
276
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
277
  true,  /* isInfallible. False in setters. */
278
  false,  /* isMovable.  Not relevant for setters. */
279
  false, /* isEliminatable.  Not relevant for setters. */
280
  false, /* isAlwaysInSlot.  Only relevant for getters. */
281
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
282
  false,  /* isTypedMethod.  Only relevant for methods. */
283
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
284
};
285
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
286
static_assert(0 < 1, "There is no slot for us");
287
288
MOZ_CAN_RUN_SCRIPT static bool
289
item(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::HTMLAllCollection* self, const JSJitMethodCallArgs& args)
290
0
{
291
0
  AUTO_PROFILER_LABEL_FAST("HTMLAllCollection.item", DOM, cx);
292
0
293
0
  unsigned argcount = std::min(args.length(), 1u);
294
0
  switch (argcount) {
295
0
    case 1: {
296
0
      if (args[0].isNumber()) {
297
0
        uint32_t arg0;
298
0
        if (!ValueToPrimitive<uint32_t, eDefault>(cx, args[0], &arg0)) {
299
0
          return false;
300
0
        }
301
0
        auto result(StrongOrRawPtr<nsINode>(self->Item(arg0)));
302
0
        MOZ_ASSERT(!JS_IsExceptionPending(cx));
303
0
        if (!result) {
304
0
          args.rval().setNull();
305
0
          return true;
306
0
        }
307
0
        if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
308
0
          MOZ_ASSERT(JS_IsExceptionPending(cx));
309
0
          return false;
310
0
        }
311
0
        return true;
312
0
      }
313
0
      binding_detail::FakeString arg0;
314
0
      if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
315
0
        return false;
316
0
      }
317
0
      Nullable<OwningNodeOrHTMLCollection> result;
318
0
      self->Item(NonNullHelper(Constify(arg0)), result);
319
0
      MOZ_ASSERT(!JS_IsExceptionPending(cx));
320
0
      if (result.IsNull()) {
321
0
        args.rval().setNull();
322
0
        return true;
323
0
      }
324
0
      if (!result.Value().ToJSVal(cx, obj, args.rval())) {
325
0
        return false;
326
0
      }
327
0
      return true;
328
0
      break;
329
0
    }
330
0
    default: {
331
0
      return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "HTMLAllCollection.item");
332
0
      break;
333
0
    }
334
0
  }
335
0
  MOZ_CRASH("We have an always-returning default case");
336
0
  return false;
337
0
}
338
339
static const JSJitInfo item_methodinfo = {
340
  { (JSJitGetterOp)item },
341
  { prototypes::id::HTMLAllCollection },
342
  { PrototypeTraits<prototypes::id::HTMLAllCollection>::Depth },
343
  JSJitInfo::Method,
344
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
345
  JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
346
  false,  /* isInfallible. False in setters. */
347
  false,  /* isMovable.  Not relevant for setters. */
348
  false, /* isEliminatable.  Not relevant for setters. */
349
  false, /* isAlwaysInSlot.  Only relevant for getters. */
350
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
351
  false,  /* isTypedMethod.  Only relevant for methods. */
352
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
353
};
354
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
355
static_assert(0 < 1, "There is no slot for us");
356
357
MOZ_CAN_RUN_SCRIPT static bool
358
namedItem(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::HTMLAllCollection* self, const JSJitMethodCallArgs& args)
359
0
{
360
0
  AUTO_PROFILER_LABEL_FAST("HTMLAllCollection.namedItem", DOM, cx);
361
0
362
0
  if (MOZ_UNLIKELY(args.length() < 1)) {
363
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "HTMLAllCollection.namedItem");
364
0
  }
365
0
  binding_detail::FakeString arg0;
366
0
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
367
0
    return false;
368
0
  }
369
0
  Nullable<OwningNodeOrHTMLCollection> result;
370
0
  self->NamedItem(NonNullHelper(Constify(arg0)), result);
371
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
372
0
  if (result.IsNull()) {
373
0
    args.rval().setNull();
374
0
    return true;
375
0
  }
376
0
  if (!result.Value().ToJSVal(cx, obj, args.rval())) {
377
0
    return false;
378
0
  }
379
0
  return true;
380
0
}
381
382
static const JSJitInfo namedItem_methodinfo = {
383
  { (JSJitGetterOp)namedItem },
384
  { prototypes::id::HTMLAllCollection },
385
  { PrototypeTraits<prototypes::id::HTMLAllCollection>::Depth },
386
  JSJitInfo::Method,
387
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
388
  JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
389
  false,  /* isInfallible. False in setters. */
390
  false,  /* isMovable.  Not relevant for setters. */
391
  false, /* isEliminatable.  Not relevant for setters. */
392
  false, /* isAlwaysInSlot.  Only relevant for getters. */
393
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
394
  false,  /* isTypedMethod.  Only relevant for methods. */
395
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
396
};
397
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
398
static_assert(0 < 1, "There is no slot for us");
399
400
// We deliberately use brace-elision to make Visual Studio produce better initalization code.
401
#if defined(__clang__)
402
#pragma clang diagnostic push
403
#pragma clang diagnostic ignored "-Wmissing-braces"
404
#endif
405
static const JSFunctionSpec sMethods_specs[] = {
406
  JS_FNSPEC("item", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&item_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
407
  JS_FNSPEC("namedItem", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&namedItem_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
408
  JS_SYM_FNSPEC(iterator, nullptr, nullptr, 0, 0, "ArrayValues"),
409
  JS_FS_END
410
};
411
#if defined(__clang__)
412
#pragma clang diagnostic pop
413
#endif
414
415
416
static const Prefable<const JSFunctionSpec> sMethods[] = {
417
  { nullptr, &sMethods_specs[0] },
418
  { nullptr, nullptr }
419
};
420
421
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
422
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
423
static_assert(3 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
424
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
425
426
// We deliberately use brace-elision to make Visual Studio produce better initalization code.
427
#if defined(__clang__)
428
#pragma clang diagnostic push
429
#pragma clang diagnostic ignored "-Wmissing-braces"
430
#endif
431
static const JSPropertySpec sAttributes_specs[] = {
432
  { "length", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &length_getterinfo, nullptr, nullptr },
433
  { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
434
};
435
#if defined(__clang__)
436
#pragma clang diagnostic pop
437
#endif
438
439
440
static const Prefable<const JSPropertySpec> sAttributes[] = {
441
  { nullptr, &sAttributes_specs[0] },
442
  { nullptr, nullptr }
443
};
444
445
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
446
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
447
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
448
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
449
450
451
static uint16_t sNativeProperties_sortedPropertyIndices[4];
452
static PropertyInfo sNativeProperties_propertyInfos[4];
453
454
static const NativePropertiesN<2> sNativeProperties = {
455
  false, 0,
456
  false, 0,
457
  true,  0 /* sMethods */,
458
  true,  1 /* sAttributes */,
459
  false, 0,
460
  false, 0,
461
  false, 0,
462
  -1,
463
  4,
464
  sNativeProperties_sortedPropertyIndices,
465
  {
466
    { sMethods, &sNativeProperties_propertyInfos[0] },
467
    { sAttributes, &sNativeProperties_propertyInfos[3] }
468
  }
469
};
470
static_assert(4 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
471
    "We have a property info count that is oversized");
472
473
static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
474
  {
475
    "Function",
476
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
477
    &sBoringInterfaceObjectClassClassOps,
478
    JS_NULL_CLASS_SPEC,
479
    JS_NULL_CLASS_EXT,
480
    &sInterfaceObjectClassObjectOps
481
  },
482
  eInterface,
483
  true,
484
  prototypes::id::HTMLAllCollection,
485
  PrototypeTraits<prototypes::id::HTMLAllCollection>::Depth,
486
  sNativePropertyHooks,
487
  "function HTMLAllCollection() {\n    [native code]\n}",
488
  JS::GetRealmFunctionPrototype
489
};
490
491
static bool
492
_legacycaller(JSContext* cx, unsigned argc, JS::Value* vp)
493
0
{
494
0
  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
495
0
  JS::Rooted<JSObject*> obj(cx, &args.callee());
496
0
497
0
  mozilla::dom::HTMLAllCollection* self;
498
0
  JS::Rooted<JS::Value> rootSelf(cx, JS::ObjectValue(*obj));
499
0
  {
500
0
    nsresult rv = UnwrapObject<prototypes::id::HTMLAllCollection, mozilla::dom::HTMLAllCollection>(&rootSelf, self);
501
0
    if (NS_FAILED(rv)) {
502
0
      return ThrowErrorMessage(cx, MSG_THIS_DOES_NOT_IMPLEMENT_INTERFACE, "Value", "HTMLAllCollection");
503
0
    }
504
0
  }
505
0
  if (MOZ_UNLIKELY(args.length() < 1)) {
506
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "HTMLAllCollection.__legacycaller");
507
0
  }
508
0
  binding_detail::FakeString arg0;
509
0
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
510
0
    return false;
511
0
  }
512
0
  Nullable<OwningNodeOrHTMLCollection> result;
513
0
  self->LegacyCall(args.thisv(), NonNullHelper(Constify(arg0)), result);
514
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
515
0
  if (result.IsNull()) {
516
0
    args.rval().setNull();
517
0
    return true;
518
0
  }
519
0
  if (!result.Value().ToJSVal(cx, obj, args.rval())) {
520
0
    return false;
521
0
  }
522
0
  return true;
523
0
}
524
525
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
526
  {
527
    "HTMLAllCollectionPrototype",
528
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
529
    JS_NULL_CLASS_OPS,
530
    JS_NULL_CLASS_SPEC,
531
    JS_NULL_CLASS_EXT,
532
    JS_NULL_OBJECT_OPS
533
  },
534
  eInterfacePrototype,
535
  false,
536
  prototypes::id::HTMLAllCollection,
537
  PrototypeTraits<prototypes::id::HTMLAllCollection>::Depth,
538
  sNativePropertyHooks,
539
  "[object HTMLAllCollectionPrototype]",
540
  JS::GetRealmObjectPrototype
541
};
542
543
static_assert(IsBaseOf<nsISupports, mozilla::dom::HTMLAllCollection >::value,
544
                  "We don't support non-nsISupports native classes for "
545
                  "proxy-based bindings yet");
546
547
548
class DOMProxyHandler : public mozilla::dom::DOMProxyHandler
549
{
550
public:
551
  explicit constexpr DOMProxyHandler()
552
0
  {
553
0
  }
554
555
  virtual bool
556
  getOwnPropDescriptor(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool ignoreNamedProps, JS::MutableHandle<JS::PropertyDescriptor> desc) const override;
557
558
  virtual bool
559
  defineProperty(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, JS::Handle<JS::PropertyDescriptor> desc, JS::ObjectOpResult& opresult, bool* defined) const override;
560
561
  using mozilla::dom::DOMProxyHandler::defineProperty;
562
563
  virtual bool
564
  ownPropNames(JSContext* cx, JS::Handle<JSObject*> proxy, unsigned flags, JS::AutoIdVector& props) const override;
565
566
  virtual bool
567
  hasOwn(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool* bp) const override;
568
569
  virtual bool
570
  get(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<JS::Value> receiver, JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp) const override;
571
572
  virtual const char*
573
  className(JSContext* cx, JS::Handle<JSObject*> proxy) const override;
574
575
  virtual bool
576
  finalizeInBackground(const JS::Value& priv) const override;
577
578
  virtual void
579
  finalize(JSFreeOp* fop, JSObject* proxy) const override;
580
581
  static const DOMProxyHandler*
582
  getInstance();
583
584
  virtual bool
585
  delete_(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, JS::ObjectOpResult& opresult) const override;
586
587
  virtual bool
588
  getElements(JSContext* cx, JS::Handle<JSObject*> proxy, uint32_t begin, uint32_t end, js::ElementAdder* adder) const override;
589
590
  virtual bool
591
  call(JSContext* cx, JS::Handle<JSObject*> proxy, const JS::CallArgs& args) const override;
592
593
  virtual bool
594
  isCallable(JSObject* obj) const override;
595
596
  virtual size_t
597
  objectMoved(JSObject* obj, JSObject* old) const override;
598
};
599
600
MOZ_ALWAYS_INLINE bool
601
IsProxy(JSObject* obj)
602
0
{
603
0
  return js::IsProxy(obj) && js::GetProxyHandler(obj) == DOMProxyHandler::getInstance();
604
0
}
605
606
MOZ_ALWAYS_INLINE mozilla::dom::HTMLAllCollection*
607
UnwrapProxy(JSObject* obj)
608
0
{
609
0
  MOZ_ASSERT(js::IsProxy(obj));
610
0
  if (js::GetProxyHandler(obj) != DOMProxyHandler::getInstance()) {
611
0
    MOZ_ASSERT(xpc::WrapperFactory::IsXrayWrapper(obj));
612
0
    obj = js::UncheckedUnwrap(obj);
613
0
  }
614
0
  MOZ_ASSERT(IsProxy(obj));
615
0
  return static_cast<mozilla::dom::HTMLAllCollection*>(js::GetProxyReservedSlot(obj, DOM_OBJECT_SLOT).toPrivate());
616
0
}
617
618
bool
619
DOMProxyHandler::getOwnPropDescriptor(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool ignoreNamedProps, JS::MutableHandle<JS::PropertyDescriptor> desc) const
620
0
{
621
0
  bool isXray = xpc::WrapperFactory::IsXrayWrapper(proxy);
622
0
  uint32_t index = GetArrayIndexFromId(cx, id);
623
0
  if (IsArrayIndex(index)) {
624
0
    mozilla::dom::HTMLAllCollection* self = UnwrapProxy(proxy);
625
0
    bool found = false;
626
0
    auto result(StrongOrRawPtr<nsINode>(self->IndexedGetter(index, found)));
627
0
    MOZ_ASSERT(!JS_IsExceptionPending(cx));
628
0
629
0
    if (found) {
630
0
      if (!result) {
631
0
        desc.value().setNull();
632
0
        FillPropertyDescriptor(desc, proxy, true);
633
0
        return true;
634
0
      }
635
0
      if (!GetOrCreateDOMReflector(cx, result, desc.value())) {
636
0
        MOZ_ASSERT(JS_IsExceptionPending(cx));
637
0
        return false;
638
0
      }
639
0
      FillPropertyDescriptor(desc, proxy, true);
640
0
      return true;
641
0
    }
642
0
  }
643
0
644
0
  JS::Rooted<JSObject*> expando(cx);
645
0
  if (!isXray && (expando = GetExpandoObject(proxy))) {
646
0
    if (!JS_GetOwnPropertyDescriptorById(cx, expando, id, desc)) {
647
0
      return false;
648
0
    }
649
0
    if (desc.object()) {
650
0
      // Pretend the property lives on the wrapper.
651
0
      desc.object().set(proxy);
652
0
      return true;
653
0
    }
654
0
  }
655
0
656
0
  bool callNamedGetter = false;
657
0
  if (!IsArrayIndex(index) && !ignoreNamedProps) {
658
0
    bool hasOnProto;
659
0
    if (!HasPropertyOnPrototype(cx, proxy, id, &hasOnProto)) {
660
0
      return false;
661
0
    }
662
0
    callNamedGetter = !hasOnProto;
663
0
  }
664
0
  if (callNamedGetter) {
665
0
    FakeString name;
666
0
    bool isSymbol;
667
0
    if (!ConvertIdToString(cx, id, name, isSymbol)) {
668
0
      return false;
669
0
    }
670
0
    if (!isSymbol) {
671
0
      mozilla::dom::HTMLAllCollection* self = UnwrapProxy(proxy);
672
0
      bool found = false;
673
0
      Nullable<OwningNodeOrHTMLCollection> result;
674
0
      self->NamedGetter(NonNullHelper(Constify(name)), found, result);
675
0
      MOZ_ASSERT(!JS_IsExceptionPending(cx));
676
0
677
0
      if (found) {
678
0
        if (result.IsNull()) {
679
0
          desc.value().setNull();
680
0
          FillPropertyDescriptor(desc, proxy, true, false);
681
0
          return true;
682
0
        }
683
0
        if (!result.Value().ToJSVal(cx, proxy, desc.value())) {
684
0
          return false;
685
0
        }
686
0
        FillPropertyDescriptor(desc, proxy, true, false);
687
0
        return true;
688
0
      }
689
0
    }
690
0
  }
691
0
692
0
  desc.object().set(nullptr);
693
0
  return true;
694
0
}
695
696
bool
697
DOMProxyHandler::defineProperty(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, JS::Handle<JS::PropertyDescriptor> desc, JS::ObjectOpResult& opresult, bool* defined) const
698
0
{
699
0
  if (IsArrayIndex(GetArrayIndexFromId(cx, id))) {
700
0
    *defined = true;
701
0
    return opresult.failNoIndexedSetter();
702
0
  }
703
0
  bool found = false;
704
0
  FakeString name;
705
0
  bool isSymbol;
706
0
  if (!ConvertIdToString(cx, id, name, isSymbol)) {
707
0
    return false;
708
0
  }
709
0
  if (!isSymbol) {
710
0
    mozilla::dom::HTMLAllCollection* self = UnwrapProxy(proxy);
711
0
    Nullable<OwningNodeOrHTMLCollection> result;
712
0
    self->NamedGetter(NonNullHelper(Constify(name)), found, result);
713
0
    MOZ_ASSERT(!JS_IsExceptionPending(cx));
714
0
    (void)result;
715
0
  }
716
0
717
0
  if (found) {
718
0
    *defined = true;
719
0
    return opresult.failNoNamedSetter();
720
0
  }
721
0
  return mozilla::dom::DOMProxyHandler::defineProperty(cx, proxy, id, desc, opresult, defined);
722
0
}
723
724
725
bool
726
DOMProxyHandler::ownPropNames(JSContext* cx, JS::Handle<JSObject*> proxy, unsigned flags, JS::AutoIdVector& props) const
727
0
{
728
0
  bool isXray = xpc::WrapperFactory::IsXrayWrapper(proxy);
729
0
730
0
  uint32_t length = UnwrapProxy(proxy)->Length();
731
0
  MOZ_ASSERT(int32_t(length) >= 0);
732
0
  for (int32_t i = 0; i < int32_t(length); ++i) {
733
0
    if (!props.append(INT_TO_JSID(i))) {
734
0
      return false;
735
0
    }
736
0
  }
737
0
738
0
  if (flags & JSITER_HIDDEN) {
739
0
    nsTArray<nsString> names;
740
0
    UnwrapProxy(proxy)->GetSupportedNames(names);
741
0
    if (!AppendNamedPropertyIds(cx, proxy, names, false, props)) {
742
0
      return false;
743
0
    }
744
0
  }
745
0
746
0
  JS::Rooted<JSObject*> expando(cx);
747
0
  if (!isXray && (expando = DOMProxyHandler::GetExpandoObject(proxy)) &&
748
0
      !js::GetPropertyKeys(cx, expando, flags, &props)) {
749
0
    return false;
750
0
  }
751
0
752
0
  return true;
753
0
}
754
755
bool
756
DOMProxyHandler::hasOwn(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool* bp) const
757
0
{
758
0
  MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
759
0
            "Should not have a XrayWrapper here");
760
0
761
0
  uint32_t index = GetArrayIndexFromId(cx, id);
762
0
  if (IsArrayIndex(index)) {
763
0
    bool found = false;
764
0
    mozilla::dom::HTMLAllCollection* self = UnwrapProxy(proxy);
765
0
    auto result(StrongOrRawPtr<nsINode>(self->IndexedGetter(index, found)));
766
0
    MOZ_ASSERT(!JS_IsExceptionPending(cx));
767
0
    (void)result;
768
0
769
0
    *bp = found;
770
0
    return true;
771
0
  }
772
0
773
0
774
0
  JS::Rooted<JSObject*> expando(cx, GetExpandoObject(proxy));
775
0
  if (expando) {
776
0
    bool b = true;
777
0
    bool ok = JS_HasPropertyById(cx, expando, id, &b);
778
0
    *bp = !!b;
779
0
    if (!ok || *bp) {
780
0
      return ok;
781
0
    }
782
0
  }
783
0
784
0
  bool hasOnProto;
785
0
  if (!HasPropertyOnPrototype(cx, proxy, id, &hasOnProto)) {
786
0
    return false;
787
0
  }
788
0
  if (!hasOnProto) {
789
0
    bool found = false;
790
0
    FakeString name;
791
0
    bool isSymbol;
792
0
    if (!ConvertIdToString(cx, id, name, isSymbol)) {
793
0
      return false;
794
0
    }
795
0
    if (!isSymbol) {
796
0
      mozilla::dom::HTMLAllCollection* self = UnwrapProxy(proxy);
797
0
      Nullable<OwningNodeOrHTMLCollection> result;
798
0
      self->NamedGetter(NonNullHelper(Constify(name)), found, result);
799
0
      MOZ_ASSERT(!JS_IsExceptionPending(cx));
800
0
      (void)result;
801
0
    }
802
0
803
0
    *bp = found;
804
0
    return true;
805
0
  }
806
0
  *bp = false;
807
0
  return true;
808
0
}
809
810
bool
811
DOMProxyHandler::get(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<JS::Value> receiver, JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp) const
812
0
{
813
0
  MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
814
0
              "Should not have a XrayWrapper here");
815
0
816
0
  uint32_t index = GetArrayIndexFromId(cx, id);
817
0
  if (IsArrayIndex(index)) {
818
0
    mozilla::dom::HTMLAllCollection* self = UnwrapProxy(proxy);
819
0
    bool found = false;
820
0
    auto result(StrongOrRawPtr<nsINode>(self->IndexedGetter(index, found)));
821
0
    MOZ_ASSERT(!JS_IsExceptionPending(cx));
822
0
823
0
    if (found) {
824
0
      if (!result) {
825
0
        vp.setNull();
826
0
        return true;
827
0
      }
828
0
      if (!GetOrCreateDOMReflector(cx, result, vp)) {
829
0
        MOZ_ASSERT(JS_IsExceptionPending(cx));
830
0
        return false;
831
0
      }
832
0
      return true;
833
0
    }
834
0
    // Even if we don't have this index, we don't forward the
835
0
    // get on to our expando object.
836
0
  } else {
837
0
    { // Scope for expando
838
0
      JS::Rooted<JSObject*> expando(cx, DOMProxyHandler::GetExpandoObject(proxy));
839
0
      if (expando) {
840
0
        bool hasProp;
841
0
        if (!JS_HasPropertyById(cx, expando, id, &hasProp)) {
842
0
          return false;
843
0
        }
844
0
845
0
        if (hasProp) {
846
0
          // Forward the get to the expando object, but our receiver is whatever our
847
0
          // receiver is.
848
0
          return JS_ForwardGetPropertyTo(cx, expando, id, receiver, vp);
849
0
        }
850
0
      }
851
0
    }
852
0
  }
853
0
854
0
  bool foundOnPrototype;
855
0
  if (!GetPropertyOnPrototype(cx, proxy, receiver, id, &foundOnPrototype, vp)) {
856
0
    return false;
857
0
  }
858
0
859
0
  if (foundOnPrototype) {
860
0
    return true;
861
0
  }
862
0
863
0
  if (!IsArrayIndex(index)) {
864
0
    FakeString name;
865
0
    bool isSymbol;
866
0
    if (!ConvertIdToString(cx, id, name, isSymbol)) {
867
0
      return false;
868
0
    }
869
0
    if (!isSymbol) {
870
0
      mozilla::dom::HTMLAllCollection* self = UnwrapProxy(proxy);
871
0
      bool found = false;
872
0
      Nullable<OwningNodeOrHTMLCollection> result;
873
0
      self->NamedGetter(NonNullHelper(Constify(name)), found, result);
874
0
      MOZ_ASSERT(!JS_IsExceptionPending(cx));
875
0
876
0
      if (found) {
877
0
        if (result.IsNull()) {
878
0
          vp.setNull();
879
0
          return true;
880
0
        }
881
0
        if (!result.Value().ToJSVal(cx, proxy, vp)) {
882
0
          return false;
883
0
        }
884
0
        return true;
885
0
      }
886
0
    }
887
0
  }
888
0
889
0
  vp.setUndefined();
890
0
  return true;
891
0
}
892
893
const char*
894
DOMProxyHandler::className(JSContext* cx, JS::Handle<JSObject*> proxy) const
895
0
{
896
0
  return "HTMLAllCollection";
897
0
}
898
899
bool
900
DOMProxyHandler::finalizeInBackground(const JS::Value& priv) const
901
0
{
902
0
  return false;
903
0
}
904
905
void
906
DOMProxyHandler::finalize(JSFreeOp* fop, JSObject* proxy) const
907
0
{
908
0
  mozilla::dom::HTMLAllCollection* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::HTMLAllCollection>(proxy);
909
0
  if (self) {
910
0
    ClearWrapper(self, self, proxy);
911
0
    AddForDeferredFinalization<mozilla::dom::HTMLAllCollection>(self);
912
0
  }
913
0
}
914
915
const DOMProxyHandler*
916
DOMProxyHandler::getInstance()
917
0
{
918
0
  static const DOMProxyHandler instance;
919
0
  return &instance;
920
0
}
921
922
bool
923
DOMProxyHandler::delete_(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, JS::ObjectOpResult& opresult) const
924
0
{
925
0
  MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
926
0
            "Should not have a XrayWrapper here");
927
0
928
0
  uint32_t index = GetArrayIndexFromId(cx, id);
929
0
  if (IsArrayIndex(index)) {
930
0
    bool deleteSucceeded;
931
0
    bool found = false;
932
0
    mozilla::dom::HTMLAllCollection* self = UnwrapProxy(proxy);
933
0
    auto result(StrongOrRawPtr<nsINode>(self->IndexedGetter(index, found)));
934
0
    MOZ_ASSERT(!JS_IsExceptionPending(cx));
935
0
    (void)result;
936
0
    deleteSucceeded = !found;
937
0
    return deleteSucceeded ? opresult.succeed() : opresult.failCantDelete();
938
0
  }
939
0
  // Try named delete only if the named property visibility
940
0
  // algorithm says the property is visible.
941
0
  bool tryNamedDelete = true;
942
0
  { // Scope for expando
943
0
    JS::Rooted<JSObject*> expando(cx, DOMProxyHandler::GetExpandoObject(proxy));
944
0
    if (expando) {
945
0
      bool hasProp;
946
0
      if (!JS_HasPropertyById(cx, expando, id, &hasProp)) {
947
0
        return false;
948
0
      }
949
0
      tryNamedDelete = !hasProp;
950
0
    }
951
0
  }
952
0
  if (tryNamedDelete) {
953
0
    bool hasOnProto;
954
0
    if (!HasPropertyOnPrototype(cx, proxy, id, &hasOnProto)) {
955
0
      return false;
956
0
    }
957
0
    tryNamedDelete = !hasOnProto;
958
0
  }
959
0
  if (tryNamedDelete) {
960
0
    bool found = false;
961
0
    bool deleteSucceeded;
962
0
    FakeString name;
963
0
    bool isSymbol;
964
0
    if (!ConvertIdToString(cx, id, name, isSymbol)) {
965
0
      return false;
966
0
    }
967
0
    if (!isSymbol) {
968
0
      mozilla::dom::HTMLAllCollection* self = UnwrapProxy(proxy);
969
0
      Nullable<OwningNodeOrHTMLCollection> result;
970
0
      self->NamedGetter(NonNullHelper(Constify(name)), found, result);
971
0
      MOZ_ASSERT(!JS_IsExceptionPending(cx));
972
0
      (void)result;
973
0
    }
974
0
    deleteSucceeded = !found;
975
0
    if (found) {
976
0
      return deleteSucceeded ? opresult.succeed() : opresult.failCantDelete();
977
0
    }
978
0
  }
979
0
980
0
  return dom::DOMProxyHandler::delete_(cx, proxy, id, opresult);
981
0
}
982
983
bool
984
DOMProxyHandler::getElements(JSContext* cx, JS::Handle<JSObject*> proxy, uint32_t begin, uint32_t end, js::ElementAdder* adder) const
985
0
{
986
0
  JS::Rooted<JS::Value> temp(cx);
987
0
  MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
988
0
             "Should not have a XrayWrapper here");
989
0
990
0
  mozilla::dom::HTMLAllCollection* self = UnwrapProxy(proxy);
991
0
  uint32_t length = self->Length();
992
0
  // Compute the end of the indices we'll get ourselves
993
0
  uint32_t ourEnd = std::max(begin, std::min(end, length));
994
0
995
0
  for (uint32_t index = begin; index < ourEnd; ++index) {
996
0
    bool found = false;
997
0
    auto result(StrongOrRawPtr<nsINode>(self->IndexedGetter(index, found)));
998
0
    MOZ_ASSERT(!JS_IsExceptionPending(cx));
999
0
1000
0
    MOZ_ASSERT(found);
1001
0
    if (!result) {
1002
0
      temp.setNull();
1003
0
      if (!adder->append(cx, temp)) return false;
1004
0
      continue;
1005
0
    }
1006
0
    if (!GetOrCreateDOMReflector(cx, result, &temp)) {
1007
0
      MOZ_ASSERT(JS_IsExceptionPending(cx));
1008
0
      return false;
1009
0
    }
1010
0
    if (!adder->append(cx, temp)) return false;
1011
0
    continue;
1012
0
  }
1013
0
1014
0
  if (end > ourEnd) {
1015
0
    JS::Rooted<JSObject*> proto(cx);
1016
0
    if (!js::GetObjectProto(cx, proxy, &proto)) {
1017
0
      return false;
1018
0
    }
1019
0
    return js::GetElementsWithAdder(cx, proto, proxy, ourEnd, end, adder);
1020
0
  }
1021
0
1022
0
  return true;
1023
0
}
1024
1025
bool
1026
DOMProxyHandler::call(JSContext* cx, JS::Handle<JSObject*> proxy, const JS::CallArgs& args) const
1027
0
{
1028
0
  return js::ForwardToNative(cx, _legacycaller, args);
1029
0
}
1030
1031
bool
1032
DOMProxyHandler::isCallable(JSObject* obj) const
1033
0
{
1034
0
  return true;
1035
0
}
1036
1037
size_t
1038
DOMProxyHandler::objectMoved(JSObject* obj, JSObject* old) const
1039
0
{
1040
0
  mozilla::dom::HTMLAllCollection* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::HTMLAllCollection>(obj);
1041
0
  if (self) {
1042
0
    UpdateWrapper(self, self, obj, old);
1043
0
  }
1044
0
1045
0
  return 0;
1046
0
}
1047
1048
static const DOMJSClass sClass = {
1049
  PROXY_CLASS_DEF("HTMLAllCollection",
1050
                  JSCLASS_IS_DOMJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_EMULATES_UNDEFINED),
1051
  { prototypes::id::HTMLAllCollection, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
1052
  IsBaseOf<nsISupports, mozilla::dom::HTMLAllCollection >::value,
1053
  sNativePropertyHooks,
1054
  FindAssociatedGlobalForNative<mozilla::dom::HTMLAllCollection>::Get,
1055
  GetProtoObjectHandle,
1056
  GetCCParticipant<mozilla::dom::HTMLAllCollection>::Get()
1057
};
1058
1059
bool
1060
Wrap(JSContext* aCx, mozilla::dom::HTMLAllCollection* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
1061
0
{
1062
0
  static_assert(!IsBaseOf<NonRefcountedDOMObject, mozilla::dom::HTMLAllCollection>::value,
1063
0
                "Shouldn't have wrappercached things that are not refcounted.");
1064
0
  MOZ_ASSERT(static_cast<mozilla::dom::HTMLAllCollection*>(aObject) ==
1065
0
             reinterpret_cast<mozilla::dom::HTMLAllCollection*>(aObject),
1066
0
             "Multiple inheritance for mozilla::dom::HTMLAllCollection is broken.");
1067
0
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
1068
0
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
1069
0
  MOZ_ASSERT(!aCache->GetWrapper(),
1070
0
             "You should probably not be using Wrap() directly; use "
1071
0
             "GetOrCreateDOMReflector instead");
1072
0
1073
0
  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
1074
0
             "nsISupports must be on our primary inheritance chain");
1075
0
1076
0
  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
1077
0
  if (!global) {
1078
0
    return false;
1079
0
  }
1080
0
  MOZ_ASSERT(JS_IsGlobalObject(global));
1081
0
  MOZ_ASSERT(JS::ObjectIsNotGray(global));
1082
0
1083
0
  // That might have ended up wrapping us already, due to the wonders
1084
0
  // of XBL.  Check for that, and bail out as needed.
1085
0
  aReflector.set(aCache->GetWrapper());
1086
0
  if (aReflector) {
1087
#ifdef DEBUG
1088
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
1089
#endif // DEBUG
1090
    return true;
1091
0
  }
1092
0
1093
0
  JSAutoRealm ar(aCx, global);
1094
0
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
1095
0
  if (!canonicalProto) {
1096
0
    return false;
1097
0
  }
1098
0
  JS::Rooted<JSObject*> proto(aCx);
1099
0
  if (aGivenProto) {
1100
0
    proto = aGivenProto;
1101
0
    // Unfortunately, while aGivenProto was in the compartment of aCx
1102
0
    // coming in, we changed compartments to that of "parent" so may need
1103
0
    // to wrap the proto here.
1104
0
    if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
1105
0
      if (!JS_WrapObject(aCx, &proto)) {
1106
0
        return false;
1107
0
      }
1108
0
    }
1109
0
  } else {
1110
0
    proto = canonicalProto;
1111
0
  }
1112
0
1113
0
  BindingJSObjectCreator<mozilla::dom::HTMLAllCollection> creator(aCx);
1114
0
  creator.CreateProxyObject(aCx, &sClass.mBase, DOMProxyHandler::getInstance(),
1115
0
                            proto, aObject, JS::UndefinedHandleValue, aReflector);
1116
0
  if (!aReflector) {
1117
0
    return false;
1118
0
  }
1119
0
1120
0
  aCache->SetWrapper(aReflector);
1121
0
  creator.InitializationSucceeded();
1122
0
1123
0
  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
1124
0
             aCache->GetWrapperPreserveColor() == aReflector);
1125
0
  // If proto != canonicalProto, we have to preserve our wrapper;
1126
0
  // otherwise we won't be able to properly recreate it later, since
1127
0
  // we won't know what proto to use.  Note that we don't check
1128
0
  // aGivenProto here, since it's entirely possible (and even
1129
0
  // somewhat common) to have a non-null aGivenProto which is the
1130
0
  // same as canonicalProto.
1131
0
  if (proto != canonicalProto) {
1132
0
    PreserveWrapper(aObject);
1133
0
  }
1134
0
1135
0
  return true;
1136
0
}
1137
1138
static bool
1139
ResolveOwnProperty(JSContext* cx, JS::Handle<JSObject*> wrapper, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::MutableHandle<JS::PropertyDescriptor> desc)
1140
0
{
1141
0
  return js::GetProxyHandler(obj)->getOwnPropertyDescriptor(cx, wrapper, id, desc);
1142
0
}
1143
1144
static bool
1145
EnumerateOwnProperties(JSContext* cx, JS::Handle<JSObject*> wrapper, JS::Handle<JSObject*> obj, JS::AutoIdVector& props)
1146
0
{
1147
0
  return js::GetProxyHandler(obj)->ownPropertyKeys(cx, wrapper, props);
1148
0
}
1149
1150
const NativePropertyHooks sNativePropertyHooks[] = { {
1151
  ResolveOwnProperty,
1152
  EnumerateOwnProperties,
1153
  nullptr,
1154
  { sNativeProperties.Upcast(), nullptr },
1155
  prototypes::id::HTMLAllCollection,
1156
  constructors::id::HTMLAllCollection,
1157
  nullptr,
1158
  &DefaultXrayExpandoObjectClass
1159
} };
1160
1161
void
1162
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
1163
0
{
1164
0
  JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
1165
0
  if (!parentProto) {
1166
0
    return;
1167
0
  }
1168
0
1169
0
  JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
1170
0
  if (!constructorProto) {
1171
0
    return;
1172
0
  }
1173
0
1174
0
  static bool sIdsInited = false;
1175
0
  if (!sIdsInited && NS_IsMainThread()) {
1176
0
    if (!InitIds(aCx, sNativeProperties.Upcast())) {
1177
0
      return;
1178
0
    }
1179
0
    sIdsInited = true;
1180
0
  }
1181
0
1182
0
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::HTMLAllCollection);
1183
0
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::HTMLAllCollection);
1184
0
  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
1185
0
                              &sPrototypeClass.mBase, protoCache,
1186
0
                              nullptr,
1187
0
                              constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
1188
0
                              interfaceCache,
1189
0
                              sNativeProperties.Upcast(),
1190
0
                              nullptr,
1191
0
                              "HTMLAllCollection", aDefineOnGlobal,
1192
0
                              nullptr,
1193
0
                              false);
1194
0
}
1195
1196
JSObject*
1197
GetConstructorObject(JSContext* aCx)
1198
0
{
1199
0
  return GetConstructorObjectHandle(aCx);
1200
0
}
1201
1202
} // namespace HTMLAllCollection_Binding
1203
1204
1205
1206
} // namespace dom
1207
} // namespace mozilla