Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dom/bindings/SpeechSynthesisEventBinding.cpp
Line
Count
Source (jump to first uncovered line)
1
/* THIS FILE IS AUTOGENERATED FROM SpeechSynthesisEvent.webidl BY Codegen.py - DO NOT EDIT */
2
3
#include "AtomList.h"
4
#include "EventBinding.h"
5
#include "SpeechSynthesisEventBinding.h"
6
#include "WrapperFactory.h"
7
#include "mozilla/FloatingPoint.h"
8
#include "mozilla/OwningNonNull.h"
9
#include "mozilla/Preferences.h"
10
#include "mozilla/dom/BindingUtils.h"
11
#include "mozilla/dom/DOMJSClass.h"
12
#include "mozilla/dom/NonRefcountedDOMObject.h"
13
#include "mozilla/dom/Nullable.h"
14
#include "mozilla/dom/PrimitiveConversions.h"
15
#include "mozilla/dom/ScriptSettings.h"
16
#include "mozilla/dom/SpeechSynthesisEvent.h"
17
#include "mozilla/dom/SpeechSynthesisUtterance.h"
18
#include "mozilla/dom/XrayExpandoClass.h"
19
20
namespace mozilla {
21
namespace dom {
22
23
namespace binding_detail {}; // Just to make sure it's known as a namespace
24
using namespace mozilla::dom::binding_detail;
25
26
27
28
SpeechSynthesisEventInit::SpeechSynthesisEventInit()
29
  : EventInit(FastDictionaryInitializer())
30
0
{
31
0
  // Safe to pass a null context if we pass a null value
32
0
  Init(nullptr, JS::NullHandleValue);
33
0
}
34
35
36
37
bool
38
SpeechSynthesisEventInit::InitIds(JSContext* cx, SpeechSynthesisEventInitAtoms* atomsCache)
39
0
{
40
0
  MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
41
0
42
0
  // Initialize these in reverse order so that any failure leaves the first one
43
0
  // uninitialized.
44
0
  if (!atomsCache->utterance_id.init(cx, "utterance") ||
45
0
      !atomsCache->name_id.init(cx, "name") ||
46
0
      !atomsCache->elapsedTime_id.init(cx, "elapsedTime") ||
47
0
      !atomsCache->charLength_id.init(cx, "charLength") ||
48
0
      !atomsCache->charIndex_id.init(cx, "charIndex")) {
49
0
    return false;
50
0
  }
51
0
  return true;
52
0
}
53
54
bool
55
SpeechSynthesisEventInit::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
56
0
{
57
0
  // Passing a null JSContext is OK only if we're initing from null,
58
0
  // Since in that case we will not have to do any property gets
59
0
  // Also evaluate isNullOrUndefined in order to avoid false-positive
60
0
  // checkers by static analysis tools
61
0
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
62
0
  SpeechSynthesisEventInitAtoms* atomsCache = nullptr;
63
0
  if (cx) {
64
0
    atomsCache = GetAtomCache<SpeechSynthesisEventInitAtoms>(cx);
65
0
    if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
66
0
      return false;
67
0
    }
68
0
  }
69
0
70
0
  // Per spec, we init the parent's members first
71
0
  if (!EventInit::Init(cx, val)) {
72
0
    return false;
73
0
  }
74
0
75
0
  bool isNull = val.isNullOrUndefined();
76
0
  // We only need these if !isNull, in which case we have |cx|.
77
0
  Maybe<JS::Rooted<JSObject *> > object;
78
0
  Maybe<JS::Rooted<JS::Value> > temp;
79
0
  if (!isNull) {
80
0
    MOZ_ASSERT(cx);
81
0
    object.emplace(cx, &val.toObject());
82
0
    temp.emplace(cx);
83
0
  }
84
0
  if (!isNull) {
85
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->charIndex_id, temp.ptr())) {
86
0
      return false;
87
0
    }
88
0
  }
89
0
  if (!isNull && !temp->isUndefined()) {
90
0
    if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), &mCharIndex)) {
91
0
      return false;
92
0
    }
93
0
  } else {
94
0
    mCharIndex = 0U;
95
0
  }
96
0
  mIsAnyMemberPresent = true;
97
0
98
0
  if (!isNull) {
99
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->charLength_id, temp.ptr())) {
100
0
      return false;
101
0
    }
102
0
  }
103
0
  if (!(!isNull && !temp->isUndefined()) || temp.ref().isNullOrUndefined()) {
104
0
    mCharLength.SetNull();
105
0
  } else if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), &mCharLength.SetValue())) {
106
0
    return false;
107
0
  }
108
0
  mIsAnyMemberPresent = true;
109
0
110
0
  if (!isNull) {
111
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->elapsedTime_id, temp.ptr())) {
112
0
      return false;
113
0
    }
