Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dom/bindings/ExternalBinding.cpp
Line
Count
Source (jump to first uncovered line)
1
/* THIS FILE IS AUTOGENERATED FROM External.webidl BY Codegen.py - DO NOT EDIT */
2
3
#include "AtomList.h"
4
#include "ExternalBinding.h"
5
#include "WrapperFactory.h"
6
#include "mozilla/OwningNonNull.h"
7
#include "mozilla/dom/BindingUtils.h"
8
#include "mozilla/dom/DOMJSClass.h"
9
#include "mozilla/dom/NonRefcountedDOMObject.h"
10
#include "mozilla/dom/PrimitiveConversions.h"
11
#include "mozilla/dom/XrayExpandoClass.h"
12
#include "nsIGlobalObject.h"
13
14
namespace mozilla {
15
namespace dom {
16
17
namespace binding_detail {}; // Just to make sure it's known as a namespace
18
using namespace mozilla::dom::binding_detail;
19
20
21
namespace External_Binding {
22
23
MOZ_CAN_RUN_SCRIPT static bool
24
AddSearchProvider(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::External* self, const JSJitMethodCallArgs& args)
25
0
{
26
0
  AUTO_PROFILER_LABEL_FAST("External.AddSearchProvider", DOM, cx);
27
0
28
0
  if (MOZ_UNLIKELY(args.length() < 1)) {
29
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "External.AddSearchProvider");
30
0
  }
31
0
  Maybe<JS::Rooted<JSObject*> > unwrappedObj;
32
0
  bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
33
0
  if (objIsXray) {
34
0
    unwrappedObj.emplace(cx, obj);
35
0
  }
36
0
  binding_detail::FakeString arg0;
37
0
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
38
0
    return false;
39
0
  }
40
0
  if (objIsXray) {
41
0
    unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
42
0
    if (!unwrappedObj.ref()) {
43
0
      return false;
44
0
    }
45
0
  }
46
0
  FastErrorResult rv;
47
0
  self->AddSearchProvider(NonNullHelper(Constify(arg0)), rv, (unwrappedObj ? js::GetNonCCWObjectRealm(*unwrappedObj) : js::GetContextRealm(cx)));
48
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
49
0
    return false;
50
0
  }
51
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
52
0
  args.rval().setUndefined();
53
0
  return true;
54
0
}
55
56
static const JSJitInfo AddSearchProvider_methodinfo = {
57
  { (JSJitGetterOp)AddSearchProvider },
58
  { prototypes::id::External },
59
  { PrototypeTraits<prototypes::id::External>::Depth },
60
  JSJitInfo::Method,
61
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
62
  JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
63
  false,  /* isInfallible. False in setters. */
64
  false,  /* isMovable.  Not relevant for setters. */
65
  false, /* isEliminatable.  Not relevant for setters. */
66
  false, /* isAlwaysInSlot.  Only relevant for getters. */
67
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
68
  false,  /* isTypedMethod.  Only relevant for methods. */
69
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
70
};
71
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
72
static_assert(0 < 1, "There is no slot for us");
73
74
MOZ_CAN_RUN_SCRIPT static bool
75
IsSearchProviderInstalled(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::External* self, const JSJitMethodCallArgs& args)
76
0
{
77
0
  AUTO_PROFILER_LABEL_FAST("External.IsSearchProviderInstalled", DOM, cx);
78
0
79
0
  if (MOZ_UNLIKELY(args.length() < 1)) {
80
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "External.IsSearchProviderInstalled");
81
0
  }
82
0
  Maybe<JS::Rooted<JSObject*> > unwrappedObj;
83
0
  bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
84
0
  if (objIsXray) {
85
0
    unwrappedObj.emplace(cx, obj);
86
0
  }
87
0
  binding_detail::FakeString arg0;
88
0
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
89
0
    return false;
90
0
  }
