Line data Source code
1 : /* THIS FILE IS AUTOGENERATED FROM Worklet.webidl BY Codegen.py - DO NOT EDIT */
2 :
3 : #include "WorkletBinding.h"
4 : #include "WrapperFactory.h"
5 : #include "mozilla/OwningNonNull.h"
6 : #include "mozilla/Preferences.h"
7 : #include "mozilla/dom/BindingUtils.h"
8 : #include "mozilla/dom/DOMJSClass.h"
9 : #include "mozilla/dom/NonRefcountedDOMObject.h"
10 : #include "mozilla/dom/Promise.h"
11 : #include "mozilla/dom/ToJSValue.h"
12 : #include "mozilla/dom/Worklet.h"
13 : #include "mozilla/dom/XrayExpandoClass.h"
14 : #include "nsContentUtils.h"
15 :
16 : namespace mozilla {
17 : namespace dom {
18 :
19 : namespace WorkletBinding {
20 :
21 : static bool
22 0 : import(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Worklet* self, const JSJitMethodCallArgs& args)
23 : {
24 0 : if (MOZ_UNLIKELY(args.length() < 1)) {
25 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "Worklet.import");
26 : }
27 0 : binding_detail::FakeString arg0;
28 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
29 0 : return false;
30 : }
31 0 : NormalizeUSVString(arg0);
32 0 : binding_detail::FastErrorResult rv;
33 0 : auto result(StrongOrRawPtr<Promise>(self->Import(Constify(arg0), nsContentUtils::IsSystemCaller(cx) ? CallerType::System : CallerType::NonSystem, rv)));
34 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
35 0 : return false;
36 : }
37 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
38 : static_assert(!IsPointer<decltype(result)>::value,
39 : "NewObject implies that we need to keep the object alive with a strong reference.");
40 0 : if (!ToJSValue(cx, result, args.rval())) {
41 0 : return false;
42 : }
43 0 : return true;
44 : }
45 :
46 : static bool
47 0 : import_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::Worklet* self, const JSJitMethodCallArgs& args)
48 : {
49 : // Make sure to save the callee before someone maybe messes
50 : // with rval().
51 0 : JS::Rooted<JSObject*> callee(cx, &args.callee());
52 0 : bool ok = import(cx, obj, self, args);
53 0 : if (ok) {
54 0 : return true;
55 : }
56 0 : return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
57 0 : args.rval());
58 : }
59 :
60 : static const JSJitInfo import_methodinfo = {
61 : { (JSJitGetterOp)import_promiseWrapper },
62 : { prototypes::id::Worklet },
63 : { PrototypeTraits<prototypes::id::Worklet>::Depth },
64 : JSJitInfo::Method,
65 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
66 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
67 : false, /* isInfallible. False in setters. */
68 : false, /* isMovable. Not relevant for setters. */
69 : false, /* isEliminatable. Not relevant for setters. */
70 : false, /* isAlwaysInSlot. Only relevant for getters. */
71 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
72 : false, /* isTypedMethod. Only relevant for methods. */
73 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
74 : };
75 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
76 : static_assert(0 < 1, "There is no slot for us");
77 :
78 : static bool
79 0 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
80 : {
81 0 : mozilla::dom::Worklet* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::Worklet>(obj);
82 : // We don't want to preserve if we don't have a wrapper, and we
83 : // obviously can't preserve if we're not initialized.
84 0 : if (self && self->GetWrapperPreserveColor()) {
85 0 : PreserveWrapper(self);
86 : }
87 0 : return true;
88 : }
89 :
90 : static void
91 0 : _finalize(js::FreeOp* fop, JSObject* obj)
92 : {
93 0 : mozilla::dom::Worklet* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::Worklet>(obj);
94 0 : if (self) {
95 0 : ClearWrapper(self, self, obj);
96 0 : AddForDeferredFinalization<mozilla::dom::Worklet>(self);
97 : }
98 0 : }
99 :
100 : static void
101 0 : _objectMoved(JSObject* obj, const JSObject* old)
102 : {
103 0 : mozilla::dom::Worklet* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::Worklet>(obj);
104 0 : if (self) {
105 0 : UpdateWrapper(self, self, obj, old);
106 : }
107 0 : }
108 :
109 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
110 : #if defined(__clang__)
111 : #pragma clang diagnostic push
112 : #pragma clang diagnostic ignored "-Wmissing-braces"
113 : #endif
114 : static const JSFunctionSpec sMethods_specs[] = {
115 : JS_FNSPEC("import", GenericPromiseReturningBindingMethod, reinterpret_cast<const JSJitInfo*>(&import_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
116 : JS_FS_END
117 : };
118 : #if defined(__clang__)
119 : #pragma clang diagnostic pop
120 : #endif
121 :
122 :
123 : // Can't be const because the pref-enabled boolean needs to be writable
124 : static Prefable<const JSFunctionSpec> sMethods[] = {
125 : { nullptr, &sMethods_specs[0] },
126 : { nullptr, nullptr }
127 : };
128 :
129 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
130 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
131 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
132 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
133 :
134 :
135 : static uint16_t sNativeProperties_sortedPropertyIndices[1];
136 : static PropertyInfo sNativeProperties_propertyInfos[1];
137 :
138 : static const NativePropertiesN<1> sNativeProperties = {
139 : false, 0,
140 : false, 0,
141 : true, 0 /* sMethods */,
142 : false, 0,
143 : false, 0,
144 : false, 0,
145 : false, 0,
146 : -1,
147 : 1,
148 : sNativeProperties_sortedPropertyIndices,
149 : {
150 : { sMethods, &sNativeProperties_propertyInfos[0] }
151 : }
152 : };
153 : static_assert(1 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
154 : "We have a property info count that is oversized");
155 :
156 : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
157 : {
158 : "Function",
159 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
160 : &sBoringInterfaceObjectClassClassOps,
161 : JS_NULL_CLASS_SPEC,
162 : JS_NULL_CLASS_EXT,
163 : &sInterfaceObjectClassObjectOps
164 : },
165 : eInterface,
166 : true,
167 : prototypes::id::Worklet,
168 : PrototypeTraits<prototypes::id::Worklet>::Depth,
169 : sNativePropertyHooks,
170 : "function Worklet() {\n [native code]\n}",
171 : JS::GetRealmFunctionPrototype
172 : };
173 :
174 : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
175 : {
176 : "WorkletPrototype",
177 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
178 : JS_NULL_CLASS_OPS,
179 : JS_NULL_CLASS_SPEC,
180 : JS_NULL_CLASS_EXT,
181 : JS_NULL_OBJECT_OPS
182 : },
183 : eInterfacePrototype,
184 : false,
185 : prototypes::id::Worklet,
186 : PrototypeTraits<prototypes::id::Worklet>::Depth,
187 : sNativePropertyHooks,
188 : "[object WorkletPrototype]",
189 : JS::GetRealmObjectPrototype
190 : };
191 :
192 : bool
193 0 : ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
194 : {
195 : static bool sPrefValue;
196 : static bool sPrefCacheSetUp = false;
197 0 : if (!sPrefCacheSetUp) {
198 0 : sPrefCacheSetUp = true;
199 0 : Preferences::AddBoolVarCache(&sPrefValue, "dom.worklet.enabled");
200 : }
201 :
202 0 : return sPrefValue;
203 : }
204 :
205 : JSObject*
206 0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
207 : {
208 0 : return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
209 : }
210 :
211 : static const js::ClassOps sClassOps = {
212 : _addProperty, /* addProperty */
213 : nullptr, /* delProperty */
214 : nullptr, /* getProperty */
215 : nullptr, /* setProperty */
216 : nullptr, /* enumerate */
217 : nullptr, /* newEnumerate */
218 : nullptr, /* resolve */
219 : nullptr, /* mayResolve */
220 : _finalize, /* finalize */
221 : nullptr, /* call */
222 : nullptr, /* hasInstance */
223 : nullptr, /* construct */
224 : nullptr, /* trace */
225 : };
226 :
227 : static const js::ClassExtension sClassExtension = {
228 : nullptr, /* weakmapKeyDelegateOp */
229 : _objectMoved /* objectMovedOp */
230 : };
231 :
232 : static const DOMJSClass sClass = {
233 : { "Worklet",
234 : JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
235 : &sClassOps,
236 : JS_NULL_CLASS_SPEC,
237 : &sClassExtension,
238 : JS_NULL_OBJECT_OPS
239 : },
240 : { prototypes::id::Worklet, 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 },
241 : IsBaseOf<nsISupports, mozilla::dom::Worklet >::value,
242 : sNativePropertyHooks,
243 : FindAssociatedGlobalForNative<mozilla::dom::Worklet>::Get,
244 : GetProtoObjectHandle,
245 : GetCCParticipant<mozilla::dom::Worklet>::Get()
246 : };
247 : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
248 : "Must have the right minimal number of reserved slots.");
249 : static_assert(1 >= 1,
250 : "Must have enough reserved slots.");
251 :
252 : const JSClass*
253 0 : GetJSClass()
254 : {
255 0 : return sClass.ToJSClass();
256 : }
257 :
258 : bool
259 0 : Wrap(JSContext* aCx, mozilla::dom::Worklet* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
260 : {
261 : MOZ_ASSERT(static_cast<mozilla::dom::Worklet*>(aObject) ==
262 : reinterpret_cast<mozilla::dom::Worklet*>(aObject),
263 : "Multiple inheritance for mozilla::dom::Worklet is broken.");
264 0 : MOZ_ASSERT(ToSupportsIsCorrect(aObject));
265 0 : MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
266 0 : MOZ_ASSERT(!aCache->GetWrapper(),
267 : "You should probably not be using Wrap() directly; use "
268 : "GetOrCreateDOMReflector instead");
269 :
270 0 : MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
271 : "nsISupports must be on our primary inheritance chain");
272 :
273 0 : JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
274 0 : if (!global) {
275 0 : return false;
276 : }
277 0 : MOZ_ASSERT(JS_IsGlobalObject(global));
278 0 : MOZ_ASSERT(JS::ObjectIsNotGray(global));
279 :
280 : // That might have ended up wrapping us already, due to the wonders
281 : // of XBL. Check for that, and bail out as needed.
282 0 : aReflector.set(aCache->GetWrapper());
283 0 : if (aReflector) {
284 : #ifdef DEBUG
285 0 : binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
286 : #endif // DEBUG
287 0 : return true;
288 : }
289 :
290 0 : JSAutoCompartment ac(aCx, global);
291 0 : JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
292 0 : if (!canonicalProto) {
293 0 : return false;
294 : }
295 0 : JS::Rooted<JSObject*> proto(aCx);
296 0 : if (aGivenProto) {
297 0 : proto = aGivenProto;
298 : // Unfortunately, while aGivenProto was in the compartment of aCx
299 : // coming in, we changed compartments to that of "parent" so may need
300 : // to wrap the proto here.
301 0 : if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
302 0 : if (!JS_WrapObject(aCx, &proto)) {
303 0 : return false;
304 : }
305 : }
306 : } else {
307 0 : proto = canonicalProto;
308 : }
309 :
310 0 : BindingJSObjectCreator<mozilla::dom::Worklet> creator(aCx);
311 0 : creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
312 0 : if (!aReflector) {
313 0 : return false;
314 : }
315 :
316 0 : aCache->SetWrapper(aReflector);
317 0 : creator.InitializationSucceeded();
318 :
319 0 : MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
320 : aCache->GetWrapperPreserveColor() == aReflector);
321 : // If proto != canonicalProto, we have to preserve our wrapper;
322 : // otherwise we won't be able to properly recreate it later, since
323 : // we won't know what proto to use. Note that we don't check
324 : // aGivenProto here, since it's entirely possible (and even
325 : // somewhat common) to have a non-null aGivenProto which is the
326 : // same as canonicalProto.
327 0 : if (proto != canonicalProto) {
328 0 : PreserveWrapper(aObject);
329 : }
330 :
331 0 : return true;
332 : }
333 :
334 : const NativePropertyHooks sNativePropertyHooks[] = { {
335 : nullptr,
336 : nullptr,
337 : nullptr,
338 : { sNativeProperties.Upcast(), nullptr },
339 : prototypes::id::Worklet,
340 : constructors::id::Worklet,
341 : nullptr,
342 : &DefaultXrayExpandoObjectClass
343 : } };
344 :
345 : void
346 0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
347 : {
348 0 : JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
349 0 : if (!parentProto) {
350 0 : return;
351 : }
352 :
353 0 : JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
354 0 : if (!constructorProto) {
355 0 : return;
356 : }
357 :
358 : static bool sIdsInited = false;
359 0 : if (!sIdsInited && NS_IsMainThread()) {
360 0 : if (!InitIds(aCx, sNativeProperties.Upcast())) {
361 0 : return;
362 : }
363 0 : sIdsInited = true;
364 : }
365 :
366 0 : JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::Worklet);
367 0 : JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::Worklet);
368 0 : dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
369 : &sPrototypeClass.mBase, protoCache,
370 : constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
371 : interfaceCache,
372 : sNativeProperties.Upcast(),
373 : nullptr,
374 : "Worklet", aDefineOnGlobal,
375 : nullptr,
376 0 : false);
377 : }
378 :
379 : JS::Handle<JSObject*>
380 0 : GetProtoObjectHandle(JSContext* aCx)
381 : {
382 : /* Get the interface prototype object for this class. This will create the
383 : object as needed. */
384 0 : bool aDefineOnGlobal = true;
385 :
386 : /* Make sure our global is sane. Hopefully we can remove this sometime */
387 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
388 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
389 0 : return nullptr;
390 : }
391 :
392 : /* Check to see whether the interface objects are already installed */
393 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
394 0 : if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::Worklet)) {
395 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
396 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
397 : }
398 :
399 : /*
400 : * The object might _still_ be null, but that's OK.
401 : *
402 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
403 : * traced by TraceProtoAndIfaceCache() and its contents are never
404 : * changed after they have been set.
405 : *
406 : * Calling address() avoids the read read barrier that does gray
407 : * unmarking, but it's not possible for the object to be gray here.
408 : */
409 :
410 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::Worklet);
411 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
412 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
413 : }
414 :
415 : JS::Handle<JSObject*>
416 0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
417 : {
418 : /* Get the interface object for this class. This will create the object as
419 : needed. */
420 :
421 : /* Make sure our global is sane. Hopefully we can remove this sometime */
422 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
423 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
424 0 : return nullptr;
425 : }
426 :
427 : /* Check to see whether the interface objects are already installed */
428 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
429 0 : if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::Worklet)) {
430 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
431 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
432 : }
433 :
434 : /*
435 : * The object might _still_ be null, but that's OK.
436 : *
437 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
438 : * traced by TraceProtoAndIfaceCache() and its contents are never
439 : * changed after they have been set.
440 : *
441 : * Calling address() avoids the read read barrier that does gray
442 : * unmarking, but it's not possible for the object to be gray here.
443 : */
444 :
445 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::Worklet);
446 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
447 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
448 : }
449 :
450 : JSObject*
451 0 : GetConstructorObject(JSContext* aCx)
452 : {
453 0 : return GetConstructorObjectHandle(aCx);
454 : }
455 :
456 : } // namespace WorkletBinding
457 :
458 :
459 :
460 : } // namespace dom
461 : } // namespace mozilla
|