Line data Source code
1 : /* THIS FILE IS AUTOGENERATED FROM Plugin.webidl BY Codegen.py - DO NOT EDIT */
2 :
3 : #include "PluginBinding.h"
4 : #include "WrapperFactory.h"
5 : #include "mozilla/OwningNonNull.h"
6 : #include "mozilla/dom/BindingUtils.h"
7 : #include "mozilla/dom/DOMJSClass.h"
8 : #include "mozilla/dom/DOMJSProxyHandler.h"
9 : #include "mozilla/dom/NonRefcountedDOMObject.h"
10 : #include "mozilla/dom/Nullable.h"
11 : #include "mozilla/dom/PrimitiveConversions.h"
12 : #include "mozilla/dom/XrayExpandoClass.h"
13 : #include "nsISupports.h"
14 : #include "nsMimeTypeArray.h"
15 : #include "nsPluginArray.h"
16 : #include "xpcjsid.h"
17 :
18 : namespace mozilla {
19 : namespace dom {
20 :
21 : namespace PluginBinding {
22 :
23 : static bool
24 0 : get_description(JSContext* cx, JS::Handle<JSObject*> obj, nsPluginElement* self, JSJitGetterCallArgs args)
25 : {
26 0 : DOMString result;
27 0 : self->GetDescription(result);
28 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
29 0 : if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
30 0 : return false;
31 : }
32 0 : return true;
33 : }
34 :
35 : static const JSJitInfo description_getterinfo = {
36 : { (JSJitGetterOp)get_description },
37 : { prototypes::id::Plugin },
38 : { PrototypeTraits<prototypes::id::Plugin>::Depth },
39 : JSJitInfo::Getter,
40 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
41 : JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
42 : false, /* isInfallible. False in setters. */
43 : false, /* isMovable. Not relevant for setters. */
44 : false, /* isEliminatable. Not relevant for setters. */
45 : false, /* isAlwaysInSlot. Only relevant for getters. */
46 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
47 : false, /* isTypedMethod. Only relevant for methods. */
48 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
49 : };
50 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
51 : static_assert(0 < 1, "There is no slot for us");
52 :
53 : static bool
54 0 : get_filename(JSContext* cx, JS::Handle<JSObject*> obj, nsPluginElement* self, JSJitGetterCallArgs args)
55 : {
56 0 : DOMString result;
57 0 : self->GetFilename(result);
58 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
59 0 : if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
60 0 : return false;
61 : }
62 0 : return true;
63 : }
64 :
65 : static const JSJitInfo filename_getterinfo = {
66 : { (JSJitGetterOp)get_filename },
67 : { prototypes::id::Plugin },
68 : { PrototypeTraits<prototypes::id::Plugin>::Depth },
69 : JSJitInfo::Getter,
70 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
71 : JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
72 : false, /* isInfallible. False in setters. */
73 : false, /* isMovable. Not relevant for setters. */
74 : false, /* isEliminatable. Not relevant for setters. */
75 : false, /* isAlwaysInSlot. Only relevant for getters. */
76 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
77 : false, /* isTypedMethod. Only relevant for methods. */
78 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
79 : };
80 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
81 : static_assert(0 < 1, "There is no slot for us");
82 :
83 : static bool
84 0 : get_version(JSContext* cx, JS::Handle<JSObject*> obj, nsPluginElement* self, JSJitGetterCallArgs args)
85 : {
86 0 : DOMString result;
87 0 : self->GetVersion(result);
88 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
89 0 : if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
90 0 : return false;
91 : }
92 0 : return true;
93 : }
94 :
95 : static const JSJitInfo version_getterinfo = {
96 : { (JSJitGetterOp)get_version },
97 : { prototypes::id::Plugin },
98 : { PrototypeTraits<prototypes::id::Plugin>::Depth },
99 : JSJitInfo::Getter,
100 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
101 : JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
102 : false, /* isInfallible. False in setters. */
103 : false, /* isMovable. Not relevant for setters. */
104 : false, /* isEliminatable. Not relevant for setters. */
105 : false, /* isAlwaysInSlot. Only relevant for getters. */
106 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
107 : false, /* isTypedMethod. Only relevant for methods. */
108 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
109 : };
110 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
111 : static_assert(0 < 1, "There is no slot for us");
112 :
113 : static bool
114 0 : get_name(JSContext* cx, JS::Handle<JSObject*> obj, nsPluginElement* self, JSJitGetterCallArgs args)
115 : {
116 0 : DOMString result;
117 0 : self->GetName(result);
118 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
119 0 : if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
120 0 : return false;
121 : }
122 0 : return true;
123 : }
124 :
125 : static const JSJitInfo name_getterinfo = {
126 : { (JSJitGetterOp)get_name },
127 : { prototypes::id::Plugin },
128 : { PrototypeTraits<prototypes::id::Plugin>::Depth },
129 : JSJitInfo::Getter,
130 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
131 : JSVAL_TYPE_STRING, /* returnType. Not relevant for setters. */
132 : false, /* isInfallible. False in setters. */
133 : false, /* isMovable. Not relevant for setters. */
134 : false, /* isEliminatable. Not relevant for setters. */
135 : false, /* isAlwaysInSlot. Only relevant for getters. */
136 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
137 : false, /* isTypedMethod. Only relevant for methods. */
138 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
139 : };
140 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
141 : static_assert(0 < 1, "There is no slot for us");
142 :
143 : static bool
144 0 : get_length(JSContext* cx, JS::Handle<JSObject*> obj, nsPluginElement* self, JSJitGetterCallArgs args)
145 : {
146 0 : uint32_t result(self->Length());
147 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
148 0 : args.rval().setNumber(result);
149 0 : return true;
150 : }
151 :
152 : static const JSJitInfo length_getterinfo = {
153 : { (JSJitGetterOp)get_length },
154 : { prototypes::id::Plugin },
155 : { PrototypeTraits<prototypes::id::Plugin>::Depth },
156 : JSJitInfo::Getter,
157 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
158 : JSVAL_TYPE_DOUBLE, /* returnType. Not relevant for setters. */
159 : true, /* isInfallible. False in setters. */
160 : false, /* isMovable. Not relevant for setters. */
161 : false, /* isEliminatable. Not relevant for setters. */
162 : false, /* isAlwaysInSlot. Only relevant for getters. */
163 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
164 : false, /* isTypedMethod. Only relevant for methods. */
165 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
166 : };
167 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
168 : static_assert(0 < 1, "There is no slot for us");
169 :
170 : static bool
171 0 : item(JSContext* cx, JS::Handle<JSObject*> obj, nsPluginElement* self, const JSJitMethodCallArgs& args)
172 : {
173 0 : if (MOZ_UNLIKELY(args.length() < 1)) {
174 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "Plugin.item");
175 : }
176 : uint32_t arg0;
177 0 : if (!ValueToPrimitive<uint32_t, eDefault>(cx, args[0], &arg0)) {
178 0 : return false;
179 : }
180 0 : auto result(StrongOrRawPtr<nsMimeType>(self->Item(arg0)));
181 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
182 0 : if (!result) {
183 0 : args.rval().setNull();
184 0 : return true;
185 : }
186 0 : if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
187 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
188 0 : return false;
189 : }
190 0 : return true;
191 : }
192 :
193 : static const JSJitInfo item_methodinfo = {
194 : { (JSJitGetterOp)item },
195 : { prototypes::id::Plugin },
196 : { PrototypeTraits<prototypes::id::Plugin>::Depth },
197 : JSJitInfo::Method,
198 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
199 : JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */
200 : false, /* isInfallible. False in setters. */
201 : false, /* isMovable. Not relevant for setters. */
202 : false, /* isEliminatable. Not relevant for setters. */
203 : false, /* isAlwaysInSlot. Only relevant for getters. */
204 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
205 : false, /* isTypedMethod. Only relevant for methods. */
206 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
207 : };
208 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
209 : static_assert(0 < 1, "There is no slot for us");
210 :
211 : static bool
212 0 : namedItem(JSContext* cx, JS::Handle<JSObject*> obj, nsPluginElement* self, const JSJitMethodCallArgs& args)
213 : {
214 0 : if (MOZ_UNLIKELY(args.length() < 1)) {
215 0 : return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "Plugin.namedItem");
216 : }
217 0 : binding_detail::FakeString arg0;
218 0 : if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
219 0 : return false;
220 : }
221 0 : auto result(StrongOrRawPtr<nsMimeType>(self->NamedItem(NonNullHelper(Constify(arg0)))));
222 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
223 0 : if (!result) {
224 0 : args.rval().setNull();
225 0 : return true;
226 : }
227 0 : if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
228 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
229 0 : return false;
230 : }
231 0 : return true;
232 : }
233 :
234 : static const JSJitInfo namedItem_methodinfo = {
235 : { (JSJitGetterOp)namedItem },
236 : { prototypes::id::Plugin },
237 : { PrototypeTraits<prototypes::id::Plugin>::Depth },
238 : JSJitInfo::Method,
239 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
240 : JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */
241 : false, /* isInfallible. False in setters. */
242 : false, /* isMovable. Not relevant for setters. */
243 : false, /* isEliminatable. Not relevant for setters. */
244 : false, /* isAlwaysInSlot. Only relevant for getters. */
245 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
246 : false, /* isTypedMethod. Only relevant for methods. */
247 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
248 : };
249 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
250 : static_assert(0 < 1, "There is no slot for us");
251 :
252 : static void
253 0 : _objectMoved(JSObject* obj, const JSObject* old)
254 : {
255 0 : nsPluginElement* self = UnwrapPossiblyNotInitializedDOMObject<nsPluginElement>(obj);
256 0 : if (self) {
257 0 : UpdateWrapper(self, self, obj, old);
258 : }
259 0 : }
260 :
261 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
262 : #if defined(__clang__)
263 : #pragma clang diagnostic push
264 : #pragma clang diagnostic ignored "-Wmissing-braces"
265 : #endif
266 : static const JSFunctionSpec sMethods_specs[] = {
267 : JS_FNSPEC("item", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&item_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
268 : JS_FNSPEC("namedItem", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&namedItem_methodinfo), 1, JSPROP_ENUMERATE, nullptr),
269 : JS_FS_END,
270 : JS_FNSPEC("QueryInterface", QueryInterface, nullptr, 1, 0, nullptr),
271 : JS_FS_END,
272 : JS_SYM_FNSPEC(iterator, nullptr, nullptr, 0, 0, "ArrayValues"),
273 : JS_FS_END
274 : };
275 : #if defined(__clang__)
276 : #pragma clang diagnostic pop
277 : #endif
278 :
279 : static PrefableDisablers sMethods_disablers3 = {
280 : true, false, 0, &WantsQueryInterface<nsPluginElement>::Enabled
281 : };
282 :
283 : // Can't be const because the pref-enabled boolean needs to be writable
284 : static Prefable<const JSFunctionSpec> sMethods[] = {
285 : { nullptr, &sMethods_specs[0] },
286 : { &sMethods_disablers3, &sMethods_specs[3] },
287 : { nullptr, &sMethods_specs[5] },
288 : { nullptr, nullptr }
289 : };
290 :
291 : static_assert(3 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
292 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
293 : static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
294 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
295 :
296 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
297 : #if defined(__clang__)
298 : #pragma clang diagnostic push
299 : #pragma clang diagnostic ignored "-Wmissing-braces"
300 : #endif
301 : static const JSPropertySpec sAttributes_specs[] = {
302 : { "description", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &description_getterinfo, nullptr, nullptr },
303 : { "filename", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &filename_getterinfo, nullptr, nullptr },
304 : { "version", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &version_getterinfo, nullptr, nullptr },
305 : { "name", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &name_getterinfo, nullptr, nullptr },
306 : { "length", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &length_getterinfo, nullptr, nullptr },
307 : { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
308 : };
309 : #if defined(__clang__)
310 : #pragma clang diagnostic pop
311 : #endif
312 :
313 :
314 : // Can't be const because the pref-enabled boolean needs to be writable
315 : static Prefable<const JSPropertySpec> sAttributes[] = {
316 : { nullptr, &sAttributes_specs[0] },
317 : { nullptr, nullptr }
318 : };
319 :
320 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
321 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
322 : static_assert(5 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
323 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
324 :
325 :
326 : static uint16_t sNativeProperties_sortedPropertyIndices[9];
327 : static PropertyInfo sNativeProperties_propertyInfos[9];
328 :
329 : static const NativePropertiesN<2> sNativeProperties = {
330 : false, 0,
331 : false, 0,
332 : true, 0 /* sMethods */,
333 : true, 1 /* sAttributes */,
334 : false, 0,
335 : false, 0,
336 : false, 0,
337 : -1,
338 : 9,
339 : sNativeProperties_sortedPropertyIndices,
340 : {
341 : { sMethods, &sNativeProperties_propertyInfos[0] },
342 : { sAttributes, &sNativeProperties_propertyInfos[4] }
343 : }
344 : };
345 : static_assert(9 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
346 : "We have a property info count that is oversized");
347 :
348 : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
349 : {
350 : "Function",
351 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
352 : &sBoringInterfaceObjectClassClassOps,
353 : JS_NULL_CLASS_SPEC,
354 : JS_NULL_CLASS_EXT,
355 : &sInterfaceObjectClassObjectOps
356 : },
357 : eInterface,
358 : true,
359 : prototypes::id::Plugin,
360 : PrototypeTraits<prototypes::id::Plugin>::Depth,
361 : sNativePropertyHooks,
362 : "function Plugin() {\n [native code]\n}",
363 : JS::GetRealmFunctionPrototype
364 : };
365 :
366 : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
367 : {
368 : "PluginPrototype",
369 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
370 : JS_NULL_CLASS_OPS,
371 : JS_NULL_CLASS_SPEC,
372 : JS_NULL_CLASS_EXT,
373 : JS_NULL_OBJECT_OPS
374 : },
375 : eInterfacePrototype,
376 : false,
377 : prototypes::id::Plugin,
378 : PrototypeTraits<prototypes::id::Plugin>::Depth,
379 : sNativePropertyHooks,
380 : "[object PluginPrototype]",
381 : JS::GetRealmObjectPrototype
382 : };
383 :
384 : JSObject*
385 0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
386 : {
387 0 : return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
388 : }
389 :
390 : static_assert(IsBaseOf<nsISupports, nsPluginElement >::value,
391 : "We don't support non-nsISupports native classes for "
392 : "proxy-based bindings yet");
393 :
394 :
395 : class DOMProxyHandler : public mozilla::dom::DOMProxyHandler
396 : {
397 : public:
398 : explicit constexpr DOMProxyHandler()
399 : {
400 : }
401 :
402 : virtual bool
403 : getOwnPropDescriptor(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool ignoreNamedProps, JS::MutableHandle<JS::PropertyDescriptor> desc) const override;
404 :
405 : virtual bool
406 : defineProperty(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, JS::Handle<JS::PropertyDescriptor> desc, JS::ObjectOpResult& opresult, bool* defined) const override;
407 :
408 : using mozilla::dom::DOMProxyHandler::defineProperty;
409 :
410 : virtual bool
411 : ownPropNames(JSContext* cx, JS::Handle<JSObject*> proxy, unsigned flags, JS::AutoIdVector& props) const override;
412 :
413 : virtual bool
414 : hasOwn(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool* bp) const override;
415 :
416 : virtual bool
417 : get(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<JS::Value> receiver, JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp) const override;
418 :
419 : virtual const char*
420 : className(JSContext* cx, JS::Handle<JSObject*> proxy) const override;
421 :
422 : virtual bool
423 : finalizeInBackground(const JS::Value& priv) const override;
424 :
425 : virtual void
426 : finalize(JSFreeOp* fop, JSObject* proxy) const override;
427 :
428 : static const DOMProxyHandler*
429 : getInstance();
430 :
431 : virtual bool
432 : delete_(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, JS::ObjectOpResult& opresult) const override;
433 :
434 : virtual bool
435 : getElements(JSContext* cx, JS::Handle<JSObject*> proxy, uint32_t begin, uint32_t end, js::ElementAdder* adder) const override;
436 : };
437 :
438 : MOZ_ALWAYS_INLINE bool
439 0 : IsProxy(JSObject* obj)
440 : {
441 0 : return js::IsProxy(obj) && js::GetProxyHandler(obj) == DOMProxyHandler::getInstance();
442 : }
443 :
444 : MOZ_ALWAYS_INLINE nsPluginElement*
445 0 : UnwrapProxy(JSObject* obj)
446 : {
447 0 : MOZ_ASSERT(js::IsProxy(obj));
448 0 : if (js::GetProxyHandler(obj) != DOMProxyHandler::getInstance()) {
449 0 : MOZ_ASSERT(xpc::WrapperFactory::IsXrayWrapper(obj));
450 0 : obj = js::UncheckedUnwrap(obj);
451 : }
452 0 : MOZ_ASSERT(IsProxy(obj));
453 0 : return static_cast<nsPluginElement*>(js::GetProxyReservedSlot(obj, DOM_OBJECT_SLOT).toPrivate());
454 : }
455 :
456 : bool
457 0 : DOMProxyHandler::getOwnPropDescriptor(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool ignoreNamedProps, JS::MutableHandle<JS::PropertyDescriptor> desc) const
458 : {
459 0 : bool isXray = xpc::WrapperFactory::IsXrayWrapper(proxy);
460 0 : uint32_t index = GetArrayIndexFromId(cx, id);
461 0 : if (IsArrayIndex(index)) {
462 0 : nsPluginElement* self = UnwrapProxy(proxy);
463 0 : bool found = false;
464 0 : auto result(StrongOrRawPtr<nsMimeType>(self->IndexedGetter(index, found)));
465 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
466 :
467 0 : if (found) {
468 0 : if (!result) {
469 0 : desc.value().setNull();
470 0 : FillPropertyDescriptor(desc, proxy, true);
471 0 : return true;
472 : }
473 0 : if (!GetOrCreateDOMReflector(cx, result, desc.value())) {
474 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
475 0 : return false;
476 : }
477 0 : FillPropertyDescriptor(desc, proxy, true);
478 0 : return true;
479 : }
480 : }
481 :
482 0 : JS::Rooted<JSObject*> expando(cx);
483 0 : if (!isXray && (expando = GetExpandoObject(proxy))) {
484 0 : if (!JS_GetOwnPropertyDescriptorById(cx, expando, id, desc)) {
485 0 : return false;
486 : }
487 0 : if (desc.object()) {
488 : // Pretend the property lives on the wrapper.
489 0 : desc.object().set(proxy);
490 0 : return true;
491 : }
492 : }
493 :
494 0 : bool callNamedGetter = false;
495 0 : if (!IsArrayIndex(index) && !ignoreNamedProps) {
496 : bool hasOnProto;
497 0 : if (!HasPropertyOnPrototype(cx, proxy, id, &hasOnProto)) {
498 0 : return false;
499 : }
500 0 : callNamedGetter = !hasOnProto;
501 : }
502 0 : if (callNamedGetter) {
503 0 : binding_detail::FakeString name;
504 : bool isSymbol;
505 0 : if (!ConvertIdToString(cx, id, name, isSymbol)) {
506 0 : return false;
507 : }
508 0 : if (!isSymbol) {
509 0 : nsPluginElement* self = UnwrapProxy(proxy);
510 0 : bool found = false;
511 0 : auto result(StrongOrRawPtr<nsMimeType>(self->NamedGetter(NonNullHelper(Constify(name)), found)));
512 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
513 :
514 0 : if (found) {
515 0 : if (!result) {
516 0 : desc.value().setNull();
517 0 : FillPropertyDescriptor(desc, proxy, true, false);
518 0 : return true;
519 : }
520 0 : if (!GetOrCreateDOMReflector(cx, result, desc.value())) {
521 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
522 0 : return false;
523 : }
524 0 : FillPropertyDescriptor(desc, proxy, true, false);
525 0 : return true;
526 : }
527 : }
528 : }
529 :
530 0 : desc.object().set(nullptr);
531 0 : return true;
532 : }
533 :
534 : bool
535 0 : DOMProxyHandler::defineProperty(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, JS::Handle<JS::PropertyDescriptor> desc, JS::ObjectOpResult& opresult, bool* defined) const
536 : {
537 0 : if (IsArrayIndex(GetArrayIndexFromId(cx, id))) {
538 0 : *defined = true;
539 0 : return opresult.failNoIndexedSetter();
540 : }
541 0 : bool found = false;
542 0 : binding_detail::FakeString name;
543 : bool isSymbol;
544 0 : if (!ConvertIdToString(cx, id, name, isSymbol)) {
545 0 : return false;
546 : }
547 0 : if (!isSymbol) {
548 0 : nsPluginElement* self = UnwrapProxy(proxy);
549 0 : auto result(StrongOrRawPtr<nsMimeType>(self->NamedGetter(NonNullHelper(Constify(name)), found)));
550 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
551 : (void)result;
552 : }
553 :
554 0 : if (found) {
555 0 : *defined = true;
556 0 : return opresult.failNoNamedSetter();
557 : }
558 0 : return mozilla::dom::DOMProxyHandler::defineProperty(cx, proxy, id, desc, opresult, defined);
559 : }
560 :
561 :
562 : bool
563 0 : DOMProxyHandler::ownPropNames(JSContext* cx, JS::Handle<JSObject*> proxy, unsigned flags, JS::AutoIdVector& props) const
564 : {
565 0 : bool isXray = xpc::WrapperFactory::IsXrayWrapper(proxy);
566 :
567 0 : uint32_t length = UnwrapProxy(proxy)->Length();
568 0 : MOZ_ASSERT(int32_t(length) >= 0);
569 0 : for (int32_t i = 0; i < int32_t(length); ++i) {
570 0 : if (!props.append(INT_TO_JSID(i))) {
571 0 : return false;
572 : }
573 : }
574 :
575 0 : if (flags & JSITER_HIDDEN) {
576 0 : nsTArray<nsString> names;
577 0 : UnwrapProxy(proxy)->GetSupportedNames(names);
578 0 : if (!AppendNamedPropertyIds(cx, proxy, names, false, props)) {
579 0 : return false;
580 : }
581 : }
582 :
583 0 : JS::Rooted<JSObject*> expando(cx);
584 0 : if (!isXray && (expando = DOMProxyHandler::GetExpandoObject(proxy)) &&
585 0 : !js::GetPropertyKeys(cx, expando, flags, &props)) {
586 0 : return false;
587 : }
588 :
589 0 : return true;
590 : }
591 :
592 : bool
593 0 : DOMProxyHandler::hasOwn(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, bool* bp) const
594 : {
595 0 : MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
596 : "Should not have a XrayWrapper here");
597 :
598 0 : uint32_t index = GetArrayIndexFromId(cx, id);
599 0 : if (IsArrayIndex(index)) {
600 0 : bool found = false;
601 0 : nsPluginElement* self = UnwrapProxy(proxy);
602 0 : auto result(StrongOrRawPtr<nsMimeType>(self->IndexedGetter(index, found)));
603 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
604 : (void)result;
605 :
606 0 : *bp = found;
607 0 : return true;
608 : }
609 :
610 :
611 0 : JS::Rooted<JSObject*> expando(cx, GetExpandoObject(proxy));
612 0 : if (expando) {
613 0 : bool b = true;
614 0 : bool ok = JS_HasPropertyById(cx, expando, id, &b);
615 0 : *bp = !!b;
616 0 : if (!ok || *bp) {
617 0 : return ok;
618 : }
619 : }
620 :
621 : bool hasOnProto;
622 0 : if (!HasPropertyOnPrototype(cx, proxy, id, &hasOnProto)) {
623 0 : return false;
624 : }
625 0 : if (!hasOnProto) {
626 0 : bool found = false;
627 0 : binding_detail::FakeString name;
628 : bool isSymbol;
629 0 : if (!ConvertIdToString(cx, id, name, isSymbol)) {
630 0 : return false;
631 : }
632 0 : if (!isSymbol) {
633 0 : nsPluginElement* self = UnwrapProxy(proxy);
634 0 : auto result(StrongOrRawPtr<nsMimeType>(self->NamedGetter(NonNullHelper(Constify(name)), found)));
635 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
636 : (void)result;
637 : }
638 :
639 0 : *bp = found;
640 0 : return true;
641 : }
642 0 : *bp = false;
643 0 : return true;
644 : }
645 :
646 : bool
647 0 : DOMProxyHandler::get(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<JS::Value> receiver, JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp) const
648 : {
649 0 : MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
650 : "Should not have a XrayWrapper here");
651 :
652 0 : uint32_t index = GetArrayIndexFromId(cx, id);
653 0 : if (IsArrayIndex(index)) {
654 0 : nsPluginElement* self = UnwrapProxy(proxy);
655 0 : bool found = false;
656 0 : auto result(StrongOrRawPtr<nsMimeType>(self->IndexedGetter(index, found)));
657 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
658 :
659 0 : if (found) {
660 0 : if (!result) {
661 0 : vp.setNull();
662 0 : return true;
663 : }
664 0 : if (!GetOrCreateDOMReflector(cx, result, vp)) {
665 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
666 0 : return false;
667 : }
668 0 : return true;
669 : }
670 : // Even if we don't have this index, we don't forward the
671 : // get on to our expando object.
672 : } else {
673 : { // Scope for expando
674 0 : JS::Rooted<JSObject*> expando(cx, DOMProxyHandler::GetExpandoObject(proxy));
675 0 : if (expando) {
676 : bool hasProp;
677 0 : if (!JS_HasPropertyById(cx, expando, id, &hasProp)) {
678 0 : return false;
679 : }
680 :
681 0 : if (hasProp) {
682 : // Forward the get to the expando object, but our receiver is whatever our
683 : // receiver is.
684 0 : return JS_ForwardGetPropertyTo(cx, expando, id, receiver, vp);
685 : }
686 : }
687 : }
688 : }
689 :
690 : bool foundOnPrototype;
691 0 : if (!GetPropertyOnPrototype(cx, proxy, receiver, id, &foundOnPrototype, vp)) {
692 0 : return false;
693 : }
694 :
695 0 : if (foundOnPrototype) {
696 0 : return true;
697 : }
698 :
699 0 : if (!IsArrayIndex(index)) {
700 0 : binding_detail::FakeString name;
701 : bool isSymbol;
702 0 : if (!ConvertIdToString(cx, id, name, isSymbol)) {
703 0 : return false;
704 : }
705 0 : if (!isSymbol) {
706 0 : nsPluginElement* self = UnwrapProxy(proxy);
707 0 : bool found = false;
708 0 : auto result(StrongOrRawPtr<nsMimeType>(self->NamedGetter(NonNullHelper(Constify(name)), found)));
709 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
710 :
711 0 : if (found) {
712 0 : if (!result) {
713 0 : vp.setNull();
714 0 : return true;
715 : }
716 0 : if (!GetOrCreateDOMReflector(cx, result, vp)) {
717 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
718 0 : return false;
719 : }
720 0 : return true;
721 : }
722 : }
723 : }
724 :
725 0 : vp.setUndefined();
726 0 : return true;
727 : }
728 :
729 : const char*
730 0 : DOMProxyHandler::className(JSContext* cx, JS::Handle<JSObject*> proxy) const
731 : {
732 0 : return "Plugin";
733 : }
734 :
735 : bool
736 0 : DOMProxyHandler::finalizeInBackground(const JS::Value& priv) const
737 : {
738 0 : return false;
739 : }
740 :
741 : void
742 0 : DOMProxyHandler::finalize(JSFreeOp* fop, JSObject* proxy) const
743 : {
744 0 : nsPluginElement* self = UnwrapPossiblyNotInitializedDOMObject<nsPluginElement>(proxy);
745 0 : if (self) {
746 0 : ClearWrapper(self, self, proxy);
747 0 : AddForDeferredFinalization<nsPluginElement>(self);
748 : }
749 0 : }
750 :
751 : const DOMProxyHandler*
752 0 : DOMProxyHandler::getInstance()
753 : {
754 : static const DOMProxyHandler instance;
755 0 : return &instance;
756 : }
757 :
758 : bool
759 0 : DOMProxyHandler::delete_(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, JS::ObjectOpResult& opresult) const
760 : {
761 0 : MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
762 : "Should not have a XrayWrapper here");
763 :
764 0 : uint32_t index = GetArrayIndexFromId(cx, id);
765 0 : if (IsArrayIndex(index)) {
766 : bool deleteSucceeded;
767 0 : bool found = false;
768 0 : nsPluginElement* self = UnwrapProxy(proxy);
769 0 : auto result(StrongOrRawPtr<nsMimeType>(self->IndexedGetter(index, found)));
770 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
771 : (void)result;
772 0 : deleteSucceeded = !found;
773 0 : return deleteSucceeded ? opresult.succeed() : opresult.failCantDelete();
774 : }
775 : // Try named delete only if the named property visibility
776 : // algorithm says the property is visible.
777 0 : bool tryNamedDelete = true;
778 : { // Scope for expando
779 0 : JS::Rooted<JSObject*> expando(cx, DOMProxyHandler::GetExpandoObject(proxy));
780 0 : if (expando) {
781 : bool hasProp;
782 0 : if (!JS_HasPropertyById(cx, expando, id, &hasProp)) {
783 0 : return false;
784 : }
785 0 : tryNamedDelete = !hasProp;
786 : }
787 : }
788 0 : if (tryNamedDelete) {
789 : bool hasOnProto;
790 0 : if (!HasPropertyOnPrototype(cx, proxy, id, &hasOnProto)) {
791 0 : return false;
792 : }
793 0 : tryNamedDelete = !hasOnProto;
794 : }
795 0 : if (tryNamedDelete) {
796 0 : bool found = false;
797 : bool deleteSucceeded;
798 0 : binding_detail::FakeString name;
799 : bool isSymbol;
800 0 : if (!ConvertIdToString(cx, id, name, isSymbol)) {
801 0 : return false;
802 : }
803 0 : if (!isSymbol) {
804 0 : nsPluginElement* self = UnwrapProxy(proxy);
805 0 : auto result(StrongOrRawPtr<nsMimeType>(self->NamedGetter(NonNullHelper(Constify(name)), found)));
806 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
807 : (void)result;
808 : }
809 0 : deleteSucceeded = !found;
810 0 : if (found) {
811 0 : return deleteSucceeded ? opresult.succeed() : opresult.failCantDelete();
812 : }
813 : }
814 :
815 0 : return dom::DOMProxyHandler::delete_(cx, proxy, id, opresult);
816 : }
817 :
818 : bool
819 0 : DOMProxyHandler::getElements(JSContext* cx, JS::Handle<JSObject*> proxy, uint32_t begin, uint32_t end, js::ElementAdder* adder) const
820 : {
821 0 : JS::Rooted<JS::Value> temp(cx);
822 0 : MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
823 : "Should not have a XrayWrapper here");
824 :
825 0 : nsPluginElement* self = UnwrapProxy(proxy);
826 0 : uint32_t length = self->Length();
827 : // Compute the end of the indices we'll get ourselves
828 0 : uint32_t ourEnd = std::max(begin, std::min(end, length));
829 :
830 0 : for (uint32_t index = begin; index < ourEnd; ++index) {
831 0 : bool found = false;
832 0 : auto result(StrongOrRawPtr<nsMimeType>(self->IndexedGetter(index, found)));
833 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
834 :
835 0 : MOZ_ASSERT(found);
836 0 : if (!result) {
837 0 : temp.setNull();
838 0 : if (!adder->append(cx, temp)) return false;
839 0 : continue;
840 : }
841 0 : if (!GetOrCreateDOMReflector(cx, result, &temp)) {
842 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
843 0 : return false;
844 : }
845 0 : if (!adder->append(cx, temp)) return false;
846 0 : continue;
847 : }
848 :
849 0 : if (end > ourEnd) {
850 0 : JS::Rooted<JSObject*> proto(cx);
851 0 : if (!js::GetObjectProto(cx, proxy, &proto)) {
852 0 : return false;
853 : }
854 0 : return js::GetElementsWithAdder(cx, proto, proxy, ourEnd, end, adder);
855 : }
856 :
857 0 : return true;
858 : }
859 :
860 : static const js::ClassExtension sClassExtension = PROXY_MAKE_EXT(
861 : _objectMoved
862 : );
863 :
864 : static const DOMJSClass sClass = {
865 : PROXY_CLASS_WITH_EXT("Plugin",
866 : JSCLASS_IS_DOMJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(1),
867 : &sClassExtension),
868 : { prototypes::id::Plugin, 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 },
869 : IsBaseOf<nsISupports, nsPluginElement >::value,
870 : sNativePropertyHooks,
871 : FindAssociatedGlobalForNative<nsPluginElement>::Get,
872 : GetProtoObjectHandle,
873 : GetCCParticipant<nsPluginElement>::Get()
874 : };
875 :
876 : bool
877 0 : Wrap(JSContext* aCx, nsPluginElement* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
878 : {
879 : MOZ_ASSERT(static_cast<nsPluginElement*>(aObject) ==
880 : reinterpret_cast<nsPluginElement*>(aObject),
881 : "Multiple inheritance for nsPluginElement is broken.");
882 0 : MOZ_ASSERT(ToSupportsIsCorrect(aObject));
883 0 : MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
884 0 : MOZ_ASSERT(!aCache->GetWrapper(),
885 : "You should probably not be using Wrap() directly; use "
886 : "GetOrCreateDOMReflector instead");
887 :
888 0 : MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
889 : "nsISupports must be on our primary inheritance chain");
890 :
891 0 : JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
892 0 : if (!global) {
893 0 : return false;
894 : }
895 0 : MOZ_ASSERT(JS_IsGlobalObject(global));
896 0 : MOZ_ASSERT(JS::ObjectIsNotGray(global));
897 :
898 : // That might have ended up wrapping us already, due to the wonders
899 : // of XBL. Check for that, and bail out as needed.
900 0 : aReflector.set(aCache->GetWrapper());
901 0 : if (aReflector) {
902 : #ifdef DEBUG
903 0 : binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
904 : #endif // DEBUG
905 0 : return true;
906 : }
907 :
908 0 : JSAutoCompartment ac(aCx, global);
909 0 : JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
910 0 : if (!canonicalProto) {
911 0 : return false;
912 : }
913 0 : JS::Rooted<JSObject*> proto(aCx);
914 0 : if (aGivenProto) {
915 0 : proto = aGivenProto;
916 : // Unfortunately, while aGivenProto was in the compartment of aCx
917 : // coming in, we changed compartments to that of "parent" so may need
918 : // to wrap the proto here.
919 0 : if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
920 0 : if (!JS_WrapObject(aCx, &proto)) {
921 0 : return false;
922 : }
923 : }
924 : } else {
925 0 : proto = canonicalProto;
926 : }
927 :
928 0 : BindingJSObjectCreator<nsPluginElement> creator(aCx);
929 0 : JS::Rooted<JS::Value> expandoValue(aCx, JS::UndefinedValue());
930 0 : creator.CreateProxyObject(aCx, &sClass.mBase, DOMProxyHandler::getInstance(),
931 0 : proto, aObject, expandoValue, aReflector);
932 0 : if (!aReflector) {
933 0 : return false;
934 : }
935 :
936 :
937 0 : aCache->SetWrapper(aReflector);
938 0 : creator.InitializationSucceeded();
939 :
940 0 : MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
941 : aCache->GetWrapperPreserveColor() == aReflector);
942 : // If proto != canonicalProto, we have to preserve our wrapper;
943 : // otherwise we won't be able to properly recreate it later, since
944 : // we won't know what proto to use. Note that we don't check
945 : // aGivenProto here, since it's entirely possible (and even
946 : // somewhat common) to have a non-null aGivenProto which is the
947 : // same as canonicalProto.
948 0 : if (proto != canonicalProto) {
949 0 : PreserveWrapper(aObject);
950 : }
951 :
952 0 : return true;
953 : }
954 :
955 : static bool
956 0 : ResolveOwnProperty(JSContext* cx, JS::Handle<JSObject*> wrapper, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::MutableHandle<JS::PropertyDescriptor> desc)
957 : {
958 0 : return js::GetProxyHandler(obj)->getOwnPropertyDescriptor(cx, wrapper, id, desc);
959 : }
960 :
961 : static bool
962 0 : EnumerateOwnProperties(JSContext* cx, JS::Handle<JSObject*> wrapper, JS::Handle<JSObject*> obj, JS::AutoIdVector& props)
963 : {
964 0 : return js::GetProxyHandler(obj)->ownPropertyKeys(cx, wrapper, props);
965 : }
966 :
967 : const NativePropertyHooks sNativePropertyHooks[] = { {
968 : ResolveOwnProperty,
969 : EnumerateOwnProperties,
970 : nullptr,
971 : { sNativeProperties.Upcast(), nullptr },
972 : prototypes::id::Plugin,
973 : constructors::id::Plugin,
974 : nullptr,
975 : &DefaultXrayExpandoObjectClass
976 : } };
977 :
978 : void
979 0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
980 : {
981 0 : JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
982 0 : if (!parentProto) {
983 0 : return;
984 : }
985 :
986 0 : JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
987 0 : if (!constructorProto) {
988 0 : return;
989 : }
990 :
991 : static bool sIdsInited = false;
992 0 : if (!sIdsInited && NS_IsMainThread()) {
993 0 : if (!InitIds(aCx, sNativeProperties.Upcast())) {
994 0 : return;
995 : }
996 0 : sIdsInited = true;
997 : }
998 :
999 0 : JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::Plugin);
1000 0 : JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::Plugin);
1001 0 : dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
1002 : &sPrototypeClass.mBase, protoCache,
1003 : constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
1004 : interfaceCache,
1005 : sNativeProperties.Upcast(),
1006 : nullptr,
1007 : "Plugin", aDefineOnGlobal,
1008 : nullptr,
1009 0 : false);
1010 : }
1011 :
1012 : JS::Handle<JSObject*>
1013 0 : GetProtoObjectHandle(JSContext* aCx)
1014 : {
1015 : /* Get the interface prototype object for this class. This will create the
1016 : object as needed. */
1017 0 : bool aDefineOnGlobal = true;
1018 :
1019 : /* Make sure our global is sane. Hopefully we can remove this sometime */
1020 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
1021 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
1022 0 : return nullptr;
1023 : }
1024 :
1025 : /* Check to see whether the interface objects are already installed */
1026 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
1027 0 : if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::Plugin)) {
1028 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
1029 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
1030 : }
1031 :
1032 : /*
1033 : * The object might _still_ be null, but that's OK.
1034 : *
1035 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
1036 : * traced by TraceProtoAndIfaceCache() and its contents are never
1037 : * changed after they have been set.
1038 : *
1039 : * Calling address() avoids the read read barrier that does gray
1040 : * unmarking, but it's not possible for the object to be gray here.
1041 : */
1042 :
1043 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::Plugin);
1044 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
1045 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
1046 : }
1047 :
1048 : JS::Handle<JSObject*>
1049 0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
1050 : {
1051 : /* Get the interface object for this class. This will create the object as
1052 : needed. */
1053 :
1054 : /* Make sure our global is sane. Hopefully we can remove this sometime */
1055 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
1056 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
1057 0 : return nullptr;
1058 : }
1059 :
1060 : /* Check to see whether the interface objects are already installed */
1061 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
1062 0 : if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::Plugin)) {
1063 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
1064 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
1065 : }
1066 :
1067 : /*
1068 : * The object might _still_ be null, but that's OK.
1069 : *
1070 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
1071 : * traced by TraceProtoAndIfaceCache() and its contents are never
1072 : * changed after they have been set.
1073 : *
1074 : * Calling address() avoids the read read barrier that does gray
1075 : * unmarking, but it's not possible for the object to be gray here.
1076 : */
1077 :
1078 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::Plugin);
1079 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
1080 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
1081 : }
1082 :
1083 : JSObject*
1084 0 : GetConstructorObject(JSContext* aCx)
1085 : {
1086 0 : return GetConstructorObjectHandle(aCx);
1087 : }
1088 :
1089 : } // namespace PluginBinding
1090 :
1091 :
1092 :
1093 : } // namespace dom
1094 : } // namespace mozilla
|