Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dom/bindings/XMLDocumentBinding.cpp
Line
Count
Source (jump to first uncovered line)
1
/* THIS FILE IS AUTOGENERATED FROM XMLDocument.webidl BY Codegen.py - DO NOT EDIT */
2
3
#include "DocumentBinding.h"
4
#include "WrapperFactory.h"
5
#include "XMLDocumentBinding.h"
6
#include "mozilla/OwningNonNull.h"
7
#include "mozilla/UseCounter.h"
8
#include "mozilla/dom/BindingUtils.h"
9
#include "mozilla/dom/DOMJSClass.h"
10
#include "mozilla/dom/Location.h"
11
#include "mozilla/dom/NonRefcountedDOMObject.h"
12
#include "mozilla/dom/Nullable.h"
13
#include "mozilla/dom/PrimitiveConversions.h"
14
#include "mozilla/dom/XMLDocument.h"
15
#include "mozilla/dom/XrayExpandoClass.h"
16
#include "nsContentUtils.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 XMLDocument_Binding {
26
27
static_assert(IsRefcounted<NativeType>::value == IsRefcounted<Document_Binding::NativeType>::value,
28
              "Can't inherit from an interface with a different ownership model.");
29
30
MOZ_CAN_RUN_SCRIPT static bool
31
load(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::XMLDocument* self, const JSJitMethodCallArgs& args)
32
0
{
33
0
  AUTO_PROFILER_LABEL_FAST("XMLDocument.load", DOM, cx);
34
0
35
0
  if (MOZ_UNLIKELY(args.length() < 1)) {
36
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "XMLDocument.load");
37
0
  }
38
0
  binding_detail::FakeString arg0;
39
0
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
40
0
    return false;
41
0
  }
42
0
  FastErrorResult rv;
43
0
  bool result(self->Load(NonNullHelper(Constify(arg0)), nsContentUtils::IsSystemCaller(cx) ? CallerType::System : CallerType::NonSystem, rv));
44
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
45
0
    return false;
46
0
  }
47
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
48
0
  args.rval().setBoolean(result);
49
0
  return true;