91
0
  if (objIsXray) {
92
0
    unwrappedObj.ref() = js::CheckedUnwrap(unwrappedObj.ref());
93
0
    if (!unwrappedObj.ref()) {
94
0
      return false;
95
0
    }
96
0
  }
97
0
  FastErrorResult rv;
98
0
  uint32_t result(self->IsSearchProviderInstalled(NonNullHelper(Constify(arg0)), rv, (unwrappedObj ? js::GetNonCCWObjectRealm(*unwrappedObj) : js::GetContextRealm(cx))));
99
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
100
0
    return false;
101
0
  }
102
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
103
0
  args.rval().setNumber(result);
104
0
  return true;
105
0
}
106
107
static const JSJitInfo IsSearchProviderInstalled_methodinfo = {
108
  { (JSJitGetterOp)IsSearchProviderInstalled },
109
  { prototypes::id::External },
110
  { PrototypeTraits<prototypes::id::External>::Depth },
111
  JSJitInfo::Method,
112
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
113
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
114
  false,  /* isInfallible. False in setters. */
115
  false,  /* isMovable.  Not relevant for setters. */
116
  false, /* isEliminatable.  Not relevant for setters. */
117
  false, /* isAlwaysInSlot.  Only relevant for getters. */
118
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
119
  false,  /* isTypedMethod.  Only relevant for methods. */
120
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
121
};
122
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
123
static_assert(0 < 1, "There is no slot for us");
124
125
static bool
126
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
127
0
{
128
0
  mozilla::dom::External* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::External>(obj);
129
0
  // We don't want to preserve if we don't have a wrapper, and we
130
0
  // obviously can't preserve if we're not initialized.
131
0
  if (self && self->GetWrapperPreserveColor()) {
132
0
    PreserveWrapper(self);
133
0
  }
134
0
  return true;
135
0
}
136
137
static void
138
_finalize(js::FreeOp* fop, JSObject* obj)
139
0
{
140
0
  mozilla::dom::External* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::External>(obj);
141
0
  if (self) {
142
0
    ClearWrapper(self, self, obj);
143
0
    AddForDeferredFinalization<mozilla::dom::External>(self);
144
0
  }
145
0
}
146
147
static size_t
148
_objectMoved(JSObject* obj, JSObject* old)
149
0
{
150
0
  mozilla::dom::External* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::External>(obj);
151
0
  if (self) {
152
0
    UpdateWrapper(self, self, obj, old);
153
0
  }
154
0
155
0
  return 0;
156
0
}
157
158
// We deliberately use brace-elision to make Visual Studio produce better initalization code.
159
#if defined(__clang__)
160
#pragma clang diagnostic push
161
#pragma clang diagnostic ignored "-Wmissing-braces"
162
#endif
163
static const JSFunctionSpec sMethods_specs[] = {
164
  JS_FNSPEC("AddSearchProvider", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&AddSearchProvider_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
165
  JS_FNSPEC("IsSearchProviderInstalled", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&IsSearchProviderInstalled_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
166
  JS_FS_END
167
};
168
#if defined(__clang__)
169
#pragma clang diagnostic pop
170
#endif
171
172
173
static const Prefable<const JSFunctionSpec> sMethods[] = {
174
  { nullptr, &sMethods_specs[0] },
175
  { nullptr, nullptr }
176
};
177
178
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
179
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
180
static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
181
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
182
183
184
static uint16_t sNativeProperties_sortedPropertyIndices[2];
185
static PropertyInfo sNativeProperties_propertyInfos[2];
186
187
static const NativePropertiesN<1> sNativeProperties = {
188
  false, 0,
189
  false, 0,
190
  true,  0 /* sMethods */,
191
  false, 0,
192
  false, 0,
193
  false, 0,
194
  false, 0,
195
  -1,
196
  2,
197
  sNativeProperties_sortedPropertyIndices,
198
  {
199
    { sMethods, &sNativeProperties_propertyInfos[0] }
200
  }
201
};
202
static_assert(2 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
203
    "We have a property info count that is oversized");
204
205
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
206
  {
207
    "ExternalPrototype",
208
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
209
    JS_NULL_CLASS_OPS,
210
    JS_NULL_CLASS_SPEC,
211
    JS_NULL_CLASS_EXT,
212
    JS_NULL_OBJECT_OPS
213
  },
214
  eInterfacePrototype,
215
  false,
216
  prototypes::id::External,
217
  PrototypeTraits<prototypes::id::External>::Depth,
218
  sNativePropertyHooks,
219
  "[object ExternalPrototype]",
220
  JS::GetRealmObjectPrototype
221
};
222
223
static const js::ClassOps sClassOps = {
224
  _addProperty, /* addProperty */
225
  nullptr,               /* delProperty */
226
  nullptr,               /* enumerate */
227
  nullptr, /* newEnumerate */
228
  nullptr, /* resolve */
229
  nullptr, /* mayResolve */
230
  _finalize, /* finalize */
231
  nullptr, /* call */
232
  nullptr,               /* hasInstance */
233
  nullptr,               /* construct */
234
  nullptr, /* trace */
235
};
236
237
static const js::ClassExtension sClassExtension = {
238
  nullptr, /* weakmapKeyDelegateOp */
239
  _objectMoved /* objectMovedOp */
240
};
241
242
static const DOMJSClass sClass = {
243
  { "External",
244
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
245
    &sClassOps,
246
    JS_NULL_CLASS_SPEC,
247
    &sClassExtension,
248
    JS_NULL_OBJECT_OPS
249
  },
250
  { prototypes::id::External, 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 },
251
  IsBaseOf<nsISupports, mozilla::dom::External >::value,
252
  sNativePropertyHooks,
253
  FindAssociatedGlobalForNative<mozilla::dom::External>::Get,
254
  GetProtoObjectHandle,
255
  GetCCParticipant<mozilla::dom::External>::Get()
256
};
257
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
258
              "Must have the right minimal number of reserved slots.");
