Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dom/bindings/ChromeUtilsBinding.cpp
Line
Count
Source (jump to first uncovered line)
1
/* THIS FILE IS AUTOGENERATED FROM ChromeUtils.webidl BY Codegen.py - DO NOT EDIT */
2
3
#include "AtomList.h"
4
#include "ChromeUtilsBinding.h"
5
#include "DOMPrefs.h"
6
#include "WindowBinding.h"
7
#include "WrapperFactory.h"
8
#include "jsapi.h"
9
#include "jsfriendapi.h"
10
#include "mozilla/OwningNonNull.h"
11
#include "mozilla/devtools/HeapSnapshot.h"
12
#include "mozilla/dom/BindingUtils.h"
13
#include "mozilla/dom/BrowsingContext.h"
14
#include "mozilla/dom/ChromeUtils.h"
15
#include "mozilla/dom/DOMJSClass.h"
16
#include "mozilla/dom/MozQueryInterface.h"
17
#include "mozilla/dom/NonRefcountedDOMObject.h"
18
#include "mozilla/dom/Nullable.h"
19
#include "mozilla/dom/PrimitiveConversions.h"
20
#include "mozilla/dom/Promise.h"
21
#include "mozilla/dom/ScriptSettings.h"
22
#include "mozilla/dom/SimpleGlobalObject.h"
23
#include "mozilla/dom/ToJSValue.h"
24
#include "mozilla/dom/TypedArray.h"
25
#include "mozilla/dom/UnionConversions.h"
26
#include "mozilla/dom/UnionTypes.h"
27
#include "mozilla/dom/XrayExpandoClass.h"
28
#include "nsContentUtils.h"
29
#include "nsIPrincipal.h"
30
#include "xpcjsid.h"
31
32
namespace mozilla {
33
namespace dom {
34
35
namespace binding_detail {}; // Just to make sure it's known as a namespace
36
using namespace mozilla::dom::binding_detail;
37
38
39
namespace Base64URLDecodePaddingValues {
40
extern const EnumEntry strings[4] = {
41
  {"require", 7},
42
  {"ignore", 6},
43
  {"reject", 6},
44
  { nullptr, 0 }
45
};
46
} // namespace Base64URLDecodePaddingValues
47
48
bool
49
ToJSValue(JSContext* aCx, Base64URLDecodePadding aArgument, JS::MutableHandle<JS::Value> aValue)
50
0
{
51
0
  MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(Base64URLDecodePaddingValues::strings));
52
0
  JSString* resultStr =
53
0
    JS_NewStringCopyN(aCx, Base64URLDecodePaddingValues::strings[uint32_t(aArgument)].value,
54
0
                      Base64URLDecodePaddingValues::strings[uint32_t(aArgument)].length);
55
0
  if (!resultStr) {
56
0
    return false;
57
0
  }
58
0
  aValue.setString(resultStr);
59
0
  return true;
60
0
}
61
62
63
void
64
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, OwningStringOrIID& aUnion, const char* aName, uint32_t aFlags)
65
0
{
66
0
  if (aUnion.IsIID()) {
67
0
    ImplCycleCollectionTraverse(aCallback, aUnion.GetAsIID(), "mIID", aFlags);
68
0
  }
69
0
}
70
71
72
void
73
ImplCycleCollectionUnlink(OwningStringOrIID& aUnion)
74
0
{
75
0
  aUnion.Uninit();
76
0
}
77
78
79
80
Base64URLDecodeOptions::Base64URLDecodeOptions()
81
0
{
82
0
  // Safe to pass a null context if we pass a null value
83
0
  Init(nullptr, JS::NullHandleValue);
84
0
}
85
86
87
88
bool
89
Base64URLDecodeOptions::InitIds(JSContext* cx, Base64URLDecodeOptionsAtoms* atomsCache)
90
0
{
91
0
  MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
92
0
93
0
  // Initialize these in reverse order so that any failure leaves the first one
94
0
  // uninitialized.
95
0
  if (!atomsCache->padding_id.init(cx, "padding")) {
96
0
    return false;
97
0
  }
98
0
  return true;
99
0
}
100
101
bool
102
Base64URLDecodeOptions::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
103
0
{
104
0
  // Passing a null JSContext is OK only if we're initing from null,
105
0
  // Since in that case we will not have to do any property gets
106
0
  // Also evaluate isNullOrUndefined in order to avoid false-positive
107
0
  // checkers by static analysis tools
108
0
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
109
0
  Base64URLDecodeOptionsAtoms* atomsCache = nullptr;
110
0
  if (cx) {
111
0
    atomsCache = GetAtomCache<Base64URLDecodeOptionsAtoms>(cx);
112
0
    if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
113
0
      return false;
114
0
    }
115
0
  }
116
0
117
0
  if (!IsConvertibleToDictionary(val)) {
118
0
    return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
119
0
  }
120
0
121
0
  bool isNull = val.isNullOrUndefined();
122
0
  // We only need these if !isNull, in which case we have |cx|.
123
0
  Maybe<JS::Rooted<JSObject *> > object;
124
0
  Maybe<JS::Rooted<JS::Value> > temp;
125
0
  if (!isNull) {
126
0
    MOZ_ASSERT(cx);
127
0
    object.emplace(cx, &val.toObject());
128
0
    temp.emplace(cx);
129
0
  }
130
0
  if (!isNull) {
131
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->padding_id, temp.ptr())) {
132
0
      return false;
133
0
    }
134
0
  }
135
0
  if (!isNull && !temp->isUndefined()) {
136
0
    {
137
0
      int index;
138
0
      if (!FindEnumStringIndex<true>(cx, temp.ref(), Base64URLDecodePaddingValues::strings, "Base64URLDecodePadding", "'padding' member of Base64URLDecodeOptions", &index)) {
139
0
        return false;
140
0
      }
141
0
      MOZ_ASSERT(index >= 0);
142
0
      mPadding = static_cast<Base64URLDecodePadding>(index);
143
0
    }
144
0
    mIsAnyMemberPresent = true;
145
0
  } else if (cx) {
146
0
    // Don't error out if we have no cx.  In that
147
0
    // situation the caller is default-constructing us and we'll
148
0
    // just assume they know what they're doing.
149
0
    return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
150
0
                             "'padding' member of Base64URLDecodeOptions");
151
0
  }
152
0
  return true;
153
0
}
154
155
bool
156
Base64URLDecodeOptions::Init(const nsAString& aJSON)
157
0
{
158
0
  AutoJSAPI jsapi;
159
0
  JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
160
0
  if (!cleanGlobal) {
161
0
    return false;
162
0
  }
163
0
  if (!jsapi.Init(cleanGlobal)) {
164
0
    return false;
165
0
  }
166
0
  JSContext* cx = jsapi.cx();
167
0
  JS::Rooted<JS::Value> json(cx);
168
0
  bool ok = ParseJSON(cx, aJSON, &json);
169
0
  NS_ENSURE_TRUE(ok, false);
170
0
  return Init(cx, json);
171
0
}
172
173
bool
174
Base64URLDecodeOptions::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
175
0
{
176
0
  Base64URLDecodeOptionsAtoms* atomsCache = GetAtomCache<Base64URLDecodeOptionsAtoms>(cx);
177
0
  if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
178
0
    return false;
179
0
  }
180
0
181
0
  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
182
0
  if (!obj) {
183
0
    return false;
184
0
  }
185
0
  rval.set(JS::ObjectValue(*obj));
186
0
187
0
  do {
188
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
189
0
    JS::Rooted<JS::Value> temp(cx);
190
0
    Base64URLDecodePadding const & currentValue = mPadding;
191
0
    if (!ToJSValue(cx, currentValue, &temp)) {
192
0
      return false;
193
0
    }
194
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->padding_id, temp, JSPROP_ENUMERATE)) {
195
0
      return false;
196
0
    }
197
0
    break;
198
0
  } while(false);
199
0
200
0
  return true;
201
0
}
202
203
bool
204
Base64URLDecodeOptions::ToJSON(nsAString& aJSON) const
205
0
{
206
0
  AutoJSAPI jsapi;
207
0
  jsapi.Init();
208
0
  JSContext *cx = jsapi.cx();
209
0
  // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
210
0
  // because we'll only be creating objects, in ways that have no
211
0
  // side-effects, followed by a call to JS::ToJSONMaybeSafely,
212
0
  // which likewise guarantees no side-effects for the sorts of
213
0
  // things we will pass it.
214
0
  JSAutoRealm ar(cx, UnprivilegedJunkScopeOrWorkerGlobal());
215
0
  JS::Rooted<JS::Value> val(cx);
216
0
  if (!ToObjectInternal(cx, &val)) {
217
0
    return false;
218
0
  }
219
0
  JS::Rooted<JSObject*> obj(cx, &val.toObject());
220
0
  return StringifyToJSON(cx, obj, aJSON);
221
0
}
222
223
void
224
Base64URLDecodeOptions::TraceDictionary(JSTracer* trc)
225
0
{
226
0
}
227
228
Base64URLDecodeOptions&
229
Base64URLDecodeOptions::operator=(const Base64URLDecodeOptions& aOther)
230
0
{
231
0
  DictionaryBase::operator=(aOther);
232
0
  mPadding = aOther.mPadding;
233
0
  return *this;
234
0
}
235
236
namespace binding_detail {
237
} // namespace binding_detail
238
239
240
241
Base64URLEncodeOptions::Base64URLEncodeOptions()
242
0
{
243
0
  // Safe to pass a null context if we pass a null value
244
0
  Init(nullptr, JS::NullHandleValue);
245
0
}
246
247
248
249
bool
250
Base64URLEncodeOptions::InitIds(JSContext* cx, Base64URLEncodeOptionsAtoms* atomsCache)
251
0
{
252
0
  MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
253
0
254
0
  // Initialize these in reverse order so that any failure leaves the first one
255
0
  // uninitialized.
256
0
  if (!atomsCache->pad_id.init(cx, "pad")) {
257
0
    return false;
258
0
  }
259
0
  return true;
260
0
}
261
262
bool
263
Base64URLEncodeOptions::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
264
0
{
265
0
  // Passing a null JSContext is OK only if we're initing from null,
266
0
  // Since in that case we will not have to do any property gets
267
0
  // Also evaluate isNullOrUndefined in order to avoid false-positive
268
0
  // checkers by static analysis tools
269
0
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
270
0
  Base64URLEncodeOptionsAtoms* atomsCache = nullptr;
271
0
  if (cx) {
272
0
    atomsCache = GetAtomCache<Base64URLEncodeOptionsAtoms>(cx);
273
0
    if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
274
0
      return false;
275
0
    }
276
0
  }
277
0
278
0
  if (!IsConvertibleToDictionary(val)) {
279
0
    return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
280
0
  }
281
0
282
0
  bool isNull = val.isNullOrUndefined();
283
0
  // We only need these if !isNull, in which case we have |cx|.
284
0
  Maybe<JS::Rooted<JSObject *> > object;
285
0
  Maybe<JS::Rooted<JS::Value> > temp;
286
0
  if (!isNull) {
287
0
    MOZ_ASSERT(cx);
288
0
    object.emplace(cx, &val.toObject());
289
0
    temp.emplace(cx);
290
0
  }
291
0
  if (!isNull) {
292
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->pad_id, temp.ptr())) {
293
0
      return false;
294
0
    }
295
0
  }
296
0
  if (!isNull && !temp->isUndefined()) {
297
0
    if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &mPad)) {
298
0
      return false;
299
0
    }
300
0
    mIsAnyMemberPresent = true;
301
0
  } else if (cx) {
302
0
    // Don't error out if we have no cx.  In that
303
0
    // situation the caller is default-constructing us and we'll
304
0
    // just assume they know what they're doing.
305
0
    return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
306
0
                             "'pad' member of Base64URLEncodeOptions");
307
0
  }
308
0
  return true;
309
0
}
310
311
bool
312
Base64URLEncodeOptions::Init(const nsAString& aJSON)
313
0
{
314
0
  AutoJSAPI jsapi;
315
0
  JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
316
0
  if (!cleanGlobal) {
317
0
    return false;
318
0
  }
319
0
  if (!jsapi.Init(cleanGlobal)) {
320
0
    return false;
321
0
  }
322
0
  JSContext* cx = jsapi.cx();
323
0
  JS::Rooted<JS::Value> json(cx);
324
0
  bool ok = ParseJSON(cx, aJSON, &json);
325
0
  NS_ENSURE_TRUE(ok, false);
326
0
  return Init(cx, json);
327
0
}
328
329
bool
330
Base64URLEncodeOptions::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
331
0
{
332
0
  Base64URLEncodeOptionsAtoms* atomsCache = GetAtomCache<Base64URLEncodeOptionsAtoms>(cx);
333
0
  if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
334
0
    return false;
335
0
  }
336
0
337
0
  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
338
0
  if (!obj) {
339
0
    return false;
340
0
  }
341
0
  rval.set(JS::ObjectValue(*obj));
342
0
343
0
  do {
344
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
345
0
    JS::Rooted<JS::Value> temp(cx);
346
0
    bool const & currentValue = mPad;
347
0
    temp.setBoolean(currentValue);
348
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->pad_id, temp, JSPROP_ENUMERATE)) {
349
0
      return false;
350
0
    }
351
0
    break;
352
0
  } while(false);
353
0
354
0
  return true;
355
0
}
356
357
bool
358
Base64URLEncodeOptions::ToJSON(nsAString& aJSON) const
359
0
{
360
0
  AutoJSAPI jsapi;
361
0
  jsapi.Init();
362
0
  JSContext *cx = jsapi.cx();
363
0
  // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
364
0
  // because we'll only be creating objects, in ways that have no
365
0
  // side-effects, followed by a call to JS::ToJSONMaybeSafely,
366
0
  // which likewise guarantees no side-effects for the sorts of
367
0
  // things we will pass it.
368
0
  JSAutoRealm ar(cx, UnprivilegedJunkScopeOrWorkerGlobal());
369
0
  JS::Rooted<JS::Value> val(cx);
370
0
  if (!ToObjectInternal(cx, &val)) {
371
0
    return false;
372
0
  }
373
0
  JS::Rooted<JSObject*> obj(cx, &val.toObject());
374
0
  return StringifyToJSON(cx, obj, aJSON);
375
0
}
376
377
void
378
Base64URLEncodeOptions::TraceDictionary(JSTracer* trc)
379
0
{
380
0
}
381
382
Base64URLEncodeOptions&
383
Base64URLEncodeOptions::operator=(const Base64URLEncodeOptions& aOther)
384
0
{
385
0
  DictionaryBase::operator=(aOther);
386
0
  mPad = aOther.mPad;
387
0
  return *this;
388
0
}
389
390
namespace binding_detail {
391
} // namespace binding_detail
392
393
394
395
CategoryDispatchDictionary::CategoryDispatchDictionary()
396
0
{
397
0
  // Safe to pass a null context if we pass a null value
398
0
  Init(nullptr, JS::NullHandleValue);
399
0
}
400
401
402
403
bool
404
CategoryDispatchDictionary::InitIds(JSContext* cx, CategoryDispatchDictionaryAtoms* atomsCache)
405
0
{
406
0
  MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
407
0
408
0
  // Initialize these in reverse order so that any failure leaves the first one
409
0
  // uninitialized.
410
0
  if (!atomsCache->count_id.init(cx, "count") ||
411
0
      !atomsCache->category_id.init(cx, "category")) {
412
0
    return false;
413
0
  }
414
0
  return true;
415
0
}
416
417
bool
418
CategoryDispatchDictionary::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
419
0
{
420
0
  // Passing a null JSContext is OK only if we're initing from null,
421
0
  // Since in that case we will not have to do any property gets
422
0
  // Also evaluate isNullOrUndefined in order to avoid false-positive
423
0
  // checkers by static analysis tools
424
0
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
425
0
  CategoryDispatchDictionaryAtoms* atomsCache = nullptr;
426
0
  if (cx) {
427
0
    atomsCache = GetAtomCache<CategoryDispatchDictionaryAtoms>(cx);
428
0
    if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
429
0
      return false;
430
0
    }
431
0
  }
432
0
433
0
  if (!IsConvertibleToDictionary(val)) {
434
0
    return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
435
0
  }
436
0
437
0
  bool isNull = val.isNullOrUndefined();
438
0
  // We only need these if !isNull, in which case we have |cx|.
439
0
  Maybe<JS::Rooted<JSObject *> > object;
440
0
  Maybe<JS::Rooted<JS::Value> > temp;
441
0
  if (!isNull) {
442
0
    MOZ_ASSERT(cx);
443
0
    object.emplace(cx, &val.toObject());
444
0
    temp.emplace(cx);
445
0
  }
446
0
  if (!isNull) {
447
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->category_id, temp.ptr())) {
448
0
      return false;
449
0
    }
450
0
  }
451
0
  if (!isNull && !temp->isUndefined()) {
452
0
    if (!ValueToPrimitive<uint16_t, eDefault>(cx, temp.ref(), &mCategory)) {
453
0
      return false;
454
0
    }
455
0
  } else {
456
0
    mCategory = 0;
457
0
  }
458
0
  mIsAnyMemberPresent = true;
459
0
460
0
  if (!isNull) {
461
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->count_id, temp.ptr())) {
462
0
      return false;
463
0
    }
464
0
  }
465
0
  if (!isNull && !temp->isUndefined()) {
466
0
    if (!ValueToPrimitive<uint16_t, eDefault>(cx, temp.ref(), &mCount)) {
467
0
      return false;
468
0
    }
469
0
  } else {
470
0
    mCount = 0;
471
0
  }
472
0
  mIsAnyMemberPresent = true;
473
0
  return true;
474
0
}
475
476
bool
477
CategoryDispatchDictionary::Init(const nsAString& aJSON)
478
0
{
479
0
  AutoJSAPI jsapi;
480
0
  JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
481
0
  if (!cleanGlobal) {
482
0
    return false;
483
0
  }
484
0
  if (!jsapi.Init(cleanGlobal)) {
485
0
    return false;
486
0
  }
487
0
  JSContext* cx = jsapi.cx();
488
0
  JS::Rooted<JS::Value> json(cx);
489
0
  bool ok = ParseJSON(cx, aJSON, &json);
490
0
  NS_ENSURE_TRUE(ok, false);
491
0
  return Init(cx, json);
492
0
}
493
494
bool
495
CategoryDispatchDictionary::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
496
0
{
497
0
  CategoryDispatchDictionaryAtoms* atomsCache = GetAtomCache<CategoryDispatchDictionaryAtoms>(cx);
498
0
  if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
499
0
    return false;
500
0
  }
501
0
502
0
  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
503
0
  if (!obj) {
504
0
    return false;
505
0
  }
506
0
  rval.set(JS::ObjectValue(*obj));
507
0
508
0
  do {
509
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
510
0
    JS::Rooted<JS::Value> temp(cx);
511
0
    uint16_t const & currentValue = mCategory;
512
0
    temp.setInt32(int32_t(currentValue));
513
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->category_id, temp, JSPROP_ENUMERATE)) {
514
0
      return false;
515
0
    }
516
0
    break;
517
0
  } while(false);
518
0
519
0
  do {
520
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
521
0
    JS::Rooted<JS::Value> temp(cx);
522
0
    uint16_t const & currentValue = mCount;
523
0
    temp.setInt32(int32_t(currentValue));
524
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->count_id, temp, JSPROP_ENUMERATE)) {
525
0
      return false;
526
0
    }
527
0
    break;
528
0
  } while(false);
529
0
530
0
  return true;
