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