Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dom/bindings/MozSharedMapBinding.cpp
Line
Count
Source (jump to first uncovered line)
1
/* THIS FILE IS AUTOGENERATED FROM MozSharedMap.webidl BY Codegen.py - DO NOT EDIT */
2
3
#include "AtomList.h"
4
#include "EventBinding.h"
5
#include "EventTargetBinding.h"
6
#include "MozSharedMapBinding.h"
7
#include "WrapperFactory.h"
8
#include "XrayWrapper.h"
9
#include "mozilla/OwningNonNull.h"
10
#include "mozilla/dom/BindingUtils.h"
11
#include "mozilla/dom/DOMJSClass.h"
12
#include "mozilla/dom/IterableIterator.h"
13
#include "mozilla/dom/NonRefcountedDOMObject.h"
14
#include "mozilla/dom/PrimitiveConversions.h"
15
#include "mozilla/dom/ScriptSettings.h"
16
#include "mozilla/dom/SimpleGlobalObject.h"
17
#include "mozilla/dom/ToJSValue.h"
18
#include "mozilla/dom/XrayExpandoClass.h"
19
#include "mozilla/dom/ipc/SharedMap.h"
20
#include "mozilla/dom/ipc/SharedMapChangeEvent.h"
21
#include "nsContentUtils.h"
22
23
namespace mozilla {
24
namespace dom {
25
26
namespace binding_detail {}; // Just to make sure it's known as a namespace
27
using namespace mozilla::dom::binding_detail;
28
29
30
31
MozSharedMapChangeEventInit::MozSharedMapChangeEventInit()
32
  : EventInit(FastDictionaryInitializer())
33
0
{
34
0
  // Safe to pass a null context if we pass a null value
35
0
  Init(nullptr, JS::NullHandleValue);
36
0
}
37
38
39
40
bool
41
MozSharedMapChangeEventInit::InitIds(JSContext* cx, MozSharedMapChangeEventInitAtoms* atomsCache)
42
0
{
43
0
  MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
44
0
45
0
  // Initialize these in reverse order so that any failure leaves the first one
46
0
  // uninitialized.
47
0
  if (!atomsCache->changedKeys_id.init(cx, "changedKeys")) {
48
0
    return false;
49
0
  }
50
0
  return true;
51
0
}
52
53
bool
54
MozSharedMapChangeEventInit::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
55
0
{
56
0
  // Passing a null JSContext is OK only if we're initing from null,
57
0
  // Since in that case we will not have to do any property gets
58
0
  // Also evaluate isNullOrUndefined in order to avoid false-positive
59
0
  // checkers by static analysis tools
60
0
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
61
0
  MozSharedMapChangeEventInitAtoms* atomsCache = nullptr;
62
0
  if (cx) {
63
0
    atomsCache = GetAtomCache<MozSharedMapChangeEventInitAtoms>(cx);
64
0
    if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
65
0
      return false;
66
0
    }
67
0
  }
68
0
69
0
  // Per spec, we init the parent's members first
70
0
  if (!EventInit::Init(cx, val)) {
71
0
    return false;
72
0
  }
73
0
74
0
  bool isNull = val.isNullOrUndefined();
75
0
  // We only need these if !isNull, in which case we have |cx|.
76
0
  Maybe<JS::Rooted<JSObject *> > object;
77
0
  Maybe<JS::Rooted<JS::Value> > temp;
78
0
  if (!isNull) {
79
0
    MOZ_ASSERT(cx);
80
0
    object.emplace(cx, &val.toObject());
81
0
    temp.emplace(cx);
82
0
  }
83
0
  if (!isNull) {
84
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->changedKeys_id, temp.ptr())) {
85
0
      return false;
86
0
    }
87
0
  }
88
0
  if (!isNull && !temp->isUndefined()) {
89
0
    if (temp.ref().isObject()) {
90
0
      JS::ForOfIterator iter(cx);
91
0
      if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
92
0
        return false;
93
0
      }
94
0
      if (!iter.valueIsIterable()) {
95
0
        ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'changedKeys' member of MozSharedMapChangeEventInit");
96
0
        return false;
97
0
      }
98
0
      Sequence<nsString> &arr = mChangedKeys;
99
0
      JS::Rooted<JS::Value> temp(cx);
100
0
      while (true) {
101
0
        bool done;
102
0
        if (!iter.next(&temp, &done)) {
103
0
          return false;
104
0
        }
105
0
        if (done) {
106
0
          break;
107
0
        }
108
0
        nsString* slotPtr = arr.AppendElement(mozilla::fallible);
109
0
        if (!slotPtr) {
110
0
          JS_ReportOutOfMemory(cx);
111
0
          return false;
112
0
        }
113
0
        nsString& slot = *slotPtr;
114
0
        if (!ConvertJSValueToString(cx, temp, eStringify, eStringify, slot)) {
115
0
          return false;
116
0
        }
117
0
      }
118
0
    } else {
119
0
      ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'changedKeys' member of MozSharedMapChangeEventInit");
120
0
      return false;
121
0
    }
122
0
    mIsAnyMemberPresent = true;
123
0
  } else if (cx) {
124
0
    // Don't error out if we have no cx.  In that
125
0
    // situation the caller is default-constructing us and we'll
126
0
    // just assume they know what they're doing.
127
0
    return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
128
0
                             "'changedKeys' member of MozSharedMapChangeEventInit");
129
0
  }
130
0
  return true;
131
0
}
132
133
bool
134
MozSharedMapChangeEventInit::Init(const nsAString& aJSON)
135
0
{
136
0
  AutoJSAPI jsapi;
137
0
  JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
138
0
  if (!cleanGlobal) {
139
0
    return false;
140
0
  }
141
0
  if (!jsapi.Init(cleanGlobal)) {
142
0
    return false;
143
0
  }
144
0
  JSContext* cx = jsapi.cx();
145
0
  JS::Rooted<JS::Value> json(cx);
146
0
  bool ok = ParseJSON(cx, aJSON, &json);
147
0
  NS_ENSURE_TRUE(ok, false);
148
0
  return Init(cx, json);
149
0
}
150
151
bool
152
MozSharedMapChangeEventInit::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
153
0
{
154
0
  MozSharedMapChangeEventInitAtoms* atomsCache = GetAtomCache<MozSharedMapChangeEventInitAtoms>(cx);
155
0
  if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
156
0
    return false;
157
0
  }
158
0
159
0
  // Per spec, we define the parent's members first
160
0
  if (!EventInit::ToObjectInternal(cx, rval)) {
161
0
    return false;
162
0
  }
163
0
  JS::Rooted<JSObject*> obj(cx, &rval.toObject());
164
0
165
0
  do {
166
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
167
0
    JS::Rooted<JS::Value> temp(cx);
168
0
    Sequence<nsString> const & currentValue = mChangedKeys;
169
0
170
0
    uint32_t length = currentValue.Length();
171
0
    JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
172
0
    if (!returnArray) {
173
0
      return false;
174
0
    }
175
0
    // Scope for 'tmp'
176
0
    {
177
0
      JS::Rooted<JS::Value> tmp(cx);
178
0
      for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
179
0
        // Control block to let us common up the JS_DefineElement calls when there
180
0
        // are different ways to succeed at wrapping the object.
181
0
        do {
182
0
          if (!xpc::NonVoidStringToJsval(cx, currentValue[sequenceIdx0], &tmp)) {
183
0
            return false;
184
0
          }
185
0
          break;
186
0
        } while (false);
187
0
        if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
188
0
                              JSPROP_ENUMERATE)) {
189
0
          return false;
190
0
        }
191
0
      }
192
0
    }
193
0
    temp.setObject(*returnArray);
194
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->changedKeys_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
MozSharedMapChangeEventInit::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
MozSharedMapChangeEventInit::TraceDictionary(JSTracer* trc)
225
0
{
226
0
  EventInit::TraceDictionary(trc);
227
0
}
228
229
MozSharedMapChangeEventInit&
230
MozSharedMapChangeEventInit::operator=(const MozSharedMapChangeEventInit& aOther)
231
0
{
232
0
  EventInit::operator=(aOther);
233
0
  mChangedKeys = aOther.mChangedKeys;
234
0
  return *this;
235
0
}
236
237
namespace binding_detail {
238
} // namespace binding_detail
239
240
241
namespace MozSharedMap_Binding {
242
243
static_assert(IsRefcounted<NativeType>::value == IsRefcounted<EventTarget_Binding::NativeType>::value,
244
              "Can't inherit from an interface with a different ownership model.");
245
246
MOZ_CAN_RUN_SCRIPT static bool
247
has(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::ipc::SharedMap* self, const JSJitMethodCallArgs& args)
248
0
{
249
0
  AUTO_PROFILER_LABEL_FAST("MozSharedMap.has", DOM, cx);
250
0
251
0
  if (MOZ_UNLIKELY(args.length() < 1)) {
252
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "MozSharedMap.has");
253
0
  }
254
0
  binding_detail::FakeString arg0;
255
0
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
256
0
    return false;
257
0
  }
258
0
  bool result(self->Has(NonNullHelper(Constify(arg0))));
259
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
260
0
  args.rval().setBoolean(result);
261
0
  return true;
262
0
}
263
264
static const JSJitInfo has_methodinfo = {
265
  { (JSJitGetterOp)has },
266
  { prototypes::id::MozSharedMap },
267
  { PrototypeTraits<prototypes::id::MozSharedMap>::Depth },
268
  JSJitInfo::Method,
269
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
270
  JSVAL_TYPE_BOOLEAN,  /* returnType.  Not relevant for setters. */
271
  false,  /* isInfallible. False in setters. */
272
  false,  /* isMovable.  Not relevant for setters. */
273
  false, /* isEliminatable.  Not relevant for setters. */
274
  false, /* isAlwaysInSlot.  Only relevant for getters. */
275
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
276
  false,  /* isTypedMethod.  Only relevant for methods. */
277
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
278
};
279
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
280
static_assert(0 < 1, "There is no slot for us");
281
282
MOZ_CAN_RUN_SCRIPT static bool
283
get(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::ipc::SharedMap* self, const JSJitMethodCallArgs& args)
284
0
{
285
0
  AUTO_PROFILER_LABEL_FAST("MozSharedMap.get", DOM, cx);
286
0
287
0
  if (MOZ_UNLIKELY(args.length() < 1)) {
288
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "MozSharedMap.get");
289
0
  }
