Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dom/bindings/StorageBinding.cpp
Line
Count
Source (jump to first uncovered line)
1
/* THIS FILE IS AUTOGENERATED FROM Storage.webidl BY Codegen.py - DO NOT EDIT */
2
3
#include "StorageBinding.h"
4
#include "WrapperFactory.h"
5
#include "mozilla/OwningNonNull.h"
6
#include "mozilla/dom/BindingUtils.h"
7
#include "mozilla/dom/DOMJSClass.h"
8
#include "mozilla/dom/DOMJSProxyHandler.h"
9
#include "mozilla/dom/NonRefcountedDOMObject.h"
10
#include "mozilla/dom/Nullable.h"
11
#include "mozilla/dom/PrimitiveConversions.h"
12
#include "mozilla/dom/Storage.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 Storage_Binding {
24
25
MOZ_CAN_RUN_SCRIPT static bool
26
get_length(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Storage* self, JSJitGetterCallArgs args)
27
0
{
28
0
  AUTO_PROFILER_LABEL_FAST("get Storage.length", DOM, cx);
29
0
30
0
  FastErrorResult rv;
31
0
  NonNull<nsIPrincipal> subjectPrincipal;
32
0
  {
33
0
    JS::Realm* realm = js::GetContextRealm(cx);
34
0
    MOZ_ASSERT(realm);
35
0
    JSPrincipals* principals = JS::GetRealmPrincipals(realm);
36
0
    nsIPrincipal* principal = nsJSPrincipals::get(principals);
37
0
38
0
    subjectPrincipal = principal;
39
0
  }
40
0
  uint32_t result(self->GetLength(subjectPrincipal, rv));
41
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
42
0
    return false;
43
0
  }
44
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
45
0
  args.rval().setNumber(result);
46
0
  return true;
47
0
}
48
49
static const JSJitInfo length_getterinfo = {
50
  { (JSJitGetterOp)get_length },
51
  { prototypes::id::Storage },
52
  { PrototypeTraits<prototypes::id::Storage>::Depth },
53
  JSJitInfo::Getter,
54
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
55
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
56
  false,  /* isInfallible. False in setters. */
57
  false,  /* isMovable.  Not relevant for setters. */
58
  false, /* isEliminatable.  Not relevant for setters. */
59
  false, /* isAlwaysInSlot.  Only relevant for getters. */
60
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
61
  false,  /* isTypedMethod.  Only relevant for methods. */
62
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
63
};
64
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
65
static_assert(0 < 1, "There is no slot for us");
66
67
MOZ_CAN_RUN_SCRIPT static bool
68
key(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Storage* self, const JSJitMethodCallArgs& args)
69
0
{
70
0
  AUTO_PROFILER_LABEL_FAST("Storage.key", DOM, cx);
71
0
72
0
  if (MOZ_UNLIKELY(args.length() < 1)) {
73
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "Storage.key");
74
0
  }
75
0
  uint32_t arg0;
76
0
  if (!ValueToPrimitive<uint32_t, eDefault>(cx, args[0], &arg0)) {
77
0
    return false;
78
0
  }
79
0
  FastErrorResult rv;
80
0
  NonNull<nsIPrincipal> subjectPrincipal;
81
0
  {
82
0
    JS::Realm* realm = js::GetContextRealm(cx);
83
0
    MOZ_ASSERT(realm);
84
0
    JSPrincipals* principals = JS::GetRealmPrincipals(realm);
85
0
    nsIPrincipal* principal = nsJSPrincipals::get(principals);
86
0
87
0
    subjectPrincipal = principal;
88
0
  }
89
0
  DOMString result;
90
0
  self->Key(arg0, result, subjectPrincipal, rv);
91
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
92
0
    return false;
93
0
  }
94
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
95
0
  if (!xpc::StringToJsval(cx, result, args.rval())) {
96
0
    return false;
97
0
  }
98
0
  return true;
99
0
}
100
101
static const JSJitInfo key_methodinfo = {
102
  { (JSJitGetterOp)key },
103
  { prototypes::id::Storage },
104
  { PrototypeTraits<prototypes::id::Storage>::Depth },
105
  JSJitInfo::Method,
106
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
107
  JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
108
  false,  /* isInfallible. False in setters. */
109
  false,  /* isMovable.  Not relevant for setters. */
110
  false, /* isEliminatable.  Not relevant for setters. */
111
  false, /* isAlwaysInSlot.  Only relevant for getters. */
112
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
113
  false,  /* isTypedMethod.  Only relevant for methods. */
114
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
115
};
116
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
117
static_assert(0 < 1, "There is no slot for us");
118
119
MOZ_CAN_RUN_SCRIPT static bool
120
getItem(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Storage* self, const JSJitMethodCallArgs& args)
121
0
{
122
0
  AUTO_PROFILER_LABEL_FAST("Storage.getItem", DOM, cx);
123
0
124
0
  if (MOZ_UNLIKELY(args.length() < 1)) {
125
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "Storage.getItem");
126
0
  }
127
0
  binding_detail::FakeString arg0;
128
0
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
129
0
    return false;
130
0
  }
131
0
  FastErrorResult rv;
132
0
  NonNull<nsIPrincipal> subjectPrincipal;
133
0
  {
134
0
    JS::Realm* realm = js::GetContextRealm(cx);
135
0
    MOZ_ASSERT(realm);
136
0
    JSPrincipals* principals = JS::GetRealmPrincipals(realm);
137
0
    nsIPrincipal* principal = nsJSPrincipals::get(principals);
138
0
139
0
    subjectPrincipal = principal;
140
0
  }