531
0
}
532
533
bool
534
CategoryDispatchDictionary::ToJSON(nsAString& aJSON) const
535
0
{
536
0
  AutoJSAPI jsapi;
537
0
  jsapi.Init();
538
0
  JSContext *cx = jsapi.cx();
539
0
  // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
540
0
  // because we'll only be creating objects, in ways that have no
541
0
  // side-effects, followed by a call to JS::ToJSONMaybeSafely,
542
0
  // which likewise guarantees no side-effects for the sorts of
543
0
  // things we will pass it.
544
0
  JSAutoRealm ar(cx, UnprivilegedJunkScopeOrWorkerGlobal());
545
0
  JS::Rooted<JS::Value> val(cx);
546
0
  if (!ToObjectInternal(cx, &val)) {
547
0
    return false;
548
0
  }
549
0
  JS::Rooted<JSObject*> obj(cx, &val.toObject());
550
0
  return StringifyToJSON(cx, obj, aJSON);
551
0
}
552
553
void
554
CategoryDispatchDictionary::TraceDictionary(JSTracer* trc)
555
0
{
556
0
}
557
558
CategoryDispatchDictionary&
559
CategoryDispatchDictionary::operator=(const CategoryDispatchDictionary& aOther)
560
0
{
561
0
  DictionaryBase::operator=(aOther);
562
0
  mCategory = aOther.mCategory;
563
0
  mCount = aOther.mCount;
564
0
  return *this;
565
0
}
566
567
namespace binding_detail {
568
} // namespace binding_detail
569
570
571
572
CompileScriptOptionsDictionary::CompileScriptOptionsDictionary()
573
0
{
574
0
  // Safe to pass a null context if we pass a null value
575
0
  Init(nullptr, JS::NullHandleValue);
576
0
}
577
578
579
580
bool
581
CompileScriptOptionsDictionary::InitIds(JSContext* cx, CompileScriptOptionsDictionaryAtoms* atomsCache)
582
0
{
583
0
  MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
584
0
585
0
  // Initialize these in reverse order so that any failure leaves the first one
586
0
  // uninitialized.
587
0
  if (!atomsCache->lazilyParse_id.init(cx, "lazilyParse") ||
588
0
      !atomsCache->hasReturnValue_id.init(cx, "hasReturnValue") ||
589
0
      !atomsCache->charset_id.init(cx, "charset")) {
590
0
    return false;
591
0
  }
592
0
  return true;
593
0
}
594
595
bool
596
CompileScriptOptionsDictionary::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
597
0
{
598
0
  // Passing a null JSContext is OK only if we're initing from null,
599
0
  // Since in that case we will not have to do any property gets
600
0
  // Also evaluate isNullOrUndefined in order to avoid false-positive
601
0
  // checkers by static analysis tools
602
0
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
603
0
  CompileScriptOptionsDictionaryAtoms* atomsCache = nullptr;
604
0
  if (cx) {
605
0
    atomsCache = GetAtomCache<CompileScriptOptionsDictionaryAtoms>(cx);
606
0
    if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
607
0
      return false;
608
0
    }
609
0
  }
610
0
611
0
  if (!IsConvertibleToDictionary(val)) {
612
0
    return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
613
0
  }
614
0
615
0
  bool isNull = val.isNullOrUndefined();
616
0
  // We only need these if !isNull, in which case we have |cx|.
617
0
  Maybe<JS::Rooted<JSObject *> > object;
618
0
  Maybe<JS::Rooted<JS::Value> > temp;
619
0
  if (!isNull) {
620
0
    MOZ_ASSERT(cx);
621
0
    object.emplace(cx, &val.toObject());
622
0
    temp.emplace(cx);
623
0
  }
624
0
  if (!isNull) {
625
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->charset_id, temp.ptr())) {
626
0
      return false;
627
0
    }
628
0
  }
629
0
  if (!isNull && !temp->isUndefined()) {
630
0
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mCharset)) {
631
0
      return false;
632
0
    }
633
0
  } else {
634
0
    static const char16_t data[] = { 'u', 't', 'f', '-', '8', 0 };
635
0
    mCharset.Rebind(data, ArrayLength(data) - 1);
636
0
  }
637
0
  mIsAnyMemberPresent = true;
638
0
639
0
  if (!isNull) {
640
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->hasReturnValue_id, temp.ptr())) {
641
0
      return false;
642
0
    }
643
0
  }
644
0
  if (!isNull && !temp->isUndefined()) {
645
0
    if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &mHasReturnValue)) {
646
0
      return false;
647
0
    }
648
0
  } else {
649
0
    mHasReturnValue = false;
650
0
  }
651
0
  mIsAnyMemberPresent = true;
652
0
653
0
  if (!isNull) {
654
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->lazilyParse_id, temp.ptr())) {
655
0
      return false;
656
0
    }
657
0
  }
658
0
  if (!isNull && !temp->isUndefined()) {
659
0
    if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &mLazilyParse)) {
660
0
      return false;
661
0
    }
662
0
  } else {
663
0
    mLazilyParse = false;
664
0
  }
665
0
  mIsAnyMemberPresent = true;
666
0
  return true;
667
0
}
668
669
bool
670
CompileScriptOptionsDictionary::Init(const nsAString& aJSON)
671
0
{
672
0
  AutoJSAPI jsapi;
673
0
  JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
674
0
  if (!cleanGlobal) {
675
0
    return false;
676
0
  }
677
0
  if (!jsapi.Init(cleanGlobal)) {
678
0
    return false;
679
0
  }
680
0
  JSContext* cx = jsapi.cx();
681
0
  JS::Rooted<JS::Value> json(cx);
682
0
  bool ok = ParseJSON(cx, aJSON, &json);
683
0
  NS_ENSURE_TRUE(ok, false);
684
0
  return Init(cx, json);
685
0
}
686
687
bool
688
CompileScriptOptionsDictionary::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
689
0
{
690
0
  CompileScriptOptionsDictionaryAtoms* atomsCache = GetAtomCache<CompileScriptOptionsDictionaryAtoms>(cx);
691
0
  if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
692
0
    return false;
693
0
  }
694
0
695
0
  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
696
0
  if (!obj) {
697
0
    return false;
698
0
  }
699
0
  rval.set(JS::ObjectValue(*obj));
700
0
701
0
  do {
702
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
703
0
    JS::Rooted<JS::Value> temp(cx);
704
0
    nsString const & currentValue = mCharset;
705
0
    if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
706
0
      return false;
707
0
    }
708
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->charset_id, temp, JSPROP_ENUMERATE)) {
709
0
      return false;
710
0
    }
711
0
    break;
712
0
  } while(false);
713
0
714
0
  do {
715
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
716
0
    JS::Rooted<JS::Value> temp(cx);
717
0
    bool const & currentValue = mHasReturnValue;
718
0
    temp.setBoolean(currentValue);
719
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->hasReturnValue_id, temp, JSPROP_ENUMERATE)) {
720
0
      return false;
721
0
    }
722
0
    break;
723
0
  } while(false);
724
0
725
0
  do {
726
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
727
0
    JS::Rooted<JS::Value> temp(cx);
728
0
    bool const & currentValue = mLazilyParse;
729
0
    temp.setBoolean(currentValue);
730
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->lazilyParse_id, temp, JSPROP_ENUMERATE)) {
731
0
      return false;
732
0
    }
733
0
    break;
734
0
  } while(false);
735
0
736
0
  return true;
737
0
}
738
739
bool
740
CompileScriptOptionsDictionary::ToJSON(nsAString& aJSON) const
741
0
{
742
0
  AutoJSAPI jsapi;
743
0
  jsapi.Init();
744
0
  JSContext *cx = jsapi.cx();
745
0
  // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
746
0
  // because we'll only be creating objects, in ways that have no
747
0
  // side-effects, followed by a call to JS::ToJSONMaybeSafely,
748
0
  // which likewise guarantees no side-effects for the sorts of
749
0
  // things we will pass it.
750
0
  JSAutoRealm ar(cx, UnprivilegedJunkScopeOrWorkerGlobal());
751
0
  JS::Rooted<JS::Value> val(cx);
752
0
  if (!ToObjectInternal(cx, &val)) {
753
0
    return false;
754
0
  }
755
0
  JS::Rooted<JSObject*> obj(cx, &val.toObject());
756
0
  return StringifyToJSON(cx, obj, aJSON);
757
0
}
758
759
void
760
CompileScriptOptionsDictionary::TraceDictionary(JSTracer* trc)
761
0
{
762
0
}
763
764
CompileScriptOptionsDictionary&
765
CompileScriptOptionsDictionary::operator=(const CompileScriptOptionsDictionary& aOther)
766
0
{
767
0
  DictionaryBase::operator=(aOther);
768
0
  mCharset = aOther.mCharset;
769
0
  mHasReturnValue = aOther.mHasReturnValue;
770
0
  mLazilyParse = aOther.mLazilyParse;
771
0
  return *this;
772
0
}
773
774
namespace binding_detail {
775
} // namespace binding_detail
776
777
778
779
HeapSnapshotBoundaries::HeapSnapshotBoundaries()
780
0
{
781
0
  // Safe to pass a null context if we pass a null value
782
0
  Init(nullptr, JS::NullHandleValue);
783
0
}
784
785
786
bool
787
HeapSnapshotBoundaries::InitIds(JSContext* cx, HeapSnapshotBoundariesAtoms* atomsCache)
788
0
{
789
0
  MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
790
0
791
0
  // Initialize these in reverse order so that any failure leaves the first one
792
0
  // uninitialized.
793
0
  if (!atomsCache->runtime_id.init(cx, "runtime") ||
794
0
      !atomsCache->globals_id.init(cx, "globals") ||
795
0
      !atomsCache->debugger_id.init(cx, "debugger")) {
796
0
    return false;
797
0
  }
798
0
  return true;
799
0
}
800
801
bool
802
HeapSnapshotBoundaries::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
803
0
{
804
0
  // Passing a null JSContext is OK only if we're initing from null,
805
0
  // Since in that case we will not have to do any property gets
806
0
  // Also evaluate isNullOrUndefined in order to avoid false-positive
807
0
  // checkers by static analysis tools
808
0
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
809
0
  HeapSnapshotBoundariesAtoms* atomsCache = nullptr;
810
0
  if (cx) {
811
0
    atomsCache = GetAtomCache<HeapSnapshotBoundariesAtoms>(cx);
812
0
    if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
813
0
      return false;
814
0
    }
815
0
  }
816
0
817
0
  if (!IsConvertibleToDictionary(val)) {
818
0
    return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
819
0
  }
820
0
821
0
  bool isNull = val.isNullOrUndefined();
822
0
  // We only need these if !isNull, in which case we have |cx|.
823
0
  Maybe<JS::Rooted<JSObject *> > object;
824
0
  Maybe<JS::Rooted<JS::Value> > temp;
825
0
  if (!isNull) {
826
0
    MOZ_ASSERT(cx);
827
0
    object.emplace(cx, &val.toObject());
828
0
    temp.emplace(cx);
829
0
  }
830
0
  if (!isNull) {
831
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->debugger_id, temp.ptr())) {
832
0
      return false;
833
0
    }
834
0
  }
835
0
  if (!isNull && !temp->isUndefined()) {
836
0
    mDebugger.Construct();
837
0
    if (temp.ref().isObject()) {
838
0
#ifdef __clang__
839
0
#pragma clang diagnostic push
840
0
#pragma clang diagnostic ignored "-Wunreachable-code"
841
0
#pragma clang diagnostic ignored "-Wunreachable-code-return"
842
0
#endif // __clang__
843
0
      if ((passedToJSImpl) && !CallerSubsumes(temp.ref())) {
844
0
        ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "'debugger' member of HeapSnapshotBoundaries");
845
0
        return false;
846
0
      }
847
0
#ifdef __clang__
848
0
#pragma clang diagnostic pop
849
0
#endif // __clang__
850
0
      (mDebugger.Value()) = &temp.ref().toObject();
851
0
    } else {
852
0
      ThrowErrorMessage(cx, MSG_NOT_OBJECT, "'debugger' member of HeapSnapshotBoundaries");
853
0
      return false;
854
0
    }
855
0
    mIsAnyMemberPresent = true;
856
0
  }
857
0
858
0
  if (!isNull) {
859
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->globals_id, temp.ptr())) {
860
0
      return false;
861
0
    }
862
0
  }
863
0
  if (!isNull && !temp->isUndefined()) {
864
0
    mGlobals.Construct();
865
0
    if (temp.ref().isObject()) {
866
0
      JS::ForOfIterator iter(cx);
867
0
      if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
868
0
        return false;
869
0
      }
870
0
      if (!iter.valueIsIterable()) {
871
0
        ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'globals' member of HeapSnapshotBoundaries");
872
0
        return false;
873
0
      }
874
0
      Sequence<JSObject*> &arr = (mGlobals.Value());
875
0
      JS::Rooted<JS::Value> temp(cx);
876
0
      while (true) {
877
0
        bool done;
878
0
        if (!iter.next(&temp, &done)) {
879
0
          return false;
880
0
        }
881
0
        if (done) {
882
0
          break;
883
0
        }
884
0
        JSObject** slotPtr = arr.AppendElement(mozilla::fallible);
885
0
        if (!slotPtr) {
886
0
          JS_ReportOutOfMemory(cx);
887
0
          return false;
888
0
        }
889
0
        JSObject*& slot = *slotPtr;
890
0
        if (temp.isObject()) {
891
0
#ifdef __clang__
892
0
#pragma clang diagnostic push
893
0
#pragma clang diagnostic ignored "-Wunreachable-code"
894
0
#pragma clang diagnostic ignored "-Wunreachable-code-return"
895
0
#endif // __clang__
896
0
          if ((passedToJSImpl) && !CallerSubsumes(temp)) {
897
0
            ThrowErrorMessage(cx, MSG_PERMISSION_DENIED_TO_PASS_ARG, "element of 'globals' member of HeapSnapshotBoundaries");
898
0
            return false;
899
0
          }
900
0
#ifdef __clang__
901
0
#pragma clang diagnostic pop
902
0
#endif // __clang__
903
0
          slot = &temp.toObject();
904
0
        } else {
905
0
          ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Element of 'globals' member of HeapSnapshotBoundaries");
906
0
          return false;
907
0
        }
908
0
      }
909
0
    } else {
910
0
      ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'globals' member of HeapSnapshotBoundaries");
911
0
      return false;
912
0
    }
913
0
    mIsAnyMemberPresent = true;
914
0
  }
915
0
916
0
  if (!isNull) {
917
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->runtime_id, temp.ptr())) {
918
0
      return false;
919
0
    }
920
0
  }
921
0
  if (!isNull && !temp->isUndefined()) {
922
0
    mRuntime.Construct();
923
0
    if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &(mRuntime.Value()))) {
924
0
      return false;
925
0
    }
926
0
    mIsAnyMemberPresent = true;
927
0
  }
928
0
  return true;
929
0
}
930
931
bool
932
HeapSnapshotBoundaries::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
933
0
{
934
0
  HeapSnapshotBoundariesAtoms* atomsCache = GetAtomCache<HeapSnapshotBoundariesAtoms>(cx);
935
0
  if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
936
0
    return false;
937
0
  }
938
0
939
0
  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
940
0
  if (!obj) {
941
0
    return false;
942
0
  }
943
0
  rval.set(JS::ObjectValue(*obj));
944
0
945
0
  if (mDebugger.WasPassed()) {
946
0
    do {
947
0
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
948
0
      JS::Rooted<JS::Value> temp(cx);
949
0
      JSObject* const & currentValue = mDebugger.InternalValue();
950
0
      JS::ExposeObjectToActiveJS(currentValue);
951
0
      temp.setObject(*currentValue);
952
0
      if (!MaybeWrapObjectValue(cx, &temp)) {
953
0
        return false;
954
0
      }
955
0
      if (!JS_DefinePropertyById(cx, obj, atomsCache->debugger_id, temp, JSPROP_ENUMERATE)) {
956
0
        return false;
957
0
      }
958
0
      break;
959
0
    } while(false);
960
0
  }
961
0
962
0
  if (mGlobals.WasPassed()) {
963
0
    do {
964
0
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
965
0
      JS::Rooted<JS::Value> temp(cx);
966
0
      Sequence<JSObject*> const & currentValue = mGlobals.InternalValue();
967
0
968
0
      uint32_t length = currentValue.Length();
969
0
      JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
970
0
      if (!returnArray) {
971
0
        return false;
972
0
      }
973
0
      // Scope for 'tmp'
974
0
      {
975
0
        JS::Rooted<JS::Value> tmp(cx);
976
0
        for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
977
0
          // Control block to let us common up the JS_DefineElement calls when there
978
0
          // are different ways to succeed at wrapping the object.
979
0
          do {
980
0
            JS::ExposeObjectToActiveJS(currentValue[sequenceIdx0]);
981
0
            tmp.setObject(*currentValue[sequenceIdx0]);
982
0
            if (!MaybeWrapObjectValue(cx, &tmp)) {
983
0
              return false;
984
0
            }
985
0
            break;
986
0
          } while (false);
987
0
          if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
988
0
                                JSPROP_ENUMERATE)) {
989
0
            return false;
990
0
          }
991
0
        }
992
0
      }
993
0
      temp.setObject(*returnArray);
994
0
      if (!JS_DefinePropertyById(cx, obj, atomsCache->globals_id, temp, JSPROP_ENUMERATE)) {
995
0
        return false;
996
0
      }
997
0
      break;
998
0
    } while(false);
999
0
  }
1000
0
1001
0
  if (mRuntime.WasPassed()) {
1002
0
    do {
1003
0
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1004
0
      JS::Rooted<JS::Value> temp(cx);
1005
0
      bool const & currentValue = mRuntime.InternalValue();
1006
0
      temp.setBoolean(currentValue);
1007
0
      if (!JS_DefinePropertyById(cx, obj, atomsCache->runtime_id, temp, JSPROP_ENUMERATE)) {
1008
0
        return false;
1009
0
      }
1010
0
      break;
1011
0
    } while(false);
1012
0
  }
1013
0
1014
0
  return true;
1015
0
}
1016
1017
void
1018
HeapSnapshotBoundaries::TraceDictionary(JSTracer* trc)
1019
0
{
1020
0
  if (mDebugger.WasPassed()) {
1021
0
    JS::UnsafeTraceRoot(trc, &mDebugger.Value(), "HeapSnapshotBoundaries.mDebugger");
1022
0
  }
1023
0
1024
0
  if (mGlobals.WasPassed()) {
1025
0
    DoTraceSequence(trc, mGlobals.Value());
1026
0
  }
1027
0
}
1028
1029
namespace binding_detail {
1030
} // namespace binding_detail
1031
1032
1033
1034
IOActivityDataDictionary::IOActivityDataDictionary()
1035
0
{
1036
0
  // Safe to pass a null context if we pass a null value
1037
0
  Init(nullptr, JS::NullHandleValue);
1038
0
}
1039
1040
1041
1042
bool
1043
IOActivityDataDictionary::InitIds(JSContext* cx, IOActivityDataDictionaryAtoms* atomsCache)
1044
0
{
1045
0
  MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
1046
0
1047
0
  // Initialize these in reverse order so that any failure leaves the first one
1048
0
  // uninitialized.
1049
0
  if (!atomsCache->tx_id.init(cx, "tx") ||
1050
0
      !atomsCache->rx_id.init(cx, "rx") ||
1051
0
      !atomsCache->location_id.init(cx, "location")) {
1052
0
    return false;
1053
0
  }
1054
0
  return true;
1055
0
}
1056
1057
bool
1058
IOActivityDataDictionary::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
1059
0
{
1060
0
  // Passing a null JSContext is OK only if we're initing from null,
1061
0
  // Since in that case we will not have to do any property gets
1062
0
  // Also evaluate isNullOrUndefined in order to avoid false-positive
1063
0
  // checkers by static analysis tools
1064
0
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
1065
0
  IOActivityDataDictionaryAtoms* atomsCache = nullptr;
1066
0
  if (cx) {
1067
0
    atomsCache = GetAtomCache<IOActivityDataDictionaryAtoms>(cx);
1068
0
    if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
1069
0
      return false;
1070
0
    }
1071
0
  }