50
0
}
51
52
static const JSJitInfo load_methodinfo = {
53
  { (JSJitGetterOp)load },
54
  { prototypes::id::XMLDocument },
55
  { PrototypeTraits<prototypes::id::XMLDocument>::Depth },
56
  JSJitInfo::Method,
57
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
58
  JSVAL_TYPE_BOOLEAN,  /* 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
get_async(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::XMLDocument* self, JSJitGetterCallArgs args)
72
0
{
73
0
  AUTO_PROFILER_LABEL_FAST("get XMLDocument.async", DOM, cx);
74
0
75
0
  bool result(self->Async());
76
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
77
0
  SetDocumentAndPageUseCounter(obj, eUseCounter_XMLDocument_async_getter);
78
0
  args.rval().setBoolean(result);
79
0
  return true;
80
0
}
81
82
MOZ_CAN_RUN_SCRIPT static bool
83
set_async(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::XMLDocument* self, JSJitSetterCallArgs args)
84
0
{
85
0
  AUTO_PROFILER_LABEL_FAST("set XMLDocument.async", DOM, cx);
86
0
87
0
  bool arg0;
88
0
  if (!ValueToPrimitive<bool, eDefault>(cx, args[0], &arg0)) {
89
0
    return false;
90
0
  }
91
0
  self->SetAsync(arg0);
92
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
93
0
  SetDocumentAndPageUseCounter(obj, eUseCounter_XMLDocument_async_setter);
94
0
95
0
  return true;
96
0
}
97
98
static const JSJitInfo async_getterinfo = {
99
  { (JSJitGetterOp)get_async },
100
  { prototypes::id::XMLDocument },
101
  { PrototypeTraits<prototypes::id::XMLDocument>::Depth },
102
  JSJitInfo::Getter,
103
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
104
  JSVAL_TYPE_BOOLEAN,  /* returnType.  Not relevant for setters. */
105
  true,  /* isInfallible. False in setters. */
106
  false,  /* isMovable.  Not relevant for setters. */
107
  false, /* isEliminatable.  Not relevant for setters. */
108
  false, /* isAlwaysInSlot.  Only relevant for getters. */
109
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
110
  false,  /* isTypedMethod.  Only relevant for methods. */
111
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
112
};
113
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
114
static_assert(0 < 1, "There is no slot for us");
115
static const JSJitInfo async_setterinfo = {
116
  { (JSJitGetterOp)set_async },
117
  { prototypes::id::XMLDocument },
118
  { PrototypeTraits<prototypes::id::XMLDocument>::Depth },
119
  JSJitInfo::Setter,
120
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
121
  JSVAL_TYPE_UNDEFINED,  /* 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
get_location(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::XMLDocument* self, JSJitGetterCallArgs args)
135
0
{
136
0
  AUTO_PROFILER_LABEL_FAST("get XMLDocument.location", DOM, cx);
137
0
138
0
  auto result(StrongOrRawPtr<mozilla::dom::Location>(self->GetLocation()));
139
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
140
0
  if (!result) {
141
0
    args.rval().setNull();
142
0
    return true;
143
0
  }
144
0
  if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
145
0
    MOZ_CRASH("Looks like bug 1488480/1405521, with getting the reflector failing");
146
0
    MOZ_ASSERT(JS_IsExceptionPending(cx));
147
0
    return false;
148
0
  }
149
0
  return true;
150
0
}
151
152
MOZ_CAN_RUN_SCRIPT static bool
153
set_location(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::XMLDocument* self, JSJitSetterCallArgs args)
154
0
{
155
0
  AUTO_PROFILER_LABEL_FAST("set XMLDocument.location", DOM, cx);
156
0
157
0
  JS::Rooted<JS::Value> v(cx);
158
0
  if (!JS_GetProperty(cx, obj, "location", &v)) {
159
0
    return false;
160
0
  }
161
0
162
0
  if (!v.isObject()) {
163
0
    return ThrowErrorMessage(cx, MSG_NOT_OBJECT, "XMLDocument.location");
164
0
  }
165
0
166
0
  JS::Rooted<JSObject*> targetObj(cx, &v.toObject());
167
0
  return JS_SetProperty(cx, targetObj, "href", args[0]);
168
0
}
169
170
static const JSJitInfo location_getterinfo = {
171
  { (JSJitGetterOp)get_location },
172
  { prototypes::id::XMLDocument },
173
  { PrototypeTraits<prototypes::id::XMLDocument>::Depth },
174
  JSJitInfo::Getter,
175
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
176
  JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
177
  false,  /* isInfallible. False in setters. */
178
  false,  /* isMovable.  Not relevant for setters. */
179
  false, /* isEliminatable.  Not relevant for setters. */
180
  false, /* isAlwaysInSlot.  Only relevant for getters. */
181
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
182
  false,  /* isTypedMethod.  Only relevant for methods. */
183
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
184
};
185
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
186
static_assert(0 < 1, "There is no slot for us");
187
static const JSJitInfo location_setterinfo = {
188
  { (JSJitGetterOp)set_location },
189
  { prototypes::id::XMLDocument },
190
  { PrototypeTraits<prototypes::id::XMLDocument>::Depth },
191
  JSJitInfo::Setter,
192
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
193
  JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
194
  false,  /* isInfallible. False in setters. */
195
  false,  /* isMovable.  Not relevant for setters. */
196
  false, /* isEliminatable.  Not relevant for setters. */
197
  false, /* isAlwaysInSlot.  Only relevant for getters. */
198
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
199
  false,  /* isTypedMethod.  Only relevant for methods. */
200
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
201
};
202
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
203
static_assert(0 < 1, "There is no slot for us");
204
205
static bool
206
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
207
0
{
208
0
  mozilla::dom::XMLDocument* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XMLDocument>(obj);
209
0
  // We don't want to preserve if we don't have a wrapper, and we
210
0
  // obviously can't preserve if we're not initialized.
211
0
  if (self && self->GetWrapperPreserveColor()) {
212
0
    PreserveWrapper(self);
213
0
  }
214
0
  return true;
215
0
}
216
217
static void
218
_finalize(js::FreeOp* fop, JSObject* obj)
219
0
{
220
0
  mozilla::dom::XMLDocument* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XMLDocument>(obj);
221
0
  if (self) {
222
0
    ClearWrapper(self, self, obj);
223
0
    AddForDeferredFinalization<mozilla::dom::XMLDocument>(self);
224
0
  }
225
0
}
226
227
static size_t
228
_objectMoved(JSObject* obj, JSObject* old)
229
0
{
230
0
  mozilla::dom::XMLDocument* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::XMLDocument>(obj);
231
0
  if (self) {
232
0
    UpdateWrapper(self, self, obj, old);
233
0
  }
234
0
235
0
  return 0;
236
0
}
237
238
// We deliberately use brace-elision to make Visual Studio produce better initalization code.
239
#if defined(__clang__)
240
#pragma clang diagnostic push
241
#pragma clang diagnostic ignored "-Wmissing-braces"
242
#endif
243
static const JSFunctionSpec sMethods_specs[] = {
244
  JS_FNSPEC("load", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&load_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
245
  JS_FS_END
246
};
247
#if defined(__clang__)
248
#pragma clang diagnostic pop
249
#endif
250
251
252
static const Prefable<const JSFunctionSpec> sMethods[] = {
253
  { nullptr, &sMethods_specs[0] },
254
  { nullptr, nullptr }
255
};
256
257
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
258
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
259
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
260
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
261
262
// We deliberately use brace-elision to make Visual Studio produce better initalization code.
263
#if defined(__clang__)
264
#pragma clang diagnostic push
265
#pragma clang diagnostic ignored "-Wmissing-braces"
266
#endif
267
static const JSPropertySpec sAttributes_specs[] = {
268
  { "async", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &async_getterinfo, GenericSetter<NormalThisPolicy>, &async_setterinfo },
269
  { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
270
};
271
#if defined(__clang__)
272
#pragma clang diagnostic pop
273
#endif
274
275
276
static const Prefable<const JSPropertySpec> sAttributes[] = {
277
  { nullptr, &sAttributes_specs[0] },
278
  { nullptr, nullptr }
279
};
280
281
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
282
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
283
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
284
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
285
286
// We deliberately use brace-elision to make Visual Studio produce better initalization code.
287
#if defined(__clang__)
288
#pragma clang diagnostic push
289
#pragma clang diagnostic ignored "-Wmissing-braces"
290
#endif
291
static const JSPropertySpec sUnforgeableAttributes_specs[] = {
292
  { "location", JSPROP_ENUMERATE | JSPROP_PERMANENT, GenericGetter<NormalThisPolicy, ThrowExceptions>, &location_getterinfo, GenericSetter<NormalThisPolicy>, &location_setterinfo },
293
  { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
294
};
295
#if defined(__clang__)
296
#pragma clang diagnostic pop
297
#endif
298
299
300
static const Prefable<const JSPropertySpec> sUnforgeableAttributes[] = {
301
  { nullptr, &sUnforgeableAttributes_specs[0] },
302
  { nullptr, nullptr }
303
};
304
305
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
306
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
307
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
308
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
309
310
311
static uint16_t sNativeProperties_sortedPropertyIndices[3];
312
static PropertyInfo sNativeProperties_propertyInfos[3];
313
314
static const NativePropertiesN<3> sNativeProperties = {
315
  false, 0,
316
  false, 0,
317
  true,  0 /* sMethods */,
318
  true,  1 /* sAttributes */,
319
  false, 0,
320
  true,  2 /* sUnforgeableAttributes */,
321
  false, 0,
322
  -1,
323
  3,
324
  sNativeProperties_sortedPropertyIndices,
325
  {
326
    { sMethods, &sNativeProperties_propertyInfos[0] },
327
    { sAttributes, &sNativeProperties_propertyInfos[1] },
328
    { sUnforgeableAttributes, &sNativeProperties_propertyInfos[2] }
329
  }
330
};
331
static_assert(3 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
332
    "We have a property info count that is oversized");
333
334
static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
335
  {
336
    "Function",
337
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
338
    &sBoringInterfaceObjectClassClassOps,
339
    JS_NULL_CLASS_SPEC,
340
    JS_NULL_CLASS_EXT,
341
    &sInterfaceObjectClassObjectOps
342
  },
343
  eInterface,
344
  true,
345
  prototypes::id::XMLDocument,
346
  PrototypeTraits<prototypes::id::XMLDocument>::Depth,
347
  sNativePropertyHooks,
348
  "function XMLDocument() {\n    [native code]\n}",
349
  Document_Binding::GetConstructorObject
350
};
351
352
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
353
  {
354
    "XMLDocumentPrototype",
355
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE + 1 /* slot for the JSObject holding the unforgeable properties */),
356
    JS_NULL_CLASS_OPS,
357
    JS_NULL_CLASS_SPEC,
358
    JS_NULL_CLASS_EXT,
359
    JS_NULL_OBJECT_OPS
360
  },
361
  eInterfacePrototype,
362
  false,
363
  prototypes::id::XMLDocument,
364
  PrototypeTraits<prototypes::id::XMLDocument>::Depth,
365
  sNativePropertyHooks,
366
  "[object XMLDocumentPrototype]",
367
  Document_Binding::GetProtoObject
368
};
369
370
static const js::ClassOps sClassOps = {
371
  _addProperty, /* addProperty */
372
  nullptr,               /* delProperty */
373
  nullptr,               /* enumerate */
374
  nullptr, /* newEnumerate */
375
  nullptr, /* resolve */
376
  nullptr, /* mayResolve */
377
  _finalize, /* finalize */
378
  nullptr, /* call */
379
  nullptr,               /* hasInstance */
380
  nullptr,               /* construct */
381
  nullptr, /* trace */
382
};
383
384
static const js::ClassExtension sClassExtension = {
385
  nullptr, /* weakmapKeyDelegateOp */
386
  _objectMoved /* objectMovedOp */
387
};
388
389
static const DOMJSClass sClass = {
390
  { "XMLDocument",
391
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
392
    &sClassOps,
393
    JS_NULL_CLASS_SPEC,
394
    &sClassExtension,
395
    JS_NULL_OBJECT_OPS
396
  },
397
  { prototypes::id::EventTarget, prototypes::id::Node, prototypes::id::Document, prototypes::id::XMLDocument, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
398
  IsBaseOf<nsISupports, mozilla::dom::XMLDocument >::value,
399
  sNativePropertyHooks,
400
  FindAssociatedGlobalForNative<mozilla::dom::XMLDocument>::Get,
401
  GetProtoObjectHandle,
402
  GetCCParticipant<mozilla::dom::XMLDocument>::Get()
403
};
404
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
405
              "Must have the right minimal number of reserved slots.");