259
static_assert(1 >= 1,
260
              "Must have enough reserved slots.");
261
262
const JSClass*
263
GetJSClass()
264
0
{
265
0
  return sClass.ToJSClass();
266
0
}
267
268
bool
269
Wrap(JSContext* aCx, mozilla::dom::External* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
270
0
{
271
0
  static_assert(!IsBaseOf<NonRefcountedDOMObject, mozilla::dom::External>::value,
272
0
                "Shouldn't have wrappercached things that are not refcounted.");
273
0
  MOZ_ASSERT(static_cast<mozilla::dom::External*>(aObject) ==
274
0
             reinterpret_cast<mozilla::dom::External*>(aObject),
275
0
             "Multiple inheritance for mozilla::dom::External is broken.");
276
0
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
277
0
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
278
0
  MOZ_ASSERT(!aCache->GetWrapper(),
279
0
             "You should probably not be using Wrap() directly; use "
280
0
             "GetOrCreateDOMReflector instead");
281
0
282
0
  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
283
0
             "nsISupports must be on our primary inheritance chain");
284
0
285
0
  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
286
0
  if (!global) {
287
0
    return false;
288
0
  }
289
0
  MOZ_ASSERT(JS_IsGlobalObject(global));
290
0
  MOZ_ASSERT(JS::ObjectIsNotGray(global));
291
0
292
0
  // That might have ended up wrapping us already, due to the wonders
293
0
  // of XBL.  Check for that, and bail out as needed.
294
0
  aReflector.set(aCache->GetWrapper());
295
0
  if (aReflector) {
296
#ifdef DEBUG
297
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
298
#endif // DEBUG
299
    return true;
300
0
  }
301
0
302
0
  JSAutoRealm ar(aCx, global);
303
0
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
304
0
  if (!canonicalProto) {
305
0
    return false;
306
0
  }
307
0
  JS::Rooted<JSObject*> proto(aCx);
308
0
  if (aGivenProto) {
309
0
    proto = aGivenProto;
310
0
    // Unfortunately, while aGivenProto was in the compartment of aCx
311
0
    // coming in, we changed compartments to that of "parent" so may need
312
0
    // to wrap the proto here.
313
0
    if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
314
0
      if (!JS_WrapObject(aCx, &proto)) {
315
0
        return false;
316
0
      }
317
0
    }
318
0
  } else {
319
0
    proto = canonicalProto;
320
0
  }