114
0
  }
115
0
  if (!isNull && !temp->isUndefined()) {
116
0
    if (!ValueToPrimitive<float, eDefault>(cx, temp.ref(), &mElapsedTime)) {
117
0
      return false;
118
0
    } else if (!mozilla::IsFinite(mElapsedTime)) {
119
0
      ThrowErrorMessage(cx, MSG_NOT_FINITE, "'elapsedTime' member of SpeechSynthesisEventInit");
120
0
      return false;
121
0
    }
122
0
  } else {
123
0
    mElapsedTime = 0.0F;
124
0
  }
125
0
  mIsAnyMemberPresent = true;
126
0
127
0
  if (!isNull) {
128
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->name_id, temp.ptr())) {
129
0
      return false;
130
0
    }
131
0
  }
132
0
  if (!isNull && !temp->isUndefined()) {
133
0
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mName)) {
134
0
      return false;
135
0
    }
136
0
  } else {
137
0
    static const char16_t data[] = { 0 };
138
0
    mName.Rebind(data, ArrayLength(data) - 1);
139
0
  }
140
0
  mIsAnyMemberPresent = true;
141
0
142
0
  if (!isNull) {
143
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->utterance_id, temp.ptr())) {
144
0
      return false;
145
0
    }
146
0
  }
147
0
  if (!isNull && !temp->isUndefined()) {
148
0
    if (temp.ref().isObject()) {
149
0
      static_assert(IsRefcounted<mozilla::dom::SpeechSynthesisUtterance>::value, "We can only store refcounted classes.");{
150
0
        nsresult rv = UnwrapObject<prototypes::id::SpeechSynthesisUtterance, mozilla::dom::SpeechSynthesisUtterance>(temp.ptr(), mUtterance);
151
0
        if (NS_FAILED(rv)) {
152
0
          ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "'utterance' member of SpeechSynthesisEventInit", "SpeechSynthesisUtterance");
153
0
          return false;
154
0
        }
155
0
      }
156
0
    } else {
157
0
      ThrowErrorMessage(cx, MSG_NOT_OBJECT, "'utterance' member of SpeechSynthesisEventInit");
158
0
      return false;
159
0
    }
160
0
    mIsAnyMemberPresent = true;
161
0
  } else if (cx) {
162
0
    // Don't error out if we have no cx.  In that
163
0
    // situation the caller is default-constructing us and we'll
164
0
    // just assume they know what they're doing.
165
0
    return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
166
0
                             "'utterance' member of SpeechSynthesisEventInit");
167
0
  }
168
0
  return true;
169
0
}
170
171
bool
172
SpeechSynthesisEventInit::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
173
0
{
174
0
  SpeechSynthesisEventInitAtoms* atomsCache = GetAtomCache<SpeechSynthesisEventInitAtoms>(cx);
175
0
  if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
176
0
    return false;
177
0
  }
178
0
179
0
  // Per spec, we define the parent's members first
180
0
  if (!EventInit::ToObjectInternal(cx, rval)) {
181
0
    return false;
182
0
  }
183
0
  JS::Rooted<JSObject*> obj(cx, &rval.toObject());
184
0
185
0
  do {
186
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
187
0
    JS::Rooted<JS::Value> temp(cx);
188
0
    uint32_t const & currentValue = mCharIndex;
189
0
    temp.setNumber(currentValue);
190
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->charIndex_id, temp, JSPROP_ENUMERATE)) {
191
0
      return false;
192
0
    }
193
0
    break;
194
0
  } while(false);
195
0
196
0
  do {
197
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
198
0
    JS::Rooted<JS::Value> temp(cx);
199
0
    Nullable<uint32_t> const & currentValue = mCharLength;
200
0
    if (currentValue.IsNull()) {
201
0
      temp.setNull();
202
0
      if (!JS_DefinePropertyById(cx, obj, atomsCache->charLength_id, temp, JSPROP_ENUMERATE)) {
203
0
        return false;
204
0
      }
205
0
      break;
206
0
    }
207
0
    temp.setNumber(currentValue.Value());
208
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->charLength_id, temp, JSPROP_ENUMERATE)) {
209
0
      return false;
210
0
    }
211
0
    break;
212
0
  } while(false);
213
0
214
0
  do {
215
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
216
0
    JS::Rooted<JS::Value> temp(cx);
217
0
    float const & currentValue = mElapsedTime;
218
0
    temp.set(JS_NumberValue(double(currentValue)));
219
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->elapsedTime_id, temp, JSPROP_ENUMERATE)) {
220
0
      return false;
221
0
    }
222
0
    break;
223
0
  } while(false);
224
0
225
0
  do {
226
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
227
0
    JS::Rooted<JS::Value> temp(cx);
228
0
    nsString const & currentValue = mName;
229
0
    if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
230
0
      return false;
231
0
    }