290
0
  binding_detail::FakeString arg0;
291
0
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
292
0
    return false;
293
0
  }
294
0
  FastErrorResult rv;
295
0
  JS::Rooted<JS::Value> result(cx);
296
0
  self->Get(cx, NonNullHelper(Constify(arg0)), &result, rv);
297
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
298
0
    return false;
299
0
  }
300
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
301
0
  JS::ExposeValueToActiveJS(result);
302
0
  args.rval().set(result);
303
0
  if (!MaybeWrapValue(cx, args.rval())) {
304
0
    return false;
305
0
  }
306
0
  return true;
307
0
}
308
309
static const JSJitInfo get_methodinfo = {
310
  { (JSJitGetterOp)get },
311
  { prototypes::id::MozSharedMap },
312
  { PrototypeTraits<prototypes::id::MozSharedMap>::Depth },
313
  JSJitInfo::Method,
314
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
315
  JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
316
  false,  /* isInfallible. False in setters. */
317
  false,  /* isMovable.  Not relevant for setters. */
318
  false, /* isEliminatable.  Not relevant for setters. */
319
  false, /* isAlwaysInSlot.  Only relevant for getters. */
320
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
321
  false,  /* isTypedMethod.  Only relevant for methods. */
322
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
323
};
324
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
325
static_assert(0 < 1, "There is no slot for us");
326
327
MOZ_CAN_RUN_SCRIPT static bool
328
entries(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::ipc::SharedMap* self, const JSJitMethodCallArgs& args)
329
0
{
330
0
  AUTO_PROFILER_LABEL_FAST("MozSharedMap.entries", DOM, cx);
331
0
332
0
  typedef mozilla::dom::IterableIterator<mozilla::dom::ipc::SharedMap> itrType;
333
0
  RefPtr<itrType> result(new itrType(self,
334
0
                                       itrType::IterableIteratorType::Entries,
335
0
                                       &MozSharedMapIterator_Binding::Wrap));
336
0
  static_assert(!IsPointer<decltype(result)>::value,
337
0
                "NewObject implies that we need to keep the object alive with a strong reference.");
338
0
  if (!WrapNewBindingNonWrapperCachedObject(cx, obj, result, args.rval())) {
339
0
    MOZ_ASSERT(JS_IsExceptionPending(cx));
340
0
    return false;
341
0
  }
342
0
  return true;
343
0
}
344
345
static const JSJitInfo::ArgType entries_methodinfo_argTypes[] = { JSJitInfo::ArgTypeListEnd };
346
static const JSTypedMethodJitInfo entries_methodinfo = {
347
  {
348
    { (JSJitGetterOp)entries },
349
    { prototypes::id::MozSharedMap },
350
    { PrototypeTraits<prototypes::id::MozSharedMap>::Depth },
351
    JSJitInfo::Method,
352
    JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
353
    JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
354
    false,  /* isInfallible. False in setters. */
355
    false,  /* isMovable.  Not relevant for setters. */
356
    false, /* isEliminatable.  Not relevant for setters. */
357
    false, /* isAlwaysInSlot.  Only relevant for getters. */
358
    false, /* isLazilyCachedInSlot.  Only relevant for getters. */
359
    true,  /* isTypedMethod.  Only relevant for methods. */
360
    0   /* Reserved slot index, if we're stored in a slot, else 0. */
361
  },
362
  entries_methodinfo_argTypes
363
};
364
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
365
static_assert(0 < 1, "There is no slot for us");
366
367
MOZ_CAN_RUN_SCRIPT static bool
368
keys(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::ipc::SharedMap* self, const JSJitMethodCallArgs& args)
369
0
{
370
0
  AUTO_PROFILER_LABEL_FAST("MozSharedMap.keys", DOM, cx);
371
0
372
0
  typedef mozilla::dom::IterableIterator<mozilla::dom::ipc::SharedMap> itrType;
373
0
  RefPtr<itrType> result(new itrType(self,
374
0
                                       itrType::IterableIteratorType::Keys,
375
0
                                       &MozSharedMapIterator_Binding::Wrap));
376
0
  static_assert(!IsPointer<decltype(result)>::value,
377
0
                "NewObject implies that we need to keep the object alive with a strong reference.");
378
0
  if (!WrapNewBindingNonWrapperCachedObject(cx, obj, result, args.rval())) {
379
0
    MOZ_ASSERT(JS_IsExceptionPending(cx));
380
0
    return false;
381
0
  }
382
0
  return true;
383
0
}
384
385
static const JSJitInfo::ArgType keys_methodinfo_argTypes[] = { JSJitInfo::ArgTypeListEnd };
386
static const JSTypedMethodJitInfo keys_methodinfo = {
387
  {
388
    { (JSJitGetterOp)keys },
389
    { prototypes::id::MozSharedMap },
390
    { PrototypeTraits<prototypes::id::MozSharedMap>::Depth },
391
    JSJitInfo::Method,
392
    JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
393
    JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
394
    false,  /* isInfallible. False in setters. */
395
    false,  /* isMovable.  Not relevant for setters. */
396
    false, /* isEliminatable.  Not relevant for setters. */
397
    false, /* isAlwaysInSlot.  Only relevant for getters. */
398
    false, /* isLazilyCachedInSlot.  Only relevant for getters. */
399
    true,  /* isTypedMethod.  Only relevant for methods. */
400
    0   /* Reserved slot index, if we're stored in a slot, else 0. */
401
  },
402
  keys_methodinfo_argTypes
403
};
404
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
405
static_assert(0 < 1, "There is no slot for us");
406
407
MOZ_CAN_RUN_SCRIPT static bool
408
values(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::ipc::SharedMap* self, const JSJitMethodCallArgs& args)
409
0
{
410
0
  AUTO_PROFILER_LABEL_FAST("MozSharedMap.values", DOM, cx);
411
0
412
0
  typedef mozilla::dom::IterableIterator<mozilla::dom::ipc::SharedMap> itrType;
413
0
  RefPtr<itrType> result(new itrType(self,
414
0
                                       itrType::IterableIteratorType::Values,
415
0
                                       &MozSharedMapIterator_Binding::Wrap));
416
0
  static_assert(!IsPointer<decltype(result)>::value,
417
0
                "NewObject implies that we need to keep the object alive with a strong reference.");
418
0
  if (!WrapNewBindingNonWrapperCachedObject(cx, obj, result, args.rval())) {
419
0
    MOZ_ASSERT(JS_IsExceptionPending(cx));
420
0
    return false;
421
0
  }
422
0
  return true;
423
0
}
424
425
static const JSJitInfo::ArgType values_methodinfo_argTypes[] = { JSJitInfo::ArgTypeListEnd };
426
static const JSTypedMethodJitInfo values_methodinfo = {
427
  {
428
    { (JSJitGetterOp)values },
429
    { prototypes::id::MozSharedMap },
430
    { PrototypeTraits<prototypes::id::MozSharedMap>::Depth },
431
    JSJitInfo::Method,
432
    JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
433
    JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
434
    false,  /* isInfallible. False in setters. */
435
    false,  /* isMovable.  Not relevant for setters. */
436
    false, /* isEliminatable.  Not relevant for setters. */
437
    false, /* isAlwaysInSlot.  Only relevant for getters. */
438
    false, /* isLazilyCachedInSlot.  Only relevant for getters. */
439
    true,  /* isTypedMethod.  Only relevant for methods. */
440
    0   /* Reserved slot index, if we're stored in a slot, else 0. */
441
  },
442
  values_methodinfo_argTypes
443
};
444
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
445
static_assert(0 < 1, "There is no slot for us");
446
447
MOZ_CAN_RUN_SCRIPT static bool
448
forEach(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::ipc::SharedMap* self, const JSJitMethodCallArgs& args)
449
0
{
450
0
  AUTO_PROFILER_LABEL_FAST("MozSharedMap.forEach", DOM, cx);
451
0
452
0
  JS::Rooted<JSObject*> arg0(cx);
453
0
  if (args.get(0).isObject()) {
454
0
    arg0 = &args.get(0).toObject();
455
0
  } else {
456
0
    ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of MozSharedMap.forEach");
457
0
    return false;
458
0
  }
459
0
  JS::Rooted<JS::Value> arg1(cx);
460
0
  if (args.hasDefined(1)) {
461
0
    arg1 = args.get(1);
462
0
  } else {
463
0
    arg1 = JS::UndefinedValue();
464
0
  }
465
0
  if (!JS::IsCallable(arg0)) {
466
0
    ThrowErrorMessage(cx, MSG_NOT_CALLABLE, "Argument 1 of MozSharedMap.forEach");
467
0
    return false;
468
0
  }
469
0
  JS::AutoValueArray<3> callArgs(cx);
470
0
  callArgs[2].setObject(*obj);
471
0
  JS::Rooted<JS::Value> ignoredReturnVal(cx);
472
0
  auto GetKeyAtIndex = &mozilla::dom::ipc::SharedMap::GetKeyAtIndex;
473
0
  auto GetValueAtIndex = &mozilla::dom::ipc::SharedMap::GetValueAtIndex;
474
0
  for (size_t i = 0; i < self->GetIterableLength(); ++i) {
475
0
    if (!CallIterableGetter(cx, GetValueAtIndex, self, i,
476
0
                            callArgs[0])) {
477
0
      return false;
478
0
    }
479
0
    if (!CallIterableGetter(cx, GetKeyAtIndex, self, i,
480
0
                            callArgs[1])) {
481
0
      return false;
482
0
    }
483
0
    if (!JS::Call(cx, arg1, arg0, JS::HandleValueArray(callArgs),
484
0
                  &ignoredReturnVal)) {
485
0
      return false;
486
0
    }
487
0
  }
488
0
  args.rval().setUndefined();
489
0
  return true;
490
0
}
491
492
static const JSJitInfo forEach_methodinfo = {
493
  { (JSJitGetterOp)forEach },
494
  { prototypes::id::MozSharedMap },
495
  { PrototypeTraits<prototypes::id::MozSharedMap>::Depth },
496
  JSJitInfo::Method,
497
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
498
  JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
499
  false,  /* isInfallible. False in setters. */
500
  false,  /* isMovable.  Not relevant for setters. */
501
  false, /* isEliminatable.  Not relevant for setters. */
502
  false, /* isAlwaysInSlot.  Only relevant for getters. */
503
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
504
  false,  /* isTypedMethod.  Only relevant for methods. */
505
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
506
};
507
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
508
static_assert(0 < 1, "There is no slot for us");
509
510
static bool
511
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
512
0
{
513
0
  mozilla::dom::ipc::SharedMap* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::ipc::SharedMap>(obj);
514
0
  // We don't want to preserve if we don't have a wrapper, and we
515
0
  // obviously can't preserve if we're not initialized.
516
0
  if (self && self->GetWrapperPreserveColor()) {
517
0
    PreserveWrapper(self);
518
0
  }
519
0
  return true;
520
0
}
521
522
static void
523
_finalize(js::FreeOp* fop, JSObject* obj)
524
0
{
525
0
  mozilla::dom::ipc::SharedMap* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::ipc::SharedMap>(obj);
526
0
  if (self) {
527
0
    ClearWrapper(self, self, obj);
528
0
    AddForDeferredFinalization<mozilla::dom::ipc::SharedMap>(self);
529
0
  }
530
0
}
531
532
static size_t
533
_objectMoved(JSObject* obj, JSObject* old)
534
0
{
535
0
  mozilla::dom::ipc::SharedMap* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::ipc::SharedMap>(obj);
536
0
  if (self) {
537
0
    UpdateWrapper(self, self, obj, old);
538
0
  }
539
0
540
0
  return 0;
541
0
}
542
543
// We deliberately use brace-elision to make Visual Studio produce better initalization code.
544
#if defined(__clang__)
545
#pragma clang diagnostic push
546
#pragma clang diagnostic ignored "-Wmissing-braces"
547
#endif
548
static const JSFunctionSpec sMethods_specs[] = {
549
  JS_FNSPEC("has", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&has_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
550
  JS_FNSPEC("get", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&get_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
551
  JS_FNSPEC("entries", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&entries_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
552
  JS_FNSPEC("keys", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&keys_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
553
  JS_FNSPEC("values", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&values_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
554
  JS_FNSPEC("forEach", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&forEach_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
555
  JS_FS_END
556
};
557
#if defined(__clang__)
558
#pragma clang diagnostic pop
559
#endif
560
561
562
static const Prefable<const JSFunctionSpec> sMethods[] = {
563
  { nullptr, &sMethods_specs[0] },
564
  { nullptr, nullptr }
565
};
566
567
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
568
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
569
static_assert(6 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
570
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
571
572
573
static uint16_t sNativeProperties_sortedPropertyIndices[6];
574
static PropertyInfo sNativeProperties_propertyInfos[6];
575
576
static const NativePropertiesN<1> sNativeProperties = {
577
  false, 0,
578
  false, 0,
579
  true,  0 /* sMethods */,
580
  false, 0,
581
  false, 0,
582
  false, 0,
583
  false, 0,
584
  2,
585
  6,
586
  sNativeProperties_sortedPropertyIndices,
587
  {
588
    { sMethods, &sNativeProperties_propertyInfos[0] }
589
  }
590
};
591
static_assert(2 < 1ull << (CHAR_BIT * sizeof(sNativeProperties.iteratorAliasMethodIndex) - 1),
592
    "We have an iterator alias index that is oversized");
593
static_assert(6 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
594
    "We have a property info count that is oversized");
595
596
static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
597
  {
598
    "Function",
599
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
600
    &sBoringInterfaceObjectClassClassOps,
601
    JS_NULL_CLASS_SPEC,
602
    JS_NULL_CLASS_EXT,
603
    &sInterfaceObjectClassObjectOps
604
  },
605
  eInterface,
606
  true,
607
  prototypes::id::MozSharedMap,
608
  PrototypeTraits<prototypes::id::MozSharedMap>::Depth,
609
  sNativePropertyHooks,
610
  "function MozSharedMap() {\n    [native code]\n}",
611
  EventTarget_Binding::GetConstructorObject
612
};
613
614
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
615
  {
616
    "MozSharedMapPrototype",
617
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
618
    JS_NULL_CLASS_OPS,
619
    JS_NULL_CLASS_SPEC,
620
    JS_NULL_CLASS_EXT,
621
    JS_NULL_OBJECT_OPS
622
  },
623
  eInterfacePrototype,
624
  false,
625
  prototypes::id::MozSharedMap,
626
  PrototypeTraits<prototypes::id::MozSharedMap>::Depth,
627
  sNativePropertyHooks,
628
  "[object MozSharedMapPrototype]",
629
  EventTarget_Binding::GetProtoObject
630
};
631
632
bool
633
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
634
0
{
635
0
  return nsContentUtils::ThreadsafeIsSystemCaller(aCx);
636
0
}
637
638
static const js::ClassOps sClassOps = {
639
  _addProperty, /* addProperty */
640
  nullptr,               /* delProperty */
641
  nullptr,               /* enumerate */
642
  nullptr, /* newEnumerate */
643
  nullptr, /* resolve */
644
  nullptr, /* mayResolve */
645
  _finalize, /* finalize */
646
  nullptr, /* call */
647
  nullptr,               /* hasInstance */
648
  nullptr,               /* construct */
649
  nullptr, /* trace */
650
};
651
652
static const js::ClassExtension sClassExtension = {
653
  nullptr, /* weakmapKeyDelegateOp */
654
  _objectMoved /* objectMovedOp */
655
};
656
657
static const DOMJSClass sClass = {
658
  { "MozSharedMap",
659
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
660
    &sClassOps,
661
    JS_NULL_CLASS_SPEC,
662
    &sClassExtension,
663
    JS_NULL_OBJECT_OPS
664
  },
665
  { prototypes::id::EventTarget, prototypes::id::MozSharedMap, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
666
  IsBaseOf<nsISupports, mozilla::dom::ipc::SharedMap >::value,
667
  sNativePropertyHooks,
668
  FindAssociatedGlobalForNative<mozilla::dom::ipc::SharedMap>::Get,
669
  GetProtoObjectHandle,
670
  GetCCParticipant<mozilla::dom::ipc::SharedMap>::Get()
671
};
672
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
673
              "Must have the right minimal number of reserved slots.");
674
static_assert(1 >= 1,
675
              "Must have enough reserved slots.");
676
677
const JSClass*
678
GetJSClass()
679
0
{
680
0
  return sClass.ToJSClass();
681
0
}
682
683
bool
684
Wrap(JSContext* aCx, mozilla::dom::ipc::SharedMap* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
685
0
{
686
0
  static_assert(!IsBaseOf<NonRefcountedDOMObject, mozilla::dom::ipc::SharedMap>::value,
687
0
                "Shouldn't have wrappercached things that are not refcounted.");
688
0
  MOZ_ASSERT(static_cast<mozilla::dom::ipc::SharedMap*>(aObject) ==
689
0
             reinterpret_cast<mozilla::dom::ipc::SharedMap*>(aObject),
690
0
             "Multiple inheritance for mozilla::dom::ipc::SharedMap is broken.");
691
0
  MOZ_ASSERT(static_cast<mozilla::dom::EventTarget*>(aObject) ==
692
0
             reinterpret_cast<mozilla::dom::EventTarget*>(aObject),
693
0
             "Multiple inheritance for mozilla::dom::EventTarget is broken.");
694
0
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
695
0
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
696
0
  MOZ_ASSERT(!aCache->GetWrapper(),
697
0
             "You should probably not be using Wrap() directly; use "
698
0
             "GetOrCreateDOMReflector instead");
699
0
700
0
  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
701
0
             "nsISupports must be on our primary inheritance chain");
702
0
703
0
  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
704
0
  if (!global) {
705
0
    return false;
706
0
  }
707
0
  MOZ_ASSERT(JS_IsGlobalObject(global));
708
0
  MOZ_ASSERT(JS::ObjectIsNotGray(global));
709
0
710
0
  // That might have ended up wrapping us already, due to the wonders
711
0
  // of XBL.  Check for that, and bail out as needed.
712
0
  aReflector.set(aCache->GetWrapper());
713
0
  if (aReflector) {
714
#ifdef DEBUG
715
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
716
#endif // DEBUG
717
    return true;
718
0
  }
719
0
720
0
  JSAutoRealm ar(aCx, global);
721
0
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
722
0
  if (!canonicalProto) {
723
0
    return false;
724
0
  }
725
0
  JS::Rooted<JSObject*> proto(aCx);
726
0
  if (aGivenProto) {
727
0
    proto = aGivenProto;
728
0
    // Unfortunately, while aGivenProto was in the compartment of aCx
729
0
    // coming in, we changed compartments to that of "parent" so may need
730
0
    // to wrap the proto here.
731
0
    if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
732
0
      if (!JS_WrapObject(aCx, &proto)) {
733
0
        return false;
734
0
      }
735
0
    }
736
0
  } else {
737
0
    proto = canonicalProto;
738
0
  }
739
0
740
0
  BindingJSObjectCreator<mozilla::dom::ipc::SharedMap> creator(aCx);
741
0
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
742
0
  if (!aReflector) {
743
0
    return false;
744
0
  }
745
0
746
0
  aCache->SetWrapper(aReflector);
747
0
  creator.InitializationSucceeded();
748
0
749
0
  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
750
0
             aCache->GetWrapperPreserveColor() == aReflector);
751
0
  // If proto != canonicalProto, we have to preserve our wrapper;
752
0
  // otherwise we won't be able to properly recreate it later, since
753
0
  // we won't know what proto to use.  Note that we don't check
754
0
  // aGivenProto here, since it's entirely possible (and even
755
0
  // somewhat common) to have a non-null aGivenProto which is the
756
0
  // same as canonicalProto.
757
0
  if (proto != canonicalProto) {
758
0
    PreserveWrapper(aObject);
759
0
  }
760
0
761
0
  return true;
762
0
}
763
764
const NativePropertyHooks sNativePropertyHooks[] = { {
765
  nullptr,
766
  nullptr,
767
  nullptr,
768
  { sNativeProperties.Upcast(), nullptr },
769
  prototypes::id::MozSharedMap,
770
  constructors::id::MozSharedMap,
771
  EventTarget_Binding::sNativePropertyHooks,
772
  &DefaultXrayExpandoObjectClass
773
} };
774
775
void
776
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
777
0
{
778
0
  JS::Handle<JSObject*> parentProto(EventTarget_Binding::GetProtoObjectHandle(aCx));
779
0
  if (!parentProto) {
780
0
    return;
781
0
  }
782
0
783
0
  JS::Handle<JSObject*> constructorProto(EventTarget_Binding::GetConstructorObjectHandle(aCx));
784
0
  if (!constructorProto) {
785
0
    return;
786
0
  }
787
0
788
0
  static bool sIdsInited = false;
789
0
  if (!sIdsInited && NS_IsMainThread()) {
790
0
    if (!InitIds(aCx, sNativeProperties.Upcast())) {
791
0
      return;
792
0
    }
793
0
    sIdsInited = true;
794
0
  }
795
0
796
0
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::MozSharedMap);
797
0
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::MozSharedMap);
798
0
  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
799
0
                              &sPrototypeClass.mBase, protoCache,
800
0
                              nullptr,
801
0
                              constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
802
0
                              interfaceCache,
803
0
                              sNativeProperties.Upcast(),
804
0
                              nullptr,
805
0
                              "MozSharedMap", aDefineOnGlobal,
806
0
                              nullptr,
807
0
                              false);
808
0
809
0
  // Set up aliases on the interface prototype object we just created.
810
0
  JS::Handle<JSObject*> proto = GetProtoObjectHandle(aCx);
811
0
  if (!proto) {
812
0
    *protoCache = nullptr;
813
0
    if (interfaceCache) {
814
0
      *interfaceCache = nullptr;
815
0
    }
816
0
    return;
817
0
  }
818
0
819
0
  JS::Rooted<JS::Value> aliasedVal(aCx);
820
0
821
0
  if (!JS_GetProperty(aCx, proto, "entries", &aliasedVal)) {
822
0
    *protoCache = nullptr;
823
0
    if (interfaceCache) {
824
0
      *interfaceCache = nullptr;
825
0
    }
826
0
    return;
827
0
  }
828
0
  JS::Rooted<jsid> iteratorId(aCx, SYMBOL_TO_JSID(JS::GetWellKnownSymbol(aCx, JS::SymbolCode::iterator)));
829
0
  if (!JS_DefinePropertyById(aCx, proto, iteratorId, aliasedVal, 0)) {
830
0
    *protoCache = nullptr;
831
0
    if (interfaceCache) {
832
0
      *interfaceCache = nullptr;
833
0
    }
834
0
    return;
835
0
  }
836
0
}
837
838
JSObject*
839
GetProtoObject(JSContext* aCx)
840
0
{
841
0
  return GetProtoObjectHandle(aCx);
842
0
}
843
844
JSObject*
845
GetConstructorObject(JSContext* aCx)
846
0
{
847
0
  return GetConstructorObjectHandle(aCx);
848
0
}
849
850
} // namespace MozSharedMap_Binding
851
852
853
854
namespace MozSharedMapChangeEvent_Binding {
855
856
static_assert(IsRefcounted<NativeType>::value == IsRefcounted<Event_Binding::NativeType>::value,
857
              "Can't inherit from an interface with a different ownership model.");
858
859
MOZ_CAN_RUN_SCRIPT static bool
860
get_changedKeys(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::ipc::SharedMapChangeEvent* self, JSJitGetterCallArgs args)
861
0
{
862
0
  AUTO_PROFILER_LABEL_FAST("get MozSharedMapChangeEvent.changedKeys", DOM, cx);
863
0
864
0
  // Have to either root across the getter call or reget after.
865
0
  bool isXray;
866
0
  JS::Rooted<JSObject*> slotStorage(cx, GetCachedSlotStorageObject(cx, obj, &isXray));
867
0
  if (!slotStorage) {
868
0
    return false;
869
0
  }
870
0
  const size_t slotIndex = isXray ? (xpc::JSSLOT_EXPANDO_COUNT + 0) : (DOM_INSTANCE_RESERVED_SLOTS + 0);
871
0
  MOZ_ASSERT(JSCLASS_RESERVED_SLOTS(js::GetObjectClass(slotStorage)) > slotIndex);
872
0
  {
873
0
    // Scope for cachedVal
874
0
    JS::Value cachedVal = js::GetReservedSlot(slotStorage, slotIndex);
875
0
    if (!cachedVal.isUndefined()) {
876
0
      args.rval().set(cachedVal);
877
0
      // The cached value is in the compartment of slotStorage,
878
0
      // so wrap into the caller compartment as needed.
879
0
      if (MaybeWrapNonDOMObjectValue(cx, args.rval())) {
880
0
        return true;
881
0
      }
882
0
      return false;
883
0
    }
884
0
  }
885
0
886
0
  nsTArray<nsString> result;
887
0
  self->GetChangedKeys(result);
888
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
889
0
  {
890
0
    JS::Rooted<JSObject*> conversionScope(cx, isXray ? JS::CurrentGlobalOrNull(cx) : slotStorage);
891
0
    JSAutoRealm ar(cx, conversionScope);
892
0
    do { // block we break out of when done wrapping
893
0
894
0
      uint32_t length = result.Length();
895
0
      JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
896
0
      if (!returnArray) {
897
0
        return false;
898
0
      }
899
0
      // Scope for 'tmp'
900
0
      {
901
0
        JS::Rooted<JS::Value> tmp(cx);
902
0
        for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
903
0
          // Control block to let us common up the JS_DefineElement calls when there
904
0
          // are different ways to succeed at wrapping the object.
905
0
          do {
906
0
            if (!xpc::NonVoidStringToJsval(cx, result[sequenceIdx0], &tmp)) {
907
0
              return false;
908
0
            }
909
0
            break;
910
0
          } while (false);
911
0
          if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
912
0
                                JSPROP_ENUMERATE)) {
913
0
            return false;
914
0
          }
915
0
        }
916
0
      }
917
0
      args.rval().setObject(*returnArray);
918
0
      break;
919
0
    } while (false);