321
0
322
0
  BindingJSObjectCreator<mozilla::dom::External> creator(aCx);
323
0
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
324
0
  if (!aReflector) {
325
0
    return false;
326
0
  }
327
0
328
0
  aCache->SetWrapper(aReflector);
329
0
  creator.InitializationSucceeded();
330
0
331
0
  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
332
0
             aCache->GetWrapperPreserveColor() == aReflector);
333
0
  // If proto != canonicalProto, we have to preserve our wrapper;
334
0
  // otherwise we won't be able to properly recreate it later, since
335
0
  // we won't know what proto to use.  Note that we don't check
336
0
  // aGivenProto here, since it's entirely possible (and even
337
0
  // somewhat common) to have a non-null aGivenProto which is the
338
0
  // same as canonicalProto.
339
0
  if (proto != canonicalProto) {
340
0
    PreserveWrapper(aObject);
341
0
  }
342
0
343
0
  return true;
344
0
}
345
346
const NativePropertyHooks sNativePropertyHooks[] = { {
347
  nullptr,
348
  nullptr,
349
  nullptr,
350
  { sNativeProperties.Upcast(), nullptr },
351
  prototypes::id::External,
352
  constructors::id::_ID_Count,
353
  nullptr,
354
  &DefaultXrayExpandoObjectClass
355
} };
356
357
void
358
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
359
0
{
360
0
  JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
361
0
  if (!parentProto) {
362
0
    return;
363
0
  }
364
0
365
0
  static bool sIdsInited = false;
366
0
  if (!sIdsInited && NS_IsMainThread()) {
367
0
    if (!InitIds(aCx, sNativeProperties.Upcast())) {
368
0
      return;
369
0
    }
370
0
    sIdsInited = true;
371
0
  }
372
0
373
0
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::External);
374
0
  JS::Heap<JSObject*>* interfaceCache = nullptr;
375
0
  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
376
0
                              &sPrototypeClass.mBase, protoCache,
377
0
                              nullptr,
378
0
                              nullptr, nullptr, 0, nullptr,
379
0
                              interfaceCache,
380
0
                              sNativeProperties.Upcast(),
381
0
                              nullptr,
382
0
                              nullptr, aDefineOnGlobal,
383
0
                              nullptr,
384
0
                              false);
385
0
}
386
387
} // namespace External_Binding
388
389
390
391
void
392
ExternalJSImpl::AddSearchProvider(const nsAString& aDescriptionURL, ErrorResult& aRv, JS::Realm* aRealm)
393
0
{
394
0
  CallSetup s(this, aRv, "External.AddSearchProvider", eRethrowContentExceptions, aRealm, /* aIsJSImplementedWebIDL = */ true);
395
0
  JSContext* cx = s.GetContext();
396
0
  if (!cx) {
397
0
    MOZ_ASSERT(aRv.Failed());
398
0
    return;
399
0
  }
400
0
  JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
401
0
  JS::AutoValueVector argv(cx);
402
0
  if (!argv.resize(1)) {
403
0
    aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
404
0
    return;
405
0
  }
406
0
  unsigned argc = 1;
407
0
408
0
  do {
409
0
    nsString mutableStr(aDescriptionURL);
410
0
    if (!xpc::NonVoidStringToJsval(cx, mutableStr, argv[0])) {
411
0
      aRv.Throw(NS_ERROR_UNEXPECTED);
412
0
      return;
413
0
    }
414
0
    break;
415
0
  } while (false);
416
0
417
0
  JS::Rooted<JS::Value> callable(cx);
418
0
  ExternalAtoms* atomsCache = GetAtomCache<ExternalAtoms>(cx);
419
0
  if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
420
0
      !GetCallableProperty(cx, atomsCache->AddSearchProvider_id, &callable)) {
421
0
    aRv.Throw(NS_ERROR_UNEXPECTED);
422
0
    return;
423
0
  }