232
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->name_id, temp, JSPROP_ENUMERATE)) {
233
0
      return false;
234
0
    }
235
0
    break;
236
0
  } while(false);
237
0
238
0
  do {
239
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
240
0
    JS::Rooted<JS::Value> temp(cx);
241
0
    OwningNonNull<mozilla::dom::SpeechSynthesisUtterance> const & currentValue = mUtterance;
242
0
    if (!GetOrCreateDOMReflector(cx, currentValue, &temp)) {
243
0
      MOZ_ASSERT(JS_IsExceptionPending(cx));
244
0
      return false;
245
0
    }
246
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->utterance_id, temp, JSPROP_ENUMERATE)) {
247
0
      return false;
248
0
    }
249
0
    break;
250
0
  } while(false);
251
0
252
0
  return true;
253
0
}
254
255
void
256
SpeechSynthesisEventInit::TraceDictionary(JSTracer* trc)
257
0
{
258
0
  EventInit::TraceDictionary(trc);
259
0
}
260
261
262
263
SpeechSynthesisEventInit&
264
SpeechSynthesisEventInit::operator=(const SpeechSynthesisEventInit& aOther)
265
0
{
266
0
  EventInit::operator=(aOther);
267
0
  mCharIndex = aOther.mCharIndex;
268
0
  mCharLength = aOther.mCharLength;
269
0
  mElapsedTime = aOther.mElapsedTime;
270
0
  mName = aOther.mName;
271
0
  mUtterance = aOther.mUtterance;
272
0
  return *this;
273
0
}
274
275
namespace binding_detail {
276
} // namespace binding_detail
277
278
279
namespace SpeechSynthesisEvent_Binding {
280
281
static_assert(IsRefcounted<NativeType>::value == IsRefcounted<Event_Binding::NativeType>::value,
282
              "Can't inherit from an interface with a different ownership model.");
283
284
MOZ_CAN_RUN_SCRIPT static bool
285
get_utterance(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SpeechSynthesisEvent* self, JSJitGetterCallArgs args)
286
0
{
287
0
  AUTO_PROFILER_LABEL_FAST("get SpeechSynthesisEvent.utterance", DOM, cx);
288
0
289
0
  auto result(StrongOrRawPtr<mozilla::dom::SpeechSynthesisUtterance>(self->Utterance()));
290
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
291
0
  if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
292
0
    MOZ_ASSERT(JS_IsExceptionPending(cx));
293
0
    return false;
294
0
  }
295
0
  return true;
296
0
}
297
298
static const JSJitInfo utterance_getterinfo = {
299
  { (JSJitGetterOp)get_utterance },
300
  { prototypes::id::SpeechSynthesisEvent },
301
  { PrototypeTraits<prototypes::id::SpeechSynthesisEvent>::Depth },
302
  JSJitInfo::Getter,
303
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
304
  JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
305
  false,  /* isInfallible. False in setters. */
306
  false,  /* isMovable.  Not relevant for setters. */
307
  false, /* isEliminatable.  Not relevant for setters. */
308
  false, /* isAlwaysInSlot.  Only relevant for getters. */
309
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
310
  false,  /* isTypedMethod.  Only relevant for methods. */
311
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
312
};
313
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
314
static_assert(0 < 1, "There is no slot for us");
315
316
MOZ_CAN_RUN_SCRIPT static bool
317
get_charIndex(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SpeechSynthesisEvent* self, JSJitGetterCallArgs args)
318
0
{
319
0
  AUTO_PROFILER_LABEL_FAST("get SpeechSynthesisEvent.charIndex", DOM, cx);
320
0
321
0
  uint32_t result(self->CharIndex());
322
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
323
0
  args.rval().setNumber(result);
324
0
  return true;
325
0
}
326
327
static const JSJitInfo charIndex_getterinfo = {
328
  { (JSJitGetterOp)get_charIndex },
329
  { prototypes::id::SpeechSynthesisEvent },
330
  { PrototypeTraits<prototypes::id::SpeechSynthesisEvent>::Depth },
331
  JSJitInfo::Getter,
332
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
333
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
334
  true,  /* isInfallible. False in setters. */
335
  false,  /* isMovable.  Not relevant for setters. */
336
  false, /* isEliminatable.  Not relevant for setters. */
337
  false, /* isAlwaysInSlot.  Only relevant for getters. */
338
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
339
  false,  /* isTypedMethod.  Only relevant for methods. */
340
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
341
};
342
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
343
static_assert(0 < 1, "There is no slot for us");
344
345
MOZ_CAN_RUN_SCRIPT static bool
346
get_charLength(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SpeechSynthesisEvent* self, JSJitGetterCallArgs args)
347
0
{
348
0
  AUTO_PROFILER_LABEL_FAST("get SpeechSynthesisEvent.charLength", DOM, cx);
349
0
350
0
  Nullable<uint32_t> result(self->GetCharLength());
351
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
352
0
  if (result.IsNull()) {
353
0
    args.rval().setNull();
354
0
    return true;
355
0
  }
356
0
  args.rval().setNumber(result.Value());
357
0
  return true;
358
0
}
359
360
static const JSJitInfo charLength_getterinfo = {
361
  { (JSJitGetterOp)get_charLength },
362
  { prototypes::id::SpeechSynthesisEvent },
363
  { PrototypeTraits<prototypes::id::SpeechSynthesisEvent>::Depth },
364
  JSJitInfo::Getter,
365
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
366
  JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
367
  true,  /* isInfallible. False in setters. */
368
  false,  /* isMovable.  Not relevant for setters. */
369
  false, /* isEliminatable.  Not relevant for setters. */
370
  false, /* isAlwaysInSlot.  Only relevant for getters. */
371
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
372
  false,  /* isTypedMethod.  Only relevant for methods. */
373
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
374
};
375
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
376
static_assert(0 < 1, "There is no slot for us");
377
378
MOZ_CAN_RUN_SCRIPT static bool
379
get_elapsedTime(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SpeechSynthesisEvent* self, JSJitGetterCallArgs args)
380
0
{
381
0
  AUTO_PROFILER_LABEL_FAST("get SpeechSynthesisEvent.elapsedTime", DOM, cx);
382
0
383
0
  float result(self->ElapsedTime());
384
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
385
0
  args.rval().set(JS_NumberValue(double(result)));
386
0
  return true;
387
0
}
388
389
static const JSJitInfo elapsedTime_getterinfo = {
390
  { (JSJitGetterOp)get_elapsedTime },
391
  { prototypes::id::SpeechSynthesisEvent },
392
  { PrototypeTraits<prototypes::id::SpeechSynthesisEvent>::Depth },
393
  JSJitInfo::Getter,
394
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
395
  JSVAL_TYPE_DOUBLE,  /* returnType.  Not relevant for setters. */
396
  true,  /* isInfallible. False in setters. */
397
  false,  /* isMovable.  Not relevant for setters. */
398
  false, /* isEliminatable.  Not relevant for setters. */
399
  false, /* isAlwaysInSlot.  Only relevant for getters. */
400
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
401
  false,  /* isTypedMethod.  Only relevant for methods. */
402
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
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
get_name(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SpeechSynthesisEvent* self, JSJitGetterCallArgs args)
409
0
{
410
0
  AUTO_PROFILER_LABEL_FAST("get SpeechSynthesisEvent.name", DOM, cx);
411
0
412
0
  DOMString result;
413
0
  self->GetName(result);
414
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
415
0
  if (!xpc::StringToJsval(cx, result, args.rval())) {
416
0
    return false;
417
0
  }
418
0
  return true;
419
0
}
420
421
static const JSJitInfo name_getterinfo = {
422
  { (JSJitGetterOp)get_name },
423
  { prototypes::id::SpeechSynthesisEvent },
424
  { PrototypeTraits<prototypes::id::SpeechSynthesisEvent>::Depth },
425
  JSJitInfo::Getter,
426
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
427
  JSVAL_TYPE_UNKNOWN,  /* returnType.  Not relevant for setters. */
428
  false,  /* isInfallible. False in setters. */
429
  false,  /* isMovable.  Not relevant for setters. */
430
  false, /* isEliminatable.  Not relevant for setters. */
431
  false, /* isAlwaysInSlot.  Only relevant for getters. */
432
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
433
  false,  /* isTypedMethod.  Only relevant for methods. */
434
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
435
};
436
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
437
static_assert(0 < 1, "There is no slot for us");
438
439
MOZ_CAN_RUN_SCRIPT static bool
440
get_isTrusted(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SpeechSynthesisEvent* self, JSJitGetterCallArgs args)
441
0
{
442
0
  AUTO_PROFILER_LABEL_FAST("get SpeechSynthesisEvent.isTrusted", DOM, cx);
443
0
444
0
  bool result(self->IsTrusted());
445
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
446
0
  args.rval().setBoolean(result);
447
0
  return true;
448
0
}
449
450
static const JSJitInfo isTrusted_getterinfo = {
451
  { (JSJitGetterOp)get_isTrusted },
452
  { prototypes::id::SpeechSynthesisEvent },
453
  { PrototypeTraits<prototypes::id::SpeechSynthesisEvent>::Depth },
454
  JSJitInfo::Getter,
455
  JSJitInfo::AliasDOMSets, /* aliasSet.  Not relevant for setters. */
456
  JSVAL_TYPE_BOOLEAN,  /* returnType.  Not relevant for setters. */
457
  true,  /* isInfallible. False in setters. */
458
  true,  /* isMovable.  Not relevant for setters. */
459
  true, /* isEliminatable.  Not relevant for setters. */
460
  false, /* isAlwaysInSlot.  Only relevant for getters. */
461
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
462
  false,  /* isTypedMethod.  Only relevant for methods. */
463
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
464
};
465
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
466
static_assert(0 < 1, "There is no slot for us");
467
468
static bool
469
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
470
0
{
471
0
  mozilla::dom::SpeechSynthesisEvent* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::SpeechSynthesisEvent>(obj);
472
0
  // We don't want to preserve if we don't have a wrapper, and we
473
0
  // obviously can't preserve if we're not initialized.
474
0
  if (self && self->GetWrapperPreserveColor()) {
475
0
    PreserveWrapper(self);
476
0
  }
477
0
  return true;
478
0
}
479
480
static void
481
_finalize(js::FreeOp* fop, JSObject* obj)
482
0
{
483
0
  mozilla::dom::SpeechSynthesisEvent* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::SpeechSynthesisEvent>(obj);
484
0
  if (self) {
485
0
    ClearWrapper(self, self, obj);
486
0
    AddForDeferredFinalization<mozilla::dom::SpeechSynthesisEvent>(self);
487
0
  }
488
0
}
489
490
static size_t
491
_objectMoved(JSObject* obj, JSObject* old)
492
0
{
493
0
  mozilla::dom::SpeechSynthesisEvent* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::SpeechSynthesisEvent>(obj);
494
0
  if (self) {
495
0
    UpdateWrapper(self, self, obj, old);
496
0
  }
497
0
498
0
  return 0;
499
0
}
500
501
// We deliberately use brace-elision to make Visual Studio produce better initalization code.
502
#if defined(__clang__)
503
#pragma clang diagnostic push
504
#pragma clang diagnostic ignored "-Wmissing-braces"
505
#endif
506
static const JSPropertySpec sAttributes_specs[] = {
507
  { "utterance", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &utterance_getterinfo, nullptr, nullptr },
508
  { "charIndex", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &charIndex_getterinfo, nullptr, nullptr },
509
  { "charLength", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &charLength_getterinfo, nullptr, nullptr },
510
  { "elapsedTime", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &elapsedTime_getterinfo, nullptr, nullptr },
511
  { "name", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &name_getterinfo, nullptr, nullptr },
512
  { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
513
};
514
#if defined(__clang__)
515
#pragma clang diagnostic pop
516
#endif
517
518
519
static const Prefable<const JSPropertySpec> sAttributes[] = {
520
  { nullptr, &sAttributes_specs[0] },
521
  { nullptr, nullptr }
522
};
523
524
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
525
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
526
static_assert(5 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
527
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
528
529
// We deliberately use brace-elision to make Visual Studio produce better initalization code.
530
#if defined(__clang__)
531
#pragma clang diagnostic push
532
#pragma clang diagnostic ignored "-Wmissing-braces"
533
#endif
534
static const JSPropertySpec sUnforgeableAttributes_specs[] = {
535
  { "isTrusted", JSPROP_ENUMERATE | JSPROP_PERMANENT, GenericGetter<NormalThisPolicy, ThrowExceptions>, &isTrusted_getterinfo, nullptr, nullptr },
536
  { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
537
};
538
#if defined(__clang__)
539
#pragma clang diagnostic pop
540
#endif
541
542
543
static const Prefable<const JSPropertySpec> sUnforgeableAttributes[] = {
544
  { nullptr, &sUnforgeableAttributes_specs[0] },
545
  { nullptr, nullptr }
546
};
547
548
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
549
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
550
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
551
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
552
553
554
static uint16_t sNativeProperties_sortedPropertyIndices[6];
555
static PropertyInfo sNativeProperties_propertyInfos[6];
556
557
static const NativePropertiesN<2> sNativeProperties = {
558
  false, 0,
559
  false, 0,
560
  false, 0,
561
  true,  0 /* sAttributes */,
562
  false, 0,
563
  true,  1 /* sUnforgeableAttributes */,
564
  false, 0,
565
  -1,
566
  6,
567
  sNativeProperties_sortedPropertyIndices,
568
  {
569
    { sAttributes, &sNativeProperties_propertyInfos[0] },
570
    { sUnforgeableAttributes, &sNativeProperties_propertyInfos[5] }
571
  }
572
};
573
static_assert(6 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
574
    "We have a property info count that is oversized");
575
576
static bool
577
_constructor(JSContext* cx, unsigned argc, JS::Value* vp)
578
0
{
579
0
  AUTO_PROFILER_LABEL_FAST("SpeechSynthesisEvent constructor", DOM, cx);
580
0
581
0
  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
582
0
  JS::Rooted<JSObject*> obj(cx, &args.callee());
583
0
  if (!args.isConstructing()) {
584
0
    // XXXbz wish I could get the name from the callee instead of
585
0
    // Adding more relocations
586
0
    return ThrowConstructorWithoutNew(cx, "SpeechSynthesisEvent");
587
0
  }
588
0
589
0
  JS::Rooted<JSObject*> desiredProto(cx);
590
0
  if (!GetDesiredProto(cx, args, &desiredProto)) {
591
0
    return false;
592
0
  }
593
0
594
0
  if (MOZ_UNLIKELY(args.length() < 2)) {
595
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "SpeechSynthesisEvent");
596
0
  }
597
0
  GlobalObject global(cx, obj);
598
0
  if (global.Failed()) {
599
0
    return false;
600
0
  }
601
0
602
0
  bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);
603
0
  binding_detail::FakeString arg0;
604
0
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
605
0
    return false;
606
0
  }
607
0
  binding_detail::FastSpeechSynthesisEventInit arg1;
608
0
  if (!arg1.Init(cx, args[1],  "Argument 2 of SpeechSynthesisEvent.constructor", false)) {
609
0
    return false;
610
0
  }
611
0
  Maybe<JSAutoRealm> ar;
612
0
  if (objIsXray) {
613
0
    obj = js::CheckedUnwrap(obj);
614
0
    if (!obj) {
615
0
      return false;
616
0
    }
617
0
    ar.emplace(cx, obj);
618
0
    if (!JS_WrapObject(cx, &desiredProto)) {
619
0
      return false;
620
0
    }
621
0
  }
622
0
  FastErrorResult rv;
623
0
  auto result(StrongOrRawPtr<mozilla::dom::SpeechSynthesisEvent>(mozilla::dom::SpeechSynthesisEvent::Constructor(global, NonNullHelper(Constify(arg0)), Constify(arg1), rv)));
624
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
625
0
    return false;
626
0
  }
627
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
628
0
  static_assert(!IsPointer<decltype(result)>::value,
629
0
                "NewObject implies that we need to keep the object alive with a strong reference.");
630
0
  if (!GetOrCreateDOMReflector(cx, result, args.rval(), desiredProto)) {
631
0
    MOZ_ASSERT(JS_IsExceptionPending(cx));
632
0
    return false;
633
0
  }
634
0
  return true;
635
0
}
636
637
static const js::ClassOps sInterfaceObjectClassOps = {
638
    nullptr,               /* addProperty */
639
    nullptr,               /* delProperty */
640
    nullptr,               /* enumerate */
641
    nullptr,               /* newEnumerate */
642
    nullptr,               /* resolve */
643
    nullptr,               /* mayResolve */
644
    nullptr,               /* finalize */
645
    _constructor, /* call */
646
    nullptr,               /* hasInstance */
647
    _constructor, /* construct */
648
    nullptr,               /* trace */
649
};
650
651
static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
652
  {
653
    "Function",
654
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
655
    &sInterfaceObjectClassOps,
656
    JS_NULL_CLASS_SPEC,
657
    JS_NULL_CLASS_EXT,
658
    &sInterfaceObjectClassObjectOps
659
  },