920
0
  }
921
0
  { // And now store things in the realm of our slotStorage.
922
0
    JSAutoRealm ar(cx, slotStorage);
923
0
    // Make a copy so that we don't do unnecessary wrapping on args.rval().
924
0
    JS::Rooted<JS::Value> storedVal(cx, args.rval());
925
0
    if (!MaybeWrapNonDOMObjectValue(cx, &storedVal)) {
926
0
      return false;
927
0
    }
928
0
    js::SetReservedSlot(slotStorage, slotIndex, storedVal);
929
0
    if (!isXray) {
930
0
      // In the Xray case we don't need to do this, because getting the
931
0
      // expando object already preserved our wrapper.
932
0
      PreserveWrapper(self);
933
0
    }
934
0
  }
935
0
  // And now make sure args.rval() is in the caller realm.
936
0
  if (MaybeWrapNonDOMObjectValue(cx, args.rval())) {
937
0
    return true;
938
0
  }
939
0
  return false;
940
0
}
941
942
static const JSJitInfo changedKeys_getterinfo = {
943
  { (JSJitGetterOp)get_changedKeys },
944
  { prototypes::id::MozSharedMapChangeEvent },
945
  { PrototypeTraits<prototypes::id::MozSharedMapChangeEvent>::Depth },
946
  JSJitInfo::Getter,
947
  JSJitInfo::AliasNone, /* aliasSet.  Not relevant for setters. */
948
  JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
949
  false,  /* isInfallible. False in setters. */
950
  true,  /* isMovable.  Not relevant for setters. */
951
  true, /* isEliminatable.  Not relevant for setters. */
952
  false, /* isAlwaysInSlot.  Only relevant for getters. */
953
  true, /* isLazilyCachedInSlot.  Only relevant for getters. */
954
  false,  /* isTypedMethod.  Only relevant for methods. */
955
  (DOM_INSTANCE_RESERVED_SLOTS + 0)   /* Reserved slot index, if we're stored in a slot, else 0. */
956
};
957
static_assert((DOM_INSTANCE_RESERVED_SLOTS + 0) <= JSJitInfo::maxSlotIndex, "We won't fit");
958
static_assert((DOM_INSTANCE_RESERVED_SLOTS + 0) < 2, "There is no slot for us");
959
960
MOZ_CAN_RUN_SCRIPT static bool
961
get_isTrusted(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::ipc::SharedMapChangeEvent* self, JSJitGetterCallArgs args)
962
0
{
963
0
  AUTO_PROFILER_LABEL_FAST("get MozSharedMapChangeEvent.isTrusted", DOM, cx);
964
0
965
0
  bool result(self->IsTrusted());
966
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
967
0
  args.rval().setBoolean(result);
968
0
  return true;
969
0
}
970
971
static const JSJitInfo isTrusted_getterinfo = {
972
  { (JSJitGetterOp)get_isTrusted },
973
  { prototypes::id::MozSharedMapChangeEvent },
974
  { PrototypeTraits<prototypes::id::MozSharedMapChangeEvent>::Depth },
975
  JSJitInfo::Getter,
976
  JSJitInfo::AliasDOMSets, /* aliasSet.  Not relevant for setters. */
977
  JSVAL_TYPE_BOOLEAN,  /* returnType.  Not relevant for setters. */
978
  true,  /* isInfallible. False in setters. */
979
  true,  /* isMovable.  Not relevant for setters. */
980
  true, /* isEliminatable.  Not relevant for setters. */
981
  false, /* isAlwaysInSlot.  Only relevant for getters. */
982
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
983
  false,  /* isTypedMethod.  Only relevant for methods. */
984
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
985
};
986
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
987
static_assert(0 < 2, "There is no slot for us");
988
989
static bool
990
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
991
0
{
992
0
  mozilla::dom::ipc::SharedMapChangeEvent* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::ipc::SharedMapChangeEvent>(obj);
993
0
  // We don't want to preserve if we don't have a wrapper, and we
994
0
  // obviously can't preserve if we're not initialized.
995
0
  if (self && self->GetWrapperPreserveColor()) {
996
0
    PreserveWrapper(self);
997
0
  }
998
0
  return true;
999
0
}
1000
1001
static void
1002
_finalize(js::FreeOp* fop, JSObject* obj)
1003
0
{
1004
0
  mozilla::dom::ipc::SharedMapChangeEvent* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::ipc::SharedMapChangeEvent>(obj);
1005
0
  if (self) {
1006
0
    ClearWrapper(self, self, obj);
1007
0
    AddForDeferredFinalization<mozilla::dom::ipc::SharedMapChangeEvent>(self);
1008
0
  }
1009
0
}
1010
1011
static size_t
1012
_objectMoved(JSObject* obj, JSObject* old)
1013
0
{
1014
0
  mozilla::dom::ipc::SharedMapChangeEvent* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::ipc::SharedMapChangeEvent>(obj);
1015
0
  if (self) {
1016
0
    UpdateWrapper(self, self, obj, old);
1017
0
  }
1018
0
1019
0
  return 0;
1020
0
}
1021
1022
// We deliberately use brace-elision to make Visual Studio produce better initalization code.
1023
#if defined(__clang__)
1024
#pragma clang diagnostic push
1025
#pragma clang diagnostic ignored "-Wmissing-braces"
1026
#endif
1027
static const JSPropertySpec sAttributes_specs[] = {
1028
  { "changedKeys", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &changedKeys_getterinfo, nullptr, nullptr },
1029
  { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
1030
};
1031
#if defined(__clang__)
1032
#pragma clang diagnostic pop
1033
#endif
1034
1035
1036
static const Prefable<const JSPropertySpec> sAttributes[] = {
1037
  { nullptr, &sAttributes_specs[0] },
1038
  { nullptr, nullptr }
1039
};
1040
1041
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
1042
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
1043
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
1044
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
1045
1046
// We deliberately use brace-elision to make Visual Studio produce better initalization code.
1047
#if defined(__clang__)
1048
#pragma clang diagnostic push
1049
#pragma clang diagnostic ignored "-Wmissing-braces"
1050
#endif
1051
static const JSPropertySpec sUnforgeableAttributes_specs[] = {
1052
  { "isTrusted", JSPROP_ENUMERATE | JSPROP_PERMANENT, GenericGetter<NormalThisPolicy, ThrowExceptions>, &isTrusted_getterinfo, nullptr, nullptr },
1053
  { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
1054
};
1055
#if defined(__clang__)
1056
#pragma clang diagnostic pop
1057
#endif
1058
1059
1060
static const Prefable<const JSPropertySpec> sUnforgeableAttributes[] = {
1061
  { nullptr, &sUnforgeableAttributes_specs[0] },
1062
  { nullptr, nullptr }
1063
};
1064
1065
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
1066
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
1067
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
1068
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
1069
1070
1071
static uint16_t sNativeProperties_sortedPropertyIndices[2];
1072
static PropertyInfo sNativeProperties_propertyInfos[2];
1073
1074
static const NativePropertiesN<2> sNativeProperties = {
1075
  false, 0,
1076
  false, 0,
1077
  false, 0,
1078
  true,  0 /* sAttributes */,
1079
  false, 0,
1080
  true,  1 /* sUnforgeableAttributes */,
1081
  false, 0,
1082
  -1,
1083
  2,
1084
  sNativeProperties_sortedPropertyIndices,
1085
  {
1086
    { sAttributes, &sNativeProperties_propertyInfos[0] },
1087
    { sUnforgeableAttributes, &sNativeProperties_propertyInfos[1] }
1088
  }
1089
};
1090
static_assert(2 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
1091
    "We have a property info count that is oversized");
1092
1093
static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
1094
  {
1095
    "Function",
1096
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
1097
    &sBoringInterfaceObjectClassClassOps,
1098
    JS_NULL_CLASS_SPEC,
1099
    JS_NULL_CLASS_EXT,
1100
    &sInterfaceObjectClassObjectOps
1101
  },
1102
  eInterface,
1103
  true,
1104
  prototypes::id::MozSharedMapChangeEvent,
1105
  PrototypeTraits<prototypes::id::MozSharedMapChangeEvent>::Depth,
1106
  sNativePropertyHooks,
1107
  "function MozSharedMapChangeEvent() {\n    [native code]\n}",
1108
  Event_Binding::GetConstructorObject
1109
};
1110
1111
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
1112
  {
1113
    "MozSharedMapChangeEventPrototype",
1114
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE + 1 /* slot for the JSObject holding the unforgeable properties */),
1115
    JS_NULL_CLASS_OPS,
1116
    JS_NULL_CLASS_SPEC,
1117
    JS_NULL_CLASS_EXT,
1118
    JS_NULL_OBJECT_OPS
1119
  },
