Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dom/bindings/WebSocketBinding.cpp
Line
Count
Source (jump to first uncovered line)
1
/* THIS FILE IS AUTOGENERATED FROM WebSocket.webidl BY Codegen.py - DO NOT EDIT */
2
3
#include "EventHandlerBinding.h"
4
#include "EventTargetBinding.h"
5
#include "WebSocketBinding.h"
6
#include "WrapperFactory.h"
7
#include "jsapi.h"
8
#include "jsfriendapi.h"
9
#include "mozilla/OwningNonNull.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/TypedArray.h"
17
#include "mozilla/dom/WebSocket.h"
18
#include "mozilla/dom/XrayExpandoClass.h"
19
#include "nsContentUtils.h"
20
#include "nsITransportProvider.h"
21
22
namespace mozilla {
23
namespace dom {
24
25
namespace binding_detail {}; // Just to make sure it's known as a namespace
26
using namespace mozilla::dom::binding_detail;
27
28
29
namespace BinaryTypeValues {
30
extern const EnumEntry strings[3] = {
31
  {"blob", 4},
32
  {"arraybuffer", 11},
33
  { nullptr, 0 }
34
};
35
} // namespace BinaryTypeValues
36
37
bool
38
ToJSValue(JSContext* aCx, BinaryType aArgument, JS::MutableHandle<JS::Value> aValue)
39
0
{
40
0
  MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(BinaryTypeValues::strings));
41
0
  JSString* resultStr =
42
0
    JS_NewStringCopyN(aCx, BinaryTypeValues::strings[uint32_t(aArgument)].value,
43
0
                      BinaryTypeValues::strings[uint32_t(aArgument)].length);
44
0
  if (!resultStr) {
45
0
    return false;
46
0
  }
47
0
  aValue.setString(resultStr);
48
0
  return true;
49
0
}
50
51
52
namespace WebSocket_Binding {
53
54
static_assert(IsRefcounted<NativeType>::value == IsRefcounted<EventTarget_Binding::NativeType>::value,
55
              "Can't inherit from an interface with a different ownership model.");
56
57
MOZ_CAN_RUN_SCRIPT static bool
58
get_url(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::WebSocket* self, JSJitGetterCallArgs args)
59
0
{
60
0
  AUTO_PROFILER_LABEL_FAST("get WebSocket.url", DOM, cx);
61
0
62
0
  DOMString result;
63
0
  self->GetUrl(result);
64
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
65
0
  if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
66
0
    return false;
67
0
  }
68
0
  return true;
69
0
}
70
71
static const JSJitInfo url_getterinfo = {
72
  { (JSJitGetterOp)get_url },
73
  { prototypes::id::WebSocket },
74
  { PrototypeTraits<prototypes::id::WebSocket>::Depth },
75
  JSJitInfo::Getter,
76
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
77
  JSVAL_TYPE_STRING,  /* returnType.  Not relevant for setters. */
78
  false,  /* isInfallible. False in setters. */
79
  false,  /* isMovable.  Not relevant for setters. */
80
  false, /* isEliminatable.  Not relevant for setters. */
81
  false, /* isAlwaysInSlot.  Only relevant for getters. */
82
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
83
  false,  /* isTypedMethod.  Only relevant for methods. */
84
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
85
};
86
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
87
static_assert(0 < 1, "There is no slot for us");
88
89
MOZ_CAN_RUN_SCRIPT static bool
90
get_readyState(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::WebSocket* self, JSJitGetterCallArgs args)
91
0
{
92
0
  AUTO_PROFILER_LABEL_FAST("get WebSocket.readyState", DOM, cx);
93
0
94
0
  uint16_t result(self->ReadyState());
95
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
96
0
  args.rval().setInt32(int32_t(result));
97
0
  return true;
98
0
}
99
100
static const JSJitInfo readyState_getterinfo = {
101
  { (JSJitGetterOp)get_readyState },
102
  { prototypes::id::WebSocket },
103
  { PrototypeTraits<prototypes::id::WebSocket>::Depth },
104
  JSJitInfo::Getter,
105
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
106
  JSVAL_TYPE_INT32,  /* returnType.  Not relevant for setters. */
107
  true,  /* isInfallible. False in setters. */
108
  false,  /* isMovable.  Not relevant for setters. */
109
  false, /* isEliminatable.  Not relevant for setters. */
110
  false, /* isAlwaysInSlot.  Only relevant for getters. */
111
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
112
  false,  /* isTypedMethod.  Only relevant for methods. */
113
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
114
};
115
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
116
static_assert(0 < 1, "There is no slot for us");
117
118
MOZ_CAN_RUN_SCRIPT static bool
119
get_bufferedAmount(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::WebSocket* self, JSJitGetterCallArgs args)
120
0
{
121
0
  AUTO_PROFILER_LABEL_FAST("get WebSocket.bufferedAmount", DOM, cx);
122
0
123
0
  uint32_t result(self->BufferedAmount());
124
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
125
0
  args.rval().setNumber(result);
126
0
  return true;
127
0
}
128
129
static const JSJitInfo bufferedAmount_getterinfo = {
130
  { (JSJitGetterOp)get_bufferedAmount },
131
  { prototypes::id::WebSocket },
132
  { PrototypeTraits<prototypes::id::WebSocket>::Depth },
133
  JSJitInfo::Getter,
134
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
135
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
136
  true,  /* isInfallible. False in setters. */
137
  false,  /* isMovable.  Not relevant for setters. */
138
  false, /* isEliminatable.  Not relevant for setters. */
139
  false, /* isAlwaysInSlot.  Only relevant for getters. */
140
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
141
  false,  /* isTypedMethod.  Only relevant for methods. */
142
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
143
};
144
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
145
static_assert(0 < 1, "There is no slot for us");
146
147
MOZ_CAN_RUN_SCRIPT static bool
148
get_onopen(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::WebSocket* self, JSJitGetterCallArgs args)
149
0
{
150
0
  AUTO_PROFILER_LABEL_FAST("get WebSocket.onopen", DOM, cx);
151
0
152
0
  RefPtr<EventHandlerNonNull> result(self->GetOnopen());
153
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
154
0
  if (result) {
155
0
    args.rval().setObjectOrNull(GetCallbackFromCallbackObject(cx, result));
156
0
    if (!MaybeWrapObjectOrNullValue(cx, args.rval())) {
157
0
      return false;
158
0
    }
159
0
    return true;
160
0
  } else {
161
0
    args.rval().setNull();
162
0
    return true;
163
0
  }
164
0
}
165
166
MOZ_CAN_RUN_SCRIPT static bool
167
set_onopen(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::WebSocket* self, JSJitSetterCallArgs args)
168
0
{
169
0
  AUTO_PROFILER_LABEL_FAST("set WebSocket.onopen", DOM, cx);
170
0
171
0
  RootedCallback<RefPtr<binding_detail::FastEventHandlerNonNull>> arg0(cx);
172
0
  if (args[0].isObject()) {
173
0
    { // scope for tempRoot and tempGlobalRoot if needed
174
0
      arg0 = new binding_detail::FastEventHandlerNonNull(&args[0].toObject(), JS::CurrentGlobalOrNull(cx));
175
0
    }
176
0
  } else {
177
0
    arg0 = nullptr;
178
0
  }
179
0
  self->SetOnopen(Constify(arg0));
180
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
181
0
182
0
  return true;
183
0
}
184
185
static const JSJitInfo onopen_getterinfo = {
186
  { (JSJitGetterOp)get_onopen },
187
  { prototypes::id::WebSocket },
188
  { PrototypeTraits<prototypes::id::WebSocket>::Depth },
189
  JSJitInfo::Getter,
190
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
191
  JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
192
  false,  /* isInfallible. False in setters. */
193
  false,  /* isMovable.  Not relevant for setters. */
194
  false, /* isEliminatable.  Not relevant for setters. */
195
  false, /* isAlwaysInSlot.  Only relevant for getters. */
196
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
197
  false,  /* isTypedMethod.  Only relevant for methods. */
198
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
199
};
200
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
201
static_assert(0 < 1, "There is no slot for us");
202
static const JSJitInfo onopen_setterinfo = {
203
  { (JSJitGetterOp)set_onopen },
204
  { prototypes::id::WebSocket },
205
  { PrototypeTraits<prototypes::id::WebSocket>::Depth },
206
  JSJitInfo::Setter,
207
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
208
  JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
209
  false,  /* isInfallible. False in setters. */
210
  false,  /* isMovable.  Not relevant for setters. */
211
  false, /* isEliminatable.  Not relevant for setters. */
212
  false, /* isAlwaysInSlot.  Only relevant for getters. */
213
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
214
  false,  /* isTypedMethod.  Only relevant for methods. */
215
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
216
};
217
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
218
static_assert(0 < 1, "There is no slot for us");
219
220
MOZ_CAN_RUN_SCRIPT static bool
221
get_onerror(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::WebSocket* self, JSJitGetterCallArgs args)
222
0
{
223
0
  AUTO_PROFILER_LABEL_FAST("get WebSocket.onerror", DOM, cx);
224
0
225
0
  RefPtr<EventHandlerNonNull> result(self->GetOnerror());
226
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
227
0
  if (result) {
228
0
    args.rval().setObjectOrNull(GetCallbackFromCallbackObject(cx, result));
229
0
    if (!MaybeWrapObjectOrNullValue(cx, args.rval())) {
230
0
      return false;
231
0
    }
232
0
    return true;
233
0
  } else {
234
0
    args.rval().setNull();
235
0
    return true;
236
0
  }
237
0
}
238
239
MOZ_CAN_RUN_SCRIPT static bool
240
set_onerror(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::WebSocket* self, JSJitSetterCallArgs args)
241
0
{
242
0
  AUTO_PROFILER_LABEL_FAST("set WebSocket.onerror", DOM, cx);
243
0
244
0
  RootedCallback<RefPtr<binding_detail::FastEventHandlerNonNull>> arg0(cx);
245
0
  if (args[0].isObject()) {
246
0
    { // scope for tempRoot and tempGlobalRoot if needed
247
0
      arg0 = new binding_detail::FastEventHandlerNonNull(&args[0].toObject(), JS::CurrentGlobalOrNull(cx));
248
0
    }
249
0
  } else {
250
0
    arg0 = nullptr;
251
0
  }
252
0
  self->SetOnerror(Constify(arg0));
253
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
254
0
255
0
  return true;
256
0
}
257
258
static const JSJitInfo onerror_getterinfo = {
259
  { (JSJitGetterOp)get_onerror },
260
  { prototypes::id::WebSocket },
261
  { PrototypeTraits<prototypes::id::WebSocket>::Depth },
262
  JSJitInfo::Getter,
263
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
264
  JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
265
  false,  /* isInfallible. False in setters. */
266
  false,  /* isMovable.  Not relevant for setters. */
267
  false, /* isEliminatable.  Not relevant for setters. */
268
  false, /* isAlwaysInSlot.  Only relevant for getters. */
269
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
270
  false,  /* isTypedMethod.  Only relevant for methods. */
271
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
272
};
273
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
274
static_assert(0 < 1, "There is no slot for us");
275
static const JSJitInfo onerror_setterinfo = {
276
  { (JSJitGetterOp)set_onerror },
277
  { prototypes::id::WebSocket },
278
  { PrototypeTraits<prototypes::id::WebSocket>::Depth },
279
  JSJitInfo::Setter,
280
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
281
  JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
282
  false,  /* isInfallible. False in setters. */
283
  false,  /* isMovable.  Not relevant for setters. */
284
  false, /* isEliminatable.  Not relevant for setters. */
285
  false, /* isAlwaysInSlot.  Only relevant for getters. */
286
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
287
  false,  /* isTypedMethod.  Only relevant for methods. */
288
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
289
};
290
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
291
static_assert(0 < 1, "There is no slot for us");
292
293
MOZ_CAN_RUN_SCRIPT static bool
294
get_onclose(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::WebSocket* self, JSJitGetterCallArgs args)
295
0
{
296
0
  AUTO_PROFILER_LABEL_FAST("get WebSocket.onclose", DOM, cx);
297
0
298
0
  RefPtr<EventHandlerNonNull> result(self->GetOnclose());
299
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
300
0
  if (result) {
301
0
    args.rval().setObjectOrNull(GetCallbackFromCallbackObject(cx, result));
302
0
    if (!MaybeWrapObjectOrNullValue(cx, args.rval())) {
303
0
      return false;
304
0
    }
305
0
    return true;
306
0
  } else {
307
0
    args.rval().setNull();
308
0
    return true;
309
0
  }
310
0
}
311
312
MOZ_CAN_RUN_SCRIPT static bool
313
set_onclose(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::WebSocket* self, JSJitSetterCallArgs args)
314
0
{
315
0
  AUTO_PROFILER_LABEL_FAST("set WebSocket.onclose", DOM, cx);
316
0
317
0
  RootedCallback<RefPtr<binding_detail::FastEventHandlerNonNull>> arg0(cx);
318
0
  if (args[0].isObject()) {
319
0
    { // scope for tempRoot and tempGlobalRoot if needed
320
0
      arg0 = new binding_detail::FastEventHandlerNonNull(&args[0].toObject(), JS::CurrentGlobalOrNull(cx));
321
0
    }
322
0
  } else {
323
0
    arg0 = nullptr;
324
0
  }
325
0
  self->SetOnclose(Constify(arg0));
326
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
327
0
328
0
  return true;
329
0
}
330
331
static const JSJitInfo onclose_getterinfo = {
332
  { (JSJitGetterOp)get_onclose },
333
  { prototypes::id::WebSocket },
334
  { PrototypeTraits<prototypes::id::WebSocket>::Depth },
335
  JSJitInfo::Getter,
336
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
337
  JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
338
  false,  /* isInfallible. False in setters. */
339
  false,  /* isMovable.  Not relevant for setters. */
340
  false, /* isEliminatable.  Not relevant for setters. */
341
  false, /* isAlwaysInSlot.  Only relevant for getters. */
342
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
343
  false,  /* isTypedMethod.  Only relevant for methods. */
344
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
345
};
346
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
347
static_assert(0 < 1, "There is no slot for us");
348
static const JSJitInfo onclose_setterinfo = {
349
  { (JSJitGetterOp)set_onclose },
350
  { prototypes::id::WebSocket },
351
  { PrototypeTraits<prototypes::id::WebSocket>::Depth },
352
  JSJitInfo::Setter,
353
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
354
  JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
355
  false,  /* isInfallible. False in setters. */
356
  false,  /* isMovable.  Not relevant for setters. */
357
  false, /* isEliminatable.  Not relevant for setters. */
358
  false, /* isAlwaysInSlot.  Only relevant for getters. */
359
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
360
  false,  /* isTypedMethod.  Only relevant for methods. */
361
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
362
};
363
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
364
static_assert(0 < 1, "There is no slot for us");
365
366
MOZ_CAN_RUN_SCRIPT static bool
367
get_extensions(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::WebSocket* self, JSJitGetterCallArgs args)
368
0
{
369
0
  AUTO_PROFILER_LABEL_FAST("get WebSocket.extensions", DOM, cx);
370
0
371
0
  DOMString result;
372
0
  self->GetExtensions(result);
373
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
374
0
  if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
375
0
    return false;
376
0
  }
377
0
  return true;
378
0
}
379
380
static const JSJitInfo extensions_getterinfo = {
381
  { (JSJitGetterOp)get_extensions },
382
  { prototypes::id::WebSocket },
383
  { PrototypeTraits<prototypes::id::WebSocket>::Depth },
384
  JSJitInfo::Getter,
385
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
386
  JSVAL_TYPE_STRING,  /* returnType.  Not relevant for setters. */
387
  false,  /* isInfallible. False in setters. */
388
  false,  /* isMovable.  Not relevant for setters. */
389
  false, /* isEliminatable.  Not relevant for setters. */
390
  false, /* isAlwaysInSlot.  Only relevant for getters. */
391
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
392
  false,  /* isTypedMethod.  Only relevant for methods. */
393
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
394
};
395
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
396
static_assert(0 < 1, "There is no slot for us");
397
398
MOZ_CAN_RUN_SCRIPT static bool
399
get_protocol(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::WebSocket* self, JSJitGetterCallArgs args)
400
0
{
401
0
  AUTO_PROFILER_LABEL_FAST("get WebSocket.protocol", DOM, cx);
402
0
403
0
  DOMString result;
404
0
  self->GetProtocol(result);
405
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
406
0
  if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
407
0
    return false;
408
0
  }