141
0
  DOMString result;
142
0
  self->GetItem(NonNullHelper(Constify(arg0)), result, subjectPrincipal, rv);
143
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
144
0
    return false;
145
0
  }
146
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
147
0
  if (!xpc::StringToJsval(cx, result, args.rval())) {
148
0
    return false;
149
0
  }
150
0
  return true;
151
0
}
152
153
static const JSJitInfo getItem_methodinfo = {
154
  { (JSJitGetterOp)getItem },
155
  { prototypes::id::Storage },
156
  { PrototypeTraits<prototypes::id::Storage>::Depth },
157
  JSJitInfo::Method,
158
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
159
  JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
160
  false,  /* isInfallible. False in setters. */
161
  false,  /* isMovable.  Not relevant for setters. */
162
  false, /* isEliminatable.  Not relevant for setters. */
163
  false, /* isAlwaysInSlot.  Only relevant for getters. */
164
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
165
  false,  /* isTypedMethod.  Only relevant for methods. */
166
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
167
};
168
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
169
static_assert(0 < 1, "There is no slot for us");
170
171
MOZ_CAN_RUN_SCRIPT static bool
172
setItem(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Storage* self, const JSJitMethodCallArgs& args)
173
0
{
174
0
  AUTO_PROFILER_LABEL_FAST("Storage.setItem", DOM, cx);
175
0
176
0
  if (MOZ_UNLIKELY(args.length() < 2)) {
177
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "Storage.setItem");
178
0
  }
179
0
  binding_detail::FakeString arg0;
180
0
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
181
0
    return false;
182
0
  }
183
0
  binding_detail::FakeString arg1;
184
0
  if (!ConvertJSValueToString(cx, args[1], eStringify, eStringify, arg1)) {
185
0
    return false;
186
0
  }
187
0
  FastErrorResult rv;
188
0
  NonNull<nsIPrincipal> subjectPrincipal;
189
0
  {
190
0
    JS::Realm* realm = js::GetContextRealm(cx);
191
0
    MOZ_ASSERT(realm);
192
0
    JSPrincipals* principals = JS::GetRealmPrincipals(realm);
193
0
    nsIPrincipal* principal = nsJSPrincipals::get(principals);
194
0
195
0
    subjectPrincipal = principal;
196
0
  }
197
0
  self->SetItem(NonNullHelper(Constify(arg0)), NonNullHelper(Constify(arg1)), subjectPrincipal, rv);
198
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
199
0
    return false;
200
0
  }
201
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
202
0
  args.rval().setUndefined();
203
0
  return true;
204
0
}
205
206
static const JSJitInfo setItem_methodinfo = {
207
  { (JSJitGetterOp)setItem },
208
  { prototypes::id::Storage },
209
  { PrototypeTraits<prototypes::id::Storage>::Depth },
210
  JSJitInfo::Method,
211
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
212
  JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
213
  false,  /* isInfallible. False in setters. */
214
  false,  /* isMovable.  Not relevant for setters. */
215
  false, /* isEliminatable.  Not relevant for setters. */
216
  false, /* isAlwaysInSlot.  Only relevant for getters. */
217
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
218
  false,  /* isTypedMethod.  Only relevant for methods. */
219
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
220
};
221
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
222
static_assert(0 < 1, "There is no slot for us");
223
224
MOZ_CAN_RUN_SCRIPT static bool
225
removeItem(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Storage* self, const JSJitMethodCallArgs& args)
226
0
{
227
0
  AUTO_PROFILER_LABEL_FAST("Storage.removeItem", DOM, cx);
228
0
229
0
  if (MOZ_UNLIKELY(args.length() < 1)) {
230
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "Storage.removeItem");
231
0
  }
232
0
  binding_detail::FakeString arg0;
233
0
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
234
0
    return false;
235
0
  }
236
0
  FastErrorResult rv;
237
0
  NonNull<nsIPrincipal> subjectPrincipal;
238
0
  {
239
0
    JS::Realm* realm = js::GetContextRealm(cx);
240
0
    MOZ_ASSERT(realm);
241
0
    JSPrincipals* principals = JS::GetRealmPrincipals(realm);
242
0
    nsIPrincipal* principal = nsJSPrincipals::get(principals);
243
0
244
0
    subjectPrincipal = principal;
245
0
  }
246
0
  self->RemoveItem(NonNullHelper(Constify(arg0)), subjectPrincipal, rv);
247
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
248
0
    return false;
249
0
  }
250
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
251
0
  args.rval().setUndefined();
252
0
  return true;
253
0
}
254
255
static const JSJitInfo removeItem_methodinfo = {
256
  { (JSJitGetterOp)removeItem },
257
  { prototypes::id::Storage },
258
  { PrototypeTraits<prototypes::id::Storage>::Depth },
259
  JSJitInfo::Method,
260
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
261
  JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
262
  false,  /* isInfallible. False in setters. */
263
  false,  /* isMovable.  Not relevant for setters. */
264
  false, /* isEliminatable.  Not relevant for setters. */
265
  false, /* isAlwaysInSlot.  Only relevant for getters. */
266
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
267
  false,  /* isTypedMethod.  Only relevant for methods. */
268
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
269
};
270
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
271
static_assert(0 < 1, "There is no slot for us");
272
273
MOZ_CAN_RUN_SCRIPT static bool
274
clear(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Storage* self, const JSJitMethodCallArgs& args)
275
0
{
276
0
  AUTO_PROFILER_LABEL_FAST("Storage.clear", DOM, cx);
277
0
278
0
  FastErrorResult rv;
279
0
  NonNull<nsIPrincipal> subjectPrincipal;
280
0
  {
281
0
    JS::Realm* realm = js::GetContextRealm(cx);
282
0
    MOZ_ASSERT(realm);
283
0
    JSPrincipals* principals = JS::GetRealmPrincipals(realm);
284
0
    nsIPrincipal* principal = nsJSPrincipals::get(principals);
285
0
286
0
    subjectPrincipal = principal;
287
0
  }
288
0
  self->Clear(subjectPrincipal, rv);
289
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
290
0
    return false;
291
0
  }
