Line data Source code
1 : /* THIS FILE IS AUTOGENERATED FROM Client.webidl BY Codegen.py - DO NOT EDIT */
2 :
3 : #include "ClientBinding.h"
4 : #include "WrapperFactory.h"
5 : #include "jsapi.h"
6 : #include "mozilla/OwningNonNull.h"
7 : #include "mozilla/dom/BindingUtils.h"
8 : #include "mozilla/dom/DOMJSClass.h"
9 : #include "mozilla/dom/NonRefcountedDOMObject.h"
10 : #include "mozilla/dom/PrimitiveConversions.h"
11 : #include "mozilla/dom/Promise.h"
12 : #include "mozilla/dom/ToJSValue.h"
13 : #include "mozilla/dom/workers/bindings/ServiceWorkerClient.h"
14 : #include "mozilla/dom/workers/bindings/ServiceWorkerWindowClient.h"
15 : #include "nsThreadUtils.h"
16 :
17 : namespace mozilla {
18 : namespace dom {
19 :
20 : namespace FrameTypeValues {
21 : extern const EnumEntry strings[5] = {
22 : {"auxiliary", 9},
23 : {"top-level", 9},
24 : {"nested", 6},
25 : {"none", 4},
26 : { nullptr, 0 }
27 : };
28 : } // namespace FrameTypeValues
29 :
30 : bool
31 0 : ToJSValue(JSContext* aCx, FrameType aArgument, JS::MutableHandle<JS::Value> aValue)
32 : {
33 0 : MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(FrameTypeValues::strings));
34 : JSString* resultStr =
35 0 : JS_NewStringCopyN(aCx, FrameTypeValues::strings[uint32_t(aArgument)].value,
36 0 : FrameTypeValues::strings[uint32_t(aArgument)].length);
37 0 : if (!resultStr) {
38 0 : return false;
39 : }
40 0 : aValue.setString(resultStr);
41 0 : return true;
42 : }
43 :
44 :
45 : namespace ClientBinding {
46 :
47 : static bool
48 0 : get_url(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::workers::ServiceWorkerClient* self, JSJitGetterCallArgs args)
49 : {
50 0 : DOMString result;
51 0 : self->GetUrl(result);
52 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
53 0 : if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
54 0 : return false;
55 : }
56 0 : return true;
57 : }
58 :
59 : static const JSJitInfo url_getterinfo = {
60 : { (JSJitGetterOp)get_url },
61 : { prototypes::id::Client },
62 : { PrototypeTraits<prototypes::id::Client>::Depth },
63 : JSJitInfo::Getter,
64 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
65 : JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
66 : false, /* isInfallible. False in setters. */
67 : false, /* isMovable. Not relevant for setters. */
68 : false, /* isEliminatable. Not relevant for setters. */
69 : false, /* isAlwaysInSlot. Only relevant for getters. */
70 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
71 : false, /* isTypedMethod. Only relevant for methods. */
72 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
73 : };
74 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
75 : static_assert(0 < 1, "There is no slot for us");
76 :
77 : static bool
78 0 : get_frameType(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::workers::ServiceWorkerClient* self, JSJitGetterCallArgs args)
79 : {
80 0 : FrameType result(self->FrameType());
81 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
82 0 : if (!ToJSValue(cx, result, args.rval())) {
83 0 : return false;
84 : }
85 0 : return true;
86 : }
87 :
88 : static const JSJitInfo frameType_getterinfo = {
89 : { (JSJitGetterOp)get_frameType },
90 : { prototypes::id::Client },
91 : { PrototypeTraits<prototypes::id::Client>::Depth },
92 : JSJitInfo::Getter,
93 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
94 : JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
95 : false, /* isInfallible. False in setters. */
96 : false, /* isMovable. Not relevant for setters. */
97 : false, /* isEliminatable. Not relevant for setters. */
98 : false, /* isAlwaysInSlot. Only relevant for getters. */
99 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
100 : false, /* isTypedMethod. Only relevant for methods. */
101 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
102 : };
103 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
104 : static_assert(0 < 1, "There is no slot for us");
105 :
106 : static bool
107 0 : get_type(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::workers::ServiceWorkerClient* self, JSJitGetterCallArgs args)
108 : {
109 0 : ClientType result(self->Type());
110 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
111 0 : if (!ToJSValue(cx, result, args.rval())) {
112 0 : return false;
113 : }
114 0 : return true;
115 : }
116 :
117 : static const JSJitInfo type_getterinfo = {
118 : { (JSJitGetterOp)get_type },
119 : { prototypes::id::Client },
120 : { PrototypeTraits<prototypes::id::Client>::Depth },
121 : JSJitInfo::Getter,
122 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
123 : JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
124 : false, /* isInfallible. False in setters. */
125 : false, /* isMovable. Not relevant for setters. */
126 : false, /* isEliminatable. Not relevant for setters. */
127 : false, /* isAlwaysInSlot. Only relevant for getters. */
128 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
129 : false, /* isTypedMethod. Only relevant for methods. */
130 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
131 : };
132 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
133 : static_assert(0 < 1, "There is no slot for us");
134 :
135 : static bool
136 0 : get_id(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::workers::ServiceWorkerClient* self, JSJitGetterCallArgs args)
137 : {
138 0 : DOMString result;
139 0 : self->GetId(result);
140 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
141 0 : if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
142 0 : return false;
143 : }
144 0 : return true;
145 : }
146 :
147 : static const JSJitInfo id_getterinfo = {
148 : { (JSJitGetterOp)get_id },
149 : { prototypes::id::Client },
150 : { PrototypeTraits<prototypes::id::Client>::Depth },
151 : JSJitInfo::Getter,
152 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
153 : JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
154 : false, /* isInfallible. False in setters. */
155 : false, /* isMovable. Not relevant for setters. */
156 : false, /* isEliminatable. Not relevant for setters. */
157 : false, /* isAlwaysInSlot. Only relevant for getters. */
158 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
159 : false, /* isTypedMethod. Only relevant for methods. */
160 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
161 : };
162 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
163 : static_assert(0 < 1, "There is no slot for us");
164 :
165 : static bool
166 0 : postMessage(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::workers::ServiceWorkerClient* self, const JSJitMethodCallArgs& args)
167 : {
168 0 : if (MOZ_UNLIKELY(args.length() < 1)) {
169 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "Client.postMessage");
170 : }
171 0 : JS::Rooted<JS::Value> arg0(cx);
172 0 : arg0 = args[0];
173 0 : binding_detail::AutoSequence<JSObject*> arg1;
174 0 : SequenceRooter<JSObject*> arg1_holder(cx, &arg1);
175 0 : if (args.hasDefined(1)) {
176 0 : if (args[1].isObject()) {
177 0 : JS::ForOfIterator iter(cx);
178 0 : if (!iter.init(args[1], JS::ForOfIterator::AllowNonIterable)) {
179 0 : return false;
180 : }
181 0 : if (!iter.valueIsIterable()) {
182 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "Argument 2 of Client.postMessage");
183 0 : return false;
184 : }
185 0 : binding_detail::AutoSequence<JSObject*> &arr = arg1;
186 0 : JS::Rooted<JS::Value> temp(cx);
187 : while (true) {
188 : bool done;
189 0 : if (!iter.next(&temp, &done)) {
190 0 : return false;
191 : }
192 0 : if (done) {
193 0 : break;
194 : }
195 0 : JSObject** slotPtr = arr.AppendElement(mozilla::fallible);
196 0 : if (!slotPtr) {
197 0 : JS_ReportOutOfMemory(cx);
198 0 : return false;
199 : }
200 0 : JSObject*& slot = *slotPtr;
201 0 : if (temp.isObject()) {
202 0 : slot = &temp.toObject();
203 : } else {
204 0 : ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Element of argument 2 of Client.postMessage");
205 0 : return false;
206 : }
207 0 : }
208 : } else {
209 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "Argument 2 of Client.postMessage");
210 0 : return false;
211 : }
212 : } else {
213 : /* Array is already empty; nothing to do */
214 : }
215 0 : binding_detail::FastErrorResult rv;
216 0 : self->PostMessage(cx, arg0, Constify(arg1), rv);
217 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
218 0 : return false;
219 : }
220 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
221 0 : args.rval().setUndefined();
222 0 : return true;
223 : }
224 :
225 : static const JSJitInfo postMessage_methodinfo = {
226 : { (JSJitGetterOp)postMessage },
227 : { prototypes::id::Client },
228 : { PrototypeTraits<prototypes::id::Client>::Depth },
229 : JSJitInfo::Method,
230 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
231 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
232 : false, /* isInfallible. False in setters. */
233 : false, /* isMovable. Not relevant for setters. */
234 : false, /* isEliminatable. Not relevant for setters. */
235 : false, /* isAlwaysInSlot. Only relevant for getters. */
236 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
237 : false, /* isTypedMethod. Only relevant for methods. */
238 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
239 : };
240 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
241 : static_assert(0 < 1, "There is no slot for us");
242 :
243 : static bool
244 0 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
245 : {
246 0 : mozilla::dom::workers::ServiceWorkerClient* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::workers::ServiceWorkerClient>(obj);
247 : // We don't want to preserve if we don't have a wrapper, and we
248 : // obviously can't preserve if we're not initialized.
249 0 : if (self && self->GetWrapperPreserveColor()) {
250 0 : PreserveWrapper(self);
251 : }
252 0 : return true;
253 : }
254 :
255 : static void
256 0 : _finalize(js::FreeOp* fop, JSObject* obj)
257 : {
258 0 : mozilla::dom::workers::ServiceWorkerClient* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::workers::ServiceWorkerClient>(obj);
259 0 : if (self) {
260 0 : ClearWrapper(self, self, obj);
261 0 : AddForDeferredFinalization<mozilla::dom::workers::ServiceWorkerClient>(self);
262 : }
263 0 : }
264 :
265 : static void
266 0 : _objectMoved(JSObject* obj, const JSObject* old)
267 : {
268 0 : mozilla::dom::workers::ServiceWorkerClient* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::workers::ServiceWorkerClient>(obj);
269 0 : if (self) {
270 0 : UpdateWrapper(self, self, obj, old);
271 : }
272 0 : }
273 :
274 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
275 : #if defined(__clang__)
276 : #pragma clang diagnostic push
277 : #pragma clang diagnostic ignored "-Wmissing-braces"
278 : #endif
279 : static const JSFunctionSpec sMethods_specs[] = {
280 : JS_FNSPEC("postMessage", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&postMessage_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
281 : JS_FS_END
282 : };
283 : #if defined(__clang__)
284 : #pragma clang diagnostic pop
285 : #endif
286 :
287 :
288 : // Can't be const because the pref-enabled boolean needs to be writable
289 : static Prefable<const JSFunctionSpec> sMethods[] = {
290 : { nullptr, &sMethods_specs[0] },
291 : { nullptr, nullptr }
292 : };
293 :
294 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
295 : #if defined(__clang__)
296 : #pragma clang diagnostic push
297 : #pragma clang diagnostic ignored "-Wmissing-braces"
298 : #endif
299 : static const JSPropertySpec sAttributes_specs[] = {
300 : { "url", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &url_getterinfo, nullptr, nullptr },
301 : { "frameType", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &frameType_getterinfo, nullptr, nullptr },
302 : { "type", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &type_getterinfo, nullptr, nullptr },
303 : { "id", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &id_getterinfo, nullptr, nullptr },
304 : { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
305 : };
306 : #if defined(__clang__)
307 : #pragma clang diagnostic pop
308 : #endif
309 :
310 :
311 : // Can't be const because the pref-enabled boolean needs to be writable
312 : static Prefable<const JSPropertySpec> sAttributes[] = {
313 : { nullptr, &sAttributes_specs[0] },
314 : { nullptr, nullptr }
315 : };
316 :
317 :
318 : static const NativePropertiesN<2> sNativeProperties = {
319 : false, 0,
320 : false, 0,
321 : true, 0 /* sMethods */,
322 : true, 1 /* sAttributes */,
323 : false, 0,
324 : false, 0,
325 : false, 0,
326 : -1,
327 : 0,
328 : nullptr,
329 : {
330 : { sMethods, nullptr },
331 : { sAttributes, nullptr }
332 : }
333 : };
334 :
335 : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
336 : {
337 : "Function",
338 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
339 : &sBoringInterfaceObjectClassClassOps,
340 : JS_NULL_CLASS_SPEC,
341 : JS_NULL_CLASS_EXT,
342 : &sInterfaceObjectClassObjectOps
343 : },
344 : eInterface,
345 : true,
346 : prototypes::id::Client,
347 : PrototypeTraits<prototypes::id::Client>::Depth,
348 : &sEmptyNativePropertyHooks,
349 : "function Client() {\n [native code]\n}",
350 : JS::GetRealmFunctionPrototype
351 : };
352 :
353 : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
354 : {
355 : "ClientPrototype",
356 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
357 : JS_NULL_CLASS_OPS,
358 : JS_NULL_CLASS_SPEC,
359 : JS_NULL_CLASS_EXT,
360 : JS_NULL_OBJECT_OPS
361 : },
362 : eInterfacePrototype,
363 : false,
364 : prototypes::id::Client,
365 : PrototypeTraits<prototypes::id::Client>::Depth,
366 : &sEmptyNativePropertyHooks,
367 : "[object ClientPrototype]",
368 : JS::GetRealmObjectPrototype
369 : };
370 :
371 : bool
372 1 : ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
373 : {
374 1 : MOZ_ASSERT(!NS_IsMainThread(), "Why did we even get called?");
375 :
376 1 : const char* name = js::GetObjectClass(aObj)->name;
377 1 : if (strcmp(name, "ServiceWorkerGlobalScope")) {
378 1 : return false;
379 : }
380 :
381 0 : return true;
382 : }
383 :
384 : static const js::ClassOps sClassOps = {
385 : _addProperty, /* addProperty */
386 : nullptr, /* delProperty */
387 : nullptr, /* getProperty */
388 : nullptr, /* setProperty */
389 : nullptr, /* enumerate */
390 : nullptr, /* newEnumerate */
391 : nullptr, /* resolve */
392 : nullptr, /* mayResolve */
393 : _finalize, /* finalize */
394 : nullptr, /* call */
395 : nullptr, /* hasInstance */
396 : nullptr, /* construct */
397 : nullptr, /* trace */
398 : };
399 :
400 : static const js::ClassExtension sClassExtension = {
401 : nullptr, /* weakmapKeyDelegateOp */
402 : _objectMoved /* objectMovedOp */
403 : };
404 :
405 : static const DOMJSClass sClass = {
406 : { "Client",
407 : JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
408 : &sClassOps,
409 : JS_NULL_CLASS_SPEC,
410 : &sClassExtension,
411 : JS_NULL_OBJECT_OPS
412 : },
413 : { prototypes::id::Client, 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 },
414 : IsBaseOf<nsISupports, mozilla::dom::workers::ServiceWorkerClient >::value,
415 : &sEmptyNativePropertyHooks,
416 : FindAssociatedGlobalForNative<mozilla::dom::workers::ServiceWorkerClient>::Get,
417 : GetProtoObjectHandle,
418 : GetCCParticipant<mozilla::dom::workers::ServiceWorkerClient>::Get()
419 : };
420 : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
421 : "Must have the right minimal number of reserved slots.");
422 : static_assert(1 >= 1,
423 : "Must have enough reserved slots.");
424 :
425 : const JSClass*
426 0 : GetJSClass()
427 : {
428 0 : return sClass.ToJSClass();
429 : }
430 :
431 : bool
432 0 : Wrap(JSContext* aCx, mozilla::dom::workers::ServiceWorkerClient* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
433 : {
434 : MOZ_ASSERT(static_cast<mozilla::dom::workers::ServiceWorkerClient*>(aObject) ==
435 : reinterpret_cast<mozilla::dom::workers::ServiceWorkerClient*>(aObject),
436 : "Multiple inheritance for mozilla::dom::workers::ServiceWorkerClient is broken.");
437 0 : MOZ_ASSERT(ToSupportsIsCorrect(aObject));
438 0 : MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
439 0 : MOZ_ASSERT(!aCache->GetWrapper(),
440 : "You should probably not be using Wrap() directly; use "
441 : "GetOrCreateDOMReflector instead");
442 :
443 0 : MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
444 : "nsISupports must be on our primary inheritance chain");
445 :
446 0 : JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
447 0 : if (!global) {
448 0 : return false;
449 : }
450 0 : MOZ_ASSERT(JS_IsGlobalObject(global));
451 0 : MOZ_ASSERT(JS::ObjectIsNotGray(global));
452 :
453 : // That might have ended up wrapping us already, due to the wonders
454 : // of XBL. Check for that, and bail out as needed.
455 0 : aReflector.set(aCache->GetWrapper());
456 0 : if (aReflector) {
457 : #ifdef DEBUG
458 0 : binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
459 : #endif // DEBUG
460 0 : return true;
461 : }
462 :
463 0 : JSAutoCompartment ac(aCx, global);
464 0 : JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
465 0 : if (!canonicalProto) {
466 0 : return false;
467 : }
468 0 : JS::Rooted<JSObject*> proto(aCx);
469 0 : if (aGivenProto) {
470 0 : proto = aGivenProto;
471 : // Unfortunately, while aGivenProto was in the compartment of aCx
472 : // coming in, we changed compartments to that of "parent" so may need
473 : // to wrap the proto here.
474 0 : if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
475 0 : if (!JS_WrapObject(aCx, &proto)) {
476 0 : return false;
477 : }
478 : }
479 : } else {
480 0 : proto = canonicalProto;
481 : }
482 :
483 0 : BindingJSObjectCreator<mozilla::dom::workers::ServiceWorkerClient> creator(aCx);
484 0 : creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
485 0 : if (!aReflector) {
486 0 : return false;
487 : }
488 :
489 0 : aCache->SetWrapper(aReflector);
490 0 : creator.InitializationSucceeded();
491 :
492 0 : MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
493 : aCache->GetWrapperPreserveColor() == aReflector);
494 : // If proto != canonicalProto, we have to preserve our wrapper;
495 : // otherwise we won't be able to properly recreate it later, since
496 : // we won't know what proto to use. Note that we don't check
497 : // aGivenProto here, since it's entirely possible (and even
498 : // somewhat common) to have a non-null aGivenProto which is the
499 : // same as canonicalProto.
500 0 : if (proto != canonicalProto) {
501 0 : PreserveWrapper(aObject);
502 : }
503 :
504 0 : return true;
505 : }
506 :
507 : void
508 0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
509 : {
510 0 : JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
511 0 : if (!parentProto) {
512 0 : return;
513 : }
514 :
515 0 : JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
516 0 : if (!constructorProto) {
517 0 : return;
518 : }
519 :
520 0 : JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::Client);
521 0 : JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::Client);
522 0 : dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
523 : &sPrototypeClass.mBase, protoCache,
524 : constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
525 : interfaceCache,
526 : sNativeProperties.Upcast(),
527 : nullptr,
528 : "Client", aDefineOnGlobal,
529 : nullptr,
530 0 : false);
531 : }
532 :
533 : JS::Handle<JSObject*>
534 0 : GetProtoObjectHandle(JSContext* aCx)
535 : {
536 : /* Get the interface prototype object for this class. This will create the
537 : object as needed. */
538 0 : bool aDefineOnGlobal = true;
539 :
540 : /* Make sure our global is sane. Hopefully we can remove this sometime */
541 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
542 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
543 0 : return nullptr;
544 : }
545 :
546 : /* Check to see whether the interface objects are already installed */
547 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
548 0 : if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::Client)) {
549 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
550 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
551 : }
552 :
553 : /*
554 : * The object might _still_ be null, but that's OK.
555 : *
556 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
557 : * traced by TraceProtoAndIfaceCache() and its contents are never
558 : * changed after they have been set.
559 : *
560 : * Calling address() avoids the read read barrier that does gray
561 : * unmarking, but it's not possible for the object to be gray here.
562 : */
563 :
564 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::Client);
565 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
566 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
567 : }
568 :
569 : JSObject*
570 0 : GetProtoObject(JSContext* aCx)
571 : {
572 0 : return GetProtoObjectHandle(aCx);
573 : }
574 :
575 : JS::Handle<JSObject*>
576 0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
577 : {
578 : /* Get the interface object for this class. This will create the object as
579 : needed. */
580 :
581 : /* Make sure our global is sane. Hopefully we can remove this sometime */
582 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
583 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
584 0 : return nullptr;
585 : }
586 :
587 : /* Check to see whether the interface objects are already installed */
588 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
589 0 : if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::Client)) {
590 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
591 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
592 : }
593 :
594 : /*
595 : * The object might _still_ be null, but that's OK.
596 : *
597 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
598 : * traced by TraceProtoAndIfaceCache() and its contents are never
599 : * changed after they have been set.
600 : *
601 : * Calling address() avoids the read read barrier that does gray
602 : * unmarking, but it's not possible for the object to be gray here.
603 : */
604 :
605 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::Client);
606 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
607 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
608 : }
609 :
610 : JSObject*
611 0 : GetConstructorObject(JSContext* aCx)
612 : {
613 0 : return GetConstructorObjectHandle(aCx);
614 : }
615 :
616 : } // namespace ClientBinding
617 :
618 :
619 :
620 : namespace WindowClientBinding {
621 :
622 : static_assert(IsRefcounted<NativeType>::value == IsRefcounted<ClientBinding::NativeType>::value,
623 : "Can't inherit from an interface with a different ownership model.");
624 :
625 : static bool
626 0 : get_visibilityState(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::workers::ServiceWorkerWindowClient* self, JSJitGetterCallArgs args)
627 : {
628 0 : VisibilityState result(self->VisibilityState());
629 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
630 0 : if (!ToJSValue(cx, result, args.rval())) {
631 0 : return false;
632 : }
633 0 : return true;
634 : }
635 :
636 : static const JSJitInfo visibilityState_getterinfo = {
637 : { (JSJitGetterOp)get_visibilityState },
638 : { prototypes::id::WindowClient },
639 : { PrototypeTraits<prototypes::id::WindowClient>::Depth },
640 : JSJitInfo::Getter,
641 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
642 : JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
643 : false, /* isInfallible. False in setters. */
644 : false, /* isMovable. Not relevant for setters. */
645 : false, /* isEliminatable. Not relevant for setters. */
646 : false, /* isAlwaysInSlot. Only relevant for getters. */
647 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
648 : false, /* isTypedMethod. Only relevant for methods. */
649 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
650 : };
651 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
652 : static_assert(0 < 1, "There is no slot for us");
653 :
654 : static bool
655 0 : get_focused(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::workers::ServiceWorkerWindowClient* self, JSJitGetterCallArgs args)
656 : {
657 0 : bool result(self->Focused());
658 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
659 0 : args.rval().setBoolean(result);
660 0 : return true;
661 : }
662 :
663 : static const JSJitInfo focused_getterinfo = {
664 : { (JSJitGetterOp)get_focused },
665 : { prototypes::id::WindowClient },
666 : { PrototypeTraits<prototypes::id::WindowClient>::Depth },
667 : JSJitInfo::Getter,
668 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
669 : JSVAL_TYPE_BOOLEAN, /* returnType. Not relevant for setters. */
670 : true, /* isInfallible. False in setters. */
671 : false, /* isMovable. Not relevant for setters. */
672 : false, /* isEliminatable. Not relevant for setters. */
673 : false, /* isAlwaysInSlot. Only relevant for getters. */
674 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
675 : false, /* isTypedMethod. Only relevant for methods. */
676 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
677 : };
678 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
679 : static_assert(0 < 1, "There is no slot for us");
680 :
681 : static bool
682 0 : focus(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::workers::ServiceWorkerWindowClient* self, const JSJitMethodCallArgs& args)
683 : {
684 0 : binding_detail::FastErrorResult rv;
685 0 : auto result(StrongOrRawPtr<Promise>(self->Focus(rv)));
686 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
687 0 : return false;
688 : }
689 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
690 : static_assert(!IsPointer<decltype(result)>::value,
691 : "NewObject implies that we need to keep the object alive with a strong reference.");
692 0 : if (!ToJSValue(cx, result, args.rval())) {
693 0 : return false;
694 : }
695 0 : return true;
696 : }
697 :
698 : static bool
699 0 : focus_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::workers::ServiceWorkerWindowClient* self, const JSJitMethodCallArgs& args)
700 : {
701 : // Make sure to save the callee before someone maybe messes
702 : // with rval().
703 0 : JS::Rooted<JSObject*> callee(cx, &args.callee());
704 0 : bool ok = focus(cx, obj, self, args);
705 0 : if (ok) {
706 0 : return true;
707 : }
708 0 : return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
709 0 : args.rval());
710 : }
711 :
712 : static const JSJitInfo focus_methodinfo = {
713 : { (JSJitGetterOp)focus_promiseWrapper },
714 : { prototypes::id::WindowClient },
715 : { PrototypeTraits<prototypes::id::WindowClient>::Depth },
716 : JSJitInfo::Method,
717 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
718 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
719 : false, /* isInfallible. False in setters. */
720 : false, /* isMovable. Not relevant for setters. */
721 : false, /* isEliminatable. Not relevant for setters. */
722 : false, /* isAlwaysInSlot. Only relevant for getters. */
723 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
724 : false, /* isTypedMethod. Only relevant for methods. */
725 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
726 : };
727 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
728 : static_assert(0 < 1, "There is no slot for us");
729 :
730 : static bool
731 0 : navigate(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::workers::ServiceWorkerWindowClient* self, const JSJitMethodCallArgs& args)
732 : {
733 0 : if (MOZ_UNLIKELY(args.length() < 1)) {
734 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "WindowClient.navigate");
735 : }
736 0 : binding_detail::FakeString arg0;
737 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
738 0 : return false;
739 : }
740 0 : NormalizeUSVString(arg0);
741 0 : binding_detail::FastErrorResult rv;
742 0 : auto result(StrongOrRawPtr<Promise>(self->Navigate(Constify(arg0), rv)));
743 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
744 0 : return false;
745 : }
746 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
747 : static_assert(!IsPointer<decltype(result)>::value,
748 : "NewObject implies that we need to keep the object alive with a strong reference.");
749 0 : if (!ToJSValue(cx, result, args.rval())) {
750 0 : return false;
751 : }
752 0 : return true;
753 : }
754 :
755 : static bool
756 0 : navigate_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::workers::ServiceWorkerWindowClient* self, const JSJitMethodCallArgs& args)
757 : {
758 : // Make sure to save the callee before someone maybe messes
759 : // with rval().
760 0 : JS::Rooted<JSObject*> callee(cx, &args.callee());
761 0 : bool ok = navigate(cx, obj, self, args);
762 0 : if (ok) {
763 0 : return true;
764 : }
765 0 : return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
766 0 : args.rval());
767 : }
768 :
769 : static const JSJitInfo navigate_methodinfo = {
770 : { (JSJitGetterOp)navigate_promiseWrapper },
771 : { prototypes::id::WindowClient },
772 : { PrototypeTraits<prototypes::id::WindowClient>::Depth },
773 : JSJitInfo::Method,
774 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
775 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
776 : false, /* isInfallible. False in setters. */
777 : false, /* isMovable. Not relevant for setters. */
778 : false, /* isEliminatable. Not relevant for setters. */
779 : false, /* isAlwaysInSlot. Only relevant for getters. */
780 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
781 : false, /* isTypedMethod. Only relevant for methods. */
782 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
783 : };
784 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
785 : static_assert(0 < 1, "There is no slot for us");
786 :
787 : static bool
788 0 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
789 : {
790 0 : mozilla::dom::workers::ServiceWorkerWindowClient* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::workers::ServiceWorkerWindowClient>(obj);
791 : // We don't want to preserve if we don't have a wrapper, and we
792 : // obviously can't preserve if we're not initialized.
793 0 : if (self && self->GetWrapperPreserveColor()) {
794 0 : PreserveWrapper(self);
795 : }
796 0 : return true;
797 : }
798 :
799 : static void
800 0 : _finalize(js::FreeOp* fop, JSObject* obj)
801 : {
802 0 : mozilla::dom::workers::ServiceWorkerWindowClient* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::workers::ServiceWorkerWindowClient>(obj);
803 0 : if (self) {
804 0 : ClearWrapper(self, self, obj);
805 0 : AddForDeferredFinalization<mozilla::dom::workers::ServiceWorkerWindowClient>(self);
806 : }
807 0 : }
808 :
809 : static void
810 0 : _objectMoved(JSObject* obj, const JSObject* old)
811 : {
812 0 : mozilla::dom::workers::ServiceWorkerWindowClient* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::workers::ServiceWorkerWindowClient>(obj);
813 0 : if (self) {
814 0 : UpdateWrapper(self, self, obj, old);
815 : }
816 0 : }
817 :
818 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
819 : #if defined(__clang__)
820 : #pragma clang diagnostic push
821 : #pragma clang diagnostic ignored "-Wmissing-braces"
822 : #endif
823 : static const JSFunctionSpec sMethods_specs[] = {
824 : JS_FNSPEC("focus", GenericPromiseReturningBindingMethod, reinterpret_cast<const JSJitInfo*>(&focus_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
825 : JS_FNSPEC("navigate", GenericPromiseReturningBindingMethod, reinterpret_cast<const JSJitInfo*>(&navigate_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
826 : JS_FS_END
827 : };
828 : #if defined(__clang__)
829 : #pragma clang diagnostic pop
830 : #endif
831 :
832 :
833 : // Can't be const because the pref-enabled boolean needs to be writable
834 : static Prefable<const JSFunctionSpec> sMethods[] = {
835 : { nullptr, &sMethods_specs[0] },
836 : { nullptr, nullptr }
837 : };
838 :
839 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
840 : #if defined(__clang__)
841 : #pragma clang diagnostic push
842 : #pragma clang diagnostic ignored "-Wmissing-braces"
843 : #endif
844 : static const JSPropertySpec sAttributes_specs[] = {
845 : { "visibilityState", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &visibilityState_getterinfo, nullptr, nullptr },
846 : { "focused", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &focused_getterinfo, nullptr, nullptr },
847 : { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
848 : };
849 : #if defined(__clang__)
850 : #pragma clang diagnostic pop
851 : #endif
852 :
853 :
854 : // Can't be const because the pref-enabled boolean needs to be writable
855 : static Prefable<const JSPropertySpec> sAttributes[] = {
856 : { nullptr, &sAttributes_specs[0] },
857 : { nullptr, nullptr }
858 : };
859 :
860 :
861 : static const NativePropertiesN<2> sNativeProperties = {
862 : false, 0,
863 : false, 0,
864 : true, 0 /* sMethods */,
865 : true, 1 /* sAttributes */,
866 : false, 0,
867 : false, 0,
868 : false, 0,
869 : -1,
870 : 0,
871 : nullptr,
872 : {
873 : { sMethods, nullptr },
874 : { sAttributes, nullptr }
875 : }
876 : };
877 :
878 : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
879 : {
880 : "Function",
881 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
882 : &sBoringInterfaceObjectClassClassOps,
883 : JS_NULL_CLASS_SPEC,
884 : JS_NULL_CLASS_EXT,
885 : &sInterfaceObjectClassObjectOps
886 : },
887 : eInterface,
888 : true,
889 : prototypes::id::WindowClient,
890 : PrototypeTraits<prototypes::id::WindowClient>::Depth,
891 : &sEmptyNativePropertyHooks,
892 : "function WindowClient() {\n [native code]\n}",
893 : ClientBinding::GetConstructorObject
894 : };
895 :
896 : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
897 : {
898 : "WindowClientPrototype",
899 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
900 : JS_NULL_CLASS_OPS,
901 : JS_NULL_CLASS_SPEC,
902 : JS_NULL_CLASS_EXT,
903 : JS_NULL_OBJECT_OPS
904 : },
905 : eInterfacePrototype,
906 : false,
907 : prototypes::id::WindowClient,
908 : PrototypeTraits<prototypes::id::WindowClient>::Depth,
909 : &sEmptyNativePropertyHooks,
910 : "[object WindowClientPrototype]",
911 : ClientBinding::GetProtoObject
912 : };
913 :
914 : bool
915 1 : ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
916 : {
917 1 : MOZ_ASSERT(!NS_IsMainThread(), "Why did we even get called?");
918 :
919 1 : const char* name = js::GetObjectClass(aObj)->name;
920 1 : if (strcmp(name, "ServiceWorkerGlobalScope")) {
921 1 : return false;
922 : }
923 :
924 0 : return true;
925 : }
926 :
927 : static const js::ClassOps sClassOps = {
928 : _addProperty, /* addProperty */
929 : nullptr, /* delProperty */
930 : nullptr, /* getProperty */
931 : nullptr, /* setProperty */
932 : nullptr, /* enumerate */
933 : nullptr, /* newEnumerate */
934 : nullptr, /* resolve */
935 : nullptr, /* mayResolve */
936 : _finalize, /* finalize */
937 : nullptr, /* call */
938 : nullptr, /* hasInstance */
939 : nullptr, /* construct */
940 : nullptr, /* trace */
941 : };
942 :
943 : static const js::ClassExtension sClassExtension = {
944 : nullptr, /* weakmapKeyDelegateOp */
945 : _objectMoved /* objectMovedOp */
946 : };
947 :
948 : static const DOMJSClass sClass = {
949 : { "WindowClient",
950 : JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
951 : &sClassOps,
952 : JS_NULL_CLASS_SPEC,
953 : &sClassExtension,
954 : JS_NULL_OBJECT_OPS
955 : },
956 : { prototypes::id::Client, prototypes::id::WindowClient, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
957 : IsBaseOf<nsISupports, mozilla::dom::workers::ServiceWorkerWindowClient >::value,
958 : &sEmptyNativePropertyHooks,
959 : FindAssociatedGlobalForNative<mozilla::dom::workers::ServiceWorkerWindowClient>::Get,
960 : GetProtoObjectHandle,
961 : GetCCParticipant<mozilla::dom::workers::ServiceWorkerWindowClient>::Get()
962 : };
963 : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
964 : "Must have the right minimal number of reserved slots.");
965 : static_assert(1 >= 1,
966 : "Must have enough reserved slots.");
967 :
968 : const JSClass*
969 0 : GetJSClass()
970 : {
971 0 : return sClass.ToJSClass();
972 : }
973 :
974 : bool
975 0 : Wrap(JSContext* aCx, mozilla::dom::workers::ServiceWorkerWindowClient* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
976 : {
977 : MOZ_ASSERT(static_cast<mozilla::dom::workers::ServiceWorkerWindowClient*>(aObject) ==
978 : reinterpret_cast<mozilla::dom::workers::ServiceWorkerWindowClient*>(aObject),
979 : "Multiple inheritance for mozilla::dom::workers::ServiceWorkerWindowClient is broken.");
980 : MOZ_ASSERT(static_cast<mozilla::dom::workers::ServiceWorkerClient*>(aObject) ==
981 : reinterpret_cast<mozilla::dom::workers::ServiceWorkerClient*>(aObject),
982 : "Multiple inheritance for mozilla::dom::workers::ServiceWorkerClient is broken.");
983 0 : MOZ_ASSERT(ToSupportsIsCorrect(aObject));
984 0 : MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
985 0 : MOZ_ASSERT(!aCache->GetWrapper(),
986 : "You should probably not be using Wrap() directly; use "
987 : "GetOrCreateDOMReflector instead");
988 :
989 0 : MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
990 : "nsISupports must be on our primary inheritance chain");
991 :
992 0 : JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
993 0 : if (!global) {
994 0 : return false;
995 : }
996 0 : MOZ_ASSERT(JS_IsGlobalObject(global));
997 0 : MOZ_ASSERT(JS::ObjectIsNotGray(global));
998 :
999 : // That might have ended up wrapping us already, due to the wonders
1000 : // of XBL. Check for that, and bail out as needed.
1001 0 : aReflector.set(aCache->GetWrapper());
1002 0 : if (aReflector) {
1003 : #ifdef DEBUG
1004 0 : binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
1005 : #endif // DEBUG
1006 0 : return true;
1007 : }
1008 :
1009 0 : JSAutoCompartment ac(aCx, global);
1010 0 : JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
1011 0 : if (!canonicalProto) {
1012 0 : return false;
1013 : }
1014 0 : JS::Rooted<JSObject*> proto(aCx);
1015 0 : if (aGivenProto) {
1016 0 : proto = aGivenProto;
1017 : // Unfortunately, while aGivenProto was in the compartment of aCx
1018 : // coming in, we changed compartments to that of "parent" so may need
1019 : // to wrap the proto here.
1020 0 : if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
1021 0 : if (!JS_WrapObject(aCx, &proto)) {
1022 0 : return false;
1023 : }
1024 : }
1025 : } else {
1026 0 : proto = canonicalProto;
1027 : }
1028 :
1029 0 : BindingJSObjectCreator<mozilla::dom::workers::ServiceWorkerWindowClient> creator(aCx);
1030 0 : creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
1031 0 : if (!aReflector) {
1032 0 : return false;
1033 : }
1034 :
1035 0 : aCache->SetWrapper(aReflector);
1036 0 : creator.InitializationSucceeded();
1037 :
1038 0 : MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
1039 : aCache->GetWrapperPreserveColor() == aReflector);
1040 : // If proto != canonicalProto, we have to preserve our wrapper;
1041 : // otherwise we won't be able to properly recreate it later, since
1042 : // we won't know what proto to use. Note that we don't check
1043 : // aGivenProto here, since it's entirely possible (and even
1044 : // somewhat common) to have a non-null aGivenProto which is the
1045 : // same as canonicalProto.
1046 0 : if (proto != canonicalProto) {
1047 0 : PreserveWrapper(aObject);
1048 : }
1049 :
1050 0 : return true;
1051 : }
1052 :
1053 : void
1054 0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
1055 : {
1056 0 : JS::Handle<JSObject*> parentProto(ClientBinding::GetProtoObjectHandle(aCx));
1057 0 : if (!parentProto) {
1058 0 : return;
1059 : }
1060 :
1061 0 : JS::Handle<JSObject*> constructorProto(ClientBinding::GetConstructorObjectHandle(aCx));
1062 0 : if (!constructorProto) {
1063 0 : return;
1064 : }
1065 :
1066 0 : JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::WindowClient);
1067 0 : JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::WindowClient);
1068 0 : dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
1069 : &sPrototypeClass.mBase, protoCache,
1070 : constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
1071 : interfaceCache,
1072 : sNativeProperties.Upcast(),
1073 : nullptr,
1074 : "WindowClient", aDefineOnGlobal,
1075 : nullptr,
1076 0 : false);
1077 : }
1078 :
1079 : JS::Handle<JSObject*>
1080 0 : GetProtoObjectHandle(JSContext* aCx)
1081 : {
1082 : /* Get the interface prototype object for this class. This will create the
1083 : object as needed. */
1084 0 : bool aDefineOnGlobal = true;
1085 :
1086 : /* Make sure our global is sane. Hopefully we can remove this sometime */
1087 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
1088 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
1089 0 : return nullptr;
1090 : }
1091 :
1092 : /* Check to see whether the interface objects are already installed */
1093 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
1094 0 : if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::WindowClient)) {
1095 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
1096 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
1097 : }
1098 :
1099 : /*
1100 : * The object might _still_ be null, but that's OK.
1101 : *
1102 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
1103 : * traced by TraceProtoAndIfaceCache() and its contents are never
1104 : * changed after they have been set.
1105 : *
1106 : * Calling address() avoids the read read barrier that does gray
1107 : * unmarking, but it's not possible for the object to be gray here.
1108 : */
1109 :
1110 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::WindowClient);
1111 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
1112 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
1113 : }
1114 :
1115 : JS::Handle<JSObject*>
1116 0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
1117 : {
1118 : /* Get the interface object for this class. This will create the object as
1119 : needed. */
1120 :
1121 : /* Make sure our global is sane. Hopefully we can remove this sometime */
1122 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
1123 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
1124 0 : return nullptr;
1125 : }
1126 :
1127 : /* Check to see whether the interface objects are already installed */
1128 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
1129 0 : if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::WindowClient)) {
1130 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
1131 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
1132 : }
1133 :
1134 : /*
1135 : * The object might _still_ be null, but that's OK.
1136 : *
1137 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
1138 : * traced by TraceProtoAndIfaceCache() and its contents are never
1139 : * changed after they have been set.
1140 : *
1141 : * Calling address() avoids the read read barrier that does gray
1142 : * unmarking, but it's not possible for the object to be gray here.
1143 : */
1144 :
1145 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::WindowClient);
1146 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
1147 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
1148 : }
1149 :
1150 : JSObject*
1151 0 : GetConstructorObject(JSContext* aCx)
1152 : {
1153 0 : return GetConstructorObjectHandle(aCx);
1154 : }
1155 :
1156 : } // namespace WindowClientBinding
1157 :
1158 :
1159 :
1160 : } // namespace dom
1161 : } // namespace mozilla
|