409
0
  return true;
410
0
}
411
412
static const JSJitInfo protocol_getterinfo = {
413
  { (JSJitGetterOp)get_protocol },
414
  { prototypes::id::WebSocket },
415
  { PrototypeTraits<prototypes::id::WebSocket>::Depth },
416
  JSJitInfo::Getter,
417
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
418
  JSVAL_TYPE_STRING,  /* returnType.  Not relevant for setters. */
419
  false,  /* isInfallible. False in setters. */
420
  false,  /* isMovable.  Not relevant for setters. */
421
  false, /* isEliminatable.  Not relevant for setters. */
422
  false, /* isAlwaysInSlot.  Only relevant for getters. */
423
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
424
  false,  /* isTypedMethod.  Only relevant for methods. */
425
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
426
};
427
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
428
static_assert(0 < 1, "There is no slot for us");
429
430
MOZ_CAN_RUN_SCRIPT static bool
431
close(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::WebSocket* self, const JSJitMethodCallArgs& args)
432
0
{
433
0
  AUTO_PROFILER_LABEL_FAST("WebSocket.close", DOM, cx);
434
0
435
0
  Optional<uint16_t> arg0;
436
0
  if (args.hasDefined(0)) {
437
0
    arg0.Construct();
438
0
    if (!ValueToPrimitive<uint16_t, eClamp>(cx, args[0], &arg0.Value())) {
439
0
      return false;
440
0
    }
441
0
  }
442
0
  Optional<nsAString> arg1;
443
0
  binding_detail::FakeString arg1_holder;
444
0
  if (args.hasDefined(1)) {
445
0
    if (!ConvertJSValueToString(cx, args[1], eStringify, eStringify, arg1_holder)) {
446
0
      return false;
447
0
    }
448
0
    arg1 = &arg1_holder;
449
0
  }
450
0
  FastErrorResult rv;
451
0
  self->Close(Constify(arg0), NonNullHelper(Constify(arg1)), rv);
452
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
453
0
    return false;
454
0
  }