292
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
293
0
  args.rval().setUndefined();
294
0
  return true;
295
0
}
296
297
static const JSJitInfo clear_methodinfo = {
298
  { (JSJitGetterOp)clear },
299
  { prototypes::id::Storage },
300
  { PrototypeTraits<prototypes::id::Storage>::Depth },
301
  JSJitInfo::Method,
302
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
303
  JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
304
  false,  /* isInfallible. False in setters. */
305
  false,  /* isMovable.  Not relevant for setters. */
306
  false, /* isEliminatable.  Not relevant for setters. */
307
  false, /* isAlwaysInSlot.  Only relevant for getters. */
308
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
309
  false,  /* isTypedMethod.  Only relevant for methods. */
310
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
311
};
312
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
313
static_assert(0 < 1, "There is no slot for us");
314
315
MOZ_CAN_RUN_SCRIPT static bool
316
get_isSessionOnly(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Storage* self, JSJitGetterCallArgs args)
317
0
{
318
0
  AUTO_PROFILER_LABEL_FAST("get Storage.isSessionOnly", DOM, cx);
319
0
320
0
  bool result(self->IsSessionOnly());
321
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
322
0
  args.rval().setBoolean(result);
323
0
  return true;
324
0
}
325
326
static const JSJitInfo isSessionOnly_getterinfo = {
327
  { (JSJitGetterOp)get_isSessionOnly },
328
  { prototypes::id::Storage },
329
  { PrototypeTraits<prototypes::id::Storage>::Depth },
330
  JSJitInfo::Getter,
331
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
332
  JSVAL_TYPE_BOOLEAN,  /* returnType.  Not relevant for setters. */
333
  true,  /* isInfallible. False in setters. */
334
  false,  /* isMovable.  Not relevant for setters. */
335
  false, /* isEliminatable.  Not relevant for setters. */
336
  false, /* isAlwaysInSlot.  Only relevant for getters. */
337
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
338
  false,  /* isTypedMethod.  Only relevant for methods. */
339
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
340
};
341
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
342
static_assert(0 < 1, "There is no slot for us");
343
344
// We deliberately use brace-elision to make Visual Studio produce better initalization code.
345
#if defined(__clang__)
346
#pragma clang diagnostic push
347
#pragma clang diagnostic ignored "-Wmissing-braces"
348
#endif
349
static const JSFunctionSpec sMethods_specs[] = {
350
  JS_FNSPEC("key", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&key_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
351
  JS_FNSPEC("getItem", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&getItem_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
352
  JS_FNSPEC("setItem", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&setItem_methodinfo), 2, JSPROP_ENUMERATE, nullptr),
353
  JS_FNSPEC("removeItem", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&removeItem_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
354
  JS_FNSPEC("clear", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&clear_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
355
  JS_FS_END
356
};
357
#if defined(__clang__)
358
#pragma clang diagnostic pop
359
#endif
360
361
362
static const Prefable<const JSFunctionSpec> sMethods[] = {
363
  { nullptr, &sMethods_specs[0] },
364
  { nullptr, nullptr }
365
};
366
367
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
368
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
369
static_assert(5 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
370
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
371
372
// We deliberately use brace-elision to make Visual Studio produce better initalization code.
373
#if defined(__clang__)
374
#pragma clang diagnostic push
375
#pragma clang diagnostic ignored "-Wmissing-braces"
376
#endif
377
static const JSPropertySpec sAttributes_specs[] = {
378
  { "length", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &length_getterinfo, nullptr, nullptr },
379
  { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
380
};
381
#if defined(__clang__)
382
#pragma clang diagnostic pop
383
#endif
384
385
386
static const Prefable<const JSPropertySpec> sAttributes[] = {
387
  { nullptr, &sAttributes_specs[0] },
388
  { nullptr, nullptr }
389
};
390
391
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
392
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
393
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
394
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
395
396
// We deliberately use brace-elision to make Visual Studio produce better initalization code.
397
#if defined(__clang__)
398
#pragma clang diagnostic push
399
#pragma clang diagnostic ignored "-Wmissing-braces"
400
#endif
401
static const JSPropertySpec sChromeAttributes_specs[] = {
402
  { "isSessionOnly", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &isSessionOnly_getterinfo, nullptr, nullptr },
403
  { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
404
};
405
#if defined(__clang__)
406
#pragma clang diagnostic pop
407
#endif
408
409
410
static const Prefable<const JSPropertySpec> sChromeAttributes[] = {
411
  { nullptr, &sChromeAttributes_specs[0] },
412
  { nullptr, nullptr }
413
};
414
415
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
416
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
417
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
418
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
419
420
421
static uint16_t sNativeProperties_sortedPropertyIndices[6];
422
static PropertyInfo sNativeProperties_propertyInfos[6];
423
424
static const NativePropertiesN<2> sNativeProperties = {
425
  false, 0,
426
  false, 0,
427
  true,  0 /* sMethods */,
428
  true,  1 /* sAttributes */,
429
  false, 0,
430
  false, 0,
431
  false, 0,
432
  -1,
433
  6,
434
  sNativeProperties_sortedPropertyIndices,
435
  {
436
    { sMethods, &sNativeProperties_propertyInfos[0] },
437
    { sAttributes, &sNativeProperties_propertyInfos[5] }
438
  }
439
};
440
static_assert(6 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
441
    "We have a property info count that is oversized");
442
443
static uint16_t sChromeOnlyNativeProperties_sortedPropertyIndices[1];
444
static PropertyInfo sChromeOnlyNativeProperties_propertyInfos[1];
445
446
static const NativePropertiesN<1> sChromeOnlyNativeProperties = {
447
  false, 0,
448
  false, 0,
449
  false, 0,
450
  true,  0 /* sChromeAttributes */,
451
  false, 0,
452
  false, 0,
453
  false, 0,
454
  -1,
455
  1,
456
  sChromeOnlyNativeProperties_sortedPropertyIndices,
457
  {
458
    { sChromeAttributes, &sChromeOnlyNativeProperties_propertyInfos[0] }
459
  }
460
};
461
static_assert(1 < 1ull << CHAR_BIT * sizeof(sChromeOnlyNativeProperties.propertyInfoCount),
462
    "We have a property info count that is oversized");
463
464
static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
465
  {
466
    "Function",
467
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
468
    &sBoringInterfaceObjectClassClassOps,
469
    JS_NULL_CLASS_SPEC,
470
    JS_NULL_CLASS_EXT,
471
    &sInterfaceObjectClassObjectOps
472
  },
473
  eInterface,
474
  true,
475
  prototypes::id::Storage,
476
  PrototypeTraits<prototypes::id::Storage>::Depth,
477
  sNativePropertyHooks,
478
  "function Storage() {\n    [native code]\n}",
479
  JS::GetRealmFunctionPrototype
480
};
481
482
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
483
  {
484
    "StoragePrototype",
485
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
486
    JS_NULL_CLASS_OPS,
487
    JS_NULL_CLASS_SPEC,
488
    JS_NULL_CLASS_EXT,
489
    JS_NULL_OBJECT_OPS
490
  },
491
  eInterfacePrototype,
492
  false,
493
  prototypes::id::Storage,
494
  PrototypeTraits<prototypes::id::Storage>::Depth,
495
  sNativePropertyHooks,
496
  "[object StoragePrototype]",
497
  JS::GetRealmObjectPrototype
498
};
499
500
static_assert(IsBaseOf<nsISupports, mozilla::dom::Storage >::value,
501
                  "We don't support non-nsISupports native classes for "
502
                  "proxy-based bindings yet");
503
504
505
class DOMProxyHandler : public mozilla::dom::DOMProxyHandler
506
{
507
public:
508
  explicit constexpr DOMProxyHandler()
509
0
  {
510
0
  }
511
512
  virtual bool
513
  getOwnPropDescriptor(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool ignoreNamedProps, JS::MutableHandle<JS::PropertyDescriptor> desc) const override;
514
515
  virtual bool
516
  defineProperty(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, JS::Handle<JS::PropertyDescriptor> desc, JS::ObjectOpResult& opresult, bool* defined) const override;
517
518
  using mozilla::dom::DOMProxyHandler::defineProperty;
519
520
  virtual bool
521
  ownPropNames(JSContext* cx, JS::Handle<JSObject*> proxy, unsigned flags, JS::AutoIdVector& props) const override;
522
523
  virtual bool
524
  hasOwn(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool* bp) const override;
525
526
  virtual bool
527
  get(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<JS::Value> receiver, JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp) const override;
528
529
  virtual const char*
530
  className(JSContext* cx, JS::Handle<JSObject*> proxy) const override;
531
532
  virtual bool
533
  finalizeInBackground(const JS::Value& priv) const override;
534
535
  virtual void
536
  finalize(JSFreeOp* fop, JSObject* proxy) const override;
537
538
  static const DOMProxyHandler*
539
  getInstance();
540
541
  virtual bool
542
  delete_(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, JS::ObjectOpResult& opresult) const override;
543
544
  virtual size_t
545
  objectMoved(JSObject* obj, JSObject* old) const override;
546
};
547
548
MOZ_ALWAYS_INLINE bool
549
IsProxy(JSObject* obj)
550
0
{
551
0
  return js::IsProxy(obj) && js::GetProxyHandler(obj) == DOMProxyHandler::getInstance();
552
0
}
553
554
MOZ_ALWAYS_INLINE mozilla::dom::Storage*
555
UnwrapProxy(JSObject* obj)
556
0
{
557
0
  MOZ_ASSERT(js::IsProxy(obj));
558
0
  if (js::GetProxyHandler(obj) != DOMProxyHandler::getInstance()) {
559
0
    MOZ_ASSERT(xpc::WrapperFactory::IsXrayWrapper(obj));
560
0
    obj = js::UncheckedUnwrap(obj);
561
0
  }
562
0
  MOZ_ASSERT(IsProxy(obj));
563
0
  return static_cast<mozilla::dom::Storage*>(js::GetProxyReservedSlot(obj, DOM_OBJECT_SLOT).toPrivate());
564
0
}
565
566
bool
567
DOMProxyHandler::getOwnPropDescriptor(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool ignoreNamedProps, JS::MutableHandle<JS::PropertyDescriptor> desc) const
568
0
{
569
0
  bool isXray = xpc::WrapperFactory::IsXrayWrapper(proxy);
570
0
  JS::Rooted<JSObject*> expando(cx);
571
0
  if (!isXray && (expando = GetExpandoObject(proxy))) {
572
0
    if (!JS_GetOwnPropertyDescriptorById(cx, expando, id, desc)) {
573
0
      return false;
574
0
    }
575
0
    if (desc.object()) {
576
0
      // Pretend the property lives on the wrapper.
577
0
      desc.object().set(proxy);
578
0
      return true;
579
0
    }
580
0
  }
581
0
582
0
  bool callNamedGetter = false;
583
0
  if (!ignoreNamedProps) {
584
0
    bool hasOnProto;
585
0
    if (!HasPropertyOnPrototype(cx, proxy, id, &hasOnProto)) {
586
0
      return false;
587
0
    }
588
0
    callNamedGetter = !hasOnProto;
589
0
  }
590
0
  if (callNamedGetter) {
591
0
    FakeString key;
592
0
    bool isSymbol;
593
0
    if (!ConvertIdToString(cx, id, key, isSymbol)) {
594
0
      return false;
595
0
    }
596
0
    if (!isSymbol) {
597
0
      mozilla::dom::Storage* self = UnwrapProxy(proxy);
598
0
      bool found = false;
599
0
      FastErrorResult rv;
600
0
      NonNull<nsIPrincipal> subjectPrincipal;
601
0
      {
602
0
        JS::Realm* realm = js::GetContextRealm(cx);
603
0
        MOZ_ASSERT(realm);
604
0
        JSPrincipals* principals = JS::GetRealmPrincipals(realm);
605
0
        nsIPrincipal* principal = nsJSPrincipals::get(principals);
606
0
607
0
        subjectPrincipal = principal;
608
0
      }
609
0
      DOMString result;
610
0
      self->NamedGetter(NonNullHelper(Constify(key)), found, result, subjectPrincipal, rv);
611
0
      if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
612
0
        return false;
613
0
      }
614
0
      MOZ_ASSERT(!JS_IsExceptionPending(cx));
615
0
616
0
      if (found) {
617
0
        if (!xpc::StringToJsval(cx, result, desc.value())) {
618
0
          return false;
619
0
        }
620
0
        FillPropertyDescriptor(desc, proxy, false, true);
621
0
        return true;
622
0
      }
623
0
    }
624
0
  }
625
0
626
0
  desc.object().set(nullptr);
627
0
  return true;
628
0
}
629
630
bool
631
DOMProxyHandler::defineProperty(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, JS::Handle<JS::PropertyDescriptor> desc, JS::ObjectOpResult& opresult, bool* defined) const
632
0
{
633
0
  *defined = true;
634
0
  FakeString key;
635
0
  bool isSymbol;
636
0
  if (!ConvertIdToString(cx, id, key, isSymbol)) {
637
0
    return false;
638
0
  }
639
0
  if (!isSymbol) {
640
0
    mozilla::dom::Storage* self = UnwrapProxy(proxy);
641
0
    JS::Rooted<JS::Value> rootedValue(cx, desc.value());
642
0
    binding_detail::FakeString value;
643
0
    if (!ConvertJSValueToString(cx, desc.value(), eStringify, eStringify, value)) {
644
0
      return false;
645
0
    }
646
0
    FastErrorResult rv;
647
0
    NonNull<nsIPrincipal> subjectPrincipal;
648
0
    {
649
0
      JS::Realm* realm = js::GetContextRealm(cx);
650
0
      MOZ_ASSERT(realm);
651
0
      JSPrincipals* principals = JS::GetRealmPrincipals(realm);
652
0
      nsIPrincipal* principal = nsJSPrincipals::get(principals);
653
0
654
0
      subjectPrincipal = principal;
655
0
    }
656
0
    self->NamedSetter(NonNullHelper(Constify(key)), NonNullHelper(Constify(value)), subjectPrincipal, rv);
657
0
    if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
658
0
      return false;
659
0
    }
660
0
    MOZ_ASSERT(!JS_IsExceptionPending(cx));
661
0
  }
662
0
663
0
  return opresult.succeed();
664
0
}
665
666
667
bool
668
DOMProxyHandler::ownPropNames(JSContext* cx, JS::Handle<JSObject*> proxy, unsigned flags, JS::AutoIdVector& props) const
669
0
{
670
0
  bool isXray = xpc::WrapperFactory::IsXrayWrapper(proxy);
671
0
672
0
  nsTArray<nsString> names;
673
0
  UnwrapProxy(proxy)->GetSupportedNames(names);
674
0
  if (!AppendNamedPropertyIds(cx, proxy, names, false, props)) {
675
0
    return false;
676
0
  }
677
0
678
0
  JS::Rooted<JSObject*> expando(cx);
679
0
  if (!isXray && (expando = DOMProxyHandler::GetExpandoObject(proxy)) &&
680
0
      !js::GetPropertyKeys(cx, expando, flags, &props)) {
681
0
    return false;
682
0
  }
683
0
684
0
  return true;
685
0
}
686
687
bool
688
DOMProxyHandler::hasOwn(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool* bp) const
689
0
{
690
0
  MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
691
0
            "Should not have a XrayWrapper here");
692
0
693
0
694
0
  JS::Rooted<JSObject*> expando(cx, GetExpandoObject(proxy));
695
0
  if (expando) {
696
0
    bool b = true;
697
0
    bool ok = JS_HasPropertyById(cx, expando, id, &b);
698
0
    *bp = !!b;
699
0
    if (!ok || *bp) {
700
0
      return ok;
701
0
    }
702
0
  }
703
0
704
0
  bool hasOnProto;
705
0
  if (!HasPropertyOnPrototype(cx, proxy, id, &hasOnProto)) {
706
0
    return false;
707
0
  }
708
0
  if (!hasOnProto) {
709
0
    bool found = false;
710
0
    FakeString key;
711
0
    bool isSymbol;
712
0
    if (!ConvertIdToString(cx, id, key, isSymbol)) {
713
0
      return false;
714
0
    }
715
0
    if (!isSymbol) {
716
0
      mozilla::dom::Storage* self = UnwrapProxy(proxy);
717
0
      FastErrorResult rv;
718
0
      NonNull<nsIPrincipal> subjectPrincipal;
719
0
      {
720
0
        JS::Realm* realm = js::GetContextRealm(cx);
721
0
        MOZ_ASSERT(realm);
722
0
        JSPrincipals* principals = JS::GetRealmPrincipals(realm);
723
0
        nsIPrincipal* principal = nsJSPrincipals::get(principals);
724
0
725
0
        subjectPrincipal = principal;
726
0
      }
727
0
      DOMString result;
728
0
      self->NamedGetter(NonNullHelper(Constify(key)), found, result, subjectPrincipal, rv);
729
0
      if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
730
0
        return false;
731
0
      }
732
0
      MOZ_ASSERT(!JS_IsExceptionPending(cx));
733
0
      (void)result;
734
0
    }
735
0
736
0
    *bp = found;
737
0
    return true;
738
0
  }
739
0
  *bp = false;
740
0
  return true;
741
0
}
742
743
bool
744
DOMProxyHandler::get(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<JS::Value> receiver, JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp) const
745
0
{
746
0
  MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
747
0
              "Should not have a XrayWrapper here");
