Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dom/bindings/DataTransferItemListBinding.cpp
Line
Count
Source (jump to first uncovered line)
1
/* THIS FILE IS AUTOGENERATED FROM DataTransferItemList.webidl BY Codegen.py - DO NOT EDIT */
2
3
#include "DataTransferItemListBinding.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/DataTransferItem.h"
10
#include "mozilla/dom/DataTransferItemList.h"
11
#include "mozilla/dom/File.h"
12
#include "mozilla/dom/NonRefcountedDOMObject.h"
13
#include "mozilla/dom/Nullable.h"
14
#include "mozilla/dom/PrimitiveConversions.h"
15
#include "mozilla/dom/XrayExpandoClass.h"
16
17
namespace mozilla {
18
namespace dom {
19
20
namespace binding_detail {}; // Just to make sure it's known as a namespace
21
using namespace mozilla::dom::binding_detail;
22
23
24
namespace DataTransferItemList_Binding {
25
26
MOZ_CAN_RUN_SCRIPT static bool
27
get_length(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::DataTransferItemList* self, JSJitGetterCallArgs args)
28
0
{
29
0
  AUTO_PROFILER_LABEL_FAST("get DataTransferItemList.length", DOM, cx);
30
0
31
0
  uint32_t result(self->Length());
32
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
33
0
  args.rval().setNumber(result);
34
0
  return true;
35
0
}
36
37
static const JSJitInfo length_getterinfo = {
38
  { (JSJitGetterOp)get_length },
39
  { prototypes::id::DataTransferItemList },
40
  { PrototypeTraits<prototypes::id::DataTransferItemList>::Depth },
41
  JSJitInfo::Getter,
42
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
43
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
44
  true,  /* isInfallible. False in setters. */
45
  false,  /* isMovable.  Not relevant for setters. */
46
  false, /* isEliminatable.  Not relevant for setters. */
47
  false, /* isAlwaysInSlot.  Only relevant for getters. */
48
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
49
  false,  /* isTypedMethod.  Only relevant for methods. */
50
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
51
};
52
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
53
static_assert(0 < 1, "There is no slot for us");
54
55
MOZ_CAN_RUN_SCRIPT static bool
56
add(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::DataTransferItemList* self, const JSJitMethodCallArgs& args)
57
0
{
58
0
  AUTO_PROFILER_LABEL_FAST("DataTransferItemList.add", DOM, cx);
59
0
60
0
  unsigned argcount = std::min(args.length(), 2u);
61
0
  switch (argcount) {
62
0
    case 1: {
63
0
      NonNull<mozilla::dom::File> arg0;
64
0
      if (args[0].isObject()) {
65
0
        {
66
0
          nsresult rv = UnwrapObject<prototypes::id::File, mozilla::dom::File>(args[0], arg0);
67
0
          if (NS_FAILED(rv)) {
68
0
            ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Argument 1 of DataTransferItemList.add", "File");
69
0
            return false;
70
0
          }
71
0
        }
72
0
      } else {
73
0
        ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 1 of DataTransferItemList.add");
74
0
        return false;
75
0
      }
76
0
      FastErrorResult rv;
77
0
      NonNull<nsIPrincipal> subjectPrincipal;
78
0
      {
79
0
        JS::Realm* realm = js::GetContextRealm(cx);
80
0
        MOZ_ASSERT(realm);
81
0
        JSPrincipals* principals = JS::GetRealmPrincipals(realm);
82
0
        nsIPrincipal* principal = nsJSPrincipals::get(principals);
83
0
84
0
        subjectPrincipal = principal;
85
0
      }
86
0
      auto result(StrongOrRawPtr<mozilla::dom::DataTransferItem>(self->Add(MOZ_KnownLive(NonNullHelper(arg0)), subjectPrincipal, rv)));
87
0
      if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
88
0
        return false;
89
0
      }
90
0
      MOZ_ASSERT(!JS_IsExceptionPending(cx));
91
0
      if (!result) {
92
0
        args.rval().setNull();
93
0
        return true;
94
0
      }
95
0
      if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
96
0
        MOZ_ASSERT(JS_IsExceptionPending(cx));
97
0
        return false;
98
0
      }
99
0
      return true;
100
0
      break;
101
0
    }
102
0
    case 2: {
103
0
      binding_detail::FakeString arg0;
104
0
      if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
105
0
        return false;
106
0
      }
107
0
      binding_detail::FakeString arg1;
108
0
      if (!ConvertJSValueToString(cx, args[1], eStringify, eStringify, arg1)) {
109
0
        return false;
110
0
      }
111
0
      FastErrorResult rv;
112
0
      NonNull<nsIPrincipal> subjectPrincipal;
113
0
      {
114
0
        JS::Realm* realm = js::GetContextRealm(cx);
115
0
        MOZ_ASSERT(realm);
116
0
        JSPrincipals* principals = JS::GetRealmPrincipals(realm);
117
0
        nsIPrincipal* principal = nsJSPrincipals::get(principals);
118
0
119
0
        subjectPrincipal = principal;
120
0
      }
121
0
      auto result(StrongOrRawPtr<mozilla::dom::DataTransferItem>(self->Add(NonNullHelper(Constify(arg0)), NonNullHelper(Constify(arg1)), subjectPrincipal, rv)));
122
0
      if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
123
0
        return false;
124
0
      }
125
0
      MOZ_ASSERT(!JS_IsExceptionPending(cx));
126
0
      if (!result) {
127
0
        args.rval().setNull();
128
0
        return true;
129
0
      }
130
0
      if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
131
0
        MOZ_ASSERT(JS_IsExceptionPending(cx));
132
0
        return false;
133
0
      }
134
0
      return true;
135
0
      break;
136
0
    }