455
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
456
0
  args.rval().setUndefined();
457
0
  return true;
458
0
}
459
460
static const JSJitInfo close_methodinfo = {
461
  { (JSJitGetterOp)close },
462
  { prototypes::id::WebSocket },
463
  { PrototypeTraits<prototypes::id::WebSocket>::Depth },
464
  JSJitInfo::Method,
465
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
466
  JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
467
  false,  /* isInfallible. False in setters. */
468
  false,  /* isMovable.  Not relevant for setters. */
469
  false, /* isEliminatable.  Not relevant for setters. */
470
  false, /* isAlwaysInSlot.  Only relevant for getters. */
471
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
472
  false,  /* isTypedMethod.  Only relevant for methods. */
473
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
474
};
475
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
476
static_assert(0 < 1, "There is no slot for us");
477
478
MOZ_CAN_RUN_SCRIPT static bool
479
get_onmessage(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::WebSocket* self, JSJitGetterCallArgs args)
480
0
{
481
0
  AUTO_PROFILER_LABEL_FAST("get WebSocket.onmessage", DOM, cx);
482
0
483
0
  RefPtr<EventHandlerNonNull> result(self->GetOnmessage());
484
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
485
0
  if (result) {
486
0
    args.rval().setObjectOrNull(GetCallbackFromCallbackObject(cx, result));
487
0
    if (!MaybeWrapObjectOrNullValue(cx, args.rval())) {
488
0
      return false;
489
0
    }
490
0
    return true;
491
0
  } else {
492
0
    args.rval().setNull();
493
0
    return true;
494
0
  }
495
0
}
496
497
MOZ_CAN_RUN_SCRIPT static bool
498
set_onmessage(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::WebSocket* self, JSJitSetterCallArgs args)
499
0
{
500
0
  AUTO_PROFILER_LABEL_FAST("set WebSocket.onmessage", DOM, cx);
501
0
502
0
  RootedCallback<RefPtr<binding_detail::FastEventHandlerNonNull>> arg0(cx);
503
0
  if (args[0].isObject()) {
504
0
    { // scope for tempRoot and tempGlobalRoot if needed
505
0
      arg0 = new binding_detail::FastEventHandlerNonNull(&args[0].toObject(), JS::CurrentGlobalOrNull(cx));
506
0
    }
507
0
  } else {
508
0
    arg0 = nullptr;
509
0
  }
510
0
  self->SetOnmessage(Constify(arg0));
511
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
512
0
513
0
  return true;
514
0
}
515
516
static const JSJitInfo onmessage_getterinfo = {
517
  { (JSJitGetterOp)get_onmessage },
518
  { prototypes::id::WebSocket },
519
  { PrototypeTraits<prototypes::id::WebSocket>::Depth },
520
  JSJitInfo::Getter,
521
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
522
  JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
523
  false,  /* isInfallible. False in setters. */
524
  false,  /* isMovable.  Not relevant for setters. */
525
  false, /* isEliminatable.  Not relevant for setters. */
526
  false, /* isAlwaysInSlot.  Only relevant for getters. */
527
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
528
  false,  /* isTypedMethod.  Only relevant for methods. */
529
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
530
};
531
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
532
static_assert(0 < 1, "There is no slot for us");
533
static const JSJitInfo onmessage_setterinfo = {
534
  { (JSJitGetterOp)set_onmessage },
535
  { prototypes::id::WebSocket },
536
  { PrototypeTraits<prototypes::id::WebSocket>::Depth },
537
  JSJitInfo::Setter,
538
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
539
  JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
540
  false,  /* isInfallible. False in setters. */
541
  false,  /* isMovable.  Not relevant for setters. */
542
  false, /* isEliminatable.  Not relevant for setters. */
543
  false, /* isAlwaysInSlot.  Only relevant for getters. */
544
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
545
  false,  /* isTypedMethod.  Only relevant for methods. */
546
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
547
};
548
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
549
static_assert(0 < 1, "There is no slot for us");
550
551
MOZ_CAN_RUN_SCRIPT static bool
552
get_binaryType(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::WebSocket* self, JSJitGetterCallArgs args)
553
0
{
554
0
  AUTO_PROFILER_LABEL_FAST("get WebSocket.binaryType", DOM, cx);
555
0
556
0
  BinaryType result(self->BinaryType());
557
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
558
0
  if (!ToJSValue(cx, result, args.rval())) {
559
0
    return false;
560
0
  }
561
0
  return true;
562
0
}
563
564
MOZ_CAN_RUN_SCRIPT static bool
565
set_binaryType(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::WebSocket* self, JSJitSetterCallArgs args)
566
0
{
567
0
  AUTO_PROFILER_LABEL_FAST("set WebSocket.binaryType", DOM, cx);
568
0
569
0
  BinaryType arg0;
570
0
  {
571
0
    int index;
572
0
    if (!FindEnumStringIndex<false>(cx, args[0], BinaryTypeValues::strings, "BinaryType", "Value being assigned to WebSocket.binaryType", &index)) {
573
0
      return false;
574
0
    }
575
0
    if (index < 0) {
576
0
      return true;
577
0
    }
578
0
    arg0 = static_cast<BinaryType>(index);
579
0
  }
580
0
  self->SetBinaryType(arg0);
581
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
582
0
583
0
  return true;
584
0
}
585
586
static const JSJitInfo binaryType_getterinfo = {
587
  { (JSJitGetterOp)get_binaryType },
588
  { prototypes::id::WebSocket },
589
  { PrototypeTraits<prototypes::id::WebSocket>::Depth },
590
  JSJitInfo::Getter,
591
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
592
  JSVAL_TYPE_STRING,  /* returnType.  Not relevant for setters. */
593
  false,  /* isInfallible. False in setters. */
594
  false,  /* isMovable.  Not relevant for setters. */
595
  false, /* isEliminatable.  Not relevant for setters. */
596
  false, /* isAlwaysInSlot.  Only relevant for getters. */
597
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
598
  false,  /* isTypedMethod.  Only relevant for methods. */
599
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
600
};
601
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
602
static_assert(0 < 1, "There is no slot for us");
603
static const JSJitInfo binaryType_setterinfo = {
604
  { (JSJitGetterOp)set_binaryType },
605
  { prototypes::id::WebSocket },
606
  { PrototypeTraits<prototypes::id::WebSocket>::Depth },
607
  JSJitInfo::Setter,
608
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
609
  JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
610
  false,  /* isInfallible. False in setters. */
611
  false,  /* isMovable.  Not relevant for setters. */
612
  false, /* isEliminatable.  Not relevant for setters. */
613
  false, /* isAlwaysInSlot.  Only relevant for getters. */
614
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
615
  false,  /* isTypedMethod.  Only relevant for methods. */
616
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
617
};
618
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
619
static_assert(0 < 1, "There is no slot for us");
620
621
MOZ_CAN_RUN_SCRIPT static bool
622
send(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::WebSocket* self, const JSJitMethodCallArgs& args)
623
0
{
624
0
  AUTO_PROFILER_LABEL_FAST("WebSocket.send", DOM, cx);
625
0
626
0
  unsigned argcount = std::min(args.length(), 1u);
627
0
  switch (argcount) {
628
0
    case 1: {
629
0
      if (args[0].isObject()) {
630
0
        do {
631
0
          NonNull<mozilla::dom::Blob> arg0;
632
0
          {
633
0
            nsresult rv = UnwrapObject<prototypes::id::Blob, mozilla::dom::Blob>(args[0], arg0);
634
0
            if (NS_FAILED(rv)) {
635
0
              break;
636
0
            }
637
0
          }
638
0
          FastErrorResult rv;
639
0
          self->Send(MOZ_KnownLive(NonNullHelper(arg0)), rv);
640
0
          if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
641
0
            return false;
642
0
          }
643
0
          MOZ_ASSERT(!JS_IsExceptionPending(cx));
644
0
          args.rval().setUndefined();
645
0
          return true;
646
0
        } while (false);
647
0
        do {
648
0
          RootedSpiderMonkeyInterface<ArrayBuffer> arg0(cx);
649
0
          if (!arg0.Init(&args[0].toObject())) {
650
0
            break;
651
0
          }
652
0
          FastErrorResult rv;
653
0
          self->Send(Constify(arg0), rv);
654
0
          if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
655
0
            return false;
656
0
          }
657
0
          MOZ_ASSERT(!JS_IsExceptionPending(cx));
658
0
          args.rval().setUndefined();
659
0
          return true;
660
0
        } while (false);
661
0
        do {
662
0
          RootedSpiderMonkeyInterface<ArrayBufferView> arg0(cx);
663
0
          if (!arg0.Init(&args[0].toObject())) {
664
0
            break;
665
0
          }
666
0
          FastErrorResult rv;
667
0
          self->Send(Constify(arg0), rv);
668
0
          if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
669
0
            return false;
670
0
          }
671
0
          MOZ_ASSERT(!JS_IsExceptionPending(cx));
672
0
          args.rval().setUndefined();
673
0
          return true;
674
0
        } while (false);
675
0
      }