748
0
749
0
  { // Scope for expando
750
0
    JS::Rooted<JSObject*> expando(cx, DOMProxyHandler::GetExpandoObject(proxy));
751
0
    if (expando) {
752
0
      bool hasProp;
753
0
      if (!JS_HasPropertyById(cx, expando, id, &hasProp)) {
754
0
        return false;
755
0
      }
756
0
757
0
      if (hasProp) {
758
0
        // Forward the get to the expando object, but our receiver is whatever our
759
0
        // receiver is.
760
0
        return JS_ForwardGetPropertyTo(cx, expando, id, receiver, vp);
761
0
      }
762
0
    }
763
0
  }
764
0
765
0
  bool foundOnPrototype;
766
0
  if (!GetPropertyOnPrototype(cx, proxy, receiver, id, &foundOnPrototype, vp)) {
767
0
    return false;
768
0
  }
769
0
770
0
  if (foundOnPrototype) {
771
0
    return true;
772
0
  }
773
0
774
0
  FakeString key;
775
0
  bool isSymbol;
776
0
  if (!ConvertIdToString(cx, id, key, isSymbol)) {
777
0
    return false;
778
0
  }
779
0
  if (!isSymbol) {
780
0
    mozilla::dom::Storage* self = UnwrapProxy(proxy);
781
0
    bool found = false;
782
0
    FastErrorResult rv;
783
0
    NonNull<nsIPrincipal> subjectPrincipal;
784
0
    {
785
0
      JS::Realm* realm = js::GetContextRealm(cx);
786
0
      MOZ_ASSERT(realm);
787
0
      JSPrincipals* principals = JS::GetRealmPrincipals(realm);
788
0
      nsIPrincipal* principal = nsJSPrincipals::get(principals);
789
0
790
0
      subjectPrincipal = principal;
791
0
    }
792
0
    DOMString result;
793
0
    self->NamedGetter(NonNullHelper(Constify(key)), found, result, subjectPrincipal, rv);
794
0
    if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
795
0
      return false;
796
0
    }
