Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dom/bindings/PermissionsBinding.cpp
Line
Count
Source (jump to first uncovered line)
1
/* THIS FILE IS AUTOGENERATED FROM Permissions.webidl BY Codegen.py - DO NOT EDIT */
2
3
#include "AtomList.h"
4
#include "PermissionsBinding.h"
5
#include "WrapperFactory.h"
6
#include "jsapi.h"
7
#include "mozilla/OwningNonNull.h"
8
#include "mozilla/Preferences.h"
9
#include "mozilla/dom/BindingUtils.h"
10
#include "mozilla/dom/DOMJSClass.h"
11
#include "mozilla/dom/NonRefcountedDOMObject.h"
12
#include "mozilla/dom/Permissions.h"
13
#include "mozilla/dom/Promise.h"
14
#include "mozilla/dom/ScriptSettings.h"
15
#include "mozilla/dom/SimpleGlobalObject.h"
16
#include "mozilla/dom/ToJSValue.h"
17
#include "mozilla/dom/XrayExpandoClass.h"
18
19
namespace mozilla {
20
namespace dom {
21
22
namespace binding_detail {}; // Just to make sure it's known as a namespace
23
using namespace mozilla::dom::binding_detail;
24
25
26
namespace PermissionNameValues {
27
extern const EnumEntry strings[5] = {
28
  {"geolocation", 11},
29
  {"notifications", 13},
30
  {"push", 4},
31
  {"persistent-storage", 18},
32
  { nullptr, 0 }
33
};
34
} // namespace PermissionNameValues
35
36
bool
37
ToJSValue(JSContext* aCx, PermissionName aArgument, JS::MutableHandle<JS::Value> aValue)
38
0
{
39
0
  MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(PermissionNameValues::strings));
40
0
  JSString* resultStr =
41
0
    JS_NewStringCopyN(aCx, PermissionNameValues::strings[uint32_t(aArgument)].value,
42
0
                      PermissionNameValues::strings[uint32_t(aArgument)].length);
43
0
  if (!resultStr) {
44
0
    return false;
45
0
  }
46
0
  aValue.setString(resultStr);
47
0
  return true;
48
0
}
49
50
51
52
PermissionDescriptor::PermissionDescriptor()
53
0
{
54
0
  // Safe to pass a null context if we pass a null value
55
0
  Init(nullptr, JS::NullHandleValue);
56
0
}
57
58
59
60
bool
61
PermissionDescriptor::InitIds(JSContext* cx, PermissionDescriptorAtoms* atomsCache)
62
0
{
63
0
  MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
64
0
65
0
  // Initialize these in reverse order so that any failure leaves the first one
66
0
  // uninitialized.
67
0
  if (!atomsCache->name_id.init(cx, "name")) {
68
0
    return false;
69
0
  }
70
0
  return true;
71
0
}
72
73
bool
74
PermissionDescriptor::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
75
0
{
76
0
  // Passing a null JSContext is OK only if we're initing from null,
77
0
  // Since in that case we will not have to do any property gets
78
0
  // Also evaluate isNullOrUndefined in order to avoid false-positive
79
0
  // checkers by static analysis tools
80
0
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
81
0
  PermissionDescriptorAtoms* atomsCache = nullptr;
82
0
  if (cx) {
83
0
    atomsCache = GetAtomCache<PermissionDescriptorAtoms>(cx);
84
0
    if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
85
0
      return false;
86
0
    }
87
0
  }
88
0
89
0
  if (!IsConvertibleToDictionary(val)) {
90
0
    return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
91
0
  }
92
0
93
0
  bool isNull = val.isNullOrUndefined();
94
0
  // We only need these if !isNull, in which case we have |cx|.
95
0
  Maybe<JS::Rooted<JSObject *> > object;
96
0
  Maybe<JS::Rooted<JS::Value> > temp;
97
0
  if (!isNull) {
98
0
    MOZ_ASSERT(cx);
99
0
    object.emplace(cx, &val.toObject());
100
0
    temp.emplace(cx);
101
0
  }
102
0
  if (!isNull) {
103
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->name_id, temp.ptr())) {
104
0
      return false;
105
0
    }
