Coverage Report

Created: 2018-09-25 14:53

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