1120
  eInterfacePrototype,
1121
  false,
1122
  prototypes::id::MozSharedMapChangeEvent,
1123
  PrototypeTraits<prototypes::id::MozSharedMapChangeEvent>::Depth,
1124
  sNativePropertyHooks,
1125
  "[object MozSharedMapChangeEventPrototype]",
1126
  Event_Binding::GetProtoObject
1127
};
1128
1129
bool
1130
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
1131
0
{
1132
0
  return nsContentUtils::ThreadsafeIsSystemCaller(aCx);
1133
0
}
1134
1135
static const js::ClassOps sClassOps = {
1136
  _addProperty, /* addProperty */
1137
  nullptr,               /* delProperty */
1138
  nullptr,               /* enumerate */
1139
  nullptr, /* newEnumerate */
1140
  nullptr, /* resolve */
1141
  nullptr, /* mayResolve */
1142
  _finalize, /* finalize */
1143
  nullptr, /* call */
1144
  nullptr,               /* hasInstance */
1145
  nullptr,               /* construct */
1146
  nullptr, /* trace */
1147
};
1148
1149
static const js::ClassExtension sClassExtension = {
1150
  nullptr, /* weakmapKeyDelegateOp */
1151
  _objectMoved /* objectMovedOp */
1152
};
1153
1154
static const DOMJSClass sClass = {
1155
  { "MozSharedMapChangeEvent",
1156
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(2) | JSCLASS_SKIP_NURSERY_FINALIZE,
1157
    &sClassOps,
1158
    JS_NULL_CLASS_SPEC,
1159
    &sClassExtension,
1160
    JS_NULL_OBJECT_OPS
1161
  },
1162
  { prototypes::id::Event, prototypes::id::MozSharedMapChangeEvent, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
1163
  IsBaseOf<nsISupports, mozilla::dom::ipc::SharedMapChangeEvent >::value,
1164
  sNativePropertyHooks,
1165
  FindAssociatedGlobalForNative<mozilla::dom::ipc::SharedMapChangeEvent>::Get,
1166
  GetProtoObjectHandle,
1167
  GetCCParticipant<mozilla::dom::ipc::SharedMapChangeEvent>::Get()
1168
};
1169
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
1170
              "Must have the right minimal number of reserved slots.");
