Coverage Report

Created: 2018-09-25 14:53

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