Coverage Report

Created: 2018-09-25 14:53

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