106
0
  }
107
0
  if (!isNull && !temp->isUndefined()) {
108
0
    {
109
0
      int index;
110
0
      if (!FindEnumStringIndex<true>(cx, temp.ref(), PermissionNameValues::strings, "PermissionName", "'name' member of PermissionDescriptor", &index)) {
111
0
        return false;
112
0
      }
113
0
      MOZ_ASSERT(index >= 0);
114
0
      mName = static_cast<PermissionName>(index);
115
0
    }
116
0
    mIsAnyMemberPresent = true;
117
0
  } else if (cx) {
118
0
    // Don't error out if we have no cx.  In that
119
0
    // situation the caller is default-constructing us and we'll
120
0
    // just assume they know what they're doing.
121
0
    return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
122
0
                             "'name' member of PermissionDescriptor");
123
0
  }
124
0
  return true;
125
0
}
126
127
bool
128
PermissionDescriptor::Init(const nsAString& aJSON)
129
0
{
130
0
  AutoJSAPI jsapi;
131
0
  JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
132
0
  if (!cleanGlobal) {
133
0
    return false;
134
0
  }
135
0
  if (!jsapi.Init(cleanGlobal)) {
136
0
    return false;
137
0
  }
138
0
  JSContext* cx = jsapi.cx();
139
0
  JS::Rooted<JS::Value> json(cx);
140
0
  bool ok = ParseJSON(cx, aJSON, &json);
141
0
  NS_ENSURE_TRUE(ok, false);
142
0
  return Init(cx, json);
143
0
}
144
145
bool
146
PermissionDescriptor::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
147
0
{
148
0
  PermissionDescriptorAtoms* atomsCache = GetAtomCache<PermissionDescriptorAtoms>(cx);
149
0
  if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
150
0
    return false;
151
0
  }
152
0
153
0
  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
154
0
  if (!obj) {
155
0
    return false;
156
0
  }
157
0
  rval.set(JS::ObjectValue(*obj));
158
0
159
0
  do {
160
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
161
0
    JS::Rooted<JS::Value> temp(cx);
162
0
    PermissionName const & currentValue = mName;
163
0
    if (!ToJSValue(cx, currentValue, &temp)) {
164
0
      return false;
165
0
    }
166
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->name_id, temp, JSPROP_ENUMERATE)) {
167
0
      return false;
168
0
    }
169
0
    break;
170
0
  } while(false);
171
0
172
0
  return true;
173
0
}
174
175
bool
176
PermissionDescriptor::ToJSON(nsAString& aJSON) const
177
0
{
178
0
  AutoJSAPI jsapi;
179
0
  jsapi.Init();
180
0
  JSContext *cx = jsapi.cx();
181
0
  // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
182
0
  // because we'll only be creating objects, in ways that have no
183
0
  // side-effects, followed by a call to JS::ToJSONMaybeSafely,
184
0
  // which likewise guarantees no side-effects for the sorts of
185
0
  // things we will pass it.
186
0
  JSAutoRealm ar(cx, UnprivilegedJunkScopeOrWorkerGlobal());
187
0
  JS::Rooted<JS::Value> val(cx);
188
0
  if (!ToObjectInternal(cx, &val)) {
189
0
    return false;
190
0
  }
191
0
  JS::Rooted<JSObject*> obj(cx, &val.toObject());
192
0
  return StringifyToJSON(cx, obj, aJSON);
193
0
}
194
195
void
196
PermissionDescriptor::TraceDictionary(JSTracer* trc)
197
0
{
198
0
}
199
200
PermissionDescriptor&
201
PermissionDescriptor::operator=(const PermissionDescriptor& aOther)
202
0
{
203
0
  DictionaryBase::operator=(aOther);
204
0
  mName = aOther.mName;
205
0
  return *this;
206
0
}
207
208
namespace binding_detail {
209
} // namespace binding_detail
210
211
212
namespace Permissions_Binding {
213
214
MOZ_CAN_RUN_SCRIPT static bool
215
query(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Permissions* self, const JSJitMethodCallArgs& args)
216
0
{
217
0
  AUTO_PROFILER_LABEL_FAST("Permissions.query", DOM, cx);
218
0
219
0
  if (MOZ_UNLIKELY(args.length() < 1)) {
220
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "Permissions.query");
221
0
  }
222
0
  JS::Rooted<JSObject*> arg0(cx);
223
0
  if (args[0].isObject()) {
224
0
    arg0 = &args[0].toObject();
225
0
  } else {
226
0
    ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of Permissions.query");
227
0
    return false;
228
0
  }
229
0
  FastErrorResult rv;
230
0
  auto result(StrongOrRawPtr<Promise>(self->Query(cx, arg0, rv)));
231
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
232
0
    return false;
233
0
  }
