Line data Source code
1 : /* THIS FILE IS AUTOGENERATED FROM Gamepad.webidl BY Codegen.py - DO NOT EDIT */
2 :
3 : #include "GamepadBinding.h"
4 : #include "WrapperFactory.h"
5 : #include "XrayWrapper.h"
6 : #include "jsapi.h"
7 : #include "mozilla/FloatingPoint.h"
8 : #include "mozilla/OwningNonNull.h"
9 : #include "mozilla/Preferences.h"
10 : #include "mozilla/dom/BindingUtils.h"
11 : #include "mozilla/dom/DOMJSClass.h"
12 : #include "mozilla/dom/Gamepad.h"
13 : #include "mozilla/dom/GamepadButton.h"
14 : #include "mozilla/dom/GamepadHapticActuator.h"
15 : #include "mozilla/dom/GamepadPose.h"
16 : #include "mozilla/dom/NonRefcountedDOMObject.h"
17 : #include "mozilla/dom/Nullable.h"
18 : #include "mozilla/dom/PrimitiveConversions.h"
19 : #include "mozilla/dom/XrayExpandoClass.h"
20 :
21 : namespace mozilla {
22 : namespace dom {
23 :
24 : namespace GamepadHandValues {
25 : extern const EnumEntry strings[4] = {
26 : {"", 0},
27 : {"left", 4},
28 : {"right", 5},
29 : { nullptr, 0 }
30 : };
31 : } // namespace GamepadHandValues
32 :
33 : bool
34 0 : ToJSValue(JSContext* aCx, GamepadHand aArgument, JS::MutableHandle<JS::Value> aValue)
35 : {
36 0 : MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(GamepadHandValues::strings));
37 : JSString* resultStr =
38 0 : JS_NewStringCopyN(aCx, GamepadHandValues::strings[uint32_t(aArgument)].value,
39 0 : GamepadHandValues::strings[uint32_t(aArgument)].length);
40 0 : if (!resultStr) {
41 0 : return false;
42 : }
43 0 : aValue.setString(resultStr);
44 0 : return true;
45 : }
46 :
47 :
48 : namespace GamepadMappingTypeValues {
49 : extern const EnumEntry strings[3] = {
50 : {"", 0},
51 : {"standard", 8},
52 : { nullptr, 0 }
53 : };
54 : } // namespace GamepadMappingTypeValues
55 :
56 : bool
57 0 : ToJSValue(JSContext* aCx, GamepadMappingType aArgument, JS::MutableHandle<JS::Value> aValue)
58 : {
59 0 : MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(GamepadMappingTypeValues::strings));
60 : JSString* resultStr =
61 0 : JS_NewStringCopyN(aCx, GamepadMappingTypeValues::strings[uint32_t(aArgument)].value,
62 0 : GamepadMappingTypeValues::strings[uint32_t(aArgument)].length);
63 0 : if (!resultStr) {
64 0 : return false;
65 : }
66 0 : aValue.setString(resultStr);
67 0 : return true;
68 : }
69 :
70 :
71 : namespace GamepadBinding {
72 :
73 : static bool
74 0 : get_id(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Gamepad* self, JSJitGetterCallArgs args)
75 : {
76 0 : DOMString result;
77 0 : self->GetId(result);
78 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
79 0 : if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
80 0 : return false;
81 : }
82 0 : return true;
83 : }
84 :
85 : static const JSJitInfo id_getterinfo = {
86 : { (JSJitGetterOp)get_id },
87 : { prototypes::id::Gamepad },
88 : { PrototypeTraits<prototypes::id::Gamepad>::Depth },
89 : JSJitInfo::Getter,
90 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
91 : JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
92 : false, /* 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 < 4, "There is no slot for us");
102 :
103 : static bool
104 0 : get_index(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Gamepad* self, JSJitGetterCallArgs args)
105 : {
106 0 : uint32_t result(self->Index());
107 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
108 0 : args.rval().setNumber(result);
109 0 : return true;
110 : }
111 :
112 : static const JSJitInfo index_getterinfo = {
113 : { (JSJitGetterOp)get_index },
114 : { prototypes::id::Gamepad },
115 : { PrototypeTraits<prototypes::id::Gamepad>::Depth },
116 : JSJitInfo::Getter,
117 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
118 : JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
119 : true, /* isInfallible. False in setters. */
120 : false, /* isMovable. Not relevant for setters. */
121 : false, /* isEliminatable. Not relevant for setters. */
122 : false, /* isAlwaysInSlot. Only relevant for getters. */
123 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
124 : false, /* isTypedMethod. Only relevant for methods. */
125 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
126 : };
127 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
128 : static_assert(0 < 4, "There is no slot for us");
129 :
130 : static bool
131 0 : get_mapping(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Gamepad* self, JSJitGetterCallArgs args)
132 : {
133 0 : GamepadMappingType result(self->Mapping());
134 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
135 0 : if (!ToJSValue(cx, result, args.rval())) {
136 0 : return false;
137 : }
138 0 : return true;
139 : }
140 :
141 : static const JSJitInfo mapping_getterinfo = {
142 : { (JSJitGetterOp)get_mapping },
143 : { prototypes::id::Gamepad },
144 : { PrototypeTraits<prototypes::id::Gamepad>::Depth },
145 : JSJitInfo::Getter,
146 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
147 : JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
148 : false, /* isInfallible. False in setters. */
149 : false, /* isMovable. Not relevant for setters. */
150 : false, /* isEliminatable. Not relevant for setters. */
151 : false, /* isAlwaysInSlot. Only relevant for getters. */
152 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
153 : false, /* isTypedMethod. Only relevant for methods. */
154 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
155 : };
156 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
157 : static_assert(0 < 4, "There is no slot for us");
158 :
159 : static bool
160 0 : get_hand(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Gamepad* self, JSJitGetterCallArgs args)
161 : {
162 0 : GamepadHand result(self->Hand());
163 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
164 0 : if (!ToJSValue(cx, result, args.rval())) {
165 0 : return false;
166 : }
167 0 : return true;
168 : }
169 :
170 : static const JSJitInfo hand_getterinfo = {
171 : { (JSJitGetterOp)get_hand },
172 : { prototypes::id::Gamepad },
173 : { PrototypeTraits<prototypes::id::Gamepad>::Depth },
174 : JSJitInfo::Getter,
175 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
176 : JSVAL_TYPE_STRING, /* 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 < 4, "There is no slot for us");
187 :
188 : static bool
189 0 : get_connected(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Gamepad* self, JSJitGetterCallArgs args)
190 : {
191 0 : bool result(self->Connected());
192 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
193 0 : args.rval().setBoolean(result);
194 0 : return true;
195 : }
196 :
197 : static const JSJitInfo connected_getterinfo = {
198 : { (JSJitGetterOp)get_connected },
199 : { prototypes::id::Gamepad },
200 : { PrototypeTraits<prototypes::id::Gamepad>::Depth },
201 : JSJitInfo::Getter,
202 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
203 : JSVAL_TYPE_BOOLEAN, /* returnType. Not relevant for setters. */
204 : true, /* isInfallible. False in setters. */
205 : false, /* isMovable. Not relevant for setters. */
206 : false, /* isEliminatable. Not relevant for setters. */
207 : false, /* isAlwaysInSlot. Only relevant for getters. */
208 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
209 : false, /* isTypedMethod. Only relevant for methods. */
210 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
211 : };
212 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
213 : static_assert(0 < 4, "There is no slot for us");
214 :
215 : static bool
216 0 : get_buttons(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Gamepad* self, JSJitGetterCallArgs args)
217 : {
218 : // Have to either root across the getter call or reget after.
219 : bool isXray;
220 0 : JS::Rooted<JSObject*> slotStorage(cx, GetCachedSlotStorageObject(cx, obj, &isXray));
221 0 : if (!slotStorage) {
222 0 : return false;
223 : }
224 0 : const size_t slotIndex = isXray ? (xpc::JSSLOT_EXPANDO_COUNT + 0) : (DOM_INSTANCE_RESERVED_SLOTS + 0);
225 0 : MOZ_ASSERT(JSCLASS_RESERVED_SLOTS(js::GetObjectClass(slotStorage)) > slotIndex);
226 : {
227 : // Scope for cachedVal
228 0 : JS::Value cachedVal = js::GetReservedSlot(slotStorage, slotIndex);
229 0 : if (!cachedVal.isUndefined()) {
230 0 : args.rval().set(cachedVal);
231 : // The cached value is in the compartment of slotStorage,
232 : // so wrap into the caller compartment as needed.
233 0 : return MaybeWrapNonDOMObjectValue(cx, args.rval());
234 : }
235 : }
236 :
237 0 : nsTArray<StrongPtrForMember<mozilla::dom::GamepadButton>::Type> result;
238 0 : self->GetButtons(result);
239 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
240 : {
241 0 : JS::Rooted<JSObject*> conversionScope(cx, isXray ? obj : slotStorage);
242 0 : JSAutoCompartment ac(cx, conversionScope);
243 : do { // block we break out of when done wrapping
244 :
245 0 : uint32_t length = result.Length();
246 0 : JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
247 0 : if (!returnArray) {
248 0 : return false;
249 : }
250 : // Scope for 'tmp'
251 : {
252 0 : JS::Rooted<JS::Value> tmp(cx);
253 0 : for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
254 : // Control block to let us common up the JS_DefineElement calls when there
255 : // are different ways to succeed at wrapping the object.
256 : do {
257 0 : if (!GetOrCreateDOMReflector(cx, result[sequenceIdx0], &tmp)) {
258 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
259 0 : return false;
260 : }
261 0 : break;
262 : } while (0);
263 0 : if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
264 : JSPROP_ENUMERATE)) {
265 0 : return false;
266 : }
267 : }
268 : }
269 0 : args.rval().setObject(*returnArray);
270 0 : break;
271 : } while (0);
272 0 : JS::Rooted<JSObject*> rvalObj(cx, &args.rval().toObject());
273 0 : if (!JS_FreezeObject(cx, rvalObj)) {
274 0 : return false;
275 : }
276 : }
277 : { // And now store things in the compartment of our slotStorage.
278 0 : JSAutoCompartment ac(cx, slotStorage);
279 : // Make a copy so that we don't do unnecessary wrapping on args.rval().
280 0 : JS::Rooted<JS::Value> storedVal(cx, args.rval());
281 0 : if (!MaybeWrapNonDOMObjectValue(cx, &storedVal)) {
282 0 : return false;
283 : }
284 0 : js::SetReservedSlot(slotStorage, slotIndex, storedVal);
285 0 : if (!isXray) {
286 : // In the Xray case we don't need to do this, because getting the
287 : // expando object already preserved our wrapper.
288 0 : PreserveWrapper(self);
289 : }
290 : }
291 : // And now make sure args.rval() is in the caller compartment
292 0 : return MaybeWrapNonDOMObjectValue(cx, args.rval());
293 : }
294 :
295 : static const JSJitInfo buttons_getterinfo = {
296 : { (JSJitGetterOp)get_buttons },
297 : { prototypes::id::Gamepad },
298 : { PrototypeTraits<prototypes::id::Gamepad>::Depth },
299 : JSJitInfo::Getter,
300 : JSJitInfo::AliasDOMSets, /* aliasSet. Not relevant for setters. */
301 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
302 : false, /* isInfallible. False in setters. */
303 : true, /* isMovable. Not relevant for setters. */
304 : true, /* isEliminatable. Not relevant for setters. */
305 : false, /* isAlwaysInSlot. Only relevant for getters. */
306 : true, /* isLazilyCachedInSlot. Only relevant for getters. */
307 : false, /* isTypedMethod. Only relevant for methods. */
308 : (DOM_INSTANCE_RESERVED_SLOTS + 0) /* Reserved slot index, if we're stored in a slot, else 0. */
309 : };
310 : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 0) <= JSJitInfo::maxSlotIndex, "We won't fit");
311 : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 0) < 4, "There is no slot for us");
312 :
313 : static bool
314 0 : get_axes(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Gamepad* self, JSJitGetterCallArgs args)
315 : {
316 : // Have to either root across the getter call or reget after.
317 : bool isXray;
318 0 : JS::Rooted<JSObject*> slotStorage(cx, GetCachedSlotStorageObject(cx, obj, &isXray));
319 0 : if (!slotStorage) {
320 0 : return false;
321 : }
322 0 : const size_t slotIndex = isXray ? (xpc::JSSLOT_EXPANDO_COUNT + 1) : (DOM_INSTANCE_RESERVED_SLOTS + 1);
323 0 : MOZ_ASSERT(JSCLASS_RESERVED_SLOTS(js::GetObjectClass(slotStorage)) > slotIndex);
324 : {
325 : // Scope for cachedVal
326 0 : JS::Value cachedVal = js::GetReservedSlot(slotStorage, slotIndex);
327 0 : if (!cachedVal.isUndefined()) {
328 0 : args.rval().set(cachedVal);
329 : // The cached value is in the compartment of slotStorage,
330 : // so wrap into the caller compartment as needed.
331 0 : return MaybeWrapNonDOMObjectValue(cx, args.rval());
332 : }
333 : }
334 :
335 0 : nsTArray<double> result;
336 0 : self->GetAxes(result);
337 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
338 : {
339 0 : JS::Rooted<JSObject*> conversionScope(cx, isXray ? obj : slotStorage);
340 0 : JSAutoCompartment ac(cx, conversionScope);
341 : do { // block we break out of when done wrapping
342 :
343 0 : uint32_t length = result.Length();
344 0 : JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
345 0 : if (!returnArray) {
346 0 : return false;
347 : }
348 : // Scope for 'tmp'
349 : {
350 0 : JS::Rooted<JS::Value> tmp(cx);
351 0 : for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
352 : // Control block to let us common up the JS_DefineElement calls when there
353 : // are different ways to succeed at wrapping the object.
354 : do {
355 0 : tmp.set(JS_NumberValue(double(result[sequenceIdx0])));
356 0 : break;
357 : } while (0);
358 0 : if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
359 : JSPROP_ENUMERATE)) {
360 0 : return false;
361 : }
362 : }
363 : }
364 0 : args.rval().setObject(*returnArray);
365 0 : break;
366 : } while (0);
367 0 : JS::Rooted<JSObject*> rvalObj(cx, &args.rval().toObject());
368 0 : if (!JS_FreezeObject(cx, rvalObj)) {
369 0 : return false;
370 : }
371 : }
372 : { // And now store things in the compartment of our slotStorage.
373 0 : JSAutoCompartment ac(cx, slotStorage);
374 : // Make a copy so that we don't do unnecessary wrapping on args.rval().
375 0 : JS::Rooted<JS::Value> storedVal(cx, args.rval());
376 0 : if (!MaybeWrapNonDOMObjectValue(cx, &storedVal)) {
377 0 : return false;
378 : }
379 0 : js::SetReservedSlot(slotStorage, slotIndex, storedVal);
380 0 : if (!isXray) {
381 : // In the Xray case we don't need to do this, because getting the
382 : // expando object already preserved our wrapper.
383 0 : PreserveWrapper(self);
384 : }
385 : }
386 : // And now make sure args.rval() is in the caller compartment
387 0 : return MaybeWrapNonDOMObjectValue(cx, args.rval());
388 : }
389 :
390 : static const JSJitInfo axes_getterinfo = {
391 : { (JSJitGetterOp)get_axes },
392 : { prototypes::id::Gamepad },
393 : { PrototypeTraits<prototypes::id::Gamepad>::Depth },
394 : JSJitInfo::Getter,
395 : JSJitInfo::AliasDOMSets, /* aliasSet. Not relevant for setters. */
396 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
397 : false, /* isInfallible. False in setters. */
398 : true, /* isMovable. Not relevant for setters. */
399 : true, /* isEliminatable. Not relevant for setters. */
400 : false, /* isAlwaysInSlot. Only relevant for getters. */
401 : true, /* isLazilyCachedInSlot. Only relevant for getters. */
402 : false, /* isTypedMethod. Only relevant for methods. */
403 : (DOM_INSTANCE_RESERVED_SLOTS + 1) /* Reserved slot index, if we're stored in a slot, else 0. */
404 : };
405 : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 1) <= JSJitInfo::maxSlotIndex, "We won't fit");
406 : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 1) < 4, "There is no slot for us");
407 :
408 : static bool
409 0 : get_timestamp(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Gamepad* self, JSJitGetterCallArgs args)
410 : {
411 0 : double result(self->Timestamp());
412 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
413 0 : args.rval().set(JS_NumberValue(double(result)));
414 0 : return true;
415 : }
416 :
417 : static const JSJitInfo timestamp_getterinfo = {
418 : { (JSJitGetterOp)get_timestamp },
419 : { prototypes::id::Gamepad },
420 : { PrototypeTraits<prototypes::id::Gamepad>::Depth },
421 : JSJitInfo::Getter,
422 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
423 : JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
424 : true, /* isInfallible. False in setters. */
425 : false, /* isMovable. Not relevant for setters. */
426 : false, /* isEliminatable. Not relevant for setters. */
427 : false, /* isAlwaysInSlot. Only relevant for getters. */
428 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
429 : false, /* isTypedMethod. Only relevant for methods. */
430 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
431 : };
432 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
433 : static_assert(0 < 4, "There is no slot for us");
434 :
435 : static bool
436 0 : get_pose(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Gamepad* self, JSJitGetterCallArgs args)
437 : {
438 0 : auto result(StrongOrRawPtr<mozilla::dom::GamepadPose>(self->GetPose()));
439 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
440 0 : if (!result) {
441 0 : args.rval().setNull();
442 0 : return true;
443 : }
444 0 : if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
445 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
446 0 : return false;
447 : }
448 0 : return true;
449 : }
450 :
451 : static const JSJitInfo pose_getterinfo = {
452 : { (JSJitGetterOp)get_pose },
453 : { prototypes::id::Gamepad },
454 : { PrototypeTraits<prototypes::id::Gamepad>::Depth },
455 : JSJitInfo::Getter,
456 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
457 : JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */
458 : false, /* isInfallible. False in setters. */
459 : false, /* isMovable. Not relevant for setters. */
460 : false, /* isEliminatable. Not relevant for setters. */
461 : false, /* isAlwaysInSlot. Only relevant for getters. */
462 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
463 : false, /* isTypedMethod. Only relevant for methods. */
464 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
465 : };
466 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
467 : static_assert(0 < 4, "There is no slot for us");
468 :
469 : static bool
470 0 : get_hapticActuators(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Gamepad* self, JSJitGetterCallArgs args)
471 : {
472 : // Have to either root across the getter call or reget after.
473 : bool isXray;
474 0 : JS::Rooted<JSObject*> slotStorage(cx, GetCachedSlotStorageObject(cx, obj, &isXray));
475 0 : if (!slotStorage) {
476 0 : return false;
477 : }
478 0 : const size_t slotIndex = isXray ? (xpc::JSSLOT_EXPANDO_COUNT + 2) : (DOM_INSTANCE_RESERVED_SLOTS + 2);
479 0 : MOZ_ASSERT(JSCLASS_RESERVED_SLOTS(js::GetObjectClass(slotStorage)) > slotIndex);
480 : {
481 : // Scope for cachedVal
482 0 : JS::Value cachedVal = js::GetReservedSlot(slotStorage, slotIndex);
483 0 : if (!cachedVal.isUndefined()) {
484 0 : args.rval().set(cachedVal);
485 : // The cached value is in the compartment of slotStorage,
486 : // so wrap into the caller compartment as needed.
487 0 : return MaybeWrapNonDOMObjectValue(cx, args.rval());
488 : }
489 : }
490 :
491 0 : nsTArray<StrongPtrForMember<mozilla::dom::GamepadHapticActuator>::Type> result;
492 0 : self->GetHapticActuators(result);
493 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
494 : {
495 0 : JS::Rooted<JSObject*> conversionScope(cx, isXray ? obj : slotStorage);
496 0 : JSAutoCompartment ac(cx, conversionScope);
497 : do { // block we break out of when done wrapping
498 :
499 0 : uint32_t length = result.Length();
500 0 : JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
501 0 : if (!returnArray) {
502 0 : return false;
503 : }
504 : // Scope for 'tmp'
505 : {
506 0 : JS::Rooted<JS::Value> tmp(cx);
507 0 : for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
508 : // Control block to let us common up the JS_DefineElement calls when there
509 : // are different ways to succeed at wrapping the object.
510 : do {
511 0 : if (!GetOrCreateDOMReflector(cx, result[sequenceIdx0], &tmp)) {
512 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
513 0 : return false;
514 : }
515 0 : break;
516 : } while (0);
517 0 : if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
518 : JSPROP_ENUMERATE)) {
519 0 : return false;
520 : }
521 : }
522 : }
523 0 : args.rval().setObject(*returnArray);
524 0 : break;
525 : } while (0);
526 0 : JS::Rooted<JSObject*> rvalObj(cx, &args.rval().toObject());
527 0 : if (!JS_FreezeObject(cx, rvalObj)) {
528 0 : return false;
529 : }
530 : }
531 : { // And now store things in the compartment of our slotStorage.
532 0 : JSAutoCompartment ac(cx, slotStorage);
533 : // Make a copy so that we don't do unnecessary wrapping on args.rval().
534 0 : JS::Rooted<JS::Value> storedVal(cx, args.rval());
535 0 : if (!MaybeWrapNonDOMObjectValue(cx, &storedVal)) {
536 0 : return false;
537 : }
538 0 : js::SetReservedSlot(slotStorage, slotIndex, storedVal);
539 0 : if (!isXray) {
540 : // In the Xray case we don't need to do this, because getting the
541 : // expando object already preserved our wrapper.
542 0 : PreserveWrapper(self);
543 : }
544 : }
545 : // And now make sure args.rval() is in the caller compartment
546 0 : return MaybeWrapNonDOMObjectValue(cx, args.rval());
547 : }
548 :
549 : static const JSJitInfo hapticActuators_getterinfo = {
550 : { (JSJitGetterOp)get_hapticActuators },
551 : { prototypes::id::Gamepad },
552 : { PrototypeTraits<prototypes::id::Gamepad>::Depth },
553 : JSJitInfo::Getter,
554 : JSJitInfo::AliasNone, /* aliasSet. Not relevant for setters. */
555 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
556 : false, /* isInfallible. False in setters. */
557 : true, /* isMovable. Not relevant for setters. */
558 : true, /* isEliminatable. Not relevant for setters. */
559 : false, /* isAlwaysInSlot. Only relevant for getters. */
560 : true, /* isLazilyCachedInSlot. Only relevant for getters. */
561 : false, /* isTypedMethod. Only relevant for methods. */
562 : (DOM_INSTANCE_RESERVED_SLOTS + 2) /* Reserved slot index, if we're stored in a slot, else 0. */
563 : };
564 : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 2) <= JSJitInfo::maxSlotIndex, "We won't fit");
565 : static_assert((DOM_INSTANCE_RESERVED_SLOTS + 2) < 4, "There is no slot for us");
566 :
567 : static bool
568 0 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
569 : {
570 0 : mozilla::dom::Gamepad* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::Gamepad>(obj);
571 : // We don't want to preserve if we don't have a wrapper, and we
572 : // obviously can't preserve if we're not initialized.
573 0 : if (self && self->GetWrapperPreserveColor()) {
574 0 : PreserveWrapper(self);
575 : }
576 0 : return true;
577 : }
578 :
579 : static void
580 0 : _finalize(js::FreeOp* fop, JSObject* obj)
581 : {
582 0 : mozilla::dom::Gamepad* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::Gamepad>(obj);
583 0 : if (self) {
584 0 : ClearWrapper(self, self, obj);
585 0 : AddForDeferredFinalization<mozilla::dom::Gamepad>(self);
586 : }
587 0 : }
588 :
589 : static void
590 0 : _objectMoved(JSObject* obj, const JSObject* old)
591 : {
592 0 : mozilla::dom::Gamepad* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::Gamepad>(obj);
593 0 : if (self) {
594 0 : UpdateWrapper(self, self, obj, old);
595 : }
596 0 : }
597 :
598 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
599 : #if defined(__clang__)
600 : #pragma clang diagnostic push
601 : #pragma clang diagnostic ignored "-Wmissing-braces"
602 : #endif
603 : static const JSPropertySpec sAttributes_specs[] = {
604 : { "id", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &id_getterinfo, nullptr, nullptr },
605 : { "index", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &index_getterinfo, nullptr, nullptr },
606 : { "mapping", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &mapping_getterinfo, nullptr, nullptr },
607 : { nullptr, 0, nullptr, nullptr, nullptr, nullptr },
608 : { "hand", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &hand_getterinfo, nullptr, nullptr },
609 : { nullptr, 0, nullptr, nullptr, nullptr, nullptr },
610 : { "connected", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &connected_getterinfo, nullptr, nullptr },
611 : { "buttons", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &buttons_getterinfo, nullptr, nullptr },
612 : { "axes", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &axes_getterinfo, nullptr, nullptr },
613 : { "timestamp", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, ×tamp_getterinfo, nullptr, nullptr },
614 : { nullptr, 0, nullptr, nullptr, nullptr, nullptr },
615 : { "pose", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &pose_getterinfo, nullptr, nullptr },
616 : { "hapticActuators", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &hapticActuators_getterinfo, nullptr, nullptr },
617 : { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
618 : };
619 : #if defined(__clang__)
620 : #pragma clang diagnostic pop
621 : #endif
622 :
623 : static PrefableDisablers sAttributes_disablers4 = {
624 : true, false, 0, nullptr
625 : };
626 :
627 : static PrefableDisablers sAttributes_disablers11 = {
628 : true, false, 0, nullptr
629 : };
630 :
631 : // Can't be const because the pref-enabled boolean needs to be writable
632 : static Prefable<const JSPropertySpec> sAttributes[] = {
633 : { nullptr, &sAttributes_specs[0] },
634 : { &sAttributes_disablers4, &sAttributes_specs[4] },
635 : { nullptr, &sAttributes_specs[6] },
636 : { &sAttributes_disablers11, &sAttributes_specs[11] },
637 : { nullptr, nullptr }
638 : };
639 :
640 : static_assert(4 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
641 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
642 : static_assert(4 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
643 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
644 :
645 :
646 : static uint16_t sNativeProperties_sortedPropertyIndices[10];
647 : static PropertyInfo sNativeProperties_propertyInfos[10];
648 :
649 : static const NativePropertiesN<1> sNativeProperties = {
650 : false, 0,
651 : false, 0,
652 : false, 0,
653 : true, 0 /* sAttributes */,
654 : false, 0,
655 : false, 0,
656 : false, 0,
657 : -1,
658 : 10,
659 : sNativeProperties_sortedPropertyIndices,
660 : {
661 : { sAttributes, &sNativeProperties_propertyInfos[0] }
662 : }
663 : };
664 : static_assert(10 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
665 : "We have a property info count that is oversized");
666 :
667 : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
668 : {
669 : "Function",
670 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
671 : &sBoringInterfaceObjectClassClassOps,
672 : JS_NULL_CLASS_SPEC,
673 : JS_NULL_CLASS_EXT,
674 : &sInterfaceObjectClassObjectOps
675 : },
676 : eInterface,
677 : true,
678 : prototypes::id::Gamepad,
679 : PrototypeTraits<prototypes::id::Gamepad>::Depth,
680 : sNativePropertyHooks,
681 : "function Gamepad() {\n [native code]\n}",
682 : JS::GetRealmFunctionPrototype
683 : };
684 :
685 : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
686 : {
687 : "GamepadPrototype",
688 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
689 : JS_NULL_CLASS_OPS,
690 : JS_NULL_CLASS_SPEC,
691 : JS_NULL_CLASS_EXT,
692 : JS_NULL_OBJECT_OPS
693 : },
694 : eInterfacePrototype,
695 : false,
696 : prototypes::id::Gamepad,
697 : PrototypeTraits<prototypes::id::Gamepad>::Depth,
698 : sNativePropertyHooks,
699 : "[object GamepadPrototype]",
700 : JS::GetRealmObjectPrototype
701 : };
702 :
703 : bool
704 0 : ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
705 : {
706 : static bool sPrefValue;
707 : static bool sPrefCacheSetUp = false;
708 0 : if (!sPrefCacheSetUp) {
709 0 : sPrefCacheSetUp = true;
710 0 : Preferences::AddBoolVarCache(&sPrefValue, "dom.gamepad.enabled");
711 : }
712 :
713 0 : return sPrefValue;
714 : }
715 :
716 : JSObject*
717 0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
718 : {
719 0 : return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
720 : }
721 :
722 : static const js::ClassOps sClassOps = {
723 : _addProperty, /* addProperty */
724 : nullptr, /* delProperty */
725 : nullptr, /* getProperty */
726 : nullptr, /* setProperty */
727 : nullptr, /* enumerate */
728 : nullptr, /* newEnumerate */
729 : nullptr, /* resolve */
730 : nullptr, /* mayResolve */
731 : _finalize, /* finalize */
732 : nullptr, /* call */
733 : nullptr, /* hasInstance */
734 : nullptr, /* construct */
735 : nullptr, /* trace */
736 : };
737 :
738 : static const js::ClassExtension sClassExtension = {
739 : nullptr, /* weakmapKeyDelegateOp */
740 : _objectMoved /* objectMovedOp */
741 : };
742 :
743 : static const DOMJSClass sClass = {
744 : { "Gamepad",
745 : JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(4),
746 : &sClassOps,
747 : JS_NULL_CLASS_SPEC,
748 : &sClassExtension,
749 : JS_NULL_OBJECT_OPS
750 : },
751 : { prototypes::id::Gamepad, 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 },
752 : IsBaseOf<nsISupports, mozilla::dom::Gamepad >::value,
753 : sNativePropertyHooks,
754 : FindAssociatedGlobalForNative<mozilla::dom::Gamepad>::Get,
755 : GetProtoObjectHandle,
756 : GetCCParticipant<mozilla::dom::Gamepad>::Get()
757 : };
758 : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
759 : "Must have the right minimal number of reserved slots.");
760 : static_assert(4 >= 4,
761 : "Must have enough reserved slots.");
762 :
763 : const JSClass*
764 0 : GetJSClass()
765 : {
766 0 : return sClass.ToJSClass();
767 : }
768 :
769 : bool
770 0 : Wrap(JSContext* aCx, mozilla::dom::Gamepad* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
771 : {
772 : MOZ_ASSERT(static_cast<mozilla::dom::Gamepad*>(aObject) ==
773 : reinterpret_cast<mozilla::dom::Gamepad*>(aObject),
774 : "Multiple inheritance for mozilla::dom::Gamepad is broken.");
775 0 : MOZ_ASSERT(ToSupportsIsCorrect(aObject));
776 0 : MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
777 0 : MOZ_ASSERT(!aCache->GetWrapper(),
778 : "You should probably not be using Wrap() directly; use "
779 : "GetOrCreateDOMReflector instead");
780 :
781 0 : MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
782 : "nsISupports must be on our primary inheritance chain");
783 :
784 0 : JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
785 0 : if (!global) {
786 0 : return false;
787 : }
788 0 : MOZ_ASSERT(JS_IsGlobalObject(global));
789 0 : MOZ_ASSERT(JS::ObjectIsNotGray(global));
790 :
791 : // That might have ended up wrapping us already, due to the wonders
792 : // of XBL. Check for that, and bail out as needed.
793 0 : aReflector.set(aCache->GetWrapper());
794 0 : if (aReflector) {
795 : #ifdef DEBUG
796 0 : binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
797 : #endif // DEBUG
798 0 : return true;
799 : }
800 :
801 0 : JSAutoCompartment ac(aCx, global);
802 0 : JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
803 0 : if (!canonicalProto) {
804 0 : return false;
805 : }
806 0 : JS::Rooted<JSObject*> proto(aCx);
807 0 : if (aGivenProto) {
808 0 : proto = aGivenProto;
809 : // Unfortunately, while aGivenProto was in the compartment of aCx
810 : // coming in, we changed compartments to that of "parent" so may need
811 : // to wrap the proto here.
812 0 : if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
813 0 : if (!JS_WrapObject(aCx, &proto)) {
814 0 : return false;
815 : }
816 : }
817 : } else {
818 0 : proto = canonicalProto;
819 : }
820 :
821 0 : BindingJSObjectCreator<mozilla::dom::Gamepad> creator(aCx);
822 0 : creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
823 0 : if (!aReflector) {
824 0 : return false;
825 : }
826 :
827 0 : aCache->SetWrapper(aReflector);
828 0 : creator.InitializationSucceeded();
829 :
830 0 : MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
831 : aCache->GetWrapperPreserveColor() == aReflector);
832 : // If proto != canonicalProto, we have to preserve our wrapper;
833 : // otherwise we won't be able to properly recreate it later, since
834 : // we won't know what proto to use. Note that we don't check
835 : // aGivenProto here, since it's entirely possible (and even
836 : // somewhat common) to have a non-null aGivenProto which is the
837 : // same as canonicalProto.
838 0 : if (proto != canonicalProto) {
839 0 : PreserveWrapper(aObject);
840 : }
841 :
842 0 : return true;
843 : }
844 :
845 : // This may allocate too many slots, because we only really need
846 : // slots for our non-interface-typed members that we cache. But
847 : // allocating slots only for those would make the slot index
848 : // computations much more complicated, so let's do this the simple
849 : // way for now.
850 : DEFINE_XRAY_EXPANDO_CLASS(static, sXrayExpandoObjectClass, 3);
851 :
852 : const NativePropertyHooks sNativePropertyHooks[] = { {
853 : nullptr,
854 : nullptr,
855 : nullptr,
856 : { sNativeProperties.Upcast(), nullptr },
857 : prototypes::id::Gamepad,
858 : constructors::id::Gamepad,
859 : nullptr,
860 : &sXrayExpandoObjectClass
861 : } };
862 :
863 : void
864 0 : ClearCachedButtonsValue(mozilla::dom::Gamepad* aObject)
865 : {
866 : JSObject* obj;
867 0 : obj = aObject->GetWrapper();
868 0 : if (!obj) {
869 0 : return;
870 : }
871 0 : js::SetReservedSlot(obj, (DOM_INSTANCE_RESERVED_SLOTS + 0), JS::UndefinedValue());
872 0 : xpc::ClearXrayExpandoSlots(obj, (xpc::JSSLOT_EXPANDO_COUNT + 0));
873 : }
874 :
875 : void
876 0 : ClearCachedAxesValue(mozilla::dom::Gamepad* aObject)
877 : {
878 : JSObject* obj;
879 0 : obj = aObject->GetWrapper();
880 0 : if (!obj) {
881 0 : return;
882 : }
883 0 : js::SetReservedSlot(obj, (DOM_INSTANCE_RESERVED_SLOTS + 1), JS::UndefinedValue());
884 0 : xpc::ClearXrayExpandoSlots(obj, (xpc::JSSLOT_EXPANDO_COUNT + 1));
885 : }
886 :
887 : void
888 0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
889 : {
890 0 : JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
891 0 : if (!parentProto) {
892 0 : return;
893 : }
894 :
895 0 : JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
896 0 : if (!constructorProto) {
897 0 : return;
898 : }
899 :
900 : static bool sIdsInited = false;
901 0 : if (!sIdsInited && NS_IsMainThread()) {
902 0 : if (!InitIds(aCx, sNativeProperties.Upcast())) {
903 0 : return;
904 : }
905 0 : sIdsInited = true;
906 : }
907 :
908 : static bool sPrefCachesInited = false;
909 0 : if (!sPrefCachesInited && NS_IsMainThread()) {
910 0 : sPrefCachesInited = true;
911 0 : Preferences::AddBoolVarCache(&sAttributes[1].disablers->enabled, "dom.gamepad.extensions.enabled");
912 0 : Preferences::AddBoolVarCache(&sAttributes[3].disablers->enabled, "dom.gamepad.extensions.enabled");
913 : }
914 :
915 0 : JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::Gamepad);
916 0 : JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::Gamepad);
917 0 : dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
918 : &sPrototypeClass.mBase, protoCache,
919 : constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
920 : interfaceCache,
921 : sNativeProperties.Upcast(),
922 : nullptr,
923 : "Gamepad", aDefineOnGlobal,
924 : nullptr,
925 0 : false);
926 : }
927 :
928 : JS::Handle<JSObject*>
929 0 : GetProtoObjectHandle(JSContext* aCx)
930 : {
931 : /* Get the interface prototype object for this class. This will create the
932 : object as needed. */
933 0 : bool aDefineOnGlobal = true;
934 :
935 : /* Make sure our global is sane. Hopefully we can remove this sometime */
936 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
937 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
938 0 : return nullptr;
939 : }
940 :
941 : /* Check to see whether the interface objects are already installed */
942 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
943 0 : if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::Gamepad)) {
944 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
945 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
946 : }
947 :
948 : /*
949 : * The object might _still_ be null, but that's OK.
950 : *
951 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
952 : * traced by TraceProtoAndIfaceCache() and its contents are never
953 : * changed after they have been set.
954 : *
955 : * Calling address() avoids the read read barrier that does gray
956 : * unmarking, but it's not possible for the object to be gray here.
957 : */
958 :
959 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::Gamepad);
960 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
961 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
962 : }
963 :
964 : JS::Handle<JSObject*>
965 0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
966 : {
967 : /* Get the interface object for this class. This will create the object as
968 : needed. */
969 :
970 : /* Make sure our global is sane. Hopefully we can remove this sometime */
971 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
972 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
973 0 : return nullptr;
974 : }
975 :
976 : /* Check to see whether the interface objects are already installed */
977 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
978 0 : if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::Gamepad)) {
979 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
980 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
981 : }
982 :
983 : /*
984 : * The object might _still_ be null, but that's OK.
985 : *
986 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
987 : * traced by TraceProtoAndIfaceCache() and its contents are never
988 : * changed after they have been set.
989 : *
990 : * Calling address() avoids the read read barrier that does gray
991 : * unmarking, but it's not possible for the object to be gray here.
992 : */
993 :
994 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::Gamepad);
995 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
996 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
997 : }
998 :
999 : JSObject*
1000 0 : GetConstructorObject(JSContext* aCx)
1001 : {
1002 0 : return GetConstructorObjectHandle(aCx);
1003 : }
1004 :
1005 : } // namespace GamepadBinding
1006 :
1007 :
1008 :
1009 : namespace GamepadButtonBinding {
1010 :
1011 : static bool
1012 0 : get_pressed(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::GamepadButton* self, JSJitGetterCallArgs args)
1013 : {
1014 0 : bool result(self->Pressed());
1015 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
1016 0 : args.rval().setBoolean(result);
1017 0 : return true;
1018 : }
1019 :
1020 : static const JSJitInfo pressed_getterinfo = {
1021 : { (JSJitGetterOp)get_pressed },
1022 : { prototypes::id::GamepadButton },
1023 : { PrototypeTraits<prototypes::id::GamepadButton>::Depth },
1024 : JSJitInfo::Getter,
1025 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
1026 : JSVAL_TYPE_BOOLEAN, /* returnType. Not relevant for setters. */
1027 : true, /* isInfallible. False in setters. */
1028 : false, /* isMovable. Not relevant for setters. */
1029 : false, /* isEliminatable. Not relevant for setters. */
1030 : false, /* isAlwaysInSlot. Only relevant for getters. */
1031 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
1032 : false, /* isTypedMethod. Only relevant for methods. */
1033 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
1034 : };
1035 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1036 : static_assert(0 < 1, "There is no slot for us");
1037 :
1038 : static bool
1039 0 : get_touched(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::GamepadButton* self, JSJitGetterCallArgs args)
1040 : {
1041 0 : bool result(self->Touched());
1042 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
1043 0 : args.rval().setBoolean(result);
1044 0 : return true;
1045 : }
1046 :
1047 : static const JSJitInfo touched_getterinfo = {
1048 : { (JSJitGetterOp)get_touched },
1049 : { prototypes::id::GamepadButton },
1050 : { PrototypeTraits<prototypes::id::GamepadButton>::Depth },
1051 : JSJitInfo::Getter,
1052 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
1053 : JSVAL_TYPE_BOOLEAN, /* returnType. Not relevant for setters. */
1054 : true, /* isInfallible. False in setters. */
1055 : false, /* isMovable. Not relevant for setters. */
1056 : false, /* isEliminatable. Not relevant for setters. */
1057 : false, /* isAlwaysInSlot. Only relevant for getters. */
1058 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
1059 : false, /* isTypedMethod. Only relevant for methods. */
1060 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
1061 : };
1062 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1063 : static_assert(0 < 1, "There is no slot for us");
1064 :
1065 : static bool
1066 0 : get_value(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::GamepadButton* self, JSJitGetterCallArgs args)
1067 : {
1068 0 : double result(self->Value());
1069 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
1070 0 : args.rval().set(JS_NumberValue(double(result)));
1071 0 : return true;
1072 : }
1073 :
1074 : static const JSJitInfo value_getterinfo = {
1075 : { (JSJitGetterOp)get_value },
1076 : { prototypes::id::GamepadButton },
1077 : { PrototypeTraits<prototypes::id::GamepadButton>::Depth },
1078 : JSJitInfo::Getter,
1079 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
1080 : JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
1081 : true, /* isInfallible. False in setters. */
1082 : false, /* isMovable. Not relevant for setters. */
1083 : false, /* isEliminatable. Not relevant for setters. */
1084 : false, /* isAlwaysInSlot. Only relevant for getters. */
1085 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
1086 : false, /* isTypedMethod. Only relevant for methods. */
1087 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
1088 : };
1089 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1090 : static_assert(0 < 1, "There is no slot for us");
1091 :
1092 : static bool
1093 0 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
1094 : {
1095 0 : mozilla::dom::GamepadButton* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::GamepadButton>(obj);
1096 : // We don't want to preserve if we don't have a wrapper, and we
1097 : // obviously can't preserve if we're not initialized.
1098 0 : if (self && self->GetWrapperPreserveColor()) {
1099 0 : PreserveWrapper(self);
1100 : }
1101 0 : return true;
1102 : }
1103 :
1104 : static void
1105 0 : _finalize(js::FreeOp* fop, JSObject* obj)
1106 : {
1107 0 : mozilla::dom::GamepadButton* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::GamepadButton>(obj);
1108 0 : if (self) {
1109 0 : ClearWrapper(self, self, obj);
1110 0 : AddForDeferredFinalization<mozilla::dom::GamepadButton>(self);
1111 : }
1112 0 : }
1113 :
1114 : static void
1115 0 : _objectMoved(JSObject* obj, const JSObject* old)
1116 : {
1117 0 : mozilla::dom::GamepadButton* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::GamepadButton>(obj);
1118 0 : if (self) {
1119 0 : UpdateWrapper(self, self, obj, old);
1120 : }
1121 0 : }
1122 :
1123 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
1124 : #if defined(__clang__)
1125 : #pragma clang diagnostic push
1126 : #pragma clang diagnostic ignored "-Wmissing-braces"
1127 : #endif
1128 : static const JSPropertySpec sAttributes_specs[] = {
1129 : { "pressed", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &pressed_getterinfo, nullptr, nullptr },
1130 : { "touched", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &touched_getterinfo, nullptr, nullptr },
1131 : { "value", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &value_getterinfo, nullptr, nullptr },
1132 : { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
1133 : };
1134 : #if defined(__clang__)
1135 : #pragma clang diagnostic pop
1136 : #endif
1137 :
1138 :
1139 : // Can't be const because the pref-enabled boolean needs to be writable
1140 : static Prefable<const JSPropertySpec> sAttributes[] = {
1141 : { nullptr, &sAttributes_specs[0] },
1142 : { nullptr, nullptr }
1143 : };
1144 :
1145 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
1146 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
1147 : static_assert(3 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
1148 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
1149 :
1150 :
1151 : static uint16_t sNativeProperties_sortedPropertyIndices[3];
1152 : static PropertyInfo sNativeProperties_propertyInfos[3];
1153 :
1154 : static const NativePropertiesN<1> sNativeProperties = {
1155 : false, 0,
1156 : false, 0,
1157 : false, 0,
1158 : true, 0 /* sAttributes */,
1159 : false, 0,
1160 : false, 0,
1161 : false, 0,
1162 : -1,
1163 : 3,
1164 : sNativeProperties_sortedPropertyIndices,
1165 : {
1166 : { sAttributes, &sNativeProperties_propertyInfos[0] }
1167 : }
1168 : };
1169 : static_assert(3 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
1170 : "We have a property info count that is oversized");
1171 :
1172 : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
1173 : {
1174 : "Function",
1175 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
1176 : &sBoringInterfaceObjectClassClassOps,
1177 : JS_NULL_CLASS_SPEC,
1178 : JS_NULL_CLASS_EXT,
1179 : &sInterfaceObjectClassObjectOps
1180 : },
1181 : eInterface,
1182 : true,
1183 : prototypes::id::GamepadButton,
1184 : PrototypeTraits<prototypes::id::GamepadButton>::Depth,
1185 : sNativePropertyHooks,
1186 : "function GamepadButton() {\n [native code]\n}",
1187 : JS::GetRealmFunctionPrototype
1188 : };
1189 :
1190 : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
1191 : {
1192 : "GamepadButtonPrototype",
1193 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
1194 : JS_NULL_CLASS_OPS,
1195 : JS_NULL_CLASS_SPEC,
1196 : JS_NULL_CLASS_EXT,
1197 : JS_NULL_OBJECT_OPS
1198 : },
1199 : eInterfacePrototype,
1200 : false,
1201 : prototypes::id::GamepadButton,
1202 : PrototypeTraits<prototypes::id::GamepadButton>::Depth,
1203 : sNativePropertyHooks,
1204 : "[object GamepadButtonPrototype]",
1205 : JS::GetRealmObjectPrototype
1206 : };
1207 :
1208 : bool
1209 0 : ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
1210 : {
1211 : static bool sPrefValue;
1212 : static bool sPrefCacheSetUp = false;
1213 0 : if (!sPrefCacheSetUp) {
1214 0 : sPrefCacheSetUp = true;
1215 0 : Preferences::AddBoolVarCache(&sPrefValue, "dom.gamepad.enabled");
1216 : }
1217 :
1218 0 : return sPrefValue;
1219 : }
1220 :
1221 : JSObject*
1222 0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
1223 : {
1224 0 : return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
1225 : }
1226 :
1227 : static const js::ClassOps sClassOps = {
1228 : _addProperty, /* addProperty */
1229 : nullptr, /* delProperty */
1230 : nullptr, /* getProperty */
1231 : nullptr, /* setProperty */
1232 : nullptr, /* enumerate */
1233 : nullptr, /* newEnumerate */
1234 : nullptr, /* resolve */
1235 : nullptr, /* mayResolve */
1236 : _finalize, /* finalize */
1237 : nullptr, /* call */
1238 : nullptr, /* hasInstance */
1239 : nullptr, /* construct */
1240 : nullptr, /* trace */
1241 : };
1242 :
1243 : static const js::ClassExtension sClassExtension = {
1244 : nullptr, /* weakmapKeyDelegateOp */
1245 : _objectMoved /* objectMovedOp */
1246 : };
1247 :
1248 : static const DOMJSClass sClass = {
1249 : { "GamepadButton",
1250 : JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
1251 : &sClassOps,
1252 : JS_NULL_CLASS_SPEC,
1253 : &sClassExtension,
1254 : JS_NULL_OBJECT_OPS
1255 : },
1256 : { prototypes::id::GamepadButton, 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 },
1257 : IsBaseOf<nsISupports, mozilla::dom::GamepadButton >::value,
1258 : sNativePropertyHooks,
1259 : FindAssociatedGlobalForNative<mozilla::dom::GamepadButton>::Get,
1260 : GetProtoObjectHandle,
1261 : GetCCParticipant<mozilla::dom::GamepadButton>::Get()
1262 : };
1263 : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
1264 : "Must have the right minimal number of reserved slots.");
1265 : static_assert(1 >= 1,
1266 : "Must have enough reserved slots.");
1267 :
1268 : const JSClass*
1269 0 : GetJSClass()
1270 : {
1271 0 : return sClass.ToJSClass();
1272 : }
1273 :
1274 : bool
1275 0 : Wrap(JSContext* aCx, mozilla::dom::GamepadButton* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
1276 : {
1277 : MOZ_ASSERT(static_cast<mozilla::dom::GamepadButton*>(aObject) ==
1278 : reinterpret_cast<mozilla::dom::GamepadButton*>(aObject),
1279 : "Multiple inheritance for mozilla::dom::GamepadButton is broken.");
1280 0 : MOZ_ASSERT(ToSupportsIsCorrect(aObject));
1281 0 : MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
1282 0 : MOZ_ASSERT(!aCache->GetWrapper(),
1283 : "You should probably not be using Wrap() directly; use "
1284 : "GetOrCreateDOMReflector instead");
1285 :
1286 0 : MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
1287 : "nsISupports must be on our primary inheritance chain");
1288 :
1289 0 : JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
1290 0 : if (!global) {
1291 0 : return false;
1292 : }
1293 0 : MOZ_ASSERT(JS_IsGlobalObject(global));
1294 0 : MOZ_ASSERT(JS::ObjectIsNotGray(global));
1295 :
1296 : // That might have ended up wrapping us already, due to the wonders
1297 : // of XBL. Check for that, and bail out as needed.
1298 0 : aReflector.set(aCache->GetWrapper());
1299 0 : if (aReflector) {
1300 : #ifdef DEBUG
1301 0 : binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
1302 : #endif // DEBUG
1303 0 : return true;
1304 : }
1305 :
1306 0 : JSAutoCompartment ac(aCx, global);
1307 0 : JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
1308 0 : if (!canonicalProto) {
1309 0 : return false;
1310 : }
1311 0 : JS::Rooted<JSObject*> proto(aCx);
1312 0 : if (aGivenProto) {
1313 0 : proto = aGivenProto;
1314 : // Unfortunately, while aGivenProto was in the compartment of aCx
1315 : // coming in, we changed compartments to that of "parent" so may need
1316 : // to wrap the proto here.
1317 0 : if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
1318 0 : if (!JS_WrapObject(aCx, &proto)) {
1319 0 : return false;
1320 : }
1321 : }
1322 : } else {
1323 0 : proto = canonicalProto;
1324 : }
1325 :
1326 0 : BindingJSObjectCreator<mozilla::dom::GamepadButton> creator(aCx);
1327 0 : creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
1328 0 : if (!aReflector) {
1329 0 : return false;
1330 : }
1331 :
1332 0 : aCache->SetWrapper(aReflector);
1333 0 : creator.InitializationSucceeded();
1334 :
1335 0 : MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
1336 : aCache->GetWrapperPreserveColor() == aReflector);
1337 : // If proto != canonicalProto, we have to preserve our wrapper;
1338 : // otherwise we won't be able to properly recreate it later, since
1339 : // we won't know what proto to use. Note that we don't check
1340 : // aGivenProto here, since it's entirely possible (and even
1341 : // somewhat common) to have a non-null aGivenProto which is the
1342 : // same as canonicalProto.
1343 0 : if (proto != canonicalProto) {
1344 0 : PreserveWrapper(aObject);
1345 : }
1346 :
1347 0 : return true;
1348 : }
1349 :
1350 : const NativePropertyHooks sNativePropertyHooks[] = { {
1351 : nullptr,
1352 : nullptr,
1353 : nullptr,
1354 : { sNativeProperties.Upcast(), nullptr },
1355 : prototypes::id::GamepadButton,
1356 : constructors::id::GamepadButton,
1357 : nullptr,
1358 : &DefaultXrayExpandoObjectClass
1359 : } };
1360 :
1361 : void
1362 0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
1363 : {
1364 0 : JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
1365 0 : if (!parentProto) {
1366 0 : return;
1367 : }
1368 :
1369 0 : JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
1370 0 : if (!constructorProto) {
1371 0 : return;
1372 : }
1373 :
1374 : static bool sIdsInited = false;
1375 0 : if (!sIdsInited && NS_IsMainThread()) {
1376 0 : if (!InitIds(aCx, sNativeProperties.Upcast())) {
1377 0 : return;
1378 : }
1379 0 : sIdsInited = true;
1380 : }
1381 :
1382 0 : JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::GamepadButton);
1383 0 : JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::GamepadButton);
1384 0 : dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
1385 : &sPrototypeClass.mBase, protoCache,
1386 : constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
1387 : interfaceCache,
1388 : sNativeProperties.Upcast(),
1389 : nullptr,
1390 : "GamepadButton", aDefineOnGlobal,
1391 : nullptr,
1392 0 : false);
1393 : }
1394 :
1395 : JS::Handle<JSObject*>
1396 0 : GetProtoObjectHandle(JSContext* aCx)
1397 : {
1398 : /* Get the interface prototype object for this class. This will create the
1399 : object as needed. */
1400 0 : bool aDefineOnGlobal = true;
1401 :
1402 : /* Make sure our global is sane. Hopefully we can remove this sometime */
1403 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
1404 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
1405 0 : return nullptr;
1406 : }
1407 :
1408 : /* Check to see whether the interface objects are already installed */
1409 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
1410 0 : if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::GamepadButton)) {
1411 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
1412 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
1413 : }
1414 :
1415 : /*
1416 : * The object might _still_ be null, but that's OK.
1417 : *
1418 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
1419 : * traced by TraceProtoAndIfaceCache() and its contents are never
1420 : * changed after they have been set.
1421 : *
1422 : * Calling address() avoids the read read barrier that does gray
1423 : * unmarking, but it's not possible for the object to be gray here.
1424 : */
1425 :
1426 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::GamepadButton);
1427 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
1428 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
1429 : }
1430 :
1431 : JS::Handle<JSObject*>
1432 0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
1433 : {
1434 : /* Get the interface object for this class. This will create the object as
1435 : needed. */
1436 :
1437 : /* Make sure our global is sane. Hopefully we can remove this sometime */
1438 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
1439 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
1440 0 : return nullptr;
1441 : }
1442 :
1443 : /* Check to see whether the interface objects are already installed */
1444 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
1445 0 : if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::GamepadButton)) {
1446 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
1447 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
1448 : }
1449 :
1450 : /*
1451 : * The object might _still_ be null, but that's OK.
1452 : *
1453 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
1454 : * traced by TraceProtoAndIfaceCache() and its contents are never
1455 : * changed after they have been set.
1456 : *
1457 : * Calling address() avoids the read read barrier that does gray
1458 : * unmarking, but it's not possible for the object to be gray here.
1459 : */
1460 :
1461 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::GamepadButton);
1462 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
1463 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
1464 : }
1465 :
1466 : JSObject*
1467 0 : GetConstructorObject(JSContext* aCx)
1468 : {
1469 0 : return GetConstructorObjectHandle(aCx);
1470 : }
1471 :
1472 : } // namespace GamepadButtonBinding
1473 :
1474 :
1475 :
1476 : } // namespace dom
1477 : } // namespace mozilla
|