676
0
      binding_detail::FakeString arg0;
677
0
      if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
678
0
        return false;
679
0
      }
680
0
      FastErrorResult rv;
681
0
      self->Send(NonNullHelper(Constify(arg0)), rv);
682
0
      if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
683
0
        return false;
684
0
      }
685
0
      MOZ_ASSERT(!JS_IsExceptionPending(cx));
686
0
      args.rval().setUndefined();
687
0
      return true;
688
0
      break;
689
0
    }
690
0
    default: {
691
0
      return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "WebSocket.send");
692
0
      break;
693
0
    }
694
0
  }
695
0
  MOZ_CRASH("We have an always-returning default case");
696
0
  return false;
697
0
}
698
699
static const JSJitInfo send_methodinfo = {
700
  { (JSJitGetterOp)send },
701
  { prototypes::id::WebSocket },
702
  { PrototypeTraits<prototypes::id::WebSocket>::Depth },
703
  JSJitInfo::Method,
704
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
705
  JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
706
  false,  /* isInfallible. False in setters. */
707
  false,  /* isMovable.  Not relevant for setters. */
708
  false, /* isEliminatable.  Not relevant for setters. */
709
  false, /* isAlwaysInSlot.  Only relevant for getters. */
710
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
711
  false,  /* isTypedMethod.  Only relevant for methods. */
712
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
713
};
714
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
715
static_assert(0 < 1, "There is no slot for us");
716
717
static bool
718
createServerWebSocket(JSContext* cx, unsigned argc, JS::Value* vp)
719
0
{
720
0
  AUTO_PROFILER_LABEL_FAST("WebSocket.createServerWebSocket", DOM, cx);
721
0
722
0
  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
723
0
  JS::Rooted<JSObject*> obj(cx, &args.callee());
724
0
725
0
  if (MOZ_UNLIKELY(args.length() < 4)) {
726
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "WebSocket.createServerWebSocket");
727
0
  }