1171
static_assert(2 >= 2,
1172
              "Must have enough reserved slots.");
1173
1174
const JSClass*
1175
GetJSClass()
1176
0
{
1177
0
  return sClass.ToJSClass();
1178
0
}
1179
1180
bool
1181
Wrap(JSContext* aCx, mozilla::dom::ipc::SharedMapChangeEvent* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
1182
0
{
1183
0
  static_assert(!IsBaseOf<NonRefcountedDOMObject, mozilla::dom::ipc::SharedMapChangeEvent>::value,
1184
0
                "Shouldn't have wrappercached things that are not refcounted.");
1185
0
  MOZ_ASSERT(static_cast<mozilla::dom::ipc::SharedMapChangeEvent*>(aObject) ==
1186
0
             reinterpret_cast<mozilla::dom::ipc::SharedMapChangeEvent*>(aObject),
1187
0
             "Multiple inheritance for mozilla::dom::ipc::SharedMapChangeEvent is broken.");
1188
0
  MOZ_ASSERT(static_cast<mozilla::dom::Event*>(aObject) ==
1189
0
             reinterpret_cast<mozilla::dom::Event*>(aObject),
1190
0
             "Multiple inheritance for mozilla::dom::Event is broken.");
1191
0
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
1192
0
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
1193
0
  MOZ_ASSERT(!aCache->GetWrapper(),
1194
0
             "You should probably not be using Wrap() directly; use "
1195
0
             "GetOrCreateDOMReflector instead");
1196
0
1197
0
  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
1198
0
             "nsISupports must be on our primary inheritance chain");
1199
0
1200
0
  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
1201
0
  if (!global) {
1202
0
    return false;
1203
0
  }
1204
0
  MOZ_ASSERT(JS_IsGlobalObject(global));
1205
0
  MOZ_ASSERT(JS::ObjectIsNotGray(global));
1206
0
1207
0
  // That might have ended up wrapping us already, due to the wonders
1208
0
  // of XBL.  Check for that, and bail out as needed.
1209
0
  aReflector.set(aCache->GetWrapper());
1210
0
  if (aReflector) {
1211
#ifdef DEBUG
1212
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
1213
#endif // DEBUG
1214
    return true;
1215
0
  }
1216
0
1217
0
  JSAutoRealm ar(aCx, global);
1218
0
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
1219
0
  if (!canonicalProto) {
1220
0
    return false;
1221
0
  }
1222
0
  JS::Rooted<JSObject*> proto(aCx);
1223
0
  if (aGivenProto) {
1224
0
    proto = aGivenProto;
1225
0
    // Unfortunately, while aGivenProto was in the compartment of aCx
1226
0
    // coming in, we changed compartments to that of "parent" so may need
1227
0
    // to wrap the proto here.
1228
0
    if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
1229
0
      if (!JS_WrapObject(aCx, &proto)) {
1230
0
        return false;
1231
0
      }
1232
0
    }
1233
0
  } else {
1234
0
    proto = canonicalProto;
1235
0
  }
1236
0
1237
0
  BindingJSObjectCreator<mozilla::dom::ipc::SharedMapChangeEvent> creator(aCx);
1238
0
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
1239
0
  if (!aReflector) {
1240
0
    return false;
1241
0
  }
1242
0
1243
0
  aCache->SetWrapper(aReflector);
1244
0
1245
0
  // Important: do unforgeable property setup after we have handed
1246
0
  // over ownership of the C++ object to obj as needed, so that if
1247
0
  // we fail and it ends up GCed it won't have problems in the
1248
0
  // finalizer trying to drop its ownership of the C++ object.
1249
0
  JS::Rooted<JSObject*> unforgeableHolder(aCx,
1250
0
    &js::GetReservedSlot(canonicalProto, DOM_INTERFACE_PROTO_SLOTS_BASE).toObject());
1251
0
  if (!JS_InitializePropertiesFromCompatibleNativeObject(aCx, aReflector, unforgeableHolder)) {
1252
0
    aCache->ReleaseWrapper(aObject);
1253
0
    aCache->ClearWrapper();
1254
0
    return false;
1255
0
  }
1256
0
  creator.InitializationSucceeded();
1257
0
1258
0
  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
1259
0
             aCache->GetWrapperPreserveColor() == aReflector);
1260
0
  // If proto != canonicalProto, we have to preserve our wrapper;