424
0
  JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
425
0
  if (!JS::Call(cx, thisValue, callable,
426
0
                JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
427
0
    aRv.NoteJSContextException(cx);
428
0
    return;
429
0
  }
430
0
}
431
432
uint32_t
433
ExternalJSImpl::IsSearchProviderInstalled(const nsAString& aSearchURL, ErrorResult& aRv, JS::Realm* aRealm)
434
0
{
435
0
  CallSetup s(this, aRv, "External.IsSearchProviderInstalled", eRethrowContentExceptions, aRealm, /* aIsJSImplementedWebIDL = */ true);
436
0
  JSContext* cx = s.GetContext();
437
0
  if (!cx) {
438
0
    MOZ_ASSERT(aRv.Failed());
439
0
    return uint32_t(0);
440
0
  }
441
0
  JS::Rooted<JS::Value> rval(cx, JS::UndefinedValue());
442
0
  JS::AutoValueVector argv(cx);
443
0
  if (!argv.resize(1)) {
444
0
    aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
445
0
    return uint32_t(0);
446
0
  }
447
0
  unsigned argc = 1;
448
0
449
0
  do {
450
0
    nsString mutableStr(aSearchURL);
451
0
    if (!xpc::NonVoidStringToJsval(cx, mutableStr, argv[0])) {
452
0
      aRv.Throw(NS_ERROR_UNEXPECTED);
453
0
      return uint32_t(0);
454
0
    }
455
0
    break;
456
0
  } while (false);
457
0
458
0
  JS::Rooted<JS::Value> callable(cx);
459
0
  ExternalAtoms* atomsCache = GetAtomCache<ExternalAtoms>(cx);
460
0
  if ((!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) ||
461
0
      !GetCallableProperty(cx, atomsCache->IsSearchProviderInstalled_id, &callable)) {
462
0
    aRv.Throw(NS_ERROR_UNEXPECTED);
463
0
    return uint32_t(0);
464
0
  }
465
0
  JS::Rooted<JS::Value> thisValue(cx, JS::ObjectValue(*mCallback));
466
0
  if (!JS::Call(cx, thisValue, callable,
467
0
                JS::HandleValueArray::subarray(argv, 0, argc), &rval)) {
468
0
    aRv.NoteJSContextException(cx);
469
0
    return uint32_t(0);
470
0
  }
471
0
  uint32_t rvalDecl;
472
0
  if (!ValueToPrimitive<uint32_t, eDefault>(cx, rval, &rvalDecl)) {
473
0
    aRv.Throw(NS_ERROR_UNEXPECTED);
474
0
    return uint32_t(0);
475
0
  }
476
0
  return rvalDecl;
477
0
}
478
479
bool
480
ExternalJSImpl::InitIds(JSContext* cx, ExternalAtoms* atomsCache)
481
0
{
482
0
  MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
483
0
484
0
  // Initialize these in reverse order so that any failure leaves the first one
485
0
  // uninitialized.
486
0
  if (!atomsCache->IsSearchProviderInstalled_id.init(cx, "IsSearchProviderInstalled") ||
487
0
      !atomsCache->AddSearchProvider_id.init(cx, "AddSearchProvider")) {
488
0
    return false;
489
0
  }
490
0
  return true;
491
0
}
492
493
494
495
NS_IMPL_CYCLE_COLLECTION_CLASS(External)
496
0
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(External)
497
0
  NS_IMPL_CYCLE_COLLECTION_UNLINK(mImpl)
498
0
  NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent)