728
0
  GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
729
0
  if (global.Failed()) {
730
0
    return false;
731
0
  }
732
0
733
0
  binding_detail::FakeString arg0;
734
0
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
735
0
    return false;
736
0
  }
737
0
  binding_detail::AutoSequence<nsString> arg1;
738
0
  if (args[1].isObject()) {
739
0
    JS::ForOfIterator iter(cx);
740
0
    if (!iter.init(args[1], JS::ForOfIterator::AllowNonIterable)) {
741
0
      return false;
742
0
    }
743
0
    if (!iter.valueIsIterable()) {
744
0
      ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "Argument 2 of WebSocket.createServerWebSocket");
745
0
      return false;
746
0
    }
747
0
    binding_detail::AutoSequence<nsString> &arr = arg1;
748
0
    JS::Rooted<JS::Value> temp(cx);
749
0
    while (true) {
750
0
      bool done;
751
0
      if (!iter.next(&temp, &done)) {
752
0
        return false;
753
0
      }
754
0
      if (done) {
755
0
        break;
756
0
      }
757
0
      nsString* slotPtr = arr.AppendElement(mozilla::fallible);
758
0
      if (!slotPtr) {
759
0
        JS_ReportOutOfMemory(cx);
760
0
        return false;
761
0
      }
762
0
      nsString& slot = *slotPtr;
763
0
      if (!ConvertJSValueToString(cx, temp, eStringify, eStringify, slot)) {
764
0
        return false;
765
0
      }
766
0
    }
767
0
  } else {
768
0
    ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "Argument 2 of WebSocket.createServerWebSocket");
769
0
    return false;
770
0
  }
771
0
  nsITransportProvider* arg2;
772
0
  RefPtr<nsITransportProvider> arg2_holder;
773
0
  if (args[2].isObject()) {
774
0
    JS::Rooted<JSObject*> source(cx, &args[2].toObject());
775
0
    if (NS_FAILED(UnwrapArg<nsITransportProvider>(cx, source, getter_AddRefs(arg2_holder)))) {
776
0
      ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Argument 3 of WebSocket.createServerWebSocket", "nsITransportProvider");
777
0
      return false;
778
0
    }
779
0
    MOZ_ASSERT(arg2_holder);
780
0
    arg2 = arg2_holder;
781
0
  } else {
782
0
    ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 3 of WebSocket.createServerWebSocket");
783
0
    return false;
784
0
  }
785
0
  binding_detail::FakeString arg3;
786
0
  if (!ConvertJSValueToString(cx, args[3], eStringify, eStringify, arg3)) {
787
0
    return false;
788
0
  }
789
0
  FastErrorResult rv;
790
0
  auto result(StrongOrRawPtr<mozilla::dom::WebSocket>(mozilla::dom::WebSocket::CreateServerWebSocket(global, NonNullHelper(Constify(arg0)), Constify(arg1), MOZ_KnownLive(NonNullHelper(arg2)), NonNullHelper(Constify(arg3)), rv)));
791
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
792
0
    return false;
793
0
  }
794
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
795
0
  static_assert(!IsPointer<decltype(result)>::value,
796
0
                "NewObject implies that we need to keep the object alive with a strong reference.");
797
0
  if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
798
0
    MOZ_ASSERT(JS_IsExceptionPending(cx));
799
0
    return false;
800
0
  }
801
0
  return true;
