Line data Source code
1 : /* THIS FILE IS AUTOGENERATED FROM UDPSocket.webidl BY Codegen.py - DO NOT EDIT */
2 :
3 : #include "AtomList.h"
4 : #include "EventHandlerBinding.h"
5 : #include "EventTargetBinding.h"
6 : #include "UDPSocketBinding.h"
7 : #include "WrapperFactory.h"
8 : #include "mozilla/OwningNonNull.h"
9 : #include "mozilla/Preferences.h"
10 : #include "mozilla/dom/BindingUtils.h"
11 : #include "mozilla/dom/Blob.h"
12 : #include "mozilla/dom/DOMJSClass.h"
13 : #include "mozilla/dom/NonRefcountedDOMObject.h"
14 : #include "mozilla/dom/Nullable.h"
15 : #include "mozilla/dom/PrimitiveConversions.h"
16 : #include "mozilla/dom/Promise.h"
17 : #include "mozilla/dom/ScriptSettings.h"
18 : #include "mozilla/dom/SimpleGlobalObject.h"
19 : #include "mozilla/dom/ToJSValue.h"
20 : #include "mozilla/dom/UDPSocket.h"
21 : #include "mozilla/dom/UnionConversions.h"
22 : #include "mozilla/dom/XrayExpandoClass.h"
23 : #include "nsContentUtils.h"
24 :
25 : namespace mozilla {
26 : namespace dom {
27 :
28 : void
29 0 : ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, OwningStringOrBlobOrArrayBufferOrArrayBufferView& aUnion, const char* aName, uint32_t aFlags)
30 : {
31 0 : if (aUnion.IsBlob()) {
32 0 : ImplCycleCollectionTraverse(aCallback, aUnion.GetAsBlob(), "mBlob", aFlags);
33 : }
34 0 : }
35 :
36 :
37 : void
38 0 : ImplCycleCollectionUnlink(OwningStringOrBlobOrArrayBufferOrArrayBufferView& aUnion)
39 : {
40 0 : aUnion.Uninit();
41 0 : }
42 :
43 :
44 : bool
45 0 : StringOrBlobOrArrayBufferOrArrayBufferView::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
46 : {
47 0 : switch (mType) {
48 : case eUninitialized: {
49 0 : return false;
50 : break;
51 : }
52 : case eString: {
53 0 : if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
54 0 : return false;
55 : }
56 0 : return true;
57 : break;
58 : }
59 : case eBlob: {
60 0 : if (!GetOrCreateDOMReflector(cx, mValue.mBlob.Value(), rval)) {
61 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
62 0 : return false;
63 : }
64 0 : return true;
65 : break;
66 : }
67 : case eArrayBuffer: {
68 0 : rval.setObject(*mValue.mArrayBuffer.Value().Obj());
69 0 : if (!MaybeWrapNonDOMObjectValue(cx, rval)) {
70 0 : return false;
71 : }
72 0 : return true;
73 : break;
74 : }
75 : case eArrayBufferView: {
76 0 : rval.setObject(*mValue.mArrayBufferView.Value().Obj());
77 0 : if (!MaybeWrapNonDOMObjectValue(cx, rval)) {
78 0 : return false;
79 : }
80 0 : return true;
81 : break;
82 : }
83 : default: {
84 0 : return false;
85 : break;
86 : }
87 : }
88 :
89 : return false;
90 : }
91 :
92 :
93 : nsString&
94 0 : OwningStringOrBlobOrArrayBufferOrArrayBufferView::RawSetAsString()
95 : {
96 0 : if (mType == eString) {
97 0 : return mValue.mString.Value();
98 : }
99 0 : MOZ_ASSERT(mType == eUninitialized);
100 0 : mType = eString;
101 0 : return mValue.mString.SetValue();
102 : }
103 :
104 : nsString&
105 0 : OwningStringOrBlobOrArrayBufferOrArrayBufferView::SetAsString()
106 : {
107 0 : if (mType == eString) {
108 0 : return mValue.mString.Value();
109 : }
110 0 : Uninit();
111 0 : mType = eString;
112 0 : return mValue.mString.SetValue();
113 : }
114 :
115 : bool
116 0 : OwningStringOrBlobOrArrayBufferOrArrayBufferView::TrySetToString(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
117 : {
118 0 : tryNext = false;
119 : { // scope for memberSlot
120 0 : nsString& memberSlot = RawSetAsString();
121 0 : if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
122 0 : return false;
123 : }
124 : }
125 0 : return true;
126 : }
127 :
128 :
129 : void
130 0 : OwningStringOrBlobOrArrayBufferOrArrayBufferView::DestroyString()
131 : {
132 0 : MOZ_ASSERT(IsString(), "Wrong type!");
133 0 : mValue.mString.Destroy();
134 0 : mType = eUninitialized;
135 0 : }
136 :
137 :
138 :
139 :
140 : OwningNonNull<mozilla::dom::Blob>&
141 0 : OwningStringOrBlobOrArrayBufferOrArrayBufferView::RawSetAsBlob()
142 : {
143 0 : if (mType == eBlob) {
144 0 : return mValue.mBlob.Value();
145 : }
146 0 : MOZ_ASSERT(mType == eUninitialized);
147 0 : mType = eBlob;
148 0 : return mValue.mBlob.SetValue();
149 : }
150 :
151 : OwningNonNull<mozilla::dom::Blob>&
152 0 : OwningStringOrBlobOrArrayBufferOrArrayBufferView::SetAsBlob()
153 : {
154 0 : if (mType == eBlob) {
155 0 : return mValue.mBlob.Value();
156 : }
157 0 : Uninit();
158 0 : mType = eBlob;
159 0 : return mValue.mBlob.SetValue();
160 : }
161 :
162 : bool
163 0 : OwningStringOrBlobOrArrayBufferOrArrayBufferView::TrySetToBlob(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
164 : {
165 0 : tryNext = false;
166 : { // scope for memberSlot
167 0 : OwningNonNull<mozilla::dom::Blob>& memberSlot = RawSetAsBlob();
168 : static_assert(IsRefcounted<mozilla::dom::Blob>::value, "We can only store refcounted classes.");{
169 0 : nsresult rv = UnwrapObject<prototypes::id::Blob, mozilla::dom::Blob>(value, memberSlot);
170 0 : if (NS_FAILED(rv)) {
171 0 : DestroyBlob();
172 0 : tryNext = true;
173 0 : return true;
174 : }
175 : }
176 : }
177 0 : return true;
178 : }
179 :
180 : void
181 0 : OwningStringOrBlobOrArrayBufferOrArrayBufferView::DestroyBlob()
182 : {
183 0 : MOZ_ASSERT(IsBlob(), "Wrong type!");
184 0 : mValue.mBlob.Destroy();
185 0 : mType = eUninitialized;
186 0 : }
187 :
188 :
189 :
190 :
191 : ArrayBuffer&
192 0 : OwningStringOrBlobOrArrayBufferOrArrayBufferView::RawSetAsArrayBuffer()
193 : {
194 0 : if (mType == eArrayBuffer) {
195 0 : return mValue.mArrayBuffer.Value();
196 : }
197 0 : MOZ_ASSERT(mType == eUninitialized);
198 0 : mType = eArrayBuffer;
199 0 : return mValue.mArrayBuffer.SetValue();
200 : }
201 :
202 : ArrayBuffer&
203 0 : OwningStringOrBlobOrArrayBufferOrArrayBufferView::SetAsArrayBuffer()
204 : {
205 0 : if (mType == eArrayBuffer) {
206 0 : return mValue.mArrayBuffer.Value();
207 : }
208 0 : Uninit();
209 0 : mType = eArrayBuffer;
210 0 : return mValue.mArrayBuffer.SetValue();
211 : }
212 :
213 : bool
214 0 : OwningStringOrBlobOrArrayBufferOrArrayBufferView::TrySetToArrayBuffer(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
215 : {
216 0 : tryNext = false;
217 : { // scope for memberSlot
218 0 : ArrayBuffer& memberSlot = RawSetAsArrayBuffer();
219 0 : if (!memberSlot.Init(&value.toObject())) {
220 0 : DestroyArrayBuffer();
221 0 : tryNext = true;
222 0 : return true;
223 : }
224 : }
225 0 : return true;
226 : }
227 :
228 : void
229 0 : OwningStringOrBlobOrArrayBufferOrArrayBufferView::DestroyArrayBuffer()
230 : {
231 0 : MOZ_ASSERT(IsArrayBuffer(), "Wrong type!");
232 0 : mValue.mArrayBuffer.Destroy();
233 0 : mType = eUninitialized;
234 0 : }
235 :
236 :
237 :
238 :
239 : ArrayBufferView&
240 0 : OwningStringOrBlobOrArrayBufferOrArrayBufferView::RawSetAsArrayBufferView()
241 : {
242 0 : if (mType == eArrayBufferView) {
243 0 : return mValue.mArrayBufferView.Value();
244 : }
245 0 : MOZ_ASSERT(mType == eUninitialized);
246 0 : mType = eArrayBufferView;
247 0 : return mValue.mArrayBufferView.SetValue();
248 : }
249 :
250 : ArrayBufferView&
251 0 : OwningStringOrBlobOrArrayBufferOrArrayBufferView::SetAsArrayBufferView()
252 : {
253 0 : if (mType == eArrayBufferView) {
254 0 : return mValue.mArrayBufferView.Value();
255 : }
256 0 : Uninit();
257 0 : mType = eArrayBufferView;
258 0 : return mValue.mArrayBufferView.SetValue();
259 : }
260 :
261 : bool
262 0 : OwningStringOrBlobOrArrayBufferOrArrayBufferView::TrySetToArrayBufferView(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
263 : {
264 0 : tryNext = false;
265 : { // scope for memberSlot
266 0 : ArrayBufferView& memberSlot = RawSetAsArrayBufferView();
267 0 : if (!memberSlot.Init(&value.toObject())) {
268 0 : DestroyArrayBufferView();
269 0 : tryNext = true;
270 0 : return true;
271 : }
272 : }
273 0 : return true;
274 : }
275 :
276 : void
277 0 : OwningStringOrBlobOrArrayBufferOrArrayBufferView::DestroyArrayBufferView()
278 : {
279 0 : MOZ_ASSERT(IsArrayBufferView(), "Wrong type!");
280 0 : mValue.mArrayBufferView.Destroy();
281 0 : mType = eUninitialized;
282 0 : }
283 :
284 :
285 :
286 :
287 : void
288 0 : OwningStringOrBlobOrArrayBufferOrArrayBufferView::Uninit()
289 : {
290 0 : switch (mType) {
291 : case eUninitialized: {
292 0 : break;
293 : }
294 : case eString: {
295 0 : DestroyString();
296 0 : break;
297 : }
298 : case eBlob: {
299 0 : DestroyBlob();
300 0 : break;
301 : }
302 : case eArrayBuffer: {
303 0 : DestroyArrayBuffer();
304 0 : break;
305 : }
306 : case eArrayBufferView: {
307 0 : DestroyArrayBufferView();
308 0 : break;
309 : }
310 : }
311 0 : }
312 :
313 : bool
314 0 : OwningStringOrBlobOrArrayBufferOrArrayBufferView::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
315 : {
316 0 : switch (mType) {
317 : case eUninitialized: {
318 0 : return false;
319 : break;
320 : }
321 : case eString: {
322 0 : if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
323 0 : return false;
324 : }
325 0 : return true;
326 : break;
327 : }
328 : case eBlob: {
329 0 : if (!GetOrCreateDOMReflector(cx, mValue.mBlob.Value(), rval)) {
330 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
331 0 : return false;
332 : }
333 0 : return true;
334 : break;
335 : }
336 : case eArrayBuffer: {
337 0 : rval.setObject(*mValue.mArrayBuffer.Value().Obj());
338 0 : if (!MaybeWrapNonDOMObjectValue(cx, rval)) {
339 0 : return false;
340 : }
341 0 : return true;
342 : break;
343 : }
344 : case eArrayBufferView: {
345 0 : rval.setObject(*mValue.mArrayBufferView.Value().Obj());
346 0 : if (!MaybeWrapNonDOMObjectValue(cx, rval)) {
347 0 : return false;
348 : }
349 0 : return true;
350 : break;
351 : }
352 : default: {
353 0 : return false;
354 : break;
355 : }
356 : }
357 :
358 : return false;
359 : }
360 :
361 : void
362 0 : OwningStringOrBlobOrArrayBufferOrArrayBufferView::TraceUnion(JSTracer* trc)
363 : {
364 0 : switch (mType) {
365 : case eArrayBuffer: {
366 0 : mValue.mArrayBuffer.Value().TraceSelf(trc);
367 0 : break;
368 : }
369 : case eArrayBufferView: {
370 0 : mValue.mArrayBufferView.Value().TraceSelf(trc);
371 0 : break;
372 : }
373 : default: {
374 0 : break;
375 : }
376 : }
377 0 : }
378 :
379 :
380 :
381 0 : UDPOptions::UDPOptions()
382 : {
383 : // Safe to pass a null context if we pass a null value
384 0 : Init(nullptr, JS::NullHandleValue);
385 0 : }
386 :
387 :
388 :
389 : bool
390 0 : UDPOptions::InitIds(JSContext* cx, UDPOptionsAtoms* atomsCache)
391 : {
392 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
393 :
394 : // Initialize these in reverse order so that any failure leaves the first one
395 : // uninitialized.
396 0 : if (!atomsCache->remotePort_id.init(cx, "remotePort") ||
397 0 : !atomsCache->remoteAddress_id.init(cx, "remoteAddress") ||
398 0 : !atomsCache->loopback_id.init(cx, "loopback") ||
399 0 : !atomsCache->localPort_id.init(cx, "localPort") ||
400 0 : !atomsCache->localAddress_id.init(cx, "localAddress") ||
401 0 : !atomsCache->addressReuse_id.init(cx, "addressReuse")) {
402 0 : return false;
403 : }
404 0 : return true;
405 : }
406 :
407 : bool
408 0 : UDPOptions::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
409 : {
410 : // Passing a null JSContext is OK only if we're initing from null,
411 : // Since in that case we will not have to do any property gets
412 : // Also evaluate isNullOrUndefined in order to avoid false-positive
413 : // checkers by static analysis tools
414 0 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
415 0 : UDPOptionsAtoms* atomsCache = nullptr;
416 0 : if (cx) {
417 0 : atomsCache = GetAtomCache<UDPOptionsAtoms>(cx);
418 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
419 0 : return false;
420 : }
421 : }
422 :
423 0 : if (!IsConvertibleToDictionary(val)) {
424 0 : return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
425 : }
426 :
427 0 : bool isNull = val.isNullOrUndefined();
428 : // We only need these if !isNull, in which case we have |cx|.
429 0 : Maybe<JS::Rooted<JSObject *> > object;
430 0 : Maybe<JS::Rooted<JS::Value> > temp;
431 0 : if (!isNull) {
432 0 : MOZ_ASSERT(cx);
433 0 : object.emplace(cx, &val.toObject());
434 0 : temp.emplace(cx);
435 : }
436 0 : if (!isNull) {
437 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->addressReuse_id, temp.ptr())) {
438 0 : return false;
439 : }
440 : }
441 0 : if (!isNull && !temp->isUndefined()) {
442 0 : if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &mAddressReuse)) {
443 0 : return false;
444 : }
445 : } else {
446 0 : mAddressReuse = true;
447 : }
448 0 : mIsAnyMemberPresent = true;
449 :
450 0 : if (!isNull) {
451 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->localAddress_id, temp.ptr())) {
452 0 : return false;
453 : }
454 : }
455 0 : if (!isNull && !temp->isUndefined()) {
456 0 : mLocalAddress.Construct();
457 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mLocalAddress.Value()))) {
458 0 : return false;
459 : }
460 0 : mIsAnyMemberPresent = true;
461 : }
462 :
463 0 : if (!isNull) {
464 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->localPort_id, temp.ptr())) {
465 0 : return false;
466 : }
467 : }
468 0 : if (!isNull && !temp->isUndefined()) {
469 0 : mLocalPort.Construct();
470 0 : if (!ValueToPrimitive<uint16_t, eDefault>(cx, temp.ref(), &(mLocalPort.Value()))) {
471 0 : return false;
472 : }
473 0 : mIsAnyMemberPresent = true;
474 : }
475 :
476 0 : if (!isNull) {
477 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->loopback_id, temp.ptr())) {
478 0 : return false;
479 : }
480 : }
481 0 : if (!isNull && !temp->isUndefined()) {
482 0 : if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &mLoopback)) {
483 0 : return false;
484 : }
485 : } else {
486 0 : mLoopback = false;
487 : }
488 0 : mIsAnyMemberPresent = true;
489 :
490 0 : if (!isNull) {
491 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->remoteAddress_id, temp.ptr())) {
492 0 : return false;
493 : }
494 : }
495 0 : if (!isNull && !temp->isUndefined()) {
496 0 : mRemoteAddress.Construct();
497 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mRemoteAddress.Value()))) {
498 0 : return false;
499 : }
500 0 : mIsAnyMemberPresent = true;
501 : }
502 :
503 0 : if (!isNull) {
504 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->remotePort_id, temp.ptr())) {
505 0 : return false;
506 : }
507 : }
508 0 : if (!isNull && !temp->isUndefined()) {
509 0 : mRemotePort.Construct();
510 0 : if (!ValueToPrimitive<uint16_t, eDefault>(cx, temp.ref(), &(mRemotePort.Value()))) {
511 0 : return false;
512 : }
513 0 : mIsAnyMemberPresent = true;
514 : }
515 0 : return true;
516 : }
517 :
518 : bool
519 0 : UDPOptions::Init(const nsAString& aJSON)
520 : {
521 0 : AutoJSAPI jsapi;
522 0 : JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
523 0 : if (!cleanGlobal) {
524 0 : return false;
525 : }
526 0 : if (!jsapi.Init(cleanGlobal)) {
527 0 : return false;
528 : }
529 0 : JSContext* cx = jsapi.cx();
530 0 : JS::Rooted<JS::Value> json(cx);
531 0 : bool ok = ParseJSON(cx, aJSON, &json);
532 0 : NS_ENSURE_TRUE(ok, false);
533 0 : return Init(cx, json);
534 : }
535 :
536 : bool
537 0 : UDPOptions::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
538 : {
539 0 : UDPOptionsAtoms* atomsCache = GetAtomCache<UDPOptionsAtoms>(cx);
540 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
541 0 : return false;
542 : }
543 :
544 0 : JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
545 0 : if (!obj) {
546 0 : return false;
547 : }
548 0 : rval.set(JS::ObjectValue(*obj));
549 :
550 : do {
551 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
552 0 : JS::Rooted<JS::Value> temp(cx);
553 0 : bool const & currentValue = mAddressReuse;
554 0 : temp.setBoolean(currentValue);
555 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->addressReuse_id, temp, JSPROP_ENUMERATE)) {
556 0 : return false;
557 : }
558 0 : break;
559 : } while(0);
560 :
561 0 : if (mLocalAddress.WasPassed()) {
562 : do {
563 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
564 0 : JS::Rooted<JS::Value> temp(cx);
565 0 : nsString const & currentValue = mLocalAddress.InternalValue();
566 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
567 0 : return false;
568 : }
569 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->localAddress_id, temp, JSPROP_ENUMERATE)) {
570 0 : return false;
571 : }
572 0 : break;
573 : } while(0);
574 : }
575 :
576 0 : if (mLocalPort.WasPassed()) {
577 : do {
578 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
579 0 : JS::Rooted<JS::Value> temp(cx);
580 0 : uint16_t const & currentValue = mLocalPort.InternalValue();
581 0 : temp.setInt32(int32_t(currentValue));
582 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->localPort_id, temp, JSPROP_ENUMERATE)) {
583 0 : return false;
584 : }
585 0 : break;
586 : } while(0);
587 : }
588 :
589 : do {
590 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
591 0 : JS::Rooted<JS::Value> temp(cx);
592 0 : bool const & currentValue = mLoopback;
593 0 : temp.setBoolean(currentValue);
594 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->loopback_id, temp, JSPROP_ENUMERATE)) {
595 0 : return false;
596 : }
597 0 : break;
598 : } while(0);
599 :
600 0 : if (mRemoteAddress.WasPassed()) {
601 : do {
602 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
603 0 : JS::Rooted<JS::Value> temp(cx);
604 0 : nsString const & currentValue = mRemoteAddress.InternalValue();
605 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
606 0 : return false;
607 : }
608 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->remoteAddress_id, temp, JSPROP_ENUMERATE)) {
609 0 : return false;
610 : }
611 0 : break;
612 : } while(0);
613 : }
614 :
615 0 : if (mRemotePort.WasPassed()) {
616 : do {
617 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
618 0 : JS::Rooted<JS::Value> temp(cx);
619 0 : uint16_t const & currentValue = mRemotePort.InternalValue();
620 0 : temp.setInt32(int32_t(currentValue));
621 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->remotePort_id, temp, JSPROP_ENUMERATE)) {
622 0 : return false;
623 : }
624 0 : break;
625 : } while(0);
626 : }
627 :
628 0 : return true;
629 : }
630 :
631 : bool
632 0 : UDPOptions::ToJSON(nsAString& aJSON) const
633 : {
634 0 : AutoJSAPI jsapi;
635 0 : jsapi.Init();
636 0 : JSContext *cx = jsapi.cx();
637 : // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
638 : // because we'll only be creating objects, in ways that have no
639 : // side-effects, followed by a call to JS::ToJSONMaybeSafely,
640 : // which likewise guarantees no side-effects for the sorts of
641 : // things we will pass it.
642 0 : JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
643 0 : JS::Rooted<JS::Value> val(cx);
644 0 : if (!ToObjectInternal(cx, &val)) {
645 0 : return false;
646 : }
647 0 : JS::Rooted<JSObject*> obj(cx, &val.toObject());
648 0 : return StringifyToJSON(cx, obj, aJSON);
649 : }
650 :
651 : void
652 0 : UDPOptions::TraceDictionary(JSTracer* trc)
653 : {
654 0 : }
655 :
656 : UDPOptions&
657 0 : UDPOptions::operator=(const UDPOptions& aOther)
658 : {
659 0 : mAddressReuse = aOther.mAddressReuse;
660 0 : mLocalAddress.Reset();
661 0 : if (aOther.mLocalAddress.WasPassed()) {
662 0 : mLocalAddress.Construct(aOther.mLocalAddress.Value());
663 : }
664 0 : mLocalPort.Reset();
665 0 : if (aOther.mLocalPort.WasPassed()) {
666 0 : mLocalPort.Construct(aOther.mLocalPort.Value());
667 : }
668 0 : mLoopback = aOther.mLoopback;
669 0 : mRemoteAddress.Reset();
670 0 : if (aOther.mRemoteAddress.WasPassed()) {
671 0 : mRemoteAddress.Construct(aOther.mRemoteAddress.Value());
672 : }
673 0 : mRemotePort.Reset();
674 0 : if (aOther.mRemotePort.WasPassed()) {
675 0 : mRemotePort.Construct(aOther.mRemotePort.Value());
676 : }
677 0 : return *this;
678 : }
679 :
680 : namespace binding_detail {
681 : } // namespace binding_detail
682 :
683 :
684 : namespace UDPSocketBinding {
685 :
686 : static_assert(IsRefcounted<NativeType>::value == IsRefcounted<EventTargetBinding::NativeType>::value,
687 : "Can't inherit from an interface with a different ownership model.");
688 :
689 : static bool
690 0 : get_localAddress(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::UDPSocket* self, JSJitGetterCallArgs args)
691 : {
692 0 : DOMString result;
693 0 : self->GetLocalAddress(result);
694 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
695 0 : if (!xpc::StringToJsval(cx, result, args.rval())) {
696 0 : return false;
697 : }
698 0 : return true;
699 : }
700 :
701 : static const JSJitInfo localAddress_getterinfo = {
702 : { (JSJitGetterOp)get_localAddress },
703 : { prototypes::id::UDPSocket },
704 : { PrototypeTraits<prototypes::id::UDPSocket>::Depth },
705 : JSJitInfo::Getter,
706 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
707 : JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */
708 : false, /* isInfallible. False in setters. */
709 : false, /* isMovable. Not relevant for setters. */
710 : false, /* isEliminatable. Not relevant for setters. */
711 : false, /* isAlwaysInSlot. Only relevant for getters. */
712 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
713 : false, /* isTypedMethod. Only relevant for methods. */
714 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
715 : };
716 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
717 : static_assert(0 < 1, "There is no slot for us");
718 :
719 : static bool
720 0 : get_localPort(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::UDPSocket* self, JSJitGetterCallArgs args)
721 : {
722 0 : Nullable<uint16_t> result(self->GetLocalPort());
723 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
724 0 : if (result.IsNull()) {
725 0 : args.rval().setNull();
726 0 : return true;
727 : }
728 0 : args.rval().setInt32(int32_t(result.Value()));
729 0 : return true;
730 : }
731 :
732 : static const JSJitInfo localPort_getterinfo = {
733 : { (JSJitGetterOp)get_localPort },
734 : { prototypes::id::UDPSocket },
735 : { PrototypeTraits<prototypes::id::UDPSocket>::Depth },
736 : JSJitInfo::Getter,
737 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
738 : JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */
739 : true, /* isInfallible. False in setters. */
740 : false, /* isMovable. Not relevant for setters. */
741 : false, /* isEliminatable. Not relevant for setters. */
742 : false, /* isAlwaysInSlot. Only relevant for getters. */
743 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
744 : false, /* isTypedMethod. Only relevant for methods. */
745 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
746 : };
747 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
748 : static_assert(0 < 1, "There is no slot for us");
749 :
750 : static bool
751 0 : get_remoteAddress(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::UDPSocket* self, JSJitGetterCallArgs args)
752 : {
753 0 : DOMString result;
754 0 : self->GetRemoteAddress(result);
755 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
756 0 : if (!xpc::StringToJsval(cx, result, args.rval())) {
757 0 : return false;
758 : }
759 0 : return true;
760 : }
761 :
762 : static const JSJitInfo remoteAddress_getterinfo = {
763 : { (JSJitGetterOp)get_remoteAddress },
764 : { prototypes::id::UDPSocket },
765 : { PrototypeTraits<prototypes::id::UDPSocket>::Depth },
766 : JSJitInfo::Getter,
767 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
768 : JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */
769 : false, /* isInfallible. False in setters. */
770 : false, /* isMovable. Not relevant for setters. */
771 : false, /* isEliminatable. Not relevant for setters. */
772 : false, /* isAlwaysInSlot. Only relevant for getters. */
773 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
774 : false, /* isTypedMethod. Only relevant for methods. */
775 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
776 : };
777 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
778 : static_assert(0 < 1, "There is no slot for us");
779 :
780 : static bool
781 0 : get_remotePort(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::UDPSocket* self, JSJitGetterCallArgs args)
782 : {
783 0 : Nullable<uint16_t> result(self->GetRemotePort());
784 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
785 0 : if (result.IsNull()) {
786 0 : args.rval().setNull();
787 0 : return true;
788 : }
789 0 : args.rval().setInt32(int32_t(result.Value()));
790 0 : return true;
791 : }
792 :
793 : static const JSJitInfo remotePort_getterinfo = {
794 : { (JSJitGetterOp)get_remotePort },
795 : { prototypes::id::UDPSocket },
796 : { PrototypeTraits<prototypes::id::UDPSocket>::Depth },
797 : JSJitInfo::Getter,
798 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
799 : JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */
800 : true, /* isInfallible. False in setters. */
801 : false, /* isMovable. Not relevant for setters. */
802 : false, /* isEliminatable. Not relevant for setters. */
803 : false, /* isAlwaysInSlot. Only relevant for getters. */
804 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
805 : false, /* isTypedMethod. Only relevant for methods. */
806 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
807 : };
808 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
809 : static_assert(0 < 1, "There is no slot for us");
810 :
811 : static bool
812 0 : get_addressReuse(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::UDPSocket* self, JSJitGetterCallArgs args)
813 : {
814 0 : bool result(self->AddressReuse());
815 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
816 0 : args.rval().setBoolean(result);
817 0 : return true;
818 : }
819 :
820 : static const JSJitInfo addressReuse_getterinfo = {
821 : { (JSJitGetterOp)get_addressReuse },
822 : { prototypes::id::UDPSocket },
823 : { PrototypeTraits<prototypes::id::UDPSocket>::Depth },
824 : JSJitInfo::Getter,
825 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
826 : JSVAL_TYPE_BOOLEAN, /* returnType. Not relevant for setters. */
827 : true, /* isInfallible. False in setters. */
828 : false, /* isMovable. Not relevant for setters. */
829 : false, /* isEliminatable. Not relevant for setters. */
830 : false, /* isAlwaysInSlot. Only relevant for getters. */
831 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
832 : false, /* isTypedMethod. Only relevant for methods. */
833 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
834 : };
835 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
836 : static_assert(0 < 1, "There is no slot for us");
837 :
838 : static bool
839 0 : get_loopback(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::UDPSocket* self, JSJitGetterCallArgs args)
840 : {
841 0 : bool result(self->Loopback());
842 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
843 0 : args.rval().setBoolean(result);
844 0 : return true;
845 : }
846 :
847 : static const JSJitInfo loopback_getterinfo = {
848 : { (JSJitGetterOp)get_loopback },
849 : { prototypes::id::UDPSocket },
850 : { PrototypeTraits<prototypes::id::UDPSocket>::Depth },
851 : JSJitInfo::Getter,
852 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
853 : JSVAL_TYPE_BOOLEAN, /* returnType. Not relevant for setters. */
854 : true, /* isInfallible. False in setters. */
855 : false, /* isMovable. Not relevant for setters. */
856 : false, /* isEliminatable. Not relevant for setters. */
857 : false, /* isAlwaysInSlot. Only relevant for getters. */
858 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
859 : false, /* isTypedMethod. Only relevant for methods. */
860 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
861 : };
862 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
863 : static_assert(0 < 1, "There is no slot for us");
864 :
865 : static bool
866 0 : get_readyState(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::UDPSocket* self, JSJitGetterCallArgs args)
867 : {
868 0 : SocketReadyState result(self->ReadyState());
869 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
870 0 : if (!ToJSValue(cx, result, args.rval())) {
871 0 : return false;
872 : }
873 0 : return true;
874 : }
875 :
876 : static const JSJitInfo readyState_getterinfo = {
877 : { (JSJitGetterOp)get_readyState },
878 : { prototypes::id::UDPSocket },
879 : { PrototypeTraits<prototypes::id::UDPSocket>::Depth },
880 : JSJitInfo::Getter,
881 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
882 : JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
883 : false, /* isInfallible. False in setters. */
884 : false, /* isMovable. Not relevant for setters. */
885 : false, /* isEliminatable. Not relevant for setters. */
886 : false, /* isAlwaysInSlot. Only relevant for getters. */
887 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
888 : false, /* isTypedMethod. Only relevant for methods. */
889 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
890 : };
891 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
892 : static_assert(0 < 1, "There is no slot for us");
893 :
894 : static bool
895 0 : get_opened(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::UDPSocket* self, JSJitGetterCallArgs args)
896 : {
897 0 : auto result(StrongOrRawPtr<Promise>(self->Opened()));
898 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
899 0 : if (!ToJSValue(cx, result, args.rval())) {
900 0 : return false;
901 : }
902 0 : return true;
903 : }
904 :
905 : static bool
906 0 : get_opened_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::UDPSocket* self, JSJitGetterCallArgs args)
907 : {
908 0 : bool ok = get_opened(cx, obj, self, args);
909 0 : if (ok) {
910 0 : return true;
911 : }
912 0 : JS::Rooted<JSObject*> globalForPromise(cx);
913 : // We can't use xpc::XrayAwareCalleeGlobal here because we have no
914 : // callee. Use our hacky version instead.
915 0 : if (!xpc::XrayAwareCalleeGlobalForSpecializedGetters(cx, obj,
916 : &globalForPromise)) {
917 0 : return false;
918 : }
919 0 : return ConvertExceptionToPromise(cx, globalForPromise, args.rval());
920 : }
921 :
922 : static const JSJitInfo opened_getterinfo = {
923 : { (JSJitGetterOp)get_opened_promiseWrapper },
924 : { prototypes::id::UDPSocket },
925 : { PrototypeTraits<prototypes::id::UDPSocket>::Depth },
926 : JSJitInfo::Getter,
927 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
928 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
929 : false, /* isInfallible. False in setters. */
930 : false, /* isMovable. Not relevant for setters. */
931 : false, /* isEliminatable. Not relevant for setters. */
932 : false, /* isAlwaysInSlot. Only relevant for getters. */
933 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
934 : false, /* isTypedMethod. Only relevant for methods. */
935 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
936 : };
937 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
938 : static_assert(0 < 1, "There is no slot for us");
939 :
940 : static bool
941 0 : get_closed(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::UDPSocket* self, JSJitGetterCallArgs args)
942 : {
943 0 : auto result(StrongOrRawPtr<Promise>(self->Closed()));
944 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
945 0 : if (!ToJSValue(cx, result, args.rval())) {
946 0 : return false;
947 : }
948 0 : return true;
949 : }
950 :
951 : static bool
952 0 : get_closed_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::UDPSocket* self, JSJitGetterCallArgs args)
953 : {
954 0 : bool ok = get_closed(cx, obj, self, args);
955 0 : if (ok) {
956 0 : return true;
957 : }
958 0 : JS::Rooted<JSObject*> globalForPromise(cx);
959 : // We can't use xpc::XrayAwareCalleeGlobal here because we have no
960 : // callee. Use our hacky version instead.
961 0 : if (!xpc::XrayAwareCalleeGlobalForSpecializedGetters(cx, obj,
962 : &globalForPromise)) {
963 0 : return false;
964 : }
965 0 : return ConvertExceptionToPromise(cx, globalForPromise, args.rval());
966 : }
967 :
968 : static const JSJitInfo closed_getterinfo = {
969 : { (JSJitGetterOp)get_closed_promiseWrapper },
970 : { prototypes::id::UDPSocket },
971 : { PrototypeTraits<prototypes::id::UDPSocket>::Depth },
972 : JSJitInfo::Getter,
973 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
974 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
975 : false, /* isInfallible. False in setters. */
976 : false, /* isMovable. Not relevant for setters. */
977 : false, /* isEliminatable. Not relevant for setters. */
978 : false, /* isAlwaysInSlot. Only relevant for getters. */
979 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
980 : false, /* isTypedMethod. Only relevant for methods. */
981 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
982 : };
983 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
984 : static_assert(0 < 1, "There is no slot for us");
985 :
986 : static bool
987 0 : get_onmessage(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::UDPSocket* self, JSJitGetterCallArgs args)
988 : {
989 0 : RefPtr<EventHandlerNonNull> result(self->GetOnmessage());
990 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
991 0 : if (result) {
992 0 : args.rval().setObjectOrNull(GetCallbackFromCallbackObject(result));
993 0 : if (!MaybeWrapObjectOrNullValue(cx, args.rval())) {
994 0 : return false;
995 : }
996 0 : return true;
997 : } else {
998 0 : args.rval().setNull();
999 0 : return true;
1000 : }
1001 : }
1002 :
1003 : static bool
1004 0 : set_onmessage(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::UDPSocket* self, JSJitSetterCallArgs args)
1005 : {
1006 0 : RootedCallback<RefPtr<binding_detail::FastEventHandlerNonNull>> arg0(cx);
1007 0 : if (args[0].isObject()) {
1008 : { // scope for tempRoot
1009 0 : JS::Rooted<JSObject*> tempRoot(cx, &args[0].toObject());
1010 0 : arg0 = new binding_detail::FastEventHandlerNonNull(tempRoot);
1011 : }
1012 : } else {
1013 0 : arg0 = nullptr;
1014 : }
1015 0 : self->SetOnmessage(Constify(arg0));
1016 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
1017 :
1018 0 : return true;
1019 : }
1020 :
1021 : static const JSJitInfo onmessage_getterinfo = {
1022 : { (JSJitGetterOp)get_onmessage },
1023 : { prototypes::id::UDPSocket },
1024 : { PrototypeTraits<prototypes::id::UDPSocket>::Depth },
1025 : JSJitInfo::Getter,
1026 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
1027 : JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */
1028 : false, /* isInfallible. False in setters. */
1029 : false, /* isMovable. Not relevant for setters. */
1030 : false, /* isEliminatable. Not relevant for setters. */
1031 : false, /* isAlwaysInSlot. Only relevant for getters. */
1032 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
1033 : false, /* isTypedMethod. Only relevant for methods. */
1034 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
1035 : };
1036 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1037 : static_assert(0 < 1, "There is no slot for us");
1038 : static const JSJitInfo onmessage_setterinfo = {
1039 : { (JSJitGetterOp)set_onmessage },
1040 : { prototypes::id::UDPSocket },
1041 : { PrototypeTraits<prototypes::id::UDPSocket>::Depth },
1042 : JSJitInfo::Setter,
1043 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
1044 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
1045 : false, /* isInfallible. False in setters. */
1046 : false, /* isMovable. Not relevant for setters. */
1047 : false, /* isEliminatable. Not relevant for setters. */
1048 : false, /* isAlwaysInSlot. Only relevant for getters. */
1049 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
1050 : false, /* isTypedMethod. Only relevant for methods. */
1051 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
1052 : };
1053 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1054 : static_assert(0 < 1, "There is no slot for us");
1055 :
1056 : static bool
1057 0 : close(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::UDPSocket* self, const JSJitMethodCallArgs& args)
1058 : {
1059 0 : auto result(StrongOrRawPtr<Promise>(self->Close()));
1060 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
1061 0 : if (!ToJSValue(cx, result, args.rval())) {
1062 0 : return false;
1063 : }
1064 0 : return true;
1065 : }
1066 :
1067 : static bool
1068 0 : close_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::UDPSocket* self, const JSJitMethodCallArgs& args)
1069 : {
1070 : // Make sure to save the callee before someone maybe messes
1071 : // with rval().
1072 0 : JS::Rooted<JSObject*> callee(cx, &args.callee());
1073 0 : bool ok = close(cx, obj, self, args);
1074 0 : if (ok) {
1075 0 : return true;
1076 : }
1077 0 : return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
1078 0 : args.rval());
1079 : }
1080 :
1081 : static const JSJitInfo close_methodinfo = {
1082 : { (JSJitGetterOp)close_promiseWrapper },
1083 : { prototypes::id::UDPSocket },
1084 : { PrototypeTraits<prototypes::id::UDPSocket>::Depth },
1085 : JSJitInfo::Method,
1086 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
1087 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
1088 : false, /* isInfallible. False in setters. */
1089 : false, /* isMovable. Not relevant for setters. */
1090 : false, /* isEliminatable. Not relevant for setters. */
1091 : false, /* isAlwaysInSlot. Only relevant for getters. */
1092 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
1093 : false, /* isTypedMethod. Only relevant for methods. */
1094 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
1095 : };
1096 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1097 : static_assert(0 < 1, "There is no slot for us");
1098 :
1099 : static bool
1100 0 : joinMulticastGroup(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::UDPSocket* self, const JSJitMethodCallArgs& args)
1101 : {
1102 0 : if (MOZ_UNLIKELY(args.length() < 1)) {
1103 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "UDPSocket.joinMulticastGroup");
1104 : }
1105 0 : binding_detail::FakeString arg0;
1106 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
1107 0 : return false;
1108 : }
1109 0 : binding_detail::FastErrorResult rv;
1110 0 : self->JoinMulticastGroup(NonNullHelper(Constify(arg0)), rv);
1111 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
1112 0 : return false;
1113 : }
1114 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
1115 0 : args.rval().setUndefined();
1116 0 : return true;
1117 : }
1118 :
1119 : static const JSJitInfo joinMulticastGroup_methodinfo = {
1120 : { (JSJitGetterOp)joinMulticastGroup },
1121 : { prototypes::id::UDPSocket },
1122 : { PrototypeTraits<prototypes::id::UDPSocket>::Depth },
1123 : JSJitInfo::Method,
1124 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
1125 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
1126 : false, /* isInfallible. False in setters. */
1127 : false, /* isMovable. Not relevant for setters. */
1128 : false, /* isEliminatable. Not relevant for setters. */
1129 : false, /* isAlwaysInSlot. Only relevant for getters. */
1130 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
1131 : false, /* isTypedMethod. Only relevant for methods. */
1132 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
1133 : };
1134 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1135 : static_assert(0 < 1, "There is no slot for us");
1136 :
1137 : static bool
1138 0 : leaveMulticastGroup(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::UDPSocket* self, const JSJitMethodCallArgs& args)
1139 : {
1140 0 : if (MOZ_UNLIKELY(args.length() < 1)) {
1141 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "UDPSocket.leaveMulticastGroup");
1142 : }
1143 0 : binding_detail::FakeString arg0;
1144 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
1145 0 : return false;
1146 : }
1147 0 : binding_detail::FastErrorResult rv;
1148 0 : self->LeaveMulticastGroup(NonNullHelper(Constify(arg0)), rv);
1149 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
1150 0 : return false;
1151 : }
1152 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
1153 0 : args.rval().setUndefined();
1154 0 : return true;
1155 : }
1156 :
1157 : static const JSJitInfo leaveMulticastGroup_methodinfo = {
1158 : { (JSJitGetterOp)leaveMulticastGroup },
1159 : { prototypes::id::UDPSocket },
1160 : { PrototypeTraits<prototypes::id::UDPSocket>::Depth },
1161 : JSJitInfo::Method,
1162 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
1163 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
1164 : false, /* isInfallible. False in setters. */
1165 : false, /* isMovable. Not relevant for setters. */
1166 : false, /* isEliminatable. Not relevant for setters. */
1167 : false, /* isAlwaysInSlot. Only relevant for getters. */
1168 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
1169 : false, /* isTypedMethod. Only relevant for methods. */
1170 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
1171 : };
1172 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1173 : static_assert(0 < 1, "There is no slot for us");
1174 :
1175 : static bool
1176 0 : send(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::UDPSocket* self, const JSJitMethodCallArgs& args)
1177 : {
1178 0 : if (MOZ_UNLIKELY(args.length() < 1)) {
1179 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "UDPSocket.send");
1180 : }
1181 0 : StringOrBlobOrArrayBufferOrArrayBufferView arg0;
1182 0 : StringOrBlobOrArrayBufferOrArrayBufferViewArgument arg0_holder(arg0);
1183 : {
1184 0 : bool done = false, failed = false, tryNext;
1185 0 : if (args[0].isObject()) {
1186 0 : done = (failed = !arg0_holder.TrySetToBlob(cx, args[0], tryNext, false)) || !tryNext ||
1187 0 : (failed = !arg0_holder.TrySetToArrayBuffer(cx, args[0], tryNext, false)) || !tryNext ||
1188 0 : (failed = !arg0_holder.TrySetToArrayBufferView(cx, args[0], tryNext, false)) || !tryNext;
1189 :
1190 : }
1191 0 : if (!done) {
1192 : do {
1193 0 : done = (failed = !arg0_holder.TrySetToString(cx, args[0], tryNext)) || !tryNext;
1194 0 : break;
1195 : } while (0);
1196 : }
1197 0 : if (failed) {
1198 0 : return false;
1199 : }
1200 0 : if (!done) {
1201 0 : ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "Argument 1 of UDPSocket.send", "Blob, ArrayBuffer, ArrayBufferView");
1202 0 : return false;
1203 : }
1204 : }
1205 0 : Optional<nsAString> arg1;
1206 0 : binding_detail::FakeString arg1_holder;
1207 0 : if (args.hasDefined(1)) {
1208 0 : if (!ConvertJSValueToString(cx, args[1], eNull, eNull, arg1_holder)) {
1209 0 : return false;
1210 : }
1211 0 : arg1 = &arg1_holder;
1212 : }
1213 0 : Optional<Nullable<uint16_t>> arg2;
1214 0 : if (args.hasDefined(2)) {
1215 0 : arg2.Construct();
1216 0 : if (args[2].isNullOrUndefined()) {
1217 0 : arg2.Value().SetNull();
1218 0 : } else if (!ValueToPrimitive<uint16_t, eDefault>(cx, args[2], &arg2.Value().SetValue())) {
1219 0 : return false;
1220 : }
1221 : }
1222 0 : binding_detail::FastErrorResult rv;
1223 0 : bool result(self->Send(Constify(arg0), NonNullHelper(Constify(arg1)), Constify(arg2), rv));
1224 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
1225 0 : return false;
1226 : }
1227 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
1228 0 : args.rval().setBoolean(result);
1229 0 : return true;
1230 : }
1231 :
1232 : static const JSJitInfo send_methodinfo = {
1233 : { (JSJitGetterOp)send },
1234 : { prototypes::id::UDPSocket },
1235 : { PrototypeTraits<prototypes::id::UDPSocket>::Depth },
1236 : JSJitInfo::Method,
1237 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
1238 : JSVAL_TYPE_BOOLEAN, /* returnType. Not relevant for setters. */
1239 : false, /* isInfallible. False in setters. */
1240 : false, /* isMovable. Not relevant for setters. */
1241 : false, /* isEliminatable. Not relevant for setters. */
1242 : false, /* isAlwaysInSlot. Only relevant for getters. */
1243 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
1244 : false, /* isTypedMethod. Only relevant for methods. */
1245 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
1246 : };
1247 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1248 : static_assert(0 < 1, "There is no slot for us");
1249 :
1250 : static bool
1251 0 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
1252 : {
1253 0 : mozilla::dom::UDPSocket* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::UDPSocket>(obj);
1254 : // We don't want to preserve if we don't have a wrapper, and we
1255 : // obviously can't preserve if we're not initialized.
1256 0 : if (self && self->GetWrapperPreserveColor()) {
1257 0 : PreserveWrapper(self);
1258 : }
1259 0 : return true;
1260 : }
1261 :
1262 : static void
1263 0 : _finalize(js::FreeOp* fop, JSObject* obj)
1264 : {
1265 0 : mozilla::dom::UDPSocket* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::UDPSocket>(obj);
1266 0 : if (self) {
1267 0 : ClearWrapper(self, self, obj);
1268 0 : AddForDeferredFinalization<mozilla::dom::UDPSocket>(self);
1269 : }
1270 0 : }
1271 :
1272 : static void
1273 0 : _objectMoved(JSObject* obj, const JSObject* old)
1274 : {
1275 0 : mozilla::dom::UDPSocket* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::UDPSocket>(obj);
1276 0 : if (self) {
1277 0 : UpdateWrapper(self, self, obj, old);
1278 : }
1279 0 : }
1280 :
1281 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
1282 : #if defined(__clang__)
1283 : #pragma clang diagnostic push
1284 : #pragma clang diagnostic ignored "-Wmissing-braces"
1285 : #endif
1286 : static const JSFunctionSpec sMethods_specs[] = {
1287 : JS_FNSPEC("close", GenericPromiseReturningBindingMethod, reinterpret_cast<const JSJitInfo*>(&close_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
1288 : JS_FNSPEC("joinMulticastGroup", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&joinMulticastGroup_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
1289 : JS_FNSPEC("leaveMulticastGroup", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&leaveMulticastGroup_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
1290 : JS_FNSPEC("send", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&send_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
1291 : JS_FS_END
1292 : };
1293 : #if defined(__clang__)
1294 : #pragma clang diagnostic pop
1295 : #endif
1296 :
1297 :
1298 : // Can't be const because the pref-enabled boolean needs to be writable
1299 : static Prefable<const JSFunctionSpec> sMethods[] = {
1300 : { nullptr, &sMethods_specs[0] },
1301 : { nullptr, nullptr }
1302 : };
1303 :
1304 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
1305 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
1306 : static_assert(4 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
1307 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
1308 :
1309 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
1310 : #if defined(__clang__)
1311 : #pragma clang diagnostic push
1312 : #pragma clang diagnostic ignored "-Wmissing-braces"
1313 : #endif
1314 : static const JSPropertySpec sAttributes_specs[] = {
1315 : { "localAddress", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &localAddress_getterinfo, nullptr, nullptr },
1316 : { "localPort", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &localPort_getterinfo, nullptr, nullptr },
1317 : { "remoteAddress", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &remoteAddress_getterinfo, nullptr, nullptr },
1318 : { "remotePort", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &remotePort_getterinfo, nullptr, nullptr },
1319 : { "addressReuse", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &addressReuse_getterinfo, nullptr, nullptr },
1320 : { "loopback", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &loopback_getterinfo, nullptr, nullptr },
1321 : { "readyState", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &readyState_getterinfo, nullptr, nullptr },
1322 : { "opened", JSPROP_SHARED | JSPROP_ENUMERATE, GenericPromiseReturningBindingGetter, &opened_getterinfo, nullptr, nullptr },
1323 : { "closed", JSPROP_SHARED | JSPROP_ENUMERATE, GenericPromiseReturningBindingGetter, &closed_getterinfo, nullptr, nullptr },
1324 : { "onmessage", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &onmessage_getterinfo, GenericBindingSetter, &onmessage_setterinfo },
1325 : { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
1326 : };
1327 : #if defined(__clang__)
1328 : #pragma clang diagnostic pop
1329 : #endif
1330 :
1331 :
1332 : // Can't be const because the pref-enabled boolean needs to be writable
1333 : static Prefable<const JSPropertySpec> sAttributes[] = {
1334 : { nullptr, &sAttributes_specs[0] },
1335 : { nullptr, nullptr }
1336 : };
1337 :
1338 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
1339 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
1340 : static_assert(10 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
1341 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
1342 :
1343 :
1344 : static uint16_t sNativeProperties_sortedPropertyIndices[14];
1345 : static PropertyInfo sNativeProperties_propertyInfos[14];
1346 :
1347 : static const NativePropertiesN<2> sNativeProperties = {
1348 : false, 0,
1349 : false, 0,
1350 : true, 0 /* sMethods */,
1351 : true, 1 /* sAttributes */,
1352 : false, 0,
1353 : false, 0,
1354 : false, 0,
1355 : -1,
1356 : 14,
1357 : sNativeProperties_sortedPropertyIndices,
1358 : {
1359 : { sMethods, &sNativeProperties_propertyInfos[0] },
1360 : { sAttributes, &sNativeProperties_propertyInfos[4] }
1361 : }
1362 : };
1363 : static_assert(14 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
1364 : "We have a property info count that is oversized");
1365 :
1366 : static bool
1367 0 : _constructor(JSContext* cx, unsigned argc, JS::Value* vp)
1368 : {
1369 0 : JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
1370 0 : JS::Rooted<JSObject*> obj(cx, &args.callee());
1371 0 : if (!args.isConstructing()) {
1372 : // XXXbz wish I could get the name from the callee instead of
1373 : // Adding more relocations
1374 0 : return ThrowConstructorWithoutNew(cx, "UDPSocket");
1375 : }
1376 :
1377 0 : GlobalObject global(cx, obj);
1378 0 : if (global.Failed()) {
1379 0 : return false;
1380 : }
1381 :
1382 0 : JS::Rooted<JSObject*> desiredProto(cx);
1383 0 : if (!GetDesiredProto(cx, args, &desiredProto)) {
1384 0 : return false;
1385 : }
1386 :
1387 0 : bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
1388 0 : binding_detail::FastUDPOptions arg0;
1389 0 : if (!arg0.Init(cx, (args.hasDefined(0)) ? args[0] : JS::NullHandleValue, "Argument 1 of UDPSocket.constructor", false)) {
1390 0 : return false;
1391 : }
1392 0 : Maybe<JSAutoCompartment> ac;
1393 0 : if (objIsXray) {
1394 0 : obj = js::CheckedUnwrap(obj);
1395 0 : if (!obj) {
1396 0 : return false;
1397 : }
1398 0 : ac.emplace(cx, obj);
1399 0 : if (!JS_WrapObject(cx, &desiredProto)) {
1400 0 : return false;
1401 : }
1402 : }
1403 0 : binding_detail::FastErrorResult rv;
1404 0 : auto result(StrongOrRawPtr<mozilla::dom::UDPSocket>(mozilla::dom::UDPSocket::Constructor(global, Constify(arg0), rv)));
1405 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
1406 0 : return false;
1407 : }
1408 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
1409 : static_assert(!IsPointer<decltype(result)>::value,
1410 : "NewObject implies that we need to keep the object alive with a strong reference.");
1411 0 : if (!GetOrCreateDOMReflector(cx, result, args.rval(), desiredProto)) {
1412 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
1413 0 : return false;
1414 : }
1415 0 : return true;
1416 : }
1417 :
1418 : static const js::ClassOps sInterfaceObjectClassOps = {
1419 : nullptr, /* addProperty */
1420 : nullptr, /* delProperty */
1421 : nullptr, /* getProperty */
1422 : nullptr, /* setProperty */
1423 : nullptr, /* enumerate */
1424 : nullptr, /* newEnumerate */
1425 : nullptr, /* resolve */
1426 : nullptr, /* mayResolve */
1427 : nullptr, /* finalize */
1428 : _constructor, /* call */
1429 : nullptr, /* hasInstance */
1430 : _constructor, /* construct */
1431 : nullptr, /* trace */
1432 : };
1433 :
1434 : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
1435 : {
1436 : "Function",
1437 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
1438 : &sInterfaceObjectClassOps,
1439 : JS_NULL_CLASS_SPEC,
1440 : JS_NULL_CLASS_EXT,
1441 : &sInterfaceObjectClassObjectOps
1442 : },
1443 : eInterface,
1444 : true,
1445 : prototypes::id::UDPSocket,
1446 : PrototypeTraits<prototypes::id::UDPSocket>::Depth,
1447 : sNativePropertyHooks,
1448 : "function UDPSocket() {\n [native code]\n}",
1449 : EventTargetBinding::GetConstructorObject
1450 : };
1451 :
1452 : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
1453 : {
1454 : "UDPSocketPrototype",
1455 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
1456 : JS_NULL_CLASS_OPS,
1457 : JS_NULL_CLASS_SPEC,
1458 : JS_NULL_CLASS_EXT,
1459 : JS_NULL_OBJECT_OPS
1460 : },
1461 : eInterfacePrototype,
1462 : false,
1463 : prototypes::id::UDPSocket,
1464 : PrototypeTraits<prototypes::id::UDPSocket>::Depth,
1465 : sNativePropertyHooks,
1466 : "[object UDPSocketPrototype]",
1467 : EventTargetBinding::GetProtoObject
1468 : };
1469 :
1470 : bool
1471 0 : ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
1472 : {
1473 : static bool sPrefValue;
1474 : static bool sPrefCacheSetUp = false;
1475 0 : if (!sPrefCacheSetUp) {
1476 0 : sPrefCacheSetUp = true;
1477 0 : Preferences::AddBoolVarCache(&sPrefValue, "dom.udpsocket.enabled");
1478 : }
1479 :
1480 0 : return sPrefValue &&
1481 0 : nsContentUtils::ThreadsafeIsSystemCaller(aCx);
1482 : }
1483 :
1484 : JSObject*
1485 0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
1486 : {
1487 0 : return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
1488 : }
1489 :
1490 : static const js::ClassOps sClassOps = {
1491 : _addProperty, /* addProperty */
1492 : nullptr, /* delProperty */
1493 : nullptr, /* getProperty */
1494 : nullptr, /* setProperty */
1495 : nullptr, /* enumerate */
1496 : nullptr, /* newEnumerate */
1497 : nullptr, /* resolve */
1498 : nullptr, /* mayResolve */
1499 : _finalize, /* finalize */
1500 : nullptr, /* call */
1501 : nullptr, /* hasInstance */
1502 : nullptr, /* construct */
1503 : nullptr, /* trace */
1504 : };
1505 :
1506 : static const js::ClassExtension sClassExtension = {
1507 : nullptr, /* weakmapKeyDelegateOp */
1508 : _objectMoved /* objectMovedOp */
1509 : };
1510 :
1511 : static const DOMJSClass sClass = {
1512 : { "UDPSocket",
1513 : JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
1514 : &sClassOps,
1515 : JS_NULL_CLASS_SPEC,
1516 : &sClassExtension,
1517 : JS_NULL_OBJECT_OPS
1518 : },
1519 : { prototypes::id::EventTarget, prototypes::id::UDPSocket, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
1520 : IsBaseOf<nsISupports, mozilla::dom::UDPSocket >::value,
1521 : sNativePropertyHooks,
1522 : FindAssociatedGlobalForNative<mozilla::dom::UDPSocket>::Get,
1523 : GetProtoObjectHandle,
1524 : GetCCParticipant<mozilla::dom::UDPSocket>::Get()
1525 : };
1526 : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
1527 : "Must have the right minimal number of reserved slots.");
1528 : static_assert(1 >= 1,
1529 : "Must have enough reserved slots.");
1530 :
1531 : const JSClass*
1532 0 : GetJSClass()
1533 : {
1534 0 : return sClass.ToJSClass();
1535 : }
1536 :
1537 : bool
1538 0 : Wrap(JSContext* aCx, mozilla::dom::UDPSocket* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
1539 : {
1540 : MOZ_ASSERT(static_cast<mozilla::dom::UDPSocket*>(aObject) ==
1541 : reinterpret_cast<mozilla::dom::UDPSocket*>(aObject),
1542 : "Multiple inheritance for mozilla::dom::UDPSocket is broken.");
1543 : MOZ_ASSERT(static_cast<mozilla::dom::EventTarget*>(aObject) ==
1544 : reinterpret_cast<mozilla::dom::EventTarget*>(aObject),
1545 : "Multiple inheritance for mozilla::dom::EventTarget is broken.");
1546 0 : MOZ_ASSERT(ToSupportsIsCorrect(aObject));
1547 0 : MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
1548 0 : MOZ_ASSERT(!aCache->GetWrapper(),
1549 : "You should probably not be using Wrap() directly; use "
1550 : "GetOrCreateDOMReflector instead");
1551 :
1552 0 : MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
1553 : "nsISupports must be on our primary inheritance chain");
1554 :
1555 0 : JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
1556 0 : if (!global) {
1557 0 : return false;
1558 : }
1559 0 : MOZ_ASSERT(JS_IsGlobalObject(global));
1560 0 : MOZ_ASSERT(JS::ObjectIsNotGray(global));
1561 :
1562 : // That might have ended up wrapping us already, due to the wonders
1563 : // of XBL. Check for that, and bail out as needed.
1564 0 : aReflector.set(aCache->GetWrapper());
1565 0 : if (aReflector) {
1566 : #ifdef DEBUG
1567 0 : binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
1568 : #endif // DEBUG
1569 0 : return true;
1570 : }
1571 :
1572 0 : JSAutoCompartment ac(aCx, global);
1573 0 : JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
1574 0 : if (!canonicalProto) {
1575 0 : return false;
1576 : }
1577 0 : JS::Rooted<JSObject*> proto(aCx);
1578 0 : if (aGivenProto) {
1579 0 : proto = aGivenProto;
1580 : // Unfortunately, while aGivenProto was in the compartment of aCx
1581 : // coming in, we changed compartments to that of "parent" so may need
1582 : // to wrap the proto here.
1583 0 : if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
1584 0 : if (!JS_WrapObject(aCx, &proto)) {
1585 0 : return false;
1586 : }
1587 : }
1588 : } else {
1589 0 : proto = canonicalProto;
1590 : }
1591 :
1592 0 : BindingJSObjectCreator<mozilla::dom::UDPSocket> creator(aCx);
1593 0 : creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
1594 0 : if (!aReflector) {
1595 0 : return false;
1596 : }
1597 :
1598 0 : aCache->SetWrapper(aReflector);
1599 0 : creator.InitializationSucceeded();
1600 :
1601 0 : MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
1602 : aCache->GetWrapperPreserveColor() == aReflector);
1603 : // If proto != canonicalProto, we have to preserve our wrapper;
1604 : // otherwise we won't be able to properly recreate it later, since
1605 : // we won't know what proto to use. Note that we don't check
1606 : // aGivenProto here, since it's entirely possible (and even
1607 : // somewhat common) to have a non-null aGivenProto which is the
1608 : // same as canonicalProto.
1609 0 : if (proto != canonicalProto) {
1610 0 : PreserveWrapper(aObject);
1611 : }
1612 :
1613 0 : return true;
1614 : }
1615 :
1616 : const NativePropertyHooks sNativePropertyHooks[] = { {
1617 : nullptr,
1618 : nullptr,
1619 : nullptr,
1620 : { sNativeProperties.Upcast(), nullptr },
1621 : prototypes::id::UDPSocket,
1622 : constructors::id::UDPSocket,
1623 : EventTargetBinding::sNativePropertyHooks,
1624 : &DefaultXrayExpandoObjectClass
1625 : } };
1626 :
1627 : void
1628 0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
1629 : {
1630 0 : JS::Handle<JSObject*> parentProto(EventTargetBinding::GetProtoObjectHandle(aCx));
1631 0 : if (!parentProto) {
1632 0 : return;
1633 : }
1634 :
1635 0 : JS::Handle<JSObject*> constructorProto(EventTargetBinding::GetConstructorObjectHandle(aCx));
1636 0 : if (!constructorProto) {
1637 0 : return;
1638 : }
1639 :
1640 : static bool sIdsInited = false;
1641 0 : if (!sIdsInited && NS_IsMainThread()) {
1642 0 : if (!InitIds(aCx, sNativeProperties.Upcast())) {
1643 0 : return;
1644 : }
1645 0 : sIdsInited = true;
1646 : }
1647 :
1648 0 : JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::UDPSocket);
1649 0 : JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::UDPSocket);
1650 0 : dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
1651 : &sPrototypeClass.mBase, protoCache,
1652 : constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
1653 : interfaceCache,
1654 : sNativeProperties.Upcast(),
1655 : nullptr,
1656 : "UDPSocket", aDefineOnGlobal,
1657 : nullptr,
1658 0 : false);
1659 : }
1660 :
1661 : JS::Handle<JSObject*>
1662 0 : GetProtoObjectHandle(JSContext* aCx)
1663 : {
1664 : /* Get the interface prototype object for this class. This will create the
1665 : object as needed. */
1666 0 : bool aDefineOnGlobal = true;
1667 :
1668 : /* Make sure our global is sane. Hopefully we can remove this sometime */
1669 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
1670 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
1671 0 : return nullptr;
1672 : }
1673 :
1674 : /* Check to see whether the interface objects are already installed */
1675 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
1676 0 : if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::UDPSocket)) {
1677 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
1678 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
1679 : }
1680 :
1681 : /*
1682 : * The object might _still_ be null, but that's OK.
1683 : *
1684 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
1685 : * traced by TraceProtoAndIfaceCache() and its contents are never
1686 : * changed after they have been set.
1687 : *
1688 : * Calling address() avoids the read read barrier that does gray
1689 : * unmarking, but it's not possible for the object to be gray here.
1690 : */
1691 :
1692 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::UDPSocket);
1693 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
1694 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
1695 : }
1696 :
1697 : JS::Handle<JSObject*>
1698 0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
1699 : {
1700 : /* Get the interface object for this class. This will create the object as
1701 : needed. */
1702 :
1703 : /* Make sure our global is sane. Hopefully we can remove this sometime */
1704 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
1705 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
1706 0 : return nullptr;
1707 : }
1708 :
1709 : /* Check to see whether the interface objects are already installed */
1710 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
1711 0 : if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::UDPSocket)) {
1712 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
1713 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
1714 : }
1715 :
1716 : /*
1717 : * The object might _still_ be null, but that's OK.
1718 : *
1719 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
1720 : * traced by TraceProtoAndIfaceCache() and its contents are never
1721 : * changed after they have been set.
1722 : *
1723 : * Calling address() avoids the read read barrier that does gray
1724 : * unmarking, but it's not possible for the object to be gray here.
1725 : */
1726 :
1727 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::UDPSocket);
1728 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
1729 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
1730 : }
1731 :
1732 : JSObject*
1733 0 : GetConstructorObject(JSContext* aCx)
1734 : {
1735 0 : return GetConstructorObjectHandle(aCx);
1736 : }
1737 :
1738 : } // namespace UDPSocketBinding
1739 :
1740 :
1741 :
1742 : } // namespace dom
1743 : } // namespace mozilla
|