1261
0
  // otherwise we won't be able to properly recreate it later, since
1262
0
  // we won't know what proto to use.  Note that we don't check
1263
0
  // aGivenProto here, since it's entirely possible (and even
1264
0
  // somewhat common) to have a non-null aGivenProto which is the
1265
0
  // same as canonicalProto.
1266
0
  if (proto != canonicalProto) {
1267
0
    PreserveWrapper(aObject);
1268
0
  }
1269
0
1270
0
  return true;
1271
0
}
1272
1273
// This may allocate too many slots, because we only really need
1274
// slots for our non-interface-typed members that we cache.  But
1275
// allocating slots only for those would make the slot index
1276
// computations much more complicated, so let's do this the simple
1277
// way for now.
1278
DEFINE_XRAY_EXPANDO_CLASS(static, sXrayExpandoObjectClass, 1);
1279
1280
const NativePropertyHooks sNativePropertyHooks[] = { {
1281
  nullptr,
1282
  nullptr,
1283
  nullptr,
1284
  { sNativeProperties.Upcast(), nullptr },
1285
  prototypes::id::MozSharedMapChangeEvent,
1286
  constructors::id::MozSharedMapChangeEvent,
1287
  Event_Binding::sNativePropertyHooks,
1288
  &sXrayExpandoObjectClass
1289
} };
1290
1291
void
1292
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
1293
0
{
1294
0
  JS::Handle<JSObject*> parentProto(Event_Binding::GetProtoObjectHandle(aCx));
1295
0
  if (!parentProto) {
1296
0
    return;
1297
0
  }
1298
0
1299
0
  JS::Handle<JSObject*> constructorProto(Event_Binding::GetConstructorObjectHandle(aCx));
1300
0
  if (!constructorProto) {
1301
0
    return;
1302
0
  }
1303
0
1304
0
  static bool sIdsInited = false;
1305
0
  if (!sIdsInited && NS_IsMainThread()) {
1306
0
    if (!InitIds(aCx, sNativeProperties.Upcast())) {
1307
0
      return;
1308
0
    }
1309
0
    sIdsInited = true;
1310
0
  }
1311
0
1312
0
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::MozSharedMapChangeEvent);
1313
0
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::MozSharedMapChangeEvent);
1314
0
  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
1315
0
                              &sPrototypeClass.mBase, protoCache,
1316
0
                              nullptr,
1317
0
                              constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
1318
0
                              interfaceCache,
1319
0
                              sNativeProperties.Upcast(),
1320
0
                              nullptr,
1321
0
                              "MozSharedMapChangeEvent", aDefineOnGlobal,
1322
0
                              nullptr,
1323
0
                              false);
1324
0
1325
0
  JS::Rooted<JSObject*> unforgeableHolder(aCx);
1326
0
  {
1327
0
    JS::Rooted<JSObject*> holderProto(aCx, *protoCache);
1328
0
    unforgeableHolder = JS_NewObjectWithoutMetadata(aCx, sClass.ToJSClass(), holderProto);
1329
0
    if (!unforgeableHolder) {
1330
0
      *protoCache = nullptr;
1331
0
      if (interfaceCache) {
1332
0
        *interfaceCache = nullptr;
1333
0
      }
1334
0
      return;
1335
0
    }
1336
0
  }
1337
0
1338
0
  if (!DefineUnforgeableAttributes(aCx, unforgeableHolder, sUnforgeableAttributes)) {
1339
0
    *protoCache = nullptr;
1340
0
    if (interfaceCache) {
1341
0
      *interfaceCache = nullptr;
1342
0
    }
1343
0
    return;
1344
0
  }
1345
0
1346
0
  if (*protoCache) {
1347
0
    js::SetReservedSlot(*protoCache, DOM_INTERFACE_PROTO_SLOTS_BASE,
1348
0
                        JS::ObjectValue(*unforgeableHolder));
1349
0
  }
1350
0
}
1351
1352
JSObject*
1353
GetConstructorObject(JSContext* aCx)
1354
0
{
1355
0
  return GetConstructorObjectHandle(aCx);
1356
0
}
1357
1358
} // namespace MozSharedMapChangeEvent_Binding
1359
1360
1361
1362
namespace MozSharedMapIterator_Binding {
1363
1364
MOZ_CAN_RUN_SCRIPT static bool
1365
next(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::IterableIterator<mozilla::dom::ipc::SharedMap>* self, const JSJitMethodCallArgs& args)
1366
0
{
1367
0
  AUTO_PROFILER_LABEL_FAST("MozSharedMapIterator.next", DOM, cx);
1368
0
1369
0
  FastErrorResult rv;
1370
0
  JS::Rooted<JSObject*> result(cx);
1371
0
  self->Next(cx, &result, rv);
1372
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
1373
0
    return false;
1374
0
  }
1375
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
1376
0
  JS::ExposeObjectToActiveJS(result);
1377
0
  args.rval().setObject(*result);
1378
0
  if (!MaybeWrapObjectValue(cx, args.rval())) {
1379
0
    return false;
1380
0
  }
1381
0
  return true;
1382
0
}
1383
1384
static const JSJitInfo next_methodinfo = {
1385
  { (JSJitGetterOp)next },
1386
  { prototypes::id::MozSharedMapIterator },
1387
  { PrototypeTraits<prototypes::id::MozSharedMapIterator>::Depth },
1388
  JSJitInfo::Method,
1389
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
1390
  JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
1391
  false,  /* isInfallible. False in setters. */
1392
  false,  /* isMovable.  Not relevant for setters. */
1393
  false, /* isEliminatable.  Not relevant for setters. */
1394
  false, /* isAlwaysInSlot.  Only relevant for getters. */
1395
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
1396
  false,  /* isTypedMethod.  Only relevant for methods. */
1397
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
1398
};
1399
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1400
static_assert(0 < 1, "There is no slot for us");
1401
1402
static void
1403
_finalize(js::FreeOp* fop, JSObject* obj)
1404
0
{
1405
0
  mozilla::dom::IterableIterator<mozilla::dom::ipc::SharedMap>* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::IterableIterator<mozilla::dom::ipc::SharedMap>>(obj);
1406
0
  if (self) {
1407
0
    AddForDeferredFinalization<mozilla::dom::IterableIterator<mozilla::dom::ipc::SharedMap>>(self);
1408
0
  }
1409
0
}
1410
1411
// We deliberately use brace-elision to make Visual Studio produce better initalization code.
1412
#if defined(__clang__)
1413
#pragma clang diagnostic push
1414
#pragma clang diagnostic ignored "-Wmissing-braces"
1415
#endif
1416
static const JSFunctionSpec sMethods_specs[] = {
1417
  JS_FNSPEC("next", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&next_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
1418
  JS_FS_END
1419
};
1420
#if defined(__clang__)
1421
#pragma clang diagnostic pop
1422
#endif
1423
1424
1425
static const Prefable<const JSFunctionSpec> sMethods[] = {
1426
  { nullptr, &sMethods_specs[0] },
1427
  { nullptr, nullptr }
1428
};
1429
1430
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
1431
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
1432
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
1433
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
1434
1435
1436
static uint16_t sNativeProperties_sortedPropertyIndices[1];
1437
static PropertyInfo sNativeProperties_propertyInfos[1];
1438
1439
static const NativePropertiesN<1> sNativeProperties = {
1440
  false, 0,
1441
  false, 0,
1442
  true,  0 /* sMethods */,
1443
  false, 0,
1444
  false, 0,
1445
  false, 0,
1446
  false, 0,
1447
  -1,
1448
  1,
1449
  sNativeProperties_sortedPropertyIndices,
1450
  {
1451
    { sMethods, &sNativeProperties_propertyInfos[0] }
1452
  }
1453
};
1454
static_assert(1 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
1455
    "We have a property info count that is oversized");
1456
1457
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
1458
  {
1459
    "MozSharedMap IteratorPrototype",
1460
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
1461
    JS_NULL_CLASS_OPS,
1462
    JS_NULL_CLASS_SPEC,
1463
    JS_NULL_CLASS_EXT,
1464
    JS_NULL_OBJECT_OPS
1465
  },
1466
  eInterfacePrototype,
1467
  false,
1468
  prototypes::id::MozSharedMapIterator,
1469
  PrototypeTraits<prototypes::id::MozSharedMapIterator>::Depth,
1470
  sNativePropertyHooks,
1471
  "[object MozSharedMap IteratorPrototype]",
1472
  JS::GetRealmIteratorPrototype
1473
};
1474
1475
static const js::ClassOps sClassOps = {
1476
  nullptr, /* addProperty */
1477
  nullptr,               /* delProperty */
1478
  nullptr,               /* enumerate */
1479
  nullptr, /* newEnumerate */
1480
  nullptr, /* resolve */
1481
  nullptr, /* mayResolve */
1482
  _finalize, /* finalize */
1483
  nullptr, /* call */
1484
  nullptr,               /* hasInstance */
1485
  nullptr,               /* construct */
1486
  nullptr, /* trace */
1487
};
1488
1489
static const js::ClassExtension sClassExtension = {
1490
  nullptr, /* weakmapKeyDelegateOp */
1491
  nullptr /* objectMovedOp */
1492
};
1493
1494
static const DOMJSClass sClass = {
1495
  { "MozSharedMap Iterator",
1496
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
1497
    &sClassOps,
1498
    JS_NULL_CLASS_SPEC,
1499
    &sClassExtension,
1500
    JS_NULL_OBJECT_OPS
1501
  },
1502
  { prototypes::id::MozSharedMapIterator, 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 },
1503
  IsBaseOf<nsISupports, mozilla::dom::IterableIterator<mozilla::dom::ipc::SharedMap> >::value,
1504
  sNativePropertyHooks,
1505
  FindAssociatedGlobalForNative<mozilla::dom::IterableIterator<mozilla::dom::ipc::SharedMap>>::Get,
1506
  GetProtoObjectHandle,
1507
  GetCCParticipant<mozilla::dom::IterableIterator<mozilla::dom::ipc::SharedMap>>::Get()
1508
};
1509
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
1510
              "Must have the right minimal number of reserved slots.");
1511
static_assert(1 >= 1,
1512
              "Must have enough reserved slots.");