802
0
}
803
804
static bool
805
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
806
0
{
807
0
  mozilla::dom::WebSocket* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::WebSocket>(obj);
808
0
  // We don't want to preserve if we don't have a wrapper, and we
809
0
  // obviously can't preserve if we're not initialized.
810
0
  if (self && self->GetWrapperPreserveColor()) {
811
0
    PreserveWrapper(self);
812
0
  }
813
0
  return true;
814
0
}
815
816
static void
817
_finalize(js::FreeOp* fop, JSObject* obj)
818
0
{
819
0
  mozilla::dom::WebSocket* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::WebSocket>(obj);
820
0
  if (self) {
821
0
    ClearWrapper(self, self, obj);
822
0
    AddForDeferredFinalization<mozilla::dom::WebSocket>(self);
823
0
  }
824
0
}
825
826
static size_t
827
_objectMoved(JSObject* obj, JSObject* old)
828
0
{
829
0
  mozilla::dom::WebSocket* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::WebSocket>(obj);
830
0
  if (self) {
831
0
    UpdateWrapper(self, self, obj, old);
832
0
  }
833
0
834
0
  return 0;
835
0
}
836
837
// We deliberately use brace-elision to make Visual Studio produce better initalization code.
838
#if defined(__clang__)
839
#pragma clang diagnostic push
840
#pragma clang diagnostic ignored "-Wmissing-braces"
841
#endif
842
static const JSFunctionSpec sChromeStaticMethods_specs[] = {
843
  JS_FNSPEC("createServerWebSocket", createServerWebSocket, nullptr, 4, JSPROP_ENUMERATE, nullptr),
844
  JS_FS_END
845
};
846
#if defined(__clang__)
847
#pragma clang diagnostic pop
848
#endif
849
850
851
static const Prefable<const JSFunctionSpec> sChromeStaticMethods[] = {
852
  { nullptr, &sChromeStaticMethods_specs[0] },
853
  { nullptr, nullptr }
854
};
855
856
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
857
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
858
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
859
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
860
861
// We deliberately use brace-elision to make Visual Studio produce better initalization code.
862
#if defined(__clang__)
863
#pragma clang diagnostic push
864
#pragma clang diagnostic ignored "-Wmissing-braces"
865
#endif
866
static const JSFunctionSpec sMethods_specs[] = {
867
  JS_FNSPEC("close", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&close_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
868
  JS_FNSPEC("send", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&send_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
869
  JS_FS_END
870
};
871
#if defined(__clang__)
872
#pragma clang diagnostic pop
873
#endif
874
875
876
static const Prefable<const JSFunctionSpec> sMethods[] = {
877
  { nullptr, &sMethods_specs[0] },
878
  { nullptr, nullptr }
879
};
880
881
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
882
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
883
static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
884
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
885
886
// We deliberately use brace-elision to make Visual Studio produce better initalization code.
887
#if defined(__clang__)
888
#pragma clang diagnostic push
889
#pragma clang diagnostic ignored "-Wmissing-braces"
890
#endif
891
static const JSPropertySpec sAttributes_specs[] = {
892
  { "url", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &url_getterinfo, nullptr, nullptr },
893
  { "readyState", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &readyState_getterinfo, nullptr, nullptr },
894
  { "bufferedAmount", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &bufferedAmount_getterinfo, nullptr, nullptr },
895
  { "onopen", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &onopen_getterinfo, GenericSetter<NormalThisPolicy>, &onopen_setterinfo },
896
  { "onerror", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &onerror_getterinfo, GenericSetter<NormalThisPolicy>, &onerror_setterinfo },
897
  { "onclose", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &onclose_getterinfo, GenericSetter<NormalThisPolicy>, &onclose_setterinfo },
898
  { "extensions", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &extensions_getterinfo, nullptr, nullptr },
899
  { "protocol", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &protocol_getterinfo, nullptr, nullptr },
900
  { "onmessage", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &onmessage_getterinfo, GenericSetter<NormalThisPolicy>, &onmessage_setterinfo },
901
  { "binaryType", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &binaryType_getterinfo, GenericSetter<NormalThisPolicy>, &binaryType_setterinfo },
902
  { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
903
};
904
#if defined(__clang__)
905
#pragma clang diagnostic pop
906
#endif
907
908
909
static const Prefable<const JSPropertySpec> sAttributes[] = {
910
  { nullptr, &sAttributes_specs[0] },
911
  { nullptr, nullptr }
912
};
913
914
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
915
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
916
static_assert(10 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
917
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
918
919
// We deliberately use brace-elision to make Visual Studio produce better initalization code.
920
#if defined(__clang__)
921
#pragma clang diagnostic push
922
#pragma clang diagnostic ignored "-Wmissing-braces"
923
#endif
924
static const ConstantSpec sConstants_specs[] = {
925
  { "CONNECTING", JS::Int32Value(0) },
926
  { "OPEN", JS::Int32Value(1) },
927
  { "CLOSING", JS::Int32Value(2) },
928
  { "CLOSED", JS::Int32Value(3) },
929
  { 0, JS::UndefinedValue() }
930
};
931
#if defined(__clang__)
932
#pragma clang diagnostic pop
933
#endif
934
935
936
static const Prefable<const ConstantSpec> sConstants[] = {
937
  { nullptr, &sConstants_specs[0] },
938
  { nullptr, nullptr }
939
};
940
941
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
942
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
943
static_assert(4 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
944
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
945
946
947
static uint16_t sNativeProperties_sortedPropertyIndices[16];
948
static PropertyInfo sNativeProperties_propertyInfos[16];
949
950
static const NativePropertiesN<3> sNativeProperties = {
951
  false, 0,
952
  false, 0,
953
  true,  0 /* sMethods */,
954
  true,  1 /* sAttributes */,
955
  false, 0,
956
  false, 0,
957
  true,  2 /* sConstants */,
958
  -1,
959
  16,
960
  sNativeProperties_sortedPropertyIndices,
961
  {
962
    { sMethods, &sNativeProperties_propertyInfos[0] },
963
    { sAttributes, &sNativeProperties_propertyInfos[2] },
964
    { sConstants, &sNativeProperties_propertyInfos[12] }
965
  }
966
};
967
static_assert(16 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
968
    "We have a property info count that is oversized");
969
970
static uint16_t sChromeOnlyNativeProperties_sortedPropertyIndices[1];
971
static PropertyInfo sChromeOnlyNativeProperties_propertyInfos[1];
972
973
static const NativePropertiesN<1> sChromeOnlyNativeProperties = {
974
  true,  0 /* sChromeStaticMethods */,
975
  false, 0,
976
  false, 0,
977
  false, 0,
978
  false, 0,
979
  false, 0,
980
  false, 0,
981
  -1,
982
  1,
983
  sChromeOnlyNativeProperties_sortedPropertyIndices,
984
  {
985
    { sChromeStaticMethods, &sChromeOnlyNativeProperties_propertyInfos[0] }
986
  }
987
};
988
static_assert(1 < 1ull << CHAR_BIT * sizeof(sChromeOnlyNativeProperties.propertyInfoCount),
989
    "We have a property info count that is oversized");
990
991
static bool
992
_constructor(JSContext* cx, unsigned argc, JS::Value* vp)
993
0
{
994
0
  AUTO_PROFILER_LABEL_FAST("WebSocket constructor", DOM, cx);
995
0
996
0
  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
997
0
  JS::Rooted<JSObject*> obj(cx, &args.callee());
998
0
  if (!args.isConstructing()) {
999
0
    // XXXbz wish I could get the name from the callee instead of
1000
0
    // Adding more relocations
1001
0
    return ThrowConstructorWithoutNew(cx, "WebSocket");
1002
0
  }
1003
0
1004
0
  JS::Rooted<JSObject*> desiredProto(cx);
1005
0
  if (!GetDesiredProto(cx, args, &desiredProto)) {
1006
0
    return false;
1007
0
  }
1008
0
1009
0
  unsigned argcount = std::min(args.length(), 2u);
1010
0
  switch (argcount) {
1011
0
    case 1: {
1012
0
      GlobalObject global(cx, obj);
1013
0
      if (global.Failed()) {
1014
0
        return false;
1015
0
      }
1016
0
1017
0
      bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
1018
0
      binding_detail::FakeString arg0;
1019
0
      if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
1020
0
        return false;
1021
0
      }
1022
0
      Maybe<JSAutoRealm> ar;
1023
0
      if (objIsXray) {
1024
0
        obj = js::CheckedUnwrap(obj);
1025
0
        if (!obj) {
1026
0
          return false;
1027
0
        }
1028
0
        ar.emplace(cx, obj);
1029
0
        if (!JS_WrapObject(cx, &desiredProto)) {
1030
0
          return false;
1031
0
        }
1032
0
      }
1033
0
      FastErrorResult rv;
1034
0
      auto result(StrongOrRawPtr<mozilla::dom::WebSocket>(mozilla::dom::WebSocket::Constructor(global, NonNullHelper(Constify(arg0)), rv)));
1035
0
      if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
1036
0
        return false;
1037
0
      }
1038
0
      MOZ_ASSERT(!JS_IsExceptionPending(cx));
1039
0
      static_assert(!IsPointer<decltype(result)>::value,
1040
0
                    "NewObject implies that we need to keep the object alive with a strong reference.");
1041
0
      if (!GetOrCreateDOMReflector(cx, result, args.rval(), desiredProto)) {
1042
0
        MOZ_ASSERT(JS_IsExceptionPending(cx));
1043
0
        return false;
1044
0
      }
1045
0
      return true;
1046
0
      break;
1047
0
    }
1048
0
    case 2: {
1049
0
      binding_detail::FakeString arg0;
1050
0
      if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
1051
0
        return false;
1052
0
      }
1053
0
      if (args[1].isObject()) {
1054
0
        do {
1055
0
          binding_detail::AutoSequence<nsString> arg1;
1056
0
          JS::ForOfIterator iter(cx);
1057
0
          if (!iter.init(args[1], JS::ForOfIterator::AllowNonIterable)) {
1058
0
            return false;
1059
0
          }
1060
0
          if (!iter.valueIsIterable()) {
1061
0
            break;
1062
0
          }
1063
0
          binding_detail::AutoSequence<nsString> &arr = arg1;
1064
0
          JS::Rooted<JS::Value> temp(cx);
1065
0
          while (true) {
1066
0
            bool done;
1067
0
            if (!iter.next(&temp, &done)) {
1068
0
              return false;
1069
0
            }
1070
0
            if (done) {
1071
0
              break;
1072
0
            }
1073
0
            nsString* slotPtr = arr.AppendElement(mozilla::fallible);
1074
0
            if (!slotPtr) {
1075
0
              JS_ReportOutOfMemory(cx);
1076
0
              return false;
1077
0
            }
1078
0
            nsString& slot = *slotPtr;
1079
0
            if (!ConvertJSValueToString(cx, temp, eStringify, eStringify, slot)) {
1080
0
              return false;
1081
0
            }
1082
0
          }
1083
0
          GlobalObject global(cx, obj);
1084
0
          if (global.Failed()) {
1085
0
            return false;
1086
0
          }
1087
0
1088
0
          bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
1089
0
          Maybe<JSAutoRealm> ar;
1090
0
          if (objIsXray) {
1091
0
            obj = js::CheckedUnwrap(obj);
1092
0
            if (!obj) {
1093
0
              return false;
1094
0
            }
1095
0
            ar.emplace(cx, obj);
1096
0
            if (!JS_WrapObject(cx, &desiredProto)) {
1097
0
              return false;
1098
0
            }
1099
0
          }
1100
0
          FastErrorResult rv;
1101
0
          auto result(StrongOrRawPtr<mozilla::dom::WebSocket>(mozilla::dom::WebSocket::Constructor(global, NonNullHelper(Constify(arg0)), Constify(arg1), rv)));
1102
0
          if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
1103
0
            return false;
1104
0
          }
1105
0
          MOZ_ASSERT(!JS_IsExceptionPending(cx));
1106
0
          static_assert(!IsPointer<decltype(result)>::value,
1107
0
                        "NewObject implies that we need to keep the object alive with a strong reference.");
1108
0
          if (!GetOrCreateDOMReflector(cx, result, args.rval(), desiredProto)) {
1109
0
            MOZ_ASSERT(JS_IsExceptionPending(cx));
1110
0
            return false;
1111
0
          }
1112
0
          return true;
1113
0
        } while (false);
1114
0
      }
1115
0
      GlobalObject global(cx, obj);
1116
0
      if (global.Failed()) {
1117
0
        return false;
1118
0
      }
1119
0
1120
0
      bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
1121
0
      binding_detail::FakeString arg1;
1122
0
      if (!ConvertJSValueToString(cx, args[1], eStringify, eStringify, arg1)) {
1123
0
        return false;
1124
0
      }
1125
0
      Maybe<JSAutoRealm> ar;
1126
0
      if (objIsXray) {
1127
0
        obj = js::CheckedUnwrap(obj);
1128
0
        if (!obj) {
1129
0
          return false;
1130
0
        }
1131
0
        ar.emplace(cx, obj);
1132
0
        if (!JS_WrapObject(cx, &desiredProto)) {
1133
0
          return false;
1134
0
        }
1135
0
      }
1136
0
      FastErrorResult rv;
1137
0
      auto result(StrongOrRawPtr<mozilla::dom::WebSocket>(mozilla::dom::WebSocket::Constructor(global, NonNullHelper(Constify(arg0)), NonNullHelper(Constify(arg1)), rv)));
1138
0
      if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
1139
0
        return false;
1140
0
      }
1141
0
      MOZ_ASSERT(!JS_IsExceptionPending(cx));
1142
0
      static_assert(!IsPointer<decltype(result)>::value,
1143
0
                    "NewObject implies that we need to keep the object alive with a strong reference.");
1144
0
      if (!GetOrCreateDOMReflector(cx, result, args.rval(), desiredProto)) {
1145
0
        MOZ_ASSERT(JS_IsExceptionPending(cx));
1146
0
        return false;
1147
0
      }
1148
0
      return true;
1149
0
      break;
1150
0
    }
1151
0
    default: {
1152
0
      return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "WebSocket");
1153
0
      break;
1154
0
    }
1155
0
  }