137
0
    default: {
138
0
      return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "DataTransferItemList.add");
139
0
      break;
140
0
    }
141
0
  }
142
0
  MOZ_CRASH("We have an always-returning default case");
143
0
  return false;
144
0
}
145
146
static const JSJitInfo add_methodinfo = {
147
  { (JSJitGetterOp)add },
148
  { prototypes::id::DataTransferItemList },
149
  { PrototypeTraits<prototypes::id::DataTransferItemList>::Depth },
150
  JSJitInfo::Method,
151
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
152
  JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
153
  false,  /* isInfallible. False in setters. */
154
  false,  /* isMovable.  Not relevant for setters. */
155
  false, /* isEliminatable.  Not relevant for setters. */
156
  false, /* isAlwaysInSlot.  Only relevant for getters. */
157
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
158
  false,  /* isTypedMethod.  Only relevant for methods. */
159
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
160
};
161
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
162
static_assert(0 < 1, "There is no slot for us");
163
164
MOZ_CAN_RUN_SCRIPT static bool
165
remove(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::DataTransferItemList* self, const JSJitMethodCallArgs& args)
166
0
{
167
0
  AUTO_PROFILER_LABEL_FAST("DataTransferItemList.remove", DOM, cx);
168
0
169
0
  if (MOZ_UNLIKELY(args.length() < 1)) {
170
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "DataTransferItemList.remove");
171
0
  }
172
0
  uint32_t arg0;
173
0
  if (!ValueToPrimitive<uint32_t, eDefault>(cx, args[0], &arg0)) {
174
0
    return false;
175
0
  }
176
0
  FastErrorResult rv;
177
0
  NonNull<nsIPrincipal> subjectPrincipal;
178
0
  {
179
0
    JS::Realm* realm = js::GetContextRealm(cx);
180
0
    MOZ_ASSERT(realm);
181
0
    JSPrincipals* principals = JS::GetRealmPrincipals(realm);
182
0
    nsIPrincipal* principal = nsJSPrincipals::get(principals);
183
0
184
0
    subjectPrincipal = principal;
185
0
  }
186
0
  self->Remove(arg0, subjectPrincipal, rv);
187
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
188
0
    return false;
189
0
  }
190
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
191
0
  args.rval().setUndefined();
192
0
  return true;