1072
0
1073
0
  if (!IsConvertibleToDictionary(val)) {
1074
0
    return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
1075
0
  }
1076
0
1077
0
  bool isNull = val.isNullOrUndefined();
1078
0
  // We only need these if !isNull, in which case we have |cx|.
1079
0
  Maybe<JS::Rooted<JSObject *> > object;
1080
0
  Maybe<JS::Rooted<JS::Value> > temp;
1081
0
  if (!isNull) {
1082
0
    MOZ_ASSERT(cx);
1083
0
    object.emplace(cx, &val.toObject());
1084
0
    temp.emplace(cx);
1085
0
  }
1086
0
  if (!isNull) {
1087
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->location_id, temp.ptr())) {
1088
0
      return false;
1089
0
    }
1090
0
  }
1091
0
  if (!isNull && !temp->isUndefined()) {
1092
0
    if (!ConvertJSValueToByteString(cx, temp.ref(), false, mLocation)) {
1093
0
      return false;
1094
0
    }
1095
0
  } else {
1096
0
    static const char data[] = { 0 };
1097
0
    mLocation.Rebind(data, ArrayLength(data) - 1);
1098
0
  }
1099
0
  mIsAnyMemberPresent = true;
1100
0
1101
0
  if (!isNull) {
1102
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->rx_id, temp.ptr())) {
1103
0
      return false;
1104
0
    }
1105
0
  }
1106
0
  if (!isNull && !temp->isUndefined()) {
1107
0
    if (!ValueToPrimitive<uint64_t, eDefault>(cx, temp.ref(), &mRx)) {
1108
0
      return false;
1109
0
    }
1110
0
  } else {
1111
0
    mRx = 0ULL;
1112
0
  }
1113
0
  mIsAnyMemberPresent = true;
1114
0
1115
0
  if (!isNull) {
1116
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->tx_id, temp.ptr())) {
1117
0
      return false;
1118
0
    }
1119
0
  }
1120
0
  if (!isNull && !temp->isUndefined()) {
1121
0
    if (!ValueToPrimitive<uint64_t, eDefault>(cx, temp.ref(), &mTx)) {
1122
0
      return false;
1123
0
    }
1124
0
  } else {
1125
0
    mTx = 0ULL;
1126
0
  }
1127
0
  mIsAnyMemberPresent = true;
1128
0
  return true;
1129
0
}
1130
1131
bool
1132
IOActivityDataDictionary::Init(const nsAString& aJSON)
1133
0
{
1134
0
  AutoJSAPI jsapi;
1135
0
  JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
1136
0
  if (!cleanGlobal) {
1137
0
    return false;
1138
0
  }
1139
0
  if (!jsapi.Init(cleanGlobal)) {
1140
0
    return false;
1141
0
  }
1142
0
  JSContext* cx = jsapi.cx();
1143
0
  JS::Rooted<JS::Value> json(cx);
1144
0
  bool ok = ParseJSON(cx, aJSON, &json);
1145
0
  NS_ENSURE_TRUE(ok, false);
1146
0
  return Init(cx, json);
1147
0
}
1148
1149
bool
1150
IOActivityDataDictionary::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
1151
0
{
1152
0
  IOActivityDataDictionaryAtoms* atomsCache = GetAtomCache<IOActivityDataDictionaryAtoms>(cx);
1153
0
  if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
1154
0
    return false;
1155
0
  }
1156
0
1157
0
  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
1158
0
  if (!obj) {
1159
0
    return false;
1160
0
  }
1161
0
  rval.set(JS::ObjectValue(*obj));
1162
0
1163
0
  do {
1164
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1165
0
    JS::Rooted<JS::Value> temp(cx);
1166
0
    nsCString const & currentValue = mLocation;
1167
0
    if (!NonVoidByteStringToJsval(cx, currentValue, &temp)) {
1168
0
      return false;
1169
0
    }
1170
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->location_id, temp, JSPROP_ENUMERATE)) {
1171
0
      return false;
1172
0
    }
1173
0
    break;
1174
0
  } while(false);
1175
0
1176
0
  do {
1177
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1178
0
    JS::Rooted<JS::Value> temp(cx);
1179
0
    uint64_t const & currentValue = mRx;
1180
0
    temp.set(JS_NumberValue(double(currentValue)));
1181
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->rx_id, temp, JSPROP_ENUMERATE)) {
1182
0
      return false;
1183
0
    }
1184
0
    break;
1185
0
  } while(false);
1186
0
1187
0
  do {
1188
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1189
0
    JS::Rooted<JS::Value> temp(cx);
1190
0
    uint64_t const & currentValue = mTx;
1191
0
    temp.set(JS_NumberValue(double(currentValue)));
1192
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->tx_id, temp, JSPROP_ENUMERATE)) {
1193
0
      return false;
1194
0
    }
1195
0
    break;
1196
0
  } while(false);
1197
0
1198
0
  return true;
1199
0
}
1200
1201
bool
1202
IOActivityDataDictionary::ToJSON(nsAString& aJSON) const
1203
0
{
1204
0
  AutoJSAPI jsapi;
1205
0
  jsapi.Init();
1206
0
  JSContext *cx = jsapi.cx();
1207
0
  // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
1208
0
  // because we'll only be creating objects, in ways that have no
1209
0
  // side-effects, followed by a call to JS::ToJSONMaybeSafely,
1210
0
  // which likewise guarantees no side-effects for the sorts of
1211
0
  // things we will pass it.
1212
0
  JSAutoRealm ar(cx, UnprivilegedJunkScopeOrWorkerGlobal());
1213
0
  JS::Rooted<JS::Value> val(cx);
1214
0
  if (!ToObjectInternal(cx, &val)) {
1215
0
    return false;
1216
0
  }
1217
0
  JS::Rooted<JSObject*> obj(cx, &val.toObject());
1218
0
  return StringifyToJSON(cx, obj, aJSON);
1219
0
}
1220
1221
void
1222
IOActivityDataDictionary::TraceDictionary(JSTracer* trc)
1223
0
{
1224
0
}
1225
1226
IOActivityDataDictionary&
1227
IOActivityDataDictionary::operator=(const IOActivityDataDictionary& aOther)
1228
0
{
1229
0
  DictionaryBase::operator=(aOther);
1230
0
  mLocation = aOther.mLocation;
1231
0
  mRx = aOther.mRx;
1232
0
  mTx = aOther.mTx;
1233
0
  return *this;
1234
0
}
1235
1236
namespace binding_detail {
1237
} // namespace binding_detail
1238
1239
1240
1241
OriginAttributesDictionary::OriginAttributesDictionary()
1242
11.5k
{
1243
11.5k
  // Safe to pass a null context if we pass a null value
1244
11.5k
  Init(nullptr, JS::NullHandleValue);
1245
11.5k
}
1246
1247
1248
1249
bool
1250
OriginAttributesDictionary::InitIds(JSContext* cx, OriginAttributesDictionaryAtoms* atomsCache)
1251
0
{
1252
0
  MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
1253
0
1254
0
  // Initialize these in reverse order so that any failure leaves the first one
1255
0
  // uninitialized.
1256
0
  if (!atomsCache->userContextId_id.init(cx, "userContextId") ||
1257
0
      !atomsCache->privateBrowsingId_id.init(cx, "privateBrowsingId") ||
1258
0
      !atomsCache->inIsolatedMozBrowser_id.init(cx, "inIsolatedMozBrowser") ||
1259
0
      !atomsCache->firstPartyDomain_id.init(cx, "firstPartyDomain") ||
1260
0
      !atomsCache->appId_id.init(cx, "appId")) {
1261
0
    return false;
1262
0
  }
1263
0
  return true;
1264
0
}
1265
1266
bool
1267
OriginAttributesDictionary::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
1268
11.5k
{
1269
11.5k
  // Passing a null JSContext is OK only if we're initing from null,
1270
11.5k
  // Since in that case we will not have to do any property gets
1271
11.5k
  // Also evaluate isNullOrUndefined in order to avoid false-positive
1272
11.5k
  // checkers by static analysis tools
1273
11.5k
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
1274
11.5k
  OriginAttributesDictionaryAtoms* atomsCache = nullptr;
1275
11.5k
  if (cx) {
1276
0
    atomsCache = GetAtomCache<OriginAttributesDictionaryAtoms>(cx);
1277
0
    if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
1278
0
      return false;
1279
0
    }
1280
11.5k
  }
1281
11.5k
1282
11.5k
  if (!IsConvertibleToDictionary(val)) {
1283
0
    return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
1284
0
  }
1285
11.5k
1286
11.5k
  bool isNull = val.isNullOrUndefined();
1287
11.5k
  // We only need these if !isNull, in which case we have |cx|.
1288
11.5k
  Maybe<JS::Rooted<JSObject *> > object;
1289
11.5k
  Maybe<JS::Rooted<JS::Value> > temp;
1290
11.5k
  if (!isNull) {
1291
0
    MOZ_ASSERT(cx);
1292
0
    object.emplace(cx, &val.toObject());
1293
0
    temp.emplace(cx);
1294
0
  }
1295
11.5k
  if (!isNull) {
1296
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->appId_id, temp.ptr())) {
1297
0
      return false;
1298
0
    }
1299
11.5k
  }
1300
11.5k
  if (!isNull && !temp->isUndefined()) {
1301
0
    if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), &mAppId)) {
1302
0
      return false;
1303
0
    }
1304
11.5k
  } else {
1305
11.5k
    mAppId = 0U;
1306
11.5k
  }
1307
11.5k
  mIsAnyMemberPresent = true;
1308
11.5k
1309
11.5k
  if (!isNull) {
1310
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->firstPartyDomain_id, temp.ptr())) {
1311
0
      return false;
1312
0
    }
1313
11.5k
  }
1314
11.5k
  if (!isNull && !temp->isUndefined()) {
1315
0
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mFirstPartyDomain)) {
1316
0
      return false;
1317
0
    }
1318
11.5k
  } else {
1319
11.5k
    static const char16_t data[] = { 0 };
1320
11.5k
    mFirstPartyDomain.Rebind(data, ArrayLength(data) - 1);
1321
11.5k
  }
1322
11.5k
  mIsAnyMemberPresent = true;
1323
11.5k
1324
11.5k
  if (!isNull) {
1325
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->inIsolatedMozBrowser_id, temp.ptr())) {
1326
0
      return false;
1327
0
    }
1328
11.5k
  }
1329
11.5k
  if (!isNull && !temp->isUndefined()) {
1330
0
    if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &mInIsolatedMozBrowser)) {
1331
0
      return false;
1332
0
    }
1333
11.5k
  } else {
1334
11.5k
    mInIsolatedMozBrowser = false;
1335
11.5k
  }
1336
11.5k
  mIsAnyMemberPresent = true;
1337
11.5k
1338
11.5k
  if (!isNull) {
1339
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->privateBrowsingId_id, temp.ptr())) {
1340
0
      return false;
1341
0
    }
1342
11.5k
  }
1343
11.5k
  if (!isNull && !temp->isUndefined()) {
1344
0
    if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), &mPrivateBrowsingId)) {
1345
0
      return false;
1346
0
    }
1347
11.5k
  } else {
1348
11.5k
    mPrivateBrowsingId = 0U;
1349
11.5k
  }
1350
11.5k
  mIsAnyMemberPresent = true;
1351
11.5k
1352
11.5k
  if (!isNull) {
1353
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->userContextId_id, temp.ptr())) {
1354
0
      return false;
1355
0
    }
1356
11.5k
  }
1357
11.5k
  if (!isNull && !temp->isUndefined()) {
1358
0
    if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), &mUserContextId)) {
1359
0
      return false;
1360
0
    }
1361
11.5k
  } else {
1362
11.5k
    mUserContextId = 0U;
1363
11.5k
  }
1364
11.5k
  mIsAnyMemberPresent = true;
1365
11.5k
  return true;
1366
11.5k
}
1367
1368
bool
1369
OriginAttributesDictionary::Init(const nsAString& aJSON)
1370
0
{
1371
0
  AutoJSAPI jsapi;
1372
0
  JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
1373
0
  if (!cleanGlobal) {
1374
0
    return false;
1375
0
  }
1376
0
  if (!jsapi.Init(cleanGlobal)) {
1377
0
    return false;
1378
0
  }
1379
0
  JSContext* cx = jsapi.cx();
1380
0
  JS::Rooted<JS::Value> json(cx);
1381
0
  bool ok = ParseJSON(cx, aJSON, &json);
1382
0
  NS_ENSURE_TRUE(ok, false);
1383
0
  return Init(cx, json);
1384
0
}
1385
1386
bool
1387
OriginAttributesDictionary::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
1388
0
{
1389
0
  OriginAttributesDictionaryAtoms* atomsCache = GetAtomCache<OriginAttributesDictionaryAtoms>(cx);
1390
0
  if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
1391
0
    return false;
1392
0
  }
1393
0
1394
0
  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
1395
0
  if (!obj) {
1396
0
    return false;
1397
0
  }
1398
0
  rval.set(JS::ObjectValue(*obj));
1399
0
1400
0
  do {
1401
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1402
0
    JS::Rooted<JS::Value> temp(cx);
1403
0
    uint32_t const & currentValue = mAppId;
1404
0
    temp.setNumber(currentValue);
1405
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->appId_id, temp, JSPROP_ENUMERATE)) {
1406
0
      return false;
1407
0
    }
1408
0
    break;
1409
0
  } while(false);
1410
0
1411
0
  do {
1412
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1413
0
    JS::Rooted<JS::Value> temp(cx);
1414
0
    nsString const & currentValue = mFirstPartyDomain;
1415
0
    if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
1416
0
      return false;
1417
0
    }
1418
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->firstPartyDomain_id, temp, JSPROP_ENUMERATE)) {
1419
0
      return false;
1420
0
    }
1421
0
    break;
1422
0
  } while(false);
1423
0
1424
0
  do {
1425
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1426
0
    JS::Rooted<JS::Value> temp(cx);
1427
0
    bool const & currentValue = mInIsolatedMozBrowser;
1428
0
    temp.setBoolean(currentValue);
1429
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->inIsolatedMozBrowser_id, temp, JSPROP_ENUMERATE)) {
1430
0
      return false;
1431
0
    }
1432
0
    break;
1433
0
  } while(false);
1434
0
1435
0
  do {
1436
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1437
0
    JS::Rooted<JS::Value> temp(cx);
1438
0
    uint32_t const & currentValue = mPrivateBrowsingId;
1439
0
    temp.setNumber(currentValue);
1440
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->privateBrowsingId_id, temp, JSPROP_ENUMERATE)) {
1441
0
      return false;
1442
0
    }
1443
0
    break;
1444
0
  } while(false);
1445
0
1446
0
  do {
1447
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1448
0
    JS::Rooted<JS::Value> temp(cx);
1449
0
    uint32_t const & currentValue = mUserContextId;
1450
0
    temp.setNumber(currentValue);
1451
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->userContextId_id, temp, JSPROP_ENUMERATE)) {
1452
0
      return false;
1453
0
    }
1454
0
    break;
1455
0
  } while(false);
1456
0
1457
0
  return true;
1458
0
}
1459
1460
bool
1461
OriginAttributesDictionary::ToJSON(nsAString& aJSON) const
1462
0
{
1463
0
  AutoJSAPI jsapi;
1464
0
  jsapi.Init();
1465
0
  JSContext *cx = jsapi.cx();
1466
0
  // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
1467
0
  // because we'll only be creating objects, in ways that have no
1468
0
  // side-effects, followed by a call to JS::ToJSONMaybeSafely,
1469
0
  // which likewise guarantees no side-effects for the sorts of
1470
0
  // things we will pass it.
1471
0
  JSAutoRealm ar(cx, UnprivilegedJunkScopeOrWorkerGlobal());
1472
0
  JS::Rooted<JS::Value> val(cx);
1473
0
  if (!ToObjectInternal(cx, &val)) {
1474
0
    return false;
1475
0
  }
1476
0
  JS::Rooted<JSObject*> obj(cx, &val.toObject());
1477
0
  return StringifyToJSON(cx, obj, aJSON);
1478
0
}
1479
1480
void
1481
OriginAttributesDictionary::TraceDictionary(JSTracer* trc)
1482
0
{
1483
0
}
1484
1485
OriginAttributesDictionary&
1486
OriginAttributesDictionary::operator=(const OriginAttributesDictionary& aOther)
1487
5.79k
{
1488
5.79k
  DictionaryBase::operator=(aOther);
1489
5.79k
  mAppId = aOther.mAppId;
1490
5.79k
  mFirstPartyDomain = aOther.mFirstPartyDomain;
1491
5.79k
  mInIsolatedMozBrowser = aOther.mInIsolatedMozBrowser;
1492
5.79k
  mPrivateBrowsingId = aOther.mPrivateBrowsingId;
1493
5.79k
  mUserContextId = aOther.mUserContextId;
1494
5.79k
  return *this;
1495
5.79k
}
1496
1497
namespace binding_detail {
1498
} // namespace binding_detail
1499
1500
1501
1502
OriginAttributesPatternDictionary::OriginAttributesPatternDictionary()
1503
0
{
1504
0
  // Safe to pass a null context if we pass a null value
1505
0
  Init(nullptr, JS::NullHandleValue);
1506
0
}
1507
1508
1509
1510
bool
1511
OriginAttributesPatternDictionary::InitIds(JSContext* cx, OriginAttributesPatternDictionaryAtoms* atomsCache)
1512
0
{
1513
0
  MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
1514
0
1515
0
  // Initialize these in reverse order so that any failure leaves the first one
1516
0
  // uninitialized.
1517
0
  if (!atomsCache->userContextId_id.init(cx, "userContextId") ||
1518
0
      !atomsCache->privateBrowsingId_id.init(cx, "privateBrowsingId") ||
1519
0
      !atomsCache->inIsolatedMozBrowser_id.init(cx, "inIsolatedMozBrowser") ||
1520
0
      !atomsCache->firstPartyDomain_id.init(cx, "firstPartyDomain") ||
1521
0
      !atomsCache->appId_id.init(cx, "appId")) {
1522
0
    return false;
1523
0
  }
1524
0
  return true;
1525
0
}
1526
1527
bool
1528
OriginAttributesPatternDictionary::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
1529
0
{
1530
0
  // Passing a null JSContext is OK only if we're initing from null,
1531
0
  // Since in that case we will not have to do any property gets
1532
0
  // Also evaluate isNullOrUndefined in order to avoid false-positive
1533
0
  // checkers by static analysis tools
1534
0
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
1535
0
  OriginAttributesPatternDictionaryAtoms* atomsCache = nullptr;
1536
0
  if (cx) {
1537
0
    atomsCache = GetAtomCache<OriginAttributesPatternDictionaryAtoms>(cx);
1538
0
    if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
1539
0
      return false;
1540
0
    }
1541
0
  }