660
  eInterface,
661
  true,
662
  prototypes::id::SpeechSynthesisEvent,
663
  PrototypeTraits<prototypes::id::SpeechSynthesisEvent>::Depth,
664
  sNativePropertyHooks,
665
  "function SpeechSynthesisEvent() {\n    [native code]\n}",
666
  Event_Binding::GetConstructorObject
667
};
668
669
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
670
  {
671
    "SpeechSynthesisEventPrototype",
672
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE + 1 /* slot for the JSObject holding the unforgeable properties */),
673
    JS_NULL_CLASS_OPS,
674
    JS_NULL_CLASS_SPEC,
675
    JS_NULL_CLASS_EXT,
676
    JS_NULL_OBJECT_OPS
677
  },
678
  eInterfacePrototype,
679
  false,
680
  prototypes::id::SpeechSynthesisEvent,
681
  PrototypeTraits<prototypes::id::SpeechSynthesisEvent>::Depth,
682
  sNativePropertyHooks,
683
  "[object SpeechSynthesisEventPrototype]",
684
  Event_Binding::GetProtoObject
685
};
686
687
bool
688
ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
689
0
{
690
0
  static bool sPrefValue;
691
0
  static bool sPrefCacheSetUp = false;
692
0
  if (!sPrefCacheSetUp) {
693
0
    sPrefCacheSetUp = true;
694
0
    Preferences::AddBoolVarCache(&sPrefValue, "media.webspeech.synth.enabled");
695
0
  }
696
0
697
0
  return sPrefValue;
698
0
}
699
700
static const js::ClassOps sClassOps = {
701
  _addProperty, /* addProperty */
702
  nullptr,               /* delProperty */
703
  nullptr,               /* enumerate */
704
  nullptr, /* newEnumerate */
705
  nullptr, /* resolve */
706
  nullptr, /* mayResolve */
707
  _finalize, /* finalize */
708
  nullptr, /* call */
709
  nullptr,               /* hasInstance */
710
  nullptr,               /* construct */
711
  nullptr, /* trace */
712
};
713
714
static const js::ClassExtension sClassExtension = {
715
  nullptr, /* weakmapKeyDelegateOp */
716
  _objectMoved /* objectMovedOp */
717
};
718
719
static const DOMJSClass sClass = {
720
  { "SpeechSynthesisEvent",
721
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_SKIP_NURSERY_FINALIZE,
722
    &sClassOps,
723
    JS_NULL_CLASS_SPEC,
724
    &sClassExtension,
725
    JS_NULL_OBJECT_OPS
726
  },
727
  { prototypes::id::Event, prototypes::id::SpeechSynthesisEvent, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
728
  IsBaseOf<nsISupports, mozilla::dom::SpeechSynthesisEvent >::value,
729
  sNativePropertyHooks,
730
  FindAssociatedGlobalForNative<mozilla::dom::SpeechSynthesisEvent>::Get,
731
  GetProtoObjectHandle,
732
  GetCCParticipant<mozilla::dom::SpeechSynthesisEvent>::Get()
733
};
734
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
735
              "Must have the right minimal number of reserved slots.");
