Line data Source code
1 : /* THIS FILE IS AUTOGENERATED FROM AccessibleNode.webidl BY Codegen.py - DO NOT EDIT */
2 :
3 : #include "AccessibleNodeBinding.h"
4 : #include "WrapperFactory.h"
5 : #include "XrayWrapper.h"
6 : #include "mozilla/OwningNonNull.h"
7 : #include "mozilla/Preferences.h"
8 : #include "mozilla/dom/AccessibleNode.h"
9 : #include "mozilla/dom/BindingUtils.h"
10 : #include "mozilla/dom/DOMJSClass.h"
11 : #include "mozilla/dom/NonRefcountedDOMObject.h"
12 : #include "mozilla/dom/Nullable.h"
13 : #include "mozilla/dom/PrimitiveConversions.h"
14 : #include "mozilla/dom/XrayExpandoClass.h"
15 : #include "nsINode.h"
16 :
17 : namespace mozilla {
18 : namespace dom {
19 :
20 : namespace AccessibleNodeBinding {
21 :
22 : static bool
23 0 : get_role(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AccessibleNode* self, JSJitGetterCallArgs args)
24 : {
25 0 : DOMString result;
26 0 : self->GetRole(result);
27 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
28 0 : if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
29 0 : return false;
30 : }
31 0 : return true;
32 : }
33 :
34 : static const JSJitInfo role_getterinfo = {
35 : { (JSJitGetterOp)get_role },
36 : { prototypes::id::AccessibleNode },
37 : { PrototypeTraits<prototypes::id::AccessibleNode>::Depth },
38 : JSJitInfo::Getter,
39 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
40 : JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
41 : false, /* isInfallible. False in setters. */
42 : false, /* isMovable. Not relevant for setters. */
43 : false, /* isEliminatable. Not relevant for setters. */
44 : false, /* isAlwaysInSlot. Only relevant for getters. */
45 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
46 : false, /* isTypedMethod. Only relevant for methods. */
47 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
48 : };
49 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
50 : static_assert(0 < 3, "There is no slot for us");
51 :
52 : static bool
53 0 : get_states(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AccessibleNode* self, JSJitGetterCallArgs args)
54 : {
55 : // Have to either root across the getter call or reget after.
56 : bool isXray;
57 0 : JS::Rooted<JSObject*> slotStorage(cx, GetCachedSlotStorageObject(cx, obj, &isXray));
58 0 : if (!slotStorage) {
59 0 : return false;
60 : }
61 0 : const size_t slotIndex = isXray ? (xpc::JSSLOT_EXPANDO_COUNT + 0) : (DOM_INSTANCE_RESERVED_SLOTS + 0);
62 0 : MOZ_ASSERT(JSCLASS_RESERVED_SLOTS(js::GetObjectClass(slotStorage)) > slotIndex);
63 : {
64 : // Scope for cachedVal
65 0 : JS::Value cachedVal = js::GetReservedSlot(slotStorage, slotIndex);
66 0 : if (!cachedVal.isUndefined()) {
67 0 : args.rval().set(cachedVal);
68 : // The cached value is in the compartment of slotStorage,
69 : // so wrap into the caller compartment as needed.
70 0 : return MaybeWrapNonDOMObjectValue(cx, args.rval());
71 : }
72 : }
73 :
74 0 : nsTArray<nsString> result;
75 0 : self->GetStates(result);
76 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
77 : {
78 0 : JS::Rooted<JSObject*> conversionScope(cx, isXray ? obj : slotStorage);
79 0 : JSAutoCompartment ac(cx, conversionScope);
80 : do { // block we break out of when done wrapping
81 :
82 0 : uint32_t length = result.Length();
83 0 : JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
84 0 : if (!returnArray) {
85 0 : return false;
86 : }
87 : // Scope for 'tmp'
88 : {
89 0 : JS::Rooted<JS::Value> tmp(cx);
90 0 : for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
91 : // Control block to let us common up the JS_DefineElement calls when there
92 : // are different ways to succeed at wrapping the object.
93 : do {
94 0 : if (!xpc::NonVoidStringToJsval(cx, result[sequenceIdx0], &tmp)) {
95 0 : return false;
96 : }
97 0 : break;
98 : } while (0);
99 0 : if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
100 : JSPROP_ENUMERATE)) {
101 0 : return false;
102 : }
103 : }
104 : }
105 0 : args.rval().setObject(*returnArray);
106 0 : break;
107 : } while (0);
108 0 : JS::Rooted<JSObject*> rvalObj(cx, &args.rval().toObject());
109 0 : if (!JS_FreezeObject(cx, rvalObj)) {
110 0 : return false;
111 : }
112 : }
113 : { // And now store things in the compartment of our slotStorage.
114 0 : JSAutoCompartment ac(cx, slotStorage);
115 : // Make a copy so that we don't do unnecessary wrapping on args.rval().
116 0 : JS::Rooted<JS::Value> storedVal(cx, args.rval());
117 0 : if (!MaybeWrapNonDOMObjectValue(cx, &storedVal)) {
118 0 : return false;
119 : }
120 0 : js::SetReservedSlot(slotStorage, slotIndex, storedVal);
121 0 : if (!isXray) {
122 : // In the Xray case we don't need to do this, because getting the
123 : // expando object already preserved our wrapper.
124 0 : PreserveWrapper(self);
125 : }
126 : }
127 : // And now make sure args.rval() is in the caller compartment
128 0 : return MaybeWrapNonDOMObjectValue(cx, args.rval());
129 : }
130 :
131 : static const JSJitInfo states_getterinfo = {
132 : { (JSJitGetterOp)get_states },
133 : { prototypes::id::AccessibleNode },
134 : { PrototypeTraits<prototypes::id::AccessibleNode>::Depth },
135 : JSJitInfo::Getter,
136 : JSJitInfo::AliasDOMSets, /* aliasSet. Not relevant for setters. */
137 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
138 : false, /* isInfallible. False in setters. */
139 : true, /* isMovable. Not relevant for setters. */
140 : true, /* isEliminatable. Not relevant for setters. */
141 : false, /* isAlwaysInSlot. Only relevant for getters. */
142 : true, /* isLazilyCachedInSlot. Only relevant for getters. */
143 : false, /* isTypedMethod. Only relevant for methods. */
144 : (DOM_INSTANCE_RESERVED_SLOTS + 0) /* Reserved slot index, if we're stored in a slot, else 0. */
145 : };
146 : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 0) <= JSJitInfo::maxSlotIndex, "We won't fit");
147 : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 0) < 3, "There is no slot for us");
148 :
149 : static bool
150 0 : get_attributes(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AccessibleNode* self, JSJitGetterCallArgs args)
151 : {
152 : // Have to either root across the getter call or reget after.
153 : bool isXray;
154 0 : JS::Rooted<JSObject*> slotStorage(cx, GetCachedSlotStorageObject(cx, obj, &isXray));
155 0 : if (!slotStorage) {
156 0 : return false;
157 : }
158 0 : const size_t slotIndex = isXray ? (xpc::JSSLOT_EXPANDO_COUNT + 1) : (DOM_INSTANCE_RESERVED_SLOTS + 1);
159 0 : MOZ_ASSERT(JSCLASS_RESERVED_SLOTS(js::GetObjectClass(slotStorage)) > slotIndex);
160 : {
161 : // Scope for cachedVal
162 0 : JS::Value cachedVal = js::GetReservedSlot(slotStorage, slotIndex);
163 0 : if (!cachedVal.isUndefined()) {
164 0 : args.rval().set(cachedVal);
165 : // The cached value is in the compartment of slotStorage,
166 : // so wrap into the caller compartment as needed.
167 0 : return MaybeWrapNonDOMObjectValue(cx, args.rval());
168 : }
169 : }
170 :
171 0 : nsTArray<nsString> result;
172 0 : self->GetAttributes(result);
173 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
174 : {
175 0 : JS::Rooted<JSObject*> conversionScope(cx, isXray ? obj : slotStorage);
176 0 : JSAutoCompartment ac(cx, conversionScope);
177 : do { // block we break out of when done wrapping
178 :
179 0 : uint32_t length = result.Length();
180 0 : JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
181 0 : if (!returnArray) {
182 0 : return false;
183 : }
184 : // Scope for 'tmp'
185 : {
186 0 : JS::Rooted<JS::Value> tmp(cx);
187 0 : for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
188 : // Control block to let us common up the JS_DefineElement calls when there
189 : // are different ways to succeed at wrapping the object.
190 : do {
191 0 : if (!xpc::NonVoidStringToJsval(cx, result[sequenceIdx0], &tmp)) {
192 0 : return false;
193 : }
194 0 : break;
195 : } while (0);
196 0 : if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
197 : JSPROP_ENUMERATE)) {
198 0 : return false;
199 : }
200 : }
201 : }
202 0 : args.rval().setObject(*returnArray);
203 0 : break;
204 : } while (0);
205 0 : JS::Rooted<JSObject*> rvalObj(cx, &args.rval().toObject());
206 0 : if (!JS_FreezeObject(cx, rvalObj)) {
207 0 : return false;
208 : }
209 : }
210 : { // And now store things in the compartment of our slotStorage.
211 0 : JSAutoCompartment ac(cx, slotStorage);
212 : // Make a copy so that we don't do unnecessary wrapping on args.rval().
213 0 : JS::Rooted<JS::Value> storedVal(cx, args.rval());
214 0 : if (!MaybeWrapNonDOMObjectValue(cx, &storedVal)) {
215 0 : return false;
216 : }
217 0 : js::SetReservedSlot(slotStorage, slotIndex, storedVal);
218 0 : if (!isXray) {
219 : // In the Xray case we don't need to do this, because getting the
220 : // expando object already preserved our wrapper.
221 0 : PreserveWrapper(self);
222 : }
223 : }
224 : // And now make sure args.rval() is in the caller compartment
225 0 : return MaybeWrapNonDOMObjectValue(cx, args.rval());
226 : }
227 :
228 : static const JSJitInfo attributes_getterinfo = {
229 : { (JSJitGetterOp)get_attributes },
230 : { prototypes::id::AccessibleNode },
231 : { PrototypeTraits<prototypes::id::AccessibleNode>::Depth },
232 : JSJitInfo::Getter,
233 : JSJitInfo::AliasDOMSets, /* aliasSet. Not relevant for setters. */
234 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
235 : false, /* isInfallible. False in setters. */
236 : true, /* isMovable. Not relevant for setters. */
237 : true, /* isEliminatable. Not relevant for setters. */
238 : false, /* isAlwaysInSlot. Only relevant for getters. */
239 : true, /* isLazilyCachedInSlot. Only relevant for getters. */
240 : false, /* isTypedMethod. Only relevant for methods. */
241 : (DOM_INSTANCE_RESERVED_SLOTS + 1) /* Reserved slot index, if we're stored in a slot, else 0. */
242 : };
243 : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 1) <= JSJitInfo::maxSlotIndex, "We won't fit");
244 : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 1) < 3, "There is no slot for us");
245 :
246 : static bool
247 0 : get_DOMNode(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AccessibleNode* self, JSJitGetterCallArgs args)
248 : {
249 0 : auto result(StrongOrRawPtr<nsINode>(self->GetDOMNode()));
250 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
251 0 : if (!result) {
252 0 : args.rval().setNull();
253 0 : return true;
254 : }
255 0 : if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
256 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
257 0 : return false;
258 : }
259 0 : return true;
260 : }
261 :
262 : static const JSJitInfo DOMNode_getterinfo = {
263 : { (JSJitGetterOp)get_DOMNode },
264 : { prototypes::id::AccessibleNode },
265 : { PrototypeTraits<prototypes::id::AccessibleNode>::Depth },
266 : JSJitInfo::Getter,
267 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
268 : JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */
269 : false, /* isInfallible. False in setters. */
270 : false, /* isMovable. Not relevant for setters. */
271 : false, /* isEliminatable. Not relevant for setters. */
272 : false, /* isAlwaysInSlot. Only relevant for getters. */
273 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
274 : false, /* isTypedMethod. Only relevant for methods. */
275 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
276 : };
277 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
278 : static_assert(0 < 3, "There is no slot for us");
279 :
280 : static bool
281 0 : is(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AccessibleNode* self, const JSJitMethodCallArgs& args)
282 : {
283 0 : binding_detail::AutoSequence<nsString> arg0;
284 0 : if (args.length() > 0) {
285 0 : if (!arg0.SetCapacity(args.length() - 0, mozilla::fallible)) {
286 0 : JS_ReportOutOfMemory(cx);
287 0 : return false;
288 : }
289 0 : for (uint32_t variadicArg = 0; variadicArg < args.length(); ++variadicArg) {
290 0 : nsString& slot = *arg0.AppendElement(mozilla::fallible);
291 0 : if (!ConvertJSValueToString(cx, args[variadicArg], eStringify, eStringify, slot)) {
292 0 : return false;
293 : }
294 : }
295 : }
296 0 : bool result(self->Is(NonNullHelper(Constify(arg0))));
297 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
298 0 : args.rval().setBoolean(result);
299 0 : return true;
300 : }
301 :
302 : static const JSJitInfo is_methodinfo = {
303 : { (JSJitGetterOp)is },
304 : { prototypes::id::AccessibleNode },
305 : { PrototypeTraits<prototypes::id::AccessibleNode>::Depth },
306 : JSJitInfo::Method,
307 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
308 : JSVAL_TYPE_BOOLEAN, /* returnType. Not relevant for setters. */
309 : false, /* isInfallible. False in setters. */
310 : false, /* isMovable. Not relevant for setters. */
311 : false, /* isEliminatable. Not relevant for setters. */
312 : false, /* isAlwaysInSlot. Only relevant for getters. */
313 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
314 : false, /* isTypedMethod. Only relevant for methods. */
315 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
316 : };
317 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
318 : static_assert(0 < 3, "There is no slot for us");
319 :
320 : static bool
321 0 : has(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AccessibleNode* self, const JSJitMethodCallArgs& args)
322 : {
323 0 : binding_detail::AutoSequence<nsString> arg0;
324 0 : if (args.length() > 0) {
325 0 : if (!arg0.SetCapacity(args.length() - 0, mozilla::fallible)) {
326 0 : JS_ReportOutOfMemory(cx);
327 0 : return false;
328 : }
329 0 : for (uint32_t variadicArg = 0; variadicArg < args.length(); ++variadicArg) {
330 0 : nsString& slot = *arg0.AppendElement(mozilla::fallible);
331 0 : if (!ConvertJSValueToString(cx, args[variadicArg], eStringify, eStringify, slot)) {
332 0 : return false;
333 : }
334 : }
335 : }
336 0 : bool result(self->Has(NonNullHelper(Constify(arg0))));
337 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
338 0 : args.rval().setBoolean(result);
339 0 : return true;
340 : }
341 :
342 : static const JSJitInfo has_methodinfo = {
343 : { (JSJitGetterOp)has },
344 : { prototypes::id::AccessibleNode },
345 : { PrototypeTraits<prototypes::id::AccessibleNode>::Depth },
346 : JSJitInfo::Method,
347 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
348 : JSVAL_TYPE_BOOLEAN, /* returnType. Not relevant for setters. */
349 : false, /* isInfallible. False in setters. */
350 : false, /* isMovable. Not relevant for setters. */
351 : false, /* isEliminatable. Not relevant for setters. */
352 : false, /* isAlwaysInSlot. Only relevant for getters. */
353 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
354 : false, /* isTypedMethod. Only relevant for methods. */
355 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
356 : };
357 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
358 : static_assert(0 < 3, "There is no slot for us");
359 :
360 : static bool
361 0 : get(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AccessibleNode* self, const JSJitMethodCallArgs& args)
362 : {
363 0 : if (MOZ_UNLIKELY(args.length() < 1)) {
364 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "AccessibleNode.get");
365 : }
366 0 : binding_detail::FakeString arg0;
367 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
368 0 : return false;
369 : }
370 0 : binding_detail::FastErrorResult rv;
371 0 : JS::Rooted<JS::Value> result(cx);
372 0 : self->Get(cx, NonNullHelper(Constify(arg0)), &result, rv);
373 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
374 0 : return false;
375 : }
376 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
377 0 : JS::ExposeValueToActiveJS(result);
378 0 : args.rval().set(result);
379 0 : if (!MaybeWrapValue(cx, args.rval())) {
380 0 : return false;
381 : }
382 0 : return true;
383 : }
384 :
385 : static const JSJitInfo get_methodinfo = {
386 : { (JSJitGetterOp)get },
387 : { prototypes::id::AccessibleNode },
388 : { PrototypeTraits<prototypes::id::AccessibleNode>::Depth },
389 : JSJitInfo::Method,
390 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
391 : JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */
392 : false, /* isInfallible. False in setters. */
393 : false, /* isMovable. Not relevant for setters. */
394 : false, /* isEliminatable. Not relevant for setters. */
395 : false, /* isAlwaysInSlot. Only relevant for getters. */
396 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
397 : false, /* isTypedMethod. Only relevant for methods. */
398 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
399 : };
400 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
401 : static_assert(0 < 3, "There is no slot for us");
402 :
403 : static bool
404 0 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
405 : {
406 0 : mozilla::dom::AccessibleNode* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::AccessibleNode>(obj);
407 : // We don't want to preserve if we don't have a wrapper, and we
408 : // obviously can't preserve if we're not initialized.
409 0 : if (self && self->GetWrapperPreserveColor()) {
410 0 : PreserveWrapper(self);
411 : }
412 0 : return true;
413 : }
414 :
415 : static void
416 0 : _finalize(js::FreeOp* fop, JSObject* obj)
417 : {
418 0 : mozilla::dom::AccessibleNode* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::AccessibleNode>(obj);
419 0 : if (self) {
420 0 : ClearWrapper(self, self, obj);
421 0 : AddForDeferredFinalization<mozilla::dom::AccessibleNode>(self);
422 : }
423 0 : }
424 :
425 : static void
426 0 : _objectMoved(JSObject* obj, const JSObject* old)
427 : {
428 0 : mozilla::dom::AccessibleNode* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::AccessibleNode>(obj);
429 0 : if (self) {
430 0 : UpdateWrapper(self, self, obj, old);
431 : }
432 0 : }
433 :
434 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
435 : #if defined(__clang__)
436 : #pragma clang diagnostic push
437 : #pragma clang diagnostic ignored "-Wmissing-braces"
438 : #endif
439 : static const JSFunctionSpec sMethods_specs[] = {
440 : JS_FNSPEC("is", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&is_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
441 : JS_FNSPEC("has", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&has_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
442 : JS_FNSPEC("get", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&get_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
443 : JS_FS_END
444 : };
445 : #if defined(__clang__)
446 : #pragma clang diagnostic pop
447 : #endif
448 :
449 :
450 : // Can't be const because the pref-enabled boolean needs to be writable
451 : static Prefable<const JSFunctionSpec> sMethods[] = {
452 : { nullptr, &sMethods_specs[0] },
453 : { nullptr, nullptr }
454 : };
455 :
456 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
457 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
458 : static_assert(3 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
459 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
460 :
461 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
462 : #if defined(__clang__)
463 : #pragma clang diagnostic push
464 : #pragma clang diagnostic ignored "-Wmissing-braces"
465 : #endif
466 : static const JSPropertySpec sAttributes_specs[] = {
467 : { "role", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &role_getterinfo, nullptr, nullptr },
468 : { "states", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &states_getterinfo, nullptr, nullptr },
469 : { "attributes", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &attributes_getterinfo, nullptr, nullptr },
470 : { "DOMNode", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &DOMNode_getterinfo, nullptr, nullptr },
471 : { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
472 : };
473 : #if defined(__clang__)
474 : #pragma clang diagnostic pop
475 : #endif
476 :
477 :
478 : // Can't be const because the pref-enabled boolean needs to be writable
479 : static Prefable<const JSPropertySpec> sAttributes[] = {
480 : { nullptr, &sAttributes_specs[0] },
481 : { nullptr, nullptr }
482 : };
483 :
484 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
485 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
486 : static_assert(4 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
487 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
488 :
489 :
490 : static uint16_t sNativeProperties_sortedPropertyIndices[7];
491 : static PropertyInfo sNativeProperties_propertyInfos[7];
492 :
493 : static const NativePropertiesN<2> sNativeProperties = {
494 : false, 0,
495 : false, 0,
496 : true, 0 /* sMethods */,
497 : true, 1 /* sAttributes */,
498 : false, 0,
499 : false, 0,
500 : false, 0,
501 : -1,
502 : 7,
503 : sNativeProperties_sortedPropertyIndices,
504 : {
505 : { sMethods, &sNativeProperties_propertyInfos[0] },
506 : { sAttributes, &sNativeProperties_propertyInfos[3] }
507 : }
508 : };
509 : static_assert(7 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
510 : "We have a property info count that is oversized");
511 :
512 : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
513 : {
514 : "Function",
515 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
516 : &sBoringInterfaceObjectClassClassOps,
517 : JS_NULL_CLASS_SPEC,
518 : JS_NULL_CLASS_EXT,
519 : &sInterfaceObjectClassObjectOps
520 : },
521 : eInterface,
522 : true,
523 : prototypes::id::AccessibleNode,
524 : PrototypeTraits<prototypes::id::AccessibleNode>::Depth,
525 : sNativePropertyHooks,
526 : "function AccessibleNode() {\n [native code]\n}",
527 : JS::GetRealmFunctionPrototype
528 : };
529 :
530 : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
531 : {
532 : "AccessibleNodePrototype",
533 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
534 : JS_NULL_CLASS_OPS,
535 : JS_NULL_CLASS_SPEC,
536 : JS_NULL_CLASS_EXT,
537 : JS_NULL_OBJECT_OPS
538 : },
539 : eInterfacePrototype,
540 : false,
541 : prototypes::id::AccessibleNode,
542 : PrototypeTraits<prototypes::id::AccessibleNode>::Depth,
543 : sNativePropertyHooks,
544 : "[object AccessibleNodePrototype]",
545 : JS::GetRealmObjectPrototype
546 : };
547 :
548 : bool
549 0 : ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
550 : {
551 : static bool sPrefValue;
552 : static bool sPrefCacheSetUp = false;
553 0 : if (!sPrefCacheSetUp) {
554 0 : sPrefCacheSetUp = true;
555 0 : Preferences::AddBoolVarCache(&sPrefValue, "accessibility.AOM.enabled");
556 : }
557 :
558 0 : return sPrefValue;
559 : }
560 :
561 : JSObject*
562 0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
563 : {
564 0 : return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
565 : }
566 :
567 : static const js::ClassOps sClassOps = {
568 : _addProperty, /* addProperty */
569 : nullptr, /* delProperty */
570 : nullptr, /* getProperty */
571 : nullptr, /* setProperty */
572 : nullptr, /* enumerate */
573 : nullptr, /* newEnumerate */
574 : nullptr, /* resolve */
575 : nullptr, /* mayResolve */
576 : _finalize, /* finalize */
577 : nullptr, /* call */
578 : nullptr, /* hasInstance */
579 : nullptr, /* construct */
580 : nullptr, /* trace */
581 : };
582 :
583 : static const js::ClassExtension sClassExtension = {
584 : nullptr, /* weakmapKeyDelegateOp */
585 : _objectMoved /* objectMovedOp */
586 : };
587 :
588 : static const DOMJSClass sClass = {
589 : { "AccessibleNode",
590 : JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(3),
591 : &sClassOps,
592 : JS_NULL_CLASS_SPEC,
593 : &sClassExtension,
594 : JS_NULL_OBJECT_OPS
595 : },
596 : { prototypes::id::AccessibleNode, 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 },
597 : IsBaseOf<nsISupports, mozilla::dom::AccessibleNode >::value,
598 : sNativePropertyHooks,
599 : FindAssociatedGlobalForNative<mozilla::dom::AccessibleNode>::Get,
600 : GetProtoObjectHandle,
601 : GetCCParticipant<mozilla::dom::AccessibleNode>::Get()
602 : };
603 : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
604 : "Must have the right minimal number of reserved slots.");
605 : static_assert(3 >= 3,
606 : "Must have enough reserved slots.");
607 :
608 : const JSClass*
609 0 : GetJSClass()
610 : {
611 0 : return sClass.ToJSClass();
612 : }
613 :
614 : bool
615 0 : Wrap(JSContext* aCx, mozilla::dom::AccessibleNode* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
616 : {
617 : MOZ_ASSERT(static_cast<mozilla::dom::AccessibleNode*>(aObject) ==
618 : reinterpret_cast<mozilla::dom::AccessibleNode*>(aObject),
619 : "Multiple inheritance for mozilla::dom::AccessibleNode is broken.");
620 0 : MOZ_ASSERT(ToSupportsIsCorrect(aObject));
621 0 : MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
622 0 : MOZ_ASSERT(!aCache->GetWrapper(),
623 : "You should probably not be using Wrap() directly; use "
624 : "GetOrCreateDOMReflector instead");
625 :
626 0 : MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
627 : "nsISupports must be on our primary inheritance chain");
628 :
629 0 : JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
630 0 : if (!global) {
631 0 : return false;
632 : }
633 0 : MOZ_ASSERT(JS_IsGlobalObject(global));
634 0 : MOZ_ASSERT(JS::ObjectIsNotGray(global));
635 :
636 : // That might have ended up wrapping us already, due to the wonders
637 : // of XBL. Check for that, and bail out as needed.
638 0 : aReflector.set(aCache->GetWrapper());
639 0 : if (aReflector) {
640 : #ifdef DEBUG
641 0 : binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
642 : #endif // DEBUG
643 0 : return true;
644 : }
645 :
646 0 : JSAutoCompartment ac(aCx, global);
647 0 : JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
648 0 : if (!canonicalProto) {
649 0 : return false;
650 : }
651 0 : JS::Rooted<JSObject*> proto(aCx);
652 0 : if (aGivenProto) {
653 0 : proto = aGivenProto;
654 : // Unfortunately, while aGivenProto was in the compartment of aCx
655 : // coming in, we changed compartments to that of "parent" so may need
656 : // to wrap the proto here.
657 0 : if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
658 0 : if (!JS_WrapObject(aCx, &proto)) {
659 0 : return false;
660 : }
661 : }
662 : } else {
663 0 : proto = canonicalProto;
664 : }
665 :
666 0 : BindingJSObjectCreator<mozilla::dom::AccessibleNode> creator(aCx);
667 0 : creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
668 0 : if (!aReflector) {
669 0 : return false;
670 : }
671 :
672 0 : aCache->SetWrapper(aReflector);
673 0 : creator.InitializationSucceeded();
674 :
675 0 : MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
676 : aCache->GetWrapperPreserveColor() == aReflector);
677 : // If proto != canonicalProto, we have to preserve our wrapper;
678 : // otherwise we won't be able to properly recreate it later, since
679 : // we won't know what proto to use. Note that we don't check
680 : // aGivenProto here, since it's entirely possible (and even
681 : // somewhat common) to have a non-null aGivenProto which is the
682 : // same as canonicalProto.
683 0 : if (proto != canonicalProto) {
684 0 : PreserveWrapper(aObject);
685 : }
686 :
687 0 : return true;
688 : }
689 :
690 : // This may allocate too many slots, because we only really need
691 : // slots for our non-interface-typed members that we cache. But
692 : // allocating slots only for those would make the slot index
693 : // computations much more complicated, so let's do this the simple
694 : // way for now.
695 : DEFINE_XRAY_EXPANDO_CLASS(static, sXrayExpandoObjectClass, 2);
696 :
697 : const NativePropertyHooks sNativePropertyHooks[] = { {
698 : nullptr,
699 : nullptr,
700 : nullptr,
701 : { sNativeProperties.Upcast(), nullptr },
702 : prototypes::id::AccessibleNode,
703 : constructors::id::AccessibleNode,
704 : nullptr,
705 : &sXrayExpandoObjectClass
706 : } };
707 :
708 : void
709 0 : ClearCachedStatesValue(mozilla::dom::AccessibleNode* aObject)
710 : {
711 : JSObject* obj;
712 0 : obj = aObject->GetWrapper();
713 0 : if (!obj) {
714 0 : return;
715 : }
716 0 : js::SetReservedSlot(obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), JS::UndefinedValue());
717 0 : xpc::ClearXrayExpandoSlots(obj, (xpc::JSSLOT_EXPANDO_COUNT + 0));
718 : }
719 :
720 : void
721 0 : ClearCachedAttributesValue(mozilla::dom::AccessibleNode* aObject)
722 : {
723 : JSObject* obj;
724 0 : obj = aObject->GetWrapper();
725 0 : if (!obj) {
726 0 : return;
727 : }
728 0 : js::SetReservedSlot(obj, (DOM_INSTANCE_RESERVED_SLOTS + 1), JS::UndefinedValue());
729 0 : xpc::ClearXrayExpandoSlots(obj, (xpc::JSSLOT_EXPANDO_COUNT + 1));
730 : }
731 :
732 : void
733 0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
734 : {
735 0 : JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
736 0 : if (!parentProto) {
737 0 : return;
738 : }
739 :
740 0 : JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
741 0 : if (!constructorProto) {
742 0 : return;
743 : }
744 :
745 : static bool sIdsInited = false;
746 0 : if (!sIdsInited && NS_IsMainThread()) {
747 0 : if (!InitIds(aCx, sNativeProperties.Upcast())) {
748 0 : return;
749 : }
750 0 : sIdsInited = true;
751 : }
752 :
753 0 : JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::AccessibleNode);
754 0 : JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::AccessibleNode);
755 0 : dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
756 : &sPrototypeClass.mBase, protoCache,
757 : constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
758 : interfaceCache,
759 : sNativeProperties.Upcast(),
760 : nullptr,
761 : "AccessibleNode", aDefineOnGlobal,
762 : nullptr,
763 0 : false);
764 : }
765 :
766 : JS::Handle<JSObject*>
767 0 : GetProtoObjectHandle(JSContext* aCx)
768 : {
769 : /* Get the interface prototype object for this class. This will create the
770 : object as needed. */
771 0 : bool aDefineOnGlobal = true;
772 :
773 : /* Make sure our global is sane. Hopefully we can remove this sometime */
774 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
775 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
776 0 : return nullptr;
777 : }
778 :
779 : /* Check to see whether the interface objects are already installed */
780 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
781 0 : if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::AccessibleNode)) {
782 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
783 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
784 : }
785 :
786 : /*
787 : * The object might _still_ be null, but that's OK.
788 : *
789 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
790 : * traced by TraceProtoAndIfaceCache() and its contents are never
791 : * changed after they have been set.
792 : *
793 : * Calling address() avoids the read read barrier that does gray
794 : * unmarking, but it's not possible for the object to be gray here.
795 : */
796 :
797 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::AccessibleNode);
798 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
799 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
800 : }
801 :
802 : JS::Handle<JSObject*>
803 0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
804 : {
805 : /* Get the interface object for this class. This will create the object as
806 : needed. */
807 :
808 : /* Make sure our global is sane. Hopefully we can remove this sometime */
809 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
810 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
811 0 : return nullptr;
812 : }
813 :
814 : /* Check to see whether the interface objects are already installed */
815 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
816 0 : if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::AccessibleNode)) {
817 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
818 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
819 : }
820 :
821 : /*
822 : * The object might _still_ be null, but that's OK.
823 : *
824 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
825 : * traced by TraceProtoAndIfaceCache() and its contents are never
826 : * changed after they have been set.
827 : *
828 : * Calling address() avoids the read read barrier that does gray
829 : * unmarking, but it's not possible for the object to be gray here.
830 : */
831 :
832 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::AccessibleNode);
833 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
834 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
835 : }
836 :
837 : JSObject*
838 0 : GetConstructorObject(JSContext* aCx)
839 : {
840 0 : return GetConstructorObjectHandle(aCx);
841 : }
842 :
843 : } // namespace AccessibleNodeBinding
844 :
845 :
846 :
847 : } // namespace dom
848 : } // namespace mozilla
|