LCOV - code coverage report
Current view: directory - js/xpconnect/src - XPCJSID.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 421 304 72.2 %
Date: 2012-06-02 Functions: 73 60 82.2 %

       1                 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
       2                 :  *
       3                 :  * ***** BEGIN LICENSE BLOCK *****
       4                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       5                 :  *
       6                 :  * The contents of this file are subject to the Mozilla Public License Version
       7                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       8                 :  * the License. You may obtain a copy of the License at
       9                 :  * http://www.mozilla.org/MPL/
      10                 :  *
      11                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      12                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      13                 :  * for the specific language governing rights and limitations under the
      14                 :  * License.
      15                 :  *
      16                 :  * The Original Code is Mozilla Communicator client code, released
      17                 :  * March 31, 1998.
      18                 :  *
      19                 :  * The Initial Developer of the Original Code is
      20                 :  * Netscape Communications Corporation.
      21                 :  * Portions created by the Initial Developer are Copyright (C) 1998
      22                 :  * the Initial Developer. All Rights Reserved.
      23                 :  *
      24                 :  * Contributor(s):
      25                 :  *   John Bandhauer <jband@netscape.com> (original author)
      26                 :  *   Pierre Phaneuf <pp@ludusdesign.com>
      27                 :  *
      28                 :  * Alternatively, the contents of this file may be used under the terms of
      29                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      30                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      31                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      32                 :  * of those above. If you wish to allow use of your version of this file only
      33                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      34                 :  * use your version of this file under the terms of the MPL, indicate your
      35                 :  * decision by deleting the provisions above and replace them with the notice
      36                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      37                 :  * the provisions above, a recipient may use your version of this file under
      38                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      39                 :  *
      40                 :  * ***** END LICENSE BLOCK ***** */
      41                 : 
      42                 : /* An xpcom implementation of the JavaScript nsIID and nsCID objects. */
      43                 : 
      44                 : #include "xpcprivate.h"
      45                 : 
      46                 : /***************************************************************************/
      47                 : // nsJSID
      48                 : 
      49         3162213 : NS_IMPL_THREADSAFE_ISUPPORTS1(nsJSID, nsIJSID)
      50                 : 
      51                 : char nsJSID::gNoString[] = "";
      52                 : 
      53          210367 : nsJSID::nsJSID()
      54          210367 :     : mID(GetInvalidIID()), mNumber(gNoString), mName(gNoString)
      55                 : {
      56          210367 : }
      57                 : 
      58          376365 : nsJSID::~nsJSID()
      59                 : {
      60          210155 :     if (mNumber && mNumber != gNoString)
      61            6114 :         NS_Free(mNumber);
      62          210155 :     if (mName && mName != gNoString)
      63           42359 :         NS_Free(mName);
      64          752730 : }
      65                 : 
      66           42560 : void nsJSID::Reset()
      67                 : {
      68           42560 :     mID = GetInvalidIID();
      69                 : 
      70           42560 :     if (mNumber && mNumber != gNoString)
      71               0 :         NS_Free(mNumber);
      72           42560 :     if (mName && mName != gNoString)
      73               0 :         NS_Free(mName);
      74                 : 
      75           42560 :     mNumber = mName = nsnull;
      76           42560 : }
      77                 : 
      78                 : bool
      79           42558 : nsJSID::SetName(const char* name)
      80                 : {
      81           42558 :     NS_ASSERTION(!mName || mName == gNoString ,"name already set");
      82           42558 :     NS_ASSERTION(name,"null name");
      83           42558 :     mName = NS_strdup(name);
      84           42558 :     return mName ? true : false;
      85                 : }
      86                 : 
      87                 : NS_IMETHODIMP
      88             182 : nsJSID::GetName(char * *aName)
      89                 : {
      90             182 :     if (!aName)
      91               0 :         return NS_ERROR_NULL_POINTER;
      92                 : 
      93             182 :     if (!NameIsSet())
      94               0 :         SetNameToNoString();
      95             182 :     NS_ASSERTION(mName, "name not set");
      96             182 :     *aName = NS_strdup(mName);
      97             182 :     return *aName ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
      98                 : }
      99                 : 
     100                 : NS_IMETHODIMP
     101            6124 : nsJSID::GetNumber(char * *aNumber)
     102                 : {
     103            6124 :     if (!aNumber)
     104               0 :         return NS_ERROR_NULL_POINTER;
     105                 : 
     106            6124 :     if (!mNumber) {
     107            6121 :         if (!(mNumber = mID.ToString()))
     108               0 :             mNumber = gNoString;
     109                 :     }
     110                 : 
     111            6124 :     *aNumber = NS_strdup(mNumber);
     112            6124 :     return *aNumber ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
     113                 : }
     114                 : 
     115                 : NS_IMETHODIMP_(const nsID*)
     116          115524 : nsJSID::GetID()
     117                 : {
     118          115524 :     return &mID;
     119                 : }
     120                 : 
     121                 : NS_IMETHODIMP
     122               0 : nsJSID::GetValid(bool *aValid)
     123                 : {
     124               0 :     if (!aValid)
     125               0 :         return NS_ERROR_NULL_POINTER;
     126                 : 
     127               0 :     *aValid = IsValid();
     128               0 :     return NS_OK;
     129                 : }
     130                 : 
     131                 : NS_IMETHODIMP
     132          357213 : nsJSID::Equals(nsIJSID *other, bool *_retval)
     133                 : {
     134          357213 :     if (!_retval)
     135               0 :         return NS_ERROR_NULL_POINTER;
     136                 : 
     137          357213 :     if (!other || mID.Equals(GetInvalidIID())) {
     138               0 :         *_retval = false;
     139               0 :         return NS_OK;
     140                 :     }
     141                 : 
     142          357213 :     *_retval = other->GetID()->Equals(mID);
     143          357213 :     return NS_OK;
     144                 : }
     145                 : 
     146                 : NS_IMETHODIMP
     147               2 : nsJSID::Initialize(const char *idString)
     148                 : {
     149               2 :     if (!idString)
     150               0 :         return NS_ERROR_NULL_POINTER;
     151                 : 
     152               2 :     if (*idString != '\0' && mID.Equals(GetInvalidIID())) {
     153               2 :         Reset();
     154                 : 
     155               2 :         if (idString[0] == '{') {
     156               2 :             if (mID.Parse(idString)) {
     157               2 :                 return NS_OK;
     158                 :             }
     159                 : 
     160                 :             // error - reset to invalid state
     161               0 :             mID = GetInvalidIID();
     162                 :         }
     163                 :     }
     164               0 :     return NS_ERROR_FAILURE;
     165                 : }
     166                 : 
     167                 : bool
     168           42558 : nsJSID::InitWithName(const nsID& id, const char *nameString)
     169                 : {
     170           42558 :     NS_ASSERTION(nameString, "no name");
     171           42558 :     Reset();
     172           42558 :     mID = id;
     173           42558 :     return SetName(nameString);
     174                 : }
     175                 : 
     176                 : // try to use the name, if no name, then use the number
     177                 : NS_IMETHODIMP
     178            6306 : nsJSID::ToString(char **_retval)
     179                 : {
     180            6306 :     if (mName && mName != gNoString)
     181             182 :         return GetName(_retval);
     182                 : 
     183            6124 :     return GetNumber(_retval);
     184                 : }
     185                 : 
     186                 : const nsID&
     187          779318 : nsJSID::GetInvalidIID() const
     188                 : {
     189                 :     // {BB1F47B0-D137-11d2-9841-006008962422}
     190                 :     static nsID invalid = {0xbb1f47b0, 0xd137, 0x11d2,
     191                 :                             {0x98, 0x41, 0x0, 0x60, 0x8, 0x96, 0x24, 0x22}};
     192          779318 :     return invalid;
     193                 : }
     194                 : 
     195                 : //static
     196                 : nsJSID*
     197               0 : nsJSID::NewID(const char* str)
     198                 : {
     199               0 :     if (!str) {
     200               0 :         NS_ERROR("no string");
     201               0 :         return nsnull;
     202                 :     }
     203                 : 
     204               0 :     nsJSID* idObj = new nsJSID();
     205               0 :     if (idObj) {
     206               0 :         NS_ADDREF(idObj);
     207               0 :         if (NS_FAILED(idObj->Initialize(str)))
     208               0 :             NS_RELEASE(idObj);
     209                 :     }
     210               0 :     return idObj;
     211                 : }
     212                 : 
     213                 : //static
     214                 : nsJSID*
     215          166223 : nsJSID::NewID(const nsID& id)
     216                 : {
     217          166223 :     nsJSID* idObj = new nsJSID();
     218          166223 :     if (idObj) {
     219          166223 :         NS_ADDREF(idObj);
     220          166223 :         idObj->mID = id;
     221          166223 :         idObj->mName = nsnull;
     222          166223 :         idObj->mNumber = nsnull;
     223                 :     }
     224          166223 :     return idObj;
     225                 : }
     226                 : 
     227                 : 
     228                 : /***************************************************************************/
     229                 : // Class object support so that we can share prototypes of wrapper
     230                 : 
     231                 : // This class exists just so we can have a shared scriptable helper for
     232                 : // the nsJSIID class. The instances implement their own helpers. But we
     233                 : // needed to be able to indicate to the shared prototypes this single flag:
     234                 : // nsIXPCScriptable::DONT_ENUM_STATIC_PROPS. And having a class to do it is
     235                 : // the only means we have. Setting this flag on any given instance scriptable
     236                 : // helper is not sufficient to convey the information that we don't want
     237                 : // static properties enumerated on the shared proto.
     238                 : 
     239                 : class SharedScriptableHelperForJSIID : public nsIXPCScriptable
     240                 : {
     241                 : public:
     242                 :     NS_DECL_ISUPPORTS
     243                 :     NS_DECL_NSIXPCSCRIPTABLE
     244            1391 :     SharedScriptableHelperForJSIID() {}
     245                 : };
     246                 : 
     247          193674 : NS_INTERFACE_MAP_BEGIN(SharedScriptableHelperForJSIID)
     248          193674 :   NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
     249               0 :   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCScriptable)
     250               0 : NS_INTERFACE_MAP_END_THREADSAFE
     251                 : 
     252          297401 : NS_IMPL_THREADSAFE_ADDREF(SharedScriptableHelperForJSIID)
     253          298752 : NS_IMPL_THREADSAFE_RELEASE(SharedScriptableHelperForJSIID)
     254                 : 
     255                 : // The nsIXPCScriptable map declaration that will generate stubs for us...
     256                 : #define XPC_MAP_CLASSNAME           SharedScriptableHelperForJSIID
     257                 : #define XPC_MAP_QUOTED_CLASSNAME   "JSIID"
     258                 : #define XPC_MAP_FLAGS               nsIXPCScriptable::DONT_ENUM_STATIC_PROPS |\
     259                 :                                     nsIXPCScriptable::ALLOW_PROP_MODS_DURING_RESOLVE
     260                 : #include "xpc_map_end.h" /* This will #undef the above */
     261                 : 
     262                 : static nsIXPCScriptable* gSharedScriptableHelperForJSIID;
     263                 : static bool gClassObjectsWereInited = false;
     264                 : 
     265           91338 : static void EnsureClassObjectsInitialized()
     266                 : {
     267           91338 :     if (!gClassObjectsWereInited) {
     268            1391 :         gSharedScriptableHelperForJSIID = new SharedScriptableHelperForJSIID();
     269            1391 :         NS_ADDREF(gSharedScriptableHelperForJSIID);
     270                 : 
     271            1391 :         gClassObjectsWereInited = true;
     272                 :     }
     273           91338 : }
     274                 : 
     275           91338 : NS_METHOD GetSharedScriptableHelperForJSIID(PRUint32 language,
     276                 :                                             nsISupports **helper)
     277                 : {
     278           91338 :     EnsureClassObjectsInitialized();
     279           91338 :     if (language == nsIProgrammingLanguage::JAVASCRIPT) {
     280           91338 :         NS_IF_ADDREF(gSharedScriptableHelperForJSIID);
     281           91338 :         *helper = gSharedScriptableHelperForJSIID;
     282                 :     } else
     283               0 :         *helper = nsnull;
     284           91338 :     return NS_OK;
     285                 : }
     286                 : 
     287                 : /******************************************************/
     288                 : 
     289                 : #define NULL_CID                                                              \
     290                 : { 0x00000000, 0x0000, 0x0000,                                                 \
     291                 :   { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
     292                 : 
     293                 : NS_DECL_CI_INTERFACE_GETTER(nsJSIID)
     294                 : NS_IMPL_CLASSINFO(nsJSIID, GetSharedScriptableHelperForJSIID,
     295                 :                   nsIClassInfo::THREADSAFE, NULL_CID)
     296                 : 
     297                 : NS_DECL_CI_INTERFACE_GETTER(nsJSCID)
     298                 : NS_IMPL_CLASSINFO(nsJSCID, NULL, nsIClassInfo::THREADSAFE, NULL_CID)
     299                 : 
     300            1404 : void xpc_DestroyJSxIDClassObjects()
     301                 : {
     302            1404 :     if (gClassObjectsWereInited) {
     303            1391 :         NS_IF_RELEASE(NS_CLASSINFO_NAME(nsJSIID));
     304            1391 :         NS_IF_RELEASE(NS_CLASSINFO_NAME(nsJSCID));
     305            1391 :         NS_IF_RELEASE(gSharedScriptableHelperForJSIID);
     306                 : 
     307            1391 :         gClassObjectsWereInited = false;
     308                 :     }
     309            1404 : }
     310                 : 
     311                 : /***************************************************************************/
     312                 : 
     313         1571608 : NS_INTERFACE_MAP_BEGIN(nsJSIID)
     314         1571608 :   NS_INTERFACE_MAP_ENTRY(nsIJSID)
     315         1189316 :   NS_INTERFACE_MAP_ENTRY(nsIJSIID)
     316          993109 :   NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
     317          719095 :   NS_INTERFACE_MAP_ENTRY(nsISecurityCheckedComponent)
     318          699203 :   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIJSID)
     319          560713 :   NS_IMPL_QUERY_CLASSINFO(nsJSIID)
     320          469375 : NS_INTERFACE_MAP_END_THREADSAFE
     321                 : 
     322         1198125 : NS_IMPL_THREADSAFE_ADDREF(nsJSIID)
     323         1197656 : NS_IMPL_THREADSAFE_RELEASE(nsJSIID)
     324            1695 : NS_IMPL_CI_INTERFACE_GETTER2(nsJSIID, nsIJSID, nsIJSIID)
     325                 : 
     326                 : // The nsIXPCScriptable map declaration that will generate stubs for us...
     327                 : #define XPC_MAP_CLASSNAME           nsJSIID
     328                 : #define XPC_MAP_QUOTED_CLASSNAME   "nsJSIID"
     329                 : #define                             XPC_MAP_WANT_NEWRESOLVE
     330                 : #define                             XPC_MAP_WANT_ENUMERATE
     331                 : #define                             XPC_MAP_WANT_HASINSTANCE
     332                 : #define XPC_MAP_FLAGS               nsIXPCScriptable::DONT_ENUM_STATIC_PROPS |\
     333                 :                                     nsIXPCScriptable::ALLOW_PROP_MODS_DURING_RESOLVE
     334                 : #include "xpc_map_end.h" /* This will #undef the above */
     335                 : 
     336                 : 
     337           91336 : nsJSIID::nsJSIID(nsIInterfaceInfo* aInfo)
     338           91336 :     : mInfo(aInfo)
     339                 : {
     340           91336 : }
     341                 : 
     342          363512 : nsJSIID::~nsJSIID() {}
     343                 : 
     344                 : // If mInfo is present we use it and ignore mDetails, else we use mDetails.
     345                 : 
     346           12819 : NS_IMETHODIMP nsJSIID::GetName(char * *aName)
     347                 : {
     348           12819 :     return mInfo->GetName(aName);
     349                 : }
     350                 : 
     351               1 : NS_IMETHODIMP nsJSIID::GetNumber(char * *aNumber)
     352                 : {
     353                 :     char str[NSID_LENGTH];
     354                 :     const nsIID* id;
     355               1 :     mInfo->GetIIDShared(&id);
     356               1 :     id->ToProvidedString(str);
     357               1 :     *aNumber = (char*) nsMemory::Clone(str, NSID_LENGTH);
     358               1 :     return *aNumber ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
     359                 : }
     360                 : 
     361          635170 : NS_IMETHODIMP_(const nsID*) nsJSIID::GetID()
     362                 : {
     363                 :     const nsIID* id;
     364          635170 :     mInfo->GetIIDShared(&id);
     365          635170 :     return id;
     366                 : }
     367                 : 
     368               0 : NS_IMETHODIMP nsJSIID::GetValid(bool *aValid)
     369                 : {
     370               0 :     *aValid = true;
     371               0 :     return NS_OK;
     372                 : }
     373                 : 
     374          109454 : NS_IMETHODIMP nsJSIID::Equals(nsIJSID *other, bool *_retval)
     375                 : {
     376          109454 :     if (!_retval)
     377               0 :         return NS_ERROR_NULL_POINTER;
     378                 : 
     379          109454 :     if (!other) {
     380               0 :         *_retval = false;
     381               0 :         return NS_OK;
     382                 :     }
     383                 : 
     384          109454 :     mInfo->IsIID(other->GetID(), _retval);
     385          109454 :     return NS_OK;
     386                 : }
     387                 : 
     388               0 : NS_IMETHODIMP nsJSIID::Initialize(const char *idString)
     389                 : {
     390               0 :     return NS_ERROR_FAILURE;
     391                 : }
     392                 : 
     393           26400 : NS_IMETHODIMP nsJSIID::ToString(char **_retval)
     394                 : {
     395           26400 :     return mInfo->GetName(_retval);
     396                 : }
     397                 : 
     398                 : // static
     399                 : nsJSIID*
     400           91336 : nsJSIID::NewID(nsIInterfaceInfo* aInfo)
     401                 : {
     402           91336 :     if (!aInfo) {
     403               0 :         NS_ERROR("no info");
     404               0 :         return nsnull;
     405                 :     }
     406                 : 
     407                 :     bool canScript;
     408           91336 :     if (NS_FAILED(aInfo->IsScriptable(&canScript)) || !canScript)
     409               0 :         return nsnull;
     410                 : 
     411           91336 :     nsJSIID* idObj = new nsJSIID(aInfo);
     412           91336 :     NS_IF_ADDREF(idObj);
     413           91336 :     return idObj;
     414                 : }
     415                 : 
     416                 : 
     417                 : /* bool resolve (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval id); */
     418                 : NS_IMETHODIMP
     419           20658 : nsJSIID::NewResolve(nsIXPConnectWrappedNative *wrapper,
     420                 :                     JSContext * cx, JSObject * obj,
     421                 :                     jsid id, PRUint32 flags,
     422                 :                     JSObject * *objp, bool *_retval)
     423                 : {
     424           41316 :     XPCCallContext ccx(JS_CALLER, cx);
     425                 : 
     426           41316 :     AutoMarkingNativeInterfacePtr iface(ccx);
     427                 : 
     428                 :     const nsIID* iid;
     429           20658 :     mInfo->GetIIDShared(&iid);
     430                 : 
     431           20658 :     iface = XPCNativeInterface::GetNewOrUsed(ccx, iid);
     432                 : 
     433           20658 :     if (!iface)
     434               0 :         return NS_OK;
     435                 : 
     436           20658 :     XPCNativeMember* member = iface->FindMember(id);
     437           20658 :     if (member && member->IsConstant()) {
     438                 :         jsval val;
     439           13719 :         if (!member->GetConstantValue(ccx, iface, &val))
     440               0 :             return NS_ERROR_OUT_OF_MEMORY;
     441                 : 
     442           13719 :         *objp = obj;
     443                 :         *_retval = JS_DefinePropertyById(cx, obj, id, val, nsnull, nsnull,
     444                 :                                          JSPROP_ENUMERATE | JSPROP_READONLY |
     445           13719 :                                          JSPROP_PERMANENT);
     446                 :     }
     447                 : 
     448           20658 :     return NS_OK;
     449                 : }
     450                 : 
     451                 : /* bool enumerate (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj); */
     452                 : NS_IMETHODIMP
     453               0 : nsJSIID::Enumerate(nsIXPConnectWrappedNative *wrapper,
     454                 :                    JSContext * cx, JSObject * obj, bool *_retval)
     455                 : {
     456                 :     // In this case, let's just eagerly resolve...
     457                 : 
     458               0 :     XPCCallContext ccx(JS_CALLER, cx);
     459                 : 
     460               0 :     AutoMarkingNativeInterfacePtr iface(ccx);
     461                 : 
     462                 :     const nsIID* iid;
     463               0 :     mInfo->GetIIDShared(&iid);
     464                 : 
     465               0 :     iface = XPCNativeInterface::GetNewOrUsed(ccx, iid);
     466                 : 
     467               0 :     if (!iface)
     468               0 :         return NS_OK;
     469                 : 
     470               0 :     PRUint16 count = iface->GetMemberCount();
     471               0 :     for (PRUint16 i = 0; i < count; i++) {
     472               0 :         XPCNativeMember* member = iface->GetMemberAt(i);
     473               0 :         if (member && member->IsConstant() &&
     474               0 :             !xpc_ForcePropertyResolve(cx, obj, member->GetName())) {
     475               0 :             return NS_ERROR_UNEXPECTED;
     476                 :         }
     477                 :     }
     478               0 :     return NS_OK;
     479                 : }
     480                 : 
     481                 : /* bool hasInstance (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval val, out bool bp); */
     482                 : NS_IMETHODIMP
     483          165302 : nsJSIID::HasInstance(nsIXPConnectWrappedNative *wrapper,
     484                 :                      JSContext * cx, JSObject * obj,
     485                 :                      const jsval &val, bool *bp, bool *_retval)
     486                 : {
     487          165302 :     *bp = false;
     488          165302 :     nsresult rv = NS_OK;
     489                 : 
     490          165302 :     if (!JSVAL_IS_PRIMITIVE(val)) {
     491                 :         // we have a JSObject
     492           62400 :         JSObject* obj = JSVAL_TO_OBJECT(val);
     493                 : 
     494           62400 :         NS_ASSERTION(obj, "when is an object not an object?");
     495                 : 
     496                 :         // is this really a native xpcom object with a wrapper?
     497                 :         const nsIID* iid;
     498           62400 :         mInfo->GetIIDShared(&iid);
     499                 : 
     500           62400 :         if (IS_SLIM_WRAPPER(obj)) {
     501            8764 :             XPCWrappedNativeProto* proto = GetSlimWrapperProto(obj);
     502            8764 :             if (proto->GetSet()->HasInterfaceWithAncestor(iid)) {
     503            3763 :                 *bp = true;
     504            3763 :                 return NS_OK;
     505                 :             }
     506                 : 
     507                 : #ifdef DEBUG_slimwrappers
     508                 :             char foo[NSID_LENGTH];
     509                 :             iid->ToProvidedString(foo);
     510                 :             SLIM_LOG_WILL_MORPH_FOR_PROP(cx, obj, foo);
     511                 : #endif
     512            5001 :             if (!MorphSlimWrapper(cx, obj))
     513               0 :                 return NS_ERROR_FAILURE;
     514                 :         }
     515                 : 
     516           58637 :         if (mozilla::dom::binding::instanceIsProxy(obj)) {
     517                 :             nsISupports *identity =
     518              12 :                 static_cast<nsISupports*>(js::GetProxyPrivate(obj).toPrivate());
     519              24 :             nsCOMPtr<nsIClassInfo> ci = do_QueryInterface(identity);
     520                 : 
     521              24 :             XPCCallContext ccx(JS_CALLER, cx);
     522                 : 
     523              24 :             AutoMarkingNativeSetPtr set(ccx);
     524              12 :             set = XPCNativeSet::GetNewOrUsed(ccx, ci);
     525              12 :             if (!set)
     526               0 :                 return NS_ERROR_FAILURE;
     527              12 :             *bp = set->HasInterfaceWithAncestor(iid);
     528              12 :             return NS_OK;
     529                 :      }
     530                 : 
     531                 :         XPCWrappedNative* other_wrapper =
     532           58625 :            XPCWrappedNative::GetWrappedNativeOfJSObject(cx, obj);
     533                 : 
     534           58625 :         if (!other_wrapper)
     535              69 :             return NS_OK;
     536                 : 
     537                 :         // We'll trust the interface set of the wrapper if this is known
     538                 :         // to be an interface that the objects *expects* to be able to
     539                 :         // handle.
     540           58556 :         if (other_wrapper->HasInterfaceNoQI(*iid)) {
     541           37294 :             *bp = true;
     542           37294 :             return NS_OK;
     543                 :         }
     544                 : 
     545                 :         // Otherwise, we'll end up Querying the native object to be sure.
     546           42524 :         XPCCallContext ccx(JS_CALLER, cx);
     547                 : 
     548           42524 :         AutoMarkingNativeInterfacePtr iface(ccx);
     549           21262 :         iface = XPCNativeInterface::GetNewOrUsed(ccx, iid);
     550                 : 
     551           21262 :         nsresult findResult = NS_OK;
     552           21262 :         if (iface && other_wrapper->FindTearOff(ccx, iface, false, &findResult))
     553           15102 :             *bp = true;
     554           21262 :         if (NS_FAILED(findResult) && findResult != NS_ERROR_NO_INTERFACE)
     555               0 :             rv = findResult;
     556                 :     }
     557          124164 :     return rv;
     558                 : }
     559                 : 
     560                 : /* string canCreateWrapper (in nsIIDPtr iid); */
     561                 : NS_IMETHODIMP
     562           19892 : nsJSIID::CanCreateWrapper(const nsIID * iid, char **_retval)
     563                 : {
     564                 :     // We let anyone do this...
     565           19892 :     *_retval = xpc_CloneAllAccess();
     566           19892 :     return NS_OK;
     567                 : }
     568                 : 
     569                 : /* string canCallMethod (in nsIIDPtr iid, in wstring methodName); */
     570                 : NS_IMETHODIMP
     571               0 : nsJSIID::CanCallMethod(const nsIID * iid, const PRUnichar *methodName, char **_retval)
     572                 : {
     573                 :     static const char* allowed[] = {"equals", "toString", nsnull};
     574                 : 
     575               0 :     *_retval = xpc_CheckAccessList(methodName, allowed);
     576               0 :     return NS_OK;
     577                 : }
     578                 : 
     579                 : /* string canGetProperty (in nsIIDPtr iid, in wstring propertyName); */
     580                 : NS_IMETHODIMP
     581               0 : nsJSIID::CanGetProperty(const nsIID * iid, const PRUnichar *propertyName, char **_retval)
     582                 : {
     583                 :     static const char* allowed[] = {"name", "number", "valid", nsnull};
     584               0 :     *_retval = xpc_CheckAccessList(propertyName, allowed);
     585               0 :     return NS_OK;
     586                 : }
     587                 : 
     588                 : /* string canSetProperty (in nsIIDPtr iid, in wstring propertyName); */
     589                 : NS_IMETHODIMP
     590               0 : nsJSIID::CanSetProperty(const nsIID * iid, const PRUnichar *propertyName, char **_retval)
     591                 : {
     592                 :     // If you have to ask, then the answer is NO
     593               0 :     *_retval = nsnull;
     594               0 :     return NS_OK;
     595                 : }
     596                 : 
     597                 : /***************************************************************************/
     598                 : 
     599          631579 : NS_INTERFACE_MAP_BEGIN(nsJSCID)
     600          631579 :   NS_INTERFACE_MAP_ENTRY(nsIJSID)
     601          631577 :   NS_INTERFACE_MAP_ENTRY(nsIJSCID)
     602          519167 :   NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
     603          391487 :   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIJSID)
     604          301777 :   NS_IMPL_QUERY_CLASSINFO(nsJSCID)
     605          259217 : NS_INTERFACE_MAP_END_THREADSAFE
     606                 : 
     607          421062 : NS_IMPL_THREADSAFE_ADDREF(nsJSCID)
     608          420863 : NS_IMPL_THREADSAFE_RELEASE(nsJSCID)
     609            1768 : NS_IMPL_CI_INTERFACE_GETTER2(nsJSCID, nsIJSID, nsIJSCID)
     610                 : 
     611                 : // The nsIXPCScriptable map declaration that will generate stubs for us...
     612                 : #define XPC_MAP_CLASSNAME           nsJSCID
     613                 : #define XPC_MAP_QUOTED_CLASSNAME   "nsJSCID"
     614                 : #define                             XPC_MAP_WANT_CONSTRUCT
     615                 : #define                             XPC_MAP_WANT_HASINSTANCE
     616                 : #define XPC_MAP_FLAGS               0
     617                 : #include "xpc_map_end.h" /* This will #undef the above */
     618                 : 
     619           44144 : nsJSCID::nsJSCID()  {}
     620          175780 : nsJSCID::~nsJSCID() {}
     621                 : 
     622               0 : NS_IMETHODIMP nsJSCID::GetName(char * *aName)
     623               0 :     {ResolveName(); return mDetails.GetName(aName);}
     624                 : 
     625               0 : NS_IMETHODIMP nsJSCID::GetNumber(char * *aNumber)
     626               0 :     {return mDetails.GetNumber(aNumber);}
     627                 : 
     628            1390 : NS_IMETHODIMP_(const nsID*) nsJSCID::GetID()
     629            1390 :     {return &mDetails.ID();}
     630                 : 
     631               0 : NS_IMETHODIMP nsJSCID::GetValid(bool *aValid)
     632               0 :     {return mDetails.GetValid(aValid);}
     633                 : 
     634               1 : NS_IMETHODIMP nsJSCID::Equals(nsIJSID *other, bool *_retval)
     635               1 :     {return mDetails.Equals(other, _retval);}
     636                 : 
     637               2 : NS_IMETHODIMP nsJSCID::Initialize(const char *idString)
     638               2 :     {return mDetails.Initialize(idString);}
     639                 : 
     640             182 : NS_IMETHODIMP nsJSCID::ToString(char **_retval)
     641             182 :     {ResolveName(); return mDetails.ToString(_retval);}
     642                 : 
     643                 : void
     644             182 : nsJSCID::ResolveName()
     645                 : {
     646             182 :     if (!mDetails.NameIsSet())
     647               0 :         mDetails.SetNameToNoString();
     648             182 : }
     649                 : 
     650                 : //static
     651                 : nsJSCID*
     652           44144 : nsJSCID::NewID(const char* str)
     653                 : {
     654           44144 :     if (!str) {
     655               0 :         NS_ERROR("no string");
     656               0 :         return nsnull;
     657                 :     }
     658                 : 
     659           44144 :     nsJSCID* idObj = new nsJSCID();
     660           44144 :     if (idObj) {
     661           44144 :         bool success = false;
     662           44144 :         NS_ADDREF(idObj);
     663                 : 
     664           44144 :         if (str[0] == '{') {
     665               2 :             if (NS_SUCCEEDED(idObj->Initialize(str)))
     666               2 :                 success = true;
     667                 :         } else {
     668           88284 :             nsCOMPtr<nsIComponentRegistrar> registrar;
     669           44142 :             NS_GetComponentRegistrar(getter_AddRefs(registrar));
     670           44142 :             if (registrar) {
     671                 :                 nsCID *cid;
     672           44142 :                 if (NS_SUCCEEDED(registrar->ContractIDToCID(str, &cid))) {
     673           42558 :                     success = idObj->mDetails.InitWithName(*cid, str);
     674           42558 :                     nsMemory::Free(cid);
     675                 :                 }
     676                 :             }
     677                 :         }
     678           44144 :         if (!success)
     679            1584 :             NS_RELEASE(idObj);
     680                 :     }
     681           44144 :     return idObj;
     682                 : }
     683                 : 
     684                 : static const nsID*
     685          169176 : GetIIDArg(PRUint32 argc, const JS::Value& val, JSContext* cx)
     686                 : {
     687                 :     const nsID* iid;
     688                 : 
     689                 :     // If an IID was passed in then use it
     690          169176 :     if (argc) {
     691                 :         JSObject* iidobj;
     692          161981 :         if (JSVAL_IS_PRIMITIVE(val) ||
     693                 :             !(iidobj = JSVAL_TO_OBJECT(val)) ||
     694                 :             !(iid = xpc_JSObjectToID(cx, iidobj))) {
     695               0 :             return nsnull;
     696                 :         }
     697                 :     } else
     698            7195 :         iid = &NS_GET_IID(nsISupports);
     699                 : 
     700          169176 :     return iid;
     701                 : }
     702                 : 
     703                 : static JSObject*
     704          169176 : GetWrapperObject()
     705                 : {
     706          169176 :     nsXPConnect* xpc = nsXPConnect::GetXPConnect();
     707          169176 :     if (!xpc)
     708               0 :         return NULL;
     709                 : 
     710          169176 :     nsAXPCNativeCallContext *ccxp = NULL;
     711          169176 :     xpc->GetCurrentNativeCallContext(&ccxp);
     712          169176 :     if (!ccxp)
     713               0 :         return NULL;
     714                 : 
     715          338352 :     nsCOMPtr<nsIXPConnectWrappedNative> wrapper;
     716          169176 :     ccxp->GetCalleeWrapper(getter_AddRefs(wrapper));
     717                 :     JSObject* obj;
     718          169176 :     wrapper->GetJSObject(&obj);
     719          169176 :     return obj;
     720                 : }
     721                 : 
     722                 : /* nsISupports createInstance (); */
     723                 : NS_IMETHODIMP
     724          100743 : nsJSCID::CreateInstance(const JS::Value& iidval, JSContext* cx,
     725                 :                         PRUint8 optionalArgc, JS::Value* retval)
     726                 : {
     727          100743 :     if (!mDetails.IsValid())
     728               0 :         return NS_ERROR_XPC_BAD_CID;
     729                 : 
     730          100743 :     JSObject* obj = GetWrapperObject();
     731          100743 :     if (!obj) {
     732               0 :         return NS_ERROR_UNEXPECTED;
     733                 :     }
     734                 : 
     735                 :     // Do the security check if necessary
     736          100743 :     XPCContext* xpcc = XPCContext::GetXPCContext(cx);
     737                 : 
     738                 :     nsIXPCSecurityManager* sm;
     739          100743 :     sm = xpcc->GetAppropriateSecurityManager(nsIXPCSecurityManager::HOOK_CREATE_INSTANCE);
     740          100743 :     if (sm && NS_FAILED(sm->CanCreateInstance(cx, mDetails.ID()))) {
     741               0 :         NS_ERROR("how are we not being called from chrome here?");
     742               0 :         return NS_OK;
     743                 :     }
     744                 : 
     745                 :     // If an IID was passed in then use it
     746          100743 :     const nsID* iid = GetIIDArg(optionalArgc, iidval, cx);
     747          100743 :     if (!iid)
     748               0 :         return NS_ERROR_XPC_BAD_IID;
     749                 : 
     750          201486 :     nsCOMPtr<nsIComponentManager> compMgr;
     751          100743 :     nsresult rv = NS_GetComponentManager(getter_AddRefs(compMgr));
     752          100743 :     if (NS_FAILED(rv))
     753               0 :         return NS_ERROR_UNEXPECTED;
     754                 : 
     755          201486 :     nsCOMPtr<nsISupports> inst;
     756          100743 :     rv = compMgr->CreateInstance(mDetails.ID(), nsnull, *iid, getter_AddRefs(inst));
     757          100743 :     NS_ASSERTION(NS_FAILED(rv) || inst, "component manager returned success, but instance is null!");
     758                 : 
     759          100743 :     if (NS_FAILED(rv) || !inst)
     760               1 :         return NS_ERROR_XPC_CI_RETURNED_FAILURE;
     761                 : 
     762          100742 :     rv = nsXPConnect::GetXPConnect()->WrapNativeToJSVal(cx, obj, inst, nsnull, iid, true, retval, nsnull);
     763          100742 :     if (NS_FAILED(rv) || JSVAL_IS_PRIMITIVE(*retval))
     764               0 :         return NS_ERROR_XPC_CANT_CREATE_WN;
     765          100742 :     return NS_OK;
     766                 : }
     767                 : 
     768                 : /* nsISupports getService (); */
     769                 : NS_IMETHODIMP
     770           68433 : nsJSCID::GetService(const JS::Value& iidval, JSContext* cx,
     771                 :                     PRUint8 optionalArgc, JS::Value* retval)
     772                 : {
     773           68433 :     if (!mDetails.IsValid())
     774               0 :         return NS_ERROR_XPC_BAD_CID;
     775                 : 
     776           68433 :     JSObject* obj = GetWrapperObject();
     777           68433 :     if (!obj) {
     778               0 :         return NS_ERROR_UNEXPECTED;
     779                 :     }
     780                 : 
     781                 :     // Do the security check if necessary
     782           68433 :     XPCContext* xpcc = XPCContext::GetXPCContext(cx);
     783                 : 
     784                 :     nsIXPCSecurityManager* sm;
     785           68433 :     sm = xpcc->GetAppropriateSecurityManager(nsIXPCSecurityManager::HOOK_GET_SERVICE);
     786           68433 :     if (sm && NS_FAILED(sm->CanCreateInstance(cx, mDetails.ID()))) {
     787               0 :         NS_ASSERTION(JS_IsExceptionPending(cx),
     788                 :                      "security manager vetoed GetService without setting exception");
     789               0 :         return NS_OK;
     790                 :     }
     791                 : 
     792                 :     // If an IID was passed in then use it
     793           68433 :     const nsID* iid = GetIIDArg(optionalArgc, iidval, cx);
     794           68433 :     if (!iid)
     795               0 :         return NS_ERROR_XPC_BAD_IID;
     796                 : 
     797          136866 :     nsCOMPtr<nsIServiceManager> svcMgr;
     798           68433 :     nsresult rv = NS_GetServiceManager(getter_AddRefs(svcMgr));
     799           68433 :     if (NS_FAILED(rv))
     800               0 :         return rv;
     801                 : 
     802          136866 :     nsCOMPtr<nsISupports> srvc;
     803           68433 :     rv = svcMgr->GetService(mDetails.ID(), *iid, getter_AddRefs(srvc));
     804           68433 :     NS_ASSERTION(NS_FAILED(rv) || srvc, "service manager returned success, but service is null!");
     805           68433 :     if (NS_FAILED(rv) || !srvc)
     806              11 :         return NS_ERROR_XPC_GS_RETURNED_FAILURE;
     807                 : 
     808                 :     JSObject* instJSObj;
     809          136844 :     nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
     810           68422 :     rv = nsXPConnect::GetXPConnect()->WrapNative(cx, obj, srvc, *iid, getter_AddRefs(holder));
     811           68422 :     if (NS_FAILED(rv) || !holder || NS_FAILED(holder->GetJSObject(&instJSObj)))
     812               0 :         return NS_ERROR_XPC_CANT_CREATE_WN;
     813                 : 
     814           68422 :     *retval = OBJECT_TO_JSVAL(instJSObj);
     815           68422 :     return NS_OK;
     816                 : }
     817                 : 
     818                 : /* bool construct (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in PRUint32 argc, in JSValPtr argv, in JSValPtr vp); */
     819                 : NS_IMETHODIMP
     820               0 : nsJSCID::Construct(nsIXPConnectWrappedNative *wrapper,
     821                 :                    JSContext * cx, JSObject * obj,
     822                 :                    PRUint32 argc, jsval * argv, jsval * vp,
     823                 :                    bool *_retval)
     824                 : {
     825               0 :     XPCJSRuntime* rt = nsXPConnect::GetRuntimeInstance();
     826               0 :     if (!rt)
     827               0 :         return NS_ERROR_FAILURE;
     828                 : 
     829                 :     // 'push' a call context and call on it
     830                 :     XPCCallContext ccx(JS_CALLER, cx, obj, nsnull,
     831                 :                        rt->GetStringID(XPCJSRuntime::IDX_CREATE_INSTANCE),
     832               0 :                        argc, argv, vp);
     833                 : 
     834               0 :     *_retval = XPCWrappedNative::CallMethod(ccx);
     835               0 :     return NS_OK;
     836                 : }
     837                 : 
     838                 : /* bool hasInstance (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval val, out bool bp); */
     839                 : NS_IMETHODIMP
     840               0 : nsJSCID::HasInstance(nsIXPConnectWrappedNative *wrapper,
     841                 :                      JSContext * cx, JSObject * obj,
     842                 :                      const jsval &val, bool *bp, bool *_retval)
     843                 : {
     844               0 :     *bp = false;
     845               0 :     nsresult rv = NS_OK;
     846                 : 
     847               0 :     if (!JSVAL_IS_PRIMITIVE(val)) {
     848                 :         // we have a JSObject
     849               0 :         JSObject* obj = JSVAL_TO_OBJECT(val);
     850                 : 
     851               0 :         NS_ASSERTION(obj, "when is an object not an object?");
     852                 : 
     853                 :         // is this really a native xpcom object with a wrapper?
     854                 :         JSObject* obj2;
     855                 :         XPCWrappedNative* other_wrapper =
     856               0 :            XPCWrappedNative::GetWrappedNativeOfJSObject(cx, obj, nsnull, &obj2);
     857                 : 
     858               0 :         if (!other_wrapper && !obj2)
     859               0 :             return NS_OK;
     860                 : 
     861                 :         nsIClassInfo* ci = other_wrapper ?
     862                 :                            other_wrapper->GetClassInfo() :
     863               0 :                            GetSlimWrapperProto(obj2)->GetClassInfo();
     864                 : 
     865                 :         // We consider CID equality to be the thing that matters here.
     866                 :         // This is perhaps debatable.
     867               0 :         if (ci) {
     868                 :             nsID cid;
     869               0 :             if (NS_SUCCEEDED(ci->GetClassIDNoAlloc(&cid)))
     870               0 :                 *bp = cid.Equals(mDetails.ID());
     871                 :         }
     872                 :     }
     873               0 :     return rv;
     874                 : }
     875                 : 
     876                 : /***************************************************************************/
     877                 : // additional utilities...
     878                 : 
     879                 : JSObject *
     880          166223 : xpc_NewIDObject(JSContext *cx, JSObject* jsobj, const nsID& aID)
     881                 : {
     882          166223 :     JSObject *obj = nsnull;
     883                 : 
     884                 :     nsCOMPtr<nsIJSID> iid =
     885          332446 :             dont_AddRef(static_cast<nsIJSID*>(nsJSID::NewID(aID)));
     886          166223 :     if (iid) {
     887          166223 :         nsXPConnect* xpc = nsXPConnect::GetXPConnect();
     888          166223 :         if (xpc) {
     889          332446 :             nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
     890                 :             nsresult rv = xpc->WrapNative(cx, jsobj,
     891          166223 :                                           static_cast<nsISupports*>(iid),
     892                 :                                           NS_GET_IID(nsIJSID),
     893          332446 :                                           getter_AddRefs(holder));
     894          166223 :             if (NS_SUCCEEDED(rv) && holder) {
     895          166223 :                 holder->GetJSObject(&obj);
     896                 :             }
     897                 :         }
     898                 :     }
     899          166223 :     return obj;
     900                 : }
     901                 : 
     902                 : // note: returned pointer is only valid while |obj| remains alive!
     903                 : const nsID*
     904          286304 : xpc_JSObjectToID(JSContext *cx, JSObject* obj)
     905                 : {
     906          286304 :     if (!cx || !obj)
     907               0 :         return nsnull;
     908                 : 
     909                 :     // NOTE: this call does NOT addref
     910                 :     XPCWrappedNative* wrapper =
     911          286304 :         XPCWrappedNative::GetWrappedNativeOfJSObject(cx, obj);
     912          572480 :     if (wrapper &&
     913          285670 :         (wrapper->HasInterfaceNoQI(NS_GET_IID(nsIJSID))  ||
     914             253 :          wrapper->HasInterfaceNoQI(NS_GET_IID(nsIJSIID)) ||
     915             253 :          wrapper->HasInterfaceNoQI(NS_GET_IID(nsIJSCID)))) {
     916          285417 :         return ((nsIJSID*)wrapper->GetIdentityObject())->GetID();
     917                 :     }
     918             887 :     return nsnull;
     919                 : }
     920                 : 
     921                 : JSBool
     922              99 : xpc_JSObjectIsID(JSContext *cx, JSObject* obj)
     923                 : {
     924              99 :     NS_ASSERTION(cx && obj, "bad param");
     925                 :     // NOTE: this call does NOT addref
     926                 :     XPCWrappedNative* wrapper =
     927              99 :         XPCWrappedNative::GetWrappedNativeOfJSObject(cx, obj);
     928                 :     return wrapper &&
     929               3 :            (wrapper->HasInterfaceNoQI(NS_GET_IID(nsIJSID))  ||
     930               3 :             wrapper->HasInterfaceNoQI(NS_GET_IID(nsIJSIID)) ||
     931             105 :             wrapper->HasInterfaceNoQI(NS_GET_IID(nsIJSCID)));
     932                 : }
     933                 : 
     934                 : 

Generated by: LCOV version 1.7