797
0
    MOZ_ASSERT(!JS_IsExceptionPending(cx));
798
0
799
0
    if (found) {
800
0
      if (!xpc::StringToJsval(cx, result, vp)) {
801
0
        return false;
802
0
      }
803
0
      return true;
804
0
    }
805
0
  }
806
0
807
0
  vp.setUndefined();
808
0
  return true;
809
0
}
810
811
const char*
812
DOMProxyHandler::className(JSContext* cx, JS::Handle<JSObject*> proxy) const
813
0
{
814
0
  return "Storage";
815
0
}
816
817
bool
818
DOMProxyHandler::finalizeInBackground(const JS::Value& priv) const
819
0
{
820
0
  return false;
821
0
}
822
823
void
824
DOMProxyHandler::finalize(JSFreeOp* fop, JSObject* proxy) const
825
0
{
826
0
  mozilla::dom::Storage* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::Storage>(proxy);
827
0
  if (self) {
828
0
    ClearWrapper(self, self, proxy);
829
0
    AddForDeferredFinalization<mozilla::dom::Storage>(self);
830
0
  }
831
0
}
832
833
const DOMProxyHandler*
834
DOMProxyHandler::getInstance()
835
0
{
836
0
  static const DOMProxyHandler instance;
837
0
  return &instance;
838
0
}
839
840
bool
841
DOMProxyHandler::delete_(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, JS::ObjectOpResult& opresult) const
842
0
{
843
0
  MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
844
0
            "Should not have a XrayWrapper here");