406
static_assert(1 >= 1,
407
              "Must have enough reserved slots.");
408
409
const JSClass*
410
GetJSClass()
411
0
{
412
0
  return sClass.ToJSClass();
413
0
}
414
415
bool
416
Wrap(JSContext* aCx, mozilla::dom::XMLDocument* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
417
0
{
418
0
  static_assert(!IsBaseOf<NonRefcountedDOMObject, mozilla::dom::XMLDocument>::value,
419
0
                "Shouldn't have wrappercached things that are not refcounted.");
420
0
  MOZ_ASSERT(static_cast<mozilla::dom::XMLDocument*>(aObject) ==
421
0
             reinterpret_cast<mozilla::dom::XMLDocument*>(aObject),
422
0
             "Multiple inheritance for mozilla::dom::XMLDocument is broken.");
423
0
  MOZ_ASSERT(static_cast<nsIDocument*>(aObject) ==
424
0
             reinterpret_cast<nsIDocument*>(aObject),
425
0
             "Multiple inheritance for nsIDocument is broken.");
426
0
  MOZ_ASSERT(static_cast<nsINode*>(aObject) ==
427
0
             reinterpret_cast<nsINode*>(aObject),
428
0
             "Multiple inheritance for nsINode is broken.");
429
0
  MOZ_ASSERT(static_cast<mozilla::dom::EventTarget*>(aObject) ==
430
0
             reinterpret_cast<mozilla::dom::EventTarget*>(aObject),
431
0
             "Multiple inheritance for mozilla::dom::EventTarget is broken.");
432
0
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
433
0
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
434
0
  MOZ_ASSERT(!aCache->GetWrapper(),
435
0
             "You should probably not be using Wrap() directly; use "
436
0
             "GetOrCreateDOMReflector instead");
437
0
438
0
  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
439
0
             "nsISupports must be on our primary inheritance chain");
440
0
441
0
  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
442
0
  if (!global) {
443
0
    return false;
444
0
  }
445
0
  MOZ_ASSERT(JS_IsGlobalObject(global));
446
0
  MOZ_ASSERT(JS::ObjectIsNotGray(global));
447
0
448
0
  // That might have ended up wrapping us already, due to the wonders
449
0
  // of XBL.  Check for that, and bail out as needed.
450
0
  aReflector.set(aCache->GetWrapper());
451
0
  if (aReflector) {
452
#ifdef DEBUG
453
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
454
#endif // DEBUG
455
    return true;
456
0
  }
457
0
458
0
  JSAutoRealm ar(aCx, global);
459
0
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
460
0
  if (!canonicalProto) {
461
0
    return false;
462
0
  }
463
0
  JS::Rooted<JSObject*> proto(aCx);
464
0
  if (aGivenProto) {
465
0
    proto = aGivenProto;
466
0
    // Unfortunately, while aGivenProto was in the compartment of aCx
467
0
    // coming in, we changed compartments to that of "parent" so may need
468
0
    // to wrap the proto here.
469
0
    if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
470
0
      if (!JS_WrapObject(aCx, &proto)) {
471
0
        return false;
472
0
      }
473
0
    }
474
0
  } else {
475
0
    proto = canonicalProto;
476
0
  }