193
0
}
194
195
static const JSJitInfo remove_methodinfo = {
196
  { (JSJitGetterOp)remove },
197
  { prototypes::id::DataTransferItemList },
198
  { PrototypeTraits<prototypes::id::DataTransferItemList>::Depth },
199
  JSJitInfo::Method,
200
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
201
  JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
202
  false,  /* isInfallible. False in setters. */
203
  false,  /* isMovable.  Not relevant for setters. */
204
  false, /* isEliminatable.  Not relevant for setters. */
205
  false, /* isAlwaysInSlot.  Only relevant for getters. */
206
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
207
  false,  /* isTypedMethod.  Only relevant for methods. */
208
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
209
};
210
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
211
static_assert(0 < 1, "There is no slot for us");
212
213
MOZ_CAN_RUN_SCRIPT static bool
214
clear(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::DataTransferItemList* self, const JSJitMethodCallArgs& args)
215
0
{
216
0
  AUTO_PROFILER_LABEL_FAST("DataTransferItemList.clear", DOM, cx);
217
0
218
0
  FastErrorResult rv;
219
0
  NonNull<nsIPrincipal> subjectPrincipal;
220
0
  {
221
0
    JS::Realm* realm = js::GetContextRealm(cx);
222
0
    MOZ_ASSERT(realm);
223
0
    JSPrincipals* principals = JS::GetRealmPrincipals(realm);
224
0
    nsIPrincipal* principal = nsJSPrincipals::get(principals);
225
0
226
0
    subjectPrincipal = principal;
227
0
  }
228
0
  self->Clear(subjectPrincipal, rv);
229
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
230
0
    return false;
231
0
  }
232
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
233
0
  args.rval().setUndefined();
234
0
  return true;