845
0
846
0
  // Try named delete only if the named property visibility
847
0
  // algorithm says the property is visible.
848
0
  bool tryNamedDelete = true;
849
0
  { // Scope for expando
850
0
    JS::Rooted<JSObject*> expando(cx, DOMProxyHandler::GetExpandoObject(proxy));
851
0
    if (expando) {
852
0
      bool hasProp;
853
0
      if (!JS_HasPropertyById(cx, expando, id, &hasProp)) {
854
0
        return false;
855
0
      }
856
0
      tryNamedDelete = !hasProp;
857
0
    }
858
0
  }
859
0
  if (tryNamedDelete) {
860
0
    bool hasOnProto;
861
0
    if (!HasPropertyOnPrototype(cx, proxy, id, &hasOnProto)) {
862
0
      return false;
863
0
    }
864
0
    tryNamedDelete = !hasOnProto;
865
0
  }
866
0
  if (tryNamedDelete) {
867
0
    bool found = false;
868
0
    bool deleteSucceeded;
869
0
    FakeString key;
870
0
    bool isSymbol;
871
0
    if (!ConvertIdToString(cx, id, key, isSymbol)) {
872
0
      return false;
873
0
    }
874
0
    if (!isSymbol) {
875
0
      mozilla::dom::Storage* self = UnwrapProxy(proxy);
876
0
      FastErrorResult rv;
877
0
      NonNull<nsIPrincipal> subjectPrincipal;
878
0
      {
879
0
        JS::Realm* realm = js::GetContextRealm(cx);
880
0
        MOZ_ASSERT(realm);
881
0
        JSPrincipals* principals = JS::GetRealmPrincipals(realm);
882
0
        nsIPrincipal* principal = nsJSPrincipals::get(principals);
883
0
884
0
        subjectPrincipal = principal;
885
0
      }
886
0
      self->NamedDeleter(NonNullHelper(Constify(key)), found, subjectPrincipal, rv);
887
0
      if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
888
0
        return false;
889
0
      }
890
0
      MOZ_ASSERT(!JS_IsExceptionPending(cx));
891
0
    }