1542
0
1543
0
  if (!IsConvertibleToDictionary(val)) {
1544
0
    return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
1545
0
  }
1546
0
1547
0
  bool isNull = val.isNullOrUndefined();
1548
0
  // We only need these if !isNull, in which case we have |cx|.
1549
0
  Maybe<JS::Rooted<JSObject *> > object;
1550
0
  Maybe<JS::Rooted<JS::Value> > temp;
1551
0
  if (!isNull) {
1552
0
    MOZ_ASSERT(cx);
1553
0
    object.emplace(cx, &val.toObject());
1554
0
    temp.emplace(cx);
1555
0
  }
1556
0
  if (!isNull) {
1557
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->appId_id, temp.ptr())) {
1558
0
      return false;
1559
0
    }
1560
0
  }
1561
0
  if (!isNull && !temp->isUndefined()) {
1562
0
    mAppId.Construct();
1563
0
    if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), &(mAppId.Value()))) {
1564
0
      return false;
1565
0
    }
1566
0
    mIsAnyMemberPresent = true;
1567
0
  }
1568
0
1569
0
  if (!isNull) {
1570
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->firstPartyDomain_id, temp.ptr())) {
1571
0
      return false;
1572
0
    }
1573
0
  }
1574
0
  if (!isNull && !temp->isUndefined()) {
1575
0
    mFirstPartyDomain.Construct();
1576
0
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mFirstPartyDomain.Value()))) {
1577
0
      return false;
1578
0
    }
1579
0
    mIsAnyMemberPresent = true;
1580
0
  }
1581
0
1582
0
  if (!isNull) {
1583
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->inIsolatedMozBrowser_id, temp.ptr())) {
1584
0
      return false;
1585
0
    }
1586
0
  }
1587
0
  if (!isNull && !temp->isUndefined()) {
1588
0
    mInIsolatedMozBrowser.Construct();
1589
0
    if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &(mInIsolatedMozBrowser.Value()))) {
1590
0
      return false;
1591
0
    }
1592
0
    mIsAnyMemberPresent = true;
1593
0
  }
1594
0
1595
0
  if (!isNull) {
1596
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->privateBrowsingId_id, temp.ptr())) {
1597
0
      return false;
1598
0
    }
1599
0
  }
1600
0
  if (!isNull && !temp->isUndefined()) {
1601
0
    mPrivateBrowsingId.Construct();
1602
0
    if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), &(mPrivateBrowsingId.Value()))) {
1603
0
      return false;
1604
0
    }
1605
0
    mIsAnyMemberPresent = true;
1606
0
  }
1607
0
1608
0
  if (!isNull) {
1609
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->userContextId_id, temp.ptr())) {
1610
0
      return false;
1611
0
    }
1612
0
  }
1613
0
  if (!isNull && !temp->isUndefined()) {
1614
0
    mUserContextId.Construct();
1615
0
    if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), &(mUserContextId.Value()))) {
1616
0
      return false;
1617
0
    }
1618
0
    mIsAnyMemberPresent = true;
1619
0
  }
1620
0
  return true;
1621
0
}
1622
1623
bool
1624
OriginAttributesPatternDictionary::Init(const nsAString& aJSON)
1625
0
{
1626
0
  AutoJSAPI jsapi;
1627
0
  JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
1628
0
  if (!cleanGlobal) {
1629
0
    return false;
1630
0
  }
1631
0
  if (!jsapi.Init(cleanGlobal)) {
1632
0
    return false;
1633
0
  }
1634
0
  JSContext* cx = jsapi.cx();
1635
0
  JS::Rooted<JS::Value> json(cx);
1636
0
  bool ok = ParseJSON(cx, aJSON, &json);
1637
0
  NS_ENSURE_TRUE(ok, false);
1638
0
  return Init(cx, json);
1639
0
}
1640
1641
bool
1642
OriginAttributesPatternDictionary::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
1643
0
{
1644
0
  OriginAttributesPatternDictionaryAtoms* atomsCache = GetAtomCache<OriginAttributesPatternDictionaryAtoms>(cx);
1645
0
  if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
1646
0
    return false;
1647
0
  }
1648
0
1649
0
  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
1650
0
  if (!obj) {
1651
0
    return false;
1652
0
  }
1653
0
  rval.set(JS::ObjectValue(*obj));
1654
0
1655
0
  if (mAppId.WasPassed()) {
1656
0
    do {
1657
0
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1658
0
      JS::Rooted<JS::Value> temp(cx);
1659
0
      uint32_t const & currentValue = mAppId.InternalValue();
1660
0
      temp.setNumber(currentValue);
1661
0
      if (!JS_DefinePropertyById(cx, obj, atomsCache->appId_id, temp, JSPROP_ENUMERATE)) {
1662
0
        return false;
1663
0
      }
1664
0
      break;
1665
0
    } while(false);
1666
0
  }
1667
0
1668
0
  if (mFirstPartyDomain.WasPassed()) {
1669
0
    do {
1670
0
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1671
0
      JS::Rooted<JS::Value> temp(cx);
1672
0
      nsString const & currentValue = mFirstPartyDomain.InternalValue();
1673
0
      if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
1674
0
        return false;
1675
0
      }
1676
0
      if (!JS_DefinePropertyById(cx, obj, atomsCache->firstPartyDomain_id, temp, JSPROP_ENUMERATE)) {
1677
0
        return false;
1678
0
      }
1679
0
      break;
1680
0
    } while(false);
1681
0
  }
1682
0
1683
0
  if (mInIsolatedMozBrowser.WasPassed()) {
1684
0
    do {
1685
0
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1686
0
      JS::Rooted<JS::Value> temp(cx);
1687
0
      bool const & currentValue = mInIsolatedMozBrowser.InternalValue();
1688
0
      temp.setBoolean(currentValue);
1689
0
      if (!JS_DefinePropertyById(cx, obj, atomsCache->inIsolatedMozBrowser_id, temp, JSPROP_ENUMERATE)) {
1690
0
        return false;
1691
0
      }
1692
0
      break;
1693
0
    } while(false);
1694
0
  }
1695
0
1696
0
  if (mPrivateBrowsingId.WasPassed()) {
1697
0
    do {
1698
0
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1699
0
      JS::Rooted<JS::Value> temp(cx);
1700
0
      uint32_t const & currentValue = mPrivateBrowsingId.InternalValue();
1701
0
      temp.setNumber(currentValue);
1702
0
      if (!JS_DefinePropertyById(cx, obj, atomsCache->privateBrowsingId_id, temp, JSPROP_ENUMERATE)) {
1703
0
        return false;
1704
0
      }
1705
0
      break;
1706
0
    } while(false);
1707
0
  }
1708
0
1709
0
  if (mUserContextId.WasPassed()) {
1710
0
    do {
1711
0
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1712
0
      JS::Rooted<JS::Value> temp(cx);
1713
0
      uint32_t const & currentValue = mUserContextId.InternalValue();
1714
0
      temp.setNumber(currentValue);
1715
0
      if (!JS_DefinePropertyById(cx, obj, atomsCache->userContextId_id, temp, JSPROP_ENUMERATE)) {
1716
0
        return false;
1717
0
      }
1718
0
      break;
1719
0
    } while(false);
1720
0
  }
1721
0
1722
0
  return true;
1723
0
}
1724
1725
bool
1726
OriginAttributesPatternDictionary::ToJSON(nsAString& aJSON) const
1727
0
{
1728
0
  AutoJSAPI jsapi;
1729
0
  jsapi.Init();
1730
0
  JSContext *cx = jsapi.cx();
1731
0
  // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
1732
0
  // because we'll only be creating objects, in ways that have no
1733
0
  // side-effects, followed by a call to JS::ToJSONMaybeSafely,
1734
0
  // which likewise guarantees no side-effects for the sorts of
1735
0
  // things we will pass it.
1736
0
  JSAutoRealm ar(cx, UnprivilegedJunkScopeOrWorkerGlobal());
1737
0
  JS::Rooted<JS::Value> val(cx);
1738
0
  if (!ToObjectInternal(cx, &val)) {
1739
0
    return false;
1740
0
  }
1741
0
  JS::Rooted<JSObject*> obj(cx, &val.toObject());
1742
0
  return StringifyToJSON(cx, obj, aJSON);
1743
0
}
1744
1745
void
1746
OriginAttributesPatternDictionary::TraceDictionary(JSTracer* trc)
1747
0
{
1748
0
}
1749
1750
OriginAttributesPatternDictionary&
1751
OriginAttributesPatternDictionary::operator=(const OriginAttributesPatternDictionary& aOther)
1752
0
{
1753
0
  DictionaryBase::operator=(aOther);
1754
0
  mAppId.Reset();
1755
0
  if (aOther.mAppId.WasPassed()) {
1756
0
    mAppId.Construct(aOther.mAppId.Value());
1757
0
  }
1758
0
  mFirstPartyDomain.Reset();
1759
0
  if (aOther.mFirstPartyDomain.WasPassed()) {
1760
0
    mFirstPartyDomain.Construct(aOther.mFirstPartyDomain.Value());
1761
0
  }
1762
0
  mInIsolatedMozBrowser.Reset();
1763
0
  if (aOther.mInIsolatedMozBrowser.WasPassed()) {
1764
0
    mInIsolatedMozBrowser.Construct(aOther.mInIsolatedMozBrowser.Value());
1765
0
  }
1766
0
  mPrivateBrowsingId.Reset();
1767
0
  if (aOther.mPrivateBrowsingId.WasPassed()) {
1768
0
    mPrivateBrowsingId.Construct(aOther.mPrivateBrowsingId.Value());
1769
0
  }
1770
0
  mUserContextId.Reset();
1771
0
  if (aOther.mUserContextId.WasPassed()) {
1772
0
    mUserContextId.Construct(aOther.mUserContextId.Value());
1773
0
  }
1774
0
  return *this;
1775
0
}
1776
1777
namespace binding_detail {
1778
} // namespace binding_detail
1779
1780
1781
bool
1782
StringOrIID::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
1783
0
{
1784
0
  switch (mType) {
1785
0
    case eUninitialized: {
1786
0
      return false;
1787
0
      break;
1788
0
    }
1789
0
    case eString: {
1790
0
      if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
1791
0
        return false;
1792
0
      }
1793
0
      return true;
1794
0
      break;
1795
0
    }
1796
0
    case eIID: {
1797
0
      if (!WrapObject(cx, mValue.mIID.Value(), rval)) {
1798
0
        return false;
1799
0
      }
1800
0
      return true;
1801
0
      break;
1802
0
    }
1803
0
    default: {
1804
0
      return false;
1805
0
      break;
1806
0
    }
1807
0
  }
1808
0
1809
0
  return false;
1810
0
}
1811
1812
1813
nsString&
1814
OwningStringOrIID::RawSetAsString()
1815
0
{
1816
0
  if (mType == eString) {
1817
0
    return mValue.mString.Value();
1818
0
  }
1819
0
  MOZ_ASSERT(mType == eUninitialized);
1820
0
  mType = eString;
1821
0
  return mValue.mString.SetValue();
1822
0
}
1823
1824
nsString&
1825
OwningStringOrIID::SetAsString()
1826
0
{
1827
0
  if (mType == eString) {
1828
0
    return mValue.mString.Value();
1829
0
  }
1830
0
  Uninit();
1831
0
  mType = eString;
1832
0
  return mValue.mString.SetValue();
1833
0
}
1834
1835
bool
1836
OwningStringOrIID::TrySetToString(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
1837
0
{
1838
0
  tryNext = false;
1839
0
  { // scope for memberSlot
1840
0
    nsString& memberSlot = RawSetAsString();
1841
0
    if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
1842
0
      return false;
1843
0
    }
1844
0
  }
1845
0
  return true;
1846
0
}
1847
1848
1849
void
1850
OwningStringOrIID::DestroyString()
1851
0
{
1852
0
  MOZ_ASSERT(IsString(), "Wrong type!");
1853
0
  mValue.mString.Destroy();
1854
0
  mType = eUninitialized;
1855
0
}
1856
1857
1858
1859
1860
RefPtr<nsIJSID>&
1861
OwningStringOrIID::RawSetAsIID()
1862
4
{
1863
4
  if (mType == eIID) {
1864
0
    return mValue.mIID.Value();
1865
0
  }
1866
4
  MOZ_ASSERT(mType == eUninitialized);
1867
4
  mType = eIID;
1868
4
  return mValue.mIID.SetValue();
1869
4
}
1870
1871
RefPtr<nsIJSID>&
1872
OwningStringOrIID::SetAsIID()
1873
0
{
1874
0
  if (mType == eIID) {
1875
0
    return mValue.mIID.Value();
1876
0
  }
1877
0
  Uninit();
1878
0
  mType = eIID;
1879
0
  return mValue.mIID.SetValue();
1880
0
}
1881
1882
bool
1883
OwningStringOrIID::TrySetToIID(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
1884
4
{
1885
4
  tryNext = false;
1886
4
  { // scope for memberSlot
1887
4
    RefPtr<nsIJSID>& memberSlot = RawSetAsIID();
1888
4
    static_assert(IsRefcounted<nsIJSID>::value, "We can only store refcounted classes.");RefPtr<nsIJSID> mIIDHolder;
1889
4
    JS::Rooted<JSObject*> source(cx, &value.toObject());
1890
4
    if (NS_FAILED(UnwrapArg<nsIJSID>(cx, source, getter_AddRefs(mIIDHolder)))) {
1891
0
      DestroyIID();
1892
0
      tryNext = true;
1893
0
      return true;
1894
0
    }
1895
4
    MOZ_ASSERT(mIIDHolder);
1896
4
    memberSlot = mIIDHolder;
1897
4
  }
1898
4
  return true;
1899
4
}
1900
1901
void
1902
OwningStringOrIID::DestroyIID()
1903
4
{
1904
4
  MOZ_ASSERT(IsIID(), "Wrong type!");
1905
4
  mValue.mIID.Destroy();
1906
4
  mType = eUninitialized;
1907
4
}
1908
1909
1910
1911
1912
void
1913
OwningStringOrIID::Uninit()
1914
4
{
1915
4
  switch (mType) {
1916
4
    case eUninitialized: {
1917
0
      break;
1918
4
    }
1919
4
    case eString: {
1920
0
      DestroyString();
1921
0
      break;
1922
4
    }
1923
4
    case eIID: {
1924
4
      DestroyIID();
1925
4
      break;
1926
4
    }
1927
4
  }
1928
4
}
1929
1930
bool
1931
OwningStringOrIID::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
1932
0
{
1933
0
  switch (mType) {
1934
0
    case eUninitialized: {
1935
0
      return false;
1936
0
      break;
1937
0
    }
1938
0
    case eString: {
1939
0
      if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
1940
0
        return false;
1941
0
      }
1942
0
      return true;
1943
0
      break;
1944
0
    }
1945
0
    case eIID: {
1946
0
      if (!WrapObject(cx, mValue.mIID.Value(), rval)) {
1947
0
        return false;
1948
0
      }
1949
0
      return true;
1950
0
      break;
1951
0
    }
1952
0
    default: {
1953
0
      return false;
1954
0
      break;
1955
0
    }
1956
0
  }
1957
0
1958
0
  return false;
1959
0
}
1960
1961
void
1962
OwningStringOrIID::TraceUnion(JSTracer* trc)
1963
0
{
1964
0
}
1965
1966
OwningStringOrIID&
1967
OwningStringOrIID::operator=(const OwningStringOrIID& aOther)
1968
0
{
1969
0
  switch (aOther.mType) {
1970
0
    case eUninitialized: {
1971
0
      MOZ_ASSERT(mType == eUninitialized,
1972
0
                 "We need to destroy ourselves?");
1973
0
      break;
1974
0
    }
1975
0
    case eString: {
1976
0
      SetAsString() = aOther.GetAsString();
1977
0
      break;
1978
0
    }
1979
0
    case eIID: {
1980
0
      SetAsIID() = aOther.GetAsIID();
1981
0
      break;
1982
0
    }
1983
0
  }
1984
0
  return *this;
1985
0
}
1986
1987
1988
1989
PerformanceInfoDictionary::PerformanceInfoDictionary()
1990
0
{
1991
0
  // Safe to pass a null context if we pass a null value
1992
0
  Init(nullptr, JS::NullHandleValue);
1993
0
}
1994
1995
1996
1997
bool
1998
PerformanceInfoDictionary::InitIds(JSContext* cx, PerformanceInfoDictionaryAtoms* atomsCache)
1999
0
{
2000
0
  MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
2001
0
2002
0
  // Initialize these in reverse order so that any failure leaves the first one
2003
0
  // uninitialized.
2004
0
  if (!atomsCache->windowId_id.init(cx, "windowId") ||
2005
0
      !atomsCache->pid_id.init(cx, "pid") ||
2006
0
      !atomsCache->items_id.init(cx, "items") ||
2007
0
      !atomsCache->isWorker_id.init(cx, "isWorker") ||
2008
0
      !atomsCache->isTopLevel_id.init(cx, "isTopLevel") ||
2009
0
      !atomsCache->host_id.init(cx, "host") ||
2010
0
      !atomsCache->duration_id.init(cx, "duration") ||
2011
0
      !atomsCache->counterId_id.init(cx, "counterId")) {
2012
0
    return false;
2013
0
  }
2014
0
  return true;
2015
0
}
2016
2017
bool
2018
PerformanceInfoDictionary::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
2019
0
{
2020
0
  // Passing a null JSContext is OK only if we're initing from null,
2021
0
  // Since in that case we will not have to do any property gets
2022
0
  // Also evaluate isNullOrUndefined in order to avoid false-positive
2023
0
  // checkers by static analysis tools
2024
0
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
2025
0
  PerformanceInfoDictionaryAtoms* atomsCache = nullptr;
2026
0
  if (cx) {
2027
0
    atomsCache = GetAtomCache<PerformanceInfoDictionaryAtoms>(cx);
2028
0
    if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
2029
0
      return false;
2030
0
    }
2031
0
  }
2032
0
2033
0
  if (!IsConvertibleToDictionary(val)) {
2034
0
    return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
2035
0
  }
2036
0
2037
0
  bool isNull = val.isNullOrUndefined();
2038
0
  // We only need these if !isNull, in which case we have |cx|.
2039
0
  Maybe<JS::Rooted<JSObject *> > object;
2040
0
  Maybe<JS::Rooted<JS::Value> > temp;
2041
0
  if (!isNull) {
2042
0
    MOZ_ASSERT(cx);
2043
0
    object.emplace(cx, &val.toObject());
2044
0
    temp.emplace(cx);
2045
0
  }
2046
0
  if (!isNull) {
2047
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->counterId_id, temp.ptr())) {
2048
0
      return false;
2049
0
    }
2050
0
  }
2051
0
  if (!isNull && !temp->isUndefined()) {
2052
0
    if (!ValueToPrimitive<uint64_t, eDefault>(cx, temp.ref(), &mCounterId)) {
2053
0
      return false;
2054
0
    }
2055
0
  } else {
2056
0
    mCounterId = 0ULL;
2057
0
  }
2058
0
  mIsAnyMemberPresent = true;
2059
0
2060
0
  if (!isNull) {
2061
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->duration_id, temp.ptr())) {
2062
0
      return false;
2063
0
    }
2064
0
  }
2065
0
  if (!isNull && !temp->isUndefined()) {
2066
0
    if (!ValueToPrimitive<uint64_t, eDefault>(cx, temp.ref(), &mDuration)) {
2067
0
      return false;
2068
0
    }
2069
0
  } else {
2070
0
    mDuration = 0ULL;
2071
0
  }
