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