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