2072
0
  mIsAnyMemberPresent = true;
2073
0
2074
0
  if (!isNull) {
2075
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->host_id, temp.ptr())) {
2076
0
      return false;
2077
0
    }
2078
0
  }
2079
0
  if (!isNull && !temp->isUndefined()) {
2080
0
    if (!ConvertJSValueToByteString(cx, temp.ref(), false, mHost)) {
2081
0
      return false;
2082
0
    }
2083
0
  } else {
2084
0
    static const char data[] = { 0 };
2085
0
    mHost.Rebind(data, ArrayLength(data) - 1);
2086
0
  }
2087
0
  mIsAnyMemberPresent = true;
2088
0
2089
0
  if (!isNull) {
2090
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->isTopLevel_id, temp.ptr())) {
2091
0
      return false;
2092
0
    }
2093
0
  }
2094
0
  if (!isNull && !temp->isUndefined()) {
2095
0
    if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &mIsTopLevel)) {
2096
0
      return false;
2097
0
    }
2098
0
  } else {
2099
0
    mIsTopLevel = false;
2100
0
  }
2101
0
  mIsAnyMemberPresent = true;
2102
0
2103
0
  if (!isNull) {
2104
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->isWorker_id, temp.ptr())) {
2105
0
      return false;
2106
0
    }
2107
0
  }
2108
0
  if (!isNull && !temp->isUndefined()) {
2109
0
    if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &mIsWorker)) {
2110
0
      return false;
2111
0
    }
2112
0
  } else {
2113
0
    mIsWorker = false;
2114
0
  }
2115
0
  mIsAnyMemberPresent = true;
2116
0
2117
0
  if (!isNull) {
2118
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->items_id, temp.ptr())) {
2119
0
      return false;
2120
0
    }
2121
0
  }
2122
0
  if (!isNull && !temp->isUndefined()) {
2123
0
    if (temp.ref().isObject()) {
2124
0
      JS::ForOfIterator iter(cx);
2125
0
      if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
2126
0
        return false;
2127
0
      }
2128
0
      if (!iter.valueIsIterable()) {
2129
0
        ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'items' member of PerformanceInfoDictionary");
2130
0
        return false;
2131
0
      }
2132
0
      Sequence<CategoryDispatchDictionary> &arr = mItems;
2133
0
      JS::Rooted<JS::Value> temp(cx);
2134
0
      while (true) {
2135
0
        bool done;
2136
0
        if (!iter.next(&temp, &done)) {
2137
0
          return false;
2138
0
        }
2139
0
        if (done) {
2140
0
          break;
2141
0
        }
2142
0
        CategoryDispatchDictionary* slotPtr = arr.AppendElement(mozilla::fallible);
2143
0
        if (!slotPtr) {
2144
0
          JS_ReportOutOfMemory(cx);
2145
0
          return false;
2146
0
        }
2147
0
        CategoryDispatchDictionary& slot = *slotPtr;
2148
0
        if (!slot.Init(cx, temp,  "Element of 'items' member of PerformanceInfoDictionary", passedToJSImpl)) {
2149
0
          return false;
2150
0
        }
2151
0
      }
2152
0
    } else {
2153
0
      ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'items' member of PerformanceInfoDictionary");
2154
0
      return false;
2155
0
    }
2156
0
  } else {
2157
0
    /* Array is already empty; nothing to do */
2158
0
  }
2159
0
  mIsAnyMemberPresent = true;
2160
0
2161
0
  if (!isNull) {
2162
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->pid_id, temp.ptr())) {
2163
0
      return false;
2164
0
    }
2165
0
  }
2166
0
  if (!isNull && !temp->isUndefined()) {
2167
0
    if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), &mPid)) {
2168
0
      return false;
2169
0
    }
2170
0
  } else {
2171
0
    mPid = 0U;
2172
0
  }
2173
0
  mIsAnyMemberPresent = true;
2174
0
2175
0
  if (!isNull) {
2176
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->windowId_id, temp.ptr())) {
2177
0
      return false;
2178
0
    }
2179
0
  }
2180
0
  if (!isNull && !temp->isUndefined()) {
2181
0
    if (!ValueToPrimitive<uint64_t, eDefault>(cx, temp.ref(), &mWindowId)) {
2182
0
      return false;
2183
0
    }
2184
0
  } else {
2185
0
    mWindowId = 0ULL;
2186
0
  }
2187
0
  mIsAnyMemberPresent = true;
2188
0
  return true;
2189
0
}
2190
2191
bool
2192
PerformanceInfoDictionary::Init(const nsAString& aJSON)
2193
0
{
2194
0
  AutoJSAPI jsapi;
2195
0
  JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
2196
0
  if (!cleanGlobal) {
2197
0
    return false;
2198
0
  }
2199
0
  if (!jsapi.Init(cleanGlobal)) {
2200
0
    return false;
2201
0
  }
2202
0
  JSContext* cx = jsapi.cx();
2203
0
  JS::Rooted<JS::Value> json(cx);
2204
0
  bool ok = ParseJSON(cx, aJSON, &json);
2205
0
  NS_ENSURE_TRUE(ok, false);
2206
0
  return Init(cx, json);
2207
0
}
2208
2209
bool
2210
PerformanceInfoDictionary::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
2211
0
{
2212
0
  PerformanceInfoDictionaryAtoms* atomsCache = GetAtomCache<PerformanceInfoDictionaryAtoms>(cx);
2213
0
  if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
2214
0
    return false;
2215
0
  }
2216
0
2217
0
  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
2218
0
  if (!obj) {
2219
0
    return false;
2220
0
  }
2221
0
  rval.set(JS::ObjectValue(*obj));
2222
0
2223
0
  do {
2224
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
2225
0
    JS::Rooted<JS::Value> temp(cx);
2226
0
    uint64_t const & currentValue = mCounterId;
2227
0
    temp.set(JS_NumberValue(double(currentValue)));
2228
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->counterId_id, temp, JSPROP_ENUMERATE)) {
2229
0
      return false;
2230
0
    }
2231
0
    break;
2232
0
  } while(false);
2233
0
2234
0
  do {
2235
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
2236
0
    JS::Rooted<JS::Value> temp(cx);
2237
0
    uint64_t const & currentValue = mDuration;
2238
0
    temp.set(JS_NumberValue(double(currentValue)));
2239
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->duration_id, temp, JSPROP_ENUMERATE)) {
2240
0
      return false;
2241
0
    }
2242
0
    break;
2243
0
  } while(false);
2244
0
2245
0
  do {
2246
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
2247
0
    JS::Rooted<JS::Value> temp(cx);
2248
0
    nsCString const & currentValue = mHost;
2249
0
    if (!NonVoidByteStringToJsval(cx, currentValue, &temp)) {
2250
0
      return false;
2251
0
    }
2252
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->host_id, temp, JSPROP_ENUMERATE)) {
2253
0
      return false;
2254
0
    }
2255
0
    break;
2256
0
  } while(false);
2257
0
2258
0
  do {
2259
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
2260
0
    JS::Rooted<JS::Value> temp(cx);
2261
0
    bool const & currentValue = mIsTopLevel;
2262
0
    temp.setBoolean(currentValue);
2263
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->isTopLevel_id, temp, JSPROP_ENUMERATE)) {
2264
0
      return false;
2265
0
    }
2266
0
    break;
2267
0
  } while(false);
2268
0
2269
0
  do {
2270
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
2271
0
    JS::Rooted<JS::Value> temp(cx);
2272
0
    bool const & currentValue = mIsWorker;
2273
0
    temp.setBoolean(currentValue);
2274
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->isWorker_id, temp, JSPROP_ENUMERATE)) {
2275
0
      return false;
2276
0
    }
2277
0
    break;
2278
0
  } while(false);
2279
0
2280
0
  do {
2281
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
2282
0
    JS::Rooted<JS::Value> temp(cx);
2283
0
    Sequence<CategoryDispatchDictionary> const & currentValue = mItems;
2284
0
2285
0
    uint32_t length = currentValue.Length();
2286
0
    JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
2287
0
    if (!returnArray) {
2288
0
      return false;
2289
0
    }
2290
0
    // Scope for 'tmp'
2291
0
    {
2292
0
      JS::Rooted<JS::Value> tmp(cx);
2293
0
      for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
2294
0
        // Control block to let us common up the JS_DefineElement calls when there
2295
0
        // are different ways to succeed at wrapping the object.
2296
0
        do {
2297
0
          if (!currentValue[sequenceIdx0].ToObjectInternal(cx, &tmp)) {
2298
0
            return false;
2299
0
          }
2300
0
          break;
2301
0
        } while (false);
2302
0
        if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
2303
0
                              JSPROP_ENUMERATE)) {
2304
0
          return false;
2305
0
        }
2306
0
      }
2307
0
    }
2308
0
    temp.setObject(*returnArray);
2309
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->items_id, temp, JSPROP_ENUMERATE)) {
2310
0
      return false;
2311
0
    }
2312
0
    break;
2313
0
  } while(false);
2314
0
2315
0
  do {
2316
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
2317
0
    JS::Rooted<JS::Value> temp(cx);
2318
0
    uint32_t const & currentValue = mPid;
2319
0
    temp.setNumber(currentValue);
2320
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->pid_id, temp, JSPROP_ENUMERATE)) {
2321
0
      return false;
2322
0
    }
2323
0
    break;
2324
0
  } while(false);
2325
0
2326
0
  do {
2327
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
2328
0
    JS::Rooted<JS::Value> temp(cx);
2329
0
    uint64_t const & currentValue = mWindowId;
2330
0
    temp.set(JS_NumberValue(double(currentValue)));
2331
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->windowId_id, temp, JSPROP_ENUMERATE)) {
2332
0
      return false;
2333
0
    }
2334
0
    break;
2335
0
  } while(false);
2336
0
2337
0
  return true;
2338
0
}
2339
2340
bool
2341
PerformanceInfoDictionary::ToJSON(nsAString& aJSON) const
2342
0
{
2343
0
  AutoJSAPI jsapi;
2344
0
  jsapi.Init();
2345
0
  JSContext *cx = jsapi.cx();
2346
0
  // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
2347
0
  // because we'll only be creating objects, in ways that have no
2348
0
  // side-effects, followed by a call to JS::ToJSONMaybeSafely,
2349
0
  // which likewise guarantees no side-effects for the sorts of
2350
0
  // things we will pass it.
2351
0
  JSAutoRealm ar(cx, UnprivilegedJunkScopeOrWorkerGlobal());
2352
0
  JS::Rooted<JS::Value> val(cx);
2353
0
  if (!ToObjectInternal(cx, &val)) {
2354
0
    return false;
2355
0
  }
2356
0
  JS::Rooted<JSObject*> obj(cx, &val.toObject());
2357
0
  return StringifyToJSON(cx, obj, aJSON);
2358
0
}
2359
2360
void
2361
PerformanceInfoDictionary::TraceDictionary(JSTracer* trc)
2362
0
{
2363
0
}
2364
2365
PerformanceInfoDictionary&
2366
PerformanceInfoDictionary::operator=(const PerformanceInfoDictionary& aOther)
2367
0
{
2368
0
  DictionaryBase::operator=(aOther);
2369
0
  mCounterId = aOther.mCounterId;
2370
0
  mDuration = aOther.mDuration;
2371
0
  mHost = aOther.mHost;
2372
0
  mIsTopLevel = aOther.mIsTopLevel;
2373
0
  mIsWorker = aOther.mIsWorker;
2374
0
  mItems = aOther.mItems;
2375
0
  mPid = aOther.mPid;
2376
0
  mWindowId = aOther.mWindowId;
2377
0
  return *this;
2378
0
}
2379
2380
namespace binding_detail {
2381
} // namespace binding_detail
2382
2383
2384
namespace ChromeUtils_Binding {
2385
2386
static bool
2387
saveHeapSnapshot(JSContext* cx, unsigned argc, JS::Value* vp)
2388
0
{
2389
0
  AUTO_PROFILER_LABEL_FAST("ChromeUtils.saveHeapSnapshot", DOM, cx);
2390
0
2391
0
  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
2392
0
  JS::Rooted<JSObject*> obj(cx, &args.callee());
2393
0
2394
0
  GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
2395
0
  if (global.Failed()) {
2396
0
    return false;
2397
0
  }
2398
0
2399
0
  RootedDictionary<binding_detail::FastHeapSnapshotBoundaries> arg0(cx);
2400
0
  if (!arg0.Init(cx, (args.hasDefined(0)) ? args[0] : JS::NullHandleValue,  "Argument 1 of ChromeUtils.saveHeapSnapshot", false)) {
2401
0
    return false;
2402
0
  }
2403
0
  FastErrorResult rv;
2404
0
  DOMString result;
2405
0
  mozilla::dom::ChromeUtils::SaveHeapSnapshot(global, Constify(arg0), result, rv);
2406
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
2407
0
    return false;
2408
0
  }
2409
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
2410
0
  if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
2411
0
    return false;
2412
0
  }
2413
0
  return true;
2414
0
}
2415
2416
static bool
2417
saveHeapSnapshotGetId(JSContext* cx, unsigned argc, JS::Value* vp)
2418
0
{
2419
0
  AUTO_PROFILER_LABEL_FAST("ChromeUtils.saveHeapSnapshotGetId", DOM, cx);
2420
0
2421
0
  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
2422
0
  JS::Rooted<JSObject*> obj(cx, &args.callee());
2423
0
2424
0
  GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
2425
0
  if (global.Failed()) {
2426
0
    return false;
2427
0
  }
2428
0
2429
0
  RootedDictionary<binding_detail::FastHeapSnapshotBoundaries> arg0(cx);
2430
0
  if (!arg0.Init(cx, (args.hasDefined(0)) ? args[0] : JS::NullHandleValue,  "Argument 1 of ChromeUtils.saveHeapSnapshotGetId", false)) {
2431
0
    return false;
2432
0
  }
2433
0
  FastErrorResult rv;
2434
0
  DOMString result;
2435
0
  mozilla::dom::ChromeUtils::SaveHeapSnapshotGetId(global, Constify(arg0), result, rv);
2436
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
2437
0
    return false;
2438
0
  }
2439
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
2440
0
  if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
2441
0
    return false;
2442
0
  }
2443
0
  return true;
2444
0
}
2445
2446
static bool
2447
readHeapSnapshot(JSContext* cx, unsigned argc, JS::Value* vp)
2448
0
{
2449
0
  AUTO_PROFILER_LABEL_FAST("ChromeUtils.readHeapSnapshot", DOM, cx);
2450
0
2451
0
  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
2452
0
  JS::Rooted<JSObject*> obj(cx, &args.callee());
2453
0
2454
0
  if (MOZ_UNLIKELY(args.length() < 1)) {
2455
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "ChromeUtils.readHeapSnapshot");
2456
0
  }
2457
0
  GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
2458
0
  if (global.Failed()) {
2459
0
    return false;
2460
0
  }
2461
0
2462
0
  binding_detail::FakeString arg0;
2463
0
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
2464
0
    return false;
2465
0
  }
2466
0
  FastErrorResult rv;
2467
0
  auto result(StrongOrRawPtr<mozilla::devtools::HeapSnapshot>(mozilla::dom::ChromeUtils::ReadHeapSnapshot(global, NonNullHelper(Constify(arg0)), rv)));
2468
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
2469
0
    return false;
2470
0
  }
2471
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
2472
0
  static_assert(!IsPointer<decltype(result)>::value,
2473
0
                "NewObject implies that we need to keep the object alive with a strong reference.");
2474
0
  if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
2475
0
    MOZ_ASSERT(JS_IsExceptionPending(cx));
2476
0
    return false;
2477
0
  }
2478
0
  return true;
2479
0
}
2480
2481
static bool
2482
nondeterministicGetWeakMapKeys(JSContext* cx, unsigned argc, JS::Value* vp)
2483
0
{
2484
0
  AUTO_PROFILER_LABEL_FAST("ChromeUtils.nondeterministicGetWeakMapKeys", DOM, cx);
2485
0
2486
0
  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
2487
0
  JS::Rooted<JSObject*> obj(cx, &args.callee());
2488
0
2489
0
  if (MOZ_UNLIKELY(args.length() < 1)) {
2490
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "ChromeUtils.nondeterministicGetWeakMapKeys");
2491
0
  }
2492
0
  GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
2493
0
  if (global.Failed()) {
2494
0
    return false;
2495
0
  }
2496
0
2497
0
  JS::Rooted<JS::Value> arg0(cx);
2498
0
  arg0 = args[0];
2499
0
  FastErrorResult rv;
2500
0
  JS::Rooted<JS::Value> result(cx);
2501
0
  mozilla::dom::ChromeUtils::NondeterministicGetWeakMapKeys(global, arg0, &result, rv);
2502
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
2503
0
    return false;
2504
0
  }
2505
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
2506
0
  JS::ExposeValueToActiveJS(result);
2507
0
  args.rval().set(result);
2508
0
  if (!MaybeWrapValue(cx, args.rval())) {
2509
0
    return false;
2510
0
  }
2511
0
  return true;
2512
0
}
2513
2514
static bool
2515
nondeterministicGetWeakSetKeys(JSContext* cx, unsigned argc, JS::Value* vp)
2516
0
{
2517
0
  AUTO_PROFILER_LABEL_FAST("ChromeUtils.nondeterministicGetWeakSetKeys", DOM, cx);
2518
0
2519
0
  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
2520
0
  JS::Rooted<JSObject*> obj(cx, &args.callee());
2521
0
2522
0
  if (MOZ_UNLIKELY(args.length() < 1)) {
2523
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "ChromeUtils.nondeterministicGetWeakSetKeys");
2524
0
  }
2525
0
  GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
2526
0
  if (global.Failed()) {
2527
0
    return false;
2528
0
  }
2529
0
2530
0
  JS::Rooted<JS::Value> arg0(cx);
2531
0
  arg0 = args[0];
2532
0
  FastErrorResult rv;
2533
0
  JS::Rooted<JS::Value> result(cx);
2534
0
  mozilla::dom::ChromeUtils::NondeterministicGetWeakSetKeys(global, arg0, &result, rv);
2535
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
2536
0
    return false;
2537
0
  }
2538
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
2539
0
  JS::ExposeValueToActiveJS(result);
2540
0
  args.rval().set(result);
2541
0
  if (!MaybeWrapValue(cx, args.rval())) {
2542
0
    return false;
2543
0
  }
2544
0
  return true;
2545
0
}
2546
2547
static bool
2548
base64URLEncode(JSContext* cx, unsigned argc, JS::Value* vp)
2549
0
{
2550
0
  AUTO_PROFILER_LABEL_FAST("ChromeUtils.base64URLEncode", DOM, cx);
2551
0
2552
0
  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
2553
0
  JS::Rooted<JSObject*> obj(cx, &args.callee());
2554
0
2555
0
  if (MOZ_UNLIKELY(args.length() < 2)) {
2556
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "ChromeUtils.base64URLEncode");
2557
0
  }
2558
0
  GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
2559
0
  if (global.Failed()) {
2560
0
    return false;
2561
0
  }
2562
0
2563
0
  ArrayBufferViewOrArrayBuffer arg0;
2564
0
  ArrayBufferViewOrArrayBufferArgument arg0_holder(arg0);