1156
0
  MOZ_CRASH("We have an always-returning default case");
1157
0
  return false;
1158
0
}
1159
1160
static const js::ClassOps sInterfaceObjectClassOps = {
1161
    nullptr,               /* addProperty */
1162
    nullptr,               /* delProperty */
1163
    nullptr,               /* enumerate */
1164
    nullptr,               /* newEnumerate */
1165
    nullptr,               /* resolve */
1166
    nullptr,               /* mayResolve */
1167
    nullptr,               /* finalize */
1168
    _constructor, /* call */
1169
    nullptr,               /* hasInstance */
1170
    _constructor, /* construct */
1171
    nullptr,               /* trace */
1172
};
1173
1174
static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
1175
  {
1176
    "Function",
1177
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
1178
    &sInterfaceObjectClassOps,
1179
    JS_NULL_CLASS_SPEC,
1180
    JS_NULL_CLASS_EXT,
1181
    &sInterfaceObjectClassObjectOps
1182
  },
1183
  eInterface,
1184
  true,
1185
  prototypes::id::WebSocket,
1186
  PrototypeTraits<prototypes::id::WebSocket>::Depth,
1187
  sNativePropertyHooks,
1188
  "function WebSocket() {\n    [native code]\n}",
1189
  EventTarget_Binding::GetConstructorObject
1190
};
1191
1192
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
1193
  {
1194
    "WebSocketPrototype",
1195
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
1196
    JS_NULL_CLASS_OPS,
1197
    JS_NULL_CLASS_SPEC,
1198
    JS_NULL_CLASS_EXT,
1199
    JS_NULL_OBJECT_OPS
1200
  },
1201
  eInterfacePrototype,
1202
  false,
1203
  prototypes::id::WebSocket,
1204
  PrototypeTraits<prototypes::id::WebSocket>::Depth,
1205
  sNativePropertyHooks,
1206
  "[object WebSocketPrototype]",
1207
  EventTarget_Binding::GetProtoObject