234
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
235
0
  if (!ToJSValue(cx, result, args.rval())) {
236
0
    return false;
237
0
  }
238
0
  return true;
239
0
}
240
241
MOZ_CAN_RUN_SCRIPT static bool
242
query_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Permissions* self, const JSJitMethodCallArgs& args)
243
0
{
244
0
  bool ok = query(cx, obj, self, args);
245
0
  if (ok) {
246
0
    return true;
247
0
  }
248
0
  return ConvertExceptionToPromise(cx, args.rval());
249
0
}
250
251
static const JSJitInfo query_methodinfo = {
252
  { (JSJitGetterOp)query_promiseWrapper },
253
  { prototypes::id::Permissions },
254
  { PrototypeTraits<prototypes::id::Permissions>::Depth },
255
  JSJitInfo::Method,
256
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
257
  JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
258
  false,  /* isInfallible. False in setters. */
259
  false,  /* isMovable.  Not relevant for setters. */
260
  false, /* isEliminatable.  Not relevant for setters. */
261
  false, /* isAlwaysInSlot.  Only relevant for getters. */
262
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
263
  false,  /* isTypedMethod.  Only relevant for methods. */
264
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
265
};
266
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
267
static_assert(0 < 1, "There is no slot for us");
268
269
MOZ_CAN_RUN_SCRIPT static bool
270
revoke(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Permissions* self, const JSJitMethodCallArgs& args)
271
0
{
272
0
  AUTO_PROFILER_LABEL_FAST("Permissions.revoke", DOM, cx);
273
0
274
0
  if (MOZ_UNLIKELY(args.length() < 1)) {
275
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "Permissions.revoke");
276
0
  }
277
0
  JS::Rooted<JSObject*> arg0(cx);
278
0
  if (args[0].isObject()) {
279
0
    arg0 = &args[0].toObject();
280
0
  } else {
281
0
    ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of Permissions.revoke");
282
0
    return false;
283
0
  }
284
0
  FastErrorResult rv;
285
0
  auto result(StrongOrRawPtr<Promise>(self->Revoke(cx, arg0, rv)));
286
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
287
0
    return false;
288
0
  }
289
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
290
0
  if (!ToJSValue(cx, result, args.rval())) {
291
0
    return false;
292
0
  }
293
0
  return true;