2565
0
  {
2566
0
    bool done = false, failed = false, tryNext;
2567
0
    if (args[0].isObject()) {
2568
0
      done = (failed = !arg0_holder.TrySetToArrayBufferView(cx, args[0], tryNext, false)) || !tryNext ||
2569
0
             (failed = !arg0_holder.TrySetToArrayBuffer(cx, args[0], tryNext, false)) || !tryNext;
2570
0
2571
0
    }
2572
0
    if (failed) {
2573
0
      return false;
2574
0
    }
2575
0
    if (!done) {
2576
0
      ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "Argument 1 of ChromeUtils.base64URLEncode", "ArrayBufferView, ArrayBuffer");
2577
0
      return false;
2578
0
    }
2579
0
  }
2580
0
  binding_detail::FastBase64URLEncodeOptions arg1;
2581
0
  if (!arg1.Init(cx, args[1],  "Argument 2 of ChromeUtils.base64URLEncode", false)) {
2582
0
    return false;
2583
0
  }
2584
0
  FastErrorResult rv;
2585
0
  nsCString result;
2586
0
  mozilla::dom::ChromeUtils::Base64URLEncode(global, Constify(arg0), Constify(arg1), result, rv);
2587
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
2588
0
    return false;
2589
0
  }
2590
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
2591
0
  if (!NonVoidByteStringToJsval(cx, result, args.rval())) {
2592
0
    return false;
2593
0
  }
2594
0
  return true;
2595
0
}
2596
2597
static bool
2598
base64URLDecode(JSContext* cx, unsigned argc, JS::Value* vp)
2599
0
{
2600
0
  AUTO_PROFILER_LABEL_FAST("ChromeUtils.base64URLDecode", DOM, cx);
2601
0
2602
0
  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
2603
0
  JS::Rooted<JSObject*> obj(cx, &args.callee());
2604
0
2605
0
  if (MOZ_UNLIKELY(args.length() < 2)) {
2606
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "ChromeUtils.base64URLDecode");
2607
0
  }
2608
0
  GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
2609
0
  if (global.Failed()) {
2610
0
    return false;
2611
0
  }
2612
0
2613
0
  nsCString arg0;
2614
0
  if (!ConvertJSValueToByteString(cx, args[0], false, arg0)) {
2615
0
    return false;
2616
0
  }
2617
0
  binding_detail::FastBase64URLDecodeOptions arg1;
2618
0
  if (!arg1.Init(cx, args[1],  "Argument 2 of ChromeUtils.base64URLDecode", false)) {
2619
0
    return false;
2620
0
  }
2621
0
  FastErrorResult rv;
2622
0
  JS::Rooted<JSObject*> result(cx);
2623
0
  mozilla::dom::ChromeUtils::Base64URLDecode(global, Constify(arg0), Constify(arg1), &result, rv);
2624
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
2625
0
    return false;
2626
0
  }
2627
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
2628
0
  JS::ExposeObjectToActiveJS(result);
2629
0
  args.rval().setObject(*result);
2630
0
  if (!MaybeWrapNonDOMObjectValue(cx, args.rval())) {
2631
0
    return false;
2632
0
  }
2633
0
  return true;
2634
0
}
2635
2636
static bool
2637
get_recentJSDevError(JSContext* cx, unsigned argc, JS::Value* vp)
2638
0
{
2639
0
  AUTO_PROFILER_LABEL_FAST("get ChromeUtils.recentJSDevError", DOM, cx);
2640
0
2641
0
  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
2642
0
  JS::Rooted<JSObject*> obj(cx, &args.callee());
2643
0
2644
0
  GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
2645
0
  if (global.Failed()) {
2646
0
    return false;
2647
0
  }
2648
0
2649
0
  FastErrorResult rv;
2650
0
  JS::Rooted<JS::Value> result(cx);
2651
0
  mozilla::dom::ChromeUtils::GetRecentJSDevError(global, &result, rv);
2652
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
2653
0
    return false;
2654
0
  }
2655
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
2656
0
  JS::ExposeValueToActiveJS(result);
2657
0
  args.rval().set(result);
2658
0
  if (!MaybeWrapValue(cx, args.rval())) {
2659
0
    return false;
2660
0
  }
2661
0
  return true;
2662
0
}
2663
2664
static bool
2665
clearRecentJSDevError(JSContext* cx, unsigned argc, JS::Value* vp)
2666
0
{
2667
0
  AUTO_PROFILER_LABEL_FAST("ChromeUtils.clearRecentJSDevError", DOM, cx);
2668
0
2669
0
  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
2670
0
  JS::Rooted<JSObject*> obj(cx, &args.callee());
2671
0
2672
0
  GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
2673
0
  if (global.Failed()) {
2674
0
    return false;
2675
0
  }
2676
0
2677
0
  mozilla::dom::ChromeUtils::ClearRecentJSDevError(global);
2678
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
2679
0
  args.rval().setUndefined();
2680
0
  return true;
2681
0
}
2682
2683
static bool
2684
originAttributesToSuffix(JSContext* cx, unsigned argc, JS::Value* vp)
2685
0
{
2686
0
  AUTO_PROFILER_LABEL_FAST("ChromeUtils.originAttributesToSuffix", DOM, cx);
2687
0
2688
0
  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
2689
0
  JS::Rooted<JSObject*> obj(cx, &args.callee());
2690
0
2691
0
  GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
2692
0
  if (global.Failed()) {
2693
0
    return false;
2694
0
  }
2695
0
2696
0
  binding_detail::FastOriginAttributesDictionary arg0;
2697
0
  if (!arg0.Init(cx, (args.hasDefined(0)) ? args[0] : JS::NullHandleValue,  "Argument 1 of ChromeUtils.originAttributesToSuffix", false)) {
2698
0
    return false;
2699
0
  }
2700
0
  nsCString result;
2701
0
  mozilla::dom::ChromeUtils::OriginAttributesToSuffix(global, Constify(arg0), result);
2702
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
2703
0
  if (!NonVoidByteStringToJsval(cx, result, args.rval())) {
2704
0
    return false;
2705
0
  }
2706
0
  return true;
2707
0
}
2708
2709
static bool
2710
originAttributesMatchPattern(JSContext* cx, unsigned argc, JS::Value* vp)
2711
0
{
2712
0
  AUTO_PROFILER_LABEL_FAST("ChromeUtils.originAttributesMatchPattern", DOM, cx);
2713
0
2714
0
  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
2715
0
  JS::Rooted<JSObject*> obj(cx, &args.callee());
2716
0
2717
0
  GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
2718
0
  if (global.Failed()) {
2719
0
    return false;
2720
0
  }
2721
0
2722
0
  binding_detail::FastOriginAttributesDictionary arg0;
2723
0
  if (!arg0.Init(cx, (args.hasDefined(0)) ? args[0] : JS::NullHandleValue,  "Argument 1 of ChromeUtils.originAttributesMatchPattern", false)) {
2724
0
    return false;
2725
0
  }
2726
0
  binding_detail::FastOriginAttributesPatternDictionary arg1;
2727
0
  if (!arg1.Init(cx, (args.hasDefined(1)) ? args[1] : JS::NullHandleValue,  "Argument 2 of ChromeUtils.originAttributesMatchPattern", false)) {
2728
0
    return false;
2729
0
  }
2730
0
  bool result(mozilla::dom::ChromeUtils::OriginAttributesMatchPattern(global, Constify(arg0), Constify(arg1)));
2731
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
2732
0
  args.rval().setBoolean(result);
2733
0
  return true;
2734
0
}
2735
2736
static bool
2737
createOriginAttributesFromOrigin(JSContext* cx, unsigned argc, JS::Value* vp)
2738
0
{
2739
0
  AUTO_PROFILER_LABEL_FAST("ChromeUtils.createOriginAttributesFromOrigin", DOM, cx);
2740
0
2741
0
  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
2742
0
  JS::Rooted<JSObject*> obj(cx, &args.callee());
2743
0
2744
0
  if (MOZ_UNLIKELY(args.length() < 1)) {
2745
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "ChromeUtils.createOriginAttributesFromOrigin");
2746
0
  }
2747
0
  GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
2748
0
  if (global.Failed()) {
2749
0
    return false;
2750
0
  }
2751
0
2752
0
  binding_detail::FakeString arg0;
2753
0
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
2754
0
    return false;
2755
0
  }
2756
0
  FastErrorResult rv;
2757
0
  OriginAttributesDictionary result;
2758
0
  mozilla::dom::ChromeUtils::CreateOriginAttributesFromOrigin(global, NonNullHelper(Constify(arg0)), result, rv);
2759
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
2760
0
    return false;
2761
0
  }
2762
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
2763
0
  if (!result.ToObjectInternal(cx, args.rval())) {
2764
0
    return false;
2765
0
  }
2766
0
  return true;
2767
0
}
2768
2769
static bool
2770
fillNonDefaultOriginAttributes(JSContext* cx, unsigned argc, JS::Value* vp)
2771
0
{
2772
0
  AUTO_PROFILER_LABEL_FAST("ChromeUtils.fillNonDefaultOriginAttributes", DOM, cx);
2773
0
2774
0
  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
2775
0
  JS::Rooted<JSObject*> obj(cx, &args.callee());
2776
0
2777
0
  GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
2778
0
  if (global.Failed()) {
2779
0
    return false;
2780
0
  }
2781
0
2782
0
  binding_detail::FastOriginAttributesDictionary arg0;
2783
0
  if (!arg0.Init(cx, (args.hasDefined(0)) ? args[0] : JS::NullHandleValue,  "Argument 1 of ChromeUtils.fillNonDefaultOriginAttributes", false)) {
2784
0
    return false;
2785
0
  }
2786
0
  OriginAttributesDictionary result;
2787
0
  mozilla::dom::ChromeUtils::FillNonDefaultOriginAttributes(global, Constify(arg0), result);
2788
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
2789
0
  if (!result.ToObjectInternal(cx, args.rval())) {
2790
0
    return false;
2791
0
  }
2792
0
  return true;
2793
0
}
2794
2795
static bool
2796
isOriginAttributesEqual(JSContext* cx, unsigned argc, JS::Value* vp)
2797
0
{
2798
0
  AUTO_PROFILER_LABEL_FAST("ChromeUtils.isOriginAttributesEqual", DOM, cx);
2799
0
2800
0
  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
2801
0
  JS::Rooted<JSObject*> obj(cx, &args.callee());
2802
0
2803
0
  GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
2804
0
  if (global.Failed()) {
2805
0
    return false;
2806
0
  }
2807
0
2808
0
  binding_detail::FastOriginAttributesDictionary arg0;
2809
0
  if (!arg0.Init(cx, (args.hasDefined(0)) ? args[0] : JS::NullHandleValue,  "Argument 1 of ChromeUtils.isOriginAttributesEqual", false)) {
2810
0
    return false;
2811
0
  }
2812
0
  binding_detail::FastOriginAttributesDictionary arg1;
2813
0
  if (!arg1.Init(cx, (args.hasDefined(1)) ? args[1] : JS::NullHandleValue,  "Argument 2 of ChromeUtils.isOriginAttributesEqual", false)) {
2814
0
    return false;
2815
0
  }
2816
0
  bool result(mozilla::dom::ChromeUtils::IsOriginAttributesEqual(global, Constify(arg0), Constify(arg1)));
2817
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
2818
0
  args.rval().setBoolean(result);
2819
0
  return true;
2820
0
}
2821
2822
static bool
2823
compileScript(JSContext* cx, unsigned argc, JS::Value* vp)
2824
0
{
2825
0
  AUTO_PROFILER_LABEL_FAST("ChromeUtils.compileScript", DOM, cx);
2826
0
2827
0
  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
2828
0
  JS::Rooted<JSObject*> obj(cx, &args.callee());
2829
0
2830
0
  if (MOZ_UNLIKELY(args.length() < 1)) {
2831
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "ChromeUtils.compileScript");
2832
0
  }
2833
0
  GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
2834
0
  if (global.Failed()) {
2835
0
    return false;
2836
0
  }
2837
0
2838
0
  binding_detail::FakeString arg0;
2839
0
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
2840
0
    return false;
2841
0
  }
2842
0
  binding_detail::FastCompileScriptOptionsDictionary arg1;
2843
0
  if (!arg1.Init(cx, (args.hasDefined(1)) ? args[1] : JS::NullHandleValue,  "Argument 2 of ChromeUtils.compileScript", false)) {
2844
0
    return false;
2845
0
  }
2846
0
  FastErrorResult rv;
2847
0
  auto result(StrongOrRawPtr<Promise>(mozilla::dom::ChromeUtils::CompileScript(global, NonNullHelper(Constify(arg0)), Constify(arg1), rv)));
2848
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
2849
0
    return false;
2850
0
  }
2851
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
2852
0
  static_assert(!IsPointer<decltype(result)>::value,
2853
0
                "NewObject implies that we need to keep the object alive with a strong reference.");
2854
0
  if (!ToJSValue(cx, result, args.rval())) {
2855
0
    return false;
2856
0
  }
2857
0
  return true;
2858
0
}
2859
2860
2861
static const JSJitInfo compileScript_methodinfo = {
2862
  { (JSJitGetterOp)compileScript },
2863
  { prototypes::id::_ID_Count }, { 0 }, JSJitInfo::StaticMethod,
2864
  JSJitInfo::AliasEverything, JSVAL_TYPE_MISSING, false, false,
2865
  false, false, 0
2866
};
2867
2868
static bool
2869
generateQI(JSContext* cx, unsigned argc, JS::Value* vp)
2870
3
{
2871
3
  AUTO_PROFILER_LABEL_FAST("ChromeUtils.generateQI", DOM, cx);
2872
3
2873
3
  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
2874
3
  JS::Rooted<JSObject*> obj(cx, &args.callee());
2875
3
2876
3
  if (MOZ_UNLIKELY(args.length() < 1)) {
2877
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "ChromeUtils.generateQI");
2878
0
  }
2879
3
  GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
2880
3
  if (global.Failed()) {
2881
0
    return false;
2882
0
  }
2883
3
2884
3
  binding_detail::AutoSequence<OwningStringOrIID> arg0;
2885
3
  if (args[0].isObject()) {
2886
3
    JS::ForOfIterator iter(cx);
2887
3
    if (!iter.init(args[0], JS::ForOfIterator::AllowNonIterable)) {
2888
0
      return false;
2889
0
    }
2890
3
    if (!iter.valueIsIterable()) {
2891
0
      ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "Argument 1 of ChromeUtils.generateQI");
2892
0
      return false;
2893
0
    }
2894
3
    binding_detail::AutoSequence<OwningStringOrIID> &arr = arg0;
2895
3
    JS::Rooted<JS::Value> temp(cx);
2896
7
    while (true) {
2897
7
      bool done;
2898
7
      if (!iter.next(&temp, &done)) {
2899
0
        return false;
2900
0
      }
2901
7
      if (done) {
2902
3
        break;
2903
3
      }
2904
4
      OwningStringOrIID* slotPtr = arr.AppendElement(mozilla::fallible);
2905
4
      if (!slotPtr) {
2906
0
        JS_ReportOutOfMemory(cx);
2907
0
        return false;
2908
0
      }
2909
4
      OwningStringOrIID& slot = *slotPtr;
2910
4
      {
2911
4
        bool done = false, failed = false, tryNext;
2912
4
        if (temp.isObject()) {
2913
4
          done = (failed = !slot.TrySetToIID(cx, temp, tryNext, false)) || !tryNext;
2914
4
2915
4
        }
2916
4
        if (!done) {
2917
0
          do {
2918
0
            done = (failed = !slot.TrySetToString(cx, temp, tryNext)) || !tryNext;
2919
0
            break;
2920
0
          } while (false);
2921
0
        }
2922
4
        if (failed) {
2923
0
          return false;
2924
0
        }
2925
4
        if (!done) {
2926
0
          ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "Element of argument 1 of ChromeUtils.generateQI", "IID");
2927
0
          return false;
2928
0
        }
2929
4
      }
2930
4
    }
2931
3
  } else {
2932
0
    ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "Argument 1 of ChromeUtils.generateQI");
2933
0
    return false;
2934
0
  }
2935
3
  FastErrorResult rv;
2936
3
  auto result(StrongOrRawPtr<mozilla::dom::MozQueryInterface>(mozilla::dom::ChromeUtils::GenerateQI(global, Constify(arg0), rv)));
2937
3
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
2938
0
    return false;
2939
0
  }
2940
3
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
2941
3
  static_assert(!IsPointer<decltype(result)>::value,
2942
3
                "NewObject implies that we need to keep the object alive with a strong reference.");
2943
3
  if (!WrapNewBindingNonWrapperCachedObject(cx, obj, result, args.rval())) {
2944
0
    MOZ_ASSERT(JS_IsExceptionPending(cx));
2945
0
    return false;
2946
0
  }
2947
3
  return true;
2948
3
}
2949
2950
static bool
2951
waiveXrays(JSContext* cx, unsigned argc, JS::Value* vp)
2952
0
{
2953
0
  AUTO_PROFILER_LABEL_FAST("ChromeUtils.waiveXrays", DOM, cx);
2954
0
2955
0
  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
2956
0
  JS::Rooted<JSObject*> obj(cx, &args.callee());
2957
0
2958
0
  if (MOZ_UNLIKELY(args.length() < 1)) {
2959
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "ChromeUtils.waiveXrays");
2960
0
  }
2961
0
  GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
2962
0
  if (global.Failed()) {
2963
0
    return false;
2964
0
  }
2965
0
2966
0
  JS::Rooted<JS::Value> arg0(cx);
2967
0
  arg0 = args[0];
2968
0
  FastErrorResult rv;
2969
0
  JS::Rooted<JS::Value> result(cx);
2970
0
  mozilla::dom::ChromeUtils::WaiveXrays(global, arg0, &result, rv);
2971
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
2972
0
    return false;
2973
0
  }
2974
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
2975
0
  JS::ExposeValueToActiveJS(result);
2976
0
  args.rval().set(result);
2977
0
  if (!MaybeWrapValue(cx, args.rval())) {
2978
0
    return false;
2979
0
  }
2980
0
  return true;
2981
0
}
2982
2983
static bool
2984
unwaiveXrays(JSContext* cx, unsigned argc, JS::Value* vp)
2985
0
{
2986
0
  AUTO_PROFILER_LABEL_FAST("ChromeUtils.unwaiveXrays", DOM, cx);
2987
0
2988
0
  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
2989
0
  JS::Rooted<JSObject*> obj(cx, &args.callee());
2990
0
2991
0
  if (MOZ_UNLIKELY(args.length() < 1)) {
2992
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "ChromeUtils.unwaiveXrays");
2993
0
  }
2994
0
  GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
2995
0
  if (global.Failed()) {
2996
0
    return false;
2997
0
  }
2998
0
2999
0
  JS::Rooted<JS::Value> arg0(cx);
3000
0
  arg0 = args[0];
3001
0
  FastErrorResult rv;
3002
0
  JS::Rooted<JS::Value> result(cx);
3003
0
  mozilla::dom::ChromeUtils::UnwaiveXrays(global, arg0, &result, rv);
3004
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
3005
0
    return false;
3006
0
  }
3007
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
3008
0
  JS::ExposeValueToActiveJS(result);
3009
0
  args.rval().set(result);
3010
0
  if (!MaybeWrapValue(cx, args.rval())) {
3011
0
    return false;
3012
0
  }
3013
0
  return true;
3014
0
}
3015
3016
static bool
3017
getClassName(JSContext* cx, unsigned argc, JS::Value* vp)
3018
0
{
3019
0
  AUTO_PROFILER_LABEL_FAST("ChromeUtils.getClassName", DOM, cx);
3020
0
3021
0
  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
3022
0
  JS::Rooted<JSObject*> obj(cx, &args.callee());
3023
0
3024
0
  if (MOZ_UNLIKELY(args.length() < 1)) {
3025
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "ChromeUtils.getClassName");
3026
0
  }