1513
1514
const JSClass*
1515
GetJSClass()
1516
0
{
1517
0
  return sClass.ToJSClass();
1518
0
}
1519
1520
bool
1521
Wrap(JSContext* aCx, mozilla::dom::IterableIterator<mozilla::dom::ipc::SharedMap>* aObject, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
1522
0
{
1523
0
  MOZ_ASSERT(static_cast<mozilla::dom::IterableIterator<mozilla::dom::ipc::SharedMap>*>(aObject) ==
1524
0
             reinterpret_cast<mozilla::dom::IterableIterator<mozilla::dom::ipc::SharedMap>*>(aObject),
1525
0
             "Multiple inheritance for mozilla::dom::IterableIterator<mozilla::dom::ipc::SharedMap> is broken.");
1526
0
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
1527
0
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
1528
0
1529
0
  JS::Rooted<JSObject*> global(aCx, JS::CurrentGlobalOrNull(aCx));
1530
0
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
1531
0
  if (!canonicalProto) {
1532
0
    return false;
1533
0
  }
1534
0
  JS::Rooted<JSObject*> proto(aCx);
1535
0
  if (aGivenProto) {
1536
0
    proto = aGivenProto;
1537
0
    // Unfortunately, while aGivenProto was in the compartment of aCx
1538
0
    // coming in, we changed compartments to that of "parent" so may need
1539
0
    // to wrap the proto here.
1540
0
    if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
1541
0
      if (!JS_WrapObject(aCx, &proto)) {
1542
0
        return false;
1543
0
      }
1544
0
    }
1545
0
  } else {
1546
0
    proto = canonicalProto;
1547
0
  }
1548
0
1549
0
  BindingJSObjectCreator<mozilla::dom::IterableIterator<mozilla::dom::ipc::SharedMap>> creator(aCx);
1550
0
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
1551
0
  if (!aReflector) {
1552
0
    return false;
1553
0
  }
1554
0
1555
0
1556
0
1557
0
  creator.InitializationSucceeded();
1558
0
  return true;
1559
0
}
1560
1561
const NativePropertyHooks sNativePropertyHooks[] = { {
1562
  nullptr,
1563
  nullptr,
1564
  nullptr,
1565
  { sNativeProperties.Upcast(), nullptr },
1566
  prototypes::id::MozSharedMapIterator,
1567
  constructors::id::_ID_Count,
1568
  nullptr,
1569
  &DefaultXrayExpandoObjectClass
1570
} };
1571
1572
void
1573
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
1574
0
{
1575
0
  JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmIteratorPrototype(aCx));
1576
0
  if (!parentProto) {
1577
0
    return;
1578
0
  }
1579
0
1580
0
  static bool sIdsInited = false;
1581
0
  if (!sIdsInited && NS_IsMainThread()) {
1582
0
    if (!InitIds(aCx, sNativeProperties.Upcast())) {
1583
0
      return;
1584
0
    }
1585
0
    sIdsInited = true;
1586
0
  }
1587
0
1588
0
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::MozSharedMapIterator);
1589
0
  JS::Heap<JSObject*>* interfaceCache = nullptr;
1590
0
  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
1591
0
                              &sPrototypeClass.mBase, protoCache,
1592
0
                              "MozSharedMap Iterator",
1593
0
                              nullptr, nullptr, 0, nullptr,
1594
0
                              interfaceCache,
1595
0
                              sNativeProperties.Upcast(),
1596
0
                              nullptr,
1597
0
                              nullptr, aDefineOnGlobal,
1598
0
                              nullptr,
1599
0
                              false);
1600
0
}
1601
1602
} // namespace MozSharedMapIterator_Binding
1603
1604
1605
1606
namespace MozWritableSharedMap_Binding {
1607
1608
static_assert(IsRefcounted<NativeType>::value == IsRefcounted<MozSharedMap_Binding::NativeType>::value,
1609
              "Can't inherit from an interface with a different ownership model.");
1610
1611
MOZ_CAN_RUN_SCRIPT static bool
1612
set(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::ipc::WritableSharedMap* self, const JSJitMethodCallArgs& args)
1613
0
{
1614
0
  AUTO_PROFILER_LABEL_FAST("MozWritableSharedMap.set", DOM, cx);
1615
0
1616
0
  if (MOZ_UNLIKELY(args.length() < 2)) {
1617
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "MozWritableSharedMap.set");
1618
0
  }
1619
0
  binding_detail::FakeString arg0;
1620
0
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
1621
0
    return false;
1622
0
  }
1623
0
  JS::Rooted<JS::Value> arg1(cx);
1624
0
  arg1 = args[1];
1625
0
  FastErrorResult rv;
1626
0
  self->Set(cx, NonNullHelper(Constify(arg0)), arg1, rv);
1627
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
1628
0
    return false;
1629
0
  }
1630
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
1631
0
  args.rval().setUndefined();
1632
0
  return true;
1633
0
}
1634
1635
static const JSJitInfo set_methodinfo = {
1636
  { (JSJitGetterOp)set },
1637
  { prototypes::id::MozWritableSharedMap },
1638
  { PrototypeTraits<prototypes::id::MozWritableSharedMap>::Depth },
1639
  JSJitInfo::Method,
1640
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
1641
  JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
1642
  false,  /* isInfallible. False in setters. */
1643
  false,  /* isMovable.  Not relevant for setters. */
1644
  false, /* isEliminatable.  Not relevant for setters. */
1645
  false, /* isAlwaysInSlot.  Only relevant for getters. */
1646
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
1647
  false,  /* isTypedMethod.  Only relevant for methods. */
1648
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
1649
};
1650
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1651
static_assert(0 < 1, "There is no slot for us");
1652
1653
MOZ_CAN_RUN_SCRIPT static bool
1654
_delete_(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::ipc::WritableSharedMap* self, const JSJitMethodCallArgs& args)
1655
0
{
1656
0
  AUTO_PROFILER_LABEL_FAST("MozWritableSharedMap.delete", DOM, cx);
1657
0
1658
0
  if (MOZ_UNLIKELY(args.length() < 1)) {
1659
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "MozWritableSharedMap.delete");
1660
0
  }
1661
0
  binding_detail::FakeString arg0;
1662
0
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
1663
0
    return false;
1664
0
  }
1665
0
  self->Delete(NonNullHelper(Constify(arg0)));
1666
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
1667
0
  args.rval().setUndefined();
1668
0
  return true;
1669
0
}
1670
1671
static const JSJitInfo delete_methodinfo = {
1672
  { (JSJitGetterOp)_delete_ },
1673
  { prototypes::id::MozWritableSharedMap },
1674
  { PrototypeTraits<prototypes::id::MozWritableSharedMap>::Depth },
1675
  JSJitInfo::Method,
1676
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
1677
  JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
1678
  false,  /* isInfallible. False in setters. */
1679
  false,  /* isMovable.  Not relevant for setters. */
1680
  false, /* isEliminatable.  Not relevant for setters. */
1681
  false, /* isAlwaysInSlot.  Only relevant for getters. */
1682
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
1683
  false,  /* isTypedMethod.  Only relevant for methods. */
1684
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
1685
};
1686
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1687
static_assert(0 < 1, "There is no slot for us");
1688
1689
MOZ_CAN_RUN_SCRIPT static bool
1690
flush(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::ipc::WritableSharedMap* self, const JSJitMethodCallArgs& args)
1691
0
{
1692
0
  AUTO_PROFILER_LABEL_FAST("MozWritableSharedMap.flush", DOM, cx);
1693
0
1694
0
  self->Flush();
1695
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
1696
0
  args.rval().setUndefined();
1697
0
  return true;
1698
0
}
1699
1700
static const JSJitInfo flush_methodinfo = {
1701
  { (JSJitGetterOp)flush },
1702
  { prototypes::id::MozWritableSharedMap },
1703
  { PrototypeTraits<prototypes::id::MozWritableSharedMap>::Depth },
1704
  JSJitInfo::Method,
1705
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
1706
  JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
1707
  true,  /* isInfallible. False in setters. */
1708
  false,  /* isMovable.  Not relevant for setters. */
1709
  false, /* isEliminatable.  Not relevant for setters. */
1710
  false, /* isAlwaysInSlot.  Only relevant for getters. */
1711
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
1712
  false,  /* isTypedMethod.  Only relevant for methods. */
1713
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
1714
};
1715
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
1716
static_assert(0 < 1, "There is no slot for us");
1717
1718
static bool
1719
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
1720
0
{
1721
0
  mozilla::dom::ipc::WritableSharedMap* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::ipc::WritableSharedMap>(obj);
1722
0
  // We don't want to preserve if we don't have a wrapper, and we
1723
0
  // obviously can't preserve if we're not initialized.
1724
0
  if (self && self->GetWrapperPreserveColor()) {
1725
0
    PreserveWrapper(self);
1726
0
  }
1727
0
  return true;
1728
0
}
1729
1730
static void
1731
_finalize(js::FreeOp* fop, JSObject* obj)
1732
0
{
1733
0
  mozilla::dom::ipc::WritableSharedMap* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::ipc::WritableSharedMap>(obj);
1734
0
  if (self) {
1735
0
    ClearWrapper(self, self, obj);
1736
0
    AddForDeferredFinalization<mozilla::dom::ipc::WritableSharedMap>(self);
1737
0
  }
1738
0
}
1739
1740
static size_t
1741
_objectMoved(JSObject* obj, JSObject* old)
1742
0
{
1743
0
  mozilla::dom::ipc::WritableSharedMap* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::ipc::WritableSharedMap>(obj);
1744
0
  if (self) {
1745
0
    UpdateWrapper(self, self, obj, old);
1746
0
  }
1747
0
1748
0
  return 0;
1749
0
}
1750
1751
// We deliberately use brace-elision to make Visual Studio produce better initalization code.
1752
#if defined(__clang__)
1753
#pragma clang diagnostic push
1754
#pragma clang diagnostic ignored "-Wmissing-braces"
1755
#endif
1756
static const JSFunctionSpec sMethods_specs[] = {
1757
  JS_FNSPEC("set", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&set_methodinfo), 2, JSPROP_ENUMERATE, nullptr),
