Line data Source code
1 : /* THIS FILE IS AUTOGENERATED FROM Clients.webidl BY Codegen.py - DO NOT EDIT */
2 :
3 : #include "AtomList.h"
4 : #include "ClientsBinding.h"
5 : #include "WrapperFactory.h"
6 : #include "jsapi.h"
7 : #include "mozilla/OwningNonNull.h"
8 : #include "mozilla/dom/BindingUtils.h"
9 : #include "mozilla/dom/DOMJSClass.h"
10 : #include "mozilla/dom/NonRefcountedDOMObject.h"
11 : #include "mozilla/dom/PrimitiveConversions.h"
12 : #include "mozilla/dom/Promise.h"
13 : #include "mozilla/dom/ScriptSettings.h"
14 : #include "mozilla/dom/SimpleGlobalObject.h"
15 : #include "mozilla/dom/ToJSValue.h"
16 : #include "mozilla/dom/workers/bindings/ServiceWorkerClients.h"
17 : #include "nsThreadUtils.h"
18 :
19 : namespace mozilla {
20 : namespace dom {
21 :
22 : namespace ClientTypeValues {
23 : extern const EnumEntry strings[5] = {
24 : {"window", 6},
25 : {"worker", 6},
26 : {"sharedworker", 12},
27 : {"all", 3},
28 : { nullptr, 0 }
29 : };
30 : } // namespace ClientTypeValues
31 :
32 : bool
33 0 : ToJSValue(JSContext* aCx, ClientType aArgument, JS::MutableHandle<JS::Value> aValue)
34 : {
35 0 : MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(ClientTypeValues::strings));
36 : JSString* resultStr =
37 0 : JS_NewStringCopyN(aCx, ClientTypeValues::strings[uint32_t(aArgument)].value,
38 0 : ClientTypeValues::strings[uint32_t(aArgument)].length);
39 0 : if (!resultStr) {
40 0 : return false;
41 : }
42 0 : aValue.setString(resultStr);
43 0 : return true;
44 : }
45 :
46 :
47 :
48 0 : ClientQueryOptions::ClientQueryOptions()
49 : {
50 : // Safe to pass a null context if we pass a null value
51 0 : Init(nullptr, JS::NullHandleValue);
52 0 : }
53 :
54 :
55 :
56 : bool
57 0 : ClientQueryOptions::InitIds(JSContext* cx, ClientQueryOptionsAtoms* atomsCache)
58 : {
59 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
60 :
61 : // Initialize these in reverse order so that any failure leaves the first one
62 : // uninitialized.
63 0 : if (!atomsCache->type_id.init(cx, "type") ||
64 0 : !atomsCache->includeUncontrolled_id.init(cx, "includeUncontrolled")) {
65 0 : return false;
66 : }
67 0 : return true;
68 : }
69 :
70 : bool
71 0 : ClientQueryOptions::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
72 : {
73 : // Passing a null JSContext is OK only if we're initing from null,
74 : // Since in that case we will not have to do any property gets
75 : // Also evaluate isNullOrUndefined in order to avoid false-positive
76 : // checkers by static analysis tools
77 0 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
78 0 : ClientQueryOptionsAtoms* atomsCache = nullptr;
79 0 : if (cx) {
80 0 : atomsCache = GetAtomCache<ClientQueryOptionsAtoms>(cx);
81 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
82 0 : return false;
83 : }
84 : }
85 :
86 0 : if (!IsConvertibleToDictionary(val)) {
87 0 : return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
88 : }
89 :
90 0 : bool isNull = val.isNullOrUndefined();
91 : // We only need these if !isNull, in which case we have |cx|.
92 0 : Maybe<JS::Rooted<JSObject *> > object;
93 0 : Maybe<JS::Rooted<JS::Value> > temp;
94 0 : if (!isNull) {
95 0 : MOZ_ASSERT(cx);
96 0 : object.emplace(cx, &val.toObject());
97 0 : temp.emplace(cx);
98 : }
99 0 : if (!isNull) {
100 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->includeUncontrolled_id, temp.ptr())) {
101 0 : return false;
102 : }
103 : }
104 0 : if (!isNull && !temp->isUndefined()) {
105 0 : if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &mIncludeUncontrolled)) {
106 0 : return false;
107 : }
108 : } else {
109 0 : mIncludeUncontrolled = false;
110 : }
111 0 : mIsAnyMemberPresent = true;
112 :
113 0 : if (!isNull) {
114 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->type_id, temp.ptr())) {
115 0 : return false;
116 : }
117 : }
118 0 : if (!isNull && !temp->isUndefined()) {
119 : {
120 : int index;
121 0 : if (!FindEnumStringIndex<true>(cx, temp.ref(), ClientTypeValues::strings, "ClientType", "'type' member of ClientQueryOptions", &index)) {
122 0 : return false;
123 : }
124 0 : MOZ_ASSERT(index >= 0);
125 0 : mType = static_cast<ClientType>(index);
126 : }
127 : } else {
128 0 : mType = ClientType::Window;
129 : }
130 0 : mIsAnyMemberPresent = true;
131 0 : return true;
132 : }
133 :
134 : bool
135 0 : ClientQueryOptions::Init(const nsAString& aJSON)
136 : {
137 0 : AutoJSAPI jsapi;
138 0 : JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
139 0 : if (!cleanGlobal) {
140 0 : return false;
141 : }
142 0 : if (!jsapi.Init(cleanGlobal)) {
143 0 : return false;
144 : }
145 0 : JSContext* cx = jsapi.cx();
146 0 : JS::Rooted<JS::Value> json(cx);
147 0 : bool ok = ParseJSON(cx, aJSON, &json);
148 0 : NS_ENSURE_TRUE(ok, false);
149 0 : return Init(cx, json);
150 : }
151 :
152 : bool
153 0 : ClientQueryOptions::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
154 : {
155 0 : ClientQueryOptionsAtoms* atomsCache = GetAtomCache<ClientQueryOptionsAtoms>(cx);
156 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
157 0 : return false;
158 : }
159 :
160 0 : JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
161 0 : if (!obj) {
162 0 : return false;
163 : }
164 0 : rval.set(JS::ObjectValue(*obj));
165 :
166 : do {
167 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
168 0 : JS::Rooted<JS::Value> temp(cx);
169 0 : bool const & currentValue = mIncludeUncontrolled;
170 0 : temp.setBoolean(currentValue);
171 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->includeUncontrolled_id, temp, JSPROP_ENUMERATE)) {
172 0 : return false;
173 : }
174 0 : break;
175 : } while(0);
176 :
177 : do {
178 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
179 0 : JS::Rooted<JS::Value> temp(cx);
180 0 : ClientType const & currentValue = mType;
181 0 : if (!ToJSValue(cx, currentValue, &temp)) {
182 0 : return false;
183 : }
184 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->type_id, temp, JSPROP_ENUMERATE)) {
185 0 : return false;
186 : }
187 0 : break;
188 : } while(0);
189 :
190 0 : return true;
191 : }
192 :
193 : bool
194 0 : ClientQueryOptions::ToJSON(nsAString& aJSON) const
195 : {
196 0 : AutoJSAPI jsapi;
197 0 : jsapi.Init();
198 0 : JSContext *cx = jsapi.cx();
199 : // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
200 : // because we'll only be creating objects, in ways that have no
201 : // side-effects, followed by a call to JS::ToJSONMaybeSafely,
202 : // which likewise guarantees no side-effects for the sorts of
203 : // things we will pass it.
204 0 : JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
205 0 : JS::Rooted<JS::Value> val(cx);
206 0 : if (!ToObjectInternal(cx, &val)) {
207 0 : return false;
208 : }
209 0 : JS::Rooted<JSObject*> obj(cx, &val.toObject());
210 0 : return StringifyToJSON(cx, obj, aJSON);
211 : }
212 :
213 : void
214 0 : ClientQueryOptions::TraceDictionary(JSTracer* trc)
215 : {
216 0 : }
217 :
218 : ClientQueryOptions&
219 0 : ClientQueryOptions::operator=(const ClientQueryOptions& aOther)
220 : {
221 0 : mIncludeUncontrolled = aOther.mIncludeUncontrolled;
222 0 : mType = aOther.mType;
223 0 : return *this;
224 : }
225 :
226 : namespace binding_detail {
227 : } // namespace binding_detail
228 :
229 :
230 : namespace ClientsBinding {
231 :
232 : static bool
233 0 : get(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::workers::ServiceWorkerClients* self, const JSJitMethodCallArgs& args)
234 : {
235 0 : if (MOZ_UNLIKELY(args.length() < 1)) {
236 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "Clients.get");
237 : }
238 0 : binding_detail::FakeString arg0;
239 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
240 0 : return false;
241 : }
242 0 : binding_detail::FastErrorResult rv;
243 0 : auto result(StrongOrRawPtr<Promise>(self->Get(NonNullHelper(Constify(arg0)), rv)));
244 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
245 0 : return false;
246 : }
247 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
248 : static_assert(!IsPointer<decltype(result)>::value,
249 : "NewObject implies that we need to keep the object alive with a strong reference.");
250 0 : if (!ToJSValue(cx, result, args.rval())) {
251 0 : return false;
252 : }
253 0 : return true;
254 : }
255 :
256 : static bool
257 0 : get_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::workers::ServiceWorkerClients* self, const JSJitMethodCallArgs& args)
258 : {
259 : // Make sure to save the callee before someone maybe messes
260 : // with rval().
261 0 : JS::Rooted<JSObject*> callee(cx, &args.callee());
262 0 : bool ok = get(cx, obj, self, args);
263 0 : if (ok) {
264 0 : return true;
265 : }
266 0 : return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
267 0 : args.rval());
268 : }
269 :
270 : static const JSJitInfo get_methodinfo = {
271 : { (JSJitGetterOp)get_promiseWrapper },
272 : { prototypes::id::Clients },
273 : { PrototypeTraits<prototypes::id::Clients>::Depth },
274 : JSJitInfo::Method,
275 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
276 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
277 : false, /* isInfallible. False in setters. */
278 : false, /* isMovable. Not relevant for setters. */
279 : false, /* isEliminatable. Not relevant for setters. */
280 : false, /* isAlwaysInSlot. Only relevant for getters. */
281 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
282 : false, /* isTypedMethod. Only relevant for methods. */
283 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
284 : };
285 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
286 : static_assert(0 < 1, "There is no slot for us");
287 :
288 : static bool
289 0 : matchAll(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::workers::ServiceWorkerClients* self, const JSJitMethodCallArgs& args)
290 : {
291 0 : binding_detail::FastClientQueryOptions arg0;
292 0 : if (!arg0.Init(cx, (args.hasDefined(0)) ? args[0] : JS::NullHandleValue, "Argument 1 of Clients.matchAll", false)) {
293 0 : return false;
294 : }
295 0 : binding_detail::FastErrorResult rv;
296 0 : auto result(StrongOrRawPtr<Promise>(self->MatchAll(Constify(arg0), rv)));
297 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
298 0 : return false;
299 : }
300 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
301 : static_assert(!IsPointer<decltype(result)>::value,
302 : "NewObject implies that we need to keep the object alive with a strong reference.");
303 0 : if (!ToJSValue(cx, result, args.rval())) {
304 0 : return false;
305 : }
306 0 : return true;
307 : }
308 :
309 : static bool
310 0 : matchAll_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::workers::ServiceWorkerClients* self, const JSJitMethodCallArgs& args)
311 : {
312 : // Make sure to save the callee before someone maybe messes
313 : // with rval().
314 0 : JS::Rooted<JSObject*> callee(cx, &args.callee());
315 0 : bool ok = matchAll(cx, obj, self, args);
316 0 : if (ok) {
317 0 : return true;
318 : }
319 0 : return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
320 0 : args.rval());
321 : }
322 :
323 : static const JSJitInfo matchAll_methodinfo = {
324 : { (JSJitGetterOp)matchAll_promiseWrapper },
325 : { prototypes::id::Clients },
326 : { PrototypeTraits<prototypes::id::Clients>::Depth },
327 : JSJitInfo::Method,
328 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
329 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
330 : false, /* isInfallible. False in setters. */
331 : false, /* isMovable. Not relevant for setters. */
332 : false, /* isEliminatable. Not relevant for setters. */
333 : false, /* isAlwaysInSlot. Only relevant for getters. */
334 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
335 : false, /* isTypedMethod. Only relevant for methods. */
336 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
337 : };
338 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
339 : static_assert(0 < 1, "There is no slot for us");
340 :
341 : static bool
342 0 : openWindow(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::workers::ServiceWorkerClients* self, const JSJitMethodCallArgs& args)
343 : {
344 0 : if (MOZ_UNLIKELY(args.length() < 1)) {
345 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "Clients.openWindow");
346 : }
347 0 : binding_detail::FakeString arg0;
348 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
349 0 : return false;
350 : }
351 0 : NormalizeUSVString(arg0);
352 0 : binding_detail::FastErrorResult rv;
353 0 : auto result(StrongOrRawPtr<Promise>(self->OpenWindow(Constify(arg0), rv)));
354 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
355 0 : return false;
356 : }
357 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
358 : static_assert(!IsPointer<decltype(result)>::value,
359 : "NewObject implies that we need to keep the object alive with a strong reference.");
360 0 : if (!ToJSValue(cx, result, args.rval())) {
361 0 : return false;
362 : }
363 0 : return true;
364 : }
365 :
366 : static bool
367 0 : openWindow_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::workers::ServiceWorkerClients* self, const JSJitMethodCallArgs& args)
368 : {
369 : // Make sure to save the callee before someone maybe messes
370 : // with rval().
371 0 : JS::Rooted<JSObject*> callee(cx, &args.callee());
372 0 : bool ok = openWindow(cx, obj, self, args);
373 0 : if (ok) {
374 0 : return true;
375 : }
376 0 : return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
377 0 : args.rval());
378 : }
379 :
380 : static const JSJitInfo openWindow_methodinfo = {
381 : { (JSJitGetterOp)openWindow_promiseWrapper },
382 : { prototypes::id::Clients },
383 : { PrototypeTraits<prototypes::id::Clients>::Depth },
384 : JSJitInfo::Method,
385 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
386 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
387 : false, /* isInfallible. False in setters. */
388 : false, /* isMovable. Not relevant for setters. */
389 : false, /* isEliminatable. Not relevant for setters. */
390 : false, /* isAlwaysInSlot. Only relevant for getters. */
391 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
392 : false, /* isTypedMethod. Only relevant for methods. */
393 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
394 : };
395 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
396 : static_assert(0 < 1, "There is no slot for us");
397 :
398 : static bool
399 0 : claim(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::workers::ServiceWorkerClients* self, const JSJitMethodCallArgs& args)
400 : {
401 0 : binding_detail::FastErrorResult rv;
402 0 : auto result(StrongOrRawPtr<Promise>(self->Claim(rv)));
403 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
404 0 : return false;
405 : }
406 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
407 : static_assert(!IsPointer<decltype(result)>::value,
408 : "NewObject implies that we need to keep the object alive with a strong reference.");
409 0 : if (!ToJSValue(cx, result, args.rval())) {
410 0 : return false;
411 : }
412 0 : return true;
413 : }
414 :
415 : static bool
416 0 : claim_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::workers::ServiceWorkerClients* self, const JSJitMethodCallArgs& args)
417 : {
418 : // Make sure to save the callee before someone maybe messes
419 : // with rval().
420 0 : JS::Rooted<JSObject*> callee(cx, &args.callee());
421 0 : bool ok = claim(cx, obj, self, args);
422 0 : if (ok) {
423 0 : return true;
424 : }
425 0 : return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
426 0 : args.rval());
427 : }
428 :
429 : static const JSJitInfo claim_methodinfo = {
430 : { (JSJitGetterOp)claim_promiseWrapper },
431 : { prototypes::id::Clients },
432 : { PrototypeTraits<prototypes::id::Clients>::Depth },
433 : JSJitInfo::Method,
434 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
435 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
436 : false, /* isInfallible. False in setters. */
437 : false, /* isMovable. Not relevant for setters. */
438 : false, /* isEliminatable. Not relevant for setters. */
439 : false, /* isAlwaysInSlot. Only relevant for getters. */
440 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
441 : false, /* isTypedMethod. Only relevant for methods. */
442 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
443 : };
444 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
445 : static_assert(0 < 1, "There is no slot for us");
446 :
447 : static bool
448 0 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
449 : {
450 0 : mozilla::dom::workers::ServiceWorkerClients* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::workers::ServiceWorkerClients>(obj);
451 : // We don't want to preserve if we don't have a wrapper, and we
452 : // obviously can't preserve if we're not initialized.
453 0 : if (self && self->GetWrapperPreserveColor()) {
454 0 : PreserveWrapper(self);
455 : }
456 0 : return true;
457 : }
458 :
459 : static void
460 0 : _finalize(js::FreeOp* fop, JSObject* obj)
461 : {
462 0 : mozilla::dom::workers::ServiceWorkerClients* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::workers::ServiceWorkerClients>(obj);
463 0 : if (self) {
464 0 : ClearWrapper(self, self, obj);
465 0 : AddForDeferredFinalization<mozilla::dom::workers::ServiceWorkerClients>(self);
466 : }
467 0 : }
468 :
469 : static void
470 0 : _objectMoved(JSObject* obj, const JSObject* old)
471 : {
472 0 : mozilla::dom::workers::ServiceWorkerClients* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::workers::ServiceWorkerClients>(obj);
473 0 : if (self) {
474 0 : UpdateWrapper(self, self, obj, old);
475 : }
476 0 : }
477 :
478 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
479 : #if defined(__clang__)
480 : #pragma clang diagnostic push
481 : #pragma clang diagnostic ignored "-Wmissing-braces"
482 : #endif
483 : static const JSFunctionSpec sMethods_specs[] = {
484 : JS_FNSPEC("get", GenericPromiseReturningBindingMethod, reinterpret_cast<const JSJitInfo*>(&get_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
485 : JS_FNSPEC("matchAll", GenericPromiseReturningBindingMethod, reinterpret_cast<const JSJitInfo*>(&matchAll_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
486 : JS_FS_END,
487 : JS_FNSPEC("openWindow", GenericPromiseReturningBindingMethod, reinterpret_cast<const JSJitInfo*>(&openWindow_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
488 : JS_FS_END,
489 : JS_FNSPEC("claim", GenericPromiseReturningBindingMethod, reinterpret_cast<const JSJitInfo*>(&claim_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
490 : JS_FS_END
491 : };
492 : #if defined(__clang__)
493 : #pragma clang diagnostic pop
494 : #endif
495 :
496 : static PrefableDisablers sMethods_disablers3 = {
497 : true, false, 0, &mozilla::dom::ServiceWorkerGlobalScope::OpenWindowEnabled
498 : };
499 :
500 : // Can't be const because the pref-enabled boolean needs to be writable
501 : static Prefable<const JSFunctionSpec> sMethods[] = {
502 : { nullptr, &sMethods_specs[0] },
503 : { &sMethods_disablers3, &sMethods_specs[3] },
504 : { nullptr, &sMethods_specs[5] },
505 : { nullptr, nullptr }
506 : };
507 :
508 :
509 : static const NativePropertiesN<1> sNativeProperties = {
510 : false, 0,
511 : false, 0,
512 : true, 0 /* sMethods */,
513 : false, 0,
514 : false, 0,
515 : false, 0,
516 : false, 0,
517 : -1,
518 : 0,
519 : nullptr,
520 : {
521 : { sMethods, nullptr }
522 : }
523 : };
524 :
525 : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
526 : {
527 : "Function",
528 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
529 : &sBoringInterfaceObjectClassClassOps,
530 : JS_NULL_CLASS_SPEC,
531 : JS_NULL_CLASS_EXT,
532 : &sInterfaceObjectClassObjectOps
533 : },
534 : eInterface,
535 : true,
536 : prototypes::id::Clients,
537 : PrototypeTraits<prototypes::id::Clients>::Depth,
538 : &sEmptyNativePropertyHooks,
539 : "function Clients() {\n [native code]\n}",
540 : JS::GetRealmFunctionPrototype
541 : };
542 :
543 : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
544 : {
545 : "ClientsPrototype",
546 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
547 : JS_NULL_CLASS_OPS,
548 : JS_NULL_CLASS_SPEC,
549 : JS_NULL_CLASS_EXT,
550 : JS_NULL_OBJECT_OPS
551 : },
552 : eInterfacePrototype,
553 : false,
554 : prototypes::id::Clients,
555 : PrototypeTraits<prototypes::id::Clients>::Depth,
556 : &sEmptyNativePropertyHooks,
557 : "[object ClientsPrototype]",
558 : JS::GetRealmObjectPrototype
559 : };
560 :
561 : bool
562 1 : ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
563 : {
564 1 : MOZ_ASSERT(!NS_IsMainThread(), "Why did we even get called?");
565 :
566 1 : const char* name = js::GetObjectClass(aObj)->name;
567 1 : if (strcmp(name, "ServiceWorkerGlobalScope")) {
568 1 : return false;
569 : }
570 :
571 0 : return true;
572 : }
573 :
574 : static const js::ClassOps sClassOps = {
575 : _addProperty, /* addProperty */
576 : nullptr, /* delProperty */
577 : nullptr, /* getProperty */
578 : nullptr, /* setProperty */
579 : nullptr, /* enumerate */
580 : nullptr, /* newEnumerate */
581 : nullptr, /* resolve */
582 : nullptr, /* mayResolve */
583 : _finalize, /* finalize */
584 : nullptr, /* call */
585 : nullptr, /* hasInstance */
586 : nullptr, /* construct */
587 : nullptr, /* trace */
588 : };
589 :
590 : static const js::ClassExtension sClassExtension = {
591 : nullptr, /* weakmapKeyDelegateOp */
592 : _objectMoved /* objectMovedOp */
593 : };
594 :
595 : static const DOMJSClass sClass = {
596 : { "Clients",
597 : JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
598 : &sClassOps,
599 : JS_NULL_CLASS_SPEC,
600 : &sClassExtension,
601 : JS_NULL_OBJECT_OPS
602 : },
603 : { prototypes::id::Clients, 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 },
604 : IsBaseOf<nsISupports, mozilla::dom::workers::ServiceWorkerClients >::value,
605 : &sEmptyNativePropertyHooks,
606 : FindAssociatedGlobalForNative<mozilla::dom::workers::ServiceWorkerClients>::Get,
607 : GetProtoObjectHandle,
608 : GetCCParticipant<mozilla::dom::workers::ServiceWorkerClients>::Get()
609 : };
610 : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
611 : "Must have the right minimal number of reserved slots.");
612 : static_assert(1 >= 1,
613 : "Must have enough reserved slots.");
614 :
615 : const JSClass*
616 0 : GetJSClass()
617 : {
618 0 : return sClass.ToJSClass();
619 : }
620 :
621 : bool
622 0 : Wrap(JSContext* aCx, mozilla::dom::workers::ServiceWorkerClients* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
623 : {
624 : MOZ_ASSERT(static_cast<mozilla::dom::workers::ServiceWorkerClients*>(aObject) ==
625 : reinterpret_cast<mozilla::dom::workers::ServiceWorkerClients*>(aObject),
626 : "Multiple inheritance for mozilla::dom::workers::ServiceWorkerClients is broken.");
627 0 : MOZ_ASSERT(ToSupportsIsCorrect(aObject));
628 0 : MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
629 0 : MOZ_ASSERT(!aCache->GetWrapper(),
630 : "You should probably not be using Wrap() directly; use "
631 : "GetOrCreateDOMReflector instead");
632 :
633 0 : MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
634 : "nsISupports must be on our primary inheritance chain");
635 :
636 0 : JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
637 0 : if (!global) {
638 0 : return false;
639 : }
640 0 : MOZ_ASSERT(JS_IsGlobalObject(global));
641 0 : MOZ_ASSERT(JS::ObjectIsNotGray(global));
642 :
643 : // That might have ended up wrapping us already, due to the wonders
644 : // of XBL. Check for that, and bail out as needed.
645 0 : aReflector.set(aCache->GetWrapper());
646 0 : if (aReflector) {
647 : #ifdef DEBUG
648 0 : binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
649 : #endif // DEBUG
650 0 : return true;
651 : }
652 :
653 0 : JSAutoCompartment ac(aCx, global);
654 0 : JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
655 0 : if (!canonicalProto) {
656 0 : return false;
657 : }
658 0 : JS::Rooted<JSObject*> proto(aCx);
659 0 : if (aGivenProto) {
660 0 : proto = aGivenProto;
661 : // Unfortunately, while aGivenProto was in the compartment of aCx
662 : // coming in, we changed compartments to that of "parent" so may need
663 : // to wrap the proto here.
664 0 : if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
665 0 : if (!JS_WrapObject(aCx, &proto)) {
666 0 : return false;
667 : }
668 : }
669 : } else {
670 0 : proto = canonicalProto;
671 : }
672 :
673 0 : BindingJSObjectCreator<mozilla::dom::workers::ServiceWorkerClients> creator(aCx);
674 0 : creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
675 0 : if (!aReflector) {
676 0 : return false;
677 : }
678 :
679 0 : aCache->SetWrapper(aReflector);
680 0 : creator.InitializationSucceeded();
681 :
682 0 : MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
683 : aCache->GetWrapperPreserveColor() == aReflector);
684 : // If proto != canonicalProto, we have to preserve our wrapper;
685 : // otherwise we won't be able to properly recreate it later, since
686 : // we won't know what proto to use. Note that we don't check
687 : // aGivenProto here, since it's entirely possible (and even
688 : // somewhat common) to have a non-null aGivenProto which is the
689 : // same as canonicalProto.
690 0 : if (proto != canonicalProto) {
691 0 : PreserveWrapper(aObject);
692 : }
693 :
694 0 : return true;
695 : }
696 :
697 : void
698 0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
699 : {
700 0 : JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
701 0 : if (!parentProto) {
702 0 : return;
703 : }
704 :
705 0 : JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
706 0 : if (!constructorProto) {
707 0 : return;
708 : }
709 :
710 0 : JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::Clients);
711 0 : JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::Clients);
712 0 : dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
713 : &sPrototypeClass.mBase, protoCache,
714 : constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
715 : interfaceCache,
716 : sNativeProperties.Upcast(),
717 : nullptr,
718 : "Clients", aDefineOnGlobal,
719 : nullptr,
720 0 : false);
721 : }
722 :
723 : JS::Handle<JSObject*>
724 0 : GetProtoObjectHandle(JSContext* aCx)
725 : {
726 : /* Get the interface prototype object for this class. This will create the
727 : object as needed. */
728 0 : bool aDefineOnGlobal = true;
729 :
730 : /* Make sure our global is sane. Hopefully we can remove this sometime */
731 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
732 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
733 0 : return nullptr;
734 : }
735 :
736 : /* Check to see whether the interface objects are already installed */
737 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
738 0 : if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::Clients)) {
739 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
740 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
741 : }
742 :
743 : /*
744 : * The object might _still_ be null, but that's OK.
745 : *
746 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
747 : * traced by TraceProtoAndIfaceCache() and its contents are never
748 : * changed after they have been set.
749 : *
750 : * Calling address() avoids the read read barrier that does gray
751 : * unmarking, but it's not possible for the object to be gray here.
752 : */
753 :
754 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::Clients);
755 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
756 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
757 : }
758 :
759 : JS::Handle<JSObject*>
760 0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
761 : {
762 : /* Get the interface object for this class. This will create the object as
763 : needed. */
764 :
765 : /* Make sure our global is sane. Hopefully we can remove this sometime */
766 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
767 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
768 0 : return nullptr;
769 : }
770 :
771 : /* Check to see whether the interface objects are already installed */
772 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
773 0 : if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::Clients)) {
774 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
775 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
776 : }
777 :
778 : /*
779 : * The object might _still_ be null, but that's OK.
780 : *
781 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
782 : * traced by TraceProtoAndIfaceCache() and its contents are never
783 : * changed after they have been set.
784 : *
785 : * Calling address() avoids the read read barrier that does gray
786 : * unmarking, but it's not possible for the object to be gray here.
787 : */
788 :
789 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::Clients);
790 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
791 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
792 : }
793 :
794 : JSObject*
795 0 : GetConstructorObject(JSContext* aCx)
796 : {
797 0 : return GetConstructorObjectHandle(aCx);
798 : }
799 :
800 : } // namespace ClientsBinding
801 :
802 :
803 :
804 : } // namespace dom
805 : } // namespace mozilla
|