477
0
478
0
  BindingJSObjectCreator<mozilla::dom::XMLDocument> creator(aCx);
479
0
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
480
0
  if (!aReflector) {
481
0
    return false;
482
0
  }
483
0
484
0
  aCache->SetWrapper(aReflector);
485
0
486
0
  // Important: do unforgeable property setup after we have handed
487
0
  // over ownership of the C++ object to obj as needed, so that if
488
0
  // we fail and it ends up GCed it won't have problems in the
489
0
  // finalizer trying to drop its ownership of the C++ object.
490
0
  JS::Rooted<JSObject*> unforgeableHolder(aCx,
491
0
    &js::GetReservedSlot(canonicalProto, DOM_INTERFACE_PROTO_SLOTS_BASE).toObject());
492
0
  if (!JS_InitializePropertiesFromCompatibleNativeObject(aCx, aReflector, unforgeableHolder)) {
493
0
    aCache->ReleaseWrapper(aObject);
494
0
    aCache->ClearWrapper();
495
0
    return false;
496
0
  }
497
0
  creator.InitializationSucceeded();
498
0
499
0
  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
500
0
             aCache->GetWrapperPreserveColor() == aReflector);
501
0
  // If proto != canonicalProto, we have to preserve our wrapper;
502
0
  // otherwise we won't be able to properly recreate it later, since