294
0
}
295
296
MOZ_CAN_RUN_SCRIPT static bool
297
revoke_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Permissions* self, const JSJitMethodCallArgs& args)
298
0
{
299
0
  bool ok = revoke(cx, obj, self, args);
300
0
  if (ok) {
301
0
    return true;
302
0
  }
303
0
  return ConvertExceptionToPromise(cx, args.rval());
304
0
}
305
306
static const JSJitInfo revoke_methodinfo = {
307
  { (JSJitGetterOp)revoke_promiseWrapper },
308
  { prototypes::id::Permissions },
309
  { PrototypeTraits<prototypes::id::Permissions>::Depth },
310
  JSJitInfo::Method,
311
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
312
  JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
313
  false,  /* isInfallible. False in setters. */
314
  false,  /* isMovable.  Not relevant for setters. */
315
  false, /* isEliminatable.  Not relevant for setters. */
316
  false, /* isAlwaysInSlot.  Only relevant for getters. */
317
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
318
  false,  /* isTypedMethod.  Only relevant for methods. */
319
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
320
};
321
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
322
static_assert(0 < 1, "There is no slot for us");
323
324
static bool
325
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
326
0
{
327
0
  mozilla::dom::Permissions* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::Permissions>(obj);
328
0
  // We don't want to preserve if we don't have a wrapper, and we
329
0
  // obviously can't preserve if we're not initialized.
330
0
  if (self && self->GetWrapperPreserveColor()) {
331
0
    PreserveWrapper(self);
332
0
  }
333
0
  return true;
334
0
}
335
336
static void
337
_finalize(js::FreeOp* fop, JSObject* obj)
338
0
{
339
0
  mozilla::dom::Permissions* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::Permissions>(obj);
340
0
  if (self) {
341
0
    ClearWrapper(self, self, obj);
342
0
    AddForDeferredFinalization<mozilla::dom::Permissions>(self);
343
0
  }
344
0
}
345
346
static size_t
347
_objectMoved(JSObject* obj, JSObject* old)
348
0
{
349
0
  mozilla::dom::Permissions* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::Permissions>(obj);
350
0
  if (self) {
351
0
    UpdateWrapper(self, self, obj, old);
352
0
  }
353
0
354
0
  return 0;
355
0
}
356
357
// We deliberately use brace-elision to make Visual Studio produce better initalization code.
358
#if defined(__clang__)
359
#pragma clang diagnostic push
360
#pragma clang diagnostic ignored "-Wmissing-braces"
361
#endif
362
static const JSFunctionSpec sMethods_specs[] = {
363
  JS_FNSPEC("query", (GenericMethod<NormalThisPolicy, ConvertExceptionsToPromises>), reinterpret_cast<const JSJitInfo*>(&query_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
364
  JS_FS_END,
365
  JS_FNSPEC("revoke", (GenericMethod<NormalThisPolicy, ConvertExceptionsToPromises>), reinterpret_cast<const JSJitInfo*>(&revoke_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
366
  JS_FS_END
367
};
368
#if defined(__clang__)
369
#pragma clang diagnostic pop
370
#endif
371
372
// Can't be const because the pref-enabled boolean needs to be writable
373
static PrefableDisablers sMethods_disablers2 = {
374
  true, false, 0, nullptr
375
};
376
377
static const Prefable<const JSFunctionSpec> sMethods[] = {
378
  { nullptr, &sMethods_specs[0] },
379
  { &sMethods_disablers2, &sMethods_specs[2] },
380
  { nullptr, nullptr }
381
};
382
383
static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
384
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
385
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
386
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
387
388
389
static uint16_t sNativeProperties_sortedPropertyIndices[2];
390
static PropertyInfo sNativeProperties_propertyInfos[2];
391
392
static const NativePropertiesN<1> sNativeProperties = {
393
  false, 0,
394
  false, 0,
395
  true,  0 /* sMethods */,
396
  false, 0,
397
  false, 0,
398
  false, 0,
399
  false, 0,
400
  -1,
401
  2,
402
  sNativeProperties_sortedPropertyIndices,
403
  {
404
    { sMethods, &sNativeProperties_propertyInfos[0] }
405
  }
406
};
407
static_assert(2 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
408
    "We have a property info count that is oversized");
409
410
static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
411
  {
412
    "Function",
413
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
414
    &sBoringInterfaceObjectClassClassOps,
415
    JS_NULL_CLASS_SPEC,
416
    JS_NULL_CLASS_EXT,
417
    &sInterfaceObjectClassObjectOps
418
  },
419
  eInterface,
420
  true,
421
  prototypes::id::Permissions,
422
  PrototypeTraits<prototypes::id::Permissions>::Depth,
423
  sNativePropertyHooks,
424
  "function Permissions() {\n    [native code]\n}",
425
  JS::GetRealmFunctionPrototype
426
};
427
428
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
429
  {
430
    "PermissionsPrototype",
431
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
432
    JS_NULL_CLASS_OPS,
433
    JS_NULL_CLASS_SPEC,
434
    JS_NULL_CLASS_EXT,
435
    JS_NULL_OBJECT_OPS
436
  },
437
  eInterfacePrototype,
438
  false,
439
  prototypes::id::Permissions,
440
  PrototypeTraits<prototypes::id::Permissions>::Depth,
441
  sNativePropertyHooks,
442
  "[object PermissionsPrototype]",
443
  JS::GetRealmObjectPrototype
444
};
445
446
static const js::ClassOps sClassOps = {
447
  _addProperty, /* addProperty */
448
  nullptr,               /* delProperty */
449
  nullptr,               /* enumerate */
450
  nullptr, /* newEnumerate */
451
  nullptr, /* resolve */
452
  nullptr, /* mayResolve */
453
  _finalize, /* finalize */
454
  nullptr, /* call */
455
  nullptr,               /* hasInstance */
456
  nullptr,               /* construct */
457
  nullptr, /* trace */
458
};
459
460
static const js::ClassExtension sClassExtension = {
461
  nullptr, /* weakmapKeyDelegateOp */
462
  _objectMoved /* objectMovedOp */
463
};
464
465
static const DOMJSClass sClass = {
466
  { "Permissions",
467
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
468
    &sClassOps,
469
    JS_NULL_CLASS_SPEC,
470
    &sClassExtension,
471
    JS_NULL_OBJECT_OPS
472
  },
473
  { prototypes::id::Permissions, 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 },
474
  IsBaseOf<nsISupports, mozilla::dom::Permissions >::value,
475
  sNativePropertyHooks,
476
  FindAssociatedGlobalForNative<mozilla::dom::Permissions>::Get,
477
  GetProtoObjectHandle,
478
  GetCCParticipant<mozilla::dom::Permissions>::Get()
479
};
480
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
481
              "Must have the right minimal number of reserved slots.");
482
static_assert(1 >= 1,
483
              "Must have enough reserved slots.");
484
485
const JSClass*
486
GetJSClass()
487
0
{
488
0
  return sClass.ToJSClass();
489
0
}
490
491
bool
492
Wrap(JSContext* aCx, mozilla::dom::Permissions* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
493
0
{
494
0
  static_assert(!IsBaseOf<NonRefcountedDOMObject, mozilla::dom::Permissions>::value,
495
0
                "Shouldn't have wrappercached things that are not refcounted.");
496
0
  MOZ_ASSERT(static_cast<mozilla::dom::Permissions*>(aObject) ==
497
0
             reinterpret_cast<mozilla::dom::Permissions*>(aObject),
498
0
             "Multiple inheritance for mozilla::dom::Permissions is broken.");
499
0
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
500
0
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
501
0
  MOZ_ASSERT(!aCache->GetWrapper(),
502
0
             "You should probably not be using Wrap() directly; use "
503
0
             "GetOrCreateDOMReflector instead");
504
0
505
0
  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
506
0
             "nsISupports must be on our primary inheritance chain");
507
0
508
0
  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
509
0
  if (!global) {
510
0
    return false;
511
0
  }
512
0
  MOZ_ASSERT(JS_IsGlobalObject(global));
513
0
  MOZ_ASSERT(JS::ObjectIsNotGray(global));
514
0
515
0
  // That might have ended up wrapping us already, due to the wonders
516
0
  // of XBL.  Check for that, and bail out as needed.
517
0
  aReflector.set(aCache->GetWrapper());
518
0
  if (aReflector) {
519
#ifdef DEBUG
520
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
521
#endif // DEBUG
522
    return true;
523
0
  }
524
0
525
0
  JSAutoRealm ar(aCx, global);
526
0
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
527
0
  if (!canonicalProto) {
528
0
    return false;
529
0
  }
530
0
  JS::Rooted<JSObject*> proto(aCx);
531
0
  if (aGivenProto) {
532
0
    proto = aGivenProto;
533
0
    // Unfortunately, while aGivenProto was in the compartment of aCx
534
0
    // coming in, we changed compartments to that of "parent" so may need
535
0
    // to wrap the proto here.
536
0
    if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
537
0
      if (!JS_WrapObject(aCx, &proto)) {
538
0
        return false;
539
0
      }
540
0
    }
541
0
  } else {
542
0
    proto = canonicalProto;
543
0
  }
544
0
545
0
  BindingJSObjectCreator<mozilla::dom::Permissions> creator(aCx);
546
0
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
547
0
  if (!aReflector) {
548
0
    return false;
549
0
  }
550
0
551
0
  aCache->SetWrapper(aReflector);
552
0
  creator.InitializationSucceeded();
553
0
554
0
  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
555
0
             aCache->GetWrapperPreserveColor() == aReflector);