892
0
    deleteSucceeded = true;
893
0
    if (found) {
894
0
      return deleteSucceeded ? opresult.succeed() : opresult.failCantDelete();
895
0
    }
896
0
  }
897
0
898
0
  return dom::DOMProxyHandler::delete_(cx, proxy, id, opresult);
899
0
}
900
901
size_t
902
DOMProxyHandler::objectMoved(JSObject* obj, JSObject* old) const
903
0
{
904
0
  mozilla::dom::Storage* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::Storage>(obj);
905
0
  if (self) {
906
0
    UpdateWrapper(self, self, obj, old);
907
0
  }
908
0
909
0
  return 0;
910
0
}
911
912
static const DOMJSClass sClass = {
913
  PROXY_CLASS_DEF("Storage",
914
                  JSCLASS_IS_DOMJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(1)),
915
  { prototypes::id::Storage, 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 },
916
  IsBaseOf<nsISupports, mozilla::dom::Storage >::value,
917
  sNativePropertyHooks,
918
  FindAssociatedGlobalForNative<mozilla::dom::Storage>::Get,
919
  GetProtoObjectHandle,
920
  GetCCParticipant<mozilla::dom::Storage>::Get()
921
};
922
923
bool
924
Wrap(JSContext* aCx, mozilla::dom::Storage* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
925
0
{
926
0
  static_assert(!IsBaseOf<NonRefcountedDOMObject, mozilla::dom::Storage>::value,
927
0
                "Shouldn't have wrappercached things that are not refcounted.");
928
0
  MOZ_ASSERT(static_cast<mozilla::dom::Storage*>(aObject) ==
929
0
             reinterpret_cast<mozilla::dom::Storage*>(aObject),
930
0
             "Multiple inheritance for mozilla::dom::Storage is broken.");
931
0
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
932
0
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
933
0
  MOZ_ASSERT(!aCache->GetWrapper(),
934
0
             "You should probably not be using Wrap() directly; use "
935
0
             "GetOrCreateDOMReflector instead");
936
0
937
0
  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
938
0
             "nsISupports must be on our primary inheritance chain");
939
0
940
0
  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
941
0
  if (!global) {
942
0
    return false;
943
0
  }
944
0
  MOZ_ASSERT(JS_IsGlobalObject(global));
945
0
  MOZ_ASSERT(JS::ObjectIsNotGray(global));
946
0
947
0
  // That might have ended up wrapping us already, due to the wonders
948
0
  // of XBL.  Check for that, and bail out as needed.
949
0
  aReflector.set(aCache->GetWrapper());
950
0
  if (aReflector) {
951
#ifdef DEBUG
952
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
953
#endif // DEBUG
954
    return true;
955
0
  }
956
0
957
0
  JSAutoRealm ar(aCx, global);
958
0
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
959
0
  if (!canonicalProto) {
960
0
    return false;
961
0
  }
962
0
  JS::Rooted<JSObject*> proto(aCx);
963
0
  if (aGivenProto) {
964
0
    proto = aGivenProto;
965
0
    // Unfortunately, while aGivenProto was in the compartment of aCx
966
0
    // coming in, we changed compartments to that of "parent" so may need
967
0
    // to wrap the proto here.
968
0
    if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
969
0
      if (!JS_WrapObject(aCx, &proto)) {
970
0
        return false;
971
0
      }
972
0
    }
973
0
  } else {
974
0
    proto = canonicalProto;
975
0
  }
976
0
977
0
  BindingJSObjectCreator<mozilla::dom::Storage> creator(aCx);
978
0
  creator.CreateProxyObject(aCx, &sClass.mBase, DOMProxyHandler::getInstance(),
979
0
                            proto, aObject, JS::UndefinedHandleValue, aReflector);