736
static_assert(1 >= 1,
737
              "Must have enough reserved slots.");
738
739
const JSClass*
740
GetJSClass()
741
0
{
742
0
  return sClass.ToJSClass();
743
0
}
744
745
bool
746
Wrap(JSContext* aCx, mozilla::dom::SpeechSynthesisEvent* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
747
0
{
748
0
  static_assert(!IsBaseOf<NonRefcountedDOMObject, mozilla::dom::SpeechSynthesisEvent>::value,
749
0
                "Shouldn't have wrappercached things that are not refcounted.");
750
0
  MOZ_ASSERT(static_cast<mozilla::dom::SpeechSynthesisEvent*>(aObject) ==
751
0
             reinterpret_cast<mozilla::dom::SpeechSynthesisEvent*>(aObject),
752
0
             "Multiple inheritance for mozilla::dom::SpeechSynthesisEvent is broken.");
753
0
  MOZ_ASSERT(static_cast<mozilla::dom::Event*>(aObject) ==
754
0
             reinterpret_cast<mozilla::dom::Event*>(aObject),
755
0
             "Multiple inheritance for mozilla::dom::Event is broken.");
756
0
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
757
0
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
758
0
  MOZ_ASSERT(!aCache->GetWrapper(),
759
0
             "You should probably not be using Wrap() directly; use "
760
0
             "GetOrCreateDOMReflector instead");
761
0
762
0
  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
763
0
             "nsISupports must be on our primary inheritance chain");
764
0
765
0
  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
766
0
  if (!global) {
767
0
    return false;
768
0
  }
769
0
  MOZ_ASSERT(JS_IsGlobalObject(global));
770
0
  MOZ_ASSERT(JS::ObjectIsNotGray(global));
771
0
772
0
  // That might have ended up wrapping us already, due to the wonders
773
0
  // of XBL.  Check for that, and bail out as needed.
774
0
  aReflector.set(aCache->GetWrapper());
775
0
  if (aReflector) {
776
#ifdef DEBUG
777
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
778
#endif // DEBUG
779
    return true;
780
0
  }
781
0
782
0
  JSAutoRealm ar(aCx, global);
783
0
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
784
0
  if (!canonicalProto) {
785
0
    return false;
786
0
  }
787
0
  JS::Rooted<JSObject*> proto(aCx);
788
0
  if (aGivenProto) {
789
0
    proto = aGivenProto;
790
0
    // Unfortunately, while aGivenProto was in the compartment of aCx
791
0
    // coming in, we changed compartments to that of "parent" so may need
792
0
    // to wrap the proto here.
793
0
    if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
794
0
      if (!JS_WrapObject(aCx, &proto)) {
795
0
        return false;
796
0
      }
797
0
    }
798
0
  } else {
799
0
    proto = canonicalProto;
800
0
  }
