Coverage Report

Created: 2018-09-25 14:53

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