3027
0
  GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
3028
0
  if (global.Failed()) {
3029
0
    return false;
3030
0
  }
3031
0
3032
0
  JS::Rooted<JSObject*> arg0(cx);
3033
0
  if (args[0].isObject()) {
3034
0
    arg0 = &args[0].toObject();
3035
0
  } else {
3036
0
    ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of ChromeUtils.getClassName");
3037
0
    return false;
3038
0
  }
3039
0
  bool arg1;
3040
0
  if (args.hasDefined(1)) {
3041
0
    if (!ValueToPrimitive<bool, eDefault>(cx, args[1], &arg1)) {
3042
0
      return false;
3043
0
    }
3044
0
  } else {
3045
0
    arg1 = true;
3046
0
  }
3047
0
  DOMString result;
3048
0
  mozilla::dom::ChromeUtils::GetClassName(global, arg0, arg1, result);
3049
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
3050
0
  if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
3051
0
    return false;
3052
0
  }
3053
0
  return true;
3054
0
}
3055
3056
static bool
3057
shallowClone(JSContext* cx, unsigned argc, JS::Value* vp)
3058
0
{
3059
0
  AUTO_PROFILER_LABEL_FAST("ChromeUtils.shallowClone", DOM, cx);
3060
0
3061
0
  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
3062
0
  JS::Rooted<JSObject*> obj(cx, &args.callee());
3063
0
3064
0
  if (MOZ_UNLIKELY(args.length() < 1)) {
3065
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "ChromeUtils.shallowClone");
3066
0
  }
3067
0
  GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
3068
0
  if (global.Failed()) {
3069
0
    return false;
3070
0
  }
3071
0
3072
0
  JS::Rooted<JSObject*> arg0(cx);
3073
0
  if (args[0].isObject()) {
3074
0
    arg0 = &args[0].toObject();
3075
0
  } else {
3076
0
    ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of ChromeUtils.shallowClone");
3077
0
    return false;
3078
0
  }
3079
0
  JS::Rooted<JSObject*> arg1(cx);
3080
0
  if (args.hasDefined(1)) {
3081
0
    if (args[1].isObject()) {
3082
0
      arg1 = &args[1].toObject();
3083
0
    } else if (args[1].isNullOrUndefined()) {
3084
0
      arg1 = nullptr;
3085
0
    } else {
3086
0
      ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 2 of ChromeUtils.shallowClone");
3087
0
      return false;
3088
0
    }
3089
0
  } else {
3090
0
    arg1 = nullptr;
3091
0
  }
3092
0
  FastErrorResult rv;
3093
0
  JS::Rooted<JSObject*> result(cx);
3094
0
  mozilla::dom::ChromeUtils::ShallowClone(global, arg0, arg1, &result, rv);
3095
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
3096
0
    return false;
3097
0
  }
3098
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
3099
0
  JS::ExposeObjectToActiveJS(result);
3100
0
  args.rval().setObject(*result);
3101
0
  if (!MaybeWrapObjectValue(cx, args.rval())) {
3102
0
    return false;
3103
0
  }
3104
0
  return true;
3105
0
}
3106
3107
static bool
3108
idleDispatch(JSContext* cx, unsigned argc, JS::Value* vp)
3109
0
{
3110
0
  AUTO_PROFILER_LABEL_FAST("ChromeUtils.idleDispatch", DOM, cx);
3111
0
3112
0
  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
3113
0
  JS::Rooted<JSObject*> obj(cx, &args.callee());
3114
0
3115
0
  if (MOZ_UNLIKELY(args.length() < 1)) {
3116
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "ChromeUtils.idleDispatch");
3117
0
  }
3118
0
  GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
3119
0
  if (global.Failed()) {
3120
0
    return false;
3121
0
  }
3122
0
3123
0
  RootedCallback<OwningNonNull<binding_detail::FastIdleRequestCallback>> arg0(cx);
3124
0
  if (args[0].isObject()) {
3125
0
    if (JS::IsCallable(&args[0].toObject())) {
3126
0
    { // scope for tempRoot and tempGlobalRoot if needed
3127
0
      arg0 = new binding_detail::FastIdleRequestCallback(&args[0].toObject(), JS::CurrentGlobalOrNull(cx));
3128
0
    }
3129
0
    } else {
3130
0
      ThrowErrorMessage(cx, MSG_NOT_CALLABLE, "Argument 1 of ChromeUtils.idleDispatch");
3131
0
      return false;
3132
0
    }
3133
0
  } else {
3134
0
    ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of ChromeUtils.idleDispatch");
3135
0
    return false;
3136
0
  }
3137
0
  binding_detail::FastIdleRequestOptions arg1;
3138
0
  if (!arg1.Init(cx, (args.hasDefined(1)) ? args[1] : JS::NullHandleValue,  "Argument 2 of ChromeUtils.idleDispatch", false)) {
3139
0
    return false;
3140
0
  }
3141
0
  FastErrorResult rv;
3142
0
  mozilla::dom::ChromeUtils::IdleDispatch(global, NonNullHelper(arg0), Constify(arg1), rv);
3143
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
3144
0
    return false;
3145
0
  }
3146
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
3147
0
  args.rval().setUndefined();
3148
0
  return true;
3149
0
}
3150
3151
static bool
3152
import(JSContext* cx, unsigned argc, JS::Value* vp)
3153
8
{
3154
8
  AUTO_PROFILER_LABEL_FAST("ChromeUtils.import", DOM, cx);
3155
8
3156
8
  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
3157
8
  JS::Rooted<JSObject*> obj(cx, &args.callee());
3158
8
3159
8
  if (MOZ_UNLIKELY(args.length() < 1)) {
3160
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "ChromeUtils.import");
3161
0
  }
3162
8
  GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
3163
8
  if (global.Failed()) {
3164
0
    return false;
3165
0
  }
3166
8
3167
8
  binding_detail::FakeString arg0;
3168
8
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
3169
0
    return false;
3170
0
  }
3171
8
  Optional<JS::Handle<JSObject*>> arg1;
3172
8
  if (args.hasDefined(1)) {
3173
0
    arg1.Construct(cx);
3174
0
    if (args[1].isObject()) {
3175
0
      arg1.Value() = &args[1].toObject();
3176
0
    } else if (args[1].isNullOrUndefined()) {
3177
0
      arg1.Value() = nullptr;
3178
0
    } else {
3179
0
      ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 2 of ChromeUtils.import");
3180
0
      return false;
3181
0
    }
3182
8
  }
3183
8
  FastErrorResult rv;
3184
8
  JS::Rooted<JSObject*> result(cx);
3185
8
  mozilla::dom::ChromeUtils::Import(global, NonNullHelper(Constify(arg0)), Constify(arg1), &result, rv);
3186
8
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
3187
0
    return false;
3188
0
  }
3189
8
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
3190
8
  JS::ExposeObjectToActiveJS(result);
3191
8
  args.rval().setObject(*result);
3192
8
  if (!MaybeWrapObjectValue(cx, args.rval())) {
3193
0
    return false;
3194
0
  }
3195
8
  return true;
3196
8
}
3197
3198
static bool
3199
defineModuleGetter(JSContext* cx, unsigned argc, JS::Value* vp)
3200
3
{
3201
3
  AUTO_PROFILER_LABEL_FAST("ChromeUtils.defineModuleGetter", DOM, cx);
3202
3
3203
3
  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
3204
3
  JS::Rooted<JSObject*> obj(cx, &args.callee());
3205
3
3206
3
  if (MOZ_UNLIKELY(args.length() < 3)) {
3207
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "ChromeUtils.defineModuleGetter");
3208
0
  }
3209
3
  GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
3210
3
  if (global.Failed()) {
3211
0
    return false;
3212
0
  }
3213
3
3214
3
  JS::Rooted<JSObject*> arg0(cx);
3215
3
  if (args[0].isObject()) {
3216
3
    arg0 = &args[0].toObject();
3217
3
  } else {
3218
0
    ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of ChromeUtils.defineModuleGetter");
3219
0
    return false;
3220
0
  }
3221
3
  binding_detail::FakeString arg1;
3222
3
  if (!ConvertJSValueToString(cx, args[1], eStringify, eStringify, arg1)) {
3223
0
    return false;
3224
0
  }
3225
3
  binding_detail::FakeString arg2;
3226
3
  if (!ConvertJSValueToString(cx, args[2], eStringify, eStringify, arg2)) {
3227
0
    return false;
3228
0
  }
3229
3
  FastErrorResult rv;
3230
3
  mozilla::dom::ChromeUtils::DefineModuleGetter(global, arg0, NonNullHelper(Constify(arg1)), NonNullHelper(Constify(arg2)), rv);
3231
3
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
3232
0
    return false;
3233
0
  }
3234
3
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
3235
3
  args.rval().setUndefined();
3236
3
  return true;
3237
3
}
3238
3239
static bool
3240
getCallerLocation(JSContext* cx, unsigned argc, JS::Value* vp)
3241
0
{
3242
0
  AUTO_PROFILER_LABEL_FAST("ChromeUtils.getCallerLocation", DOM, cx);
3243
0
3244
0
  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
3245
0
  JS::Rooted<JSObject*> obj(cx, &args.callee());
3246
0
3247
0
  if (MOZ_UNLIKELY(args.length() < 1)) {
3248
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "ChromeUtils.getCallerLocation");
3249
0
  }
3250
0
  GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
3251
0
  if (global.Failed()) {
3252
0
    return false;
3253
0
  }
3254
0
3255
0
  nsIPrincipal* arg0;
3256
0
  RefPtr<nsIPrincipal> arg0_holder;
3257
0
  if (args[0].isObject()) {
3258
0
    JS::Rooted<JSObject*> source(cx, &args[0].toObject());
3259
0
    if (NS_FAILED(UnwrapArg<nsIPrincipal>(cx, source, getter_AddRefs(arg0_holder)))) {
3260
0
      ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Argument 1 of ChromeUtils.getCallerLocation", "Principal");
3261
0
      return false;
3262
0
    }
3263
0
    MOZ_ASSERT(arg0_holder);
3264
0
    arg0 = arg0_holder;
3265
0
  } else {
3266
0
    ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of ChromeUtils.getCallerLocation");
3267
0
    return false;
3268
0
  }
3269
0
  JS::Rooted<JSObject*> result(cx);
3270
0
  mozilla::dom::ChromeUtils::GetCallerLocation(global, MOZ_KnownLive(NonNullHelper(arg0)), &result);
3271
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
3272
0
  if (result) {
3273
0
                JS::ExposeObjectToActiveJS(result);
3274
0
              }
3275
0
              args.rval().setObjectOrNull(result);
3276
0
  if (!MaybeWrapObjectOrNullValue(cx, args.rval())) {
3277
0
    return false;
3278
0
  }
3279
0
  return true;
3280
0
}
3281
3282
static bool
3283
createError(JSContext* cx, unsigned argc, JS::Value* vp)
3284
0
{
3285
0
  AUTO_PROFILER_LABEL_FAST("ChromeUtils.createError", DOM, cx);
3286
0
3287
0
  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
3288
0
  JS::Rooted<JSObject*> obj(cx, &args.callee());
3289
0
3290
0
  if (MOZ_UNLIKELY(args.length() < 1)) {
3291
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "ChromeUtils.createError");
3292
0
  }
3293
0
  GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
3294
0
  if (global.Failed()) {
3295
0
    return false;
3296
0
  }
3297
0
3298
0
  binding_detail::FakeString arg0;
3299
0
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
3300
0
    return false;
3301
0
  }
3302
0
  JS::Rooted<JSObject*> arg1(cx);
3303
0
  if (args.hasDefined(1)) {
3304
0
    if (args[1].isObject()) {
3305
0
      arg1 = &args[1].toObject();
3306
0
    } else if (args[1].isNullOrUndefined()) {
3307
0
      arg1 = nullptr;
3308
0
    } else {
3309
0
      ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 2 of ChromeUtils.createError");
3310
0
      return false;
3311
0
    }
3312
0
  } else {
3313
0
    arg1 = nullptr;
3314
0
  }
3315
0
  FastErrorResult rv;
3316
0
  JS::Rooted<JSObject*> result(cx);
3317
0
  mozilla::dom::ChromeUtils::CreateError(global, NonNullHelper(Constify(arg0)), arg1, &result, rv);
3318
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
3319
0
    return false;
3320
0
  }
3321
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
3322
0
  JS::ExposeObjectToActiveJS(result);
3323
0
  args.rval().setObject(*result);
3324
0
  if (!MaybeWrapObjectValue(cx, args.rval())) {
3325
0
    return false;
3326
0
  }
3327
0
  return true;
3328
0
}
3329
3330
static bool
3331
requestPerformanceMetrics(JSContext* cx, unsigned argc, JS::Value* vp)
3332
0
{
3333
0
  AUTO_PROFILER_LABEL_FAST("ChromeUtils.requestPerformanceMetrics", DOM, cx);
3334
0
3335
0
  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
3336
0
  JS::Rooted<JSObject*> obj(cx, &args.callee());
3337
0
3338
0
  GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
3339
0
  if (global.Failed()) {
3340
0
    return false;
3341
0
  }
3342
0
3343
0
  FastErrorResult rv;
3344
0
  auto result(StrongOrRawPtr<Promise>(mozilla::dom::ChromeUtils::RequestPerformanceMetrics(global, rv)));
3345
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
3346
0
    return false;
3347
0
  }
3348
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
3349
0
  if (!ToJSValue(cx, result, args.rval())) {
3350
0
    return false;
3351
0
  }
3352
0
  return true;
3353
0
}
3354
3355
3356
static const JSJitInfo requestPerformanceMetrics_methodinfo = {
3357
  { (JSJitGetterOp)requestPerformanceMetrics },
3358
  { prototypes::id::_ID_Count }, { 0 }, JSJitInfo::StaticMethod,
3359
  JSJitInfo::AliasEverything, JSVAL_TYPE_MISSING, false, false,
3360
  false, false, 0
3361
};
3362
3363
static bool
3364
requestIOActivity(JSContext* cx, unsigned argc, JS::Value* vp)
3365
0
{
3366
0
  AUTO_PROFILER_LABEL_FAST("ChromeUtils.requestIOActivity", DOM, cx);
3367
0
3368
0
  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
3369
0
  JS::Rooted<JSObject*> obj(cx, &args.callee());
3370
0
3371
0
  GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
3372
0
  if (global.Failed()) {
3373
0
    return false;
3374
0
  }
3375
0
3376
0
  FastErrorResult rv;
3377
0
  auto result(StrongOrRawPtr<Promise>(mozilla::dom::ChromeUtils::RequestIOActivity(global, rv)));
3378
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
3379
0
    return false;
3380
0
  }
3381
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
3382
0
  if (!ToJSValue(cx, result, args.rval())) {
3383
0
    return false;
3384
0
  }
3385
0
  return true;
3386
0
}
3387
3388
3389
static const JSJitInfo requestIOActivity_methodinfo = {
3390
  { (JSJitGetterOp)requestIOActivity },
3391
  { prototypes::id::_ID_Count }, { 0 }, JSJitInfo::StaticMethod,
3392
  JSJitInfo::AliasEverything, JSVAL_TYPE_MISSING, false, false,
3393
  false, false, 0
3394
};
3395
3396
static bool
3397
getRootBrowsingContexts(JSContext* cx, unsigned argc, JS::Value* vp)
3398
0
{
3399
0
  AUTO_PROFILER_LABEL_FAST("ChromeUtils.getRootBrowsingContexts", DOM, cx);
3400
0
3401
0
  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
3402
0
  JS::Rooted<JSObject*> obj(cx, &args.callee());
3403
0
3404
0
  GlobalObject global(cx, xpc::XrayAwareCalleeGlobal(obj));
3405
0
  if (global.Failed()) {
3406
0
    return false;
3407
0
  }
3408
0
3409
0
  nsTArray<StrongPtrForMember<mozilla::dom::BrowsingContext>::Type> result;
3410
0
  mozilla::dom::ChromeUtils::GetRootBrowsingContexts(global, result);
3411
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
3412
0
3413
0
  uint32_t length = result.Length();
3414
0
  JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
3415
0
  if (!returnArray) {
3416
0
    return false;
3417
0
  }
3418
0
  // Scope for 'tmp'
3419
0
  {
3420
0
    JS::Rooted<JS::Value> tmp(cx);
3421
0
    for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
3422
0
      // Control block to let us common up the JS_DefineElement calls when there
3423
0
      // are different ways to succeed at wrapping the object.
3424
0
      do {
3425
0
        if (!GetOrCreateDOMReflector(cx, result[sequenceIdx0], &tmp)) {
3426
0
          MOZ_ASSERT(JS_IsExceptionPending(cx));
3427
0
          return false;
3428
0
        }
3429
0
        break;
3430
0
      } while (false);
3431
0
      if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
3432
0
                            JSPROP_ENUMERATE)) {
3433
0
        return false;
3434
0
      }
3435
0
    }
3436
0
  }
3437
0
  args.rval().setObject(*returnArray);
3438
0
  return true;