1758
  JS_FNSPEC("delete", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&delete_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
1759
  JS_FNSPEC("flush", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&flush_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
1760
  JS_FS_END
1761
};
1762
#if defined(__clang__)
1763
#pragma clang diagnostic pop
1764
#endif
1765
1766
1767
static const Prefable<const JSFunctionSpec> sMethods[] = {
1768
  { nullptr, &sMethods_specs[0] },
1769
  { nullptr, nullptr }
1770
};
1771
1772
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
1773
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
1774
static_assert(3 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
1775
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
1776
1777
1778
static uint16_t sNativeProperties_sortedPropertyIndices[3];
1779
static PropertyInfo sNativeProperties_propertyInfos[3];
1780
1781
static const NativePropertiesN<1> sNativeProperties = {
1782
  false, 0,
1783
  false, 0,
1784
  true,  0 /* sMethods */,
1785
  false, 0,
1786
  false, 0,
1787
  false, 0,
1788
  false, 0,
1789
  -1,
1790
  3,
1791
  sNativeProperties_sortedPropertyIndices,
1792
  {
1793
    { sMethods, &sNativeProperties_propertyInfos[0] }
1794
  }
1795
};
1796
static_assert(3 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
1797
    "We have a property info count that is oversized");
1798
1799
static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
1800
  {
1801
    "Function",
1802
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
1803
    &sBoringInterfaceObjectClassClassOps,
1804
    JS_NULL_CLASS_SPEC,
1805
    JS_NULL_CLASS_EXT,
1806
    &sInterfaceObjectClassObjectOps
1807
  },
1808
  eInterface,
1809
  true,
1810
  prototypes::id::MozWritableSharedMap,
1811
  PrototypeTraits<prototypes::id::MozWritableSharedMap>::Depth,
1812
  sNativePropertyHooks,
1813
  "function MozWritableSharedMap() {\n    [native code]\n}",
1814
  MozSharedMap_Binding::GetConstructorObject
1815
};
1816
1817
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
1818
  {
1819
    "MozWritableSharedMapPrototype",
1820
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
1821
    JS_NULL_CLASS_OPS,
1822
    JS_NULL_CLASS_SPEC,
1823
    JS_NULL_CLASS_EXT,
1824
    JS_NULL_OBJECT_OPS
1825
  },
1826
  eInterfacePrototype,
1827
  false,
1828
  prototypes::id::MozWritableSharedMap,
1829
  PrototypeTraits<prototypes::id::MozWritableSharedMap>::Depth,
1830
  sNativePropertyHooks,
1831
  "[object MozWritableSharedMapPrototype]",
1832
  MozSharedMap_Binding::GetProtoObject
1833
};
1834
1835
bool
1836
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
1837
0
{
1838
0
  return nsContentUtils::ThreadsafeIsSystemCaller(aCx);
1839
0
}
1840
1841
static const js::ClassOps sClassOps = {
1842
  _addProperty, /* addProperty */
1843
  nullptr,               /* delProperty */
1844
  nullptr,               /* enumerate */
1845
  nullptr, /* newEnumerate */
1846
  nullptr, /* resolve */
1847
  nullptr, /* mayResolve */
1848
  _finalize, /* finalize */
1849
  nullptr, /* call */
1850
  nullptr,               /* hasInstance */
1851
  nullptr,               /* construct */
1852
  nullptr, /* trace */
1853
};
1854
1855
static const js::ClassExtension sClassExtension = {
1856
  nullptr, /* weakmapKeyDelegateOp */
1857
  _objectMoved /* objectMovedOp */
1858
};
1859
1860
static const DOMJSClass sClass = {
1861
  { "MozWritableSharedMap",
1862
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
1863
    &sClassOps,
1864
    JS_NULL_CLASS_SPEC,
1865
    &sClassExtension,
1866
    JS_NULL_OBJECT_OPS
1867
  },
1868
  { prototypes::id::EventTarget, prototypes::id::MozSharedMap, prototypes::id::MozWritableSharedMap, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
1869
  IsBaseOf<nsISupports, mozilla::dom::ipc::WritableSharedMap >::value,
1870
  sNativePropertyHooks,
1871
  FindAssociatedGlobalForNative<mozilla::dom::ipc::WritableSharedMap>::Get,
1872
  GetProtoObjectHandle,
1873
  GetCCParticipant<mozilla::dom::ipc::WritableSharedMap>::Get()
1874
};
1875
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
1876
              "Must have the right minimal number of reserved slots.");
1877
static_assert(1 >= 1,
1878
              "Must have enough reserved slots.");
1879
1880
const JSClass*
1881
GetJSClass()
1882
0
{
1883
0
  return sClass.ToJSClass();
1884
0
}
1885
1886
bool
1887
Wrap(JSContext* aCx, mozilla::dom::ipc::WritableSharedMap* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
1888
0
{
1889
0
  static_assert(!IsBaseOf<NonRefcountedDOMObject, mozilla::dom::ipc::WritableSharedMap>::value,
1890
0
                "Shouldn't have wrappercached things that are not refcounted.");
1891
0
  MOZ_ASSERT(static_cast<mozilla::dom::ipc::WritableSharedMap*>(aObject) ==
1892
0
             reinterpret_cast<mozilla::dom::ipc::WritableSharedMap*>(aObject),
1893
0
             "Multiple inheritance for mozilla::dom::ipc::WritableSharedMap is broken.");
1894
0
  MOZ_ASSERT(static_cast<mozilla::dom::ipc::SharedMap*>(aObject) ==
1895
0
             reinterpret_cast<mozilla::dom::ipc::SharedMap*>(aObject),
1896
0
             "Multiple inheritance for mozilla::dom::ipc::SharedMap is broken.");
1897
0
  MOZ_ASSERT(static_cast<mozilla::dom::EventTarget*>(aObject) ==
1898
0
             reinterpret_cast<mozilla::dom::EventTarget*>(aObject),
1899
0
             "Multiple inheritance for mozilla::dom::EventTarget is broken.");
1900
0
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
1901
0
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
1902
0
  MOZ_ASSERT(!aCache->GetWrapper(),
1903
0
             "You should probably not be using Wrap() directly; use "
1904
0
             "GetOrCreateDOMReflector instead");
1905
0
1906
0
  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
1907
0
             "nsISupports must be on our primary inheritance chain");
1908
0
1909
0
  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
1910
0
  if (!global) {
1911
0
    return false;
1912
0
  }
1913
0
  MOZ_ASSERT(JS_IsGlobalObject(global));
1914
0
  MOZ_ASSERT(JS::ObjectIsNotGray(global));
1915
0
1916
0
  // That might have ended up wrapping us already, due to the wonders
1917
0
  // of XBL.  Check for that, and bail out as needed.
1918
0
  aReflector.set(aCache->GetWrapper());
1919
0
  if (aReflector) {
1920
#ifdef DEBUG
1921
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
1922
#endif // DEBUG
1923
    return true;
1924
0
  }
1925
0
1926
0
  JSAutoRealm ar(aCx, global);
1927
0
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
1928
0
  if (!canonicalProto) {
1929
0
    return false;
1930
0
  }
1931
0
  JS::Rooted<JSObject*> proto(aCx);
1932
0
  if (aGivenProto) {
1933
0
    proto = aGivenProto;
1934
0
    // Unfortunately, while aGivenProto was in the compartment of aCx
1935
0
    // coming in, we changed compartments to that of "parent" so may need
1936
0
    // to wrap the proto here.
1937
0
    if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
1938
0
      if (!JS_WrapObject(aCx, &proto)) {
1939
0
        return false;
1940
0
      }
1941
0
    }
1942
0
  } else {
1943
0
    proto = canonicalProto;
1944
0
  }
1945
0
1946
0
  BindingJSObjectCreator<mozilla::dom::ipc::WritableSharedMap> creator(aCx);
1947
0
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
1948
0
  if (!aReflector) {
1949
0
    return false;
1950
0
  }
1951
0
1952
0
  aCache->SetWrapper(aReflector);
1953
0
  creator.InitializationSucceeded();
1954
0
1955
0
  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
1956
0
             aCache->GetWrapperPreserveColor() == aReflector);
1957
0
  // If proto != canonicalProto, we have to preserve our wrapper;
1958
0
  // otherwise we won't be able to properly recreate it later, since
1959
0
  // we won't know what proto to use.  Note that we don't check
1960
0
  // aGivenProto here, since it's entirely possible (and even
1961
0
  // somewhat common) to have a non-null aGivenProto which is the
1962
0
  // same as canonicalProto.
1963
0
  if (proto != canonicalProto) {
1964
0
    PreserveWrapper(aObject);
1965
0
  }
1966
0
1967
0
  return true;
1968
0
}
1969
1970
const NativePropertyHooks sNativePropertyHooks[] = { {
1971
  nullptr,
1972
  nullptr,
1973
  nullptr,
1974
  { sNativeProperties.Upcast(), nullptr },
1975
  prototypes::id::MozWritableSharedMap,
1976
  constructors::id::MozWritableSharedMap,
1977
  MozSharedMap_Binding::sNativePropertyHooks,
1978
  &DefaultXrayExpandoObjectClass
1979
} };
1980
1981
void
1982
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
1983
0
{
1984
0
  JS::Handle<JSObject*> parentProto(MozSharedMap_Binding::GetProtoObjectHandle(aCx));
1985
0
  if (!parentProto) {
1986
0
    return;
1987
0
  }
1988
0
1989
0
  JS::Handle<JSObject*> constructorProto(MozSharedMap_Binding::GetConstructorObjectHandle(aCx));
1990
0
  if (!constructorProto) {
1991
0
    return;
1992
0
  }
1993
0
1994
0
  static bool sIdsInited = false;
1995
0
  if (!sIdsInited && NS_IsMainThread()) {
1996
0
    if (!InitIds(aCx, sNativeProperties.Upcast())) {
1997
0
      return;
1998
0
    }
1999
0
    sIdsInited = true;
2000
0
  }
2001
0
2002
0
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::MozWritableSharedMap);
2003
0
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::MozWritableSharedMap);
2004
0
  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
2005
0
                              &sPrototypeClass.mBase, protoCache,
2006
0
                              nullptr,
2007
0
                              constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
2008
0
                              interfaceCache,
2009
0
                              sNativeProperties.Upcast(),
2010
0
                              nullptr,
2011
0
                              "MozWritableSharedMap", aDefineOnGlobal,
2012
0
                              nullptr,
2013
0
                              false);
2014
0
}
2015
2016
JSObject*
2017
GetConstructorObject(JSContext* aCx)
2018
0
{
2019
0
  return GetConstructorObjectHandle(aCx);
2020
0
}
2021
2022
} // namespace MozWritableSharedMap_Binding
2023
2024
2025
2026
} // namespace dom
2027
} // namespace mozilla