235
0
}
236
237
static const JSJitInfo clear_methodinfo = {
238
  { (JSJitGetterOp)clear },
239
  { prototypes::id::DataTransferItemList },
240
  { PrototypeTraits<prototypes::id::DataTransferItemList>::Depth },
241
  JSJitInfo::Method,
242
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
243
  JSVAL_TYPE_UNDEFINED,  /* returnType.  Not relevant for setters. */
244
  false,  /* isInfallible. False in setters. */
245
  false,  /* isMovable.  Not relevant for setters. */
246
  false, /* isEliminatable.  Not relevant for setters. */
247
  false, /* isAlwaysInSlot.  Only relevant for getters. */
248
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
249
  false,  /* isTypedMethod.  Only relevant for methods. */
250
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
251
};
252
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
253
static_assert(0 < 1, "There is no slot for us");
254
255
// We deliberately use brace-elision to make Visual Studio produce better initalization code.
256
#if defined(__clang__)
257
#pragma clang diagnostic push
258
#pragma clang diagnostic ignored "-Wmissing-braces"
259
#endif
260
static const JSFunctionSpec sMethods_specs[] = {
261
  JS_FNSPEC("add", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&add_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
262
  JS_FNSPEC("remove", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&remove_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
263
  JS_FNSPEC("clear", (GenericMethod<NormalThisPolicy, ThrowExceptions>), reinterpret_cast<const JSJitInfo*>(&clear_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
264
  JS_SYM_FNSPEC(iterator, nullptr, nullptr, 0, 0, "ArrayValues"),
265
  JS_FS_END
266
};
267
#if defined(__clang__)
268
#pragma clang diagnostic pop
269
#endif
270
271
272
static const Prefable<const JSFunctionSpec> sMethods[] = {
273
  { nullptr, &sMethods_specs[0] },
274
  { nullptr, nullptr }
275
};
276
277
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
278
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
279
static_assert(4 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
280
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
281
282
// We deliberately use brace-elision to make Visual Studio produce better initalization code.
283
#if defined(__clang__)
284
#pragma clang diagnostic push
285
#pragma clang diagnostic ignored "-Wmissing-braces"
286
#endif
287
static const JSPropertySpec sAttributes_specs[] = {
288
  { "length", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &length_getterinfo, nullptr, nullptr },
289
  { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
290
};
291
#if defined(__clang__)
292
#pragma clang diagnostic pop
293
#endif
294
295
296
static const Prefable<const JSPropertySpec> sAttributes[] = {
297
  { nullptr, &sAttributes_specs[0] },
298
  { nullptr, nullptr }
299
};
300
301
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
302
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
303
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
304
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
305
306
307
static uint16_t sNativeProperties_sortedPropertyIndices[5];
308
static PropertyInfo sNativeProperties_propertyInfos[5];
309
310
static const NativePropertiesN<2> sNativeProperties = {
311
  false, 0,
312
  false, 0,
313
  true,  0 /* sMethods */,
314
  true,  1 /* sAttributes */,
315
  false, 0,
316
  false, 0,
317
  false, 0,
318
  -1,
319
  5,
320
  sNativeProperties_sortedPropertyIndices,
321
  {
322
    { sMethods, &sNativeProperties_propertyInfos[0] },
323
    { sAttributes, &sNativeProperties_propertyInfos[4] }
324
  }
325
};
326
static_assert(5 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
327
    "We have a property info count that is oversized");
328
329
static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
330
  {
331
    "Function",
332
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
333
    &sBoringInterfaceObjectClassClassOps,
334
    JS_NULL_CLASS_SPEC,
335
    JS_NULL_CLASS_EXT,
336
    &sInterfaceObjectClassObjectOps
337
  },
338
  eInterface,
339
  true,
340
  prototypes::id::DataTransferItemList,
341
  PrototypeTraits<prototypes::id::DataTransferItemList>::Depth,
342
  sNativePropertyHooks,
343
  "function DataTransferItemList() {\n    [native code]\n}",
344
  JS::GetRealmFunctionPrototype
345
};
346
347
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
348
  {
349
    "DataTransferItemListPrototype",
350
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
351
    JS_NULL_CLASS_OPS,
352
    JS_NULL_CLASS_SPEC,
353
    JS_NULL_CLASS_EXT,
354
    JS_NULL_OBJECT_OPS
355
  },
356
  eInterfacePrototype,
357
  false,
358
  prototypes::id::DataTransferItemList,
359
  PrototypeTraits<prototypes::id::DataTransferItemList>::Depth,
360
  sNativePropertyHooks,
361
  "[object DataTransferItemListPrototype]",
362
  JS::GetRealmObjectPrototype
363
};
364
365
static_assert(IsBaseOf<nsISupports, mozilla::dom::DataTransferItemList >::value,
366
                  "We don't support non-nsISupports native classes for "
367
                  "proxy-based bindings yet");
368
369
370
class DOMProxyHandler : public mozilla::dom::DOMProxyHandler
371
{
372
public:
373
  explicit constexpr DOMProxyHandler()
374
0
  {
375
0
  }
376
377
  virtual bool
378
  getOwnPropDescriptor(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool ignoreNamedProps, JS::MutableHandle<JS::PropertyDescriptor> desc) const override;
379
380
  virtual bool
381
  defineProperty(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, JS::Handle<JS::PropertyDescriptor> desc, JS::ObjectOpResult& opresult, bool* defined) const override;
382
383
  using mozilla::dom::DOMProxyHandler::defineProperty;
384
385
  virtual bool
386
  ownPropNames(JSContext* cx, JS::Handle<JSObject*> proxy, unsigned flags, JS::AutoIdVector& props) const override;
387
388
  virtual bool
389
  hasOwn(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool* bp) const override;
390
391
  virtual bool
392
  get(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<JS::Value> receiver, JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp) const override;
393
394
  virtual const char*
395
  className(JSContext* cx, JS::Handle<JSObject*> proxy) const override;
396
397
  virtual bool
398
  finalizeInBackground(const JS::Value& priv) const override;
399
400
  virtual void
401
  finalize(JSFreeOp* fop, JSObject* proxy) const override;
402
403
  static const DOMProxyHandler*
404
  getInstance();
405
406
  virtual bool
407
  delete_(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, JS::ObjectOpResult& opresult) const override;
408
409
  virtual bool
410
  getElements(JSContext* cx, JS::Handle<JSObject*> proxy, uint32_t begin, uint32_t end, js::ElementAdder* adder) const override;
411
412
  virtual size_t
413
  objectMoved(JSObject* obj, JSObject* old) const override;
414
};
415
416
MOZ_ALWAYS_INLINE bool
417
IsProxy(JSObject* obj)
418
0
{
419
0
  return js::IsProxy(obj) && js::GetProxyHandler(obj) == DOMProxyHandler::getInstance();
420
0
}
421
422
MOZ_ALWAYS_INLINE mozilla::dom::DataTransferItemList*
423
UnwrapProxy(JSObject* obj)
424
0
{
425
0
  MOZ_ASSERT(js::IsProxy(obj));
426
0
  if (js::GetProxyHandler(obj) != DOMProxyHandler::getInstance()) {
427
0
    MOZ_ASSERT(xpc::WrapperFactory::IsXrayWrapper(obj));
428
0
    obj = js::UncheckedUnwrap(obj);
429
0
  }
430
0
  MOZ_ASSERT(IsProxy(obj));
431
0
  return static_cast<mozilla::dom::DataTransferItemList*>(js::GetProxyReservedSlot(obj, DOM_OBJECT_SLOT).toPrivate());
432
0
}
433
434
bool
435
DOMProxyHandler::getOwnPropDescriptor(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool ignoreNamedProps, JS::MutableHandle<JS::PropertyDescriptor> desc) const
436
0
{
437
0
  bool isXray = xpc::WrapperFactory::IsXrayWrapper(proxy);
438
0
  uint32_t index = GetArrayIndexFromId(cx, id);
439
0
  if (IsArrayIndex(index)) {
440
0
    mozilla::dom::DataTransferItemList* self = UnwrapProxy(proxy);
441
0
    bool found = false;
442
0
    auto result(StrongOrRawPtr<mozilla::dom::DataTransferItem>(self->IndexedGetter(index, found)));
443
0
    MOZ_ASSERT(!JS_IsExceptionPending(cx));
444
0
445
0
    if (found) {
446
0
      if (!GetOrCreateDOMReflector(cx, result, desc.value())) {
447
0
        MOZ_ASSERT(JS_IsExceptionPending(cx));
448
0
        return false;
449
0
      }
450
0
      FillPropertyDescriptor(desc, proxy, true);
451
0
      return true;
452
0
    }
453
0
  }
454
0
455
0
  JS::Rooted<JSObject*> expando(cx);
456
0
  if (!isXray && (expando = GetExpandoObject(proxy))) {
457
0
    if (!JS_GetOwnPropertyDescriptorById(cx, expando, id, desc)) {
458
0
      return false;
459
0
    }
460
0
    if (desc.object()) {
461
0
      // Pretend the property lives on the wrapper.
462
0
      desc.object().set(proxy);
463
0
      return true;
464
0
    }
465
0
  }
466
0
467
0
  desc.object().set(nullptr);
468
0
  return true;
469
0
}
470
471
bool
472
DOMProxyHandler::defineProperty(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, JS::Handle<JS::PropertyDescriptor> desc, JS::ObjectOpResult& opresult, bool* defined) const
473
0
{
474
0
  if (IsArrayIndex(GetArrayIndexFromId(cx, id))) {
475
0
    *defined = true;
476
0
    return opresult.failNoIndexedSetter();
477
0
  }
478
0
  return mozilla::dom::DOMProxyHandler::defineProperty(cx, proxy, id, desc, opresult, defined);
479
0
}
480
481
482
bool
483
DOMProxyHandler::ownPropNames(JSContext* cx, JS::Handle<JSObject*> proxy, unsigned flags, JS::AutoIdVector& props) const
484
0
{
485
0
  bool isXray = xpc::WrapperFactory::IsXrayWrapper(proxy);
486
0
487
0
  uint32_t length = UnwrapProxy(proxy)->Length();
488
0
  MOZ_ASSERT(int32_t(length) >= 0);
489
0
  for (int32_t i = 0; i < int32_t(length); ++i) {
490
0
    if (!props.append(INT_TO_JSID(i))) {
491
0
      return false;
492
0
    }
493
0
  }
494
0
495
0
  JS::Rooted<JSObject*> expando(cx);
496
0
  if (!isXray && (expando = DOMProxyHandler::GetExpandoObject(proxy)) &&
497
0
      !js::GetPropertyKeys(cx, expando, flags, &props)) {
498
0
    return false;
499
0
  }
500
0
501
0
  return true;
502
0
}
503
504
bool
505
DOMProxyHandler::hasOwn(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool* bp) const
506
0
{
507
0
  MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
508
0
            "Should not have a XrayWrapper here");
509
0
510
0
  uint32_t index = GetArrayIndexFromId(cx, id);
511
0
  if (IsArrayIndex(index)) {
512
0
    bool found = false;
513
0
    mozilla::dom::DataTransferItemList* self = UnwrapProxy(proxy);
514
0
    auto result(StrongOrRawPtr<mozilla::dom::DataTransferItem>(self->IndexedGetter(index, found)));
515
0
    MOZ_ASSERT(!JS_IsExceptionPending(cx));
516
0
    (void)result;
517
0
518
0
    *bp = found;
519
0
    return true;
520
0
  }
521
0
522
0
523
0
  JS::Rooted<JSObject*> expando(cx, GetExpandoObject(proxy));
524
0
  if (expando) {
525
0
    bool b = true;
526
0
    bool ok = JS_HasPropertyById(cx, expando, id, &b);
527
0
    *bp = !!b;
528
0
    if (!ok || *bp) {
529
0
      return ok;
530
0
    }
531
0
  }
532
0
533
0
  *bp = false;
534
0
  return true;
535
0
}
536
537
bool
538
DOMProxyHandler::get(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<JS::Value> receiver, JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp) const
539
0
{
540
0
  MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
541
0
              "Should not have a XrayWrapper here");
542
0
543
0
  uint32_t index = GetArrayIndexFromId(cx, id);
544
0
  if (IsArrayIndex(index)) {
545
0
    mozilla::dom::DataTransferItemList* self = UnwrapProxy(proxy);
546
0
    bool found = false;
547
0
    auto result(StrongOrRawPtr<mozilla::dom::DataTransferItem>(self->IndexedGetter(index, found)));
548
0
    MOZ_ASSERT(!JS_IsExceptionPending(cx));
549
0
550
0
    if (found) {
551
0
      if (!GetOrCreateDOMReflector(cx, result, vp)) {
552
0
        MOZ_ASSERT(JS_IsExceptionPending(cx));
553
0
        return false;
554
0
      }
555
0
      return true;
556
0
    }
557
0
    // Even if we don't have this index, we don't forward the
558
0
    // get on to our expando object.
559
0
  } else {
560
0
    { // Scope for expando
561
0
      JS::Rooted<JSObject*> expando(cx, DOMProxyHandler::GetExpandoObject(proxy));
562
0
      if (expando) {
563
0
        bool hasProp;
564
0
        if (!JS_HasPropertyById(cx, expando, id, &hasProp)) {
565
0
          return false;
566
0
        }
567
0
568
0
        if (hasProp) {
569
0
          // Forward the get to the expando object, but our receiver is whatever our
570
0
          // receiver is.
571
0
          return JS_ForwardGetPropertyTo(cx, expando, id, receiver, vp);
572
0
        }
573
0
      }
574
0
    }
575
0
  }
576
0
577
0
  bool foundOnPrototype;
578
0
  if (!GetPropertyOnPrototype(cx, proxy, receiver, id, &foundOnPrototype, vp)) {
579
0
    return false;
580
0
  }
581
0
582
0
  if (foundOnPrototype) {
583
0
    return true;
584
0
  }
585
0
586
0
  vp.setUndefined();
587
0
  return true;
588
0
}
589
590
const char*
591
DOMProxyHandler::className(JSContext* cx, JS::Handle<JSObject*> proxy) const
592
0
{
593
0
  return "DataTransferItemList";
594
0
}
595
596
bool
597
DOMProxyHandler::finalizeInBackground(const JS::Value& priv) const
598
0
{
599
0
  return false;
600
0
}
601
602
void
603
DOMProxyHandler::finalize(JSFreeOp* fop, JSObject* proxy) const
604
0
{
605
0
  mozilla::dom::DataTransferItemList* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::DataTransferItemList>(proxy);
606
0
  if (self) {
607
0
    ClearWrapper(self, self, proxy);
608
0
    AddForDeferredFinalization<mozilla::dom::DataTransferItemList>(self);
609
0
  }
610
0
}
611
612
const DOMProxyHandler*
613
DOMProxyHandler::getInstance()
614
0
{
615
0
  static const DOMProxyHandler instance;
616
0
  return &instance;
617
0
}
618
619
bool
620
DOMProxyHandler::delete_(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, JS::ObjectOpResult& opresult) const
621
0
{
622
0
  MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
623
0
            "Should not have a XrayWrapper here");
624
0
625
0
  uint32_t index = GetArrayIndexFromId(cx, id);
626
0
  if (IsArrayIndex(index)) {
627
0
    bool deleteSucceeded;
628
0
    bool found = false;
629
0
    mozilla::dom::DataTransferItemList* self = UnwrapProxy(proxy);
630
0
    auto result(StrongOrRawPtr<mozilla::dom::DataTransferItem>(self->IndexedGetter(index, found)));
631
0
    MOZ_ASSERT(!JS_IsExceptionPending(cx));
632
0
    (void)result;
633
0
    deleteSucceeded = !found;
634
0
    return deleteSucceeded ? opresult.succeed() : opresult.failCantDelete();
635
0
  }
636
0
637
0
  return dom::DOMProxyHandler::delete_(cx, proxy, id, opresult);
638
0
}
639
640
bool
641
DOMProxyHandler::getElements(JSContext* cx, JS::Handle<JSObject*> proxy, uint32_t begin, uint32_t end, js::ElementAdder* adder) const
642
0
{
643
0
  JS::Rooted<JS::Value> temp(cx);
644
0
  MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
645
0
             "Should not have a XrayWrapper here");
646
0
647
0
  mozilla::dom::DataTransferItemList* self = UnwrapProxy(proxy);
648
0
  uint32_t length = self->Length();
649
0
  // Compute the end of the indices we'll get ourselves
650
0
  uint32_t ourEnd = std::max(begin, std::min(end, length));
651
0
652
0
  for (uint32_t index = begin; index < ourEnd; ++index) {
653
0
    bool found = false;
654
0
    auto result(StrongOrRawPtr<mozilla::dom::DataTransferItem>(self->IndexedGetter(index, found)));
655
0
    MOZ_ASSERT(!JS_IsExceptionPending(cx));
656
0
657
0
    MOZ_ASSERT(found);
658
0
    if (!GetOrCreateDOMReflector(cx, result, &temp)) {
659
0
      MOZ_ASSERT(JS_IsExceptionPending(cx));
660
0
      return false;
661
0
    }
662
0
    if (!adder->append(cx, temp)) return false;
663
0
    continue;
664
0
  }
665
0
666
0
  if (end > ourEnd) {
667
0
    JS::Rooted<JSObject*> proto(cx);
668
0
    if (!js::GetObjectProto(cx, proxy, &proto)) {
669
0
      return false;
670
0
    }
671
0
    return js::GetElementsWithAdder(cx, proto, proxy, ourEnd, end, adder);
672
0
  }
673
0
674
0
  return true;
675
0
}
676
677
size_t
678
DOMProxyHandler::objectMoved(JSObject* obj, JSObject* old) const
679
0
{
680
0
  mozilla::dom::DataTransferItemList* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::DataTransferItemList>(obj);
681
0
  if (self) {
682
0
    UpdateWrapper(self, self, obj, old);
683
0
  }
684
0
685
0
  return 0;
686
0
}
687
688
static const DOMJSClass sClass = {
689
  PROXY_CLASS_DEF("DataTransferItemList",
690
                  JSCLASS_IS_DOMJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(1)),
691
  { prototypes::id::DataTransferItemList, 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 },
692
  IsBaseOf<nsISupports, mozilla::dom::DataTransferItemList >::value,
693
  sNativePropertyHooks,
694
  FindAssociatedGlobalForNative<mozilla::dom::DataTransferItemList>::Get,
695
  GetProtoObjectHandle,
696
  GetCCParticipant<mozilla::dom::DataTransferItemList>::Get()
697
};
698
699
bool
700
Wrap(JSContext* aCx, mozilla::dom::DataTransferItemList* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
701
0
{
702
0
  static_assert(!IsBaseOf<NonRefcountedDOMObject, mozilla::dom::DataTransferItemList>::value,
703
0
                "Shouldn't have wrappercached things that are not refcounted.");
704
0
  MOZ_ASSERT(static_cast<mozilla::dom::DataTransferItemList*>(aObject) ==
705
0
             reinterpret_cast<mozilla::dom::DataTransferItemList*>(aObject),
706
0
             "Multiple inheritance for mozilla::dom::DataTransferItemList is broken.");
707
0
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
708
0
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
709
0
  MOZ_ASSERT(!aCache->GetWrapper(),
710
0
             "You should probably not be using Wrap() directly; use "
711
0
             "GetOrCreateDOMReflector instead");
712
0
713
0
  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
714
0
             "nsISupports must be on our primary inheritance chain");
715
0
716
0
  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
717
0
  if (!global) {
718
0
    return false;
719
0
  }
720
0
  MOZ_ASSERT(JS_IsGlobalObject(global));
721
0
  MOZ_ASSERT(JS::ObjectIsNotGray(global));
722
0
723
0
  // That might have ended up wrapping us already, due to the wonders
724
0
  // of XBL.  Check for that, and bail out as needed.
725
0
  aReflector.set(aCache->GetWrapper());
726
0
  if (aReflector) {
727
#ifdef DEBUG
728
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
729
#endif // DEBUG
730
    return true;
731
0
  }
732
0
733
0
  JSAutoRealm ar(aCx, global);
734
0
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
735
0
  if (!canonicalProto) {
736
0
    return false;
737
0
  }
738
0
  JS::Rooted<JSObject*> proto(aCx);
739
0
  if (aGivenProto) {
740
0
    proto = aGivenProto;
741
0
    // Unfortunately, while aGivenProto was in the compartment of aCx
742
0
    // coming in, we changed compartments to that of "parent" so may need
743
0
    // to wrap the proto here.
744
0
    if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
745
0
      if (!JS_WrapObject(aCx, &proto)) {
746
0
        return false;
747
0
      }
748
0
    }
749
0
  } else {
750
0
    proto = canonicalProto;
751
0
  }