3439
0
}
3440
3441
// We deliberately use brace-elision to make Visual Studio produce better initalization code.
3442
#if defined(__clang__)
3443
#pragma clang diagnostic push
3444
#pragma clang diagnostic ignored "-Wmissing-braces"
3445
#endif
3446
static const JSFunctionSpec sStaticMethods_specs[] = {
3447
  JS_FNSPEC("saveHeapSnapshot", saveHeapSnapshot, nullptr, 0, JSPROP_ENUMERATE, nullptr),
3448
  JS_FNSPEC("saveHeapSnapshotGetId", saveHeapSnapshotGetId, nullptr, 0, JSPROP_ENUMERATE, nullptr),
3449
  JS_FNSPEC("readHeapSnapshot", readHeapSnapshot, nullptr, 1, JSPROP_ENUMERATE, nullptr),
3450
  JS_FNSPEC("nondeterministicGetWeakMapKeys", nondeterministicGetWeakMapKeys, nullptr, 1, JSPROP_ENUMERATE, nullptr),
3451
  JS_FNSPEC("nondeterministicGetWeakSetKeys", nondeterministicGetWeakSetKeys, nullptr, 1, JSPROP_ENUMERATE, nullptr),
3452
  JS_FNSPEC("base64URLEncode", base64URLEncode, nullptr, 2, JSPROP_ENUMERATE, nullptr),
3453
  JS_FNSPEC("base64URLDecode", base64URLDecode, nullptr, 2, JSPROP_ENUMERATE, nullptr),
3454
  JS_FNSPEC("clearRecentJSDevError", clearRecentJSDevError, nullptr, 0, JSPROP_ENUMERATE, nullptr),
3455
  JS_FS_END,
3456
  JS_FNSPEC("originAttributesToSuffix", originAttributesToSuffix, nullptr, 0, JSPROP_ENUMERATE, nullptr),
3457
  JS_FNSPEC("originAttributesMatchPattern", originAttributesMatchPattern, nullptr, 0, JSPROP_ENUMERATE, nullptr),
3458
  JS_FNSPEC("createOriginAttributesFromOrigin", createOriginAttributesFromOrigin, nullptr, 1, JSPROP_ENUMERATE, nullptr),
3459
  JS_FNSPEC("fillNonDefaultOriginAttributes", fillNonDefaultOriginAttributes, nullptr, 0, JSPROP_ENUMERATE, nullptr),
3460
  JS_FNSPEC("isOriginAttributesEqual", isOriginAttributesEqual, nullptr, 0, JSPROP_ENUMERATE, nullptr),
3461
  JS_FNSPEC("compileScript", StaticMethodPromiseWrapper, &compileScript_methodinfo, 1, JSPROP_ENUMERATE, nullptr),
3462
  JS_FNSPEC("generateQI", generateQI, nullptr, 1, JSPROP_ENUMERATE, nullptr),
3463
  JS_FNSPEC("waiveXrays", waiveXrays, nullptr, 1, JSPROP_ENUMERATE, nullptr),
3464
  JS_FNSPEC("unwaiveXrays", unwaiveXrays, nullptr, 1, JSPROP_ENUMERATE, nullptr),
3465
  JS_FNSPEC("getClassName", getClassName, nullptr, 1, JSPROP_ENUMERATE, nullptr),
3466
  JS_FNSPEC("shallowClone", shallowClone, nullptr, 1, JSPROP_ENUMERATE, nullptr),
3467
  JS_FNSPEC("idleDispatch", idleDispatch, nullptr, 1, JSPROP_ENUMERATE, nullptr),
3468
  JS_FNSPEC("import", import, nullptr, 1, JSPROP_ENUMERATE, nullptr),
3469
  JS_FNSPEC("defineModuleGetter", defineModuleGetter, nullptr, 3, JSPROP_ENUMERATE, nullptr),
3470
  JS_FNSPEC("getCallerLocation", getCallerLocation, nullptr, 1, JSPROP_ENUMERATE, nullptr),
3471
  JS_FNSPEC("createError", createError, nullptr, 1, JSPROP_ENUMERATE, nullptr),
3472
  JS_FS_END,
3473
  JS_FNSPEC("requestPerformanceMetrics", StaticMethodPromiseWrapper, &requestPerformanceMetrics_methodinfo, 0, JSPROP_ENUMERATE, nullptr),
3474
  JS_FS_END,
3475
  JS_FNSPEC("requestIOActivity", StaticMethodPromiseWrapper, &requestIOActivity_methodinfo, 0, JSPROP_ENUMERATE, nullptr),
3476
  JS_FS_END
3477
};
3478
#if defined(__clang__)
3479
#pragma clang diagnostic pop
3480
#endif
3481
3482
// Can't be const because the pref-enabled boolean needs to be writable
3483
static PrefableDisablers sStaticMethods_disablers9 = {
3484
  true, false, GlobalNames::DedicatedWorkerGlobalScope | GlobalNames::ServiceWorkerGlobalScope | GlobalNames::SharedWorkerGlobalScope, nullptr
3485
};
3486
3487
// Can't be const because the pref-enabled boolean needs to be writable
3488
static PrefableDisablers sStaticMethods_disablers26 = {
3489
  true, false, GlobalNames::DedicatedWorkerGlobalScope | GlobalNames::ServiceWorkerGlobalScope | GlobalNames::SharedWorkerGlobalScope, &DOMPrefs::dom_performance_enable_scheduler_timing
3490
};
3491
3492
// Can't be const because the pref-enabled boolean needs to be writable
3493
static PrefableDisablers sStaticMethods_disablers28 = {
3494
  true, false, GlobalNames::DedicatedWorkerGlobalScope | GlobalNames::ServiceWorkerGlobalScope | GlobalNames::SharedWorkerGlobalScope, nullptr
3495
};
3496
3497
static const Prefable<const JSFunctionSpec> sStaticMethods[] = {
3498
  { nullptr, &sStaticMethods_specs[0] },
3499
  { &sStaticMethods_disablers9, &sStaticMethods_specs[9] },
3500
  { &sStaticMethods_disablers26, &sStaticMethods_specs[26] },
3501
  { &sStaticMethods_disablers28, &sStaticMethods_specs[28] },
3502
  { nullptr, nullptr }
3503
};
3504
3505
static_assert(4 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
3506
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
3507
static_assert(16 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
3508
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
3509
3510
// We deliberately use brace-elision to make Visual Studio produce better initalization code.
3511
#if defined(__clang__)
3512
#pragma clang diagnostic push
3513
#pragma clang diagnostic ignored "-Wmissing-braces"
3514
#endif
3515
static const JSFunctionSpec sChromeStaticMethods_specs[] = {
3516
  JS_FNSPEC("getRootBrowsingContexts", getRootBrowsingContexts, nullptr, 0, JSPROP_ENUMERATE, nullptr),
3517
  JS_FS_END
3518
};
3519
#if defined(__clang__)
3520
#pragma clang diagnostic pop
3521
#endif
3522
3523
// Can't be const because the pref-enabled boolean needs to be writable
3524
static PrefableDisablers sChromeStaticMethods_disablers0 = {
3525
  true, false, GlobalNames::DedicatedWorkerGlobalScope | GlobalNames::ServiceWorkerGlobalScope | GlobalNames::SharedWorkerGlobalScope, nullptr
3526
};
3527
3528
static const Prefable<const JSFunctionSpec> sChromeStaticMethods[] = {
3529
  { &sChromeStaticMethods_disablers0, &sChromeStaticMethods_specs[0] },
3530
  { nullptr, nullptr }
3531
};
3532
3533
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
3534
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
3535
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
3536
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
3537
3538
// We deliberately use brace-elision to make Visual Studio produce better initalization code.
3539
#if defined(__clang__)
3540
#pragma clang diagnostic push
3541
#pragma clang diagnostic ignored "-Wmissing-braces"
3542
#endif
3543
static const JSPropertySpec sStaticAttributes_specs[] = {
3544
  { "recentJSDevError", JSPROP_ENUMERATE, get_recentJSDevError, nullptr, nullptr, nullptr },
3545
  { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
3546
};
3547
#if defined(__clang__)
3548
#pragma clang diagnostic pop
3549
#endif
3550
3551
3552
static const Prefable<const JSPropertySpec> sStaticAttributes[] = {
3553
  { nullptr, &sStaticAttributes_specs[0] },
3554
  { nullptr, nullptr }
3555
};
3556
3557
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
3558
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
3559
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
3560
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
3561
3562
3563
static uint16_t sNativeProperties_sortedPropertyIndices[27];
3564
static PropertyInfo sNativeProperties_propertyInfos[27];
3565
3566
static const NativePropertiesN<2> sNativeProperties = {
3567
  true,  0 /* sStaticMethods */,
3568
  true,  1 /* sStaticAttributes */,
3569
  false, 0,
3570
  false, 0,
3571
  false, 0,
3572
  false, 0,
3573
  false, 0,
3574
  -1,
3575
  27,
3576
  sNativeProperties_sortedPropertyIndices,
3577
  {
3578
    { sStaticMethods, &sNativeProperties_propertyInfos[0] },
3579
    { sStaticAttributes, &sNativeProperties_propertyInfos[26] }
3580
  }
3581
};
3582
static_assert(27 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
3583
    "We have a property info count that is oversized");
3584
3585
static uint16_t sChromeOnlyNativeProperties_sortedPropertyIndices[1];
3586
static PropertyInfo sChromeOnlyNativeProperties_propertyInfos[1];
3587
3588
static const NativePropertiesN<1> sChromeOnlyNativeProperties = {
3589
  true,  0 /* sChromeStaticMethods */,
3590
  false, 0,
3591
  false, 0,
3592
  false, 0,
3593
  false, 0,
3594
  false, 0,
3595
  false, 0,
3596
  -1,
3597
  1,
3598
  sChromeOnlyNativeProperties_sortedPropertyIndices,
3599
  {
3600
    { sChromeStaticMethods, &sChromeOnlyNativeProperties_propertyInfos[0] }
3601
  }
3602
};
3603
static_assert(1 < 1ull << CHAR_BIT * sizeof(sChromeOnlyNativeProperties.propertyInfoCount),
3604
    "We have a property info count that is oversized");
3605
3606
static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
3607
  {
3608
    "Object",
3609
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
3610
    JS_NULL_CLASS_OPS,
3611
    JS_NULL_CLASS_SPEC,
3612
    JS_NULL_CLASS_EXT,
3613
    JS_NULL_OBJECT_OPS
3614
  },
3615
  eInterface,
3616
  false,
3617
  prototypes::id::_ID_Count,
3618
  0,
3619
  sNativePropertyHooks,
3620
  "[object Object]",
3621
  JS::GetRealmObjectPrototype
3622
};
3623
3624
bool
3625
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
3626
1
{
3627
1
  return nsContentUtils::ThreadsafeIsSystemCaller(aCx);
3628
1
}
3629
3630
const NativePropertyHooks sNativePropertyHooks[] = { {
3631
  nullptr,
3632
  nullptr,
3633
  nullptr,
3634
  { sNativeProperties.Upcast(), sChromeOnlyNativeProperties.Upcast() },
3635
  prototypes::id::_ID_Count,
3636
  constructors::id::ChromeUtils,
3637
  nullptr,
3638
  &DefaultXrayExpandoObjectClass
3639
} };
3640
3641
void
3642
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
3643
1
{
3644
1
  JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmObjectPrototype(aCx));
3645
1
  if (!constructorProto) {
3646
0
    return;
3647
0
  }
3648
1
3649
1
  static bool sIdsInited = false;
3650
1
  if (!sIdsInited && NS_IsMainThread()) {
3651
1
    if (!InitIds(aCx, sNativeProperties.Upcast())) {
3652
0
      return;
3653
0
    }
3654
1
    if (!InitIds(aCx, sChromeOnlyNativeProperties.Upcast())) {
3655
0
      return;
3656
0
    }
3657
1
    sIdsInited = true;
3658
1
  }
3659
1
3660
1
  JS::Heap<JSObject*>* protoCache = nullptr;
3661
1
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::ChromeUtils);
3662
1
  dom::CreateInterfaceObjects(aCx, aGlobal, nullptr,
3663
1
                              nullptr, protoCache,
3664
1
                              nullptr,
3665
1
                              constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
3666
1
                              interfaceCache,
3667
1
                              sNativeProperties.Upcast(),
3668
1
                              sChromeOnlyNativeProperties.Upcast(),
3669
1
                              "ChromeUtils", aDefineOnGlobal,
3670
1
                              nullptr,
3671
1
                              false);
3672
1
}
3673
3674
JSObject*
3675
GetConstructorObject(JSContext* aCx)
3676
1
{
3677
1
  return GetConstructorObjectHandle(aCx);
3678
1
}
3679
3680
} // namespace ChromeUtils_Binding
3681
3682
3683
3684
namespace MozQueryInterface_Binding {
3685
3686
static void
3687
_finalize(js::FreeOp* fop, JSObject* obj)
3688
0
{
3689
0
  mozilla::dom::MozQueryInterface* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::MozQueryInterface>(obj);
3690
0
  if (self) {
3691
0
    AddForDeferredFinalization<mozilla::dom::MozQueryInterface>(self);
3692
0
  }
3693
0
}
3694
3695
static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
3696
  {
3697
    "Function",
3698
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
3699
    &sBoringInterfaceObjectClassClassOps,
3700
    JS_NULL_CLASS_SPEC,
3701
    JS_NULL_CLASS_EXT,
3702
    &sInterfaceObjectClassObjectOps
3703
  },
3704
  eInterface,
3705
  true,
3706
  prototypes::id::MozQueryInterface,
3707
  PrototypeTraits<prototypes::id::MozQueryInterface>::Depth,
3708
  sNativePropertyHooks,
3709
  "function MozQueryInterface() {\n    [native code]\n}",
3710
  JS::GetRealmFunctionPrototype
3711
};
3712
3713
static bool
3714
_legacycaller(JSContext* cx, unsigned argc, JS::Value* vp)
3715
1
{
3716
1
  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
3717
1
  JS::Rooted<JSObject*> obj(cx, &args.callee());
3718
1
3719
1
  mozilla::dom::MozQueryInterface* self;
3720
1
  JS::Rooted<JS::Value> rootSelf(cx, JS::ObjectValue(*obj));
3721
1
  {
3722
1
    nsresult rv = UnwrapObject<prototypes::id::MozQueryInterface, mozilla::dom::MozQueryInterface>(&rootSelf, self);
3723
1
    if (NS_FAILED(rv)) {
3724
0
      return ThrowErrorMessage(cx, MSG_THIS_DOES_NOT_IMPLEMENT_INTERFACE, "Value", "MozQueryInterface");
3725
0
    }
3726
1
  }
3727
1
  if (MOZ_UNLIKELY(args.length() < 1)) {
3728
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "MozQueryInterface.__legacycaller");
3729
0
  }
3730
1
  nsIJSID* arg0;
3731
1
  RefPtr<nsIJSID> arg0_holder;
3732
1
  if (args[0].isObject()) {
3733
1
    JS::Rooted<JSObject*> source(cx, &args[0].toObject());
3734
1
    if (NS_FAILED(UnwrapArg<nsIJSID>(cx, source, getter_AddRefs(arg0_holder)))) {
3735
0
      ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Argument 1 of MozQueryInterface.__legacycaller", "IID");
3736
0
      return false;
3737
0
    }
3738
1
    MOZ_ASSERT(arg0_holder);
3739
1
    arg0 = arg0_holder;
3740
1
  } else {
3741
0
    ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of MozQueryInterface.__legacycaller");
3742
0
    return false;
3743
0
  }
3744
1
  FastErrorResult rv;
3745
1
  JS::Rooted<JS::Value> result(cx);
3746
1
  self->LegacyCall(cx, args.thisv(), MOZ_KnownLive(NonNullHelper(arg0)), &result, rv);
3747
1
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
3748
0
    return false;
3749
0
  }
3750
1
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
3751
1
  JS::ExposeValueToActiveJS(result);
3752
1
  args.rval().set(result);
3753
1
  if (!MaybeWrapValue(cx, args.rval())) {
3754
0
    return false;
3755
0
  }
3756
1
  return true;
3757
1
}
3758
3759
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
3760
  {
3761
    "MozQueryInterfacePrototype",
3762
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
3763
    JS_NULL_CLASS_OPS,
3764
    JS_NULL_CLASS_SPEC,
3765
    JS_NULL_CLASS_EXT,
3766
    JS_NULL_OBJECT_OPS
3767
  },
3768
  eInterfacePrototype,
3769
  false,
3770
  prototypes::id::MozQueryInterface,
3771
  PrototypeTraits<prototypes::id::MozQueryInterface>::Depth,
3772
  sNativePropertyHooks,
3773
  "[object MozQueryInterfacePrototype]",
3774
  JS::GetRealmObjectPrototype
3775
};
3776
3777
bool
3778
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
3779
0
{
3780
0
  return nsContentUtils::ThreadsafeIsSystemCaller(aCx);
3781
0
}
3782
3783
static const js::ClassOps sClassOps = {
3784
  nullptr, /* addProperty */
3785
  nullptr,               /* delProperty */
3786
  nullptr,               /* enumerate */
3787
  nullptr, /* newEnumerate */
3788
  nullptr, /* resolve */
3789
  nullptr, /* mayResolve */
3790
  _finalize, /* finalize */
3791
  _legacycaller, /* call */
3792
  nullptr,               /* hasInstance */
3793
  nullptr,               /* construct */
3794
  nullptr, /* trace */
3795
};
3796
3797
static const js::ClassExtension sClassExtension = {
3798
  nullptr, /* weakmapKeyDelegateOp */
3799
  nullptr /* objectMovedOp */
3800
};
3801
3802
static const DOMJSClass sClass = {
3803
  { "MozQueryInterface",
3804
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
3805
    &sClassOps,
3806
    JS_NULL_CLASS_SPEC,
3807
    &sClassExtension,
3808
    JS_NULL_OBJECT_OPS
3809
  },
3810
  { prototypes::id::MozQueryInterface, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
3811
  IsBaseOf<nsISupports, mozilla::dom::MozQueryInterface >::value,
3812
  sNativePropertyHooks,
3813
  FindAssociatedGlobalForNative<mozilla::dom::MozQueryInterface>::Get,
3814
  GetProtoObjectHandle,
3815
  GetCCParticipant<mozilla::dom::MozQueryInterface>::Get()
3816
};
3817
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
3818
              "Must have the right minimal number of reserved slots.");
3819
static_assert(1 >= 1,
3820
              "Must have enough reserved slots.");
3821
3822
const JSClass*
3823
GetJSClass()
3824
0
{
3825
0
  return sClass.ToJSClass();
3826
0
}
3827
3828
bool
3829
Wrap(JSContext* aCx, mozilla::dom::MozQueryInterface* aObject, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
3830
3
{
3831
3
  MOZ_ASSERT(static_cast<mozilla::dom::MozQueryInterface*>(aObject) ==
3832
3
             reinterpret_cast<mozilla::dom::MozQueryInterface*>(aObject),
3833
3
             "Multiple inheritance for mozilla::dom::MozQueryInterface is broken.");
3834
3
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
3835
3
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
3836
3
3837
3
  JS::Rooted<JSObject*> global(aCx, JS::CurrentGlobalOrNull(aCx));
3838
3
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
3839
3
  if (!canonicalProto) {
3840
0
    return false;
3841
0
  }
3842
3
  JS::Rooted<JSObject*> proto(aCx);
3843
3
  if (aGivenProto) {
3844
0
    proto = aGivenProto;
3845
0
    // Unfortunately, while aGivenProto was in the compartment of aCx
3846
0
    // coming in, we changed compartments to that of "parent" so may need
3847
0
    // to wrap the proto here.
3848
0
    if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
3849
0
      if (!JS_WrapObject(aCx, &proto)) {
3850
0
        return false;
3851
0
      }
3852
3
    }
3853
3
  } else {
3854
3
    proto = canonicalProto;
3855
3
  }
3856
3
3857
3
  BindingJSObjectCreator<mozilla::dom::MozQueryInterface> creator(aCx);
3858
3
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
3859
3
  if (!aReflector) {
3860
0
    return false;
3861
0
  }
3862
3
3863
3
3864
3
3865
3
  creator.InitializationSucceeded();
3866
3
  return true;
3867
3
}
3868
3869
const NativePropertyHooks sNativePropertyHooks[] = { {
3870
  nullptr,
3871
  nullptr,
3872
  nullptr,
3873
  { nullptr, nullptr },
3874
  prototypes::id::MozQueryInterface,
3875
  constructors::id::MozQueryInterface,
3876
  nullptr,
3877
  &DefaultXrayExpandoObjectClass
3878
} };
3879
3880
void
3881
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
3882
1
{
3883
1
  JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
3884
1
  if (!parentProto) {
3885
0
    return;
3886
0
  }
3887
1
3888
1
  JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
3889
1
  if (!constructorProto) {
3890
0
    return;
3891
0
  }
3892
1
3893
1
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::MozQueryInterface);
3894
1
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::MozQueryInterface);
3895
1
  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
3896
1
                              &sPrototypeClass.mBase, protoCache,
3897
1
                              nullptr,
3898
1
                              constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
3899
1
                              interfaceCache,
3900
1
                              nullptr,
3901
1
                              nullptr,
3902
1
                              "MozQueryInterface", aDefineOnGlobal,
3903
1
                              nullptr,
3904
1
                              false);
3905
1
}
3906
3907
JSObject*
3908
GetConstructorObject(JSContext* aCx)
3909
0
{
3910
0
  return GetConstructorObjectHandle(aCx);
3911
0
}
3912
3913
} // namespace MozQueryInterface_Binding
3914
3915
3916
3917
} // namespace dom
3918
} // namespace mozilla