801
0
802
0
  BindingJSObjectCreator<mozilla::dom::SpeechSynthesisEvent> creator(aCx);
803
0
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
804
0
  if (!aReflector) {
805
0
    return false;
806
0
  }
807
0
808
0
  aCache->SetWrapper(aReflector);
809
0
810
0
  // Important: do unforgeable property setup after we have handed
811
0
  // over ownership of the C++ object to obj as needed, so that if
812
0
  // we fail and it ends up GCed it won't have problems in the
813
0
  // finalizer trying to drop its ownership of the C++ object.
814
0
  JS::Rooted<JSObject*> unforgeableHolder(aCx,
815
0
    &js::GetReservedSlot(canonicalProto, DOM_INTERFACE_PROTO_SLOTS_BASE).toObject());
816
0
  if (!JS_InitializePropertiesFromCompatibleNativeObject(aCx, aReflector, unforgeableHolder)) {
817
0
    aCache->ReleaseWrapper(aObject);
818
0
    aCache->ClearWrapper();
819
0
    return false;
820
0
  }
821
0
  creator.InitializationSucceeded();
822
0
823
0
  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
824
0
             aCache->GetWrapperPreserveColor() == aReflector);
825
0
  // If proto != canonicalProto, we have to preserve our wrapper;
826
0
  // otherwise we won't be able to properly recreate it later, since
