LCOV - code coverage report
Current view: top level - obj-x86_64-pc-linux-gnu/dom/bindings - PluginBinding.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 391 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 29 0.0 %
Legend: Lines: hit not hit

          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

Generated by: LCOV version 1.13