LCOV - code coverage report
Current view: top level - dom/plugins/ipc - PluginScriptableObjectChild.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 1 677 0.1 %
Date: 2017-07-14 16:53:18 Functions: 0 52 0.0 %
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 "PluginScriptableObjectChild.h"
       8             : #include "PluginScriptableObjectUtils.h"
       9             : #include "mozilla/plugins/PluginTypes.h"
      10             : 
      11             : using namespace mozilla::plugins;
      12             : 
      13             : /**
      14             :  * NPIdentifiers in the plugin process use a tagged representation. The low bit
      15             :  * stores the tag. If it's zero, the identifier is a string, and the value is a
      16             :  * pointer to a StoredIdentifier. If the tag bit is 1, then the rest of the
      17             :  * NPIdentifier value is the integer itself. Like the JSAPI, we require that all
      18             :  * integers stored in NPIdentifier be non-negative.
      19             :  *
      20             :  * String identifiers are stored in the sIdentifiers hashtable to ensure
      21             :  * uniqueness. The lifetime of these identifiers is only as long as the incoming
      22             :  * IPC call from the chrome process. If the plugin wants to retain an
      23             :  * identifier, it needs to call NPN_GetStringIdentifier, which causes the
      24             :  * mPermanent flag to be set on the identifier. When this flag is set, the
      25             :  * identifier is saved until the plugin process exits.
      26             :  *
      27             :  * The StackIdentifier RAII class is used to manage ownership of
      28             :  * identifiers. Any identifier obtained from this class should not be used
      29             :  * outside its scope, except when the MakePermanent() method has been called on
      30             :  * it.
      31             :  *
      32             :  * The lifetime of an NPIdentifier in the plugin process is totally divorced
      33             :  * from the lifetime of an NPIdentifier in the chrome process (where an
      34             :  * NPIdentifier is stored as a jsid). The JS GC in the chrome process is able to
      35             :  * trace through the entire heap, unlike in the plugin process, so there is no
      36             :  * reason to retain identifiers there.
      37             :  */
      38             : 
      39           3 : PluginScriptableObjectChild::IdentifierTable PluginScriptableObjectChild::sIdentifiers;
      40             : 
      41             : /* static */ PluginScriptableObjectChild::StoredIdentifier*
      42           0 : PluginScriptableObjectChild::HashIdentifier(const nsCString& aIdentifier)
      43             : {
      44           0 :   StoredIdentifier* stored = sIdentifiers.Get(aIdentifier).get();
      45           0 :   if (stored) {
      46           0 :     return stored;
      47             :   }
      48             : 
      49           0 :   stored = new StoredIdentifier(aIdentifier);
      50           0 :   sIdentifiers.Put(aIdentifier, stored);
      51           0 :   return stored;
      52             : }
      53             : 
      54             : /* static */ void
      55           0 : PluginScriptableObjectChild::UnhashIdentifier(StoredIdentifier* aStored)
      56             : {
      57           0 :   MOZ_ASSERT(sIdentifiers.Get(aStored->mIdentifier));
      58           0 :   sIdentifiers.Remove(aStored->mIdentifier);
      59           0 : }
      60             : 
      61             : /* static */ void
      62           0 : PluginScriptableObjectChild::ClearIdentifiers()
      63             : {
      64           0 :   sIdentifiers.Clear();
      65           0 : }
      66             : 
      67           0 : PluginScriptableObjectChild::StackIdentifier::StackIdentifier(const PluginIdentifier& aIdentifier)
      68             : : mIdentifier(aIdentifier),
      69           0 :   mStored(nullptr)
      70             : {
      71           0 :   if (aIdentifier.type() == PluginIdentifier::TnsCString) {
      72           0 :     mStored = PluginScriptableObjectChild::HashIdentifier(mIdentifier.get_nsCString());
      73             :   }
      74           0 : }
      75             : 
      76           0 : PluginScriptableObjectChild::StackIdentifier::StackIdentifier(NPIdentifier aIdentifier)
      77           0 : : mStored(nullptr)
      78             : {
      79           0 :   uintptr_t bits = reinterpret_cast<uintptr_t>(aIdentifier);
      80           0 :   if (bits & 1) {
      81           0 :     int32_t num = int32_t(bits >> 1);
      82           0 :     mIdentifier = PluginIdentifier(num);
      83             :   } else {
      84           0 :     mStored = static_cast<StoredIdentifier*>(aIdentifier);
      85           0 :     mIdentifier = mStored->mIdentifier;
      86             :   }
      87           0 : }
      88             : 
      89           0 : PluginScriptableObjectChild::StackIdentifier::~StackIdentifier()
      90             : {
      91           0 :   if (!mStored) {
      92           0 :     return;
      93             :   }
      94             : 
      95             :   // Each StackIdentifier owns one reference to its StoredIdentifier. In
      96             :   // addition, the sIdentifiers table owns a reference. If mPermanent is false
      97             :   // and sIdentifiers has the last reference, then we want to remove the
      98             :   // StoredIdentifier from the table (and destroy it).
      99           0 :   StoredIdentifier *stored = mStored;
     100           0 :   mStored = nullptr;
     101           0 :   if (stored->mRefCnt == 1 && !stored->mPermanent) {
     102           0 :     PluginScriptableObjectChild::UnhashIdentifier(stored);
     103             :   }
     104           0 : }
     105             : 
     106             : NPIdentifier
     107           0 : PluginScriptableObjectChild::StackIdentifier::ToNPIdentifier() const
     108             : {
     109           0 :   if (mStored) {
     110           0 :     MOZ_ASSERT(mIdentifier.type() == PluginIdentifier::TnsCString);
     111           0 :     MOZ_ASSERT((reinterpret_cast<uintptr_t>(mStored.get()) & 1) == 0);
     112           0 :     return mStored;
     113             :   }
     114             : 
     115           0 :   int32_t num = mIdentifier.get_int32_t();
     116             :   // The JS engine imposes this condition on int32s in jsids, so we assume it.
     117           0 :   MOZ_ASSERT(num >= 0);
     118           0 :   return reinterpret_cast<NPIdentifier>((num << 1) | 1);
     119             : }
     120             : 
     121             : static PluginIdentifier
     122           0 : FromNPIdentifier(NPIdentifier aIdentifier)
     123             : {
     124           0 :   PluginScriptableObjectChild::StackIdentifier stack(aIdentifier);
     125           0 :   return stack.GetIdentifier();
     126             : }
     127             : 
     128             : // static
     129             : NPObject*
     130           0 : PluginScriptableObjectChild::ScriptableAllocate(NPP aInstance,
     131             :                                                 NPClass* aClass)
     132             : {
     133           0 :   AssertPluginThread();
     134             : 
     135           0 :   if (aClass != GetClass()) {
     136           0 :     MOZ_CRASH("Huh?! Wrong class!");
     137             :   }
     138             : 
     139           0 :   return new ChildNPObject();
     140             : }
     141             : 
     142             : // static
     143             : void
     144           0 : PluginScriptableObjectChild::ScriptableInvalidate(NPObject* aObject)
     145             : {
     146           0 :   AssertPluginThread();
     147             : 
     148           0 :   if (aObject->_class != GetClass()) {
     149           0 :     MOZ_CRASH("Don't know what kind of object this is!");
     150             :   }
     151             : 
     152           0 :   ChildNPObject* object = reinterpret_cast<ChildNPObject*>(aObject);
     153           0 :   if (object->invalidated) {
     154             :     // This can happen more than once, and is just fine.
     155           0 :     return;
     156             :   }
     157             : 
     158           0 :   object->invalidated = true;
     159             : }
     160             : 
     161             : // static
     162             : void
     163           0 : PluginScriptableObjectChild::ScriptableDeallocate(NPObject* aObject)
     164             : {
     165           0 :   AssertPluginThread();
     166             : 
     167           0 :   if (aObject->_class != GetClass()) {
     168           0 :     MOZ_CRASH("Don't know what kind of object this is!");
     169             :   }
     170             : 
     171           0 :   ChildNPObject* object = reinterpret_cast<ChildNPObject*>(aObject);
     172           0 :   PluginScriptableObjectChild* actor = object->parent;
     173           0 :   if (actor) {
     174           0 :     NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
     175           0 :     actor->DropNPObject();
     176             :   }
     177             : 
     178           0 :   delete object;
     179           0 : }
     180             : 
     181             : // static
     182             : bool
     183           0 : PluginScriptableObjectChild::ScriptableHasMethod(NPObject* aObject,
     184             :                                                  NPIdentifier aName)
     185             : {
     186           0 :   AssertPluginThread();
     187             : 
     188           0 :   if (aObject->_class != GetClass()) {
     189           0 :     MOZ_CRASH("Don't know what kind of object this is!");
     190             :   }
     191             : 
     192           0 :   ChildNPObject* object = reinterpret_cast<ChildNPObject*>(aObject);
     193           0 :   if (object->invalidated) {
     194           0 :     NS_WARNING("Calling method on an invalidated object!");
     195           0 :     return false;
     196             :   }
     197             : 
     198           0 :   ProtectedActor<PluginScriptableObjectChild> actor(object->parent);
     199           0 :   NS_ASSERTION(actor, "This shouldn't ever be null!");
     200           0 :   NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
     201             : 
     202             :   bool result;
     203           0 :   actor->CallHasMethod(FromNPIdentifier(aName), &result);
     204             : 
     205           0 :   return result;
     206             : }
     207             : 
     208             : // static
     209             : bool
     210           0 : PluginScriptableObjectChild::ScriptableInvoke(NPObject* aObject,
     211             :                                               NPIdentifier aName,
     212             :                                               const NPVariant* aArgs,
     213             :                                               uint32_t aArgCount,
     214             :                                               NPVariant* aResult)
     215             : {
     216           0 :   AssertPluginThread();
     217             : 
     218           0 :   if (aObject->_class != GetClass()) {
     219           0 :     MOZ_CRASH("Don't know what kind of object this is!");
     220             :   }
     221             : 
     222           0 :   ChildNPObject* object = reinterpret_cast<ChildNPObject*>(aObject);
     223           0 :   if (object->invalidated) {
     224           0 :     NS_WARNING("Calling method on an invalidated object!");
     225           0 :     return false;
     226             :   }
     227             : 
     228           0 :   ProtectedActor<PluginScriptableObjectChild> actor(object->parent);
     229           0 :   NS_ASSERTION(actor, "This shouldn't ever be null!");
     230           0 :   NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
     231             : 
     232           0 :   ProtectedVariantArray args(aArgs, aArgCount, actor->GetInstance());
     233           0 :   if (!args.IsOk()) {
     234           0 :     NS_ERROR("Failed to convert arguments!");
     235           0 :     return false;
     236             :   }
     237             : 
     238           0 :   Variant remoteResult;
     239             :   bool success;
     240           0 :   actor->CallInvoke(FromNPIdentifier(aName), args,
     241           0 :                     &remoteResult, &success);
     242             : 
     243           0 :   if (!success) {
     244           0 :     return false;
     245             :   }
     246             : 
     247           0 :   ConvertToVariant(remoteResult, *aResult);
     248           0 :   return true;
     249             : }
     250             : 
     251             : // static
     252             : bool
     253           0 : PluginScriptableObjectChild::ScriptableInvokeDefault(NPObject* aObject,
     254             :                                                      const NPVariant* aArgs,
     255             :                                                      uint32_t aArgCount,
     256             :                                                      NPVariant* aResult)
     257             : {
     258           0 :   AssertPluginThread();
     259             : 
     260           0 :   if (aObject->_class != GetClass()) {
     261           0 :     MOZ_CRASH("Don't know what kind of object this is!");
     262             :   }
     263             : 
     264           0 :   ChildNPObject* object = reinterpret_cast<ChildNPObject*>(aObject);
     265           0 :   if (object->invalidated) {
     266           0 :     NS_WARNING("Calling method on an invalidated object!");
     267           0 :     return false;
     268             :   }
     269             : 
     270           0 :   ProtectedActor<PluginScriptableObjectChild> actor(object->parent);
     271           0 :   NS_ASSERTION(actor, "This shouldn't ever be null!");
     272           0 :   NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
     273             : 
     274           0 :   ProtectedVariantArray args(aArgs, aArgCount, actor->GetInstance());
     275           0 :   if (!args.IsOk()) {
     276           0 :     NS_ERROR("Failed to convert arguments!");
     277           0 :     return false;
     278             :   }
     279             : 
     280           0 :   Variant remoteResult;
     281             :   bool success;
     282           0 :   actor->CallInvokeDefault(args, &remoteResult, &success);
     283             : 
     284           0 :   if (!success) {
     285           0 :     return false;
     286             :   }
     287             : 
     288           0 :   ConvertToVariant(remoteResult, *aResult);
     289           0 :   return true;
     290             : }
     291             : 
     292             : // static
     293             : bool
     294           0 : PluginScriptableObjectChild::ScriptableHasProperty(NPObject* aObject,
     295             :                                                    NPIdentifier aName)
     296             : {
     297           0 :   AssertPluginThread();
     298             : 
     299           0 :   if (aObject->_class != GetClass()) {
     300           0 :     MOZ_CRASH("Don't know what kind of object this is!");
     301             :   }
     302             : 
     303           0 :   ChildNPObject* object = reinterpret_cast<ChildNPObject*>(aObject);
     304           0 :   if (object->invalidated) {
     305           0 :     NS_WARNING("Calling method on an invalidated object!");
     306           0 :     return false;
     307             :   }
     308             : 
     309           0 :   ProtectedActor<PluginScriptableObjectChild> actor(object->parent);
     310           0 :   NS_ASSERTION(actor, "This shouldn't ever be null!");
     311           0 :   NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
     312             : 
     313             :   bool result;
     314           0 :   actor->CallHasProperty(FromNPIdentifier(aName), &result);
     315             : 
     316           0 :   return result;
     317             : }
     318             : 
     319             : // static
     320             : bool
     321           0 : PluginScriptableObjectChild::ScriptableGetProperty(NPObject* aObject,
     322             :                                                    NPIdentifier aName,
     323             :                                                    NPVariant* aResult)
     324             : {
     325           0 :   AssertPluginThread();
     326             : 
     327           0 :   if (aObject->_class != GetClass()) {
     328           0 :     MOZ_CRASH("Don't know what kind of object this is!");
     329             :   }
     330             : 
     331           0 :   ChildNPObject* object = reinterpret_cast<ChildNPObject*>(aObject);
     332           0 :   if (object->invalidated) {
     333           0 :     NS_WARNING("Calling method on an invalidated object!");
     334           0 :     return false;
     335             :   }
     336             : 
     337           0 :   ProtectedActor<PluginScriptableObjectChild> actor(object->parent);
     338           0 :   NS_ASSERTION(actor, "This shouldn't ever be null!");
     339           0 :   NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
     340             : 
     341           0 :   PluginInstanceChild::AutoStackHelper guard(actor->mInstance);
     342             : 
     343           0 :   Variant result;
     344             :   bool success;
     345           0 :   actor->CallGetParentProperty(FromNPIdentifier(aName),
     346           0 :                                &result, &success);
     347             : 
     348           0 :   if (!success) {
     349           0 :     return false;
     350             :   }
     351             : 
     352           0 :   ConvertToVariant(result, *aResult);
     353           0 :   return true;
     354             : }
     355             : 
     356             : // static
     357             : bool
     358           0 : PluginScriptableObjectChild::ScriptableSetProperty(NPObject* aObject,
     359             :                                                    NPIdentifier aName,
     360             :                                                    const NPVariant* aValue)
     361             : {
     362           0 :   AssertPluginThread();
     363             : 
     364           0 :   if (aObject->_class != GetClass()) {
     365           0 :     MOZ_CRASH("Don't know what kind of object this is!");
     366             :   }
     367             : 
     368           0 :   ChildNPObject* object = reinterpret_cast<ChildNPObject*>(aObject);
     369           0 :   if (object->invalidated) {
     370           0 :     NS_WARNING("Calling method on an invalidated object!");
     371           0 :     return false;
     372             :   }
     373             : 
     374           0 :   ProtectedActor<PluginScriptableObjectChild> actor(object->parent);
     375           0 :   NS_ASSERTION(actor, "This shouldn't ever be null!");
     376           0 :   NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
     377             : 
     378           0 :   ProtectedVariant value(*aValue, actor->GetInstance());
     379           0 :   if (!value.IsOk()) {
     380           0 :     NS_WARNING("Failed to convert variant!");
     381           0 :     return false;
     382             :   }
     383             : 
     384             :   bool success;
     385           0 :   actor->CallSetProperty(FromNPIdentifier(aName), value,
     386           0 :                          &success);
     387             : 
     388           0 :   return success;
     389             : }
     390             : 
     391             : // static
     392             : bool
     393           0 : PluginScriptableObjectChild::ScriptableRemoveProperty(NPObject* aObject,
     394             :                                                       NPIdentifier aName)
     395             : {
     396           0 :   AssertPluginThread();
     397             : 
     398           0 :   if (aObject->_class != GetClass()) {
     399           0 :     MOZ_CRASH("Don't know what kind of object this is!");
     400             :   }
     401             : 
     402           0 :   ChildNPObject* object = reinterpret_cast<ChildNPObject*>(aObject);
     403           0 :   if (object->invalidated) {
     404           0 :     NS_WARNING("Calling method on an invalidated object!");
     405           0 :     return false;
     406             :   }
     407             : 
     408           0 :   ProtectedActor<PluginScriptableObjectChild> actor(object->parent);
     409           0 :   NS_ASSERTION(actor, "This shouldn't ever be null!");
     410           0 :   NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
     411             : 
     412             :   bool success;
     413           0 :   actor->CallRemoveProperty(FromNPIdentifier(aName),
     414           0 :                             &success);
     415             : 
     416           0 :   return success;
     417             : }
     418             : 
     419             : // static
     420             : bool
     421           0 : PluginScriptableObjectChild::ScriptableEnumerate(NPObject* aObject,
     422             :                                                  NPIdentifier** aIdentifiers,
     423             :                                                  uint32_t* aCount)
     424             : {
     425           0 :   AssertPluginThread();
     426             : 
     427           0 :   if (aObject->_class != GetClass()) {
     428           0 :     MOZ_CRASH("Don't know what kind of object this is!");
     429             :   }
     430             : 
     431           0 :   ChildNPObject* object = reinterpret_cast<ChildNPObject*>(aObject);
     432           0 :   if (object->invalidated) {
     433           0 :     NS_WARNING("Calling method on an invalidated object!");
     434           0 :     return false;
     435             :   }
     436             : 
     437           0 :   ProtectedActor<PluginScriptableObjectChild> actor(object->parent);
     438           0 :   NS_ASSERTION(actor, "This shouldn't ever be null!");
     439           0 :   NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
     440             : 
     441           0 :   AutoTArray<PluginIdentifier, 10> identifiers;
     442             :   bool success;
     443           0 :   actor->CallEnumerate(&identifiers, &success);
     444             : 
     445           0 :   if (!success) {
     446           0 :     return false;
     447             :   }
     448             : 
     449           0 :   *aCount = identifiers.Length();
     450           0 :   if (!*aCount) {
     451           0 :     *aIdentifiers = nullptr;
     452           0 :     return true;
     453             :   }
     454             : 
     455           0 :   *aIdentifiers = reinterpret_cast<NPIdentifier*>(
     456           0 :       PluginModuleChild::sBrowserFuncs.memalloc(*aCount * sizeof(NPIdentifier)));
     457           0 :   if (!*aIdentifiers) {
     458           0 :     NS_ERROR("Out of memory!");
     459           0 :     return false;
     460             :   }
     461             : 
     462           0 :   for (uint32_t index = 0; index < *aCount; index++) {
     463           0 :     StackIdentifier id(identifiers[index]);
     464             :     // Make the id permanent in case the plugin retains it.
     465           0 :     id.MakePermanent();
     466           0 :     (*aIdentifiers)[index] = id.ToNPIdentifier();
     467             :   }
     468           0 :   return true;
     469             : }
     470             : 
     471             : // static
     472             : bool
     473           0 : PluginScriptableObjectChild::ScriptableConstruct(NPObject* aObject,
     474             :                                                  const NPVariant* aArgs,
     475             :                                                  uint32_t aArgCount,
     476             :                                                  NPVariant* aResult)
     477             : {
     478           0 :   AssertPluginThread();
     479             : 
     480           0 :   if (aObject->_class != GetClass()) {
     481           0 :     MOZ_CRASH("Don't know what kind of object this is!");
     482             :   }
     483             : 
     484           0 :   ChildNPObject* object = reinterpret_cast<ChildNPObject*>(aObject);
     485           0 :   if (object->invalidated) {
     486           0 :     NS_WARNING("Calling method on an invalidated object!");
     487           0 :     return false;
     488             :   }
     489             : 
     490           0 :   ProtectedActor<PluginScriptableObjectChild> actor(object->parent);
     491           0 :   NS_ASSERTION(actor, "This shouldn't ever be null!");
     492           0 :   NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
     493             : 
     494           0 :   ProtectedVariantArray args(aArgs, aArgCount, actor->GetInstance());
     495           0 :   if (!args.IsOk()) {
     496           0 :     NS_ERROR("Failed to convert arguments!");
     497           0 :     return false;
     498             :   }
     499             : 
     500           0 :   Variant remoteResult;
     501             :   bool success;
     502           0 :   actor->CallConstruct(args, &remoteResult, &success);
     503             : 
     504           0 :   if (!success) {
     505           0 :     return false;
     506             :   }
     507             : 
     508           0 :   ConvertToVariant(remoteResult, *aResult);
     509           0 :   return true;
     510             : }
     511             : 
     512             : const NPClass PluginScriptableObjectChild::sNPClass = {
     513             :   NP_CLASS_STRUCT_VERSION,
     514             :   PluginScriptableObjectChild::ScriptableAllocate,
     515             :   PluginScriptableObjectChild::ScriptableDeallocate,
     516             :   PluginScriptableObjectChild::ScriptableInvalidate,
     517             :   PluginScriptableObjectChild::ScriptableHasMethod,
     518             :   PluginScriptableObjectChild::ScriptableInvoke,
     519             :   PluginScriptableObjectChild::ScriptableInvokeDefault,
     520             :   PluginScriptableObjectChild::ScriptableHasProperty,
     521             :   PluginScriptableObjectChild::ScriptableGetProperty,
     522             :   PluginScriptableObjectChild::ScriptableSetProperty,
     523             :   PluginScriptableObjectChild::ScriptableRemoveProperty,
     524             :   PluginScriptableObjectChild::ScriptableEnumerate,
     525             :   PluginScriptableObjectChild::ScriptableConstruct
     526             : };
     527             : 
     528           0 : PluginScriptableObjectChild::PluginScriptableObjectChild(
     529           0 :                                                      ScriptableObjectType aType)
     530             : : mInstance(nullptr),
     531             :   mObject(nullptr),
     532             :   mInvalidated(false),
     533             :   mProtectCount(0),
     534           0 :   mType(aType)
     535             : {
     536           0 :   AssertPluginThread();
     537           0 : }
     538             : 
     539           0 : PluginScriptableObjectChild::~PluginScriptableObjectChild()
     540             : {
     541           0 :   AssertPluginThread();
     542             : 
     543           0 :   if (mObject) {
     544           0 :     UnregisterActor(mObject);
     545             : 
     546           0 :     if (mObject->_class == GetClass()) {
     547           0 :       NS_ASSERTION(mType == Proxy, "Wrong type!");
     548           0 :       static_cast<ChildNPObject*>(mObject)->parent = nullptr;
     549             :     }
     550             :     else {
     551           0 :       NS_ASSERTION(mType == LocalObject, "Wrong type!");
     552           0 :       PluginModuleChild::sBrowserFuncs.releaseobject(mObject);
     553             :     }
     554             :   }
     555           0 : }
     556             : 
     557             : bool
     558           0 : PluginScriptableObjectChild::InitializeProxy()
     559             : {
     560           0 :   AssertPluginThread();
     561           0 :   NS_ASSERTION(mType == Proxy, "Bad type!");
     562           0 :   NS_ASSERTION(!mObject, "Calling Initialize more than once!");
     563           0 :   NS_ASSERTION(!mInvalidated, "Already invalidated?!");
     564             : 
     565           0 :   mInstance = static_cast<PluginInstanceChild*>(Manager());
     566           0 :   NS_ASSERTION(mInstance, "Null manager?!");
     567             : 
     568           0 :   NPObject* object = CreateProxyObject();
     569           0 :   if (!object) {
     570           0 :     NS_ERROR("Failed to create object!");
     571           0 :     return false;
     572             :   }
     573             : 
     574           0 :   if (!RegisterActor(object)) {
     575           0 :     NS_ERROR("RegisterActor failed");
     576           0 :     return false;
     577             :   }
     578             : 
     579           0 :   mObject = object;
     580           0 :   return true;
     581             : }
     582             : 
     583             : void
     584           0 : PluginScriptableObjectChild::InitializeLocal(NPObject* aObject)
     585             : {
     586           0 :   AssertPluginThread();
     587           0 :   NS_ASSERTION(mType == LocalObject, "Bad type!");
     588           0 :   NS_ASSERTION(!mObject, "Calling Initialize more than once!");
     589           0 :   NS_ASSERTION(!mInvalidated, "Already invalidated?!");
     590             : 
     591           0 :   mInstance = static_cast<PluginInstanceChild*>(Manager());
     592           0 :   NS_ASSERTION(mInstance, "Null manager?!");
     593             : 
     594           0 :   PluginModuleChild::sBrowserFuncs.retainobject(aObject);
     595             : 
     596           0 :   NS_ASSERTION(!mProtectCount, "Should be zero!");
     597           0 :   mProtectCount++;
     598             : 
     599           0 :   if (!RegisterActor(aObject)) {
     600           0 :     NS_ERROR("RegisterActor failed");
     601             :   }
     602             : 
     603           0 :   mObject = aObject;
     604           0 : }
     605             : 
     606             : NPObject*
     607           0 : PluginScriptableObjectChild::CreateProxyObject()
     608             : {
     609           0 :   NS_ASSERTION(mInstance, "Must have an instance!");
     610           0 :   NS_ASSERTION(mType == Proxy, "Shouldn't call this for non-proxy object!");
     611             : 
     612           0 :   NPClass* proxyClass = const_cast<NPClass*>(GetClass());
     613             :   NPObject* npobject =
     614           0 :     PluginModuleChild::sBrowserFuncs.createobject(mInstance->GetNPP(),
     615           0 :                                                   proxyClass);
     616           0 :   NS_ASSERTION(npobject, "Failed to create object?!");
     617           0 :   NS_ASSERTION(npobject->_class == GetClass(), "Wrong kind of object!");
     618           0 :   NS_ASSERTION(npobject->referenceCount == 1, "Some kind of live object!");
     619             : 
     620           0 :   ChildNPObject* object = static_cast<ChildNPObject*>(npobject);
     621           0 :   NS_ASSERTION(!object->invalidated, "Bad object!");
     622           0 :   NS_ASSERTION(!object->parent, "Bad object!");
     623             : 
     624             :   // We don't want to have the actor own this object but rather let the object
     625             :   // own this actor. Set the reference count to 0 here so that when the object
     626             :   // dies we will send the destructor message to the child.
     627           0 :   object->referenceCount = 0;
     628           0 :   NS_LOG_RELEASE(object, 0, "NPObject");
     629             : 
     630           0 :   object->parent = const_cast<PluginScriptableObjectChild*>(this);
     631           0 :   return object;
     632             : }
     633             : 
     634             : bool
     635           0 : PluginScriptableObjectChild::ResurrectProxyObject()
     636             : {
     637           0 :   NS_ASSERTION(mInstance, "Must have an instance already!");
     638           0 :   NS_ASSERTION(!mObject, "Should not have an object already!");
     639           0 :   NS_ASSERTION(mType == Proxy, "Shouldn't call this for non-proxy object!");
     640             : 
     641           0 :   if (!InitializeProxy()) {
     642           0 :     NS_ERROR("Initialize failed!");
     643           0 :     return false;
     644             :   }
     645             : 
     646           0 :   SendProtect();
     647           0 :   return true;
     648             : }
     649             : 
     650             : NPObject*
     651           0 : PluginScriptableObjectChild::GetObject(bool aCanResurrect)
     652             : {
     653           0 :   if (!mObject && aCanResurrect && !ResurrectProxyObject()) {
     654           0 :     NS_ERROR("Null object!");
     655           0 :     return nullptr;
     656             :   }
     657           0 :   return mObject;
     658             : }
     659             : 
     660             : void
     661           0 : PluginScriptableObjectChild::Protect()
     662             : {
     663           0 :   NS_ASSERTION(mObject, "No object!");
     664           0 :   NS_ASSERTION(mProtectCount >= 0, "Negative retain count?!");
     665             : 
     666           0 :   if (mType == LocalObject) {
     667           0 :     ++mProtectCount;
     668             :   }
     669           0 : }
     670             : 
     671             : void
     672           0 : PluginScriptableObjectChild::Unprotect()
     673             : {
     674           0 :   NS_ASSERTION(mObject, "Bad state!");
     675           0 :   NS_ASSERTION(mProtectCount >= 0, "Negative retain count?!");
     676             : 
     677           0 :   if (mType == LocalObject) {
     678           0 :     if (--mProtectCount == 0) {
     679           0 :       PluginScriptableObjectChild::Send__delete__(this);
     680             :     }
     681             :   }
     682           0 : }
     683             : 
     684             : void
     685           0 : PluginScriptableObjectChild::DropNPObject()
     686             : {
     687           0 :   NS_ASSERTION(mObject, "Invalidated object!");
     688           0 :   NS_ASSERTION(mObject->_class == GetClass(), "Wrong type of object!");
     689           0 :   NS_ASSERTION(mType == Proxy, "Shouldn't call this for non-proxy object!");
     690             : 
     691             :   // We think we're about to be deleted, but we could be racing with the other
     692             :   // process.
     693           0 :   UnregisterActor(mObject);
     694           0 :   mObject = nullptr;
     695             : 
     696           0 :   SendUnprotect();
     697           0 : }
     698             : 
     699             : void
     700           0 : PluginScriptableObjectChild::NPObjectDestroyed()
     701             : {
     702           0 :   NS_ASSERTION(LocalObject == mType,
     703             :                "ScriptableDeallocate should have handled this for proxies");
     704           0 :   mInvalidated = true;
     705           0 :   mObject = nullptr;
     706           0 : }
     707             : 
     708             : mozilla::ipc::IPCResult
     709           0 : PluginScriptableObjectChild::AnswerInvalidate()
     710             : {
     711           0 :   AssertPluginThread();
     712           0 :   PluginInstanceChild::AutoStackHelper guard(mInstance);
     713             : 
     714           0 :   if (mInvalidated) {
     715           0 :     return IPC_OK();
     716             :   }
     717             : 
     718           0 :   mInvalidated = true;
     719             : 
     720           0 :   NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
     721           0 :   NS_ASSERTION(mType == LocalObject, "Bad type!");
     722             : 
     723           0 :   if (mObject->_class && mObject->_class->invalidate) {
     724           0 :     mObject->_class->invalidate(mObject);
     725             :   }
     726             : 
     727           0 :   Unprotect();
     728             : 
     729           0 :   return IPC_OK();
     730             : }
     731             : 
     732             : mozilla::ipc::IPCResult
     733           0 : PluginScriptableObjectChild::AnswerHasMethod(const PluginIdentifier& aId,
     734             :                                              bool* aHasMethod)
     735             : {
     736           0 :   AssertPluginThread();
     737           0 :   PluginInstanceChild::AutoStackHelper guard(mInstance);
     738             : 
     739           0 :   if (mInvalidated) {
     740           0 :     NS_WARNING("Calling AnswerHasMethod with an invalidated object!");
     741           0 :     *aHasMethod = false;
     742           0 :     return IPC_OK();
     743             :   }
     744             : 
     745           0 :   NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
     746           0 :   NS_ASSERTION(mType == LocalObject, "Bad type!");
     747             : 
     748           0 :   if (!(mObject->_class && mObject->_class->hasMethod)) {
     749           0 :     *aHasMethod = false;
     750           0 :     return IPC_OK();
     751             :   }
     752             : 
     753           0 :   StackIdentifier id(aId);
     754           0 :   *aHasMethod = mObject->_class->hasMethod(mObject, id.ToNPIdentifier());
     755           0 :   return IPC_OK();
     756             : }
     757             : 
     758             : mozilla::ipc::IPCResult
     759           0 : PluginScriptableObjectChild::AnswerInvoke(const PluginIdentifier& aId,
     760             :                                           InfallibleTArray<Variant>&& aArgs,
     761             :                                           Variant* aResult,
     762             :                                           bool* aSuccess)
     763             : {
     764           0 :   AssertPluginThread();
     765           0 :   PluginInstanceChild::AutoStackHelper guard(mInstance);
     766             : 
     767           0 :   if (mInvalidated) {
     768           0 :     NS_WARNING("Calling AnswerInvoke with an invalidated object!");
     769           0 :     *aResult = void_t();
     770           0 :     *aSuccess = false;
     771           0 :     return IPC_OK();
     772             :   }
     773             : 
     774           0 :   NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
     775           0 :   NS_ASSERTION(mType == LocalObject, "Bad type!");
     776             : 
     777           0 :   if (!(mObject->_class && mObject->_class->invoke)) {
     778           0 :     *aResult = void_t();
     779           0 :     *aSuccess = false;
     780           0 :     return IPC_OK();
     781             :   }
     782             : 
     783           0 :   AutoTArray<NPVariant, 10> convertedArgs;
     784           0 :   uint32_t argCount = aArgs.Length();
     785             : 
     786           0 :   if (!convertedArgs.SetLength(argCount, mozilla::fallible)) {
     787           0 :     *aResult = void_t();
     788           0 :     *aSuccess = false;
     789           0 :     return IPC_OK();
     790             :   }
     791             : 
     792           0 :   for (uint32_t index = 0; index < argCount; index++) {
     793           0 :     ConvertToVariant(aArgs[index], convertedArgs[index]);
     794             :   }
     795             : 
     796             :   NPVariant result;
     797           0 :   VOID_TO_NPVARIANT(result);
     798           0 :   StackIdentifier id(aId);
     799           0 :   bool success = mObject->_class->invoke(mObject, id.ToNPIdentifier(),
     800           0 :                                          convertedArgs.Elements(), argCount,
     801           0 :                                          &result);
     802             : 
     803           0 :   for (uint32_t index = 0; index < argCount; index++) {
     804           0 :     PluginModuleChild::sBrowserFuncs.releasevariantvalue(&convertedArgs[index]);
     805             :   }
     806             : 
     807           0 :   if (!success) {
     808           0 :     *aResult = void_t();
     809           0 :     *aSuccess = false;
     810           0 :     return IPC_OK();
     811             :   }
     812             : 
     813           0 :   Variant convertedResult;
     814           0 :   success = ConvertToRemoteVariant(result, convertedResult, GetInstance(),
     815           0 :                                    false);
     816             : 
     817           0 :   DeferNPVariantLastRelease(&PluginModuleChild::sBrowserFuncs, &result);
     818             : 
     819           0 :   if (!success) {
     820           0 :     *aResult = void_t();
     821           0 :     *aSuccess = false;
     822           0 :     return IPC_OK();
     823             :   }
     824             : 
     825           0 :   *aSuccess = true;
     826           0 :   *aResult = convertedResult;
     827           0 :   return IPC_OK();
     828             : }
     829             : 
     830             : mozilla::ipc::IPCResult
     831           0 : PluginScriptableObjectChild::AnswerInvokeDefault(InfallibleTArray<Variant>&& aArgs,
     832             :                                                  Variant* aResult,
     833             :                                                  bool* aSuccess)
     834             : {
     835           0 :   AssertPluginThread();
     836           0 :   PluginInstanceChild::AutoStackHelper guard(mInstance);
     837             : 
     838           0 :   if (mInvalidated) {
     839           0 :     NS_WARNING("Calling AnswerInvokeDefault with an invalidated object!");
     840           0 :     *aResult = void_t();
     841           0 :     *aSuccess = false;
     842           0 :     return IPC_OK();
     843             :   }
     844             : 
     845           0 :   NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
     846           0 :   NS_ASSERTION(mType == LocalObject, "Bad type!");
     847             : 
     848           0 :   if (!(mObject->_class && mObject->_class->invokeDefault)) {
     849           0 :     *aResult = void_t();
     850           0 :     *aSuccess = false;
     851           0 :     return IPC_OK();
     852             :   }
     853             : 
     854           0 :   AutoTArray<NPVariant, 10> convertedArgs;
     855           0 :   uint32_t argCount = aArgs.Length();
     856             : 
     857           0 :   if (!convertedArgs.SetLength(argCount, mozilla::fallible)) {
     858           0 :     *aResult = void_t();
     859           0 :     *aSuccess = false;
     860           0 :     return IPC_OK();
     861             :   }
     862             : 
     863           0 :   for (uint32_t index = 0; index < argCount; index++) {
     864           0 :     ConvertToVariant(aArgs[index], convertedArgs[index]);
     865             :   }
     866             : 
     867             :   NPVariant result;
     868           0 :   VOID_TO_NPVARIANT(result);
     869           0 :   bool success = mObject->_class->invokeDefault(mObject,
     870           0 :                                                 convertedArgs.Elements(),
     871           0 :                                                 argCount, &result);
     872             : 
     873           0 :   for (uint32_t index = 0; index < argCount; index++) {
     874           0 :     PluginModuleChild::sBrowserFuncs.releasevariantvalue(&convertedArgs[index]);
     875             :   }
     876             : 
     877           0 :   if (!success) {
     878           0 :     *aResult = void_t();
     879           0 :     *aSuccess = false;
     880           0 :     return IPC_OK();
     881             :   }
     882             : 
     883           0 :   Variant convertedResult;
     884           0 :   success = ConvertToRemoteVariant(result, convertedResult, GetInstance(),
     885           0 :                                    false);
     886             : 
     887           0 :   DeferNPVariantLastRelease(&PluginModuleChild::sBrowserFuncs, &result);
     888             : 
     889           0 :   if (!success) {
     890           0 :     *aResult = void_t();
     891           0 :     *aSuccess = false;
     892           0 :     return IPC_OK();
     893             :   }
     894             : 
     895           0 :   *aResult = convertedResult;
     896           0 :   *aSuccess = true;
     897           0 :   return IPC_OK();
     898             : }
     899             : 
     900             : mozilla::ipc::IPCResult
     901           0 : PluginScriptableObjectChild::AnswerHasProperty(const PluginIdentifier& aId,
     902             :                                                bool* aHasProperty)
     903             : {
     904           0 :   AssertPluginThread();
     905           0 :   PluginInstanceChild::AutoStackHelper guard(mInstance);
     906             : 
     907           0 :   if (mInvalidated) {
     908           0 :     NS_WARNING("Calling AnswerHasProperty with an invalidated object!");
     909           0 :     *aHasProperty = false;
     910           0 :     return IPC_OK();
     911             :   }
     912             : 
     913           0 :   NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
     914           0 :   NS_ASSERTION(mType == LocalObject, "Bad type!");
     915             : 
     916           0 :   if (!(mObject->_class && mObject->_class->hasProperty)) {
     917           0 :     *aHasProperty = false;
     918           0 :     return IPC_OK();
     919             :   }
     920             : 
     921           0 :   StackIdentifier id(aId);
     922           0 :   *aHasProperty = mObject->_class->hasProperty(mObject, id.ToNPIdentifier());
     923           0 :   return IPC_OK();
     924             : }
     925             : 
     926             : mozilla::ipc::IPCResult
     927           0 : PluginScriptableObjectChild::AnswerGetChildProperty(const PluginIdentifier& aId,
     928             :                                                     bool* aHasProperty,
     929             :                                                     bool* aHasMethod,
     930             :                                                     Variant* aResult,
     931             :                                                     bool* aSuccess)
     932             : {
     933           0 :   AssertPluginThread();
     934           0 :   PluginInstanceChild::AutoStackHelper guard(mInstance);
     935             : 
     936           0 :   *aHasProperty = *aHasMethod = *aSuccess = false;
     937           0 :   *aResult = void_t();
     938             : 
     939           0 :   if (mInvalidated) {
     940           0 :     NS_WARNING("Calling AnswerGetProperty with an invalidated object!");
     941           0 :     return IPC_OK();
     942             :   }
     943             : 
     944           0 :   NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
     945           0 :   NS_ASSERTION(mType == LocalObject, "Bad type!");
     946             : 
     947           0 :   if (!(mObject->_class && mObject->_class->hasProperty &&
     948           0 :         mObject->_class->hasMethod && mObject->_class->getProperty)) {
     949           0 :     return IPC_OK();
     950             :   }
     951             : 
     952           0 :   StackIdentifier stackID(aId);
     953           0 :   NPIdentifier id = stackID.ToNPIdentifier();
     954             : 
     955           0 :   *aHasProperty = mObject->_class->hasProperty(mObject, id);
     956           0 :   *aHasMethod = mObject->_class->hasMethod(mObject, id);
     957             : 
     958           0 :   if (*aHasProperty) {
     959             :     NPVariant result;
     960           0 :     VOID_TO_NPVARIANT(result);
     961             : 
     962           0 :     if (!mObject->_class->getProperty(mObject, id, &result)) {
     963           0 :       return IPC_OK();
     964             :     }
     965             : 
     966           0 :     Variant converted;
     967           0 :     if ((*aSuccess = ConvertToRemoteVariant(result, converted, GetInstance(),
     968             :                                             false))) {
     969           0 :       DeferNPVariantLastRelease(&PluginModuleChild::sBrowserFuncs, &result);
     970           0 :       *aResult = converted;
     971             :     }
     972             :   }
     973             : 
     974           0 :   return IPC_OK();
     975             : }
     976             : 
     977             : mozilla::ipc::IPCResult
     978           0 : PluginScriptableObjectChild::AnswerSetProperty(const PluginIdentifier& aId,
     979             :                                                const Variant& aValue,
     980             :                                                bool* aSuccess)
     981             : {
     982           0 :   AssertPluginThread();
     983           0 :   PluginInstanceChild::AutoStackHelper guard(mInstance);
     984             : 
     985           0 :   if (mInvalidated) {
     986           0 :     NS_WARNING("Calling AnswerSetProperty with an invalidated object!");
     987           0 :     *aSuccess = false;
     988           0 :     return IPC_OK();
     989             :   }
     990             : 
     991           0 :   NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
     992           0 :   NS_ASSERTION(mType == LocalObject, "Bad type!");
     993             : 
     994           0 :   if (!(mObject->_class && mObject->_class->hasProperty &&
     995           0 :         mObject->_class->setProperty)) {
     996           0 :     *aSuccess = false;
     997           0 :     return IPC_OK();
     998             :   }
     999             : 
    1000           0 :   StackIdentifier stackID(aId);
    1001           0 :   NPIdentifier id = stackID.ToNPIdentifier();
    1002             : 
    1003           0 :   if (!mObject->_class->hasProperty(mObject, id)) {
    1004           0 :     *aSuccess = false;
    1005           0 :     return IPC_OK();
    1006             :   }
    1007             : 
    1008             :   NPVariant converted;
    1009           0 :   ConvertToVariant(aValue, converted);
    1010             : 
    1011           0 :   if ((*aSuccess = mObject->_class->setProperty(mObject, id, &converted))) {
    1012           0 :     PluginModuleChild::sBrowserFuncs.releasevariantvalue(&converted);
    1013             :   }
    1014           0 :   return IPC_OK();
    1015             : }
    1016             : 
    1017             : mozilla::ipc::IPCResult
    1018           0 : PluginScriptableObjectChild::AnswerRemoveProperty(const PluginIdentifier& aId,
    1019             :                                                   bool* aSuccess)
    1020             : {
    1021           0 :   AssertPluginThread();
    1022           0 :   PluginInstanceChild::AutoStackHelper guard(mInstance);
    1023             : 
    1024           0 :   if (mInvalidated) {
    1025           0 :     NS_WARNING("Calling AnswerRemoveProperty with an invalidated object!");
    1026           0 :     *aSuccess = false;
    1027           0 :     return IPC_OK();
    1028             :   }
    1029             : 
    1030           0 :   NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
    1031           0 :   NS_ASSERTION(mType == LocalObject, "Bad type!");
    1032             : 
    1033           0 :   if (!(mObject->_class && mObject->_class->hasProperty &&
    1034           0 :         mObject->_class->removeProperty)) {
    1035           0 :     *aSuccess = false;
    1036           0 :     return IPC_OK();
    1037             :   }
    1038             : 
    1039           0 :   StackIdentifier stackID(aId);
    1040           0 :   NPIdentifier id = stackID.ToNPIdentifier();
    1041           0 :   *aSuccess = mObject->_class->hasProperty(mObject, id) ?
    1042           0 :               mObject->_class->removeProperty(mObject, id) :
    1043             :               true;
    1044             : 
    1045           0 :   return IPC_OK();
    1046             : }
    1047             : 
    1048             : mozilla::ipc::IPCResult
    1049           0 : PluginScriptableObjectChild::AnswerEnumerate(InfallibleTArray<PluginIdentifier>* aProperties,
    1050             :                                              bool* aSuccess)
    1051             : {
    1052           0 :   AssertPluginThread();
    1053           0 :   PluginInstanceChild::AutoStackHelper guard(mInstance);
    1054             : 
    1055           0 :   if (mInvalidated) {
    1056           0 :     NS_WARNING("Calling AnswerEnumerate with an invalidated object!");
    1057           0 :     *aSuccess = false;
    1058           0 :     return IPC_OK();
    1059             :   }
    1060             : 
    1061           0 :   NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
    1062           0 :   NS_ASSERTION(mType == LocalObject, "Bad type!");
    1063             : 
    1064           0 :   if (!(mObject->_class && mObject->_class->enumerate)) {
    1065           0 :     *aSuccess = false;
    1066           0 :     return IPC_OK();
    1067             :   }
    1068             : 
    1069             :   NPIdentifier* ids;
    1070             :   uint32_t idCount;
    1071           0 :   if (!mObject->_class->enumerate(mObject, &ids, &idCount)) {
    1072           0 :     *aSuccess = false;
    1073           0 :     return IPC_OK();
    1074             :   }
    1075             : 
    1076           0 :   aProperties->SetCapacity(idCount);
    1077             : 
    1078           0 :   for (uint32_t index = 0; index < idCount; index++) {
    1079           0 :     aProperties->AppendElement(FromNPIdentifier(ids[index]));
    1080             :   }
    1081             : 
    1082           0 :   PluginModuleChild::sBrowserFuncs.memfree(ids);
    1083           0 :   *aSuccess = true;
    1084           0 :   return IPC_OK();
    1085             : }
    1086             : 
    1087             : mozilla::ipc::IPCResult
    1088           0 : PluginScriptableObjectChild::AnswerConstruct(InfallibleTArray<Variant>&& aArgs,
    1089             :                                              Variant* aResult,
    1090             :                                              bool* aSuccess)
    1091             : {
    1092           0 :   AssertPluginThread();
    1093           0 :   PluginInstanceChild::AutoStackHelper guard(mInstance);
    1094             : 
    1095           0 :   if (mInvalidated) {
    1096           0 :     NS_WARNING("Calling AnswerConstruct with an invalidated object!");
    1097           0 :     *aResult = void_t();
    1098           0 :     *aSuccess = false;
    1099           0 :     return IPC_OK();
    1100             :   }
    1101             : 
    1102           0 :   NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
    1103           0 :   NS_ASSERTION(mType == LocalObject, "Bad type!");
    1104             : 
    1105           0 :   if (!(mObject->_class && mObject->_class->construct)) {
    1106           0 :     *aResult = void_t();
    1107           0 :     *aSuccess = false;
    1108           0 :     return IPC_OK();
    1109             :   }
    1110             : 
    1111           0 :   AutoTArray<NPVariant, 10> convertedArgs;
    1112           0 :   uint32_t argCount = aArgs.Length();
    1113             : 
    1114           0 :   if (!convertedArgs.SetLength(argCount, mozilla::fallible)) {
    1115           0 :     *aResult = void_t();
    1116           0 :     *aSuccess = false;
    1117           0 :     return IPC_OK();
    1118             :   }
    1119             : 
    1120           0 :   for (uint32_t index = 0; index < argCount; index++) {
    1121           0 :     ConvertToVariant(aArgs[index], convertedArgs[index]);
    1122             :   }
    1123             : 
    1124             :   NPVariant result;
    1125           0 :   VOID_TO_NPVARIANT(result);
    1126           0 :   bool success = mObject->_class->construct(mObject, convertedArgs.Elements(),
    1127           0 :                                             argCount, &result);
    1128             : 
    1129           0 :   for (uint32_t index = 0; index < argCount; index++) {
    1130           0 :     PluginModuleChild::sBrowserFuncs.releasevariantvalue(&convertedArgs[index]);
    1131             :   }
    1132             : 
    1133           0 :   if (!success) {
    1134           0 :     *aResult = void_t();
    1135           0 :     *aSuccess = false;
    1136           0 :     return IPC_OK();
    1137             :   }
    1138             : 
    1139           0 :   Variant convertedResult;
    1140           0 :   success = ConvertToRemoteVariant(result, convertedResult, GetInstance(),
    1141           0 :                                    false);
    1142             : 
    1143           0 :   DeferNPVariantLastRelease(&PluginModuleChild::sBrowserFuncs, &result);
    1144             : 
    1145           0 :   if (!success) {
    1146           0 :     *aResult = void_t();
    1147           0 :     *aSuccess = false;
    1148           0 :     return IPC_OK();
    1149             :   }
    1150             : 
    1151           0 :   *aResult = convertedResult;
    1152           0 :   *aSuccess = true;
    1153           0 :   return IPC_OK();
    1154             : }
    1155             : 
    1156             : mozilla::ipc::IPCResult
    1157           0 : PluginScriptableObjectChild::RecvProtect()
    1158             : {
    1159           0 :   NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
    1160           0 :   NS_ASSERTION(mType == LocalObject, "Bad type!");
    1161             : 
    1162           0 :   Protect();
    1163           0 :   return IPC_OK();
    1164             : }
    1165             : 
    1166             : mozilla::ipc::IPCResult
    1167           0 : PluginScriptableObjectChild::RecvUnprotect()
    1168             : {
    1169           0 :   NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
    1170           0 :   NS_ASSERTION(mType == LocalObject, "Bad type!");
    1171             : 
    1172           0 :   Unprotect();
    1173           0 :   return IPC_OK();
    1174             : }
    1175             : 
    1176             : bool
    1177           0 : PluginScriptableObjectChild::Evaluate(NPString* aScript,
    1178             :                                       NPVariant* aResult)
    1179             : {
    1180           0 :   PluginInstanceChild::AutoStackHelper guard(mInstance);
    1181             : 
    1182           0 :   nsDependentCString script("");
    1183           0 :   if (aScript->UTF8Characters && aScript->UTF8Length) {
    1184           0 :     script.Rebind(aScript->UTF8Characters, aScript->UTF8Length);
    1185             :   }
    1186             : 
    1187             :   bool success;
    1188           0 :   Variant result;
    1189           0 :   CallNPN_Evaluate(script, &result, &success);
    1190             : 
    1191           0 :   if (!success) {
    1192           0 :     return false;
    1193             :   }
    1194             : 
    1195           0 :   ConvertToVariant(result, *aResult);
    1196           0 :   return true;
    1197             : }
    1198             : 
    1199             : nsTHashtable<PluginScriptableObjectChild::NPObjectData>* PluginScriptableObjectChild::sObjectMap;
    1200             : 
    1201             : bool
    1202           0 : PluginScriptableObjectChild::RegisterActor(NPObject* aObject)
    1203             : {
    1204           0 :   AssertPluginThread();
    1205           0 :   MOZ_ASSERT(aObject, "Null pointer!");
    1206             : 
    1207           0 :   NPObjectData* d = sObjectMap->GetEntry(aObject);
    1208           0 :   if (!d) {
    1209           0 :     NS_ERROR("NPObject not in object table");
    1210           0 :     return false;
    1211             :   }
    1212             : 
    1213           0 :   d->actor = this;
    1214           0 :   return true;
    1215             : }
    1216             : 
    1217             : void
    1218           0 : PluginScriptableObjectChild::UnregisterActor(NPObject* aObject)
    1219             : {
    1220           0 :   AssertPluginThread();
    1221           0 :   MOZ_ASSERT(aObject, "Null pointer!");
    1222             : 
    1223           0 :   NPObjectData* d = sObjectMap->GetEntry(aObject);
    1224           0 :   MOZ_ASSERT(d, "NPObject not in object table");
    1225           0 :   if (d) {
    1226           0 :     d->actor = nullptr;
    1227             :   }
    1228           0 : }
    1229             : 
    1230             : /* static */ PluginScriptableObjectChild*
    1231           0 : PluginScriptableObjectChild::GetActorForNPObject(NPObject* aObject)
    1232             : {
    1233           0 :   AssertPluginThread();
    1234           0 :   MOZ_ASSERT(aObject, "Null pointer!");
    1235             : 
    1236           0 :   NPObjectData* d = sObjectMap->GetEntry(aObject);
    1237           0 :   if (!d) {
    1238           0 :     NS_ERROR("Plugin using object not created with NPN_CreateObject?");
    1239           0 :     return nullptr;
    1240             :   }
    1241             : 
    1242           0 :   return d->actor;
    1243             : }
    1244             : 
    1245             : /* static */ void
    1246           0 : PluginScriptableObjectChild::RegisterObject(NPObject* aObject, PluginInstanceChild* aInstance)
    1247             : {
    1248           0 :   AssertPluginThread();
    1249             : 
    1250           0 :   if (!sObjectMap) {
    1251           0 :     sObjectMap = new nsTHashtable<PluginScriptableObjectChild::NPObjectData>();
    1252             :   }
    1253             : 
    1254           0 :   NPObjectData* d = sObjectMap->PutEntry(aObject);
    1255           0 :   MOZ_ASSERT(!d->instance, "New NPObject already mapped?");
    1256           0 :   d->instance = aInstance;
    1257           0 : }
    1258             : 
    1259             : /* static */ void
    1260           0 : PluginScriptableObjectChild::UnregisterObject(NPObject* aObject)
    1261             : {
    1262           0 :   AssertPluginThread();
    1263             : 
    1264           0 :   sObjectMap->RemoveEntry(aObject);
    1265             : 
    1266           0 :   if (!sObjectMap->Count()) {
    1267           0 :     delete sObjectMap;
    1268           0 :     sObjectMap = nullptr;
    1269             :   }
    1270           0 : }
    1271             : 
    1272             : /* static */ PluginInstanceChild*
    1273           0 : PluginScriptableObjectChild::GetInstanceForNPObject(NPObject* aObject)
    1274             : {
    1275           0 :   AssertPluginThread();
    1276           0 :   NPObjectData* d = sObjectMap->GetEntry(aObject);
    1277           0 :   if (!d) {
    1278           0 :     return nullptr;
    1279             :   }
    1280           0 :   return d->instance;
    1281             : }
    1282             : 
    1283             : /* static */ void
    1284           0 : PluginScriptableObjectChild::NotifyOfInstanceShutdown(PluginInstanceChild* aInstance)
    1285             : {
    1286           0 :   AssertPluginThread();
    1287           0 :   if (!sObjectMap) {
    1288           0 :     return;
    1289             :   }
    1290             : 
    1291           0 :   for (auto iter = sObjectMap->Iter(); !iter.Done(); iter.Next()) {
    1292           0 :     NPObjectData* d = iter.Get();
    1293           0 :     if (d->instance == aInstance) {
    1294           0 :         NPObject* o = d->GetKey();
    1295           0 :         aInstance->mDeletingHash->PutEntry(o);
    1296             :     }
    1297             :   }
    1298             : }

Generated by: LCOV version 1.13