752
0
753
0
  BindingJSObjectCreator<mozilla::dom::DataTransferItemList> creator(aCx);
754
0
  creator.CreateProxyObject(aCx, &sClass.mBase, DOMProxyHandler::getInstance(),
755
0
                            proto, aObject, JS::UndefinedHandleValue, aReflector);
756
0
  if (!aReflector) {
757
0
    return false;
758
0
  }
759
0
760
0
  aCache->SetWrapper(aReflector);
761
0
  creator.InitializationSucceeded();
762
0
763
0
  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
764
0
             aCache->GetWrapperPreserveColor() == aReflector);
765
0
  // If proto != canonicalProto, we have to preserve our wrapper;
766
0
  // otherwise we won't be able to properly recreate it later, since
767
0
  // we won't know what proto to use.  Note that we don't check
768
0
  // aGivenProto here, since it's entirely possible (and even
769
0
  // somewhat common) to have a non-null aGivenProto which is the
770
0
  // same as canonicalProto.
771
0
  if (proto != canonicalProto) {
772
0
    PreserveWrapper(aObject);
773
0
  }
774
0
775
0
  return true;
776
0
}
777
778
static bool
779
ResolveOwnProperty(JSContext* cx, JS::Handle<JSObject*> wrapper, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::MutableHandle<JS::PropertyDescriptor> desc)
780
0
{
781
0
  return js::GetProxyHandler(obj)->getOwnPropertyDescriptor(cx, wrapper, id, desc);
782
0
}
783
784
static bool
785
EnumerateOwnProperties(JSContext* cx, JS::Handle<JSObject*> wrapper, JS::Handle<JSObject*> obj, JS::AutoIdVector& props)
786
0
{
787
0
  return js::GetProxyHandler(obj)->ownPropertyKeys(cx, wrapper, props);
788
0
}
789
790
const NativePropertyHooks sNativePropertyHooks[] = { {
791
  ResolveOwnProperty,
792
  EnumerateOwnProperties,
793
  nullptr,
794
  { sNativeProperties.Upcast(), nullptr },
795
  prototypes::id::DataTransferItemList,
796
  constructors::id::DataTransferItemList,
797
  nullptr,
798
  &DefaultXrayExpandoObjectClass
799
} };
800
801
void
802
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
803
0
{
804
0
  JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
805
0
  if (!parentProto) {
806
0
    return;
807
0
  }
808
0
809
0
  JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
810
0
  if (!constructorProto) {
811
0
    return;
812
0
  }
813
0
814
0
  static bool sIdsInited = false;
815
0
  if (!sIdsInited && NS_IsMainThread()) {
816
0
    if (!InitIds(aCx, sNativeProperties.Upcast())) {
817
0
      return;
818
0
    }
819
0
    sIdsInited = true;
820
0
  }
821
0
822
0
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::DataTransferItemList);
823
0
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::DataTransferItemList);
824
0
  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
825
0
                              &sPrototypeClass.mBase, protoCache,
826
0
                              nullptr,
827
0
                              constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
828
0
                              interfaceCache,
829
0
                              sNativeProperties.Upcast(),
830
0
                              nullptr,
831
0
                              "DataTransferItemList", aDefineOnGlobal,
832
0
                              nullptr,
833
0
                              false);
834
0
}
835
836
JSObject*
837
GetConstructorObject(JSContext* aCx)
838
0
{
839
0
  return GetConstructorObjectHandle(aCx);
840
0
}
841
842
} // namespace DataTransferItemList_Binding
843
844
845
846
} // namespace dom
847
} // namespace mozilla