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