827
0
  // we won't know what proto to use.  Note that we don't check
828
0
  // aGivenProto here, since it's entirely possible (and even
829
0
  // somewhat common) to have a non-null aGivenProto which is the
830
0
  // same as canonicalProto.
831
0
  if (proto != canonicalProto) {
832
0
    PreserveWrapper(aObject);
833
0
  }
834
0
835
0
  return true;
836
0
}
837
838
const NativePropertyHooks sNativePropertyHooks[] = { {
839
  nullptr,
840
  nullptr,
841
  nullptr,
842
  { sNativeProperties.Upcast(), nullptr },
843
  prototypes::id::SpeechSynthesisEvent,
844
  constructors::id::SpeechSynthesisEvent,
845
  Event_Binding::sNativePropertyHooks,
846
  &DefaultXrayExpandoObjectClass
847
} };
848
849
void
850
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
851
0
{
852
0
  JS::Handle<JSObject*> parentProto(Event_Binding::GetProtoObjectHandle(aCx));
853
0
  if (!parentProto) {
854
0
    return;
855
0
  }
856
0
857
0
  JS::Handle<JSObject*> constructorProto(Event_Binding::GetConstructorObjectHandle(aCx));
858
0
  if (!constructorProto) {
859
0
    return;
860
0
  }
861
0
862
0
  static bool sIdsInited = false;
863
0
  if (!sIdsInited && NS_IsMainThread()) {
864
0
    if (!InitIds(aCx, sNativeProperties.Upcast())) {
865
0
      return;
866
0
    }
867
0
    sIdsInited = true;
868
0
  }
869
0
870
0
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::SpeechSynthesisEvent);
871
0
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::SpeechSynthesisEvent);
872
0
  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