499
0
  NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
500
0
  tmp->ClearWeakReferences();
501
0
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
502
0
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(External)
503
0
  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mImpl)
504
0
  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent)
505
0
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
506
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(External)
507
NS_IMPL_CYCLE_COLLECTING_ADDREF(External)
508
NS_IMPL_CYCLE_COLLECTING_RELEASE(External)
509
0
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(External)
510
0
  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
511
0
  NS_INTERFACE_MAP_ENTRY(nsISupports)
512
0
  NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
513
0
NS_INTERFACE_MAP_END
514
515
External::External(JS::Handle<JSObject*> aJSImplObject, JS::Handle<JSObject*> aJSImplGlobal, nsIGlobalObject* aParent)
516
  : mImpl(new ExternalJSImpl(nullptr, aJSImplObject, aJSImplGlobal, /* aIncumbentGlobal = */ nullptr)),
517
    mParent(aParent)
518
0
{
519
0
}
520
521
522
External::~External()
523
0
{
524
0
}
525
526
nsISupports*
527
External::GetParentObject() const
528
0
{
529
0
  return mParent;
530
0
}
531
532
JSObject*
533
External::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
534
0
{
535
0
  JS::Rooted<JSObject*> obj(aCx, External_Binding::Wrap(aCx, this, aGivenProto));
536
0
  if (!obj) {
537
0
    return nullptr;
538
0
  }
539
0
540
0
  // Now define it on our chrome object
541
0
  JSAutoRealm ar(aCx, mImpl->CallbackGlobalOrNull());
542
0
  if (!JS_WrapObject(aCx, &obj)) {
543
0
    return nullptr;
544
0
  }
545
0
  if (!JS_DefineProperty(aCx, mImpl->CallbackOrNull(), "__DOM_IMPL__", obj, 0)) {
546
0
    return nullptr;
547
0
  }
548
0
  return obj;
549
0
}
550
551
void
552
External::AddSearchProvider(const nsAString& aDescriptionURL, ErrorResult& aRv, JS::Realm* aRealm)
553
0
{
554
0
  return mImpl->AddSearchProvider(aDescriptionURL, aRv, aRealm);
555
0
}
556
557
uint32_t
558
External::IsSearchProviderInstalled(const nsAString& aSearchURL, ErrorResult& aRv, JS::Realm* aRealm)
559
0
{
560
0
  return mImpl->IsSearchProviderInstalled(aSearchURL, aRv, aRealm);
561
0
}
562
563
bool
564
External::_Create(JSContext* cx, unsigned argc, JS::Value* vp)
565
0
{
566
0
  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
567
0
  if (args.length() < 2) {
568
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "External._create");
569
0
  }
570
0
  if (!args[0].isObject()) {
571
0
    return ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of External._create");
572
0
  }
573
0
  if (!args[1].isObject()) {
574
0
    return ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 2 of External._create");
575
0
  }
576
0
577
0
  // GlobalObject will go through wrappers as needed for us, and
578
0
  // is simpler than the right UnwrapArg incantation.
579
0
  GlobalObject global(cx, &args[0].toObject());
580
0
  if (global.Failed()) {
581
0
    return false;
582
0
  }
583
0
  nsCOMPtr<nsIGlobalObject> globalHolder = do_QueryInterface(global.GetAsSupports());
584
0
  MOZ_ASSERT(globalHolder);
585
0
  JS::Rooted<JSObject*> arg(cx, &args[1].toObject());
586
0
  JS::Rooted<JSObject*> argGlobal(cx, JS::CurrentGlobalOrNull(cx));
587
0
  RefPtr<External> impl = new External(arg, argGlobal, globalHolder);
588
0
  MOZ_ASSERT(js::IsObjectInContextCompartment(arg, cx));
589
0
  return GetOrCreateDOMReflector(cx, impl, args.rval());
590
0
}
591
592
593
} // namespace dom
594
} // namespace mozilla