LCOV - code coverage report
Current view: top level - dom/plugins/ipc - PluginScriptableObjectParent.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 1 740 0.1 %
Date: 2017-07-14 16:53:18 Functions: 2 45 4.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
       2             :  * vim: sw=2 ts=2 et :
       3             :  * This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "PluginScriptableObjectParent.h"
       8             : 
       9             : #include "jsapi.h"
      10             : #include "mozilla/DebugOnly.h"
      11             : #include "mozilla/dom/ScriptSettings.h"
      12             : #include "mozilla/plugins/PluginTypes.h"
      13             : #include "mozilla/Unused.h"
      14             : #include "nsNPAPIPlugin.h"
      15             : #include "PluginScriptableObjectUtils.h"
      16             : 
      17             : using namespace mozilla;
      18             : using namespace mozilla::plugins;
      19             : using namespace mozilla::plugins::parent;
      20             : 
      21             : /**
      22             :  * NPIdentifiers in the chrome process are stored as jsids. The difficulty is in
      23             :  * ensuring that string identifiers are rooted without pinning them all. We
      24             :  * assume that all NPIdentifiers passed into nsJSNPRuntime will not be used
      25             :  * outside the scope of the NPAPI call (i.e., they won't be stored in the
      26             :  * heap). Rooting is done using the StackIdentifier class, which roots the
      27             :  * identifier via RootedId.
      28             :  *
      29             :  * This system does not allow jsids to be moved, as would be needed for
      30             :  * generational or compacting GC. When Firefox implements a moving GC for
      31             :  * strings, we will need to ensure that no movement happens while NPAPI code is
      32             :  * on the stack: although StackIdentifier roots all identifiers used, the GC has
      33             :  * no way to know that a jsid cast to an NPIdentifier needs to be fixed up if it
      34             :  * is moved.
      35             :  */
      36             : 
      37           0 : class MOZ_STACK_CLASS StackIdentifier
      38             : {
      39             : public:
      40             :   explicit StackIdentifier(const PluginIdentifier& aIdentifier,
      41             :                            bool aAtomizeAndPin = false);
      42             : 
      43           0 :   bool Failed() const { return mFailed; }
      44           0 :   NPIdentifier ToNPIdentifier() const { return mIdentifier; }
      45             : 
      46             : private:
      47             :   bool mFailed;
      48             :   NPIdentifier mIdentifier;
      49             :   AutoSafeJSContext mCx;
      50             :   JS::RootedId mId;
      51             : };
      52             : 
      53           0 : StackIdentifier::StackIdentifier(const PluginIdentifier& aIdentifier, bool aAtomizeAndPin)
      54             : : mFailed(false),
      55           0 :   mId(mCx)
      56             : {
      57           0 :   if (aIdentifier.type() == PluginIdentifier::TnsCString) {
      58             :     // We don't call _getstringidentifier because we may not want to intern the string.
      59           0 :     NS_ConvertUTF8toUTF16 utf16name(aIdentifier.get_nsCString());
      60           0 :     JS::RootedString str(mCx, JS_NewUCStringCopyN(mCx, utf16name.get(), utf16name.Length()));
      61           0 :     if (!str) {
      62           0 :       NS_ERROR("Id can't be allocated");
      63           0 :       mFailed = true;
      64           0 :       return;
      65             :     }
      66           0 :     if (aAtomizeAndPin) {
      67           0 :       str = JS_AtomizeAndPinJSString(mCx, str);
      68           0 :       if (!str) {
      69           0 :         NS_ERROR("Id can't be allocated");
      70           0 :         mFailed = true;
      71           0 :         return;
      72             :       }
      73             :     }
      74           0 :     if (!JS_StringToId(mCx, str, &mId)) {
      75           0 :       NS_ERROR("Id can't be allocated");
      76           0 :       mFailed = true;
      77           0 :       return;
      78             :     }
      79           0 :     mIdentifier = JSIdToNPIdentifier(mId);
      80           0 :     return;
      81             :   }
      82             : 
      83           0 :   mIdentifier = mozilla::plugins::parent::_getintidentifier(aIdentifier.get_int32_t());
      84             : }
      85             : 
      86             : static bool
      87           0 : FromNPIdentifier(NPIdentifier aIdentifier, PluginIdentifier* aResult)
      88             : {
      89           0 :   if (mozilla::plugins::parent::_identifierisstring(aIdentifier)) {
      90           0 :     nsCString string;
      91             :     NPUTF8* chars =
      92           0 :       mozilla::plugins::parent::_utf8fromidentifier(aIdentifier);
      93           0 :     if (!chars) {
      94           0 :       return false;
      95             :     }
      96           0 :     string.Adopt(chars);
      97           0 :     *aResult = PluginIdentifier(string);
      98           0 :     return true;
      99             :   }
     100             :   else {
     101           0 :     int32_t intval = mozilla::plugins::parent::_intfromidentifier(aIdentifier);
     102           0 :     *aResult = PluginIdentifier(intval);
     103           0 :     return true;
     104             :   }
     105             : }
     106             : 
     107             : namespace {
     108             : 
     109             : inline void
     110           0 : ReleaseVariant(NPVariant& aVariant,
     111             :                PluginInstanceParent* aInstance)
     112             : {
     113           0 :   const NPNetscapeFuncs* npn = GetNetscapeFuncs(aInstance);
     114           0 :   if (npn) {
     115           0 :     npn->releasevariantvalue(&aVariant);
     116             :   }
     117           0 : }
     118             : 
     119             : } // namespace
     120             : 
     121             : // static
     122             : NPObject*
     123           0 : PluginScriptableObjectParent::ScriptableAllocate(NPP aInstance,
     124             :                                                  NPClass* aClass)
     125             : {
     126           0 :   if (aClass != GetClass()) {
     127           0 :     NS_ERROR("Huh?! Wrong class!");
     128           0 :     return nullptr;
     129             :   }
     130             : 
     131           0 :   return new ParentNPObject();
     132             : }
     133             : 
     134             : // static
     135             : void
     136           0 : PluginScriptableObjectParent::ScriptableInvalidate(NPObject* aObject)
     137             : {
     138           0 :   if (aObject->_class != GetClass()) {
     139           0 :     NS_ERROR("Don't know what kind of object this is!");
     140           0 :     return;
     141             :   }
     142             : 
     143           0 :   ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject);
     144           0 :   if (object->invalidated) {
     145             :     // This can happen more than once, and is just fine.
     146           0 :     return;
     147             :   }
     148             : 
     149           0 :   object->invalidated = true;
     150             : 
     151             :   // |object->parent| may be null already if the instance has gone away.
     152           0 :   if (object->parent && !object->parent->CallInvalidate()) {
     153           0 :     NS_ERROR("Failed to send message!");
     154             :   }
     155             : }
     156             : 
     157             : // static
     158             : void
     159           0 : PluginScriptableObjectParent::ScriptableDeallocate(NPObject* aObject)
     160             : {
     161           0 :   if (aObject->_class != GetClass()) {
     162           0 :     NS_ERROR("Don't know what kind of object this is!");
     163           0 :     return;
     164             :   }
     165             : 
     166           0 :   ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject);
     167             : 
     168           0 :   if (object->asyncWrapperCount > 0) {
     169             :     // In this case we should just drop the refcount to the asyncWrapperCount
     170             :     // instead of deallocating because there are still some async wrappers
     171             :     // out there that are referencing this object.
     172           0 :     object->referenceCount = object->asyncWrapperCount;
     173           0 :     return;
     174             :   }
     175             : 
     176           0 :   PluginScriptableObjectParent* actor = object->parent;
     177           0 :   if (actor) {
     178           0 :     NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
     179           0 :     actor->DropNPObject();
     180             :   }
     181             : 
     182             :   delete object;
     183             : }
     184             : 
     185             : // static
     186             : bool
     187           0 : PluginScriptableObjectParent::ScriptableHasMethod(NPObject* aObject,
     188             :                                                   NPIdentifier aName)
     189             : {
     190           0 :   if (aObject->_class != GetClass()) {
     191           0 :     NS_ERROR("Don't know what kind of object this is!");
     192           0 :     return false;
     193             :   }
     194             : 
     195           0 :   ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject);
     196           0 :   if (object->invalidated) {
     197           0 :     NS_WARNING("Calling method on an invalidated object!");
     198           0 :     return false;
     199             :   }
     200             : 
     201           0 :   ProtectedActor<PluginScriptableObjectParent> actor(object->parent);
     202           0 :   if (!actor) {
     203           0 :     return false;
     204             :   }
     205             : 
     206           0 :   PluginIdentifier identifier;
     207           0 :   if (!FromNPIdentifier(aName, &identifier)) {
     208           0 :     return false;
     209             :   }
     210             : 
     211           0 :   NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
     212             : 
     213             :   bool result;
     214           0 :   if (!actor->CallHasMethod(identifier, &result)) {
     215           0 :     NS_WARNING("Failed to send message!");
     216           0 :     return false;
     217             :   }
     218             : 
     219           0 :   return result;
     220             : }
     221             : 
     222             : // static
     223             : bool
     224           0 : PluginScriptableObjectParent::ScriptableInvoke(NPObject* aObject,
     225             :                                                NPIdentifier aName,
     226             :                                                const NPVariant* aArgs,
     227             :                                                uint32_t aArgCount,
     228             :                                                NPVariant* aResult)
     229             : {
     230           0 :   if (aObject->_class != GetClass()) {
     231           0 :     NS_ERROR("Don't know what kind of object this is!");
     232           0 :     return false;
     233             :   }
     234             : 
     235           0 :   ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject);
     236           0 :   if (object->invalidated) {
     237           0 :     NS_WARNING("Calling method on an invalidated object!");
     238           0 :     return false;
     239             :   }
     240             : 
     241           0 :   ProtectedActor<PluginScriptableObjectParent> actor(object->parent);
     242           0 :   if (!actor) {
     243           0 :     return false;
     244             :   }
     245             : 
     246           0 :   PluginIdentifier identifier;
     247           0 :   if (!FromNPIdentifier(aName, &identifier)) {
     248           0 :     return false;
     249             :   }
     250             : 
     251           0 :   NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
     252             : 
     253           0 :   ProtectedVariantArray args(aArgs, aArgCount, actor->GetInstance());
     254           0 :   if (!args.IsOk()) {
     255           0 :     NS_ERROR("Failed to convert arguments!");
     256           0 :     return false;
     257             :   }
     258             : 
     259           0 :   Variant remoteResult;
     260             :   bool success;
     261           0 :   if (!actor->CallInvoke(identifier, args, &remoteResult,
     262           0 :                          &success)) {
     263           0 :     NS_WARNING("Failed to send message!");
     264           0 :     return false;
     265             :   }
     266             : 
     267           0 :   if (!success) {
     268           0 :     return false;
     269             :   }
     270             : 
     271           0 :   if (!ConvertToVariant(remoteResult, *aResult, actor->GetInstance())) {
     272           0 :     NS_WARNING("Failed to convert result!");
     273           0 :     return false;
     274             :   }
     275           0 :   return true;
     276             : }
     277             : 
     278             : // static
     279             : bool
     280           0 : PluginScriptableObjectParent::ScriptableInvokeDefault(NPObject* aObject,
     281             :                                                       const NPVariant* aArgs,
     282             :                                                       uint32_t aArgCount,
     283             :                                                       NPVariant* aResult)
     284             : {
     285           0 :   if (aObject->_class != GetClass()) {
     286           0 :     NS_ERROR("Don't know what kind of object this is!");
     287           0 :     return false;
     288             :   }
     289             : 
     290           0 :   ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject);
     291           0 :   if (object->invalidated) {
     292           0 :     NS_WARNING("Calling method on an invalidated object!");
     293           0 :     return false;
     294             :   }
     295             : 
     296           0 :   ProtectedActor<PluginScriptableObjectParent> actor(object->parent);
     297           0 :   if (!actor) {
     298           0 :     return false;
     299             :   }
     300             : 
     301           0 :   NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
     302             : 
     303           0 :   ProtectedVariantArray args(aArgs, aArgCount, actor->GetInstance());
     304           0 :   if (!args.IsOk()) {
     305           0 :     NS_ERROR("Failed to convert arguments!");
     306           0 :     return false;
     307             :   }
     308             : 
     309           0 :   Variant remoteResult;
     310             :   bool success;
     311           0 :   if (!actor->CallInvokeDefault(args, &remoteResult, &success)) {
     312           0 :     NS_WARNING("Failed to send message!");
     313           0 :     return false;
     314             :   }
     315             : 
     316           0 :   if (!success) {
     317           0 :     return false;
     318             :   }
     319             : 
     320           0 :   if (!ConvertToVariant(remoteResult, *aResult, actor->GetInstance())) {
     321           0 :     NS_WARNING("Failed to convert result!");
     322           0 :     return false;
     323             :   }
     324           0 :   return true;
     325             : }
     326             : 
     327             : // static
     328             : bool
     329           0 : PluginScriptableObjectParent::ScriptableHasProperty(NPObject* aObject,
     330             :                                                     NPIdentifier aName)
     331             : {
     332           0 :   if (aObject->_class != GetClass()) {
     333           0 :     NS_ERROR("Don't know what kind of object this is!");
     334           0 :     return false;
     335             :   }
     336             : 
     337           0 :   ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject);
     338           0 :   if (object->invalidated) {
     339           0 :     NS_WARNING("Calling method on an invalidated object!");
     340           0 :     return false;
     341             :   }
     342             : 
     343           0 :   ProtectedActor<PluginScriptableObjectParent> actor(object->parent);
     344           0 :   if (!actor) {
     345           0 :     return false;
     346             :   }
     347             : 
     348           0 :   PluginIdentifier identifier;
     349           0 :   if (!FromNPIdentifier(aName, &identifier)) {
     350           0 :     return false;
     351             :   }
     352             : 
     353           0 :   NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
     354             : 
     355             :   bool result;
     356           0 :   if (!actor->CallHasProperty(identifier, &result)) {
     357           0 :     NS_WARNING("Failed to send message!");
     358           0 :     return false;
     359             :   }
     360             : 
     361           0 :   return result;
     362             : }
     363             : 
     364             : // static
     365             : bool
     366           0 : PluginScriptableObjectParent::ScriptableGetProperty(NPObject* aObject,
     367             :                                                     NPIdentifier aName,
     368             :                                                     NPVariant* aResult)
     369             : {
     370             :   // See GetPropertyHelper below.
     371           0 :   NS_NOTREACHED("Shouldn't ever call this directly!");
     372           0 :   return false;
     373             : }
     374             : 
     375             : // static
     376             : bool
     377           0 : PluginScriptableObjectParent::ScriptableSetProperty(NPObject* aObject,
     378             :                                                     NPIdentifier aName,
     379             :                                                     const NPVariant* aValue)
     380             : {
     381           0 :   if (aObject->_class != GetClass()) {
     382           0 :     NS_ERROR("Don't know what kind of object this is!");
     383           0 :     return false;
     384             :   }
     385             : 
     386           0 :   ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject);
     387           0 :   if (object->invalidated) {
     388           0 :     NS_WARNING("Calling method on an invalidated object!");
     389           0 :     return false;
     390             :   }
     391             : 
     392           0 :   ProtectedActor<PluginScriptableObjectParent> actor(object->parent);
     393           0 :   if (!actor) {
     394           0 :     return false;
     395             :   }
     396             : 
     397           0 :   PluginIdentifier identifier;
     398           0 :   if (!FromNPIdentifier(aName, &identifier)) {
     399           0 :     return false;
     400             :   }
     401             : 
     402           0 :   NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
     403             : 
     404           0 :   ProtectedVariant value(*aValue, actor->GetInstance());
     405           0 :   if (!value.IsOk()) {
     406           0 :     NS_WARNING("Failed to convert variant!");
     407           0 :     return false;
     408             :   }
     409             : 
     410             :   bool success;
     411           0 :   if (!actor->CallSetProperty(identifier, value, &success)) {
     412           0 :     NS_WARNING("Failed to send message!");
     413           0 :     return false;
     414             :   }
     415             : 
     416           0 :   return success;
     417             : }
     418             : 
     419             : // static
     420             : bool
     421           0 : PluginScriptableObjectParent::ScriptableRemoveProperty(NPObject* aObject,
     422             :                                                        NPIdentifier aName)
     423             : {
     424           0 :   if (aObject->_class != GetClass()) {
     425           0 :     NS_ERROR("Don't know what kind of object this is!");
     426           0 :     return false;
     427             :   }
     428             : 
     429           0 :   ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject);
     430           0 :   if (object->invalidated) {
     431           0 :     NS_WARNING("Calling method on an invalidated object!");
     432           0 :     return false;
     433             :   }
     434             : 
     435           0 :   ProtectedActor<PluginScriptableObjectParent> actor(object->parent);
     436           0 :   if (!actor) {
     437           0 :     return false;
     438             :   }
     439             : 
     440           0 :   PluginIdentifier identifier;
     441           0 :   if (!FromNPIdentifier(aName, &identifier)) {
     442           0 :     return false;
     443             :   }
     444             : 
     445           0 :   NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
     446             : 
     447             :   bool success;
     448           0 :   if (!actor->CallRemoveProperty(identifier, &success)) {
     449           0 :     NS_WARNING("Failed to send message!");
     450           0 :     return false;
     451             :   }
     452             : 
     453           0 :   return success;
     454             : }
     455             : 
     456             : // static
     457             : bool
     458           0 : PluginScriptableObjectParent::ScriptableEnumerate(NPObject* aObject,
     459             :                                                   NPIdentifier** aIdentifiers,
     460             :                                                   uint32_t* aCount)
     461             : {
     462           0 :   if (aObject->_class != GetClass()) {
     463           0 :     NS_ERROR("Don't know what kind of object this is!");
     464           0 :     return false;
     465             :   }
     466             : 
     467           0 :   ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject);
     468           0 :   if (object->invalidated) {
     469           0 :     NS_WARNING("Calling method on an invalidated object!");
     470           0 :     return false;
     471             :   }
     472             : 
     473           0 :   ProtectedActor<PluginScriptableObjectParent> actor(object->parent);
     474           0 :   if (!actor) {
     475           0 :     return false;
     476             :   }
     477             : 
     478           0 :   NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
     479             : 
     480           0 :   const NPNetscapeFuncs* npn = GetNetscapeFuncs(aObject);
     481           0 :   if (!npn) {
     482           0 :     NS_ERROR("No netscape funcs!");
     483           0 :     return false;
     484             :   }
     485             : 
     486           0 :   AutoTArray<PluginIdentifier, 10> identifiers;
     487             :   bool success;
     488           0 :   if (!actor->CallEnumerate(&identifiers, &success)) {
     489           0 :     NS_WARNING("Failed to send message!");
     490           0 :     return false;
     491             :   }
     492             : 
     493           0 :   if (!success) {
     494           0 :     return false;
     495             :   }
     496             : 
     497           0 :   *aCount = identifiers.Length();
     498           0 :   if (!*aCount) {
     499           0 :     *aIdentifiers = nullptr;
     500           0 :     return true;
     501             :   }
     502             : 
     503           0 :   *aIdentifiers = (NPIdentifier*)npn->memalloc(*aCount * sizeof(NPIdentifier));
     504           0 :   if (!*aIdentifiers) {
     505           0 :     NS_ERROR("Out of memory!");
     506           0 :     return false;
     507             :   }
     508             : 
     509           0 :   for (uint32_t index = 0; index < *aCount; index++) {
     510             :     // We pin the ID to avoid a GC hazard here. This could probably be fixed
     511             :     // if the interface with nsJSNPRuntime were smarter.
     512           0 :     StackIdentifier stackID(identifiers[index], true /* aAtomizeAndPin */);
     513           0 :     if (stackID.Failed()) {
     514           0 :       return false;
     515             :     }
     516           0 :     (*aIdentifiers)[index] = stackID.ToNPIdentifier();
     517             :   }
     518           0 :   return true;
     519             : }
     520             : 
     521             : // static
     522             : bool
     523           0 : PluginScriptableObjectParent::ScriptableConstruct(NPObject* aObject,
     524             :                                                   const NPVariant* aArgs,
     525             :                                                   uint32_t aArgCount,
     526             :                                                   NPVariant* aResult)
     527             : {
     528           0 :   if (aObject->_class != GetClass()) {
     529           0 :     NS_ERROR("Don't know what kind of object this is!");
     530           0 :     return false;
     531             :   }
     532             : 
     533           0 :   ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject);
     534           0 :   if (object->invalidated) {
     535           0 :     NS_WARNING("Calling method on an invalidated object!");
     536           0 :     return false;
     537             :   }
     538             : 
     539           0 :   ProtectedActor<PluginScriptableObjectParent> actor(object->parent);
     540           0 :   if (!actor) {
     541           0 :     return false;
     542             :   }
     543             : 
     544           0 :   NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
     545             : 
     546           0 :   ProtectedVariantArray args(aArgs, aArgCount, actor->GetInstance());
     547           0 :   if (!args.IsOk()) {
     548           0 :     NS_ERROR("Failed to convert arguments!");
     549           0 :     return false;
     550             :   }
     551             : 
     552           0 :   Variant remoteResult;
     553             :   bool success;
     554           0 :   if (!actor->CallConstruct(args, &remoteResult, &success)) {
     555           0 :     NS_WARNING("Failed to send message!");
     556           0 :     return false;
     557             :   }
     558             : 
     559           0 :   if (!success) {
     560           0 :     return false;
     561             :   }
     562             : 
     563           0 :   if (!ConvertToVariant(remoteResult, *aResult, actor->GetInstance())) {
     564           0 :     NS_WARNING("Failed to convert result!");
     565           0 :     return false;
     566             :   }
     567           0 :   return true;
     568             : }
     569             : 
     570             : const NPClass PluginScriptableObjectParent::sNPClass = {
     571             :   NP_CLASS_STRUCT_VERSION,
     572             :   PluginScriptableObjectParent::ScriptableAllocate,
     573             :   PluginScriptableObjectParent::ScriptableDeallocate,
     574             :   PluginScriptableObjectParent::ScriptableInvalidate,
     575             :   PluginScriptableObjectParent::ScriptableHasMethod,
     576             :   PluginScriptableObjectParent::ScriptableInvoke,
     577             :   PluginScriptableObjectParent::ScriptableInvokeDefault,
     578             :   PluginScriptableObjectParent::ScriptableHasProperty,
     579             :   PluginScriptableObjectParent::ScriptableGetProperty,
     580             :   PluginScriptableObjectParent::ScriptableSetProperty,
     581             :   PluginScriptableObjectParent::ScriptableRemoveProperty,
     582             :   PluginScriptableObjectParent::ScriptableEnumerate,
     583             :   PluginScriptableObjectParent::ScriptableConstruct
     584             : };
     585             : 
     586           0 : PluginScriptableObjectParent::PluginScriptableObjectParent(
     587           0 :                                                      ScriptableObjectType aType)
     588             : : mInstance(nullptr),
     589             :   mObject(nullptr),
     590             :   mProtectCount(0),
     591           0 :   mType(aType)
     592             : {
     593           0 : }
     594             : 
     595           0 : PluginScriptableObjectParent::~PluginScriptableObjectParent()
     596             : {
     597           0 :   if (mObject) {
     598           0 :     if (mObject->_class == GetClass()) {
     599           0 :       NS_ASSERTION(mType == Proxy, "Wrong type!");
     600           0 :       static_cast<ParentNPObject*>(mObject)->parent = nullptr;
     601             :     }
     602             :     else {
     603           0 :       NS_ASSERTION(mType == LocalObject, "Wrong type!");
     604           0 :       GetInstance()->GetNPNIface()->releaseobject(mObject);
     605             :     }
     606             :   }
     607           0 : }
     608             : 
     609             : void
     610           0 : PluginScriptableObjectParent::InitializeProxy()
     611             : {
     612           0 :   NS_ASSERTION(mType == Proxy, "Bad type!");
     613           0 :   NS_ASSERTION(!mObject, "Calling Initialize more than once!");
     614             : 
     615           0 :   mInstance = static_cast<PluginInstanceParent*>(Manager());
     616           0 :   NS_ASSERTION(mInstance, "Null manager?!");
     617             : 
     618           0 :   NPObject* object = CreateProxyObject();
     619           0 :   NS_ASSERTION(object, "Failed to create object!");
     620             : 
     621           0 :   if (!mInstance->RegisterNPObjectForActor(object, this)) {
     622           0 :     NS_ERROR("Out of memory?");
     623             :   }
     624             : 
     625           0 :   mObject = object;
     626           0 : }
     627             : 
     628             : void
     629           0 : PluginScriptableObjectParent::InitializeLocal(NPObject* aObject)
     630             : {
     631           0 :   NS_ASSERTION(mType == LocalObject, "Bad type!");
     632           0 :   NS_ASSERTION(!(mInstance && mObject), "Calling Initialize more than once!");
     633             : 
     634           0 :   mInstance = static_cast<PluginInstanceParent*>(Manager());
     635           0 :   NS_ASSERTION(mInstance, "Null manager?!");
     636             : 
     637           0 :   mInstance->GetNPNIface()->retainobject(aObject);
     638             : 
     639           0 :   NS_ASSERTION(!mProtectCount, "Should be zero!");
     640           0 :   mProtectCount++;
     641             : 
     642           0 :   if (!mInstance->RegisterNPObjectForActor(aObject, this)) {
     643           0 :     NS_ERROR("Out of memory?");
     644             :   }
     645             : 
     646           0 :   mObject = aObject;
     647           0 : }
     648             : 
     649             : NPObject*
     650           0 : PluginScriptableObjectParent::CreateProxyObject()
     651             : {
     652           0 :   NS_ASSERTION(mInstance, "Must have an instance!");
     653           0 :   NS_ASSERTION(mType == Proxy, "Shouldn't call this for non-proxy object!");
     654             : 
     655           0 :   const NPNetscapeFuncs* npn = GetNetscapeFuncs(mInstance);
     656             : 
     657           0 :   NPObject* npobject = npn->createobject(mInstance->GetNPP(),
     658           0 :                                          const_cast<NPClass*>(GetClass()));
     659           0 :   NS_ASSERTION(npobject, "Failed to create object?!");
     660           0 :   NS_ASSERTION(npobject->_class == GetClass(), "Wrong kind of object!");
     661           0 :   NS_ASSERTION(npobject->referenceCount == 1, "Some kind of live object!");
     662             : 
     663           0 :   ParentNPObject* object = static_cast<ParentNPObject*>(npobject);
     664           0 :   NS_ASSERTION(!object->invalidated, "Bad object!");
     665           0 :   NS_ASSERTION(!object->parent, "Bad object!");
     666             : 
     667             :   // We don't want to have the actor own this object but rather let the object
     668             :   // own this actor. Set the reference count to 0 here so that when the object
     669             :   // dies we will send the destructor message to the child.
     670           0 :   object->referenceCount = 0;
     671           0 :   NS_LOG_RELEASE(object, 0, "BrowserNPObject");
     672             : 
     673           0 :   object->parent = const_cast<PluginScriptableObjectParent*>(this);
     674           0 :   return object;
     675             : }
     676             : 
     677             : bool
     678           0 : PluginScriptableObjectParent::ResurrectProxyObject()
     679             : {
     680           0 :   NS_ASSERTION(mInstance, "Must have an instance already!");
     681           0 :   NS_ASSERTION(!mObject, "Should not have an object already!");
     682           0 :   NS_ASSERTION(mType == Proxy, "Shouldn't call this for non-proxy object!");
     683             : 
     684           0 :   InitializeProxy();
     685           0 :   NS_ASSERTION(mObject, "Initialize failed!");
     686             : 
     687           0 :   if (!SendProtect()) {
     688           0 :     NS_WARNING("Failed to send message!");
     689           0 :     return false;
     690             :   }
     691             : 
     692           0 :   return true;
     693             : }
     694             : 
     695             : NPObject*
     696           0 : PluginScriptableObjectParent::GetObject(bool aCanResurrect)
     697             : {
     698           0 :   if (!mObject && aCanResurrect && !ResurrectProxyObject()) {
     699           0 :     NS_ERROR("Null object!");
     700           0 :     return nullptr;
     701             :   }
     702           0 :   return mObject;
     703             : }
     704             : 
     705             : void
     706           0 : PluginScriptableObjectParent::Protect()
     707             : {
     708           0 :   NS_ASSERTION(mObject, "No object!");
     709           0 :   NS_ASSERTION(mProtectCount >= 0, "Negative protect count?!");
     710             : 
     711           0 :   if (mType == LocalObject) {
     712           0 :     ++mProtectCount;
     713             :   }
     714           0 : }
     715             : 
     716             : void
     717           0 : PluginScriptableObjectParent::Unprotect()
     718             : {
     719           0 :   NS_ASSERTION(mObject, "No object!");
     720           0 :   NS_ASSERTION(mProtectCount >= 0, "Negative protect count?!");
     721             : 
     722           0 :   if (mType == LocalObject) {
     723           0 :     if (--mProtectCount == 0) {
     724           0 :       Unused << PluginScriptableObjectParent::Send__delete__(this);
     725             :     }
     726             :   }
     727           0 : }
     728             : 
     729             : void
     730           0 : PluginScriptableObjectParent::DropNPObject()
     731             : {
     732           0 :   NS_ASSERTION(mObject, "Invalidated object!");
     733           0 :   NS_ASSERTION(mObject->_class == GetClass(), "Wrong type of object!");
     734           0 :   NS_ASSERTION(mType == Proxy, "Shouldn't call this for non-proxy object!");
     735             : 
     736             :   // We think we're about to be deleted, but we could be racing with the other
     737             :   // process.
     738           0 :   PluginInstanceParent* instance = GetInstance();
     739           0 :   NS_ASSERTION(instance, "Must have an instance!");
     740             : 
     741           0 :   instance->UnregisterNPObject(mObject);
     742           0 :   mObject = nullptr;
     743             : 
     744           0 :   Unused << SendUnprotect();
     745           0 : }
     746             : 
     747             : void
     748           0 : PluginScriptableObjectParent::ActorDestroy(ActorDestroyReason aWhy)
     749             : {
     750             :   // Implement me! Bug 1005163
     751           0 : }
     752             : 
     753             : mozilla::ipc::IPCResult
     754           0 : PluginScriptableObjectParent::AnswerHasMethod(const PluginIdentifier& aId,
     755             :                                               bool* aHasMethod)
     756             : {
     757           0 :   if (!mObject) {
     758           0 :     NS_WARNING("Calling AnswerHasMethod with an invalidated object!");
     759           0 :     *aHasMethod = false;
     760           0 :     return IPC_OK();
     761             :   }
     762             : 
     763           0 :   NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
     764           0 :   NS_ASSERTION(mType == LocalObject, "Bad type!");
     765             : 
     766           0 :   PluginInstanceParent* instance = GetInstance();
     767           0 :   if (!instance) {
     768           0 :     NS_ERROR("No instance?!");
     769           0 :     *aHasMethod = false;
     770           0 :     return IPC_OK();
     771             :   }
     772             : 
     773           0 :   const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance);
     774           0 :   if (!npn) {
     775           0 :     NS_ERROR("No netscape funcs?!");
     776           0 :     *aHasMethod = false;
     777           0 :     return IPC_OK();
     778             :   }
     779             : 
     780           0 :   StackIdentifier stackID(aId);
     781           0 :   if (stackID.Failed()) {
     782           0 :     *aHasMethod = false;
     783           0 :     return IPC_OK();
     784             :   }
     785           0 :   *aHasMethod = npn->hasmethod(instance->GetNPP(), mObject, stackID.ToNPIdentifier());
     786           0 :   return IPC_OK();
     787             : }
     788             : 
     789             : mozilla::ipc::IPCResult
     790           0 : PluginScriptableObjectParent::AnswerInvoke(const PluginIdentifier& aId,
     791             :                                            InfallibleTArray<Variant>&& aArgs,
     792             :                                            Variant* aResult,
     793             :                                            bool* aSuccess)
     794             : {
     795           0 :   if (!mObject) {
     796           0 :     NS_WARNING("Calling AnswerInvoke with an invalidated object!");
     797           0 :     *aResult = void_t();
     798           0 :     *aSuccess = false;
     799           0 :     return IPC_OK();
     800             :   }
     801             : 
     802           0 :   NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
     803           0 :   NS_ASSERTION(mType == LocalObject, "Bad type!");
     804             : 
     805           0 :   PluginInstanceParent* instance = GetInstance();
     806           0 :   if (!instance) {
     807           0 :     NS_ERROR("No instance?!");
     808           0 :     *aResult = void_t();
     809           0 :     *aSuccess = false;
     810           0 :     return IPC_OK();
     811             :   }
     812             : 
     813           0 :   const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance);
     814           0 :   if (!npn) {
     815           0 :     NS_ERROR("No netscape funcs?!");
     816           0 :     *aResult = void_t();
     817           0 :     *aSuccess = false;
     818           0 :     return IPC_OK();
     819             :   }
     820             : 
     821           0 :   StackIdentifier stackID(aId);
     822           0 :   if (stackID.Failed()) {
     823           0 :     *aResult = void_t();
     824           0 :     *aSuccess = false;
     825           0 :     return IPC_OK();
     826             :   }
     827             : 
     828           0 :   AutoTArray<NPVariant, 10> convertedArgs;
     829           0 :   uint32_t argCount = aArgs.Length();
     830             : 
     831           0 :   if (!convertedArgs.SetLength(argCount, fallible)) {
     832           0 :     *aResult = void_t();
     833           0 :     *aSuccess = false;
     834           0 :     return IPC_OK();
     835             :   }
     836             : 
     837           0 :   for (uint32_t index = 0; index < argCount; index++) {
     838           0 :     if (!ConvertToVariant(aArgs[index], convertedArgs[index], instance)) {
     839             :       // Don't leak things we've already converted!
     840           0 :       while (index-- > 0) {
     841           0 :         ReleaseVariant(convertedArgs[index], instance);
     842             :       }
     843           0 :       *aResult = void_t();
     844           0 :       *aSuccess = false;
     845           0 :       return IPC_OK();
     846             :     }
     847             :   }
     848             : 
     849             :   NPVariant result;
     850           0 :   bool success = npn->invoke(instance->GetNPP(), mObject, stackID.ToNPIdentifier(),
     851           0 :                              convertedArgs.Elements(), argCount, &result);
     852             : 
     853           0 :   for (uint32_t index = 0; index < argCount; index++) {
     854           0 :     ReleaseVariant(convertedArgs[index], instance);
     855             :   }
     856             : 
     857           0 :   if (!success) {
     858           0 :     *aResult = void_t();
     859           0 :     *aSuccess = false;
     860           0 :     return IPC_OK();
     861             :   }
     862             : 
     863           0 :   Variant convertedResult;
     864           0 :   success = ConvertToRemoteVariant(result, convertedResult, GetInstance());
     865             : 
     866           0 :   DeferNPVariantLastRelease(npn, &result);
     867             : 
     868           0 :   if (!success) {
     869           0 :     *aResult = void_t();
     870           0 :     *aSuccess = false;
     871           0 :     return IPC_OK();
     872             :   }
     873             : 
     874           0 :   *aResult = convertedResult;
     875           0 :   *aSuccess = true;
     876           0 :   return IPC_OK();
     877             : }
     878             : 
     879             : mozilla::ipc::IPCResult
     880           0 : PluginScriptableObjectParent::AnswerInvokeDefault(InfallibleTArray<Variant>&& aArgs,
     881             :                                                   Variant* aResult,
     882             :                                                   bool* aSuccess)
     883             : {
     884           0 :   if (!mObject) {
     885           0 :     NS_WARNING("Calling AnswerInvoke with an invalidated object!");
     886           0 :     *aResult = void_t();
     887           0 :     *aSuccess = false;
     888           0 :     return IPC_OK();
     889             :   }
     890             : 
     891           0 :   NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
     892           0 :   NS_ASSERTION(mType == LocalObject, "Bad type!");
     893             : 
     894           0 :   PluginInstanceParent* instance = GetInstance();
     895           0 :   if (!instance) {
     896           0 :     NS_ERROR("No instance?!");
     897           0 :     *aResult = void_t();
     898           0 :     *aSuccess = false;
     899           0 :     return IPC_OK();
     900             :   }
     901             : 
     902           0 :   const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance);
     903           0 :   if (!npn) {
     904           0 :     NS_ERROR("No netscape funcs?!");
     905           0 :     *aResult = void_t();
     906           0 :     *aSuccess = false;
     907           0 :     return IPC_OK();
     908             :   }
     909             : 
     910           0 :   AutoTArray<NPVariant, 10> convertedArgs;
     911           0 :   uint32_t argCount = aArgs.Length();
     912             : 
     913           0 :   if (!convertedArgs.SetLength(argCount, fallible)) {
     914           0 :     *aResult = void_t();
     915           0 :     *aSuccess = false;
     916           0 :     return IPC_OK();
     917             :   }
     918             : 
     919           0 :   for (uint32_t index = 0; index < argCount; index++) {
     920           0 :     if (!ConvertToVariant(aArgs[index], convertedArgs[index], instance)) {
     921             :       // Don't leak things we've already converted!
     922           0 :       while (index-- > 0) {
     923           0 :         ReleaseVariant(convertedArgs[index], instance);
     924             :       }
     925           0 :       *aResult = void_t();
     926           0 :       *aSuccess = false;
     927           0 :       return IPC_OK();
     928             :     }
     929             :   }
     930             : 
     931             :   NPVariant result;
     932           0 :   bool success = npn->invokeDefault(instance->GetNPP(), mObject,
     933           0 :                                     convertedArgs.Elements(), argCount,
     934           0 :                                     &result);
     935             : 
     936           0 :   for (uint32_t index = 0; index < argCount; index++) {
     937           0 :     ReleaseVariant(convertedArgs[index], instance);
     938             :   }
     939             : 
     940           0 :   if (!success) {
     941           0 :     *aResult = void_t();
     942           0 :     *aSuccess = false;
     943           0 :     return IPC_OK();
     944             :   }
     945             : 
     946           0 :   Variant convertedResult;
     947           0 :   success = ConvertToRemoteVariant(result, convertedResult, GetInstance());
     948             : 
     949           0 :   DeferNPVariantLastRelease(npn, &result);
     950             : 
     951           0 :   if (!success) {
     952           0 :     *aResult = void_t();
     953           0 :     *aSuccess = false;
     954           0 :     return IPC_OK();
     955             :   }
     956             : 
     957           0 :   *aResult = convertedResult;
     958           0 :   *aSuccess = true;
     959           0 :   return IPC_OK();
     960             : }
     961             : 
     962             : mozilla::ipc::IPCResult
     963           0 : PluginScriptableObjectParent::AnswerHasProperty(const PluginIdentifier& aId,
     964             :                                                 bool* aHasProperty)
     965             : {
     966           0 :   if (!mObject) {
     967           0 :     NS_WARNING("Calling AnswerHasProperty with an invalidated object!");
     968           0 :     *aHasProperty = false;
     969           0 :     return IPC_OK();
     970             :   }
     971             : 
     972           0 :   NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
     973           0 :   NS_ASSERTION(mType == LocalObject, "Bad type!");
     974             : 
     975           0 :   PluginInstanceParent* instance = GetInstance();
     976           0 :   if (!instance) {
     977           0 :     NS_ERROR("No instance?!");
     978           0 :     *aHasProperty = false;
     979           0 :     return IPC_OK();
     980             :   }
     981             : 
     982           0 :   const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance);
     983           0 :   if (!npn) {
     984           0 :     NS_ERROR("No netscape funcs?!");
     985           0 :     *aHasProperty = false;
     986           0 :     return IPC_OK();
     987             :   }
     988             : 
     989           0 :   StackIdentifier stackID(aId);
     990           0 :   if (stackID.Failed()) {
     991           0 :     *aHasProperty = false;
     992           0 :     return IPC_OK();
     993             :   }
     994             : 
     995           0 :   *aHasProperty = npn->hasproperty(instance->GetNPP(), mObject,
     996             :                                    stackID.ToNPIdentifier());
     997           0 :   return IPC_OK();
     998             : }
     999             : 
    1000             : mozilla::ipc::IPCResult
    1001           0 : PluginScriptableObjectParent::AnswerGetParentProperty(
    1002             :                                                    const PluginIdentifier& aId,
    1003             :                                                    Variant* aResult,
    1004             :                                                    bool* aSuccess)
    1005             : {
    1006           0 :   if (!mObject) {
    1007           0 :     NS_WARNING("Calling AnswerGetProperty with an invalidated object!");
    1008           0 :     *aResult = void_t();
    1009           0 :     *aSuccess = false;
    1010           0 :     return IPC_OK();
    1011             :   }
    1012             : 
    1013           0 :   NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
    1014           0 :   NS_ASSERTION(mType == LocalObject, "Bad type!");
    1015             : 
    1016           0 :   PluginInstanceParent* instance = GetInstance();
    1017           0 :   if (!instance) {
    1018           0 :     NS_ERROR("No instance?!");
    1019           0 :     *aResult = void_t();
    1020           0 :     *aSuccess = false;
    1021           0 :     return IPC_OK();
    1022             :   }
    1023             : 
    1024           0 :   const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance);
    1025           0 :   if (!npn) {
    1026           0 :     NS_ERROR("No netscape funcs?!");
    1027           0 :     *aResult = void_t();
    1028           0 :     *aSuccess = false;
    1029           0 :     return IPC_OK();
    1030             :   }
    1031             : 
    1032           0 :   StackIdentifier stackID(aId);
    1033           0 :   if (stackID.Failed()) {
    1034           0 :     *aResult = void_t();
    1035           0 :     *aSuccess = false;
    1036           0 :     return IPC_OK();
    1037             :   }
    1038             : 
    1039             :   NPVariant result;
    1040           0 :   if (!npn->getproperty(instance->GetNPP(), mObject, stackID.ToNPIdentifier(),
    1041             :                         &result)) {
    1042           0 :     *aResult = void_t();
    1043           0 :     *aSuccess = false;
    1044           0 :     return IPC_OK();
    1045             :   }
    1046             : 
    1047           0 :   Variant converted;
    1048           0 :   if ((*aSuccess = ConvertToRemoteVariant(result, converted, instance))) {
    1049           0 :     DeferNPVariantLastRelease(npn, &result);
    1050           0 :     *aResult = converted;
    1051             :   }
    1052             :   else {
    1053           0 :     *aResult = void_t();
    1054             :   }
    1055             : 
    1056           0 :   return IPC_OK();
    1057             : }
    1058             : 
    1059             : mozilla::ipc::IPCResult
    1060           0 : PluginScriptableObjectParent::AnswerSetProperty(const PluginIdentifier& aId,
    1061             :                                                 const Variant& aValue,
    1062             :                                                 bool* aSuccess)
    1063             : {
    1064           0 :   if (!mObject) {
    1065           0 :     NS_WARNING("Calling AnswerSetProperty with an invalidated object!");
    1066           0 :     *aSuccess = false;
    1067           0 :     return IPC_OK();
    1068             :   }
    1069             : 
    1070           0 :   NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
    1071           0 :   NS_ASSERTION(mType == LocalObject, "Bad type!");
    1072             : 
    1073           0 :   PluginInstanceParent* instance = GetInstance();
    1074           0 :   if (!instance) {
    1075           0 :     NS_ERROR("No instance?!");
    1076           0 :     *aSuccess = false;
    1077           0 :     return IPC_OK();
    1078             :   }
    1079             : 
    1080           0 :   const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance);
    1081           0 :   if (!npn) {
    1082           0 :     NS_ERROR("No netscape funcs?!");
    1083           0 :     *aSuccess = false;
    1084           0 :     return IPC_OK();
    1085             :   }
    1086             : 
    1087             :   NPVariant converted;
    1088           0 :   if (!ConvertToVariant(aValue, converted, instance)) {
    1089           0 :     *aSuccess = false;
    1090           0 :     return IPC_OK();
    1091             :   }
    1092             : 
    1093           0 :   StackIdentifier stackID(aId);
    1094           0 :   if (stackID.Failed()) {
    1095           0 :     *aSuccess = false;
    1096           0 :     return IPC_OK();
    1097             :   }
    1098             : 
    1099           0 :   if ((*aSuccess = npn->setproperty(instance->GetNPP(), mObject,
    1100             :                                     stackID.ToNPIdentifier(), &converted))) {
    1101           0 :     ReleaseVariant(converted, instance);
    1102             :   }
    1103           0 :   return IPC_OK();
    1104             : }
    1105             : 
    1106             : mozilla::ipc::IPCResult
    1107           0 : PluginScriptableObjectParent::AnswerRemoveProperty(const PluginIdentifier& aId,
    1108             :                                                    bool* aSuccess)
    1109             : {
    1110           0 :   if (!mObject) {
    1111           0 :     NS_WARNING("Calling AnswerRemoveProperty with an invalidated object!");
    1112           0 :     *aSuccess = false;
    1113           0 :     return IPC_OK();
    1114             :   }
    1115             : 
    1116           0 :   NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
    1117           0 :   NS_ASSERTION(mType == LocalObject, "Bad type!");
    1118             : 
    1119           0 :   PluginInstanceParent* instance = GetInstance();
    1120           0 :   if (!instance) {
    1121           0 :     NS_ERROR("No instance?!");
    1122           0 :     *aSuccess = false;
    1123           0 :     return IPC_OK();
    1124             :   }
    1125             : 
    1126           0 :   const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance);
    1127           0 :   if (!npn) {
    1128           0 :     NS_ERROR("No netscape funcs?!");
    1129           0 :     *aSuccess = false;
    1130           0 :     return IPC_OK();
    1131             :   }
    1132             : 
    1133           0 :   StackIdentifier stackID(aId);
    1134           0 :   if (stackID.Failed()) {
    1135           0 :     *aSuccess = false;
    1136           0 :     return IPC_OK();
    1137             :   }
    1138             : 
    1139           0 :   *aSuccess = npn->removeproperty(instance->GetNPP(), mObject,
    1140             :                                   stackID.ToNPIdentifier());
    1141           0 :   return IPC_OK();
    1142             : }
    1143             : 
    1144             : mozilla::ipc::IPCResult
    1145           0 : PluginScriptableObjectParent::AnswerEnumerate(InfallibleTArray<PluginIdentifier>* aProperties,
    1146             :                                               bool* aSuccess)
    1147             : {
    1148           0 :   if (!mObject) {
    1149           0 :     NS_WARNING("Calling AnswerEnumerate with an invalidated object!");
    1150           0 :     *aSuccess = false;
    1151           0 :     return IPC_OK();
    1152             :   }
    1153             : 
    1154           0 :   NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
    1155           0 :   NS_ASSERTION(mType == LocalObject, "Bad type!");
    1156             : 
    1157           0 :   PluginInstanceParent* instance = GetInstance();
    1158           0 :   if (!instance) {
    1159           0 :     NS_ERROR("No instance?!");
    1160           0 :     *aSuccess = false;
    1161           0 :     return IPC_OK();
    1162             :   }
    1163             : 
    1164           0 :   const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance);
    1165           0 :   if (!npn) {
    1166           0 :     NS_WARNING("No netscape funcs?!");
    1167           0 :     *aSuccess = false;
    1168           0 :     return IPC_OK();
    1169             :   }
    1170             : 
    1171             :   NPIdentifier* ids;
    1172             :   uint32_t idCount;
    1173           0 :   if (!npn->enumerate(instance->GetNPP(), mObject, &ids, &idCount)) {
    1174           0 :     *aSuccess = false;
    1175           0 :     return IPC_OK();
    1176             :   }
    1177             : 
    1178           0 :   aProperties->SetCapacity(idCount);
    1179             : 
    1180           0 :   for (uint32_t index = 0; index < idCount; index++) {
    1181           0 :     PluginIdentifier id;
    1182           0 :     if (!FromNPIdentifier(ids[index], &id)) {
    1183           0 :       return IPC_FAIL_NO_REASON(this);
    1184             :     }
    1185           0 :     aProperties->AppendElement(id);
    1186             :   }
    1187             : 
    1188           0 :   npn->memfree(ids);
    1189           0 :   *aSuccess = true;
    1190           0 :   return IPC_OK();
    1191             : }
    1192             : 
    1193             : mozilla::ipc::IPCResult
    1194           0 : PluginScriptableObjectParent::AnswerConstruct(InfallibleTArray<Variant>&& aArgs,
    1195             :                                               Variant* aResult,
    1196             :                                               bool* aSuccess)
    1197             : {
    1198           0 :   if (!mObject) {
    1199           0 :     NS_WARNING("Calling AnswerConstruct with an invalidated object!");
    1200           0 :     *aResult = void_t();
    1201           0 :     *aSuccess = false;
    1202           0 :     return IPC_OK();
    1203             :   }
    1204             : 
    1205           0 :   NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
    1206           0 :   NS_ASSERTION(mType == LocalObject, "Bad type!");
    1207             : 
    1208           0 :   PluginInstanceParent* instance = GetInstance();
    1209           0 :   if (!instance) {
    1210           0 :     NS_ERROR("No instance?!");
    1211           0 :     *aResult = void_t();
    1212           0 :     *aSuccess = false;
    1213           0 :     return IPC_OK();
    1214             :   }
    1215             : 
    1216           0 :   const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance);
    1217           0 :   if (!npn) {
    1218           0 :     NS_ERROR("No netscape funcs?!");
    1219           0 :     *aResult = void_t();
    1220           0 :     *aSuccess = false;
    1221           0 :     return IPC_OK();
    1222             :   }
    1223             : 
    1224           0 :   AutoTArray<NPVariant, 10> convertedArgs;
    1225           0 :   uint32_t argCount = aArgs.Length();
    1226             : 
    1227           0 :   if (!convertedArgs.SetLength(argCount, fallible)) {
    1228           0 :     *aResult = void_t();
    1229           0 :     *aSuccess = false;
    1230           0 :     return IPC_OK();
    1231             :   }
    1232             : 
    1233           0 :   for (uint32_t index = 0; index < argCount; index++) {
    1234           0 :     if (!ConvertToVariant(aArgs[index], convertedArgs[index], instance)) {
    1235             :       // Don't leak things we've already converted!
    1236           0 :       while (index-- > 0) {
    1237           0 :         ReleaseVariant(convertedArgs[index], instance);
    1238             :       }
    1239           0 :       *aResult = void_t();
    1240           0 :       *aSuccess = false;
    1241           0 :       return IPC_OK();
    1242             :     }
    1243             :   }
    1244             : 
    1245             :   NPVariant result;
    1246           0 :   bool success = npn->construct(instance->GetNPP(), mObject,
    1247           0 :                                 convertedArgs.Elements(), argCount, &result);
    1248             : 
    1249           0 :   for (uint32_t index = 0; index < argCount; index++) {
    1250           0 :     ReleaseVariant(convertedArgs[index], instance);
    1251             :   }
    1252             : 
    1253           0 :   if (!success) {
    1254           0 :     *aResult = void_t();
    1255           0 :     *aSuccess = false;
    1256           0 :     return IPC_OK();
    1257             :   }
    1258             : 
    1259           0 :   Variant convertedResult;
    1260           0 :   success = ConvertToRemoteVariant(result, convertedResult, instance);
    1261             : 
    1262           0 :   DeferNPVariantLastRelease(npn, &result);
    1263             : 
    1264           0 :   if (!success) {
    1265           0 :     *aResult = void_t();
    1266           0 :     *aSuccess = false;
    1267           0 :     return IPC_OK();
    1268             :   }
    1269             : 
    1270           0 :   *aSuccess = true;
    1271           0 :   *aResult = convertedResult;
    1272           0 :   return IPC_OK();
    1273             : }
    1274             : 
    1275             : mozilla::ipc::IPCResult
    1276           0 : PluginScriptableObjectParent::RecvProtect()
    1277             : {
    1278           0 :   NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
    1279           0 :   NS_ASSERTION(mType == LocalObject, "Bad type!");
    1280             : 
    1281           0 :   Protect();
    1282           0 :   return IPC_OK();
    1283             : }
    1284             : 
    1285             : mozilla::ipc::IPCResult
    1286           0 : PluginScriptableObjectParent::RecvUnprotect()
    1287             : {
    1288           0 :   NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
    1289           0 :   NS_ASSERTION(mType == LocalObject, "Bad type!");
    1290             : 
    1291           0 :   Unprotect();
    1292           0 :   return IPC_OK();
    1293             : }
    1294             : 
    1295             : mozilla::ipc::IPCResult
    1296           0 : PluginScriptableObjectParent::AnswerNPN_Evaluate(const nsCString& aScript,
    1297             :                                                  Variant* aResult,
    1298             :                                                  bool* aSuccess)
    1299             : {
    1300           0 :   PluginInstanceParent* instance = GetInstance();
    1301           0 :   if (!instance) {
    1302           0 :     NS_ERROR("No instance?!");
    1303           0 :     *aResult = void_t();
    1304           0 :     *aSuccess = false;
    1305           0 :     return IPC_OK();
    1306             :   }
    1307             : 
    1308           0 :   const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance);
    1309           0 :   if (!npn) {
    1310           0 :     NS_ERROR("No netscape funcs?!");
    1311           0 :     *aResult = void_t();
    1312           0 :     *aSuccess = false;
    1313           0 :     return IPC_OK();
    1314             :   }
    1315             : 
    1316           0 :   NPString script = { aScript.get(), aScript.Length() };
    1317             : 
    1318             :   NPVariant result;
    1319           0 :   bool success = npn->evaluate(instance->GetNPP(), mObject, &script, &result);
    1320           0 :   if (!success) {
    1321           0 :     *aResult = void_t();
    1322           0 :     *aSuccess = false;
    1323           0 :     return IPC_OK();
    1324             :   }
    1325             : 
    1326           0 :   Variant convertedResult;
    1327           0 :   success = ConvertToRemoteVariant(result, convertedResult, instance);
    1328             : 
    1329           0 :   DeferNPVariantLastRelease(npn, &result);
    1330             : 
    1331           0 :   if (!success) {
    1332           0 :     *aResult = void_t();
    1333           0 :     *aSuccess = false;
    1334           0 :     return IPC_OK();
    1335             :   }
    1336             : 
    1337           0 :   *aSuccess = true;
    1338           0 :   *aResult = convertedResult;
    1339           0 :   return IPC_OK();
    1340             : }
    1341             : 
    1342             : bool
    1343           0 : PluginScriptableObjectParent::GetPropertyHelper(NPIdentifier aName,
    1344             :                                                 bool* aHasProperty,
    1345             :                                                 bool* aHasMethod,
    1346             :                                                 NPVariant* aResult)
    1347             : {
    1348           0 :   NS_ASSERTION(Type() == Proxy, "Bad type!");
    1349             : 
    1350           0 :   ParentNPObject* object = static_cast<ParentNPObject*>(mObject);
    1351           0 :   if (object->invalidated) {
    1352           0 :     NS_WARNING("Calling method on an invalidated object!");
    1353           0 :     return false;
    1354             :   }
    1355             : 
    1356           0 :   PluginIdentifier identifier;
    1357           0 :   if (!FromNPIdentifier(aName, &identifier)) {
    1358           0 :     return false;
    1359             :   }
    1360             : 
    1361             :   bool hasProperty, hasMethod, success;
    1362           0 :   Variant result;
    1363           0 :   if (!CallGetChildProperty(identifier, &hasProperty, &hasMethod, &result,
    1364             :                             &success)) {
    1365           0 :     return false;
    1366             :   }
    1367             : 
    1368           0 :   if (!success) {
    1369           0 :     return false;
    1370             :   }
    1371             : 
    1372           0 :   if (!ConvertToVariant(result, *aResult, GetInstance())) {
    1373           0 :     NS_WARNING("Failed to convert result!");
    1374           0 :     return false;
    1375             :   }
    1376             : 
    1377           0 :   *aHasProperty = hasProperty;
    1378           0 :   *aHasMethod = hasMethod;
    1379           0 :   return true;
    1380           9 : }

Generated by: LCOV version 1.13