503
0
  // we won't know what proto to use.  Note that we don't check
504
0
  // aGivenProto here, since it's entirely possible (and even
505
0
  // somewhat common) to have a non-null aGivenProto which is the
506
0
  // same as canonicalProto.
507
0
  if (proto != canonicalProto) {
508
0
    PreserveWrapper(aObject);
509
0
  }
510
0
511
0
  return true;
512
0
}
513
514
const NativePropertyHooks sNativePropertyHooks[] = { {
515
  nullptr,
516
  nullptr,
517
  nullptr,
518
  { sNativeProperties.Upcast(), nullptr },
519
  prototypes::id::XMLDocument,
520
  constructors::id::XMLDocument,
521
  Document_Binding::sNativePropertyHooks,
522
  &DefaultXrayExpandoObjectClass
523
} };
524
525
void
526
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
527
0
{
528
0
  JS::Handle<JSObject*> parentProto(Document_Binding::GetProtoObjectHandle(aCx));
529
0
  if (!parentProto) {
530
0
    return;
531
0
  }
532
0
533
0
  JS::Handle<JSObject*> constructorProto(Document_Binding::GetConstructorObjectHandle(aCx));
534
0
  if (!constructorProto) {
535
0
    return;
536
0
  }
537
0
538
0
  static bool sIdsInited = false;
539
0
  if (!sIdsInited && NS_IsMainThread()) {
540
0
    if (!InitIds(aCx, sNativeProperties.Upcast())) {
541
0
      return;
542
0
    }
543
0
    sIdsInited = true;
544
0
  }
545
0
546
0
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::XMLDocument);
547
0
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::XMLDocument);
548
0
  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
549
0
                              &sPrototypeClass.mBase, protoCache,
550
0
                              nullptr,
551
0
                              constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
552
0
                              interfaceCache,
553
0
                              sNativeProperties.Upcast(),
554
0
                              nullptr,
555
0
                              "XMLDocument", aDefineOnGlobal,
556
0
                              nullptr,
557
0
                              false);
558
0
559
0
  JS::Rooted<JSObject*> unforgeableHolder(aCx);
560
0
  {
561
0
    JS::Rooted<JSObject*> holderProto(aCx, *protoCache);
562
0
    unforgeableHolder = JS_NewObjectWithoutMetadata(aCx, sClass.ToJSClass(), holderProto);
563
0
    if (!unforgeableHolder) {
564
0
      *protoCache = nullptr;
565
0
      if (interfaceCache) {
566
0
        *interfaceCache = nullptr;
567
0
      }
568
0
      return;
569
0
    }
570
0
  }
571
0
572
0
  if (!DefineUnforgeableAttributes(aCx, unforgeableHolder, sUnforgeableAttributes)) {
573
0
    *protoCache = nullptr;
574
0
    if (interfaceCache) {
575
0
      *interfaceCache = nullptr;
576
0
    }
577
0
    return;
578
0
  }
579
0
580
0
  if (*protoCache) {
581
0
    js::SetReservedSlot(*protoCache, DOM_INTERFACE_PROTO_SLOTS_BASE,
582
0
                        JS::ObjectValue(*unforgeableHolder));
583
0
  }
584
0
}
585
586
JSObject*
587
GetConstructorObject(JSContext* aCx)
588
0
{
589
0
  return GetConstructorObjectHandle(aCx);
590
0
}
591
592
} // namespace XMLDocument_Binding
593
594
595
596
} // namespace dom
597
} // namespace mozilla