980
0
  if (!aReflector) {
981
0
    return false;
982
0
  }
983
0
984
0
  aCache->SetWrapper(aReflector);
985
0
  creator.InitializationSucceeded();
986
0
987
0
  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
988
0
             aCache->GetWrapperPreserveColor() == aReflector);
989
0
  // If proto != canonicalProto, we have to preserve our wrapper;
990
0
  // otherwise we won't be able to properly recreate it later, since
991
0
  // we won't know what proto to use.  Note that we don't check
992
0
  // aGivenProto here, since it's entirely possible (and even
993
0
  // somewhat common) to have a non-null aGivenProto which is the
994
0
  // same as canonicalProto.
995
0
  if (proto != canonicalProto) {
996
0
    PreserveWrapper(aObject);
997
0
  }
998
0
999
0
  return true;
1000
0
}
1001
1002
static bool
1003
ResolveOwnProperty(JSContext* cx, JS::Handle<JSObject*> wrapper, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::MutableHandle<JS::PropertyDescriptor> desc)
1004
0
{
1005
0
  return js::GetProxyHandler(obj)->getOwnPropertyDescriptor(cx, wrapper, id, desc);
1006
0
}
1007
1008
static bool
1009
EnumerateOwnProperties(JSContext* cx, JS::Handle<JSObject*> wrapper, JS::Handle<JSObject*> obj, JS::AutoIdVector& props)
1010
0
{
1011
0
  return js::GetProxyHandler(obj)->ownPropertyKeys(cx, wrapper, props);
1012
0
}
1013
1014
static bool
1015
DeleteNamedProperty(JSContext* cx, JS::Handle<JSObject*> xray, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, JS::ObjectOpResult& opresult)
1016
0
{
1017
0
  MOZ_ASSERT(xpc::WrapperFactory::IsXrayWrapper(xray));
1018
0
  MOZ_ASSERT(js::IsProxy(proxy));
1019
0
  MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy));
1020
0
  JSAutoRealm ar(cx, proxy);
1021
0
  bool deleteSucceeded = false;
1022
0
  bool found = false;
1023
0
  FakeString key;
1024
0
  bool isSymbol;
1025
0
  if (!ConvertIdToString(cx, id, key, isSymbol)) {
1026
0
    return false;
1027
0
  }
1028
0
  if (!isSymbol) {
1029
0
    mozilla::dom::Storage* self = UnwrapProxy(proxy);
1030
0
    FastErrorResult rv;
1031
0
    NonNull<nsIPrincipal> subjectPrincipal;
1032
0
    {
1033
0
      JS::Realm* realm = js::GetContextRealm(cx);
1034
0
      MOZ_ASSERT(realm);
1035
0
      JSPrincipals* principals = JS::GetRealmPrincipals(realm);
1036
0
      nsIPrincipal* principal = nsJSPrincipals::get(principals);
1037
0
1038
0
      subjectPrincipal = principal;
1039
0
    }
1040
0
    self->NamedDeleter(NonNullHelper(Constify(key)), found, subjectPrincipal, rv);
1041
0
    if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
1042
0
      return false;
1043
0
    }
1044
0
    MOZ_ASSERT(!JS_IsExceptionPending(cx));
1045
0
  }
1046
0
  deleteSucceeded = true;
1047
0
  if (!found || deleteSucceeded) {
1048
0
    return opresult.succeed();
1049
0
  }
1050
0
  return opresult.failCantDelete();
1051
0
}
1052
1053
const NativePropertyHooks sNativePropertyHooks[] = { {
1054
  ResolveOwnProperty,
1055
  EnumerateOwnProperties,
1056
  DeleteNamedProperty,
1057
  { sNativeProperties.Upcast(), sChromeOnlyNativeProperties.Upcast() },
1058
  prototypes::id::Storage,
1059
  constructors::id::Storage,
1060
  nullptr,
1061
  &DefaultXrayExpandoObjectClass
1062
} };
1063
1064
void
1065
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
1066
0
{
1067
0
  JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
1068
0
  if (!parentProto) {
1069
0
    return;
1070
0
  }
1071
0
1072
0
  JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
1073
0
  if (!constructorProto) {
1074
0
    return;
1075
0
  }
1076
0
1077
0
  static bool sIdsInited = false;
1078
0
  if (!sIdsInited && NS_IsMainThread()) {
1079
0
    if (!InitIds(aCx, sNativeProperties.Upcast())) {
1080
0
      return;
1081
0
    }
1082
0
    if (!InitIds(aCx, sChromeOnlyNativeProperties.Upcast())) {
1083
0
      return;
1084
0
    }
1085
0
    sIdsInited = true;
1086
0
  }
1087
0
1088
0
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::Storage);
1089
0
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::Storage);
1090
0
  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
1091
0
                              &sPrototypeClass.mBase, protoCache,
1092
0
                              nullptr,
1093
0
                              constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
1094
0
                              interfaceCache,
1095
0
                              sNativeProperties.Upcast(),
1096
0
                              sChromeOnlyNativeProperties.Upcast(),
1097
0
                              "Storage", aDefineOnGlobal,
1098
0
                              nullptr,
1099
0
                              false);
1100
0
}
1101
1102
JSObject*
1103
GetConstructorObject(JSContext* aCx)
1104
0
{
1105
0
  return GetConstructorObjectHandle(aCx);
1106
0
}
1107
1108
} // namespace Storage_Binding
1109
1110
1111
1112
} // namespace dom
1113
} // namespace mozilla