556
0
  // If proto != canonicalProto, we have to preserve our wrapper;
557
0
  // otherwise we won't be able to properly recreate it later, since
558
0
  // we won't know what proto to use.  Note that we don't check
559
0
  // aGivenProto here, since it's entirely possible (and even
560
0
  // somewhat common) to have a non-null aGivenProto which is the
561
0
  // same as canonicalProto.
562
0
  if (proto != canonicalProto) {
563
0
    PreserveWrapper(aObject);
564
0
  }
565
0
566
0
  return true;
567
0
}
568
569
const NativePropertyHooks sNativePropertyHooks[] = { {
570
  nullptr,
571
  nullptr,
572
  nullptr,
573
  { sNativeProperties.Upcast(), nullptr },
574
  prototypes::id::Permissions,
575
  constructors::id::Permissions,
576
  nullptr,
577
  &DefaultXrayExpandoObjectClass
578
} };
579
580
void
581
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
582
0
{
583
0
  JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
584
0
  if (!parentProto) {
585
0
    return;
586
0
  }
587
0
588
0
  JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
589
0
  if (!constructorProto) {
590
0
    return;
591
0
  }
592
0
593
0
  static bool sIdsInited = false;
594
0
  if (!sIdsInited && NS_IsMainThread()) {
595
0
    if (!InitIds(aCx, sNativeProperties.Upcast())) {
596
0
      return;
597
0
    }
598
0
    sIdsInited = true;
599
0
  }
600
0
601
0
  static bool sPrefCachesInited = false;
602
0
  if (!sPrefCachesInited && NS_IsMainThread()) {
603
0
    sPrefCachesInited = true;
604
0
    Preferences::AddBoolVarCache(&sMethods[1].disablers->enabled, "dom.permissions.revoke.enable");
605
0
  }
606
0
607
0
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::Permissions);
608
0
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::Permissions);
609
0
  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
610
0
                              &sPrototypeClass.mBase, protoCache,
611
0
                              nullptr,
612
0
                              constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
613
0
                              interfaceCache,
614
0
                              sNativeProperties.Upcast(),
615
0
                              nullptr,
616
0
                              "Permissions", aDefineOnGlobal,
617
0
                              nullptr,
618
0
                              false);
619
0
}
620
621
JSObject*
622
GetConstructorObject(JSContext* aCx)
623
0
{
624
0
  return GetConstructorObjectHandle(aCx);
625
0
}
626
627
} // namespace Permissions_Binding
628
629
630
631
} // namespace dom
632
} // namespace mozilla