873
0
                              &sPrototypeClass.mBase, protoCache,
874
0
                              nullptr,
875
0
                              constructorProto, &sInterfaceObjectClass.mBase, 2, nullptr,
876
0
                              interfaceCache,
877
0
                              sNativeProperties.Upcast(),
878
0
                              nullptr,
879
0
                              "SpeechSynthesisEvent", aDefineOnGlobal,
880
0
                              nullptr,
881
0
                              false);
882
0
883
0
  JS::Rooted<JSObject*> unforgeableHolder(aCx);
884
0
  {
885
0
    JS::Rooted<JSObject*> holderProto(aCx, *protoCache);
886
0
    unforgeableHolder = JS_NewObjectWithoutMetadata(aCx, sClass.ToJSClass(), holderProto);
887
0
    if (!unforgeableHolder) {
888
0
      *protoCache = nullptr;
889
0
      if (interfaceCache) {
890
0
        *interfaceCache = nullptr;
891
0
      }
892
0
      return;
893
0
    }
894
0
  }
895
0
896
0
  if (!DefineUnforgeableAttributes(aCx, unforgeableHolder, sUnforgeableAttributes)) {
897
0
    *protoCache = nullptr;
898
0
    if (interfaceCache) {
899
0
      *interfaceCache = nullptr;
900
0
    }
901
0
    return;
902
0
  }
903
0
904
0
  if (*protoCache) {
905
0
    js::SetReservedSlot(*protoCache, DOM_INTERFACE_PROTO_SLOTS_BASE,
906
0
                        JS::ObjectValue(*unforgeableHolder));
907
0
  }
908
0
}
909
910
JSObject*
911
GetProtoObject(JSContext* aCx)
912
0
{
913
0
  return GetProtoObjectHandle(aCx);
914
0
}
915
916
JSObject*
917
GetConstructorObject(JSContext* aCx)
918
0
{
919
0
  return GetConstructorObjectHandle(aCx);
920
0
}
921
922
} // namespace SpeechSynthesisEvent_Binding
923
924
925
926
} // namespace dom
927
} // namespace mozilla