1208
};
1209
1210
static const js::ClassOps sClassOps = {
1211
  _addProperty, /* addProperty */
1212
  nullptr,               /* delProperty */
1213
  nullptr,               /* enumerate */
1214
  nullptr, /* newEnumerate */
1215
  nullptr, /* resolve */
1216
  nullptr, /* mayResolve */
1217
  _finalize, /* finalize */
1218
  nullptr, /* call */
1219
  nullptr,               /* hasInstance */
1220
  nullptr,               /* construct */
1221
  nullptr, /* trace */
1222
};
1223
1224
static const js::ClassExtension sClassExtension = {
1225
  nullptr, /* weakmapKeyDelegateOp */
1226
  _objectMoved /* objectMovedOp */
1227
};
1228
1229
static const DOMJSClass sClass = {
1230
  { "WebSocket",
1231
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
1232
    &sClassOps,
1233
    JS_NULL_CLASS_SPEC,
1234
    &sClassExtension,
1235
    JS_NULL_OBJECT_OPS
1236
  },
1237
  { prototypes::id::EventTarget, prototypes::id::WebSocket, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
1238
  IsBaseOf<nsISupports, mozilla::dom::WebSocket >::value,
1239
  sNativePropertyHooks,
1240
  FindAssociatedGlobalForNative<mozilla::dom::WebSocket>::Get,
1241
  GetProtoObjectHandle,
1242
  GetCCParticipant<mozilla::dom::WebSocket>::Get()
1243
};
1244
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
1245
              "Must have the right minimal number of reserved slots.");
1246
static_assert(1 >= 1,
1247
              "Must have enough reserved slots.");
1248
1249
const JSClass*
1250
GetJSClass()
1251
0
{
1252
0
  return sClass.ToJSClass();
1253
0
}
1254
1255
bool
1256
Wrap(JSContext* aCx, mozilla::dom::WebSocket* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
1257
0
{
1258
0
  static_assert(!IsBaseOf<NonRefcountedDOMObject, mozilla::dom::WebSocket>::value,
1259
0
                "Shouldn't have wrappercached things that are not refcounted.");
1260
0
  MOZ_ASSERT(static_cast<mozilla::dom::WebSocket*>(aObject) ==
1261
0
             reinterpret_cast<mozilla::dom::WebSocket*>(aObject),
1262
0
             "Multiple inheritance for mozilla::dom::WebSocket is broken.");
1263
0
  MOZ_ASSERT(static_cast<mozilla::dom::EventTarget*>(aObject) ==
1264
0
             reinterpret_cast<mozilla::dom::EventTarget*>(aObject),
1265
0
             "Multiple inheritance for mozilla::dom::EventTarget is broken.");
1266
0
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
1267
0
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
1268
0
  MOZ_ASSERT(!aCache->GetWrapper(),
1269
0
             "You should probably not be using Wrap() directly; use "
1270
0
             "GetOrCreateDOMReflector instead");
1271
0
1272
0
  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
1273
0
             "nsISupports must be on our primary inheritance chain");
1274
0
1275
0
  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
1276
0
  if (!global) {
1277
0
    return false;
1278
0
  }
1279
0
  MOZ_ASSERT(JS_IsGlobalObject(global));
1280
0
  MOZ_ASSERT(JS::ObjectIsNotGray(global));
1281
0
1282
0
  // That might have ended up wrapping us already, due to the wonders
1283
0
  // of XBL.  Check for that, and bail out as needed.
1284
0
  aReflector.set(aCache->GetWrapper());
1285
0
  if (aReflector) {
1286
#ifdef DEBUG
1287
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
1288
#endif // DEBUG
1289
    return true;
1290
0
  }
1291
0
1292
0
  JSAutoRealm ar(aCx, global);
1293
0
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
1294
0
  if (!canonicalProto) {
1295
0
    return false;
1296
0
  }
1297
0
  JS::Rooted<JSObject*> proto(aCx);
1298
0
  if (aGivenProto) {
1299
0
    proto = aGivenProto;
1300
0
    // Unfortunately, while aGivenProto was in the compartment of aCx
1301
0
    // coming in, we changed compartments to that of "parent" so may need
1302
0
    // to wrap the proto here.
1303
0
    if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
1304
0
      if (!JS_WrapObject(aCx, &proto)) {
1305
0
        return false;
1306
0
      }
1307
0
    }
1308
0
  } else {
1309
0
    proto = canonicalProto;
1310
0
  }
1311
0
1312
0
  BindingJSObjectCreator<mozilla::dom::WebSocket> creator(aCx);
1313
0
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
1314
0
  if (!aReflector) {
1315
0
    return false;
1316
0
  }
1317
0
1318
0
  aCache->SetWrapper(aReflector);
1319
0
  creator.InitializationSucceeded();
1320
0
1321
0
  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
1322
0
             aCache->GetWrapperPreserveColor() == aReflector);
1323
0
  // If proto != canonicalProto, we have to preserve our wrapper;
1324
0
  // otherwise we won't be able to properly recreate it later, since
1325
0
  // we won't know what proto to use.  Note that we don't check
1326
0
  // aGivenProto here, since it's entirely possible (and even
1327
0
  // somewhat common) to have a non-null aGivenProto which is the
1328
0
  // same as canonicalProto.
1329
0
  if (proto != canonicalProto) {
1330
0
    PreserveWrapper(aObject);
1331
0
  }
1332
0
1333
0
  return true;
1334
0
}
1335
1336
const NativePropertyHooks sNativePropertyHooks[] = { {
1337
  nullptr,
1338
  nullptr,
1339
  nullptr,
1340
  { sNativeProperties.Upcast(), sChromeOnlyNativeProperties.Upcast() },
1341
  prototypes::id::WebSocket,
1342
  constructors::id::WebSocket,
1343
  EventTarget_Binding::sNativePropertyHooks,
1344
  &DefaultXrayExpandoObjectClass
1345
} };
1346
1347
void
1348
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
1349
0
{
1350
0
  JS::Handle<JSObject*> parentProto(EventTarget_Binding::GetProtoObjectHandle(aCx));
1351
0
  if (!parentProto) {
1352
0
    return;
1353
0
  }
1354
0
1355
0
  JS::Handle<JSObject*> constructorProto(EventTarget_Binding::GetConstructorObjectHandle(aCx));
1356
0
  if (!constructorProto) {
1357
0
    return;
1358
0
  }
1359
0
1360
0
  static bool sIdsInited = false;
1361
0
  if (!sIdsInited && NS_IsMainThread()) {
1362
0
    if (!InitIds(aCx, sNativeProperties.Upcast())) {
1363
0
      return;
1364
0
    }
1365
0
    if (!InitIds(aCx, sChromeOnlyNativeProperties.Upcast())) {
1366
0
      return;
1367
0
    }
1368
0
    sIdsInited = true;
1369
0
  }
1370
0
1371
0
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::WebSocket);
1372
0
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::WebSocket);
1373
0
  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
1374
0
                              &sPrototypeClass.mBase, protoCache,
1375
0
                              nullptr,
1376
0
                              constructorProto, &sInterfaceObjectClass.mBase, 1, nullptr,
1377
0
                              interfaceCache,
1378
0
                              sNativeProperties.Upcast(),
1379
0
                              sChromeOnlyNativeProperties.Upcast(),
1380
0
                              "WebSocket", aDefineOnGlobal,
1381
0
                              nullptr,
1382
0
                              false);
1383
0
}
1384
1385
JSObject*
1386
GetConstructorObject(JSContext* aCx)
1387
0
{
1388
0
  return GetConstructorObjectHandle(aCx);
1389
0
}
1390
1391
} // namespace WebSocket_Binding
1392
1393
1394
1395
} // namespace dom
1396
} // namespace mozilla