Line data Source code
1 : /* THIS FILE IS AUTOGENERATED FROM CustomEvent.webidl BY Codegen.py - DO NOT EDIT */
2 :
3 : #include "AtomList.h"
4 : #include "CustomEventBinding.h"
5 : #include "EventBinding.h"
6 : #include "WrapperFactory.h"
7 : #include "mozilla/OwningNonNull.h"
8 : #include "mozilla/dom/BindingUtils.h"
9 : #include "mozilla/dom/CustomEvent.h"
10 : #include "mozilla/dom/DOMJSClass.h"
11 : #include "mozilla/dom/NonRefcountedDOMObject.h"
12 : #include "mozilla/dom/PrimitiveConversions.h"
13 : #include "mozilla/dom/ScriptSettings.h"
14 : #include "mozilla/dom/XrayExpandoClass.h"
15 :
16 : namespace mozilla {
17 : namespace dom {
18 :
19 :
20 0 : CustomEventInit::CustomEventInit()
21 0 : : EventInit(FastDictionaryInitializer()),
22 0 : mDetail(JS::UndefinedValue())
23 : {
24 : // Safe to pass a null context if we pass a null value
25 0 : Init(nullptr, JS::NullHandleValue);
26 0 : }
27 :
28 :
29 : bool
30 2 : CustomEventInit::InitIds(JSContext* cx, CustomEventInitAtoms* atomsCache)
31 : {
32 2 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
33 :
34 : // Initialize these in reverse order so that any failure leaves the first one
35 : // uninitialized.
36 2 : if (!atomsCache->detail_id.init(cx, "detail")) {
37 0 : return false;
38 : }
39 2 : return true;
40 : }
41 :
42 : bool
43 9 : CustomEventInit::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
44 : {
45 : // Passing a null JSContext is OK only if we're initing from null,
46 : // Since in that case we will not have to do any property gets
47 : // Also evaluate isNullOrUndefined in order to avoid false-positive
48 : // checkers by static analysis tools
49 9 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
50 9 : CustomEventInitAtoms* atomsCache = nullptr;
51 9 : if (cx) {
52 9 : atomsCache = GetAtomCache<CustomEventInitAtoms>(cx);
53 9 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
54 0 : return false;
55 : }
56 : }
57 :
58 : // Per spec, we init the parent's members first
59 9 : if (!EventInit::Init(cx, val)) {
60 0 : return false;
61 : }
62 :
63 9 : bool isNull = val.isNullOrUndefined();
64 : // We only need these if !isNull, in which case we have |cx|.
65 18 : Maybe<JS::Rooted<JSObject *> > object;
66 18 : Maybe<JS::Rooted<JS::Value> > temp;
67 9 : if (!isNull) {
68 7 : MOZ_ASSERT(cx);
69 7 : object.emplace(cx, &val.toObject());
70 7 : temp.emplace(cx);
71 : }
72 9 : if (!isNull) {
73 7 : if (!JS_GetPropertyById(cx, *object, atomsCache->detail_id, temp.ptr())) {
74 0 : return false;
75 : }
76 : }
77 9 : if (!isNull && !temp->isUndefined()) {
78 : #ifdef __clang__
79 : #pragma clang diagnostic push
80 : #pragma clang diagnostic ignored "-Wunreachable-code"
81 : #pragma clang diagnostic ignored "-Wunreachable-code-return"
82 : #endif // __clang__
83 6 : if ((passedToJSImpl) && !CallerSubsumes(temp.ref())) {
84 0 : ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "'detail' member of CustomEventInit");
85 0 : return false;
86 : }
87 : #ifdef __clang__
88 : #pragma clang diagnostic pop
89 : #endif // __clang__
90 6 : mDetail = temp.ref();
91 : } else {
92 3 : mDetail = JS::NullValue();
93 : }
94 9 : mIsAnyMemberPresent = true;
95 9 : return true;
96 : }
97 :
98 : bool
99 0 : CustomEventInit::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
100 : {
101 0 : CustomEventInitAtoms* atomsCache = GetAtomCache<CustomEventInitAtoms>(cx);
102 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
103 0 : return false;
104 : }
105 :
106 : // Per spec, we define the parent's members first
107 0 : if (!EventInit::ToObjectInternal(cx, rval)) {
108 0 : return false;
109 : }
110 0 : JS::Rooted<JSObject*> obj(cx, &rval.toObject());
111 :
112 : do {
113 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
114 0 : JS::Rooted<JS::Value> temp(cx);
115 0 : JS::Value const & currentValue = mDetail;
116 0 : JS::ExposeValueToActiveJS(currentValue);
117 0 : temp.set(currentValue);
118 0 : if (!MaybeWrapValue(cx, &temp)) {
119 0 : return false;
120 : }
121 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->detail_id, temp, JSPROP_ENUMERATE)) {
122 0 : return false;
123 : }
124 0 : break;
125 : } while(0);
126 :
127 0 : return true;
128 : }
129 :
130 : void
131 0 : CustomEventInit::TraceDictionary(JSTracer* trc)
132 : {
133 0 : EventInit::TraceDictionary(trc);
134 0 : JS::UnsafeTraceRoot(trc, &mDetail, "CustomEventInit.mDetail");
135 0 : }
136 :
137 : namespace binding_detail {
138 : } // namespace binding_detail
139 :
140 :
141 : namespace CustomEventBinding {
142 :
143 : static_assert(IsRefcounted<NativeType>::value == IsRefcounted<EventBinding::NativeType>::value,
144 : "Can't inherit from an interface with a different ownership model.");
145 :
146 : static bool
147 2 : get_detail(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::CustomEvent* self, JSJitGetterCallArgs args)
148 : {
149 4 : JS::Rooted<JS::Value> result(cx);
150 2 : self->GetDetail(cx, &result);
151 2 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
152 2 : JS::ExposeValueToActiveJS(result);
153 2 : args.rval().set(result);
154 2 : if (!MaybeWrapValue(cx, args.rval())) {
155 0 : return false;
156 : }
157 2 : return true;
158 : }
159 :
160 : static const JSJitInfo detail_getterinfo = {
161 : { (JSJitGetterOp)get_detail },
162 : { prototypes::id::CustomEvent },
163 : { PrototypeTraits<prototypes::id::CustomEvent>::Depth },
164 : JSJitInfo::Getter,
165 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
166 : JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */
167 : false, /* isInfallible. False in setters. */
168 : false, /* isMovable. Not relevant for setters. */
169 : false, /* isEliminatable. Not relevant for setters. */
170 : false, /* isAlwaysInSlot. Only relevant for getters. */
171 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
172 : false, /* isTypedMethod. Only relevant for methods. */
173 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
174 : };
175 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
176 : static_assert(0 < 1, "There is no slot for us");
177 :
178 : static bool
179 0 : initCustomEvent(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::CustomEvent* self, const JSJitMethodCallArgs& args)
180 : {
181 0 : if (MOZ_UNLIKELY(args.length() < 1)) {
182 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "CustomEvent.initCustomEvent");
183 : }
184 0 : binding_detail::FakeString arg0;
185 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
186 0 : return false;
187 : }
188 : bool arg1;
189 0 : if (args.hasDefined(1)) {
190 0 : if (!ValueToPrimitive<bool, eDefault>(cx, args[1], &arg1)) {
191 0 : return false;
192 : }
193 : } else {
194 0 : arg1 = false;
195 : }
196 : bool arg2;
197 0 : if (args.hasDefined(2)) {
198 0 : if (!ValueToPrimitive<bool, eDefault>(cx, args[2], &arg2)) {
199 0 : return false;
200 : }
201 : } else {
202 0 : arg2 = false;
203 : }
204 0 : JS::Rooted<JS::Value> arg3(cx);
205 0 : if (args.hasDefined(3)) {
206 0 : arg3 = args[3];
207 : } else {
208 0 : arg3 = JS::NullValue();
209 : }
210 0 : binding_detail::FastErrorResult rv;
211 0 : self->InitCustomEvent(cx, NonNullHelper(Constify(arg0)), arg1, arg2, arg3, rv);
212 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
213 0 : return false;
214 : }
215 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
216 0 : args.rval().setUndefined();
217 0 : return true;
218 : }
219 :
220 : static const JSJitInfo initCustomEvent_methodinfo = {
221 : { (JSJitGetterOp)initCustomEvent },
222 : { prototypes::id::CustomEvent },
223 : { PrototypeTraits<prototypes::id::CustomEvent>::Depth },
224 : JSJitInfo::Method,
225 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
226 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
227 : false, /* isInfallible. False in setters. */
228 : false, /* isMovable. Not relevant for setters. */
229 : false, /* isEliminatable. Not relevant for setters. */
230 : false, /* isAlwaysInSlot. Only relevant for getters. */
231 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
232 : false, /* isTypedMethod. Only relevant for methods. */
233 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
234 : };
235 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
236 : static_assert(0 < 1, "There is no slot for us");
237 :
238 : static bool
239 0 : get_isTrusted(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::CustomEvent* self, JSJitGetterCallArgs args)
240 : {
241 0 : bool result(self->IsTrusted());
242 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
243 0 : args.rval().setBoolean(result);
244 0 : return true;
245 : }
246 :
247 : static const JSJitInfo isTrusted_getterinfo = {
248 : { (JSJitGetterOp)get_isTrusted },
249 : { prototypes::id::CustomEvent },
250 : { PrototypeTraits<prototypes::id::CustomEvent>::Depth },
251 : JSJitInfo::Getter,
252 : JSJitInfo::AliasDOMSets, /* aliasSet. Not relevant for setters. */
253 : JSVAL_TYPE_BOOLEAN, /* returnType. Not relevant for setters. */
254 : true, /* isInfallible. False in setters. */
255 : true, /* isMovable. Not relevant for setters. */
256 : true, /* isEliminatable. Not relevant for setters. */
257 : false, /* isAlwaysInSlot. Only relevant for getters. */
258 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
259 : false, /* isTypedMethod. Only relevant for methods. */
260 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
261 : };
262 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
263 : static_assert(0 < 1, "There is no slot for us");
264 :
265 : static bool
266 3 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
267 : {
268 3 : mozilla::dom::CustomEvent* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::CustomEvent>(obj);
269 : // We don't want to preserve if we don't have a wrapper, and we
270 : // obviously can't preserve if we're not initialized.
271 3 : if (self && self->GetWrapperPreserveColor()) {
272 0 : PreserveWrapper(self);
273 : }
274 3 : return true;
275 : }
276 :
277 : static void
278 6 : _finalize(js::FreeOp* fop, JSObject* obj)
279 : {
280 6 : mozilla::dom::CustomEvent* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::CustomEvent>(obj);
281 6 : if (self) {
282 6 : ClearWrapper(self, self, obj);
283 6 : AddForDeferredFinalization<mozilla::dom::CustomEvent>(self);
284 : }
285 6 : }
286 :
287 : static void
288 1 : _objectMoved(JSObject* obj, const JSObject* old)
289 : {
290 1 : mozilla::dom::CustomEvent* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::CustomEvent>(obj);
291 1 : if (self) {
292 0 : UpdateWrapper(self, self, obj, old);
293 : }
294 1 : }
295 :
296 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
297 : #if defined(__clang__)
298 : #pragma clang diagnostic push
299 : #pragma clang diagnostic ignored "-Wmissing-braces"
300 : #endif
301 : static const JSFunctionSpec sMethods_specs[] = {
302 : JS_FNSPEC("initCustomEvent", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&initCustomEvent_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
303 : JS_FS_END
304 : };
305 : #if defined(__clang__)
306 : #pragma clang diagnostic pop
307 : #endif
308 :
309 :
310 : // Can't be const because the pref-enabled boolean needs to be writable
311 : static Prefable<const JSFunctionSpec> sMethods[] = {
312 : { nullptr, &sMethods_specs[0] },
313 : { nullptr, nullptr }
314 : };
315 :
316 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
317 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
318 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
319 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
320 :
321 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
322 : #if defined(__clang__)
323 : #pragma clang diagnostic push
324 : #pragma clang diagnostic ignored "-Wmissing-braces"
325 : #endif
326 : static const JSPropertySpec sAttributes_specs[] = {
327 : { "detail", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &detail_getterinfo, nullptr, nullptr },
328 : { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
329 : };
330 : #if defined(__clang__)
331 : #pragma clang diagnostic pop
332 : #endif
333 :
334 :
335 : // Can't be const because the pref-enabled boolean needs to be writable
336 : static Prefable<const JSPropertySpec> sAttributes[] = {
337 : { nullptr, &sAttributes_specs[0] },
338 : { nullptr, nullptr }
339 : };
340 :
341 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
342 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
343 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
344 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
345 :
346 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
347 : #if defined(__clang__)
348 : #pragma clang diagnostic push
349 : #pragma clang diagnostic ignored "-Wmissing-braces"
350 : #endif
351 : static const JSPropertySpec sUnforgeableAttributes_specs[] = {
352 : { "isTrusted", JSPROP_SHARED | JSPROP_ENUMERATE | JSPROP_PERMANENT, GenericBindingGetter, &isTrusted_getterinfo, nullptr, nullptr },
353 : { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
354 : };
355 : #if defined(__clang__)
356 : #pragma clang diagnostic pop
357 : #endif
358 :
359 :
360 : // Can't be const because the pref-enabled boolean needs to be writable
361 : static Prefable<const JSPropertySpec> sUnforgeableAttributes[] = {
362 : { nullptr, &sUnforgeableAttributes_specs[0] },
363 : { nullptr, nullptr }
364 : };
365 :
366 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
367 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
368 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
369 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
370 :
371 :
372 : static uint16_t sNativeProperties_sortedPropertyIndices[3];
373 : static PropertyInfo sNativeProperties_propertyInfos[3];
374 :
375 : static const NativePropertiesN<3> sNativeProperties = {
376 : false, 0,
377 : false, 0,
378 : true, 0 /* sMethods */,
379 : true, 1 /* sAttributes */,
380 : false, 0,
381 : true, 2 /* sUnforgeableAttributes */,
382 : false, 0,
383 : -1,
384 : 3,
385 : sNativeProperties_sortedPropertyIndices,
386 : {
387 : { sMethods, &sNativeProperties_propertyInfos[0] },
388 : { sAttributes, &sNativeProperties_propertyInfos[1] },
389 : { sUnforgeableAttributes, &sNativeProperties_propertyInfos[2] }
390 : }
391 : };
392 : static_assert(3 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
393 : "We have a property info count that is oversized");
394 :
395 : static bool
396 9 : _constructor(JSContext* cx, unsigned argc, JS::Value* vp)
397 : {
398 9 : JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
399 18 : JS::Rooted<JSObject*> obj(cx, &args.callee());
400 9 : if (!args.isConstructing()) {
401 : // XXXbz wish I could get the name from the callee instead of
402 : // Adding more relocations
403 0 : return ThrowConstructorWithoutNew(cx, "CustomEvent");
404 : }
405 :
406 18 : GlobalObject global(cx, obj);
407 9 : if (global.Failed()) {
408 0 : return false;
409 : }
410 :
411 18 : JS::Rooted<JSObject*> desiredProto(cx);
412 9 : if (!GetDesiredProto(cx, args, &desiredProto)) {
413 0 : return false;
414 : }
415 :
416 9 : if (MOZ_UNLIKELY(args.length() < 1)) {
417 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "CustomEvent");
418 : }
419 9 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
420 18 : binding_detail::FakeString arg0;
421 9 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
422 0 : return false;
423 : }
424 18 : RootedDictionary<binding_detail::FastCustomEventInit> arg1(cx);
425 9 : if (!arg1.Init(cx, (args.hasDefined(1)) ? args[1] : JS::NullHandleValue, "Argument 2 of CustomEvent.constructor", false)) {
426 0 : return false;
427 : }
428 18 : Maybe<JSAutoCompartment> ac;
429 9 : if (objIsXray) {
430 1 : obj = js::CheckedUnwrap(obj);
431 1 : if (!obj) {
432 0 : return false;
433 : }
434 1 : ac.emplace(cx, obj);
435 1 : if (!JS_WrapObject(cx, &desiredProto)) {
436 0 : return false;
437 : }
438 1 : if (!JS_WrapValue(cx, JS::MutableHandle<JS::Value>::fromMarkedLocation(&arg1.mDetail))) {
439 0 : return false;
440 : }
441 : }
442 18 : binding_detail::FastErrorResult rv;
443 18 : auto result(StrongOrRawPtr<mozilla::dom::CustomEvent>(mozilla::dom::CustomEvent::Constructor(global, NonNullHelper(Constify(arg0)), Constify(arg1), rv)));
444 9 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
445 0 : return false;
446 : }
447 9 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
448 : static_assert(!IsPointer<decltype(result)>::value,
449 : "NewObject implies that we need to keep the object alive with a strong reference.");
450 9 : if (!GetOrCreateDOMReflector(cx, result, args.rval(), desiredProto)) {
451 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
452 0 : return false;
453 : }
454 9 : return true;
455 : }
456 :
457 : static const js::ClassOps sInterfaceObjectClassOps = {
458 : nullptr, /* addProperty */
459 : nullptr, /* delProperty */
460 : nullptr, /* getProperty */
461 : nullptr, /* setProperty */
462 : nullptr, /* enumerate */
463 : nullptr, /* newEnumerate */
464 : nullptr, /* resolve */
465 : nullptr, /* mayResolve */
466 : nullptr, /* finalize */
467 : _constructor, /* call */
468 : nullptr, /* hasInstance */
469 : _constructor, /* construct */
470 : nullptr, /* trace */
471 : };
472 :
473 : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
474 : {
475 : "Function",
476 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
477 : &sInterfaceObjectClassOps,
478 : JS_NULL_CLASS_SPEC,
479 : JS_NULL_CLASS_EXT,
480 : &sInterfaceObjectClassObjectOps
481 : },
482 : eInterface,
483 : true,
484 : prototypes::id::CustomEvent,
485 : PrototypeTraits<prototypes::id::CustomEvent>::Depth,
486 : sNativePropertyHooks,
487 : "function CustomEvent() {\n [native code]\n}",
488 : EventBinding::GetConstructorObject
489 : };
490 :
491 : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
492 : {
493 : "CustomEventPrototype",
494 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE + 1 /* slot for the JSObject holding the unforgeable properties */),
495 : JS_NULL_CLASS_OPS,
496 : JS_NULL_CLASS_SPEC,
497 : JS_NULL_CLASS_EXT,
498 : JS_NULL_OBJECT_OPS
499 : },
500 : eInterfacePrototype,
501 : false,
502 : prototypes::id::CustomEvent,
503 : PrototypeTraits<prototypes::id::CustomEvent>::Depth,
504 : sNativePropertyHooks,
505 : "[object CustomEventPrototype]",
506 : EventBinding::GetProtoObject
507 : };
508 :
509 : JSObject*
510 6 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
511 : {
512 6 : return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
513 : }
514 :
515 : static const js::ClassOps sClassOps = {
516 : _addProperty, /* addProperty */
517 : nullptr, /* delProperty */
518 : nullptr, /* getProperty */
519 : nullptr, /* setProperty */
520 : nullptr, /* enumerate */
521 : nullptr, /* newEnumerate */
522 : nullptr, /* resolve */
523 : nullptr, /* mayResolve */
524 : _finalize, /* finalize */
525 : nullptr, /* call */
526 : nullptr, /* hasInstance */
527 : nullptr, /* construct */
528 : nullptr, /* trace */
529 : };
530 :
531 : static const js::ClassExtension sClassExtension = {
532 : nullptr, /* weakmapKeyDelegateOp */
533 : _objectMoved /* objectMovedOp */
534 : };
535 :
536 : static const DOMJSClass sClass = {
537 : { "CustomEvent",
538 : JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_SKIP_NURSERY_FINALIZE,
539 : &sClassOps,
540 : JS_NULL_CLASS_SPEC,
541 : &sClassExtension,
542 : JS_NULL_OBJECT_OPS
543 : },
544 : { prototypes::id::Event, prototypes::id::CustomEvent, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
545 : IsBaseOf<nsISupports, mozilla::dom::CustomEvent >::value,
546 : sNativePropertyHooks,
547 : FindAssociatedGlobalForNative<mozilla::dom::CustomEvent>::Get,
548 : GetProtoObjectHandle,
549 : GetCCParticipant<mozilla::dom::CustomEvent>::Get()
550 : };
551 : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
552 : "Must have the right minimal number of reserved slots.");
553 : static_assert(1 >= 1,
554 : "Must have enough reserved slots.");
555 :
556 : const JSClass*
557 0 : GetJSClass()
558 : {
559 0 : return sClass.ToJSClass();
560 : }
561 :
562 : bool
563 9 : Wrap(JSContext* aCx, mozilla::dom::CustomEvent* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
564 : {
565 : MOZ_ASSERT(static_cast<mozilla::dom::CustomEvent*>(aObject) ==
566 : reinterpret_cast<mozilla::dom::CustomEvent*>(aObject),
567 : "Multiple inheritance for mozilla::dom::CustomEvent is broken.");
568 : MOZ_ASSERT(static_cast<mozilla::dom::Event*>(aObject) ==
569 : reinterpret_cast<mozilla::dom::Event*>(aObject),
570 : "Multiple inheritance for mozilla::dom::Event is broken.");
571 9 : MOZ_ASSERT(ToSupportsIsCorrect(aObject));
572 9 : MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
573 9 : MOZ_ASSERT(!aCache->GetWrapper(),
574 : "You should probably not be using Wrap() directly; use "
575 : "GetOrCreateDOMReflector instead");
576 :
577 9 : MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
578 : "nsISupports must be on our primary inheritance chain");
579 :
580 18 : JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
581 9 : if (!global) {
582 0 : return false;
583 : }
584 9 : MOZ_ASSERT(JS_IsGlobalObject(global));
585 9 : MOZ_ASSERT(JS::ObjectIsNotGray(global));
586 :
587 : // That might have ended up wrapping us already, due to the wonders
588 : // of XBL. Check for that, and bail out as needed.
589 9 : aReflector.set(aCache->GetWrapper());
590 9 : if (aReflector) {
591 : #ifdef DEBUG
592 0 : binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
593 : #endif // DEBUG
594 0 : return true;
595 : }
596 :
597 18 : JSAutoCompartment ac(aCx, global);
598 9 : JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
599 9 : if (!canonicalProto) {
600 0 : return false;
601 : }
602 18 : JS::Rooted<JSObject*> proto(aCx);
603 9 : if (aGivenProto) {
604 9 : proto = aGivenProto;
605 : // Unfortunately, while aGivenProto was in the compartment of aCx
606 : // coming in, we changed compartments to that of "parent" so may need
607 : // to wrap the proto here.
608 9 : if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
609 0 : if (!JS_WrapObject(aCx, &proto)) {
610 0 : return false;
611 : }
612 : }
613 : } else {
614 0 : proto = canonicalProto;
615 : }
616 :
617 18 : BindingJSObjectCreator<mozilla::dom::CustomEvent> creator(aCx);
618 9 : creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
619 9 : if (!aReflector) {
620 0 : return false;
621 : }
622 :
623 9 : aCache->SetWrapper(aReflector);
624 :
625 : // Important: do unforgeable property setup after we have handed
626 : // over ownership of the C++ object to obj as needed, so that if
627 : // we fail and it ends up GCed it won't have problems in the
628 : // finalizer trying to drop its ownership of the C++ object.
629 : JS::Rooted<JSObject*> unforgeableHolder(aCx,
630 18 : &js::GetReservedSlot(canonicalProto, DOM_INTERFACE_PROTO_SLOTS_BASE).toObject());
631 9 : if (!JS_InitializePropertiesFromCompatibleNativeObject(aCx, aReflector, unforgeableHolder)) {
632 0 : aCache->ReleaseWrapper(aObject);
633 0 : aCache->ClearWrapper();
634 0 : return false;
635 : }
636 9 : creator.InitializationSucceeded();
637 :
638 9 : MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
639 : aCache->GetWrapperPreserveColor() == aReflector);
640 : // If proto != canonicalProto, we have to preserve our wrapper;
641 : // otherwise we won't be able to properly recreate it later, since
642 : // we won't know what proto to use. Note that we don't check
643 : // aGivenProto here, since it's entirely possible (and even
644 : // somewhat common) to have a non-null aGivenProto which is the
645 : // same as canonicalProto.
646 9 : if (proto != canonicalProto) {
647 0 : PreserveWrapper(aObject);
648 : }
649 :
650 9 : return true;
651 : }
652 :
653 : const NativePropertyHooks sNativePropertyHooks[] = { {
654 : nullptr,
655 : nullptr,
656 : nullptr,
657 : { sNativeProperties.Upcast(), nullptr },
658 : prototypes::id::CustomEvent,
659 : constructors::id::CustomEvent,
660 : EventBinding::sNativePropertyHooks,
661 : &DefaultXrayExpandoObjectClass
662 : } };
663 :
664 : void
665 3 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
666 : {
667 3 : JS::Handle<JSObject*> parentProto(EventBinding::GetProtoObjectHandle(aCx));
668 3 : if (!parentProto) {
669 0 : return;
670 : }
671 :
672 3 : JS::Handle<JSObject*> constructorProto(EventBinding::GetConstructorObjectHandle(aCx));
673 3 : if (!constructorProto) {
674 0 : return;
675 : }
676 :
677 : static bool sIdsInited = false;
678 3 : if (!sIdsInited && NS_IsMainThread()) {
679 2 : if (!InitIds(aCx, sNativeProperties.Upcast())) {
680 0 : return;
681 : }
682 2 : sIdsInited = true;
683 : }
684 :
685 3 : JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::CustomEvent);
686 3 : JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::CustomEvent);
687 3 : dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
688 : &sPrototypeClass.mBase, protoCache,
689 : constructorProto, &sInterfaceObjectClass.mBase, 1, nullptr,
690 : interfaceCache,
691 : sNativeProperties.Upcast(),
692 : nullptr,
693 : "CustomEvent", aDefineOnGlobal,
694 : nullptr,
695 3 : false);
696 :
697 6 : JS::Rooted<JSObject*> unforgeableHolder(aCx);
698 : {
699 6 : JS::Rooted<JSObject*> holderProto(aCx, *protoCache);
700 3 : unforgeableHolder = JS_NewObjectWithoutMetadata(aCx, sClass.ToJSClass(), holderProto);
701 3 : if (!unforgeableHolder) {
702 0 : *protoCache = nullptr;
703 0 : if (interfaceCache) {
704 0 : *interfaceCache = nullptr;
705 : }
706 0 : return;
707 : }
708 : }
709 :
710 3 : if (!DefineUnforgeableAttributes(aCx, unforgeableHolder, sUnforgeableAttributes)) {
711 0 : *protoCache = nullptr;
712 0 : if (interfaceCache) {
713 0 : *interfaceCache = nullptr;
714 : }
715 0 : return;
716 : }
717 :
718 3 : if (*protoCache) {
719 3 : js::SetReservedSlot(*protoCache, DOM_INTERFACE_PROTO_SLOTS_BASE,
720 6 : JS::ObjectValue(*unforgeableHolder));
721 : }
722 : }
723 :
724 : JS::Handle<JSObject*>
725 10 : GetProtoObjectHandle(JSContext* aCx)
726 : {
727 : /* Get the interface prototype object for this class. This will create the
728 : object as needed. */
729 10 : bool aDefineOnGlobal = true;
730 :
731 : /* Make sure our global is sane. Hopefully we can remove this sometime */
732 10 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
733 10 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
734 0 : return nullptr;
735 : }
736 :
737 : /* Check to see whether the interface objects are already installed */
738 10 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
739 10 : if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::CustomEvent)) {
740 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
741 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
742 : }
743 :
744 : /*
745 : * The object might _still_ be null, but that's OK.
746 : *
747 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
748 : * traced by TraceProtoAndIfaceCache() and its contents are never
749 : * changed after they have been set.
750 : *
751 : * Calling address() avoids the read read barrier that does gray
752 : * unmarking, but it's not possible for the object to be gray here.
753 : */
754 :
755 10 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::CustomEvent);
756 10 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
757 10 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
758 : }
759 :
760 : JS::Handle<JSObject*>
761 7 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
762 : {
763 : /* Get the interface object for this class. This will create the object as
764 : needed. */
765 :
766 : /* Make sure our global is sane. Hopefully we can remove this sometime */
767 7 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
768 7 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
769 0 : return nullptr;
770 : }
771 :
772 : /* Check to see whether the interface objects are already installed */
773 7 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
774 7 : if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::CustomEvent)) {
775 6 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
776 3 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
777 : }
778 :
779 : /*
780 : * The object might _still_ be null, but that's OK.
781 : *
782 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
783 : * traced by TraceProtoAndIfaceCache() and its contents are never
784 : * changed after they have been set.
785 : *
786 : * Calling address() avoids the read read barrier that does gray
787 : * unmarking, but it's not possible for the object to be gray here.
788 : */
789 :
790 7 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::CustomEvent);
791 7 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
792 7 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
793 : }
794 :
795 : JSObject*
796 1 : GetConstructorObject(JSContext* aCx)
797 : {
798 1 : return GetConstructorObjectHandle(aCx);
799 : }
800 :
801 : } // namespace CustomEventBinding
802 :
803 :
804 :
805 : } // namespace dom
806 : } // namespace mozilla
|