LCOV - code coverage report
Current view: directory - js/xpconnect/src - XPCComponents.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 1733 954 55.0 %
Date: 2012-06-02 Functions: 289 182 63.0 %

       1                 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
       2                 :  * vim: set ts=8 sw=4 et tw=78:
       3                 :  *
       4                 :  * ***** BEGIN LICENSE BLOCK *****
       5                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       6                 :  *
       7                 :  * The contents of this file are subject to the Mozilla Public License Version
       8                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       9                 :  * the License. You may obtain a copy of the License at
      10                 :  * http://www.mozilla.org/MPL/
      11                 :  *
      12                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      13                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      14                 :  * for the specific language governing rights and limitations under the
      15                 :  * License.
      16                 :  *
      17                 :  * The Original Code is Mozilla Communicator client code, released
      18                 :  * March 31, 1998.
      19                 :  *
      20                 :  * The Initial Developer of the Original Code is
      21                 :  * Netscape Communications Corporation.
      22                 :  * Portions created by the Initial Developer are Copyright (C) 1998
      23                 :  * the Initial Developer. All Rights Reserved.
      24                 :  *
      25                 :  * Contributor(s):
      26                 :  *   John Bandhauer <jband@netscape.com> (original author)
      27                 :  *   Pierre Phaneuf <pp@ludusdesign.com>
      28                 :  *
      29                 :  * Alternatively, the contents of this file may be used under the terms of
      30                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      31                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      32                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      33                 :  * of those above. If you wish to allow use of your version of this file only
      34                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      35                 :  * use your version of this file under the terms of the MPL, indicate your
      36                 :  * decision by deleting the provisions above and replace them with the notice
      37                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      38                 :  * the provisions above, a recipient may use your version of this file under
      39                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      40                 :  *
      41                 :  * ***** END LICENSE BLOCK ***** */
      42                 : 
      43                 : /* The "Components" xpcom objects for JavaScript. */
      44                 : 
      45                 : #include "mozilla/unused.h"
      46                 : 
      47                 : #include "xpcprivate.h"
      48                 : #include "nsReadableUtils.h"
      49                 : #include "xpcIJSModuleLoader.h"
      50                 : #include "nsIScriptObjectPrincipal.h"
      51                 : #include "nsIDOMWindow.h"
      52                 : #include "XPCJSWeakReference.h"
      53                 : #include "XPCWrapper.h"
      54                 : #include "jsproxy.h"
      55                 : #include "WrapperFactory.h"
      56                 : #include "XrayWrapper.h"
      57                 : #include "nsNullPrincipal.h"
      58                 : #include "nsJSUtils.h"
      59                 : #include "mozJSComponentLoader.h"
      60                 : #include "nsContentUtils.h"
      61                 : #include "jsgc.h"
      62                 : #include "jsfriendapi.h"
      63                 : 
      64                 : using namespace mozilla;
      65                 : using namespace js;
      66                 : /***************************************************************************/
      67                 : // stuff used by all
      68                 : 
      69               0 : static nsresult ThrowAndFail(unsigned errNum, JSContext* cx, bool* retval)
      70                 : {
      71               0 :     XPCThrower::Throw(errNum, cx);
      72               0 :     *retval = false;
      73               0 :     return NS_OK;
      74                 : }
      75                 : 
      76                 : static JSBool
      77            2628 : JSValIsInterfaceOfType(JSContext *cx, jsval v, REFNSIID iid)
      78                 : {
      79            5256 :     nsCOMPtr<nsIXPConnect> xpc;
      80            5256 :     nsCOMPtr<nsIXPConnectWrappedNative> wn;
      81            5256 :     nsCOMPtr<nsISupports> sup;
      82                 :     nsISupports* iface;
      83           18396 :     if (!JSVAL_IS_PRIMITIVE(v) &&
      84            2628 :         nsnull != (xpc = nsXPConnect::GetXPConnect()) &&
      85            7884 :         NS_SUCCEEDED(xpc->GetWrappedNativeOfJSObject(cx, JSVAL_TO_OBJECT(v),
      86            2628 :                                                      getter_AddRefs(wn))) && wn &&
      87            2628 :         NS_SUCCEEDED(wn->Native()->QueryInterface(iid, (void**)&iface)) && iface) {
      88            2628 :         NS_RELEASE(iface);
      89            2628 :         return true;
      90                 :     }
      91               0 :     return false;
      92                 : }
      93                 : 
      94           46803 : char* xpc_CloneAllAccess()
      95                 : {
      96                 :     static const char allAccess[] = "AllAccess";
      97           46803 :     return (char*)nsMemory::Clone(allAccess, sizeof(allAccess));
      98                 : }
      99                 : 
     100               0 : char * xpc_CheckAccessList(const PRUnichar* wideName, const char* list[])
     101                 : {
     102               0 :     nsCAutoString asciiName;
     103               0 :     CopyUTF16toUTF8(nsDependentString(wideName), asciiName);
     104                 : 
     105               0 :     for (const char** p = list; *p; p++)
     106               0 :         if (!strcmp(*p, asciiName.get()))
     107               0 :             return xpc_CloneAllAccess();
     108                 : 
     109               0 :     return nsnull;
     110                 : }
     111                 : 
     112                 : /***************************************************************************/
     113                 : /***************************************************************************/
     114                 : /***************************************************************************/
     115                 : 
     116                 : 
     117                 : 
     118                 : class nsXPCComponents_Interfaces :
     119                 :             public nsIXPCComponents_Interfaces,
     120                 :             public nsIXPCScriptable,
     121                 :             public nsIClassInfo,
     122                 :             public nsISecurityCheckedComponent
     123                 : {
     124                 : public:
     125                 :     // all the interface method declarations...
     126                 :     NS_DECL_ISUPPORTS
     127                 :     NS_DECL_NSIXPCCOMPONENTS_INTERFACES
     128                 :     NS_DECL_NSIXPCSCRIPTABLE
     129                 :     NS_DECL_NSICLASSINFO
     130                 :     NS_DECL_NSISECURITYCHECKEDCOMPONENT
     131                 : 
     132                 : public:
     133                 :     nsXPCComponents_Interfaces();
     134                 :     virtual ~nsXPCComponents_Interfaces();
     135                 : 
     136                 : private:
     137                 :     nsCOMPtr<nsIInterfaceInfoManager> mManager;
     138                 : };
     139                 : 
     140                 : /* void getInterfaces (out PRUint32 count, [array, size_is (count), retval]
     141                 :                        out nsIIDPtr array); */
     142                 : NS_IMETHODIMP
     143           12967 : nsXPCComponents_Interfaces::GetInterfaces(PRUint32 *aCount, nsIID * **aArray)
     144                 : {
     145           12967 :     const PRUint32 count = 3;
     146           12967 :     *aCount = count;
     147                 :     nsIID **array;
     148           12967 :     *aArray = array = static_cast<nsIID**>(nsMemory::Alloc(count * sizeof(nsIID*)));
     149           12967 :     if (!array)
     150               0 :         return NS_ERROR_OUT_OF_MEMORY;
     151                 : 
     152           12967 :     PRUint32 index = 0;
     153                 :     nsIID* clone;
     154                 : #define PUSH_IID(id)                                                          \
     155                 :     clone = static_cast<nsIID *>(nsMemory::Clone(&NS_GET_IID( id ),           \
     156                 :                                                  sizeof(nsIID)));             \
     157                 :     if (!clone)                                                               \
     158                 :         goto oom;                                                             \
     159                 :     array[index++] = clone;
     160                 : 
     161           12967 :     PUSH_IID(nsIXPCComponents_Interfaces)
     162           12967 :     PUSH_IID(nsIXPCScriptable)
     163           12967 :     PUSH_IID(nsISecurityCheckedComponent)
     164                 : #undef PUSH_IID
     165                 : 
     166           12967 :     return NS_OK;
     167                 : oom:
     168               0 :     while (index)
     169               0 :         nsMemory::Free(array[--index]);
     170               0 :     nsMemory::Free(array);
     171               0 :     *aArray = nsnull;
     172               0 :     return NS_ERROR_OUT_OF_MEMORY;
     173                 : }
     174                 : 
     175                 : /* nsISupports getHelperForLanguage (in PRUint32 language); */
     176                 : NS_IMETHODIMP
     177           12967 : nsXPCComponents_Interfaces::GetHelperForLanguage(PRUint32 language,
     178                 :                                                  nsISupports **retval)
     179                 : {
     180           12967 :     *retval = nsnull;
     181           12967 :     return NS_OK;
     182                 : }
     183                 : 
     184                 : /* readonly attribute string contractID; */
     185                 : NS_IMETHODIMP
     186               0 : nsXPCComponents_Interfaces::GetContractID(char * *aContractID)
     187                 : {
     188               0 :     *aContractID = nsnull;
     189               0 :     return NS_ERROR_NOT_AVAILABLE;
     190                 : }
     191                 : 
     192                 : /* readonly attribute string classDescription; */
     193                 : NS_IMETHODIMP
     194               1 : nsXPCComponents_Interfaces::GetClassDescription(char * *aClassDescription)
     195                 : {
     196                 :     static const char classDescription[] = "XPCComponents_Interfaces";
     197               1 :     *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription));
     198               1 :     return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
     199                 : }
     200                 : 
     201                 : /* readonly attribute nsCIDPtr classID; */
     202                 : NS_IMETHODIMP
     203               0 : nsXPCComponents_Interfaces::GetClassID(nsCID * *aClassID)
     204                 : {
     205               0 :     *aClassID = nsnull;
     206               0 :     return NS_OK;
     207                 : }
     208                 : 
     209                 : /* readonly attribute PRUint32 implementationLanguage; */
     210                 : NS_IMETHODIMP
     211               0 : nsXPCComponents_Interfaces::GetImplementationLanguage(PRUint32 *aImplementationLanguage)
     212                 : {
     213               0 :     *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS;
     214               0 :     return NS_OK;
     215                 : }
     216                 : 
     217                 : /* readonly attribute PRUint32 flags; */
     218                 : NS_IMETHODIMP
     219           25325 : nsXPCComponents_Interfaces::GetFlags(PRUint32 *aFlags)
     220                 : {
     221           25325 :     *aFlags = nsIClassInfo::THREADSAFE;
     222           25325 :     return NS_OK;
     223                 : }
     224                 : 
     225                 : /* [notxpcom] readonly attribute nsCID classIDNoAlloc; */
     226                 : NS_IMETHODIMP
     227               0 : nsXPCComponents_Interfaces::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
     228                 : {
     229               0 :     return NS_ERROR_NOT_AVAILABLE;
     230                 : }
     231                 : 
     232           12686 : nsXPCComponents_Interfaces::nsXPCComponents_Interfaces() :
     233           12686 :     mManager(do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID))
     234                 : {
     235           12686 : }
     236                 : 
     237           25336 : nsXPCComponents_Interfaces::~nsXPCComponents_Interfaces()
     238                 : {
     239                 :     // empty
     240           50672 : }
     241                 : 
     242                 : 
     243          295680 : NS_INTERFACE_MAP_BEGIN(nsXPCComponents_Interfaces)
     244          295680 :   NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_Interfaces)
     245          276206 :   NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
     246          237305 :   NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
     247          211369 :   NS_INTERFACE_MAP_ENTRY(nsISecurityCheckedComponent)
     248          199011 :   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_Interfaces)
     249          127080 : NS_INTERFACE_MAP_END_THREADSAFE
     250                 : 
     251          279148 : NS_IMPL_THREADSAFE_ADDREF(nsXPCComponents_Interfaces)
     252          279109 : NS_IMPL_THREADSAFE_RELEASE(nsXPCComponents_Interfaces)
     253                 : 
     254                 : // The nsIXPCScriptable map declaration that will generate stubs for us...
     255                 : #define XPC_MAP_CLASSNAME           nsXPCComponents_Interfaces
     256                 : #define XPC_MAP_QUOTED_CLASSNAME   "nsXPCComponents_Interfaces"
     257                 : #define                             XPC_MAP_WANT_NEWRESOLVE
     258                 : #define                             XPC_MAP_WANT_NEWENUMERATE
     259                 : #define XPC_MAP_FLAGS               nsIXPCScriptable::DONT_ENUM_STATIC_PROPS |\
     260                 :                                     nsIXPCScriptable::ALLOW_PROP_MODS_DURING_RESOLVE
     261                 : #include "xpc_map_end.h" /* This will #undef the above */
     262                 : 
     263                 : 
     264                 : /* bool newEnumerate (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in PRUint32 enum_op, in JSValPtr statep, out JSID idp); */
     265                 : NS_IMETHODIMP
     266               0 : nsXPCComponents_Interfaces::NewEnumerate(nsIXPConnectWrappedNative *wrapper,
     267                 :                                          JSContext * cx, JSObject * obj,
     268                 :                                          PRUint32 enum_op, jsval * statep,
     269                 :                                          jsid * idp, bool *_retval)
     270                 : {
     271                 :     nsIEnumerator* e;
     272                 : 
     273               0 :     switch (enum_op) {
     274                 :         case JSENUMERATE_INIT:
     275                 :         case JSENUMERATE_INIT_ALL:
     276                 :         {
     277               0 :             if (!mManager ||
     278               0 :                 NS_FAILED(mManager->EnumerateInterfaces(&e)) || !e ||
     279               0 :                 NS_FAILED(e->First()))
     280                 : 
     281                 :             {
     282               0 :                 *statep = JSVAL_NULL;
     283               0 :                 return NS_ERROR_UNEXPECTED;
     284                 :             }
     285                 : 
     286               0 :             *statep = PRIVATE_TO_JSVAL(e);
     287               0 :             if (idp)
     288               0 :                 *idp = INT_TO_JSID(0); // indicate that we don't know the count
     289               0 :             return NS_OK;
     290                 :         }
     291                 :         case JSENUMERATE_NEXT:
     292                 :         {
     293               0 :             nsCOMPtr<nsISupports> isup;
     294                 : 
     295               0 :             e = (nsIEnumerator*) JSVAL_TO_PRIVATE(*statep);
     296                 : 
     297               0 :             while (1) {
     298               0 :                 if (NS_ENUMERATOR_FALSE == e->IsDone() &&
     299               0 :                     NS_SUCCEEDED(e->CurrentItem(getter_AddRefs(isup))) && isup) {
     300               0 :                     e->Next();
     301               0 :                     nsCOMPtr<nsIInterfaceInfo> iface(do_QueryInterface(isup));
     302               0 :                     if (iface) {
     303                 :                         JSString* idstr;
     304                 :                         const char* name;
     305                 :                         bool scriptable;
     306                 : 
     307               0 :                         if (NS_SUCCEEDED(iface->IsScriptable(&scriptable)) &&
     308               0 :                             !scriptable) {
     309               0 :                             continue;
     310                 :                         }
     311                 : 
     312               0 :                         if (NS_SUCCEEDED(iface->GetNameShared(&name)) && name &&
     313               0 :                             nsnull != (idstr = JS_NewStringCopyZ(cx, name)) &&
     314               0 :                             JS_ValueToId(cx, STRING_TO_JSVAL(idstr), idp)) {
     315               0 :                             return NS_OK;
     316                 :                         }
     317                 :                     }
     318                 :                 }
     319                 :                 // else...
     320                 :                 break;
     321                 :             }
     322                 :             // FALL THROUGH
     323                 :         }
     324                 : 
     325                 :         case JSENUMERATE_DESTROY:
     326                 :         default:
     327               0 :             e = (nsIEnumerator*) JSVAL_TO_PRIVATE(*statep);
     328               0 :             NS_IF_RELEASE(e);
     329               0 :             *statep = JSVAL_NULL;
     330               0 :             return NS_OK;
     331                 :     }
     332                 : }
     333                 : 
     334                 : /* bool newResolve (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval id, in PRUint32 flags, out JSObjectPtr objp); */
     335                 : NS_IMETHODIMP
     336           92930 : nsXPCComponents_Interfaces::NewResolve(nsIXPConnectWrappedNative *wrapper,
     337                 :                                        JSContext * cx, JSObject * obj,
     338                 :                                        jsid id, PRUint32 flags,
     339                 :                                        JSObject * *objp, bool *_retval)
     340                 : {
     341          185860 :     JSAutoByteString name;
     342          371720 :     if (mManager &&
     343          185860 :         JSID_IS_STRING(id) &&
     344           92930 :         name.encode(cx, JSID_TO_STRING(id)) &&
     345           92930 :         name.ptr()[0] != '{') { // we only allow interfaces by name here
     346          185860 :         nsCOMPtr<nsIInterfaceInfo> info;
     347           92930 :         mManager->GetInfoForName(name.ptr(), getter_AddRefs(info));
     348           92930 :         if (!info)
     349            1594 :             return NS_OK;
     350                 : 
     351                 :         nsCOMPtr<nsIJSIID> nsid =
     352          275602 :             dont_AddRef(static_cast<nsIJSIID*>(nsJSIID::NewID(info)));
     353                 : 
     354           91336 :         if (nsid) {
     355          182672 :             nsCOMPtr<nsIXPConnect> xpc;
     356           91336 :             wrapper->GetXPConnect(getter_AddRefs(xpc));
     357           91336 :             if (xpc) {
     358          182672 :                 nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
     359           91336 :                 if (NS_SUCCEEDED(xpc->WrapNative(cx, obj,
     360                 :                                                  static_cast<nsIJSIID*>(nsid),
     361                 :                                                  NS_GET_IID(nsIJSIID),
     362                 :                                                  getter_AddRefs(holder)))) {
     363                 :                     JSObject* idobj;
     364           91336 :                     if (holder && NS_SUCCEEDED(holder->GetJSObject(&idobj))) {
     365           91336 :                         *objp = obj;
     366                 :                         *_retval = JS_DefinePropertyById(cx, obj, id,
     367           91336 :                                                          OBJECT_TO_JSVAL(idobj),
     368                 :                                                          nsnull, nsnull,
     369                 :                                                          JSPROP_ENUMERATE |
     370                 :                                                          JSPROP_READONLY |
     371           91336 :                                                          JSPROP_PERMANENT);
     372                 :                     }
     373                 :                 }
     374                 :             }
     375                 :         }
     376                 :     }
     377           91336 :     return NS_OK;
     378                 : }
     379                 : 
     380                 : /* string canCreateWrapper (in nsIIDPtr iid); */
     381                 : NS_IMETHODIMP
     382           12358 : nsXPCComponents_Interfaces::CanCreateWrapper(const nsIID * iid, char **_retval)
     383                 : {
     384                 :     // We let anyone do this...
     385           12358 :     *_retval = xpc_CloneAllAccess();
     386           12358 :     return NS_OK;
     387                 : }
     388                 : 
     389                 : /* string canCallMethod (in nsIIDPtr iid, in wstring methodName); */
     390                 : NS_IMETHODIMP
     391               0 : nsXPCComponents_Interfaces::CanCallMethod(const nsIID * iid, const PRUnichar *methodName, char **_retval)
     392                 : {
     393                 :     // If you have to ask, then the answer is NO
     394               0 :     *_retval = nsnull;
     395               0 :     return NS_OK;
     396                 : }
     397                 : 
     398                 : /* string canGetProperty (in nsIIDPtr iid, in wstring propertyName); */
     399                 : NS_IMETHODIMP
     400               0 : nsXPCComponents_Interfaces::CanGetProperty(const nsIID * iid, const PRUnichar *propertyName, char **_retval)
     401                 : {
     402                 :     // If you have to ask, then the answer is NO
     403               0 :     *_retval = nsnull;
     404               0 :     return NS_OK;
     405                 : }
     406                 : 
     407                 : /* string canSetProperty (in nsIIDPtr iid, in wstring propertyName); */
     408                 : NS_IMETHODIMP
     409               0 : nsXPCComponents_Interfaces::CanSetProperty(const nsIID * iid, const PRUnichar *propertyName, char **_retval)
     410                 : {
     411                 :     // If you have to ask, then the answer is NO
     412               0 :     *_retval = nsnull;
     413               0 :     return NS_OK;
     414                 : }
     415                 : 
     416                 : /***************************************************************************/
     417                 : /***************************************************************************/
     418                 : /***************************************************************************/
     419                 : 
     420                 : class nsXPCComponents_InterfacesByID :
     421                 :             public nsIXPCComponents_InterfacesByID,
     422                 :             public nsIXPCScriptable,
     423                 :             public nsIClassInfo,
     424                 :             public nsISecurityCheckedComponent
     425                 : {
     426                 : public:
     427                 :     // all the interface method declarations...
     428                 :     NS_DECL_ISUPPORTS
     429                 :     NS_DECL_NSIXPCCOMPONENTS_INTERFACESBYID
     430                 :     NS_DECL_NSIXPCSCRIPTABLE
     431                 :     NS_DECL_NSICLASSINFO
     432                 :     NS_DECL_NSISECURITYCHECKEDCOMPONENT
     433                 : 
     434                 : public:
     435                 :     nsXPCComponents_InterfacesByID();
     436                 :     virtual ~nsXPCComponents_InterfacesByID();
     437                 : 
     438                 : private:
     439                 :     nsCOMPtr<nsIInterfaceInfoManager> mManager;
     440                 : };
     441                 : 
     442                 : /***************************************************************************/
     443                 : /* void getInterfaces (out PRUint32 count, [array, size_is (count), retval]
     444                 :                        out nsIIDPtr array); */
     445                 : NS_IMETHODIMP
     446               1 : nsXPCComponents_InterfacesByID::GetInterfaces(PRUint32 *aCount, nsIID * **aArray)
     447                 : {
     448               1 :     const PRUint32 count = 3;
     449               1 :     *aCount = count;
     450                 :     nsIID **array;
     451               1 :     *aArray = array = static_cast<nsIID**>(nsMemory::Alloc(count * sizeof(nsIID*)));
     452               1 :     if (!array)
     453               0 :         return NS_ERROR_OUT_OF_MEMORY;
     454                 : 
     455               1 :     PRUint32 index = 0;
     456                 :     nsIID* clone;
     457                 : #define PUSH_IID(id)                                                          \
     458                 :     clone = static_cast<nsIID *>(nsMemory::Clone(&NS_GET_IID( id ),           \
     459                 :                                                  sizeof(nsIID)));             \
     460                 :     if (!clone)                                                               \
     461                 :         goto oom;                                                             \
     462                 :     array[index++] = clone;
     463                 : 
     464               1 :     PUSH_IID(nsIXPCComponents_InterfacesByID)
     465               1 :     PUSH_IID(nsIXPCScriptable)
     466               1 :     PUSH_IID(nsISecurityCheckedComponent)
     467                 : #undef PUSH_IID
     468                 : 
     469               1 :     return NS_OK;
     470                 : oom:
     471               0 :     while (index)
     472               0 :         nsMemory::Free(array[--index]);
     473               0 :     nsMemory::Free(array);
     474               0 :     *aArray = nsnull;
     475               0 :     return NS_ERROR_OUT_OF_MEMORY;
     476                 : }
     477                 : 
     478                 : /* nsISupports getHelperForLanguage (in PRUint32 language); */
     479                 : NS_IMETHODIMP
     480               1 : nsXPCComponents_InterfacesByID::GetHelperForLanguage(PRUint32 language,
     481                 :                                                      nsISupports **retval)
     482                 : {
     483               1 :     *retval = nsnull;
     484               1 :     return NS_OK;
     485                 : }
     486                 : 
     487                 : /* readonly attribute string contractID; */
     488                 : NS_IMETHODIMP
     489               0 : nsXPCComponents_InterfacesByID::GetContractID(char * *aContractID)
     490                 : {
     491               0 :     *aContractID = nsnull;
     492               0 :     return NS_ERROR_NOT_AVAILABLE;
     493                 : }
     494                 : 
     495                 : /* readonly attribute string classDescription; */
     496                 : NS_IMETHODIMP
     497               1 : nsXPCComponents_InterfacesByID::GetClassDescription(char * *aClassDescription)
     498                 : {
     499                 :     static const char classDescription[] = "XPCComponents_InterfacesByID";
     500               1 :     *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription));
     501               1 :     return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
     502                 : }
     503                 : 
     504                 : /* readonly attribute nsCIDPtr classID; */
     505                 : NS_IMETHODIMP
     506               0 : nsXPCComponents_InterfacesByID::GetClassID(nsCID * *aClassID)
     507                 : {
     508               0 :     *aClassID = nsnull;
     509               0 :     return NS_OK;
     510                 : }
     511                 : 
     512                 : /* readonly attribute PRUint32 implementationLanguage; */
     513                 : NS_IMETHODIMP
     514               0 : nsXPCComponents_InterfacesByID::GetImplementationLanguage(PRUint32 *aImplementationLanguage)
     515                 : {
     516               0 :     *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS;
     517               0 :     return NS_OK;
     518                 : }
     519                 : 
     520                 : /* readonly attribute PRUint32 flags; */
     521                 : NS_IMETHODIMP
     522               1 : nsXPCComponents_InterfacesByID::GetFlags(PRUint32 *aFlags)
     523                 : {
     524               1 :     *aFlags = nsIClassInfo::THREADSAFE;
     525               1 :     return NS_OK;
     526                 : }
     527                 : 
     528                 : /* [notxpcom] readonly attribute nsCID classIDNoAlloc; */
     529                 : NS_IMETHODIMP
     530               0 : nsXPCComponents_InterfacesByID::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
     531                 : {
     532               0 :     return NS_ERROR_NOT_AVAILABLE;
     533                 : }
     534                 : 
     535               1 : nsXPCComponents_InterfacesByID::nsXPCComponents_InterfacesByID() :
     536               1 :     mManager(do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID))
     537                 : {
     538               1 : }
     539                 : 
     540               2 : nsXPCComponents_InterfacesByID::~nsXPCComponents_InterfacesByID()
     541                 : {
     542                 :     // empty
     543               4 : }
     544                 : 
     545              20 : NS_INTERFACE_MAP_BEGIN(nsXPCComponents_InterfacesByID)
     546              20 :   NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_InterfacesByID)
     547              19 :   NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
     548              16 :   NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
     549              12 :   NS_INTERFACE_MAP_ENTRY(nsISecurityCheckedComponent)
     550              12 :   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_InterfacesByID)
     551               8 : NS_INTERFACE_MAP_END_THREADSAFE
     552                 : 
     553              16 : NS_IMPL_THREADSAFE_ADDREF(nsXPCComponents_InterfacesByID)
     554              16 : NS_IMPL_THREADSAFE_RELEASE(nsXPCComponents_InterfacesByID)
     555                 : 
     556                 : // The nsIXPCScriptable map declaration that will generate stubs for us...
     557                 : #define XPC_MAP_CLASSNAME           nsXPCComponents_InterfacesByID
     558                 : #define XPC_MAP_QUOTED_CLASSNAME   "nsXPCComponents_InterfacesByID"
     559                 : #define                             XPC_MAP_WANT_NEWRESOLVE
     560                 : #define                             XPC_MAP_WANT_NEWENUMERATE
     561                 : #define XPC_MAP_FLAGS               nsIXPCScriptable::DONT_ENUM_STATIC_PROPS |\
     562                 :                                     nsIXPCScriptable::ALLOW_PROP_MODS_DURING_RESOLVE
     563                 : #include "xpc_map_end.h" /* This will #undef the above */
     564                 : 
     565                 : /* bool newEnumerate (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in PRUint32 enum_op, in JSValPtr statep, out JSID idp); */
     566                 : NS_IMETHODIMP
     567               0 : nsXPCComponents_InterfacesByID::NewEnumerate(nsIXPConnectWrappedNative *wrapper,
     568                 :                                              JSContext * cx, JSObject * obj,
     569                 :                                              PRUint32 enum_op, jsval * statep,
     570                 :                                              jsid * idp, bool *_retval)
     571                 : {
     572                 :     nsIEnumerator* e;
     573                 : 
     574               0 :     switch (enum_op) {
     575                 :         case JSENUMERATE_INIT:
     576                 :         case JSENUMERATE_INIT_ALL:
     577                 :         {
     578               0 :             if (!mManager ||
     579               0 :                 NS_FAILED(mManager->EnumerateInterfaces(&e)) || !e ||
     580               0 :                 NS_FAILED(e->First()))
     581                 : 
     582                 :             {
     583               0 :                 *statep = JSVAL_NULL;
     584               0 :                 return NS_ERROR_UNEXPECTED;
     585                 :             }
     586                 : 
     587               0 :             *statep = PRIVATE_TO_JSVAL(e);
     588               0 :             if (idp)
     589               0 :                 *idp = INT_TO_JSID(0); // indicate that we don't know the count
     590               0 :             return NS_OK;
     591                 :         }
     592                 :         case JSENUMERATE_NEXT:
     593                 :         {
     594               0 :             nsCOMPtr<nsISupports> isup;
     595                 : 
     596               0 :             e = (nsIEnumerator*) JSVAL_TO_PRIVATE(*statep);
     597                 : 
     598               0 :             while (1) {
     599               0 :                 if (NS_ENUMERATOR_FALSE == e->IsDone() &&
     600               0 :                     NS_SUCCEEDED(e->CurrentItem(getter_AddRefs(isup))) && isup) {
     601               0 :                     e->Next();
     602               0 :                     nsCOMPtr<nsIInterfaceInfo> iface(do_QueryInterface(isup));
     603               0 :                     if (iface) {
     604                 :                         nsIID const *iid;
     605                 :                         char idstr[NSID_LENGTH];
     606                 :                         JSString* jsstr;
     607                 :                         bool scriptable;
     608                 : 
     609               0 :                         if (NS_SUCCEEDED(iface->IsScriptable(&scriptable)) &&
     610               0 :                             !scriptable) {
     611               0 :                             continue;
     612                 :                         }
     613                 : 
     614               0 :                         if (NS_SUCCEEDED(iface->GetIIDShared(&iid))) {
     615               0 :                             iid->ToProvidedString(idstr);
     616               0 :                             jsstr = JS_NewStringCopyZ(cx, idstr);
     617               0 :                             if (jsstr &&
     618               0 :                                 JS_ValueToId(cx, STRING_TO_JSVAL(jsstr), idp)) {
     619               0 :                                 return NS_OK;
     620                 :                             }
     621                 :                         }
     622                 :                     }
     623                 :                 }
     624                 :                 // else...
     625                 :                 break;
     626                 :             }
     627                 :             // FALL THROUGH
     628                 :         }
     629                 : 
     630                 :         case JSENUMERATE_DESTROY:
     631                 :         default:
     632               0 :             e = (nsIEnumerator*) JSVAL_TO_PRIVATE(*statep);
     633               0 :             NS_IF_RELEASE(e);
     634               0 :             *statep = JSVAL_NULL;
     635               0 :             return NS_OK;
     636                 :     }
     637                 : }
     638                 : 
     639                 : /* bool newResolve (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval id, in PRUint32 flags, out JSObjectPtr objp); */
     640                 : NS_IMETHODIMP
     641               2 : nsXPCComponents_InterfacesByID::NewResolve(nsIXPConnectWrappedNative *wrapper,
     642                 :                                            JSContext * cx, JSObject * obj,
     643                 :                                            jsid id, PRUint32 flags,
     644                 :                                            JSObject * *objp, bool *_retval)
     645                 : {
     646               2 :     const jschar* name = nsnull;
     647                 : 
     648               6 :     if (mManager &&
     649               4 :         JSID_IS_STRING(id) &&
     650               2 :         38 == JS_GetStringLength(JSID_TO_STRING(id)) &&
     651               0 :         nsnull != (name = JS_GetInternedStringChars(JSID_TO_STRING(id)))) {
     652                 :         nsID iid;
     653               0 :         if (!iid.Parse(NS_ConvertUTF16toUTF8(name).get()))
     654               0 :             return NS_OK;
     655                 : 
     656               0 :         nsCOMPtr<nsIInterfaceInfo> info;
     657               0 :         mManager->GetInfoForIID(&iid, getter_AddRefs(info));
     658               0 :         if (!info)
     659               0 :             return NS_OK;
     660                 : 
     661                 :         nsCOMPtr<nsIJSIID> nsid =
     662               0 :             dont_AddRef(static_cast<nsIJSIID*>(nsJSIID::NewID(info)));
     663                 : 
     664               0 :         if (!nsid)
     665               0 :             return NS_ERROR_OUT_OF_MEMORY;
     666                 : 
     667               0 :         nsCOMPtr<nsIXPConnect> xpc;
     668               0 :         wrapper->GetXPConnect(getter_AddRefs(xpc));
     669               0 :         if (xpc) {
     670               0 :             nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
     671               0 :             if (NS_SUCCEEDED(xpc->WrapNative(cx, obj,
     672                 :                                              static_cast<nsIJSIID*>(nsid),
     673                 :                                              NS_GET_IID(nsIJSIID),
     674                 :                                              getter_AddRefs(holder)))) {
     675                 :                 JSObject* idobj;
     676               0 :                 if (holder && NS_SUCCEEDED(holder->GetJSObject(&idobj))) {
     677               0 :                     *objp = obj;
     678                 :                     *_retval =
     679                 :                         JS_DefinePropertyById(cx, obj, id,
     680               0 :                                               OBJECT_TO_JSVAL(idobj),
     681                 :                                               nsnull, nsnull,
     682                 :                                               JSPROP_ENUMERATE |
     683                 :                                               JSPROP_READONLY |
     684               0 :                                               JSPROP_PERMANENT);
     685                 :                 }
     686                 :             }
     687                 :         }
     688                 :     }
     689               2 :     return NS_OK;
     690                 : }
     691                 : 
     692                 : /* string canCreateWrapper (in nsIIDPtr iid); */
     693                 : NS_IMETHODIMP
     694               0 : nsXPCComponents_InterfacesByID::CanCreateWrapper(const nsIID * iid, char **_retval)
     695                 : {
     696                 :     // We let anyone do this...
     697               0 :     *_retval = xpc_CloneAllAccess();
     698               0 :     return NS_OK;
     699                 : }
     700                 : 
     701                 : /* string canCallMethod (in nsIIDPtr iid, in wstring methodName); */
     702                 : NS_IMETHODIMP
     703               0 : nsXPCComponents_InterfacesByID::CanCallMethod(const nsIID * iid, const PRUnichar *methodName, char **_retval)
     704                 : {
     705                 :     // If you have to ask, then the answer is NO
     706               0 :     *_retval = nsnull;
     707               0 :     return NS_OK;
     708                 : }
     709                 : 
     710                 : /* string canGetProperty (in nsIIDPtr iid, in wstring propertyName); */
     711                 : NS_IMETHODIMP
     712               0 : nsXPCComponents_InterfacesByID::CanGetProperty(const nsIID * iid, const PRUnichar *propertyName, char **_retval)
     713                 : {
     714                 :     // If you have to ask, then the answer is NO
     715               0 :     *_retval = nsnull;
     716               0 :     return NS_OK;
     717                 : }
     718                 : 
     719                 : /* string canSetProperty (in nsIIDPtr iid, in wstring propertyName); */
     720                 : NS_IMETHODIMP
     721               0 : nsXPCComponents_InterfacesByID::CanSetProperty(const nsIID * iid, const PRUnichar *propertyName, char **_retval)
     722                 : {
     723                 :     // If you have to ask, then the answer is NO
     724               0 :     *_retval = nsnull;
     725               0 :     return NS_OK;
     726                 : }
     727                 : 
     728                 : /***************************************************************************/
     729                 : /***************************************************************************/
     730                 : /***************************************************************************/
     731                 : 
     732                 : 
     733                 : 
     734                 : class nsXPCComponents_Classes :
     735                 :   public nsIXPCComponents_Classes,
     736                 :   public nsIXPCScriptable,
     737                 :   public nsIClassInfo
     738                 : {
     739                 : public:
     740                 :     // all the interface method declarations...
     741                 :     NS_DECL_ISUPPORTS
     742                 :     NS_DECL_NSIXPCCOMPONENTS_CLASSES
     743                 :     NS_DECL_NSIXPCSCRIPTABLE
     744                 :     NS_DECL_NSICLASSINFO
     745                 : 
     746                 : public:
     747                 :     nsXPCComponents_Classes();
     748                 :     virtual ~nsXPCComponents_Classes();
     749                 : };
     750                 : 
     751                 : /***************************************************************************/
     752                 : /* void getInterfaces (out PRUint32 count, [array, size_is (count), retval]
     753                 :                        out nsIIDPtr array); */
     754                 : NS_IMETHODIMP
     755           12878 : nsXPCComponents_Classes::GetInterfaces(PRUint32 *aCount, nsIID * **aArray)
     756                 : {
     757           12878 :     const PRUint32 count = 2;
     758           12878 :     *aCount = count;
     759                 :     nsIID **array;
     760           12878 :     *aArray = array = static_cast<nsIID**>(nsMemory::Alloc(count * sizeof(nsIID*)));
     761           12878 :     if (!array)
     762               0 :         return NS_ERROR_OUT_OF_MEMORY;
     763                 : 
     764           12878 :     PRUint32 index = 0;
     765                 :     nsIID* clone;
     766                 : #define PUSH_IID(id)                                                          \
     767                 :     clone = static_cast<nsIID *>(nsMemory::Clone(&NS_GET_IID( id ),           \
     768                 :                                                  sizeof(nsIID)));             \
     769                 :     if (!clone)                                                               \
     770                 :         goto oom;                                                             \
     771                 :     array[index++] = clone;
     772                 : 
     773           12878 :     PUSH_IID(nsIXPCComponents_Classes)
     774           12878 :     PUSH_IID(nsIXPCScriptable)
     775                 : #undef PUSH_IID
     776                 : 
     777           12878 :     return NS_OK;
     778                 : oom:
     779               0 :     while (index)
     780               0 :         nsMemory::Free(array[--index]);
     781               0 :     nsMemory::Free(array);
     782               0 :     *aArray = nsnull;
     783               0 :     return NS_ERROR_OUT_OF_MEMORY;
     784                 : }
     785                 : 
     786                 : /* nsISupports getHelperForLanguage (in PRUint32 language); */
     787                 : NS_IMETHODIMP
     788           12878 : nsXPCComponents_Classes::GetHelperForLanguage(PRUint32 language,
     789                 :                                               nsISupports **retval)
     790                 : {
     791           12878 :     *retval = nsnull;
     792           12878 :     return NS_OK;
     793                 : }
     794                 : 
     795                 : /* readonly attribute string contractID; */
     796                 : NS_IMETHODIMP
     797               0 : nsXPCComponents_Classes::GetContractID(char * *aContractID)
     798                 : {
     799               0 :     *aContractID = nsnull;
     800               0 :     return NS_ERROR_NOT_AVAILABLE;
     801                 : }
     802                 : 
     803                 : /* readonly attribute string classDescription; */
     804                 : NS_IMETHODIMP
     805               1 : nsXPCComponents_Classes::GetClassDescription(char * *aClassDescription)
     806                 : {
     807                 :     static const char classDescription[] = "XPCComponents_Classes";
     808               1 :     *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription));
     809               1 :     return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
     810                 : }
     811                 : 
     812                 : /* readonly attribute nsCIDPtr classID; */
     813                 : NS_IMETHODIMP
     814               0 : nsXPCComponents_Classes::GetClassID(nsCID * *aClassID)
     815                 : {
     816               0 :     *aClassID = nsnull;
     817               0 :     return NS_OK;
     818                 : }
     819                 : 
     820                 : /* readonly attribute PRUint32 implementationLanguage; */
     821                 : NS_IMETHODIMP
     822               0 : nsXPCComponents_Classes::GetImplementationLanguage(PRUint32 *aImplementationLanguage)
     823                 : {
     824               0 :     *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS;
     825               0 :     return NS_OK;
     826                 : }
     827                 : 
     828                 : /* readonly attribute PRUint32 flags; */
     829                 : NS_IMETHODIMP
     830           25076 : nsXPCComponents_Classes::GetFlags(PRUint32 *aFlags)
     831                 : {
     832           25076 :     *aFlags = nsIClassInfo::THREADSAFE;
     833           25076 :     return NS_OK;
     834                 : }
     835                 : 
     836                 : /* [notxpcom] readonly attribute nsCID classIDNoAlloc; */
     837                 : NS_IMETHODIMP
     838               0 : nsXPCComponents_Classes::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
     839                 : {
     840               0 :     return NS_ERROR_NOT_AVAILABLE;
     841                 : }
     842                 : 
     843           12598 : nsXPCComponents_Classes::nsXPCComponents_Classes()
     844                 : {
     845           12598 : }
     846                 : 
     847           25162 : nsXPCComponents_Classes::~nsXPCComponents_Classes()
     848                 : {
     849                 :     // empty
     850           50324 : }
     851                 : 
     852          243273 : NS_INTERFACE_MAP_BEGIN(nsXPCComponents_Classes)
     853          243273 :   NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_Classes)
     854          224074 :   NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
     855          185440 :   NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
     856          159682 :   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_Classes)
     857          113220 : NS_INTERFACE_MAP_END_THREADSAFE
     858                 : 
     859          214866 : NS_IMPL_THREADSAFE_ADDREF(nsXPCComponents_Classes)
     860          214831 : NS_IMPL_THREADSAFE_RELEASE(nsXPCComponents_Classes)
     861                 : 
     862                 : // The nsIXPCScriptable map declaration that will generate stubs for us...
     863                 : #define XPC_MAP_CLASSNAME           nsXPCComponents_Classes
     864                 : #define XPC_MAP_QUOTED_CLASSNAME   "nsXPCComponents_Classes"
     865                 : #define                             XPC_MAP_WANT_NEWRESOLVE
     866                 : #define                             XPC_MAP_WANT_NEWENUMERATE
     867                 : #define XPC_MAP_FLAGS               nsIXPCScriptable::DONT_ENUM_STATIC_PROPS |\
     868                 :                                     nsIXPCScriptable::ALLOW_PROP_MODS_DURING_RESOLVE
     869                 : #include "xpc_map_end.h" /* This will #undef the above */
     870                 : 
     871                 : 
     872                 : /* bool newEnumerate (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in PRUint32 enum_op, in JSValPtr statep, out JSID idp); */
     873                 : NS_IMETHODIMP
     874               0 : nsXPCComponents_Classes::NewEnumerate(nsIXPConnectWrappedNative *wrapper,
     875                 :                                       JSContext * cx, JSObject * obj,
     876                 :                                       PRUint32 enum_op, jsval * statep,
     877                 :                                       jsid * idp, bool *_retval)
     878                 : {
     879                 :     nsISimpleEnumerator* e;
     880                 : 
     881               0 :     switch (enum_op) {
     882                 :         case JSENUMERATE_INIT:
     883                 :         case JSENUMERATE_INIT_ALL:
     884                 :         {
     885               0 :             nsCOMPtr<nsIComponentRegistrar> compMgr;
     886               0 :             if (NS_FAILED(NS_GetComponentRegistrar(getter_AddRefs(compMgr))) || !compMgr ||
     887               0 :                 NS_FAILED(compMgr->EnumerateContractIDs(&e)) || !e ) {
     888               0 :                 *statep = JSVAL_NULL;
     889               0 :                 return NS_ERROR_UNEXPECTED;
     890                 :             }
     891                 : 
     892               0 :             *statep = PRIVATE_TO_JSVAL(e);
     893               0 :             if (idp)
     894               0 :                 *idp = INT_TO_JSID(0); // indicate that we don't know the count
     895               0 :             return NS_OK;
     896                 :         }
     897                 :         case JSENUMERATE_NEXT:
     898                 :         {
     899               0 :             nsCOMPtr<nsISupports> isup;
     900                 :             bool hasMore;
     901               0 :             e = (nsISimpleEnumerator*) JSVAL_TO_PRIVATE(*statep);
     902                 : 
     903               0 :             if (NS_SUCCEEDED(e->HasMoreElements(&hasMore)) && hasMore &&
     904               0 :                 NS_SUCCEEDED(e->GetNext(getter_AddRefs(isup))) && isup) {
     905               0 :                 nsCOMPtr<nsISupportsCString> holder(do_QueryInterface(isup));
     906               0 :                 if (holder) {
     907               0 :                     nsCAutoString name;
     908               0 :                     if (NS_SUCCEEDED(holder->GetData(name))) {
     909               0 :                         JSString* idstr = JS_NewStringCopyN(cx, name.get(), name.Length());
     910               0 :                         if (idstr &&
     911               0 :                             JS_ValueToId(cx, STRING_TO_JSVAL(idstr), idp)) {
     912               0 :                             return NS_OK;
     913                 :                         }
     914                 :                     }
     915                 :                 }
     916                 :             }
     917                 :             // else... FALL THROUGH
     918                 :         }
     919                 : 
     920                 :         case JSENUMERATE_DESTROY:
     921                 :         default:
     922               0 :             e = (nsISimpleEnumerator*) JSVAL_TO_PRIVATE(*statep);
     923               0 :             NS_IF_RELEASE(e);
     924               0 :             *statep = JSVAL_NULL;
     925               0 :             return NS_OK;
     926                 :     }
     927                 : }
     928                 : 
     929                 : /* bool newResolve (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval id, in PRUint32 flags, out JSObjectPtr objp); */
     930                 : NS_IMETHODIMP
     931           44142 : nsXPCComponents_Classes::NewResolve(nsIXPConnectWrappedNative *wrapper,
     932                 :                                     JSContext * cx, JSObject * obj,
     933                 :                                     jsid id, PRUint32 flags,
     934                 :                                     JSObject * *objp, bool *_retval)
     935                 : 
     936                 : {
     937           88284 :     JSAutoByteString name;
     938                 : 
     939          132426 :     if (JSID_IS_STRING(id) &&
     940           44142 :         name.encode(cx, JSID_TO_STRING(id)) &&
     941           44142 :         name.ptr()[0] != '{') { // we only allow contractids here
     942                 :         nsCOMPtr<nsIJSCID> nsid =
     943           88284 :             dont_AddRef(static_cast<nsIJSCID*>(nsJSCID::NewID(name.ptr())));
     944           44142 :         if (nsid) {
     945           85116 :             nsCOMPtr<nsIXPConnect> xpc;
     946           42558 :             wrapper->GetXPConnect(getter_AddRefs(xpc));
     947           42558 :             if (xpc) {
     948           85116 :                 nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
     949           42558 :                 if (NS_SUCCEEDED(xpc->WrapNative(cx, obj,
     950                 :                                                  static_cast<nsIJSCID*>(nsid),
     951                 :                                                  NS_GET_IID(nsIJSCID),
     952                 :                                                  getter_AddRefs(holder)))) {
     953                 :                     JSObject* idobj;
     954           42558 :                     if (holder && NS_SUCCEEDED(holder->GetJSObject(&idobj))) {
     955           42558 :                         *objp = obj;
     956                 :                         *_retval = JS_DefinePropertyById(cx, obj, id,
     957           42558 :                                                          OBJECT_TO_JSVAL(idobj),
     958                 :                                                          nsnull, nsnull,
     959                 :                                                          JSPROP_ENUMERATE |
     960                 :                                                          JSPROP_READONLY |
     961           42558 :                                                          JSPROP_PERMANENT);
     962                 :                     }
     963                 :                 }
     964                 :             }
     965                 :         }
     966                 :     }
     967           44142 :     return NS_OK;
     968                 : }
     969                 : 
     970                 : /***************************************************************************/
     971                 : /***************************************************************************/
     972                 : /***************************************************************************/
     973                 : 
     974                 : class nsXPCComponents_ClassesByID :
     975                 :   public nsIXPCComponents_ClassesByID,
     976                 :   public nsIXPCScriptable,
     977                 :   public nsIClassInfo
     978                 : {
     979                 : public:
     980                 :     // all the interface method declarations...
     981                 :     NS_DECL_ISUPPORTS
     982                 :     NS_DECL_NSIXPCCOMPONENTS_CLASSESBYID
     983                 :     NS_DECL_NSIXPCSCRIPTABLE
     984                 :     NS_DECL_NSICLASSINFO
     985                 : 
     986                 : public:
     987                 :     nsXPCComponents_ClassesByID();
     988                 :     virtual ~nsXPCComponents_ClassesByID();
     989                 : };
     990                 : 
     991                 : /***************************************************************************/
     992                 : /* void getInterfaces (out PRUint32 count, [array, size_is (count), retval]
     993                 :                        out nsIIDPtr array); */
     994                 : NS_IMETHODIMP
     995               4 : nsXPCComponents_ClassesByID::GetInterfaces(PRUint32 *aCount, nsIID * **aArray)
     996                 : {
     997               4 :     const PRUint32 count = 2;
     998               4 :     *aCount = count;
     999                 :     nsIID **array;
    1000               4 :     *aArray = array = static_cast<nsIID**>(nsMemory::Alloc(count * sizeof(nsIID*)));
    1001               4 :     if (!array)
    1002               0 :         return NS_ERROR_OUT_OF_MEMORY;
    1003                 : 
    1004               4 :     PRUint32 index = 0;
    1005                 :     nsIID* clone;
    1006                 : #define PUSH_IID(id)                                                          \
    1007                 :     clone = static_cast<nsIID *>(nsMemory::Clone(&NS_GET_IID( id ),           \
    1008                 :                                                  sizeof(nsIID)));             \
    1009                 :     if (!clone)                                                               \
    1010                 :         goto oom;                                                             \
    1011                 :     array[index++] = clone;
    1012                 : 
    1013               4 :     PUSH_IID(nsIXPCComponents_ClassesByID)
    1014               4 :     PUSH_IID(nsIXPCScriptable)
    1015                 : #undef PUSH_IID
    1016                 : 
    1017               4 :     return NS_OK;
    1018                 : oom:
    1019               0 :     while (index)
    1020               0 :         nsMemory::Free(array[--index]);
    1021               0 :     nsMemory::Free(array);
    1022               0 :     *aArray = nsnull;
    1023               0 :     return NS_ERROR_OUT_OF_MEMORY;
    1024                 : }
    1025                 : 
    1026                 : /* nsISupports getHelperForLanguage (in PRUint32 language); */
    1027                 : NS_IMETHODIMP
    1028               4 : nsXPCComponents_ClassesByID::GetHelperForLanguage(PRUint32 language,
    1029                 :                                                   nsISupports **retval)
    1030                 : {
    1031               4 :     *retval = nsnull;
    1032               4 :     return NS_OK;
    1033                 : }
    1034                 : 
    1035                 : /* readonly attribute string contractID; */
    1036                 : NS_IMETHODIMP
    1037               0 : nsXPCComponents_ClassesByID::GetContractID(char * *aContractID)
    1038                 : {
    1039               0 :     *aContractID = nsnull;
    1040               0 :     return NS_ERROR_NOT_AVAILABLE;
    1041                 : }
    1042                 : 
    1043                 : /* readonly attribute string classDescription; */
    1044                 : NS_IMETHODIMP
    1045               1 : nsXPCComponents_ClassesByID::GetClassDescription(char * *aClassDescription)
    1046                 : {
    1047                 :     static const char classDescription[] = "XPCComponents_ClassesByID";
    1048               1 :     *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription));
    1049               1 :     return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
    1050                 : }
    1051                 : 
    1052                 : /* readonly attribute nsCIDPtr classID; */
    1053                 : NS_IMETHODIMP
    1054               0 : nsXPCComponents_ClassesByID::GetClassID(nsCID * *aClassID)
    1055                 : {
    1056               0 :     *aClassID = nsnull;
    1057               0 :     return NS_OK;
    1058                 : }
    1059                 : 
    1060                 : /* readonly attribute PRUint32 implementationLanguage; */
    1061                 : NS_IMETHODIMP
    1062               0 : nsXPCComponents_ClassesByID::GetImplementationLanguage(PRUint32 *aImplementationLanguage)
    1063                 : {
    1064               0 :     *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS;
    1065               0 :     return NS_OK;
    1066                 : }
    1067                 : 
    1068                 : /* readonly attribute PRUint32 flags; */
    1069                 : NS_IMETHODIMP
    1070               4 : nsXPCComponents_ClassesByID::GetFlags(PRUint32 *aFlags)
    1071                 : {
    1072               4 :     *aFlags = nsIClassInfo::THREADSAFE;
    1073               4 :     return NS_OK;
    1074                 : }
    1075                 : 
    1076                 : /* [notxpcom] readonly attribute nsCID classIDNoAlloc; */
    1077                 : NS_IMETHODIMP
    1078               0 : nsXPCComponents_ClassesByID::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
    1079                 : {
    1080               0 :     return NS_ERROR_NOT_AVAILABLE;
    1081                 : }
    1082                 : 
    1083               4 : nsXPCComponents_ClassesByID::nsXPCComponents_ClassesByID()
    1084                 : {
    1085               4 : }
    1086                 : 
    1087               8 : nsXPCComponents_ClassesByID::~nsXPCComponents_ClassesByID()
    1088                 : {
    1089                 :     // empty
    1090              16 : }
    1091                 : 
    1092              58 : NS_INTERFACE_MAP_BEGIN(nsXPCComponents_ClassesByID)
    1093              58 :   NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_ClassesByID)
    1094              54 :   NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
    1095              42 :   NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
    1096              32 :   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_ClassesByID)
    1097              24 : NS_INTERFACE_MAP_END_THREADSAFE
    1098                 : 
    1099              51 : NS_IMPL_THREADSAFE_ADDREF(nsXPCComponents_ClassesByID)
    1100              51 : NS_IMPL_THREADSAFE_RELEASE(nsXPCComponents_ClassesByID)
    1101                 : 
    1102                 : // The nsIXPCScriptable map declaration that will generate stubs for us...
    1103                 : #define XPC_MAP_CLASSNAME           nsXPCComponents_ClassesByID
    1104                 : #define XPC_MAP_QUOTED_CLASSNAME   "nsXPCComponents_ClassesByID"
    1105                 : #define                             XPC_MAP_WANT_NEWRESOLVE
    1106                 : #define                             XPC_MAP_WANT_NEWENUMERATE
    1107                 : #define XPC_MAP_FLAGS               nsIXPCScriptable::DONT_ENUM_STATIC_PROPS |\
    1108                 :                                     nsIXPCScriptable::ALLOW_PROP_MODS_DURING_RESOLVE
    1109                 : #include "xpc_map_end.h" /* This will #undef the above */
    1110                 : 
    1111                 : /* bool newEnumerate (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in PRUint32 enum_op, in JSValPtr statep, out JSID idp); */
    1112                 : NS_IMETHODIMP
    1113               0 : nsXPCComponents_ClassesByID::NewEnumerate(nsIXPConnectWrappedNative *wrapper,
    1114                 :                                           JSContext * cx, JSObject * obj,
    1115                 :                                           PRUint32 enum_op, jsval * statep,
    1116                 :                                           jsid * idp, bool *_retval)
    1117                 : {
    1118                 :     nsISimpleEnumerator* e;
    1119                 : 
    1120               0 :     switch (enum_op) {
    1121                 :         case JSENUMERATE_INIT:
    1122                 :         case JSENUMERATE_INIT_ALL:
    1123                 :         {
    1124               0 :             nsCOMPtr<nsIComponentRegistrar> compMgr;
    1125               0 :             if (NS_FAILED(NS_GetComponentRegistrar(getter_AddRefs(compMgr))) || !compMgr ||
    1126               0 :                 NS_FAILED(compMgr->EnumerateCIDs(&e)) || !e ) {
    1127               0 :                 *statep = JSVAL_NULL;
    1128               0 :                 return NS_ERROR_UNEXPECTED;
    1129                 :             }
    1130                 : 
    1131               0 :             *statep = PRIVATE_TO_JSVAL(e);
    1132               0 :             if (idp)
    1133               0 :                 *idp = INT_TO_JSID(0); // indicate that we don't know the count
    1134               0 :             return NS_OK;
    1135                 :         }
    1136                 :         case JSENUMERATE_NEXT:
    1137                 :         {
    1138               0 :             nsCOMPtr<nsISupports> isup;
    1139                 :             bool hasMore;
    1140               0 :             e = (nsISimpleEnumerator*) JSVAL_TO_PRIVATE(*statep);
    1141                 : 
    1142               0 :             if (NS_SUCCEEDED(e->HasMoreElements(&hasMore)) && hasMore &&
    1143               0 :                 NS_SUCCEEDED(e->GetNext(getter_AddRefs(isup))) && isup) {
    1144               0 :                 nsCOMPtr<nsISupportsID> holder(do_QueryInterface(isup));
    1145               0 :                 if (holder) {
    1146                 :                     char* name;
    1147               0 :                     if (NS_SUCCEEDED(holder->ToString(&name)) && name) {
    1148               0 :                         JSString* idstr = JS_NewStringCopyZ(cx, name);
    1149               0 :                         nsMemory::Free(name);
    1150               0 :                         if (idstr &&
    1151               0 :                             JS_ValueToId(cx, STRING_TO_JSVAL(idstr), idp)) {
    1152               0 :                             return NS_OK;
    1153                 :                         }
    1154                 :                     }
    1155                 :                 }
    1156                 :             }
    1157                 :             // else... FALL THROUGH
    1158                 :         }
    1159                 : 
    1160                 :         case JSENUMERATE_DESTROY:
    1161                 :         default:
    1162               0 :             e = (nsISimpleEnumerator*) JSVAL_TO_PRIVATE(*statep);
    1163               0 :             NS_IF_RELEASE(e);
    1164               0 :             *statep = JSVAL_NULL;
    1165               0 :             return NS_OK;
    1166                 :     }
    1167                 : }
    1168                 : 
    1169                 : static bool
    1170               3 : IsRegisteredCLSID(const char* str)
    1171                 : {
    1172                 :     bool registered;
    1173                 :     nsID id;
    1174                 : 
    1175               3 :     if (!id.Parse(str))
    1176               0 :         return false;
    1177                 : 
    1178               6 :     nsCOMPtr<nsIComponentRegistrar> compMgr;
    1179               6 :     if (NS_FAILED(NS_GetComponentRegistrar(getter_AddRefs(compMgr))) || !compMgr ||
    1180               3 :         NS_FAILED(compMgr->IsCIDRegistered(id, &registered)))
    1181               0 :         return false;
    1182                 : 
    1183               3 :     return registered;
    1184                 : }
    1185                 : 
    1186                 : /* bool newResolve (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval id, in PRUint32 flags, out JSObjectPtr objp); */
    1187                 : NS_IMETHODIMP
    1188               5 : nsXPCComponents_ClassesByID::NewResolve(nsIXPConnectWrappedNative *wrapper,
    1189                 :                                         JSContext * cx, JSObject * obj,
    1190                 :                                         jsid id, PRUint32 flags,
    1191                 :                                         JSObject * *objp, bool *_retval)
    1192                 : {
    1193              10 :     JSAutoByteString name;
    1194                 : 
    1195              18 :     if (JSID_IS_STRING(id) &&
    1196               5 :         name.encode(cx, JSID_TO_STRING(id)) &&
    1197               5 :         name.ptr()[0] == '{' &&
    1198               3 :         IsRegisteredCLSID(name.ptr())) { // we only allow canonical CLSIDs here
    1199                 :         nsCOMPtr<nsIJSCID> nsid =
    1200               4 :             dont_AddRef(static_cast<nsIJSCID*>(nsJSCID::NewID(name.ptr())));
    1201               2 :         if (nsid) {
    1202               4 :             nsCOMPtr<nsIXPConnect> xpc;
    1203               2 :             wrapper->GetXPConnect(getter_AddRefs(xpc));
    1204               2 :             if (xpc) {
    1205               4 :                 nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
    1206               2 :                 if (NS_SUCCEEDED(xpc->WrapNative(cx, obj,
    1207                 :                                                  static_cast<nsIJSCID*>(nsid),
    1208                 :                                                  NS_GET_IID(nsIJSCID),
    1209                 :                                                  getter_AddRefs(holder)))) {
    1210                 :                     JSObject* idobj;
    1211               2 :                     if (holder && NS_SUCCEEDED(holder->GetJSObject(&idobj))) {
    1212               2 :                         *objp = obj;
    1213                 :                         *_retval = JS_DefinePropertyById(cx, obj, id,
    1214               2 :                                                          OBJECT_TO_JSVAL(idobj),
    1215                 :                                                          nsnull, nsnull,
    1216                 :                                                          JSPROP_ENUMERATE |
    1217                 :                                                          JSPROP_READONLY |
    1218               2 :                                                          JSPROP_PERMANENT);
    1219                 :                     }
    1220                 :                 }
    1221                 :             }
    1222                 :         }
    1223                 :     }
    1224               5 :     return NS_OK;
    1225                 : }
    1226                 : 
    1227                 : 
    1228                 : /***************************************************************************/
    1229                 : 
    1230                 : // Currently the possible results do not change at runtime, so they are only
    1231                 : // cached once (unlike ContractIDs, CLSIDs, and IIDs)
    1232                 : 
    1233                 : class nsXPCComponents_Results :
    1234                 :   public nsIXPCComponents_Results,
    1235                 :   public nsIXPCScriptable,
    1236                 :   public nsIClassInfo
    1237                 : {
    1238                 : public:
    1239                 :     // all the interface method declarations...
    1240                 :     NS_DECL_ISUPPORTS
    1241                 :     NS_DECL_NSIXPCCOMPONENTS_RESULTS
    1242                 :     NS_DECL_NSIXPCSCRIPTABLE
    1243                 :     NS_DECL_NSICLASSINFO
    1244                 : 
    1245                 : public:
    1246                 :     nsXPCComponents_Results();
    1247                 :     virtual ~nsXPCComponents_Results();
    1248                 : };
    1249                 : 
    1250                 : /***************************************************************************/
    1251                 : /* void getInterfaces (out PRUint32 count, [array, size_is (count), retval]
    1252                 :                        out nsIIDPtr array); */
    1253                 : NS_IMETHODIMP
    1254            9796 : nsXPCComponents_Results::GetInterfaces(PRUint32 *aCount, nsIID * **aArray)
    1255                 : {
    1256            9796 :     const PRUint32 count = 2;
    1257            9796 :     *aCount = count;
    1258                 :     nsIID **array;
    1259            9796 :     *aArray = array = static_cast<nsIID**>(nsMemory::Alloc(count * sizeof(nsIID*)));
    1260            9796 :     if (!array)
    1261               0 :         return NS_ERROR_OUT_OF_MEMORY;
    1262                 : 
    1263            9796 :     PRUint32 index = 0;
    1264                 :     nsIID* clone;
    1265                 : #define PUSH_IID(id)                                                          \
    1266                 :     clone = static_cast<nsIID *>(nsMemory::Clone(&NS_GET_IID( id ),           \
    1267                 :                                                  sizeof(nsIID)));             \
    1268                 :     if (!clone)                                                               \
    1269                 :         goto oom;                                                             \
    1270                 :     array[index++] = clone;
    1271                 : 
    1272            9796 :     PUSH_IID(nsIXPCComponents_Results)
    1273            9796 :     PUSH_IID(nsIXPCScriptable)
    1274                 : #undef PUSH_IID
    1275                 : 
    1276            9796 :     return NS_OK;
    1277                 : oom:
    1278               0 :     while (index)
    1279               0 :         nsMemory::Free(array[--index]);
    1280               0 :     nsMemory::Free(array);
    1281               0 :     *aArray = nsnull;
    1282               0 :     return NS_ERROR_OUT_OF_MEMORY;
    1283                 : }
    1284                 : 
    1285                 : /* nsISupports getHelperForLanguage (in PRUint32 language); */
    1286                 : NS_IMETHODIMP
    1287            9796 : nsXPCComponents_Results::GetHelperForLanguage(PRUint32 language,
    1288                 :                                               nsISupports **retval)
    1289                 : {
    1290            9796 :     *retval = nsnull;
    1291            9796 :     return NS_OK;
    1292                 : }
    1293                 : 
    1294                 : /* readonly attribute string contractID; */
    1295                 : NS_IMETHODIMP
    1296               0 : nsXPCComponents_Results::GetContractID(char * *aContractID)
    1297                 : {
    1298               0 :     *aContractID = nsnull;
    1299               0 :     return NS_ERROR_NOT_AVAILABLE;
    1300                 : }
    1301                 : 
    1302                 : /* readonly attribute string classDescription; */
    1303                 : NS_IMETHODIMP
    1304               1 : nsXPCComponents_Results::GetClassDescription(char * *aClassDescription)
    1305                 : {
    1306                 :     static const char classDescription[] = "XPCComponents_Results";
    1307               1 :     *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription));
    1308               1 :     return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
    1309                 : }
    1310                 : 
    1311                 : /* readonly attribute nsCIDPtr classID; */
    1312                 : NS_IMETHODIMP
    1313               0 : nsXPCComponents_Results::GetClassID(nsCID * *aClassID)
    1314                 : {
    1315               0 :     *aClassID = nsnull;
    1316               0 :     return NS_OK;
    1317                 : }
    1318                 : 
    1319                 : /* readonly attribute PRUint32 implementationLanguage; */
    1320                 : NS_IMETHODIMP
    1321               0 : nsXPCComponents_Results::GetImplementationLanguage(PRUint32 *aImplementationLanguage)
    1322                 : {
    1323               0 :     *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS;
    1324               0 :     return NS_OK;
    1325                 : }
    1326                 : 
    1327                 : /* readonly attribute PRUint32 flags; */
    1328                 : NS_IMETHODIMP
    1329           18403 : nsXPCComponents_Results::GetFlags(PRUint32 *aFlags)
    1330                 : {
    1331           18403 :     *aFlags = nsIClassInfo::THREADSAFE;
    1332           18403 :     return NS_OK;
    1333                 : }
    1334                 : 
    1335                 : /* [notxpcom] readonly attribute nsCID classIDNoAlloc; */
    1336                 : NS_IMETHODIMP
    1337               0 : nsXPCComponents_Results::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
    1338                 : {
    1339               0 :     return NS_ERROR_NOT_AVAILABLE;
    1340                 : }
    1341                 : 
    1342            9794 : nsXPCComponents_Results::nsXPCComponents_Results()
    1343                 : {
    1344            9794 : }
    1345                 : 
    1346           19568 : nsXPCComponents_Results::~nsXPCComponents_Results()
    1347                 : {
    1348                 :     // empty
    1349           39136 : }
    1350                 : 
    1351          139315 : NS_INTERFACE_MAP_BEGIN(nsXPCComponents_Results)
    1352          139315 :   NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_Results)
    1353          129152 :   NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
    1354           99764 :   NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
    1355           80170 :   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_Results)
    1356           64668 : NS_INTERFACE_MAP_END_THREADSAFE
    1357                 : 
    1358          119532 : NS_IMPL_THREADSAFE_ADDREF(nsXPCComponents_Results)
    1359          119512 : NS_IMPL_THREADSAFE_RELEASE(nsXPCComponents_Results)
    1360                 : 
    1361                 : // The nsIXPCScriptable map declaration that will generate stubs for us...
    1362                 : #define XPC_MAP_CLASSNAME           nsXPCComponents_Results
    1363                 : #define XPC_MAP_QUOTED_CLASSNAME   "nsXPCComponents_Results"
    1364                 : #define                             XPC_MAP_WANT_NEWRESOLVE
    1365                 : #define                             XPC_MAP_WANT_NEWENUMERATE
    1366                 : #define XPC_MAP_FLAGS               nsIXPCScriptable::DONT_ENUM_STATIC_PROPS |\
    1367                 :                                     nsIXPCScriptable::ALLOW_PROP_MODS_DURING_RESOLVE
    1368                 : #include "xpc_map_end.h" /* This will #undef the above */
    1369                 : 
    1370                 : /* bool newEnumerate (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in PRUint32 enum_op, in JSValPtr statep, out JSID idp); */
    1371                 : NS_IMETHODIMP
    1372               0 : nsXPCComponents_Results::NewEnumerate(nsIXPConnectWrappedNative *wrapper,
    1373                 :                                       JSContext * cx, JSObject * obj,
    1374                 :                                       PRUint32 enum_op, jsval * statep,
    1375                 :                                       jsid * idp, bool *_retval)
    1376                 : {
    1377                 :     void** iter;
    1378                 : 
    1379               0 :     switch (enum_op) {
    1380                 :         case JSENUMERATE_INIT:
    1381                 :         case JSENUMERATE_INIT_ALL:
    1382                 :         {
    1383               0 :             if (idp)
    1384               0 :                 *idp = INT_TO_JSID(nsXPCException::GetNSResultCount());
    1385                 : 
    1386               0 :             void** space = (void**) new char[sizeof(void*)];
    1387               0 :             *space = nsnull;
    1388               0 :             *statep = PRIVATE_TO_JSVAL(space);
    1389               0 :             return NS_OK;
    1390                 :         }
    1391                 :         case JSENUMERATE_NEXT:
    1392                 :         {
    1393                 :             const char* name;
    1394               0 :             iter = (void**) JSVAL_TO_PRIVATE(*statep);
    1395               0 :             if (nsXPCException::IterateNSResults(nsnull, &name, nsnull, iter)) {
    1396               0 :                 JSString* idstr = JS_NewStringCopyZ(cx, name);
    1397               0 :                 if (idstr && JS_ValueToId(cx, STRING_TO_JSVAL(idstr), idp))
    1398               0 :                     return NS_OK;
    1399                 :             }
    1400                 :             // else... FALL THROUGH
    1401                 :         }
    1402                 : 
    1403                 :         case JSENUMERATE_DESTROY:
    1404                 :         default:
    1405               0 :             iter = (void**) JSVAL_TO_PRIVATE(*statep);
    1406               0 :             delete [] (char*) iter;
    1407               0 :             *statep = JSVAL_NULL;
    1408               0 :             return NS_OK;
    1409                 :     }
    1410                 : }
    1411                 : 
    1412                 : 
    1413                 : /* bool newResolve (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval id, in PRUint32 flags, out JSObjectPtr objp); */
    1414                 : NS_IMETHODIMP
    1415            5763 : nsXPCComponents_Results::NewResolve(nsIXPConnectWrappedNative *wrapper,
    1416                 :                                     JSContext * cx, JSObject * obj,
    1417                 :                                     jsid id, PRUint32 flags,
    1418                 :                                     JSObject * *objp, bool *_retval)
    1419                 : {
    1420           11526 :     JSAutoByteString name;
    1421                 : 
    1422            5763 :     if (JSID_IS_STRING(id) && name.encode(cx, JSID_TO_STRING(id))) {
    1423                 :         const char* rv_name;
    1424            5763 :         void* iter = nsnull;
    1425                 :         nsresult rv;
    1426          933606 :         while (nsXPCException::IterateNSResults(&rv, &rv_name, nsnull, &iter)) {
    1427          922080 :             if (!strcmp(name.ptr(), rv_name)) {
    1428                 :                 jsval val;
    1429                 : 
    1430            5761 :                 *objp = obj;
    1431           11522 :                 if (!JS_NewNumberValue(cx, (double)rv, &val) ||
    1432                 :                     !JS_DefinePropertyById(cx, obj, id, val,
    1433                 :                                            nsnull, nsnull,
    1434                 :                                            JSPROP_ENUMERATE |
    1435                 :                                            JSPROP_READONLY |
    1436            5761 :                                            JSPROP_PERMANENT)) {
    1437               0 :                     return NS_ERROR_UNEXPECTED;
    1438                 :                 }
    1439                 :             }
    1440                 :         }
    1441                 :     }
    1442            5763 :     return NS_OK;
    1443                 : }
    1444                 : 
    1445                 : /***************************************************************************/
    1446                 : // JavaScript Constructor for nsIJSID objects (Components.ID)
    1447                 : 
    1448                 : class nsXPCComponents_ID :
    1449                 :   public nsIXPCComponents_ID,
    1450                 :   public nsIXPCScriptable,
    1451                 :   public nsIClassInfo
    1452                 : {
    1453                 : public:
    1454                 :     // all the interface method declarations...
    1455                 :     NS_DECL_ISUPPORTS
    1456                 :     NS_DECL_NSIXPCCOMPONENTS_ID
    1457                 :     NS_DECL_NSIXPCSCRIPTABLE
    1458                 :     NS_DECL_NSICLASSINFO
    1459                 : 
    1460                 : 
    1461                 : public:
    1462                 :     nsXPCComponents_ID();
    1463                 :     virtual ~nsXPCComponents_ID();
    1464                 : 
    1465                 : private:
    1466                 :     static nsresult CallOrConstruct(nsIXPConnectWrappedNative *wrapper,
    1467                 :                                     JSContext * cx, JSObject * obj,
    1468                 :                                     PRUint32 argc, jsval * argv,
    1469                 :                                     jsval * vp, bool *_retval);
    1470                 : };
    1471                 : 
    1472                 : /***************************************************************************/
    1473                 : /* void getInterfaces (out PRUint32 count, [array, size_is (count), retval]
    1474                 :                        out nsIIDPtr array); */
    1475                 : NS_IMETHODIMP
    1476            3525 : nsXPCComponents_ID::GetInterfaces(PRUint32 *aCount, nsIID * **aArray)
    1477                 : {
    1478            3525 :     const PRUint32 count = 2;
    1479            3525 :     *aCount = count;
    1480                 :     nsIID **array;
    1481            3525 :     *aArray = array = static_cast<nsIID**>(nsMemory::Alloc(count * sizeof(nsIID*)));
    1482            3525 :     if (!array)
    1483               0 :         return NS_ERROR_OUT_OF_MEMORY;
    1484                 : 
    1485            3525 :     PRUint32 index = 0;
    1486                 :     nsIID* clone;
    1487                 : #define PUSH_IID(id)                                                          \
    1488                 :     clone = static_cast<nsIID *>(nsMemory::Clone(&NS_GET_IID( id ),           \
    1489                 :                                                  sizeof(nsIID)));             \
    1490                 :     if (!clone)                                                               \
    1491                 :         goto oom;                                                             \
    1492                 :     array[index++] = clone;
    1493                 : 
    1494            3525 :     PUSH_IID(nsIXPCComponents_ID)
    1495            3525 :     PUSH_IID(nsIXPCScriptable)
    1496                 : #undef PUSH_IID
    1497                 : 
    1498            3525 :     return NS_OK;
    1499                 : oom:
    1500               0 :     while (index)
    1501               0 :         nsMemory::Free(array[--index]);
    1502               0 :     nsMemory::Free(array);
    1503               0 :     *aArray = nsnull;
    1504               0 :     return NS_ERROR_OUT_OF_MEMORY;
    1505                 : }
    1506                 : 
    1507                 : /* nsISupports getHelperForLanguage (in PRUint32 language); */
    1508                 : NS_IMETHODIMP
    1509            3525 : nsXPCComponents_ID::GetHelperForLanguage(PRUint32 language,
    1510                 :                                          nsISupports **retval)
    1511                 : {
    1512            3525 :     *retval = nsnull;
    1513            3525 :     return NS_OK;
    1514                 : }
    1515                 : 
    1516                 : /* readonly attribute string contractID; */
    1517                 : NS_IMETHODIMP
    1518               0 : nsXPCComponents_ID::GetContractID(char * *aContractID)
    1519                 : {
    1520               0 :     *aContractID = nsnull;
    1521               0 :     return NS_ERROR_NOT_AVAILABLE;
    1522                 : }
    1523                 : 
    1524                 : /* readonly attribute string classDescription; */
    1525                 : NS_IMETHODIMP
    1526               0 : nsXPCComponents_ID::GetClassDescription(char * *aClassDescription)
    1527                 : {
    1528                 :     static const char classDescription[] = "XPCComponents_ID";
    1529               0 :     *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription));
    1530               0 :     return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
    1531                 : }
    1532                 : 
    1533                 : /* readonly attribute nsCIDPtr classID; */
    1534                 : NS_IMETHODIMP
    1535               0 : nsXPCComponents_ID::GetClassID(nsCID * *aClassID)
    1536                 : {
    1537               0 :     *aClassID = nsnull;
    1538               0 :     return NS_OK;
    1539                 : }
    1540                 : 
    1541                 : /* readonly attribute PRUint32 implementationLanguage; */
    1542                 : NS_IMETHODIMP
    1543               0 : nsXPCComponents_ID::GetImplementationLanguage(PRUint32 *aImplementationLanguage)
    1544                 : {
    1545               0 :     *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS;
    1546               0 :     return NS_OK;
    1547                 : }
    1548                 : 
    1549                 : /* readonly attribute PRUint32 flags; */
    1550                 : NS_IMETHODIMP
    1551            6126 : nsXPCComponents_ID::GetFlags(PRUint32 *aFlags)
    1552                 : {
    1553            6126 :     *aFlags = nsIClassInfo::THREADSAFE;
    1554            6126 :     return NS_OK;
    1555                 : }
    1556                 : 
    1557                 : /* [notxpcom] readonly attribute nsCID classIDNoAlloc; */
    1558                 : NS_IMETHODIMP
    1559               0 : nsXPCComponents_ID::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
    1560                 : {
    1561               0 :     return NS_ERROR_NOT_AVAILABLE;
    1562                 : }
    1563                 : 
    1564            3458 : nsXPCComponents_ID::nsXPCComponents_ID()
    1565                 : {
    1566            3458 : }
    1567                 : 
    1568            6912 : nsXPCComponents_ID::~nsXPCComponents_ID()
    1569                 : {
    1570                 :     // empty
    1571           13824 : }
    1572                 : 
    1573           49621 : NS_INTERFACE_MAP_BEGIN(nsXPCComponents_ID)
    1574           49621 :   NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_ID)
    1575           46096 :   NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
    1576           35521 :   NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
    1577           28471 :   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_ID)
    1578           22586 : NS_INTERFACE_MAP_END_THREADSAFE
    1579                 : 
    1580           43428 : NS_IMPL_THREADSAFE_ADDREF(nsXPCComponents_ID)
    1581           43426 : NS_IMPL_THREADSAFE_RELEASE(nsXPCComponents_ID)
    1582                 : 
    1583                 : // The nsIXPCScriptable map declaration that will generate stubs for us...
    1584                 : #define XPC_MAP_CLASSNAME           nsXPCComponents_ID
    1585                 : #define XPC_MAP_QUOTED_CLASSNAME   "nsXPCComponents_ID"
    1586                 : #define                             XPC_MAP_WANT_CALL
    1587                 : #define                             XPC_MAP_WANT_CONSTRUCT
    1588                 : #define                             XPC_MAP_WANT_HASINSTANCE
    1589                 : #define XPC_MAP_FLAGS               nsIXPCScriptable::ALLOW_PROP_MODS_DURING_RESOLVE
    1590                 : #include "xpc_map_end.h" /* This will #undef the above */
    1591                 : 
    1592                 : 
    1593                 : /* bool call (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in PRUint32 argc, in JSValPtr argv, in JSValPtr vp); */
    1594                 : NS_IMETHODIMP
    1595            3257 : nsXPCComponents_ID::Call(nsIXPConnectWrappedNative *wrapper, JSContext * cx, JSObject * obj, PRUint32 argc, jsval * argv, jsval * vp, bool *_retval)
    1596                 : {
    1597            3257 :     return CallOrConstruct(wrapper, cx, obj, argc, argv, vp, _retval);
    1598                 : 
    1599                 : }
    1600                 : 
    1601                 : /* bool construct (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in PRUint32 argc, in JSValPtr argv, in JSValPtr vp); */
    1602                 : NS_IMETHODIMP
    1603               0 : nsXPCComponents_ID::Construct(nsIXPConnectWrappedNative *wrapper, JSContext * cx, JSObject * obj, PRUint32 argc, jsval * argv, jsval * vp, bool *_retval)
    1604                 : {
    1605               0 :     return CallOrConstruct(wrapper, cx, obj, argc, argv, vp, _retval);
    1606                 : }
    1607                 : 
    1608                 : // static
    1609                 : nsresult
    1610            3257 : nsXPCComponents_ID::CallOrConstruct(nsIXPConnectWrappedNative *wrapper,
    1611                 :                                     JSContext * cx, JSObject * obj,
    1612                 :                                     PRUint32 argc, jsval * argv,
    1613                 :                                     jsval * vp, bool *_retval)
    1614                 : {
    1615                 :     // make sure we have at least one arg
    1616                 : 
    1617            3257 :     if (!argc)
    1618               0 :         return ThrowAndFail(NS_ERROR_XPC_NOT_ENOUGH_ARGS, cx, _retval);
    1619                 : 
    1620            6514 :     XPCCallContext ccx(JS_CALLER, cx);
    1621            3257 :     if (!ccx.IsValid())
    1622               0 :         return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
    1623                 : 
    1624            3257 :     XPCContext* xpcc = ccx.GetXPCContext();
    1625                 : 
    1626                 :     // Do the security check if necessary
    1627                 : 
    1628                 :     nsIXPCSecurityManager* sm =
    1629            3257 :             xpcc->GetAppropriateSecurityManager(nsIXPCSecurityManager::HOOK_CREATE_INSTANCE);
    1630            3257 :     if (sm && NS_FAILED(sm->CanCreateInstance(cx, nsJSID::GetCID()))) {
    1631                 :         // the security manager vetoed. It should have set an exception.
    1632               0 :         *_retval = false;
    1633               0 :         return NS_OK;
    1634                 :     }
    1635                 : 
    1636                 :     // convert the first argument into a string and see if it looks like an id
    1637                 : 
    1638                 :     JSString* jsstr;
    1639            6514 :     JSAutoByteString bytes;
    1640                 :     nsID id;
    1641                 : 
    1642            9771 :     if (!(jsstr = JS_ValueToString(cx, argv[0])) ||
    1643            3257 :         !bytes.encode(cx, jsstr) ||
    1644            3257 :         !id.Parse(bytes.ptr())) {
    1645               0 :         return ThrowAndFail(NS_ERROR_XPC_BAD_ID_STRING, cx, _retval);
    1646                 :     }
    1647                 : 
    1648                 :     // make the new object and return it.
    1649                 : 
    1650            3257 :     JSObject* newobj = xpc_NewIDObject(cx, obj, id);
    1651                 : 
    1652            3257 :     if (vp)
    1653            3257 :         *vp = OBJECT_TO_JSVAL(newobj);
    1654                 : 
    1655            3257 :     return NS_OK;
    1656                 : }
    1657                 : 
    1658                 : /* bool hasInstance (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval val, out bool bp); */
    1659                 : NS_IMETHODIMP
    1660            2628 : nsXPCComponents_ID::HasInstance(nsIXPConnectWrappedNative *wrapper,
    1661                 :                                 JSContext * cx, JSObject * obj,
    1662                 :                                 const jsval &val, bool *bp, bool *_retval)
    1663                 : {
    1664            2628 :     if (bp)
    1665            2628 :         *bp = JSValIsInterfaceOfType(cx, val, NS_GET_IID(nsIJSID));
    1666            2628 :     return NS_OK;
    1667                 : }
    1668                 : 
    1669                 : /***************************************************************************/
    1670                 : // JavaScript Constructor for nsIXPCException objects (Components.Exception)
    1671                 : 
    1672                 : class nsXPCComponents_Exception :
    1673                 :   public nsIXPCComponents_Exception,
    1674                 :   public nsIXPCScriptable,
    1675                 :   public nsIClassInfo
    1676                 : {
    1677                 : public:
    1678                 :     // all the interface method declarations...
    1679                 :     NS_DECL_ISUPPORTS
    1680                 :     NS_DECL_NSIXPCCOMPONENTS_EXCEPTION
    1681                 :     NS_DECL_NSIXPCSCRIPTABLE
    1682                 :     NS_DECL_NSICLASSINFO
    1683                 : 
    1684                 : 
    1685                 : public:
    1686                 :     nsXPCComponents_Exception();
    1687                 :     virtual ~nsXPCComponents_Exception();
    1688                 : 
    1689                 : private:
    1690                 :     static nsresult CallOrConstruct(nsIXPConnectWrappedNative *wrapper,
    1691                 :                                     JSContext * cx, JSObject * obj,
    1692                 :                                     PRUint32 argc, jsval * argv,
    1693                 :                                     jsval * vp, bool *_retval);
    1694                 : };
    1695                 : 
    1696                 : /***************************************************************************/
    1697                 : /* void getInterfaces (out PRUint32 count, [array, size_is (count), retval]
    1698                 :                        out nsIIDPtr array); */
    1699                 : NS_IMETHODIMP
    1700             372 : nsXPCComponents_Exception::GetInterfaces(PRUint32 *aCount, nsIID * **aArray)
    1701                 : {
    1702             372 :     const PRUint32 count = 2;
    1703             372 :     *aCount = count;
    1704                 :     nsIID **array;
    1705             372 :     *aArray = array = static_cast<nsIID**>(nsMemory::Alloc(count * sizeof(nsIID*)));
    1706             372 :     if (!array)
    1707               0 :         return NS_ERROR_OUT_OF_MEMORY;
    1708                 : 
    1709             372 :     PRUint32 index = 0;
    1710                 :     nsIID* clone;
    1711                 : #define PUSH_IID(id)                                                          \
    1712                 :     clone = static_cast<nsIID *>(nsMemory::Clone(&NS_GET_IID( id ),           \
    1713                 :                                                  sizeof(nsIID)));             \
    1714                 :     if (!clone)                                                               \
    1715                 :         goto oom;                                                             \
    1716                 :     array[index++] = clone;
    1717                 : 
    1718             372 :     PUSH_IID(nsIXPCComponents_Exception)
    1719             372 :     PUSH_IID(nsIXPCScriptable)
    1720                 : #undef PUSH_IID
    1721                 : 
    1722             372 :     return NS_OK;
    1723                 : oom:
    1724               0 :     while (index)
    1725               0 :         nsMemory::Free(array[--index]);
    1726               0 :     nsMemory::Free(array);
    1727               0 :     *aArray = nsnull;
    1728               0 :     return NS_ERROR_OUT_OF_MEMORY;
    1729                 : }
    1730                 : 
    1731                 : /* nsISupports getHelperForLanguage (in PRUint32 language); */
    1732                 : NS_IMETHODIMP
    1733             372 : nsXPCComponents_Exception::GetHelperForLanguage(PRUint32 language,
    1734                 :                                                 nsISupports **retval)
    1735                 : {
    1736             372 :     *retval = nsnull;
    1737             372 :     return NS_OK;
    1738                 : }
    1739                 : 
    1740                 : /* readonly attribute string contractID; */
    1741                 : NS_IMETHODIMP
    1742               0 : nsXPCComponents_Exception::GetContractID(char * *aContractID)
    1743                 : {
    1744               0 :     *aContractID = nsnull;
    1745               0 :     return NS_ERROR_NOT_AVAILABLE;
    1746                 : }
    1747                 : 
    1748                 : /* readonly attribute string classDescription; */
    1749                 : NS_IMETHODIMP
    1750               0 : nsXPCComponents_Exception::GetClassDescription(char * *aClassDescription)
    1751                 : {
    1752                 :     static const char classDescription[] = "XPCComponents_Exception";
    1753               0 :     *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription));
    1754               0 :     return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
    1755                 : }
    1756                 : 
    1757                 : /* readonly attribute nsCIDPtr classID; */
    1758                 : NS_IMETHODIMP
    1759               0 : nsXPCComponents_Exception::GetClassID(nsCID * *aClassID)
    1760                 : {
    1761               0 :     *aClassID = nsnull;
    1762               0 :     return NS_OK;
    1763                 : }
    1764                 : 
    1765                 : /* readonly attribute PRUint32 implementationLanguage; */
    1766                 : NS_IMETHODIMP
    1767               0 : nsXPCComponents_Exception::GetImplementationLanguage(PRUint32 *aImplementationLanguage)
    1768                 : {
    1769               0 :     *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS;
    1770               0 :     return NS_OK;
    1771                 : }
    1772                 : 
    1773                 : /* readonly attribute PRUint32 flags; */
    1774                 : NS_IMETHODIMP
    1775             734 : nsXPCComponents_Exception::GetFlags(PRUint32 *aFlags)
    1776                 : {
    1777             734 :     *aFlags = nsIClassInfo::THREADSAFE;
    1778             734 :     return NS_OK;
    1779                 : }
    1780                 : 
    1781                 : /* [notxpcom] readonly attribute nsCID classIDNoAlloc; */
    1782                 : NS_IMETHODIMP
    1783               0 : nsXPCComponents_Exception::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
    1784                 : {
    1785               0 :     return NS_ERROR_NOT_AVAILABLE;
    1786                 : }
    1787                 : 
    1788             361 : nsXPCComponents_Exception::nsXPCComponents_Exception()
    1789                 : {
    1790             361 : }
    1791                 : 
    1792             722 : nsXPCComponents_Exception::~nsXPCComponents_Exception()
    1793                 : {
    1794                 :     // empty
    1795            1444 : }
    1796                 : 
    1797            4974 : NS_INTERFACE_MAP_BEGIN(nsXPCComponents_Exception)
    1798            4974 :   NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_Exception)
    1799            4602 :   NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
    1800            3486 :   NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
    1801            2742 :   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_Exception)
    1802            2296 : NS_INTERFACE_MAP_END_THREADSAFE
    1803                 : 
    1804            4229 : NS_IMPL_THREADSAFE_ADDREF(nsXPCComponents_Exception)
    1805            4229 : NS_IMPL_THREADSAFE_RELEASE(nsXPCComponents_Exception)
    1806                 : 
    1807                 : // The nsIXPCScriptable map declaration that will generate stubs for us...
    1808                 : #define XPC_MAP_CLASSNAME           nsXPCComponents_Exception
    1809                 : #define XPC_MAP_QUOTED_CLASSNAME   "nsXPCComponents_Exception"
    1810                 : #define                             XPC_MAP_WANT_CALL
    1811                 : #define                             XPC_MAP_WANT_CONSTRUCT
    1812                 : #define                             XPC_MAP_WANT_HASINSTANCE
    1813                 : #define XPC_MAP_FLAGS               nsIXPCScriptable::ALLOW_PROP_MODS_DURING_RESOLVE
    1814                 : #include "xpc_map_end.h" /* This will #undef the above */
    1815                 : 
    1816                 : 
    1817                 : /* bool call (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in PRUint32 argc, in JSValPtr argv, in JSValPtr vp); */
    1818                 : NS_IMETHODIMP
    1819              96 : nsXPCComponents_Exception::Call(nsIXPConnectWrappedNative *wrapper, JSContext * cx, JSObject * obj, PRUint32 argc, jsval * argv, jsval * vp, bool *_retval)
    1820                 : {
    1821              96 :     return CallOrConstruct(wrapper, cx, obj, argc, argv, vp, _retval);
    1822                 : 
    1823                 : }
    1824                 : 
    1825                 : /* bool construct (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in PRUint32 argc, in JSValPtr argv, in JSValPtr vp); */
    1826                 : NS_IMETHODIMP
    1827              12 : nsXPCComponents_Exception::Construct(nsIXPConnectWrappedNative *wrapper, JSContext * cx, JSObject * obj, PRUint32 argc, jsval * argv, jsval * vp, bool *_retval)
    1828                 : {
    1829              12 :     return CallOrConstruct(wrapper, cx, obj, argc, argv, vp, _retval);
    1830                 : }
    1831                 : 
    1832                 : // static
    1833                 : nsresult
    1834             108 : nsXPCComponents_Exception::CallOrConstruct(nsIXPConnectWrappedNative *wrapper,
    1835                 :                                            JSContext * cx, JSObject * obj,
    1836                 :                                            PRUint32 argc, jsval * argv,
    1837                 :                                            jsval * vp, bool *_retval)
    1838                 : {
    1839             216 :     XPCCallContext ccx(JS_CALLER, cx);
    1840             108 :     if (!ccx.IsValid())
    1841               0 :         return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
    1842                 : 
    1843             108 :     nsXPConnect* xpc = ccx.GetXPConnect();
    1844             108 :     XPCContext* xpcc = ccx.GetXPCContext();
    1845                 : 
    1846                 :     // Do the security check if necessary
    1847                 : 
    1848                 :     nsIXPCSecurityManager* sm =
    1849             108 :             xpcc->GetAppropriateSecurityManager(nsIXPCSecurityManager::HOOK_CREATE_INSTANCE);
    1850             108 :     if (sm && NS_FAILED(sm->CanCreateInstance(cx, nsXPCException::GetCID()))) {
    1851                 :         // the security manager vetoed. It should have set an exception.
    1852               0 :         *_retval = false;
    1853               0 :         return NS_OK;
    1854                 :     }
    1855                 : 
    1856                 :     // initialization params for the exception object we will create
    1857             108 :     const char*             eMsg = "exception";
    1858             216 :     JSAutoByteString        eMsgBytes;
    1859             108 :     nsresult                eResult = NS_ERROR_FAILURE;
    1860             216 :     nsCOMPtr<nsIStackFrame> eStack;
    1861             216 :     nsCOMPtr<nsISupports>   eData;
    1862                 : 
    1863                 :     // all params are optional - grab any passed in
    1864             108 :     switch (argc) {
    1865                 :         default:    // more than 4 - ignore extra
    1866                 :             // ...fall through...
    1867                 :         case 4:     // argv[3] is object for eData
    1868               3 :             if (JSVAL_IS_NULL(argv[3])) {
    1869                 :                 // do nothing, leave eData as null
    1870                 :             } else {
    1871               0 :                 if (JSVAL_IS_PRIMITIVE(argv[3]) ||
    1872               0 :                     NS_FAILED(xpc->WrapJS(cx, JSVAL_TO_OBJECT(argv[3]),
    1873                 :                                           NS_GET_IID(nsISupports),
    1874                 :                                           (void**)getter_AddRefs(eData))))
    1875               0 :                     return ThrowAndFail(NS_ERROR_XPC_BAD_CONVERT_JS, cx, _retval);
    1876                 :             }
    1877                 :             // ...fall through...
    1878                 :         case 3:     // argv[2] is object for eStack
    1879              10 :             if (JSVAL_IS_NULL(argv[2])) {
    1880                 :                 // do nothing, leave eStack as null
    1881                 :             } else {
    1882              40 :                 if (JSVAL_IS_PRIMITIVE(argv[2]) ||
    1883              30 :                     NS_FAILED(xpc->WrapJS(cx, JSVAL_TO_OBJECT(argv[2]),
    1884                 :                                           NS_GET_IID(nsIStackFrame),
    1885                 :                                           (void**)getter_AddRefs(eStack))))
    1886               0 :                     return ThrowAndFail(NS_ERROR_XPC_BAD_CONVERT_JS, cx, _retval);
    1887                 :             }
    1888                 :             // fall through...
    1889                 :         case 2:     // argv[1] is nsresult for eResult
    1890             108 :             if (!JS_ValueToECMAInt32(cx, argv[1], (int32_t*) &eResult))
    1891               0 :                 return ThrowAndFail(NS_ERROR_XPC_BAD_CONVERT_JS, cx, _retval);
    1892                 :             // ...fall through...
    1893                 :         case 1:     // argv[0] is string for eMsg
    1894                 :             {
    1895             108 :                 JSString* str = JS_ValueToString(cx, argv[0]);
    1896             108 :                 if (!str || !(eMsg = eMsgBytes.encode(cx, str)))
    1897               0 :                     return ThrowAndFail(NS_ERROR_XPC_BAD_CONVERT_JS, cx, _retval);
    1898                 :             }
    1899                 :             // ...fall through...
    1900                 :         case 0: // this case required so that 'default' does not include zero.
    1901                 :             ;   // -- do nothing --
    1902                 :     }
    1903                 : 
    1904             216 :     nsCOMPtr<nsIException> e;
    1905             108 :     nsXPCException::NewException(eMsg, eResult, eStack, eData, getter_AddRefs(e));
    1906             108 :     if (!e)
    1907               0 :         return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
    1908                 : 
    1909             216 :     nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
    1910             108 :     JSObject* newObj = nsnull;
    1911                 : 
    1912             432 :     if (NS_FAILED(xpc->WrapNative(cx, obj, e, NS_GET_IID(nsIXPCException),
    1913             108 :                                   getter_AddRefs(holder))) || !holder ||
    1914             216 :         NS_FAILED(holder->GetJSObject(&newObj)) || !newObj) {
    1915               0 :         return ThrowAndFail(NS_ERROR_XPC_CANT_CREATE_WN, cx, _retval);
    1916                 :     }
    1917                 : 
    1918             108 :     if (vp)
    1919             108 :         *vp = OBJECT_TO_JSVAL(newObj);
    1920                 : 
    1921             108 :     return NS_OK;
    1922                 : }
    1923                 : 
    1924                 : /* bool hasInstance (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval val, out bool bp); */
    1925                 : NS_IMETHODIMP
    1926               0 : nsXPCComponents_Exception::HasInstance(nsIXPConnectWrappedNative *wrapper,
    1927                 :                                        JSContext * cx, JSObject * obj,
    1928                 :                                        const jsval &val, bool *bp,
    1929                 :                                        bool *_retval)
    1930                 : {
    1931               0 :     if (bp)
    1932               0 :         *bp = JSValIsInterfaceOfType(cx, val, NS_GET_IID(nsIException));
    1933               0 :     return NS_OK;
    1934                 : }
    1935                 : 
    1936                 : /***************************************************************************/
    1937                 : // This class is for the thing returned by "new Component.Constructor".
    1938                 : 
    1939                 : // XXXjband we use this CID for security check, but security system can't see
    1940                 : // it since it has no registed factory. Security really kicks in when we try
    1941                 : // to build a wrapper around an instance.
    1942                 : 
    1943                 : // {B4A95150-E25A-11d3-8F61-0010A4E73D9A}
    1944                 : #define NS_XPCCONSTRUCTOR_CID                                                 \
    1945                 : { 0xb4a95150, 0xe25a, 0x11d3,                                                 \
    1946                 :     { 0x8f, 0x61, 0x0, 0x10, 0xa4, 0xe7, 0x3d, 0x9a } }
    1947                 : 
    1948                 : class nsXPCConstructor :
    1949                 :   public nsIXPCConstructor,
    1950                 :   public nsIXPCScriptable,
    1951                 :   public nsIClassInfo
    1952                 : {
    1953                 : public:
    1954            4556 :     NS_DEFINE_STATIC_CID_ACCESSOR(NS_XPCCONSTRUCTOR_CID)
    1955                 : public:
    1956                 :     // all the interface method declarations...
    1957                 :     NS_DECL_ISUPPORTS
    1958                 :     NS_DECL_NSIXPCCONSTRUCTOR
    1959                 :     NS_DECL_NSIXPCSCRIPTABLE
    1960                 :     NS_DECL_NSICLASSINFO
    1961                 : 
    1962                 : public:
    1963                 :     nsXPCConstructor(); // not implemented
    1964                 :     nsXPCConstructor(nsIJSCID* aClassID,
    1965                 :                      nsIJSIID* aInterfaceID,
    1966                 :                      const char* aInitializer);
    1967                 :     virtual ~nsXPCConstructor();
    1968                 : 
    1969                 : private:
    1970                 :     nsresult CallOrConstruct(nsIXPConnectWrappedNative *wrapper,
    1971                 :                              JSContext * cx, JSObject * obj,
    1972                 :                              PRUint32 argc, jsval * argv,
    1973                 :                              jsval * vp, bool *_retval);
    1974                 : private:
    1975                 :     nsIJSCID* mClassID;
    1976                 :     nsIJSIID* mInterfaceID;
    1977                 :     char*     mInitializer;
    1978                 : };
    1979                 : 
    1980                 : /***************************************************************************/
    1981                 : /* void getInterfaces (out PRUint32 count, [array, size_is (count), retval]
    1982                 :                        out nsIIDPtr array); */
    1983                 : NS_IMETHODIMP
    1984            4556 : nsXPCConstructor::GetInterfaces(PRUint32 *aCount, nsIID * **aArray)
    1985                 : {
    1986            4556 :     const PRUint32 count = 2;
    1987            4556 :     *aCount = count;
    1988                 :     nsIID **array;
    1989            4556 :     *aArray = array = static_cast<nsIID**>(nsMemory::Alloc(count * sizeof(nsIID*)));
    1990            4556 :     if (!array)
    1991               0 :         return NS_ERROR_OUT_OF_MEMORY;
    1992                 : 
    1993            4556 :     PRUint32 index = 0;
    1994                 :     nsIID* clone;
    1995                 : #define PUSH_IID(id)                                                          \
    1996                 :     clone = static_cast<nsIID *>(nsMemory::Clone(&NS_GET_IID( id ),           \
    1997                 :                                                  sizeof(nsIID)));             \
    1998                 :     if (!clone)                                                               \
    1999                 :         goto oom;                                                             \
    2000                 :     array[index++] = clone;
    2001                 : 
    2002            4556 :     PUSH_IID(nsIXPCConstructor)
    2003            4556 :     PUSH_IID(nsIXPCScriptable)
    2004                 : #undef PUSH_IID
    2005                 : 
    2006            4556 :     return NS_OK;
    2007                 : oom:
    2008               0 :     while (index)
    2009               0 :         nsMemory::Free(array[--index]);
    2010               0 :     nsMemory::Free(array);
    2011               0 :     *aArray = nsnull;
    2012               0 :     return NS_ERROR_OUT_OF_MEMORY;
    2013                 : }
    2014                 : 
    2015                 : /* nsISupports getHelperForLanguage (in PRUint32 language); */
    2016                 : NS_IMETHODIMP
    2017            4556 : nsXPCConstructor::GetHelperForLanguage(PRUint32 language,
    2018                 :                                        nsISupports **retval)
    2019                 : {
    2020            4556 :     *retval = nsnull;
    2021            4556 :     return NS_OK;
    2022                 : }
    2023                 : 
    2024                 : /* readonly attribute string contractID; */
    2025                 : NS_IMETHODIMP
    2026               0 : nsXPCConstructor::GetContractID(char * *aContractID)
    2027                 : {
    2028               0 :     *aContractID = nsnull;
    2029               0 :     return NS_ERROR_NOT_AVAILABLE;
    2030                 : }
    2031                 : 
    2032                 : /* readonly attribute string classDescription; */
    2033                 : NS_IMETHODIMP
    2034               0 : nsXPCConstructor::GetClassDescription(char * *aClassDescription)
    2035                 : {
    2036                 :     static const char classDescription[] = "XPCConstructor";
    2037               0 :     *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription));
    2038               0 :     return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
    2039                 : }
    2040                 : 
    2041                 : /* readonly attribute nsCIDPtr classID; */
    2042                 : NS_IMETHODIMP
    2043               0 : nsXPCConstructor::GetClassID(nsCID * *aClassID)
    2044                 : {
    2045               0 :     *aClassID = nsnull;
    2046               0 :     return NS_OK;
    2047                 : }
    2048                 : 
    2049                 : /* readonly attribute PRUint32 implementationLanguage; */
    2050                 : NS_IMETHODIMP
    2051               0 : nsXPCConstructor::GetImplementationLanguage(PRUint32 *aImplementationLanguage)
    2052                 : {
    2053               0 :     *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS;
    2054               0 :     return NS_OK;
    2055                 : }
    2056                 : 
    2057                 : /* readonly attribute PRUint32 flags; */
    2058                 : NS_IMETHODIMP
    2059            4556 : nsXPCConstructor::GetFlags(PRUint32 *aFlags)
    2060                 : {
    2061            4556 :     *aFlags = nsIClassInfo::THREADSAFE;
    2062            4556 :     return NS_OK;
    2063                 : }
    2064                 : 
    2065                 : /* [notxpcom] readonly attribute nsCID classIDNoAlloc; */
    2066                 : NS_IMETHODIMP
    2067               0 : nsXPCConstructor::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
    2068                 : {
    2069               0 :     return NS_ERROR_NOT_AVAILABLE;
    2070                 : }
    2071                 : 
    2072            4556 : nsXPCConstructor::nsXPCConstructor(nsIJSCID* aClassID,
    2073                 :                                    nsIJSIID* aInterfaceID,
    2074            4556 :                                    const char* aInitializer)
    2075                 : {
    2076            4556 :     NS_IF_ADDREF(mClassID = aClassID);
    2077            4556 :     NS_IF_ADDREF(mInterfaceID = aInterfaceID);
    2078                 :     mInitializer = aInitializer ?
    2079            3494 :         (char*) nsMemory::Clone(aInitializer, strlen(aInitializer)+1) :
    2080            8050 :         nsnull;
    2081            4556 : }
    2082                 : 
    2083            9112 : nsXPCConstructor::~nsXPCConstructor()
    2084                 : {
    2085            4556 :     NS_IF_RELEASE(mClassID);
    2086            4556 :     NS_IF_RELEASE(mInterfaceID);
    2087            4556 :     if (mInitializer)
    2088            3494 :         nsMemory::Free(mInitializer);
    2089           18224 : }
    2090                 : 
    2091                 : /* readonly attribute nsIJSCID classID; */
    2092                 : NS_IMETHODIMP
    2093               0 : nsXPCConstructor::GetClassID(nsIJSCID * *aClassID)
    2094                 : {
    2095               0 :     NS_IF_ADDREF(*aClassID = mClassID);
    2096               0 :     return NS_OK;
    2097                 : }
    2098                 : 
    2099                 : /* readonly attribute nsIJSIID interfaceID; */
    2100                 : NS_IMETHODIMP
    2101               0 : nsXPCConstructor::GetInterfaceID(nsIJSIID * *aInterfaceID)
    2102                 : {
    2103               0 :     NS_IF_ADDREF(*aInterfaceID = mInterfaceID);
    2104               0 :     return NS_OK;
    2105                 : }
    2106                 : 
    2107                 : /* readonly attribute string initializer; */
    2108                 : NS_IMETHODIMP
    2109               0 : nsXPCConstructor::GetInitializer(char * *aInitializer)
    2110                 : {
    2111               0 :     XPC_STRING_GETTER_BODY(aInitializer, mInitializer);
    2112                 : }
    2113                 : 
    2114           59228 : NS_INTERFACE_MAP_BEGIN(nsXPCConstructor)
    2115           59228 :   NS_INTERFACE_MAP_ENTRY(nsIXPCConstructor)
    2116           50116 :   NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
    2117           36448 :   NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
    2118           27336 :   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCConstructor)
    2119           22780 : NS_INTERFACE_MAP_END_THREADSAFE
    2120                 : 
    2121           50116 : NS_IMPL_THREADSAFE_ADDREF(nsXPCConstructor)
    2122           50116 : NS_IMPL_THREADSAFE_RELEASE(nsXPCConstructor)
    2123                 : 
    2124                 : // The nsIXPCScriptable map declaration that will generate stubs for us...
    2125                 : #define XPC_MAP_CLASSNAME           nsXPCConstructor
    2126                 : #define XPC_MAP_QUOTED_CLASSNAME   "nsXPCConstructor"
    2127                 : #define                             XPC_MAP_WANT_CALL
    2128                 : #define                             XPC_MAP_WANT_CONSTRUCT
    2129                 : #define XPC_MAP_FLAGS               0
    2130                 : #include "xpc_map_end.h" /* This will #undef the above */
    2131                 : 
    2132                 : 
    2133                 : /* bool call (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in PRUint32 argc, in JSValPtr argv, in JSValPtr vp); */
    2134                 : NS_IMETHODIMP
    2135              29 : nsXPCConstructor::Call(nsIXPConnectWrappedNative *wrapper, JSContext * cx, JSObject * obj, PRUint32 argc, jsval * argv, jsval * vp, bool *_retval)
    2136                 : {
    2137              29 :     return CallOrConstruct(wrapper, cx, obj, argc, argv, vp, _retval);
    2138                 : 
    2139                 : }
    2140                 : 
    2141                 : /* bool construct (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in PRUint32 argc, in JSValPtr argv, in JSValPtr vp); */
    2142                 : NS_IMETHODIMP
    2143           47121 : nsXPCConstructor::Construct(nsIXPConnectWrappedNative *wrapper, JSContext * cx, JSObject * obj, PRUint32 argc, jsval * argv, jsval * vp, bool *_retval)
    2144                 : {
    2145           47121 :     return CallOrConstruct(wrapper, cx, obj, argc, argv, vp, _retval);
    2146                 : }
    2147                 : 
    2148                 : // static
    2149                 : nsresult
    2150           47150 : nsXPCConstructor::CallOrConstruct(nsIXPConnectWrappedNative *wrapper,
    2151                 :                                   JSContext * cx, JSObject * obj,
    2152                 :                                   PRUint32 argc, jsval * argv,
    2153                 :                                   jsval * vp, bool *_retval)
    2154                 : {
    2155           94300 :     XPCCallContext ccx(JS_CALLER, cx);
    2156           47150 :     if (!ccx.IsValid())
    2157               0 :         return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
    2158                 : 
    2159           47150 :     nsXPConnect* xpc = ccx.GetXPConnect();
    2160                 : 
    2161                 :     // security check not required because we are going to call through the
    2162                 :     // code which is reflected into JS which will do that for us later.
    2163                 : 
    2164           94300 :     nsCOMPtr<nsIXPConnectJSObjectHolder> cidHolder;
    2165           94300 :     nsCOMPtr<nsIXPConnectJSObjectHolder> iidHolder;
    2166                 :     JSObject* cidObj;
    2167                 :     JSObject* iidObj;
    2168                 : 
    2169          471500 :     if (NS_FAILED(xpc->WrapNative(cx, obj, mClassID, NS_GET_IID(nsIJSCID),
    2170           47150 :                                   getter_AddRefs(cidHolder))) || !cidHolder ||
    2171           94300 :         NS_FAILED(cidHolder->GetJSObject(&cidObj)) || !cidObj ||
    2172          141450 :         NS_FAILED(xpc->WrapNative(cx, obj, mInterfaceID, NS_GET_IID(nsIJSIID),
    2173           47150 :                                   getter_AddRefs(iidHolder))) || !iidHolder ||
    2174           94300 :         NS_FAILED(iidHolder->GetJSObject(&iidObj)) || !iidObj) {
    2175               0 :         return ThrowAndFail(NS_ERROR_XPC_CANT_CREATE_WN, cx, _retval);
    2176                 :     }
    2177                 : 
    2178           47150 :     jsval ctorArgs[1] = {OBJECT_TO_JSVAL(iidObj)};
    2179                 :     jsval val;
    2180                 : 
    2181           94300 :     if (!JS_CallFunctionName(cx, cidObj, "createInstance", 1, ctorArgs, &val) ||
    2182           47150 :         JSVAL_IS_PRIMITIVE(val)) {
    2183                 :         // createInstance will have thrown an exception
    2184               0 :         *_retval = false;
    2185               0 :         return NS_OK;
    2186                 :     }
    2187                 : 
    2188                 :     // root the result
    2189           47150 :     if (vp)
    2190           47150 :         *vp = val;
    2191                 : 
    2192                 :     // call initializer method if supplied
    2193           47150 :     if (mInitializer) {
    2194           27182 :         JSObject* newObj = JSVAL_TO_OBJECT(val);
    2195                 :         jsval fun;
    2196                 :         jsval ignored;
    2197                 : 
    2198                 :         // first check existence of function property for better error reporting
    2199           54364 :         if (!JS_GetProperty(cx, newObj, mInitializer, &fun) ||
    2200           27182 :             JSVAL_IS_PRIMITIVE(fun)) {
    2201               0 :             return ThrowAndFail(NS_ERROR_XPC_BAD_INITIALIZER_NAME, cx, _retval);
    2202                 :         }
    2203                 : 
    2204           27182 :         if (!JS_CallFunctionValue(cx, newObj, fun, argc, argv, &ignored)) {
    2205                 :             // function should have thrown an exception
    2206              28 :             *_retval = false;
    2207              28 :             return NS_OK;
    2208                 :         }
    2209                 :     }
    2210                 : 
    2211           47122 :     return NS_OK;
    2212                 : }
    2213                 : 
    2214                 : /*******************************************************/
    2215                 : // JavaScript Constructor for nsIXPCConstructor objects (Components.Constructor)
    2216                 : 
    2217                 : class nsXPCComponents_Constructor :
    2218                 :   public nsIXPCComponents_Constructor,
    2219                 :   public nsIXPCScriptable,
    2220                 :   public nsIClassInfo
    2221                 : {
    2222                 : public:
    2223                 :     // all the interface method declarations...
    2224                 :     NS_DECL_ISUPPORTS
    2225                 :     NS_DECL_NSIXPCCOMPONENTS_CONSTRUCTOR
    2226                 :     NS_DECL_NSIXPCSCRIPTABLE
    2227                 :     NS_DECL_NSICLASSINFO
    2228                 : 
    2229                 : public:
    2230                 :     nsXPCComponents_Constructor();
    2231                 :     virtual ~nsXPCComponents_Constructor();
    2232                 : 
    2233                 : private:
    2234                 :     static nsresult CallOrConstruct(nsIXPConnectWrappedNative *wrapper,
    2235                 :                                     JSContext * cx, JSObject * obj,
    2236                 :                                     PRUint32 argc, jsval * argv,
    2237                 :                                     jsval * vp, bool *_retval);
    2238                 : };
    2239                 : 
    2240                 : /***************************************************************************/
    2241                 : /* void getInterfaces (out PRUint32 count, [array, size_is (count), retval]
    2242                 :                        out nsIIDPtr array); */
    2243                 : NS_IMETHODIMP
    2244            1078 : nsXPCComponents_Constructor::GetInterfaces(PRUint32 *aCount, nsIID * **aArray)
    2245                 : {
    2246            1078 :     const PRUint32 count = 2;
    2247            1078 :     *aCount = count;
    2248                 :     nsIID **array;
    2249            1078 :     *aArray = array = static_cast<nsIID**>(nsMemory::Alloc(count * sizeof(nsIID*)));
    2250            1078 :     if (!array)
    2251               0 :         return NS_ERROR_OUT_OF_MEMORY;
    2252                 : 
    2253            1078 :     PRUint32 index = 0;
    2254                 :     nsIID* clone;
    2255                 : #define PUSH_IID(id)                                                          \
    2256                 :     clone = static_cast<nsIID *>(nsMemory::Clone(&NS_GET_IID( id ),           \
    2257                 :                                                  sizeof(nsIID)));             \
    2258                 :     if (!clone)                                                               \
    2259                 :         goto oom;                                                             \
    2260                 :     array[index++] = clone;
    2261                 : 
    2262            1078 :     PUSH_IID(nsIXPCComponents_Constructor)
    2263            1078 :     PUSH_IID(nsIXPCScriptable)
    2264                 : #undef PUSH_IID
    2265                 : 
    2266            1078 :     return NS_OK;
    2267                 : oom:
    2268               0 :     while (index)
    2269               0 :         nsMemory::Free(array[--index]);
    2270               0 :     nsMemory::Free(array);
    2271               0 :     *aArray = nsnull;
    2272               0 :     return NS_ERROR_OUT_OF_MEMORY;
    2273                 : }
    2274                 : 
    2275                 : /* nsISupports getHelperForLanguage (in PRUint32 language); */
    2276                 : NS_IMETHODIMP
    2277            1078 : nsXPCComponents_Constructor::GetHelperForLanguage(PRUint32 language,
    2278                 :                                                   nsISupports **retval)
    2279                 : {
    2280            1078 :     *retval = nsnull;
    2281            1078 :     return NS_OK;
    2282                 : }
    2283                 : 
    2284                 : /* readonly attribute string contractID; */
    2285                 : NS_IMETHODIMP
    2286               0 : nsXPCComponents_Constructor::GetContractID(char * *aContractID)
    2287                 : {
    2288               0 :     *aContractID = nsnull;
    2289               0 :     return NS_ERROR_NOT_AVAILABLE;
    2290                 : }
    2291                 : 
    2292                 : /* readonly attribute string classDescription; */
    2293                 : NS_IMETHODIMP
    2294               0 : nsXPCComponents_Constructor::GetClassDescription(char * *aClassDescription)
    2295                 : {
    2296                 :     static const char classDescription[] = "XPCComponents_Constructor";
    2297               0 :     *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription));
    2298               0 :     return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
    2299                 : }
    2300                 : 
    2301                 : /* readonly attribute nsCIDPtr classID; */
    2302                 : NS_IMETHODIMP
    2303               0 : nsXPCComponents_Constructor::GetClassID(nsCID * *aClassID)
    2304                 : {
    2305               0 :     *aClassID = nsnull;
    2306               0 :     return NS_OK;
    2307                 : }
    2308                 : 
    2309                 : /* readonly attribute PRUint32 implementationLanguage; */
    2310                 : NS_IMETHODIMP
    2311               0 : nsXPCComponents_Constructor::GetImplementationLanguage(PRUint32 *aImplementationLanguage)
    2312                 : {
    2313               0 :     *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS;
    2314               0 :     return NS_OK;
    2315                 : }
    2316                 : 
    2317                 : /* readonly attribute PRUint32 flags; */
    2318                 : NS_IMETHODIMP
    2319            1542 : nsXPCComponents_Constructor::GetFlags(PRUint32 *aFlags)
    2320                 : {
    2321            1542 :     *aFlags = nsIClassInfo::THREADSAFE;
    2322            1542 :     return NS_OK;
    2323                 : }
    2324                 : 
    2325                 : /* [notxpcom] readonly attribute nsCID classIDNoAlloc; */
    2326                 : NS_IMETHODIMP
    2327               0 : nsXPCComponents_Constructor::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
    2328                 : {
    2329               0 :     return NS_ERROR_NOT_AVAILABLE;
    2330                 : }
    2331                 : 
    2332            1074 : nsXPCComponents_Constructor::nsXPCComponents_Constructor()
    2333                 : {
    2334            1074 : }
    2335                 : 
    2336            2148 : nsXPCComponents_Constructor::~nsXPCComponents_Constructor()
    2337                 : {
    2338                 :     // empty
    2339            4296 : }
    2340                 : 
    2341           15178 : NS_INTERFACE_MAP_BEGIN(nsXPCComponents_Constructor)
    2342           15178 :   NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_Constructor)
    2343           13749 :   NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
    2344           10515 :   NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
    2345            8359 :   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_Constructor)
    2346            6743 : NS_INTERFACE_MAP_END_THREADSAFE
    2347                 : 
    2348           13281 : NS_IMPL_THREADSAFE_ADDREF(nsXPCComponents_Constructor)
    2349           13281 : NS_IMPL_THREADSAFE_RELEASE(nsXPCComponents_Constructor)
    2350                 : 
    2351                 : // The nsIXPCScriptable map declaration that will generate stubs for us...
    2352                 : #define XPC_MAP_CLASSNAME           nsXPCComponents_Constructor
    2353                 : #define XPC_MAP_QUOTED_CLASSNAME   "nsXPCComponents_Constructor"
    2354                 : #define                             XPC_MAP_WANT_CALL
    2355                 : #define                             XPC_MAP_WANT_CONSTRUCT
    2356                 : #define                             XPC_MAP_WANT_HASINSTANCE
    2357                 : #define XPC_MAP_FLAGS               nsIXPCScriptable::ALLOW_PROP_MODS_DURING_RESOLVE
    2358                 : #include "xpc_map_end.h" /* This will #undef the above */
    2359                 : 
    2360                 : 
    2361                 : /* bool call (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in PRUint32 argc, in JSValPtr argv, in JSValPtr vp); */
    2362                 : NS_IMETHODIMP
    2363            4378 : nsXPCComponents_Constructor::Call(nsIXPConnectWrappedNative *wrapper, JSContext * cx, JSObject * obj, PRUint32 argc, jsval * argv, jsval * vp, bool *_retval)
    2364                 : {
    2365            4378 :     return CallOrConstruct(wrapper, cx, obj, argc, argv, vp, _retval);
    2366                 : }
    2367                 : 
    2368                 : /* bool construct (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in PRUint32 argc, in JSValPtr argv, in JSValPtr vp); */
    2369                 : NS_IMETHODIMP
    2370             178 : nsXPCComponents_Constructor::Construct(nsIXPConnectWrappedNative *wrapper, JSContext * cx, JSObject * obj, PRUint32 argc, jsval * argv, jsval * vp, bool *_retval)
    2371                 : {
    2372             178 :     return CallOrConstruct(wrapper, cx, obj, argc, argv, vp, _retval);
    2373                 : }
    2374                 : 
    2375                 : // static
    2376                 : nsresult
    2377            4556 : nsXPCComponents_Constructor::CallOrConstruct(nsIXPConnectWrappedNative *wrapper,
    2378                 :                                              JSContext * cx, JSObject * obj,
    2379                 :                                              PRUint32 argc, jsval * argv,
    2380                 :                                              jsval * vp, bool *_retval)
    2381                 : {
    2382                 :     // make sure we have at least one arg
    2383                 : 
    2384            4556 :     if (!argc)
    2385               0 :         return ThrowAndFail(NS_ERROR_XPC_NOT_ENOUGH_ARGS, cx, _retval);
    2386                 : 
    2387                 :     // get the various other object pointers we need
    2388                 : 
    2389            9112 :     XPCCallContext ccx(JS_CALLER, cx);
    2390            4556 :     if (!ccx.IsValid())
    2391               0 :         return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
    2392                 : 
    2393            4556 :     nsXPConnect* xpc = ccx.GetXPConnect();
    2394            4556 :     XPCContext* xpcc = ccx.GetXPCContext();
    2395                 :     XPCWrappedNativeScope* scope =
    2396            4556 :         XPCWrappedNativeScope::FindInJSObjectScope(ccx, obj);
    2397                 :     nsXPCComponents* comp;
    2398                 : 
    2399            4556 :     if (!xpc || !xpcc || !scope || !(comp = scope->GetComponents()))
    2400               0 :         return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
    2401                 : 
    2402                 :     // Do the security check if necessary
    2403                 : 
    2404                 :     nsIXPCSecurityManager* sm =
    2405            4556 :             xpcc->GetAppropriateSecurityManager(nsIXPCSecurityManager::HOOK_CREATE_INSTANCE);
    2406            4556 :     if (sm && NS_FAILED(sm->CanCreateInstance(cx, nsXPCConstructor::GetCID()))) {
    2407                 :         // the security manager vetoed. It should have set an exception.
    2408               0 :         *_retval = false;
    2409               0 :         return NS_OK;
    2410                 :     }
    2411                 : 
    2412                 :     // initialization params for the Constructor object we will create
    2413            9112 :     nsCOMPtr<nsIJSCID> cClassID;
    2414            9112 :     nsCOMPtr<nsIJSIID> cInterfaceID;
    2415            4556 :     const char*        cInitializer = nsnull;
    2416            9112 :     JSAutoByteString  cInitializerBytes;
    2417                 : 
    2418            4556 :     if (argc >= 3) {
    2419                 :         // argv[2] is an initializer function or property name
    2420            3494 :         JSString* str = JS_ValueToString(cx, argv[2]);
    2421            3494 :         if (!str || !(cInitializer = cInitializerBytes.encode(cx, str)))
    2422               0 :             return ThrowAndFail(NS_ERROR_XPC_BAD_CONVERT_JS, cx, _retval);
    2423                 :     }
    2424                 : 
    2425            4556 :     if (argc >= 2) {
    2426                 :         // argv[1] is an iid name string
    2427                 :         // XXXjband support passing "Components.interfaces.foo"?
    2428                 : 
    2429            9112 :         nsCOMPtr<nsIXPCComponents_Interfaces> ifaces;
    2430            9112 :         nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
    2431            4556 :         JSObject* ifacesObj = nsnull;
    2432                 : 
    2433                 :         // we do the lookup by asking the Components.interfaces object
    2434                 :         // for the property with this name - i.e. we let its caching of these
    2435                 :         // nsIJSIID objects work for us.
    2436                 : 
    2437           31892 :         if (NS_FAILED(comp->GetInterfaces(getter_AddRefs(ifaces))) ||
    2438           13668 :             NS_FAILED(xpc->WrapNative(cx, obj, ifaces,
    2439                 :                                       NS_GET_IID(nsIXPCComponents_Interfaces),
    2440            4556 :                                       getter_AddRefs(holder))) || !holder ||
    2441            9112 :             NS_FAILED(holder->GetJSObject(&ifacesObj)) || !ifacesObj) {
    2442               0 :             return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
    2443                 :         }
    2444                 : 
    2445            4556 :         JSString* str = JS_ValueToString(cx, argv[1]);
    2446                 :         jsid id;
    2447            4556 :         if (!str || !JS_ValueToId(cx, STRING_TO_JSVAL(str), &id))
    2448               0 :             return ThrowAndFail(NS_ERROR_XPC_BAD_CONVERT_JS, cx, _retval);
    2449                 : 
    2450                 :         jsval val;
    2451            4556 :         if (!JS_GetPropertyById(cx, ifacesObj, id, &val) || JSVAL_IS_PRIMITIVE(val))
    2452               0 :             return ThrowAndFail(NS_ERROR_XPC_BAD_IID, cx, _retval);
    2453                 : 
    2454            9112 :         nsCOMPtr<nsIXPConnectWrappedNative> wn;
    2455           13668 :         if (NS_FAILED(xpc->GetWrappedNativeOfJSObject(cx, JSVAL_TO_OBJECT(val),
    2456            4556 :                                                       getter_AddRefs(wn))) || !wn ||
    2457            4556 :             !(cInterfaceID = do_QueryWrappedNative(wn))) {
    2458               0 :             return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
    2459                 :         }
    2460                 :     } else {
    2461               0 :         nsCOMPtr<nsIInterfaceInfo> info;
    2462               0 :         xpc->GetInfoForIID(&NS_GET_IID(nsISupports), getter_AddRefs(info));
    2463                 : 
    2464               0 :         if (info) {
    2465                 :             cInterfaceID =
    2466               0 :                 dont_AddRef(static_cast<nsIJSIID*>(nsJSIID::NewID(info)));
    2467                 :         }
    2468               0 :         if (!cInterfaceID)
    2469               0 :             return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
    2470                 :     }
    2471                 : 
    2472                 :     // a new scope to avoid warnings about shadowed names
    2473                 :     {
    2474                 :         // argv[0] is a contractid name string
    2475                 :         // XXXjband support passing "Components.classes.foo"?
    2476                 : 
    2477                 :         // we do the lookup by asking the Components.classes object
    2478                 :         // for the property with this name - i.e. we let its caching of these
    2479                 :         // nsIJSCID objects work for us.
    2480                 : 
    2481            9112 :         nsCOMPtr<nsIXPCComponents_Classes> classes;
    2482            9112 :         nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
    2483            4556 :         JSObject* classesObj = nsnull;
    2484                 : 
    2485           31892 :         if (NS_FAILED(comp->GetClasses(getter_AddRefs(classes))) ||
    2486           13668 :             NS_FAILED(xpc->WrapNative(cx, obj, classes,
    2487                 :                                       NS_GET_IID(nsIXPCComponents_Classes),
    2488            4556 :                                       getter_AddRefs(holder))) || !holder ||
    2489            9112 :             NS_FAILED(holder->GetJSObject(&classesObj)) || !classesObj) {
    2490               0 :             return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
    2491                 :         }
    2492                 : 
    2493            4556 :         JSString* str = JS_ValueToString(cx, argv[0]);
    2494                 :         jsid id;
    2495            4556 :         if (!str || !JS_ValueToId(cx, STRING_TO_JSVAL(str), &id))
    2496               0 :             return ThrowAndFail(NS_ERROR_XPC_BAD_CONVERT_JS, cx, _retval);
    2497                 : 
    2498                 :         jsval val;
    2499            4556 :         if (!JS_GetPropertyById(cx, classesObj, id, &val) || JSVAL_IS_PRIMITIVE(val))
    2500               0 :             return ThrowAndFail(NS_ERROR_XPC_BAD_CID, cx, _retval);
    2501                 : 
    2502            9112 :         nsCOMPtr<nsIXPConnectWrappedNative> wn;
    2503           13668 :         if (NS_FAILED(xpc->GetWrappedNativeOfJSObject(cx, JSVAL_TO_OBJECT(val),
    2504            4556 :                                                       getter_AddRefs(wn))) || !wn ||
    2505            4556 :             !(cClassID = do_QueryWrappedNative(wn))) {
    2506               0 :             return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
    2507                 :         }
    2508                 :     }
    2509                 : 
    2510                 :     nsCOMPtr<nsIXPCConstructor> ctor =
    2511                 :         static_cast<nsIXPCConstructor*>
    2512           13668 :                    (new nsXPCConstructor(cClassID, cInterfaceID, cInitializer));
    2513            4556 :     if (!ctor)
    2514               0 :         return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
    2515                 : 
    2516            9112 :     nsCOMPtr<nsIXPConnectJSObjectHolder> holder2;
    2517            4556 :     JSObject* newObj = nsnull;
    2518                 : 
    2519           18224 :     if (NS_FAILED(xpc->WrapNative(cx, obj, ctor, NS_GET_IID(nsIXPCConstructor),
    2520            4556 :                                   getter_AddRefs(holder2))) || !holder2 ||
    2521            9112 :         NS_FAILED(holder2->GetJSObject(&newObj)) || !newObj) {
    2522               0 :         return ThrowAndFail(NS_ERROR_XPC_CANT_CREATE_WN, cx, _retval);
    2523                 :     }
    2524                 : 
    2525            4556 :     if (vp)
    2526            4556 :         *vp = OBJECT_TO_JSVAL(newObj);
    2527                 : 
    2528            4556 :     return NS_OK;
    2529                 : }
    2530                 : 
    2531                 : /* bool hasInstance (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval val, out bool bp); */
    2532                 : NS_IMETHODIMP
    2533               0 : nsXPCComponents_Constructor::HasInstance(nsIXPConnectWrappedNative *wrapper,
    2534                 :                                          JSContext * cx, JSObject * obj,
    2535                 :                                          const jsval &val, bool *bp,
    2536                 :                                          bool *_retval)
    2537                 : {
    2538               0 :     if (bp)
    2539               0 :         *bp = JSValIsInterfaceOfType(cx, val, NS_GET_IID(nsIXPCConstructor));
    2540               0 :     return NS_OK;
    2541                 : }
    2542                 : 
    2543                 : /***************************************************************************/
    2544                 : // Javascript constructor for the sandbox object
    2545                 : class nsXPCComponents_utils_Sandbox : public nsIXPCComponents_utils_Sandbox,
    2546                 :                                       public nsIXPCScriptable
    2547                 : {
    2548                 : public:
    2549                 :     // Aren't macros nice?
    2550                 :     NS_DECL_ISUPPORTS
    2551                 :     NS_DECL_NSIXPCCOMPONENTS_UTILS_SANDBOX
    2552                 :     NS_DECL_NSIXPCSCRIPTABLE
    2553                 : 
    2554                 : public:
    2555                 :     nsXPCComponents_utils_Sandbox();
    2556                 :     virtual ~nsXPCComponents_utils_Sandbox();
    2557                 : 
    2558                 : private:
    2559                 :     static nsresult CallOrConstruct(nsIXPConnectWrappedNative *wrapper,
    2560                 :                                     JSContext * cx, JSObject * obj,
    2561                 :                                     PRUint32 argc, jsval * argv,
    2562                 :                                     jsval * vp, bool *_retval);
    2563                 : };
    2564                 : 
    2565                 : class nsXPCComponents_Utils :
    2566                 :             public nsIXPCComponents_Utils,
    2567                 :             public nsIXPCScriptable,
    2568                 :             public nsISecurityCheckedComponent
    2569                 : {
    2570                 : public:
    2571                 :     // all the interface method declarations...
    2572                 :     NS_DECL_ISUPPORTS
    2573                 :     NS_DECL_NSIXPCSCRIPTABLE
    2574                 :     NS_DECL_NSISECURITYCHECKEDCOMPONENT
    2575                 :     NS_DECL_NSIXPCCOMPONENTS_UTILS
    2576                 : 
    2577                 : public:
    2578           11477 :     nsXPCComponents_Utils() { }
    2579           45872 :     virtual ~nsXPCComponents_Utils() { }
    2580                 : 
    2581                 : private:
    2582                 :     nsCOMPtr<nsIXPCComponents_utils_Sandbox> mSandbox;
    2583                 : };
    2584                 : 
    2585          193935 : NS_INTERFACE_MAP_BEGIN(nsXPCComponents_Utils)
    2586          193935 :   NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_Utils)
    2587          181427 :   NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
    2588          145886 :   NS_INTERFACE_MAP_ENTRY(nsISecurityCheckedComponent)
    2589          134801 :   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_Utils)
    2590           91603 : NS_INTERFACE_MAP_END_THREADSAFE
    2591                 : 
    2592          168854 : NS_IMPL_THREADSAFE_ADDREF(nsXPCComponents_Utils)
    2593          168843 : NS_IMPL_THREADSAFE_RELEASE(nsXPCComponents_Utils)
    2594                 : 
    2595                 : // The nsIXPCScriptable map declaration that will generate stubs for us...
    2596                 : #define XPC_MAP_CLASSNAME           nsXPCComponents_Utils
    2597                 : #define XPC_MAP_QUOTED_CLASSNAME   "nsXPCComponents_Utils"
    2598                 : #define XPC_MAP_FLAGS               nsIXPCScriptable::ALLOW_PROP_MODS_DURING_RESOLVE
    2599                 : #include "xpc_map_end.h" /* This will #undef the above */
    2600                 : 
    2601                 : NS_IMETHODIMP
    2602             574 : nsXPCComponents_Utils::GetSandbox(nsIXPCComponents_utils_Sandbox **aSandbox)
    2603                 : {
    2604             574 :     NS_ENSURE_ARG_POINTER(aSandbox);
    2605             783 :     if (!mSandbox && !(mSandbox = new nsXPCComponents_utils_Sandbox())) {
    2606               0 :         *aSandbox = nsnull;
    2607               0 :         return NS_ERROR_OUT_OF_MEMORY;
    2608                 :     }
    2609             574 :     NS_ADDREF(*aSandbox = mSandbox);
    2610             574 :     return NS_OK;
    2611                 : }
    2612                 : 
    2613                 : /* void lookupMethod (); */
    2614                 : NS_IMETHODIMP
    2615               0 : nsXPCComponents_Utils::LookupMethod(const JS::Value& object,
    2616                 :                                     const JS::Value& name,
    2617                 :                                     JSContext *cx,
    2618                 :                                     JS::Value *retval)
    2619                 : {
    2620               0 :     JSAutoRequest ar(cx);
    2621                 : 
    2622                 :     // first param must be a JSObject
    2623               0 :     if (JSVAL_IS_PRIMITIVE(object))
    2624               0 :         return NS_ERROR_XPC_BAD_CONVERT_JS;
    2625                 : 
    2626               0 :     JSObject* obj = JSVAL_TO_OBJECT(object);
    2627               0 :     while (obj && !js::IsWrapper(obj) && !IS_WRAPPER_CLASS(js::GetObjectClass(obj)))
    2628               0 :         obj = JS_GetPrototype(obj);
    2629                 : 
    2630               0 :     if (!obj)
    2631               0 :         return NS_ERROR_XPC_BAD_CONVERT_JS;
    2632                 : 
    2633                 :     JSObject* unwrappedObject;
    2634               0 :     nsresult rv = nsXPConnect::GetXPConnect()->GetJSObjectOfWrapper(cx, obj, &unwrappedObject);
    2635               0 :     if (NS_FAILED(rv))
    2636               0 :         return rv;
    2637                 : 
    2638               0 :     unwrappedObject = JS_ObjectToInnerObject(cx, unwrappedObject);
    2639               0 :     if (!unwrappedObject)
    2640               0 :         return NS_ERROR_XPC_BAD_CONVERT_JS;
    2641                 : 
    2642                 :     // second param must be a string
    2643               0 :     if (!JSVAL_IS_STRING(name))
    2644               0 :         return NS_ERROR_XPC_BAD_CONVERT_JS;
    2645                 : 
    2646                 :     // Make sure the name that we use for looking up the method/property is
    2647                 :     // atomized.
    2648                 :     jsid name_id;
    2649                 :     JS::Value dummy;
    2650               0 :     if (!JS_ValueToId(cx, name, &name_id) ||
    2651               0 :         !JS_IdToValue(cx, name_id, &dummy))
    2652               0 :         return NS_ERROR_XPC_BAD_CONVERT_JS;
    2653                 : 
    2654                 :     // this will do verification and the method lookup for us
    2655                 :     // Note that if |obj| is an XPCNativeWrapper this will all still work.
    2656                 :     // We'll hand back the same method that we'd hand back for the underlying
    2657                 :     // XPCWrappedNative.  This means no deep wrapping, unfortunately, but we
    2658                 :     // can't keep track of both the underlying function and the
    2659                 :     // XPCNativeWrapper at once in a single parent slot...
    2660               0 :     XPCCallContext inner_cc(JS_CALLER, cx, unwrappedObject, nsnull, name_id);
    2661                 : 
    2662                 :     // was our jsobject really a wrapped native at all?
    2663               0 :     XPCWrappedNative* wrapper = inner_cc.GetWrapper();
    2664               0 :     if (!wrapper || !wrapper->IsValid())
    2665               0 :         return NS_ERROR_XPC_BAD_CONVERT_JS;
    2666                 : 
    2667                 :     // did we find a method/attribute by that name?
    2668               0 :     XPCNativeMember* member = inner_cc.GetMember();
    2669               0 :     if (!member || member->IsConstant())
    2670               0 :         return NS_ERROR_XPC_BAD_CONVERT_JS;
    2671                 : 
    2672                 :     // it would a be a big surprise if there is a member without an interface :)
    2673               0 :     XPCNativeInterface* iface = inner_cc.GetInterface();
    2674               0 :     if (!iface)
    2675               0 :         return NS_ERROR_XPC_BAD_CONVERT_JS;
    2676                 : 
    2677                 :     jsval funval;
    2678                 : 
    2679                 :     // get (and perhaps lazily create) the member's cloned function
    2680               0 :     if (!member->NewFunctionObject(inner_cc, iface, obj, &funval))
    2681               0 :         return NS_ERROR_XPC_BAD_CONVERT_JS;
    2682                 : 
    2683               0 :     NS_ASSERTION(JS_ValueToFunction(inner_cc, funval),
    2684                 :                  "Function is not a function");
    2685                 : 
    2686                 :     // Stick the function in the return value. This roots it.
    2687               0 :     *retval = funval;
    2688               0 :     return NS_OK;
    2689                 : }
    2690                 : 
    2691                 : /* void reportError (); */
    2692                 : NS_IMETHODIMP
    2693              45 : nsXPCComponents_Utils::ReportError(const JS::Value &error, JSContext *cx)
    2694                 : {
    2695                 :     // This function shall never fail! Silently eat any failure conditions.
    2696                 : 
    2697              90 :     nsCOMPtr<nsIConsoleService> console(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
    2698                 : 
    2699              90 :     nsCOMPtr<nsIScriptError> scripterr(do_CreateInstance(NS_SCRIPTERROR_CONTRACTID));
    2700                 : 
    2701              45 :     if (!scripterr || !console)
    2702               0 :         return NS_OK;
    2703                 : 
    2704              90 :     JSAutoRequest ar(cx);
    2705                 : 
    2706              45 :     const PRUint64 innerWindowID = nsJSUtils::GetCurrentlyRunningCodeInnerWindowID(cx);
    2707                 : 
    2708              45 :     JSErrorReport *err = JS_ErrorFromException(cx, error);
    2709              45 :     if (err) {
    2710                 :         // It's a proper JS Error
    2711               0 :         nsAutoString fileUni;
    2712               0 :         CopyUTF8toUTF16(err->filename, fileUni);
    2713                 : 
    2714               0 :         PRUint32 column = err->uctokenptr - err->uclinebuf;
    2715                 : 
    2716               0 :         nsresult rv = scripterr->InitWithWindowID(
    2717                 :                 static_cast<const PRUnichar*>(err->ucmessage), fileUni.get(),
    2718                 :                 static_cast<const PRUnichar*>(err->uclinebuf), err->lineno,
    2719               0 :                 column, err->flags, "XPConnect JavaScript", innerWindowID);
    2720               0 :         NS_ENSURE_SUCCESS(rv, NS_OK);
    2721                 : 
    2722               0 :         console->LogMessage(scripterr);
    2723               0 :         return NS_OK;
    2724                 :     }
    2725                 : 
    2726                 :     // It's not a JS Error object, so we synthesize as best we're able.
    2727              45 :     JSString *msgstr = JS_ValueToString(cx, error);
    2728              45 :     if (!msgstr) {
    2729               0 :         return NS_OK;
    2730                 :     }
    2731                 : 
    2732              90 :     nsCOMPtr<nsIStackFrame> frame;
    2733              45 :     nsXPConnect *xpc = nsXPConnect::GetXPConnect();
    2734              45 :     if (xpc)
    2735              45 :         xpc->GetCurrentJSStack(getter_AddRefs(frame));
    2736                 : 
    2737              90 :     nsXPIDLCString fileName;
    2738              45 :     PRInt32 lineNo = 0;
    2739              45 :     if (frame) {
    2740              45 :         frame->GetFilename(getter_Copies(fileName));
    2741              45 :         frame->GetLineNumber(&lineNo);
    2742                 :     }
    2743                 : 
    2744              45 :     const jschar *msgchars = JS_GetStringCharsZ(cx, msgstr);
    2745              45 :     if (!msgchars)
    2746               0 :         return NS_OK;
    2747                 : 
    2748              45 :     nsresult rv = scripterr->InitWithWindowID(
    2749                 :             reinterpret_cast<const PRUnichar *>(msgchars),
    2750              45 :             NS_ConvertUTF8toUTF16(fileName).get(),
    2751              45 :             nsnull, lineNo, 0, 0, "XPConnect JavaScript", innerWindowID);
    2752              45 :     NS_ENSURE_SUCCESS(rv, NS_OK);
    2753                 : 
    2754              45 :     console->LogMessage(scripterr);
    2755              45 :     return NS_OK;
    2756                 : }
    2757                 : 
    2758                 : #include "nsIScriptSecurityManager.h"
    2759                 : #include "nsIURI.h"
    2760                 : #include "nsNetUtil.h"
    2761                 : const char kScriptSecurityManagerContractID[] = NS_SCRIPTSECURITYMANAGER_CONTRACTID;
    2762                 : 
    2763           30535 : NS_IMPL_THREADSAFE_ISUPPORTS1(PrincipalHolder, nsIScriptObjectPrincipal)
    2764                 : 
    2765                 : nsIPrincipal *
    2766            4413 : PrincipalHolder::GetPrincipal()
    2767                 : {
    2768            4413 :     return mHoldee;
    2769                 : }
    2770                 : 
    2771                 : static JSBool
    2772              26 : SandboxDump(JSContext *cx, unsigned argc, jsval *vp)
    2773                 : {
    2774                 :     JSString *str;
    2775              26 :     if (!argc)
    2776               0 :         return true;
    2777                 : 
    2778              26 :     str = JS_ValueToString(cx, JS_ARGV(cx, vp)[0]);
    2779              26 :     if (!str)
    2780               0 :         return false;
    2781                 : 
    2782                 :     size_t length;
    2783              26 :     const jschar *chars = JS_GetStringCharsZAndLength(cx, str, &length);
    2784              26 :     if (!chars)
    2785               0 :         return false;
    2786                 : 
    2787              52 :     nsDependentString wstr(chars, length);
    2788              26 :     char *cstr = ToNewUTF8String(wstr);
    2789              26 :     if (!cstr)
    2790               0 :         return false;
    2791                 : 
    2792                 : #if defined(XP_MACOSX)
    2793                 :     // Be nice and convert all \r to \n.
    2794                 :     char *c = cstr, *cEnd = cstr + strlen(cstr);
    2795                 :     while (c < cEnd) {
    2796                 :         if (*c == '\r')
    2797                 :             *c = '\n';
    2798                 :         c++;
    2799                 :     }
    2800                 : #endif
    2801                 : 
    2802              26 :     fputs(cstr, stdout);
    2803              26 :     fflush(stdout);
    2804              26 :     NS_Free(cstr);
    2805              26 :     JS_SET_RVAL(cx, vp, JSVAL_TRUE);
    2806              26 :     return true;
    2807                 : }
    2808                 : 
    2809                 : static JSBool
    2810               0 : SandboxDebug(JSContext *cx, unsigned argc, jsval *vp)
    2811                 : {
    2812                 : #ifdef DEBUG
    2813               0 :     return SandboxDump(cx, argc, vp);
    2814                 : #else
    2815                 :     return true;
    2816                 : #endif
    2817                 : }
    2818                 : 
    2819                 : static JSBool
    2820            2206 : SandboxImport(JSContext *cx, unsigned argc, jsval *vp)
    2821                 : {
    2822            2206 :     JSObject *thisobj = JS_THIS_OBJECT(cx, vp);
    2823            2206 :     if (!thisobj)
    2824               0 :         return false;
    2825                 : 
    2826            2206 :     jsval *argv = JS_ARGV(cx, vp);
    2827            2206 :     if (argc < 1 || JSVAL_IS_PRIMITIVE(argv[0])) {
    2828               0 :         XPCThrower::Throw(NS_ERROR_INVALID_ARG, cx);
    2829               0 :         return false;
    2830                 :     }
    2831                 : 
    2832                 :     JSString *funname;
    2833            2206 :     if (argc > 1) {
    2834                 :         // Use the second parameter as the function name.
    2835             282 :         funname = JS_ValueToString(cx, argv[1]);
    2836             282 :         if (!funname)
    2837               0 :             return false;
    2838             282 :         argv[1] = STRING_TO_JSVAL(funname);
    2839                 :     } else {
    2840                 :         // NB: funobj must only be used to get the JSFunction out.
    2841            1924 :         JSObject *funobj = JSVAL_TO_OBJECT(argv[0]);
    2842            1924 :         if (js::IsProxy(funobj)) {
    2843            1924 :             funobj = XPCWrapper::UnsafeUnwrapSecurityWrapper(funobj);
    2844                 :         }
    2845                 : 
    2846            3848 :         JSAutoEnterCompartment ac;
    2847            1924 :         if (!ac.enter(cx, funobj)) {
    2848               0 :             return false;
    2849                 :         }
    2850                 : 
    2851            1924 :         JSFunction *fun = JS_ValueToFunction(cx, OBJECT_TO_JSVAL(funobj));
    2852            1924 :         if (!fun) {
    2853               0 :             XPCThrower::Throw(NS_ERROR_INVALID_ARG, cx);
    2854               0 :             return false;
    2855                 :         }
    2856                 : 
    2857                 :         // Use the actual function name as the name.
    2858            1924 :         funname = JS_GetFunctionId(fun);
    2859            1924 :         if (!funname) {
    2860               0 :             XPCThrower::Throw(NS_ERROR_INVALID_ARG, cx);
    2861               0 :             return false;
    2862                 :         }
    2863                 :     }
    2864                 : 
    2865                 :     jsid id;
    2866            2206 :     if (!JS_ValueToId(cx, STRING_TO_JSVAL(funname), &id))
    2867               0 :         return false;
    2868                 : 
    2869            2206 :     JS_SET_RVAL(cx, vp, JSVAL_VOID);
    2870            2206 :     return JS_SetPropertyById(cx, thisobj, id, &argv[0]);
    2871                 : }
    2872                 : 
    2873                 : static JSBool
    2874               0 : sandbox_enumerate(JSContext *cx, JSObject *obj)
    2875                 : {
    2876               0 :     return JS_EnumerateStandardClasses(cx, obj);
    2877                 : }
    2878                 : 
    2879                 : static JSBool
    2880            6708 : sandbox_resolve(JSContext *cx, JSObject *obj, jsid id)
    2881                 : {
    2882                 :     JSBool resolved;
    2883            6708 :     return JS_ResolveStandardClass(cx, obj, id, &resolved);
    2884                 : }
    2885                 : 
    2886                 : static void
    2887             574 : sandbox_finalize(JSContext *cx, JSObject *obj)
    2888                 : {
    2889                 :     nsIScriptObjectPrincipal *sop =
    2890             574 :         (nsIScriptObjectPrincipal *)xpc_GetJSPrivate(obj);
    2891             574 :     NS_IF_RELEASE(sop);
    2892             574 : }
    2893                 : 
    2894                 : static JSBool
    2895             127 : sandbox_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
    2896                 : {
    2897             127 :     if (type == JSTYPE_OBJECT) {
    2898               0 :         *vp = OBJECT_TO_JSVAL(obj);
    2899               0 :         return true;
    2900                 :     }
    2901                 : 
    2902             127 :     return JS_ConvertStub(cx, obj, type, vp);
    2903                 : }
    2904                 : 
    2905                 : static JSClass SandboxClass = {
    2906                 :     "Sandbox",
    2907                 :     XPCONNECT_GLOBAL_FLAGS,
    2908                 :     JS_PropertyStub,   JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
    2909                 :     sandbox_enumerate, sandbox_resolve, sandbox_convert,  sandbox_finalize,
    2910                 :     NULL, NULL, NULL, NULL, TraceXPCGlobal
    2911                 : };
    2912                 : 
    2913                 : static JSFunctionSpec SandboxFunctions[] = {
    2914                 :     {"dump",    SandboxDump,    1,0},
    2915                 :     {"debug",   SandboxDebug,   1,0},
    2916                 :     {"importFunction", SandboxImport, 1,0},
    2917                 :     {nsnull,nsnull,0,0}
    2918                 : };
    2919                 : 
    2920                 : /***************************************************************************/
    2921             209 : nsXPCComponents_utils_Sandbox::nsXPCComponents_utils_Sandbox()
    2922                 : {
    2923             209 : }
    2924                 : 
    2925             418 : nsXPCComponents_utils_Sandbox::~nsXPCComponents_utils_Sandbox()
    2926                 : {
    2927             836 : }
    2928                 : 
    2929            5358 : NS_INTERFACE_MAP_BEGIN(nsXPCComponents_utils_Sandbox)
    2930            5358 :   NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_utils_Sandbox)
    2931            4668 :   NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
    2932            3225 :   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_utils_Sandbox)
    2933            2651 : NS_INTERFACE_MAP_END_THREADSAFE
    2934                 : 
    2935            3971 : NS_IMPL_THREADSAFE_ADDREF(nsXPCComponents_utils_Sandbox)
    2936            3971 : NS_IMPL_THREADSAFE_RELEASE(nsXPCComponents_utils_Sandbox)
    2937                 : 
    2938                 : // We use the nsIXPScriptable macros to generate lots of stuff for us.
    2939                 : #define XPC_MAP_CLASSNAME           nsXPCComponents_utils_Sandbox
    2940                 : #define XPC_MAP_QUOTED_CLASSNAME   "nsXPCComponents_utils_Sandbox"
    2941                 : #define                             XPC_MAP_WANT_CALL
    2942                 : #define                             XPC_MAP_WANT_CONSTRUCT
    2943                 : #define XPC_MAP_FLAGS               0
    2944                 : #include "xpc_map_end.h" /* This #undef's the above. */
    2945                 : 
    2946                 : static bool
    2947            1086 : WrapForSandbox(JSContext *cx, bool wantXrays, jsval *vp)
    2948                 : {
    2949                 :     return wantXrays
    2950            1086 :            ? JS_WrapValue(cx, vp)
    2951            2172 :            : xpc::WrapperFactory::WaiveXrayAndWrap(cx, vp);
    2952                 : }
    2953                 : 
    2954                 : // Needed to distinguish multiple compartments with the same origin from each
    2955                 : // other. The only thing we need out of identity objects are unique addresses.
    2956                 : class Identity : public nsISupports
    2957             574 : {
    2958                 :     NS_DECL_ISUPPORTS
    2959                 : };
    2960                 : 
    2961            5166 : NS_IMPL_ISUPPORTS0(Identity)
    2962                 : 
    2963                 : nsresult
    2964             574 : xpc_CreateSandboxObject(JSContext * cx, jsval * vp, nsISupports *prinOrSop, JSObject *proto,
    2965                 :                         bool wantXrays, const nsACString &sandboxName, nsISupports *identityPtr)
    2966                 : {
    2967                 :     // Create the sandbox global object
    2968                 :     nsresult rv;
    2969            1148 :     nsCOMPtr<nsIXPConnect> xpc(do_GetService(nsIXPConnect::GetCID(), &rv));
    2970             574 :     if (NS_FAILED(rv))
    2971               0 :         return NS_ERROR_XPC_UNEXPECTED;
    2972                 : 
    2973            1148 :     nsCOMPtr<nsIScriptObjectPrincipal> sop(do_QueryInterface(prinOrSop));
    2974                 : 
    2975             574 :     if (!sop) {
    2976             604 :         nsCOMPtr<nsIPrincipal> principal(do_QueryInterface(prinOrSop));
    2977                 : 
    2978             302 :         if (!principal) {
    2979               0 :             principal = do_CreateInstance("@mozilla.org/nullprincipal;1", &rv);
    2980               0 :             NS_ASSERTION(NS_FAILED(rv) || principal,
    2981                 :                          "Bad return from do_CreateInstance");
    2982                 : 
    2983               0 :             if (!principal || NS_FAILED(rv)) {
    2984               0 :                 if (NS_SUCCEEDED(rv)) {
    2985               0 :                     rv = NS_ERROR_FAILURE;
    2986                 :                 }
    2987                 : 
    2988               0 :                 return rv;
    2989                 :             }
    2990                 :         }
    2991                 : 
    2992             604 :         sop = new PrincipalHolder(principal);
    2993             302 :         if (!sop)
    2994               0 :             return NS_ERROR_OUT_OF_MEMORY;
    2995                 :     }
    2996                 : 
    2997             574 :     nsIPrincipal *principal = sop->GetPrincipal();
    2998                 : 
    2999                 :     JSCompartment *compartment;
    3000                 :     JSObject *sandbox;
    3001                 : 
    3002            1148 :     nsRefPtr<Identity> identity;
    3003             574 :     if (!identityPtr) {
    3004             574 :       identity = new Identity();
    3005             574 :       identityPtr = identity;
    3006                 :     }
    3007                 : 
    3008                 :     rv = xpc_CreateGlobalObject(cx, &SandboxClass, principal, identityPtr,
    3009             574 :                                 wantXrays, &sandbox, &compartment);
    3010             574 :     NS_ENSURE_SUCCESS(rv, rv);
    3011                 : 
    3012            1148 :     JS::AutoObjectRooter tvr(cx, sandbox);
    3013                 : 
    3014                 :     {
    3015            1148 :         JSAutoEnterCompartment ac;
    3016             574 :         if (!ac.enter(cx, sandbox))
    3017               0 :             return NS_ERROR_XPC_UNEXPECTED;
    3018                 : 
    3019             574 :         if (proto) {
    3020               0 :             bool ok = JS_WrapObject(cx, &proto);
    3021               0 :             if (!ok)
    3022               0 :                 return NS_ERROR_XPC_UNEXPECTED;
    3023                 : 
    3024               0 :             if (xpc::WrapperFactory::IsXrayWrapper(proto) && !wantXrays) {
    3025               0 :                 jsval v = OBJECT_TO_JSVAL(proto);
    3026               0 :                 if (!xpc::WrapperFactory::WaiveXrayAndWrap(cx, &v))
    3027               0 :                     return NS_ERROR_FAILURE;
    3028               0 :                 proto = JSVAL_TO_OBJECT(v);
    3029                 :             }
    3030                 : 
    3031               0 :             ok = JS_SetPrototype(cx, sandbox, proto);
    3032               0 :             if (!ok)
    3033               0 :                 return NS_ERROR_XPC_UNEXPECTED;
    3034                 :         }
    3035                 : 
    3036                 :         // Pass on ownership of sop to |sandbox|.
    3037             574 :         JS_SetPrivate(sandbox, sop.forget().get());
    3038                 : 
    3039             574 :         rv = xpc->InitClasses(cx, sandbox);
    3040            1148 :         if (NS_SUCCEEDED(rv) &&
    3041             574 :             !JS_DefineFunctions(cx, sandbox, SandboxFunctions)) {
    3042               0 :             rv = NS_ERROR_FAILURE;
    3043                 :         }
    3044             574 :         if (NS_FAILED(rv))
    3045               0 :             return NS_ERROR_XPC_UNEXPECTED;
    3046                 :     }
    3047                 : 
    3048             574 :     if (vp) {
    3049             574 :         *vp = OBJECT_TO_JSVAL(sandbox);
    3050             574 :         if (!WrapForSandbox(cx, wantXrays, vp)) {
    3051               0 :             return NS_ERROR_UNEXPECTED;
    3052                 :         }
    3053                 :     }
    3054                 : 
    3055                 :     xpc::CompartmentPrivate *compartmentPrivate =
    3056             574 :         static_cast<xpc::CompartmentPrivate*>(JS_GetCompartmentPrivate(compartment));
    3057             574 :     compartmentPrivate->location = sandboxName;
    3058                 : 
    3059             574 :     return NS_OK;
    3060                 : }
    3061                 : 
    3062                 : /* bool call(in nsIXPConnectWrappedNative wrapper,
    3063                 :                in JSContextPtr cx,
    3064                 :                in JSObjectPtr obj,
    3065                 :                in PRUint32 argc,
    3066                 :                in JSValPtr argv,
    3067                 :                in JSValPtr vp);
    3068                 : */
    3069                 : NS_IMETHODIMP
    3070             320 : nsXPCComponents_utils_Sandbox::Call(nsIXPConnectWrappedNative *wrapper,
    3071                 :                                     JSContext * cx,
    3072                 :                                     JSObject * obj,
    3073                 :                                     PRUint32 argc,
    3074                 :                                     jsval * argv,
    3075                 :                                     jsval * vp,
    3076                 :                                     bool *_retval)
    3077                 : {
    3078             320 :     return CallOrConstruct(wrapper, cx, obj, argc, argv, vp, _retval);
    3079                 : }
    3080                 : 
    3081                 : /* bool construct(in nsIXPConnectWrappedNative wrapper,
    3082                 :                     in JSContextPtr cx,
    3083                 :                     in JSObjectPtr obj,
    3084                 :                     in PRUint32 argc,
    3085                 :                     in JSValPtr argv,
    3086                 :                     in JSValPtr vp);
    3087                 : */
    3088                 : NS_IMETHODIMP
    3089             254 : nsXPCComponents_utils_Sandbox::Construct(nsIXPConnectWrappedNative *wrapper,
    3090                 :                                          JSContext * cx,
    3091                 :                                          JSObject * obj,
    3092                 :                                          PRUint32 argc,
    3093                 :                                          jsval * argv,
    3094                 :                                          jsval * vp,
    3095                 :                                          bool *_retval)
    3096                 : {
    3097             254 :     return CallOrConstruct(wrapper, cx, obj, argc, argv, vp, _retval);
    3098                 : }
    3099                 : 
    3100                 : // static
    3101                 : nsresult
    3102             574 : nsXPCComponents_utils_Sandbox::CallOrConstruct(nsIXPConnectWrappedNative *wrapper,
    3103                 :                                                JSContext * cx, JSObject * obj,
    3104                 :                                                PRUint32 argc, jsval * argv,
    3105                 :                                                jsval * vp, bool *_retval)
    3106                 : {
    3107             574 :     if (argc < 1)
    3108               0 :         return ThrowAndFail(NS_ERROR_XPC_NOT_ENOUGH_ARGS, cx, _retval);
    3109                 : 
    3110                 :     nsresult rv;
    3111                 : 
    3112                 :     // Make sure to set up principals on the sandbox before initing classes
    3113            1148 :     nsCOMPtr<nsIScriptObjectPrincipal> sop;
    3114            1148 :     nsCOMPtr<nsIPrincipal> principal;
    3115             574 :     nsISupports *prinOrSop = nsnull;
    3116             574 :     nsISupports *identity = nsnull;
    3117             574 :     if (JSVAL_IS_STRING(argv[0])) {
    3118              10 :         JSString *codebaseStr = JSVAL_TO_STRING(argv[0]);
    3119                 :         size_t codebaseLength;
    3120                 :         const jschar *codebaseChars = JS_GetStringCharsAndLength(cx, codebaseStr,
    3121              10 :                                                                  &codebaseLength);
    3122              10 :         if (!codebaseChars) {
    3123               0 :             return ThrowAndFail(NS_ERROR_FAILURE, cx, _retval);
    3124                 :         }
    3125                 : 
    3126              20 :         nsAutoString codebase(codebaseChars, codebaseLength);
    3127              20 :         nsCOMPtr<nsIURI> uri;
    3128              10 :         rv = NS_NewURI(getter_AddRefs(uri), codebase);
    3129              10 :         if (NS_FAILED(rv)) {
    3130               0 :             return ThrowAndFail(rv, cx, _retval);
    3131                 :         }
    3132                 : 
    3133                 :         nsCOMPtr<nsIScriptSecurityManager> secman =
    3134              20 :             do_GetService(kScriptSecurityManagerContractID);
    3135              60 :         if (!secman ||
    3136              40 :             NS_FAILED(rv = secman->GetCodebasePrincipal(uri,
    3137                 :                                                         getter_AddRefs(principal))) ||
    3138              10 :             !principal) {
    3139               0 :             if (NS_SUCCEEDED(rv))
    3140               0 :                 rv = NS_ERROR_FAILURE;
    3141               0 :             return ThrowAndFail(rv, cx, _retval);
    3142                 :         }
    3143                 : 
    3144              20 :         prinOrSop = principal;
    3145                 :     } else {
    3146             564 :         if (!JSVAL_IS_PRIMITIVE(argv[0])) {
    3147            1128 :             nsCOMPtr<nsIXPConnect> xpc(do_GetService(nsIXPConnect::GetCID()));
    3148             564 :             if (!xpc)
    3149               0 :                 return NS_ERROR_XPC_UNEXPECTED;
    3150            1692 :             nsCOMPtr<nsIXPConnectWrappedNative> wrapper;
    3151             564 :             xpc->GetWrappedNativeOfJSObject(cx, JSVAL_TO_OBJECT(argv[0]),
    3152             564 :                                             getter_AddRefs(wrapper));
    3153                 : 
    3154             564 :             if (wrapper) {
    3155             564 :                 sop = do_QueryWrappedNative(wrapper);
    3156             564 :                 if (sop) {
    3157             272 :                     prinOrSop = sop;
    3158                 :                 } else {
    3159             292 :                     principal = do_QueryWrappedNative(wrapper);
    3160             292 :                     prinOrSop = principal;
    3161                 :                 }
    3162                 :             }
    3163                 :         }
    3164                 : 
    3165             564 :         if (!prinOrSop)
    3166               0 :             return ThrowAndFail(NS_ERROR_INVALID_ARG, cx, _retval);
    3167                 :     }
    3168                 : 
    3169             574 :     JSObject *proto = nsnull;
    3170             574 :     bool wantXrays = true;
    3171            1148 :     nsCString sandboxName;
    3172                 : 
    3173             574 :     if (argc > 1) {
    3174             253 :         if (!JSVAL_IS_OBJECT(argv[1]))
    3175               0 :             return ThrowAndFail(NS_ERROR_INVALID_ARG, cx, _retval);
    3176                 : 
    3177             253 :         JSObject *optionsObject = JSVAL_TO_OBJECT(argv[1]);
    3178                 :         jsval option;
    3179                 : 
    3180                 :         JSBool found;
    3181             253 :         if (!JS_HasProperty(cx, optionsObject, "sandboxPrototype", &found))
    3182               0 :             return NS_ERROR_INVALID_ARG;
    3183                 : 
    3184             253 :         if (found) {
    3185               0 :             if (!JS_GetProperty(cx, optionsObject, "sandboxPrototype", &option) ||
    3186               0 :                 !JSVAL_IS_OBJECT(option)) {
    3187               0 :                 return ThrowAndFail(NS_ERROR_INVALID_ARG, cx, _retval);
    3188                 :             }
    3189                 : 
    3190               0 :             proto = JSVAL_TO_OBJECT(option);
    3191                 :         }
    3192                 : 
    3193             253 :         if (!JS_HasProperty(cx, optionsObject, "wantXrays", &found))
    3194               0 :             return NS_ERROR_INVALID_ARG;
    3195                 : 
    3196             253 :         if (found) {
    3197               0 :             if (!JS_GetProperty(cx, optionsObject, "wantXrays", &option) ||
    3198               0 :                 !JSVAL_IS_BOOLEAN(option)) {
    3199               0 :                 return ThrowAndFail(NS_ERROR_INVALID_ARG, cx, _retval);
    3200                 :             }
    3201                 : 
    3202               0 :             wantXrays = JSVAL_TO_BOOLEAN(option);
    3203                 :         }
    3204                 : 
    3205             253 :         if (!JS_HasProperty(cx, optionsObject, "sandboxName", &found))
    3206               0 :             return NS_ERROR_INVALID_ARG;
    3207                 : 
    3208             253 :         if (found) {
    3209             506 :             if (!JS_GetProperty(cx, optionsObject, "sandboxName", &option) ||
    3210             253 :                 !JSVAL_IS_STRING(option)) {
    3211               0 :                 return ThrowAndFail(NS_ERROR_INVALID_ARG, cx, _retval);
    3212                 :             }
    3213                 : 
    3214             253 :             char *tmp = JS_EncodeString(cx, JSVAL_TO_STRING(option));
    3215             253 :             if (!tmp) {
    3216               0 :                 return ThrowAndFail(NS_ERROR_INVALID_ARG, cx, _retval);
    3217                 :             }
    3218                 : 
    3219             253 :             sandboxName.Adopt(tmp, strlen(tmp));
    3220                 :         }
    3221                 : 
    3222                 :         // see Bug 677294:
    3223             253 :         if (!JS_HasProperty(cx, optionsObject, "sameGroupAs", &found))
    3224               0 :             return NS_ERROR_INVALID_ARG;
    3225                 : 
    3226             253 :         if (found) {
    3227               0 :             if (!JS_GetProperty(cx, optionsObject, "sameGroupAs", &option) ||
    3228               0 :                 JSVAL_IS_PRIMITIVE(option))
    3229               0 :                 return ThrowAndFail(NS_ERROR_INVALID_ARG, cx, _retval);
    3230                 : 
    3231               0 :             JSObject* unwrapped = UnwrapObject(JSVAL_TO_OBJECT(option));
    3232               0 :             JSObject* global = GetGlobalForObjectCrossCompartment(unwrapped);
    3233               0 :             if (GetObjectJSClass(unwrapped) != &SandboxClass &&
    3234               0 :                 GetObjectJSClass(global) != &SandboxClass)
    3235               0 :                 return ThrowAndFail(NS_ERROR_INVALID_ARG, cx, _retval);
    3236                 : 
    3237                 :             void* privateValue =
    3238               0 :                 JS_GetCompartmentPrivate(GetObjectCompartment(unwrapped));
    3239                 :             xpc::CompartmentPrivate *compartmentPrivate =
    3240               0 :                 static_cast<xpc::CompartmentPrivate*>(privateValue);
    3241                 : 
    3242               0 :             if (!compartmentPrivate || !compartmentPrivate->key)
    3243               0 :                 return ThrowAndFail(NS_ERROR_INVALID_ARG, cx, _retval);
    3244                 : 
    3245               0 :             identity = compartmentPrivate->key->GetPtr();
    3246                 :         }
    3247                 :     }
    3248                 : 
    3249                 :     // If there is no options object given, or no sandboxName property
    3250                 :     // specified, use the caller's filename as sandboxName.
    3251             574 :     if (sandboxName.IsEmpty()) {
    3252             321 :         nsXPConnect* xpc = nsXPConnect::GetXPConnect();
    3253                 : 
    3254             321 :         if (!xpc)
    3255               0 :             return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
    3256                 : 
    3257                 :         // Get the xpconnect native call context.
    3258             321 :         nsAXPCNativeCallContext *cc = nsnull;
    3259             321 :         xpc->GetCurrentNativeCallContext(&cc);
    3260                 : 
    3261             321 :         if (!cc)
    3262               0 :             return ThrowAndFail(NS_ERROR_INVALID_ARG, cx, _retval);
    3263                 : 
    3264                 :         // Get the current source info from xpc.
    3265             642 :         nsCOMPtr<nsIStackFrame> frame;
    3266             321 :         xpc->GetCurrentJSStack(getter_AddRefs(frame));
    3267                 : 
    3268             321 :         if (frame)
    3269             321 :             frame->GetFilename(getter_Copies(sandboxName));
    3270                 :     }
    3271                 : 
    3272             574 :     rv = xpc_CreateSandboxObject(cx, vp, prinOrSop, proto, wantXrays, sandboxName, identity);
    3273                 : 
    3274             574 :     if (NS_FAILED(rv)) {
    3275               0 :         return ThrowAndFail(rv, cx, _retval);
    3276                 :     }
    3277                 : 
    3278             574 :     *_retval = true;
    3279                 : 
    3280             574 :     return rv;
    3281                 : }
    3282                 : 
    3283                 : class ContextHolder : public nsISupports
    3284                 : {
    3285                 : public:
    3286                 :     ContextHolder(JSContext *aOuterCx, JSObject *aSandbox);
    3287                 :     virtual ~ContextHolder();
    3288                 : 
    3289            3356 :     JSContext * GetJSContext()
    3290                 :     {
    3291            3356 :         return mJSContext;
    3292                 :     }
    3293                 : 
    3294                 :     NS_DECL_ISUPPORTS
    3295                 : 
    3296                 : private:
    3297                 :     static JSBool ContextHolderOperationCallback(JSContext *cx);
    3298                 : 
    3299                 :     JSContext* mJSContext;
    3300                 :     JSContext* mOrigCx;
    3301                 : };
    3302                 : 
    3303            1186 : NS_IMPL_ISUPPORTS0(ContextHolder)
    3304                 : 
    3305             591 : ContextHolder::ContextHolder(JSContext *aOuterCx, JSObject *aSandbox)
    3306             591 :     : mJSContext(JS_NewContext(JS_GetRuntime(aOuterCx), 1024)),
    3307            1182 :       mOrigCx(aOuterCx)
    3308                 : {
    3309             591 :     if (mJSContext) {
    3310            1182 :         JSAutoRequest ar(mJSContext);
    3311                 :         JS_SetOptions(mJSContext,
    3312             591 :                       JS_GetOptions(mJSContext) |
    3313                 :                       JSOPTION_DONT_REPORT_UNCAUGHT |
    3314             591 :                       JSOPTION_PRIVATE_IS_NSISUPPORTS);
    3315             591 :         JS_SetGlobalObject(mJSContext, aSandbox);
    3316             591 :         JS_SetContextPrivate(mJSContext, this);
    3317             591 :         JS_SetOperationCallback(mJSContext, ContextHolderOperationCallback);
    3318                 :     }
    3319             591 : }
    3320                 : 
    3321            1182 : ContextHolder::~ContextHolder()
    3322                 : {
    3323             591 :     if (mJSContext)
    3324             591 :         JS_DestroyContextNoGC(mJSContext);
    3325            2364 : }
    3326                 : 
    3327                 : JSBool
    3328               3 : ContextHolder::ContextHolderOperationCallback(JSContext *cx)
    3329                 : {
    3330                 :     ContextHolder* thisObject =
    3331               3 :         static_cast<ContextHolder*>(JS_GetContextPrivate(cx));
    3332               3 :     NS_ASSERTION(thisObject, "How did that happen?");
    3333                 : 
    3334               3 :     JSContext *origCx = thisObject->mOrigCx;
    3335               3 :     JSOperationCallback callback = JS_GetOperationCallback(origCx);
    3336               3 :     JSBool ok = true;
    3337               3 :     if (callback)
    3338               0 :         ok = callback(origCx);
    3339               3 :     return ok;
    3340                 : }
    3341                 : 
    3342                 : /***************************************************************************/
    3343                 : 
    3344                 : /* void evalInSandbox(in AString source, in nativeobj sandbox); */
    3345                 : NS_IMETHODIMP
    3346             591 : nsXPCComponents_Utils::EvalInSandbox(const nsAString& source,
    3347                 :                                      const JS::Value& sandboxVal,
    3348                 :                                      const JS::Value& version,
    3349                 :                                      const JS::Value& filenameVal,
    3350                 :                                      PRInt32 lineNumber,
    3351                 :                                      JSContext *cx,
    3352                 :                                      PRUint8 optionalArgc,
    3353                 :                                      JS::Value *retval)
    3354                 : {
    3355                 :     JSObject *sandbox;
    3356             591 :     if (!JS_ValueToObject(cx, sandboxVal, &sandbox) || !sandbox)
    3357               0 :         return NS_ERROR_INVALID_ARG;
    3358                 : 
    3359                 :     // Optional third argument: JS version, as a string.
    3360             591 :     JSVersion jsVersion = JSVERSION_DEFAULT;
    3361             591 :     if (optionalArgc >= 1) {
    3362             243 :         JSString *jsVersionStr = JS_ValueToString(cx, version);
    3363             243 :         if (!jsVersionStr)
    3364               0 :             return NS_ERROR_INVALID_ARG;
    3365                 : 
    3366             486 :         JSAutoByteString bytes(cx, jsVersionStr);
    3367             243 :         if (!bytes)
    3368               0 :             return NS_ERROR_INVALID_ARG;
    3369                 : 
    3370             243 :         jsVersion = JS_StringToVersion(bytes.ptr());
    3371             243 :         if (jsVersion == JSVERSION_UNKNOWN)
    3372               0 :             return NS_ERROR_INVALID_ARG;
    3373                 :     }
    3374                 : 
    3375                 :     // Optional fourth and fifth arguments: filename and line number.
    3376            1182 :     nsXPIDLCString filename;
    3377             591 :     PRInt32 lineNo = (optionalArgc >= 3) ? lineNumber : 0;
    3378             591 :     if (optionalArgc >= 2) {
    3379               0 :         JSString *filenameStr = JS_ValueToString(cx, filenameVal);
    3380               0 :         if (!filenameStr)
    3381               0 :             return NS_ERROR_INVALID_ARG;
    3382                 : 
    3383               0 :         JSAutoByteString filenameBytes;
    3384               0 :         if (!filenameBytes.encode(cx, filenameStr))
    3385               0 :             return NS_ERROR_INVALID_ARG;
    3386               0 :         filename = filenameBytes.ptr();
    3387                 :     } else {
    3388                 :         // Get the current source info from xpc.
    3389                 :         nsresult rv;
    3390            1182 :         nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID(), &rv);
    3391             591 :         NS_ENSURE_SUCCESS(rv, rv);
    3392                 : 
    3393            1773 :         nsCOMPtr<nsIStackFrame> frame;
    3394             591 :         xpc->GetCurrentJSStack(getter_AddRefs(frame));
    3395             591 :         if (frame) {
    3396             591 :             frame->GetFilename(getter_Copies(filename));
    3397             591 :             frame->GetLineNumber(&lineNo);
    3398                 :         }
    3399                 :     }
    3400                 : 
    3401                 :     return xpc_EvalInSandbox(cx, sandbox, source, filename.get(), lineNo,
    3402             591 :                              jsVersion, false, retval);
    3403                 : }
    3404                 : 
    3405                 : nsresult
    3406             591 : xpc_EvalInSandbox(JSContext *cx, JSObject *sandbox, const nsAString& source,
    3407                 :                   const char *filename, PRInt32 lineNo,
    3408                 :                   JSVersion jsVersion, bool returnStringOnly, jsval *rval)
    3409                 : {
    3410             591 :     JS_AbortIfWrongThread(JS_GetRuntime(cx));
    3411                 : 
    3412                 : #ifdef DEBUG
    3413                 :     // NB: The "unsafe" unwrap here is OK because we must be called from chrome.
    3414                 :     {
    3415             591 :         nsIScriptSecurityManager *ssm = XPCWrapper::GetSecurityManager();
    3416             591 :         if (ssm) {
    3417                 :             JSStackFrame *fp;
    3418                 :             nsIPrincipal *subjectPrincipal =
    3419             591 :                 ssm->GetCxSubjectPrincipalAndFrame(cx, &fp);
    3420                 :             bool system;
    3421             591 :             ssm->IsSystemPrincipal(subjectPrincipal, &system);
    3422             591 :             if (fp && !system) {
    3423               0 :                 ssm->IsCapabilityEnabled("UniversalXPConnect", &system);
    3424               0 :                 NS_ASSERTION(system, "Bad caller!");
    3425                 :             }
    3426                 :         }
    3427                 :     }
    3428                 : #endif
    3429                 : 
    3430             591 :     sandbox = XPCWrapper::UnsafeUnwrapSecurityWrapper(sandbox);
    3431             591 :     if (!sandbox || js::GetObjectJSClass(sandbox) != &SandboxClass) {
    3432               0 :         return NS_ERROR_INVALID_ARG;
    3433                 :     }
    3434                 : 
    3435                 :     nsIScriptObjectPrincipal *sop =
    3436             591 :         (nsIScriptObjectPrincipal*)xpc_GetJSPrivate(sandbox);
    3437             591 :     NS_ASSERTION(sop, "Invalid sandbox passed");
    3438            1182 :     nsCOMPtr<nsIPrincipal> prin = sop->GetPrincipal();
    3439                 : 
    3440             591 :     if (!prin) {
    3441               0 :         return NS_ERROR_FAILURE;
    3442                 :     }
    3443                 : 
    3444            1182 :     nsCAutoString filenameBuf;
    3445             591 :     if (!filename) {
    3446                 :         // Default to the spec of the principal.
    3447               0 :         nsJSPrincipals::get(prin)->GetScriptLocation(filenameBuf);
    3448               0 :         filename = filenameBuf.get();
    3449               0 :         lineNo = 1;
    3450                 :     }
    3451                 : 
    3452                 :     JSObject *callingScope;
    3453                 :     {
    3454            1182 :         JSAutoRequest req(cx);
    3455                 : 
    3456             591 :         callingScope = JS_GetGlobalForScopeChain(cx);
    3457             591 :         if (!callingScope) {
    3458               0 :             return NS_ERROR_FAILURE;
    3459                 :         }
    3460                 :     }
    3461                 : 
    3462            1182 :     nsRefPtr<ContextHolder> sandcx = new ContextHolder(cx, sandbox);
    3463             591 :     if (!sandcx || !sandcx->GetJSContext()) {
    3464               0 :         JS_ReportError(cx, "Can't prepare context for evalInSandbox");
    3465               0 :         return NS_ERROR_OUT_OF_MEMORY;
    3466                 :     }
    3467                 : 
    3468             591 :     if (jsVersion != JSVERSION_DEFAULT)
    3469             243 :         JS_SetVersion(sandcx->GetJSContext(), jsVersion);
    3470                 : 
    3471             591 :     XPCPerThreadData *data = XPCPerThreadData::GetData(cx);
    3472             591 :     XPCJSContextStack *stack = nsnull;
    3473             591 :     if (data && (stack = data->GetJSContextStack())) {
    3474             591 :         if (!stack->Push(sandcx->GetJSContext())) {
    3475                 :             JS_ReportError(cx,
    3476               0 :                            "Unable to initialize XPConnect with the sandbox context");
    3477               0 :             return NS_ERROR_FAILURE;
    3478                 :         }
    3479                 :     }
    3480                 : 
    3481             591 :     nsresult rv = NS_OK;
    3482                 : 
    3483                 :     {
    3484            1182 :         JSAutoRequest req(sandcx->GetJSContext());
    3485            1182 :         JSAutoEnterCompartment ac;
    3486                 : 
    3487             591 :         if (!ac.enter(sandcx->GetJSContext(), sandbox)) {
    3488               0 :             if (stack)
    3489               0 :                 unused << stack->Pop();
    3490               0 :             return NS_ERROR_FAILURE;
    3491                 :         }
    3492                 : 
    3493                 :         jsval v;
    3494             591 :         JSString *str = nsnull;
    3495                 :         JSBool ok =
    3496                 :             JS_EvaluateUCScriptForPrincipals(sandcx->GetJSContext(), sandbox,
    3497             591 :                                              nsJSPrincipals::get(prin),
    3498                 :                                              reinterpret_cast<const jschar *>
    3499            1182 :                                                              (PromiseFlatString(source).get()),
    3500                 :                                              source.Length(), filename, lineNo,
    3501            1182 :                                              &v);
    3502             591 :         if (ok && returnStringOnly && !(JSVAL_IS_VOID(v))) {
    3503               0 :             ok = !!(str = JS_ValueToString(sandcx->GetJSContext(), v));
    3504                 :         }
    3505                 : 
    3506             591 :         if (!ok) {
    3507                 :             // The sandbox threw an exception, convert it to a string (if
    3508                 :             // asked) or convert it to a SJOW.
    3509                 : 
    3510                 :             jsval exn;
    3511              79 :             if (JS_GetPendingException(sandcx->GetJSContext(), &exn)) {
    3512              79 :                 JS_ClearPendingException(sandcx->GetJSContext());
    3513                 : 
    3514              79 :                 if (returnStringOnly) {
    3515                 :                     // The caller asked for strings only, convert the
    3516                 :                     // exception into a string.
    3517               0 :                     str = JS_ValueToString(sandcx->GetJSContext(), exn);
    3518                 : 
    3519               0 :                     if (str) {
    3520                 :                         // We converted the exception to a string. Use that
    3521                 :                         // as the value exception.
    3522               0 :                         exn = STRING_TO_JSVAL(str);
    3523               0 :                         if (JS_WrapValue(cx, &exn)) {
    3524               0 :                             JS_SetPendingException(cx, exn);
    3525                 :                         } else {
    3526               0 :                             JS_ClearPendingException(cx);
    3527               0 :                             rv = NS_ERROR_FAILURE;
    3528                 :                         }
    3529                 :                     } else {
    3530               0 :                         JS_ClearPendingException(cx);
    3531               0 :                         rv = NS_ERROR_FAILURE;
    3532                 :                     }
    3533                 :                 } else {
    3534              79 :                     if (JS_WrapValue(cx, &exn)) {
    3535              79 :                         JS_SetPendingException(cx, exn);
    3536                 :                     }
    3537                 :                 }
    3538                 : 
    3539                 : 
    3540                 :                 // Clear str so we don't confuse callers.
    3541              79 :                 str = nsnull;
    3542                 :             } else {
    3543               0 :                 rv = NS_ERROR_OUT_OF_MEMORY;
    3544                 :             }
    3545                 :         } else {
    3546                 :             // Convert the result into something safe for our caller.
    3547            1024 :             JSAutoRequest req(cx);
    3548            1024 :             JSAutoEnterCompartment ac;
    3549             512 :             if (str) {
    3550               0 :                 v = STRING_TO_JSVAL(str);
    3551                 :             }
    3552                 : 
    3553                 :             xpc::CompartmentPrivate *sandboxdata =
    3554                 :                 static_cast<xpc::CompartmentPrivate *>
    3555             512 :                            (JS_GetCompartmentPrivate(js::GetObjectCompartment(sandbox)));
    3556            1024 :             if (!ac.enter(cx, callingScope) ||
    3557             512 :                 !WrapForSandbox(cx, sandboxdata->wantXrays, &v)) {
    3558               0 :                 rv = NS_ERROR_FAILURE;
    3559                 :             }
    3560                 : 
    3561             512 :             if (NS_SUCCEEDED(rv)) {
    3562             512 :                 *rval = v;
    3563                 :             }
    3564                 :         }
    3565                 :     }
    3566                 : 
    3567             591 :     if (stack)
    3568             591 :         unused << stack->Pop();
    3569                 : 
    3570             591 :     return rv;
    3571                 : }
    3572                 : 
    3573                 : /* JSObject import (in AUTF8String registryLocation,
    3574                 :  *                  [optional] in JSObject targetObj);
    3575                 :  */
    3576                 : NS_IMETHODIMP
    3577           45915 : nsXPCComponents_Utils::Import(const nsACString& registryLocation,
    3578                 :                               const JS::Value& targetObj,
    3579                 :                               JSContext* cx,
    3580                 :                               PRUint8 optionalArgc,
    3581                 :                               JS::Value* retval)
    3582                 : {
    3583                 :     nsCOMPtr<xpcIJSModuleLoader> moduleloader =
    3584           91830 :         do_GetService(MOZJSCOMPONENTLOADER_CONTRACTID);
    3585           45915 :     if (!moduleloader)
    3586               0 :         return NS_ERROR_FAILURE;
    3587           45915 :     return moduleloader->Import(registryLocation, targetObj, cx, optionalArgc, retval);
    3588                 : }
    3589                 : 
    3590                 : /* unload (in AUTF8String registryLocation);
    3591                 :  */
    3592                 : NS_IMETHODIMP
    3593            1236 : nsXPCComponents_Utils::Unload(const nsACString & registryLocation)
    3594                 : {
    3595                 :     nsCOMPtr<xpcIJSModuleLoader> moduleloader =
    3596            2472 :         do_GetService(MOZJSCOMPONENTLOADER_CONTRACTID);
    3597            1236 :     if (!moduleloader)
    3598               0 :         return NS_ERROR_FAILURE;
    3599            1236 :     return moduleloader->Unload(registryLocation);
    3600                 : }
    3601                 : 
    3602                 : /* xpcIJSWeakReference getWeakReference (); */
    3603                 : NS_IMETHODIMP
    3604            3505 : nsXPCComponents_Utils::GetWeakReference(const JS::Value &object, JSContext *cx,
    3605                 :                                         xpcIJSWeakReference **_retval)
    3606                 : {
    3607            7010 :     nsRefPtr<xpcJSWeakReference> ref = new xpcJSWeakReference();
    3608            3505 :     nsresult rv = ref->Init(cx, object);
    3609            3505 :     NS_ENSURE_SUCCESS(rv, rv);
    3610            3505 :     ref.forget(_retval);
    3611            3505 :     return NS_OK;
    3612                 : }
    3613                 : 
    3614                 : /* void forceGC (); */
    3615                 : NS_IMETHODIMP
    3616               7 : nsXPCComponents_Utils::ForceGC(JSContext *cx)
    3617                 : {
    3618               7 :     js::GCForReason(cx, js::gcreason::COMPONENT_UTILS);
    3619               7 :     return NS_OK;
    3620                 : }
    3621                 : 
    3622                 : /* void forceShrinkingGC (); */
    3623                 : NS_IMETHODIMP
    3624               0 : nsXPCComponents_Utils::ForceShrinkingGC(JSContext *cx)
    3625                 : {
    3626               0 :     js::ShrinkingGC(cx, js::gcreason::COMPONENT_UTILS);
    3627               0 :     return NS_OK;
    3628                 : }
    3629                 : 
    3630                 : class PreciseGCRunnable : public nsRunnable
    3631               0 : {
    3632                 :   public:
    3633               0 :     PreciseGCRunnable(JSContext *aCx, ScheduledGCCallback* aCallback, bool aShrinking)
    3634               0 :     : mCallback(aCallback), mCx(aCx), mShrinking(aShrinking) {}
    3635                 : 
    3636               0 :     NS_IMETHOD Run()
    3637                 :     {
    3638               0 :         nsCOMPtr<nsIJSRuntimeService> runtimeSvc = do_GetService("@mozilla.org/js/xpc/RuntimeService;1");
    3639               0 :         NS_ENSURE_STATE(runtimeSvc);
    3640                 : 
    3641               0 :         JSRuntime* rt = nsnull;
    3642               0 :         runtimeSvc->GetRuntime(&rt);
    3643               0 :         NS_ENSURE_STATE(rt);
    3644                 : 
    3645                 :         JSContext *cx;
    3646               0 :         JSContext *iter = nsnull;
    3647               0 :         while ((cx = JS_ContextIterator(rt, &iter)) != NULL) {
    3648               0 :             if (JS_IsRunning(cx)) {
    3649               0 :                 return NS_DispatchToMainThread(this);
    3650                 :             }
    3651                 :         }
    3652                 : 
    3653               0 :         if (mShrinking)
    3654               0 :             js::ShrinkingGC(mCx, js::gcreason::COMPONENT_UTILS);
    3655                 :         else
    3656               0 :             js::GCForReason(mCx, js::gcreason::COMPONENT_UTILS);
    3657                 : 
    3658               0 :         mCallback->Callback();
    3659               0 :         return NS_OK;
    3660                 :     }
    3661                 : 
    3662                 :   private:
    3663                 :     nsRefPtr<ScheduledGCCallback> mCallback;
    3664                 :     JSContext *mCx;
    3665                 :     bool mShrinking;
    3666                 : };
    3667                 : 
    3668                 : /* [inline_jscontext] void schedulePreciseGC(in ScheduledGCCallback callback); */
    3669                 : NS_IMETHODIMP
    3670               0 : nsXPCComponents_Utils::SchedulePreciseGC(ScheduledGCCallback* aCallback, JSContext* aCx)
    3671                 : {
    3672               0 :     nsRefPtr<PreciseGCRunnable> event = new PreciseGCRunnable(aCx, aCallback, false);
    3673               0 :     return NS_DispatchToMainThread(event);
    3674                 : }
    3675                 : 
    3676                 : /* [inline_jscontext] void schedulePreciseShrinkingGC(in ScheduledGCCallback callback); */
    3677                 : NS_IMETHODIMP
    3678               0 : nsXPCComponents_Utils::SchedulePreciseShrinkingGC(ScheduledGCCallback* aCallback, JSContext* aCx)
    3679                 : {
    3680               0 :     nsRefPtr<PreciseGCRunnable> event = new PreciseGCRunnable(aCx, aCallback, true);
    3681               0 :     return NS_DispatchToMainThread(event);
    3682                 : }
    3683                 : 
    3684                 : /* [implicit_jscontext] jsval nondeterministicGetWeakMapKeys(in jsval aMap); */
    3685                 : NS_IMETHODIMP
    3686               0 : nsXPCComponents_Utils::NondeterministicGetWeakMapKeys(const jsval &aMap,
    3687                 :                                                       JSContext *aCx,
    3688                 :                                                       jsval *aKeys)
    3689                 : {
    3690               0 :     if (!JSVAL_IS_OBJECT(aMap)) {
    3691               0 :         *aKeys = JSVAL_VOID;
    3692               0 :         return NS_OK; 
    3693                 :     }
    3694                 :     JSObject *objRet;
    3695               0 :     if (!JS_NondeterministicGetWeakMapKeys(aCx, JSVAL_TO_OBJECT(aMap), &objRet))
    3696               0 :         return NS_ERROR_OUT_OF_MEMORY;
    3697               0 :     *aKeys = objRet ? OBJECT_TO_JSVAL(objRet) : JSVAL_VOID;
    3698               0 :     return NS_OK;
    3699                 : }
    3700                 : 
    3701                 : /* void getDebugObject(); */
    3702                 : NS_IMETHODIMP
    3703               0 : nsXPCComponents_Utils::GetJSTestingFunctions(JSContext *cx,
    3704                 :                                              JS::Value *retval)
    3705                 : {
    3706               0 :     JSObject *obj = js::GetTestingFunctions(cx);
    3707               0 :     if (!obj)
    3708               0 :         return NS_ERROR_XPC_JAVASCRIPT_ERROR;
    3709               0 :     *retval = OBJECT_TO_JSVAL(obj);
    3710               0 :     return NS_OK;
    3711                 : }
    3712                 : 
    3713                 : /* void getGlobalForObject(); */
    3714                 : NS_IMETHODIMP
    3715             176 : nsXPCComponents_Utils::GetGlobalForObject(const JS::Value& object,
    3716                 :                                           JSContext *cx,
    3717                 :                                           JS::Value *retval)
    3718                 : {
    3719                 :   // First argument must be an object.
    3720             176 :   if (JSVAL_IS_PRIMITIVE(object))
    3721               0 :     return NS_ERROR_XPC_BAD_CONVERT_JS;
    3722                 : 
    3723             176 :   JSObject *obj = JS_GetGlobalForObject(cx, JSVAL_TO_OBJECT(object));
    3724             176 :   *retval = OBJECT_TO_JSVAL(obj);
    3725                 : 
    3726                 :   // Outerize if necessary.
    3727             176 :   if (JSObjectOp outerize = js::GetObjectClass(obj)->ext.outerObject)
    3728               0 :       *retval = OBJECT_TO_JSVAL(outerize(cx, obj));
    3729                 : 
    3730             176 :   return NS_OK;
    3731                 : }
    3732                 : 
    3733                 : /* jsval createObjectIn(in jsval vobj); */
    3734                 : NS_IMETHODIMP
    3735               0 : nsXPCComponents_Utils::CreateObjectIn(const jsval &vobj, JSContext *cx, jsval *rval)
    3736                 : {
    3737               0 :     if (!cx)
    3738               0 :         return NS_ERROR_FAILURE;
    3739                 : 
    3740                 :     // first argument must be an object
    3741               0 :     if (JSVAL_IS_PRIMITIVE(vobj))
    3742               0 :         return NS_ERROR_XPC_BAD_CONVERT_JS;
    3743                 : 
    3744               0 :     JSObject *scope = js::UnwrapObject(JSVAL_TO_OBJECT(vobj));
    3745                 :     JSObject *obj;
    3746                 :     {
    3747               0 :         JSAutoEnterCompartment ac;
    3748               0 :         if (!ac.enter(cx, scope))
    3749               0 :             return NS_ERROR_FAILURE;
    3750                 : 
    3751               0 :         obj = JS_NewObject(cx, nsnull, nsnull, scope);
    3752               0 :         if (!obj)
    3753               0 :             return NS_ERROR_FAILURE;
    3754                 :     }
    3755                 : 
    3756               0 :     if (!JS_WrapObject(cx, &obj))
    3757               0 :         return NS_ERROR_FAILURE;
    3758               0 :     *rval = OBJECT_TO_JSVAL(obj);
    3759               0 :     return NS_OK;
    3760                 : }
    3761                 : 
    3762                 : JSBool
    3763               0 : FunctionWrapper(JSContext *cx, unsigned argc, jsval *vp)
    3764                 : {
    3765               0 :     jsval v = js::GetFunctionNativeReserved(JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)), 0);
    3766               0 :     NS_ASSERTION(JSVAL_IS_OBJECT(v), "weird function");
    3767                 : 
    3768               0 :     JSObject *obj = JS_THIS_OBJECT(cx, vp);
    3769               0 :     if (!obj) {
    3770               0 :         return JS_FALSE;
    3771                 :     }
    3772               0 :     return JS_CallFunctionValue(cx, obj, v, argc, JS_ARGV(cx, vp), vp);
    3773                 : }
    3774                 : 
    3775                 : JSBool
    3776               0 : WrapCallable(JSContext *cx, JSObject *obj, jsid id, JSObject *propobj, jsval *vp)
    3777                 : {
    3778                 :     JSFunction *fun = js::NewFunctionByIdWithReserved(cx, FunctionWrapper, 0, 0,
    3779               0 :                                                       JS_GetGlobalForObject(cx, obj), id);
    3780               0 :     if (!fun)
    3781               0 :         return false;
    3782                 : 
    3783               0 :     JSObject *funobj = JS_GetFunctionObject(fun);
    3784               0 :     js::SetFunctionNativeReserved(funobj, 0, OBJECT_TO_JSVAL(propobj));
    3785               0 :     *vp = OBJECT_TO_JSVAL(funobj);
    3786               0 :     return true;
    3787                 : }
    3788                 : 
    3789                 : /* void makeObjectPropsNormal(jsval vobj); */
    3790                 : NS_IMETHODIMP
    3791               0 : nsXPCComponents_Utils::MakeObjectPropsNormal(const jsval &vobj, JSContext *cx)
    3792                 : {
    3793               0 :     if (!cx)
    3794               0 :         return NS_ERROR_FAILURE;
    3795                 : 
    3796                 :     // first argument must be an object
    3797               0 :     if (JSVAL_IS_PRIMITIVE(vobj))
    3798               0 :         return NS_ERROR_XPC_BAD_CONVERT_JS;
    3799                 : 
    3800               0 :     JSObject *obj = js::UnwrapObject(JSVAL_TO_OBJECT(vobj));
    3801                 : 
    3802               0 :     JSAutoEnterCompartment ac;
    3803               0 :     if (!ac.enter(cx, obj))
    3804               0 :         return NS_ERROR_FAILURE;
    3805                 : 
    3806               0 :     JS::AutoIdArray ida(cx, JS_Enumerate(cx, obj));
    3807               0 :     if (!ida)
    3808               0 :         return NS_ERROR_FAILURE;
    3809                 : 
    3810               0 :     for (size_t i = 0; i < ida.length(); ++i) {
    3811               0 :         jsid id = ida[i];
    3812                 :         jsval v;
    3813                 : 
    3814               0 :         if (!JS_GetPropertyById(cx, obj, id, &v))
    3815               0 :             return NS_ERROR_FAILURE;
    3816                 : 
    3817               0 :         if (JSVAL_IS_PRIMITIVE(v))
    3818               0 :             continue;
    3819                 : 
    3820               0 :         JSObject *propobj = JSVAL_TO_OBJECT(v);
    3821                 :         // TODO Deal with non-functions.
    3822               0 :         if (!js::IsWrapper(propobj) || !JS_ObjectIsCallable(cx, propobj))
    3823               0 :             continue;
    3824                 : 
    3825               0 :         if (!WrapCallable(cx, obj, id, propobj, &v) ||
    3826               0 :             !JS_SetPropertyById(cx, obj, id, &v))
    3827               0 :             return NS_ERROR_FAILURE;
    3828                 :     }
    3829                 : 
    3830               0 :     return NS_OK;
    3831                 : }
    3832                 : 
    3833                 : /* string canCreateWrapper (in nsIIDPtr iid); */
    3834                 : NS_IMETHODIMP
    3835           11085 : nsXPCComponents_Utils::CanCreateWrapper(const nsIID * iid, char **_retval)
    3836                 : {
    3837                 :     // We let anyone do this...
    3838           11085 :     *_retval = xpc_CloneAllAccess();
    3839           11085 :     return NS_OK;
    3840                 : }
    3841                 : 
    3842                 : /* string canCallMethod (in nsIIDPtr iid, in wstring methodName); */
    3843                 : NS_IMETHODIMP
    3844               0 : nsXPCComponents_Utils::CanCallMethod(const nsIID * iid, const PRUnichar *methodName, char **_retval)
    3845                 : {
    3846                 :     static const char* allowed[] = { "lookupMethod", "evalInSandbox", nsnull };
    3847               0 :     *_retval = xpc_CheckAccessList(methodName, allowed);
    3848               0 :     return NS_OK;
    3849                 : }
    3850                 : 
    3851                 : /* string canGetProperty (in nsIIDPtr iid, in wstring propertyName); */
    3852                 : NS_IMETHODIMP
    3853               0 : nsXPCComponents_Utils::CanGetProperty(const nsIID * iid, const PRUnichar *propertyName, char **_retval)
    3854                 : {
    3855               0 :     *_retval = nsnull;
    3856               0 :     return NS_OK;
    3857                 : }
    3858                 : 
    3859                 : /* string canSetProperty (in nsIIDPtr iid, in wstring propertyName); */
    3860                 : NS_IMETHODIMP
    3861               0 : nsXPCComponents_Utils::CanSetProperty(const nsIID * iid, const PRUnichar *propertyName, char **_retval)
    3862                 : {
    3863                 :     // If you have to ask, then the answer is NO
    3864               0 :     *_retval = nsnull;
    3865               0 :     return NS_OK;
    3866                 : }
    3867                 : 
    3868                 : nsresult
    3869               0 : GetBoolOption(JSContext* cx, uint32_t aOption, bool* aValue)
    3870                 : {
    3871               0 :     *aValue = !!(JS_GetOptions(cx) & aOption);
    3872               0 :     return NS_OK;
    3873                 : }
    3874                 : 
    3875                 : nsresult
    3876               0 : SetBoolOption(JSContext* cx, uint32_t aOption, bool aValue)
    3877                 : {
    3878               0 :     uint32_t options = JS_GetOptions(cx);
    3879               0 :     if (aValue) {
    3880               0 :         options |= aOption;
    3881                 :     } else {
    3882               0 :         options &= ~aOption;
    3883                 :     }
    3884               0 :     JS_SetOptions(cx, options & JSALLOPTION_MASK);
    3885               0 :     return NS_OK;
    3886                 : }
    3887                 : 
    3888                 : #define GENERATE_JSOPTION_GETTER_SETTER(_attr, _flag)                   \
    3889                 :     NS_IMETHODIMP                                                       \
    3890                 :     nsXPCComponents_Utils::Get## _attr(JSContext* cx, bool* aValue)     \
    3891                 :     {                                                                   \
    3892                 :         return GetBoolOption(cx, _flag, aValue);                        \
    3893                 :     }                                                                   \
    3894                 :     NS_IMETHODIMP                                                       \
    3895                 :     nsXPCComponents_Utils::Set## _attr(JSContext* cx, bool aValue)      \
    3896                 :     {                                                                   \
    3897                 :         return SetBoolOption(cx, _flag, aValue);                        \
    3898                 :     }
    3899                 : 
    3900               0 : GENERATE_JSOPTION_GETTER_SETTER(Strict, JSOPTION_STRICT)
    3901               0 : GENERATE_JSOPTION_GETTER_SETTER(Werror, JSOPTION_WERROR)
    3902               0 : GENERATE_JSOPTION_GETTER_SETTER(Atline, JSOPTION_ATLINE)
    3903               0 : GENERATE_JSOPTION_GETTER_SETTER(Xml, JSOPTION_XML)
    3904               0 : GENERATE_JSOPTION_GETTER_SETTER(Relimit, JSOPTION_RELIMIT)
    3905               0 : GENERATE_JSOPTION_GETTER_SETTER(Methodjit, JSOPTION_METHODJIT)
    3906               0 : GENERATE_JSOPTION_GETTER_SETTER(Methodjit_always, JSOPTION_METHODJIT_ALWAYS)
    3907                 : 
    3908                 : #undef GENERATE_JSOPTION_GETTER_SETTER
    3909                 : 
    3910                 : NS_IMETHODIMP
    3911               0 : nsXPCComponents_Utils::SetGCZeal(PRInt32 aValue, JSContext* cx)
    3912                 : {
    3913                 : #ifdef JS_GC_ZEAL
    3914               0 :     JS_SetGCZeal(cx, PRUint8(aValue), JS_DEFAULT_ZEAL_FREQ, false);
    3915                 : #endif
    3916               0 :     return NS_OK;
    3917                 : }
    3918                 : 
    3919                 : /***************************************************************************/
    3920                 : /***************************************************************************/
    3921                 : /***************************************************************************/
    3922                 : 
    3923                 : // XXXjband We ought to cache the wrapper in the object's slots rather than
    3924                 : // re-wrapping on demand
    3925                 : 
    3926          220799 : NS_INTERFACE_MAP_BEGIN(nsXPCComponents)
    3927          220799 :   NS_INTERFACE_MAP_ENTRY(nsIXPCComponents)
    3928          183403 :   NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
    3929          136975 :   NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
    3930          106021 :   NS_INTERFACE_MAP_ENTRY(nsISecurityCheckedComponent)
    3931          102553 :   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents)
    3932           87073 : NS_INTERFACE_MAP_END_THREADSAFE
    3933                 : 
    3934          195628 : NS_IMPL_THREADSAFE_ADDREF(nsXPCComponents)
    3935          195564 : NS_IMPL_THREADSAFE_RELEASE(nsXPCComponents)
    3936                 : 
    3937                 : /* void getInterfaces (out PRUint32 count, [array, size_is (count), retval]
    3938                 :                        out nsIIDPtr array); */
    3939                 : NS_IMETHODIMP
    3940           15475 : nsXPCComponents::GetInterfaces(PRUint32 *aCount, nsIID * **aArray)
    3941                 : {
    3942           15475 :     const PRUint32 count = 3;
    3943           15475 :     *aCount = count;
    3944                 :     nsIID **array;
    3945           15475 :     *aArray = array = static_cast<nsIID**>(nsMemory::Alloc(count * sizeof(nsIID*)));
    3946           15475 :     if (!array)
    3947               0 :         return NS_ERROR_OUT_OF_MEMORY;
    3948                 : 
    3949           15475 :     PRUint32 index = 0;
    3950                 :     nsIID* clone;
    3951                 : #define PUSH_IID(id)                                                          \
    3952                 :     clone = static_cast<nsIID *>(nsMemory::Clone(&NS_GET_IID( id ),           \
    3953                 :                                                  sizeof(nsIID)));             \
    3954                 :     if (!clone)                                                               \
    3955                 :         goto oom;                                                             \
    3956                 :     array[index++] = clone;
    3957                 : 
    3958           15475 :     PUSH_IID(nsIXPCComponents)
    3959           15475 :     PUSH_IID(nsIXPCScriptable)
    3960           15475 :     PUSH_IID(nsISecurityCheckedComponent)
    3961                 : #undef PUSH_IID
    3962                 : 
    3963           15475 :     return NS_OK;
    3964                 : oom:
    3965               0 :     while (index)
    3966               0 :         nsMemory::Free(array[--index]);
    3967               0 :     nsMemory::Free(array);
    3968               0 :     *aArray = nsnull;
    3969               0 :     return NS_ERROR_OUT_OF_MEMORY;
    3970                 : }
    3971                 : 
    3972                 : /* nsISupports getHelperForLanguage (in PRUint32 language); */
    3973                 : NS_IMETHODIMP
    3974           15476 : nsXPCComponents::GetHelperForLanguage(PRUint32 language,
    3975                 :                                       nsISupports **retval)
    3976                 : {
    3977           15476 :     *retval = nsnull;
    3978           15476 :     return NS_OK;
    3979                 : }
    3980                 : 
    3981                 : /* readonly attribute string contractID; */
    3982                 : NS_IMETHODIMP
    3983               0 : nsXPCComponents::GetContractID(char * *aContractID)
    3984                 : {
    3985               0 :     *aContractID = nsnull;
    3986               0 :     return NS_ERROR_NOT_AVAILABLE;
    3987                 : }
    3988                 : 
    3989                 : /* readonly attribute string classDescription; */
    3990                 : NS_IMETHODIMP
    3991               1 : nsXPCComponents::GetClassDescription(char * *aClassDescription)
    3992                 : {
    3993                 :     static const char classDescription[] = "XPCComponents";
    3994               1 :     *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription));
    3995               1 :     return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
    3996                 : }
    3997                 : 
    3998                 : /* readonly attribute nsCIDPtr classID; */
    3999                 : NS_IMETHODIMP
    4000               0 : nsXPCComponents::GetClassID(nsCID * *aClassID)
    4001                 : {
    4002               0 :     *aClassID = nsnull;
    4003               0 :     return NS_OK;
    4004                 : }
    4005                 : 
    4006                 : /* readonly attribute PRUint32 implementationLanguage; */
    4007                 : NS_IMETHODIMP
    4008               0 : nsXPCComponents::GetImplementationLanguage(PRUint32 *aImplementationLanguage)
    4009                 : {
    4010               0 :     *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS;
    4011               0 :     return NS_OK;
    4012                 : }
    4013                 : 
    4014                 : /* readonly attribute PRUint32 flags; */
    4015                 : NS_IMETHODIMP
    4016           18944 : nsXPCComponents::GetFlags(PRUint32 *aFlags)
    4017                 : {
    4018           18944 :     *aFlags = nsIClassInfo::THREADSAFE;
    4019           18944 :     return NS_OK;
    4020                 : }
    4021                 : 
    4022                 : /* [notxpcom] readonly attribute nsCID classIDNoAlloc; */
    4023                 : NS_IMETHODIMP
    4024               0 : nsXPCComponents::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
    4025                 : {
    4026               0 :     return NS_ERROR_NOT_AVAILABLE;
    4027                 : }
    4028                 : 
    4029           15475 : nsXPCComponents::nsXPCComponents()
    4030                 :     :   mInterfaces(nsnull),
    4031                 :         mInterfacesByID(nsnull),
    4032                 :         mClasses(nsnull),
    4033                 :         mClassesByID(nsnull),
    4034                 :         mResults(nsnull),
    4035                 :         mID(nsnull),
    4036                 :         mException(nsnull),
    4037                 :         mConstructor(nsnull),
    4038           15475 :         mUtils(nsnull)
    4039                 : {
    4040           15475 : }
    4041                 : 
    4042           30894 : nsXPCComponents::~nsXPCComponents()
    4043                 : {
    4044           15447 :     ClearMembers();
    4045           61788 : }
    4046                 : 
    4047                 : void
    4048           15471 : nsXPCComponents::ClearMembers()
    4049                 : {
    4050           15471 :     NS_IF_RELEASE(mInterfaces);
    4051           15471 :     NS_IF_RELEASE(mInterfacesByID);
    4052           15471 :     NS_IF_RELEASE(mClasses);
    4053           15471 :     NS_IF_RELEASE(mClassesByID);
    4054           15471 :     NS_IF_RELEASE(mResults);
    4055           15471 :     NS_IF_RELEASE(mID);
    4056           15471 :     NS_IF_RELEASE(mException);
    4057           15471 :     NS_IF_RELEASE(mConstructor);
    4058           15471 :     NS_IF_RELEASE(mUtils);
    4059           15471 : }
    4060                 : 
    4061                 : /*******************************************/
    4062                 : #define XPC_IMPL_GET_OBJ_METHOD(_n)                                           \
    4063                 : NS_IMETHODIMP nsXPCComponents::Get##_n(nsIXPCComponents_##_n * *a##_n) {      \
    4064                 :     NS_ENSURE_ARG_POINTER(a##_n);                                             \
    4065                 :     if (!m##_n) {                                                             \
    4066                 :         if (!(m##_n = new nsXPCComponents_##_n())) {                          \
    4067                 :             *a##_n = nsnull;                                                  \
    4068                 :             return NS_ERROR_OUT_OF_MEMORY;                                    \
    4069                 :         }                                                                     \
    4070                 :         NS_ADDREF(m##_n);                                                     \
    4071                 :     }                                                                         \
    4072                 :     NS_ADDREF(m##_n);                                                         \
    4073                 :     *a##_n = m##_n;                                                           \
    4074                 :     return NS_OK;                                                             \
    4075                 : }
    4076                 : 
    4077           84614 : XPC_IMPL_GET_OBJ_METHOD(Interfaces)
    4078               2 : XPC_IMPL_GET_OBJ_METHOD(InterfacesByID)
    4079           59057 : XPC_IMPL_GET_OBJ_METHOD(Classes)
    4080               9 : XPC_IMPL_GET_OBJ_METHOD(ClassesByID)
    4081           25293 : XPC_IMPL_GET_OBJ_METHOD(Results)
    4082            9343 : XPC_IMPL_GET_OBJ_METHOD(ID)
    4083             807 : XPC_IMPL_GET_OBJ_METHOD(Exception)
    4084            2690 : XPC_IMPL_GET_OBJ_METHOD(Constructor)
    4085           54675 : XPC_IMPL_GET_OBJ_METHOD(Utils)
    4086                 : 
    4087                 : #undef XPC_IMPL_GET_OBJ_METHOD
    4088                 : /*******************************************/
    4089                 : 
    4090                 : NS_IMETHODIMP
    4091            8269 : nsXPCComponents::IsSuccessCode(nsresult result, bool *out)
    4092                 : {
    4093            8269 :     *out = NS_SUCCEEDED(result);
    4094            8269 :     return NS_OK;
    4095                 : }
    4096                 : 
    4097                 : NS_IMETHODIMP
    4098          155853 : nsXPCComponents::GetStack(nsIStackFrame * *aStack)
    4099                 : {
    4100                 :     nsresult rv;
    4101          155853 :     nsXPConnect* xpc = nsXPConnect::GetXPConnect();
    4102          155853 :     if (!xpc)
    4103               0 :         return NS_ERROR_FAILURE;
    4104          155853 :     rv = xpc->GetCurrentJSStack(aStack);
    4105          155853 :     return rv;
    4106                 : }
    4107                 : 
    4108                 : NS_IMETHODIMP
    4109            3824 : nsXPCComponents::GetManager(nsIComponentManager * *aManager)
    4110                 : {
    4111            3824 :     NS_ASSERTION(aManager, "bad param");
    4112            3824 :     return NS_GetComponentManager(aManager);
    4113                 : }
    4114                 : 
    4115                 : /**********************************************/
    4116                 : 
    4117                 : // The nsIXPCScriptable map declaration that will generate stubs for us...
    4118                 : #define XPC_MAP_CLASSNAME           nsXPCComponents
    4119                 : #define XPC_MAP_QUOTED_CLASSNAME   "nsXPCComponents"
    4120                 : #define                             XPC_MAP_WANT_NEWRESOLVE
    4121                 : #define                             XPC_MAP_WANT_GETPROPERTY
    4122                 : #define                             XPC_MAP_WANT_SETPROPERTY
    4123                 : #define XPC_MAP_FLAGS               nsIXPCScriptable::ALLOW_PROP_MODS_DURING_RESOLVE
    4124                 : #include "xpc_map_end.h" /* This will #undef the above */
    4125                 : 
    4126                 : /* bool newResolve (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval id, in PRUint32 flags, out JSObjectPtr objp); */
    4127                 : NS_IMETHODIMP
    4128          161341 : nsXPCComponents::NewResolve(nsIXPConnectWrappedNative *wrapper,
    4129                 :                             JSContext * cx, JSObject * obj,
    4130                 :                             jsid id, PRUint32 flags,
    4131                 :                             JSObject * *objp, bool *_retval)
    4132                 : {
    4133          161341 :     XPCJSRuntime* rt = nsXPConnect::GetRuntimeInstance();
    4134          161341 :     if (!rt)
    4135               0 :         return NS_ERROR_FAILURE;
    4136                 : 
    4137          161341 :     unsigned attrs = 0;
    4138                 : 
    4139          161341 :     if (id == rt->GetStringID(XPCJSRuntime::IDX_LAST_RESULT))
    4140               2 :         attrs = JSPROP_READONLY;
    4141          161339 :     else if (id != rt->GetStringID(XPCJSRuntime::IDX_RETURN_CODE))
    4142          161339 :         return NS_OK;
    4143                 : 
    4144               2 :     *objp = obj;
    4145                 :     *_retval = JS_DefinePropertyById(cx, obj, id, JSVAL_VOID, nsnull, nsnull,
    4146                 :                                      JSPROP_ENUMERATE | JSPROP_PERMANENT |
    4147               2 :                                      attrs);
    4148               2 :     return NS_OK;
    4149                 : }
    4150                 : 
    4151                 : /* bool getProperty (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval id, in JSValPtr vp); */
    4152                 : NS_IMETHODIMP
    4153               2 : nsXPCComponents::GetProperty(nsIXPConnectWrappedNative *wrapper,
    4154                 :                              JSContext * cx, JSObject * obj,
    4155                 :                              jsid id, jsval * vp, bool *_retval)
    4156                 : {
    4157               2 :     XPCContext* xpcc = XPCContext::GetXPCContext(cx);
    4158               2 :     if (!xpcc)
    4159               0 :         return NS_ERROR_FAILURE;
    4160                 : 
    4161               2 :     bool doResult = false;
    4162                 :     nsresult res;
    4163               2 :     XPCJSRuntime* rt = xpcc->GetRuntime();
    4164               2 :     if (id == rt->GetStringID(XPCJSRuntime::IDX_LAST_RESULT)) {
    4165               2 :         res = xpcc->GetLastResult();
    4166               2 :         doResult = true;
    4167               0 :     } else if (id == rt->GetStringID(XPCJSRuntime::IDX_RETURN_CODE)) {
    4168               0 :         res = xpcc->GetPendingResult();
    4169               0 :         doResult = true;
    4170                 :     }
    4171                 : 
    4172               2 :     nsresult rv = NS_OK;
    4173               2 :     if (doResult) {
    4174               2 :         if (!JS_NewNumberValue(cx, (double) res, vp))
    4175               0 :             return NS_ERROR_OUT_OF_MEMORY;
    4176               2 :         rv = NS_SUCCESS_I_DID_SOMETHING;
    4177                 :     }
    4178                 : 
    4179               2 :     return rv;
    4180                 : }
    4181                 : 
    4182                 : /* bool setProperty (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsid id, in JSValPtr vp); */
    4183                 : NS_IMETHODIMP
    4184               0 : nsXPCComponents::SetProperty(nsIXPConnectWrappedNative *wrapper,
    4185                 :                              JSContext * cx, JSObject * obj, jsid id,
    4186                 :                              jsval * vp, bool *_retval)
    4187                 : {
    4188               0 :     XPCContext* xpcc = XPCContext::GetXPCContext(cx);
    4189               0 :     if (!xpcc)
    4190               0 :         return NS_ERROR_FAILURE;
    4191                 : 
    4192               0 :     XPCJSRuntime* rt = xpcc->GetRuntime();
    4193               0 :     if (!rt)
    4194               0 :         return NS_ERROR_FAILURE;
    4195                 : 
    4196               0 :     if (id == rt->GetStringID(XPCJSRuntime::IDX_RETURN_CODE)) {
    4197                 :         nsresult rv;
    4198               0 :         if (JS_ValueToECMAUint32(cx, *vp, (uint32_t*)&rv)) {
    4199               0 :             xpcc->SetPendingResult(rv);
    4200               0 :             xpcc->SetLastResult(rv);
    4201               0 :             return NS_SUCCESS_I_DID_SOMETHING;
    4202                 :         }
    4203               0 :         return NS_ERROR_FAILURE;
    4204                 :     }
    4205                 : 
    4206               0 :     return NS_ERROR_XPC_CANT_MODIFY_PROP_ON_WN;
    4207                 : }
    4208                 : 
    4209                 : // static
    4210                 : JSBool
    4211           15475 : nsXPCComponents::AttachNewComponentsObject(XPCCallContext& ccx,
    4212                 :                                            XPCWrappedNativeScope* aScope,
    4213                 :                                            JSObject* aGlobal)
    4214                 : {
    4215           15475 :     if (!aGlobal)
    4216               0 :         return false;
    4217                 : 
    4218           15475 :     nsXPCComponents* components = new nsXPCComponents();
    4219           15475 :     if (!components)
    4220               0 :         return false;
    4221                 : 
    4222           30950 :     nsCOMPtr<nsIXPCComponents> cholder(components);
    4223                 : 
    4224           30950 :     AutoMarkingNativeInterfacePtr iface(ccx);
    4225           15475 :     iface = XPCNativeInterface::GetNewOrUsed(ccx, &NS_GET_IID(nsIXPCComponents));
    4226                 : 
    4227           15475 :     if (!iface)
    4228               0 :         return false;
    4229                 : 
    4230           30950 :     nsCOMPtr<XPCWrappedNative> wrapper;
    4231           30950 :     xpcObjectHelper helper(cholder);
    4232           15475 :     XPCWrappedNative::GetNewOrUsed(ccx, helper, aScope, iface, getter_AddRefs(wrapper));
    4233           15475 :     if (!wrapper)
    4234               0 :         return false;
    4235                 : 
    4236           15475 :     aScope->SetComponents(components);
    4237                 : 
    4238           15475 :     jsid id = ccx.GetRuntime()->GetStringID(XPCJSRuntime::IDX_COMPONENTS);
    4239                 :     JSObject* obj;
    4240                 : 
    4241           15475 :     return NS_SUCCEEDED(wrapper->GetJSObject(&obj)) &&
    4242           15475 :            obj && JS_DefinePropertyById(ccx, aGlobal, id, OBJECT_TO_JSVAL(obj),
    4243                 :                                         nsnull, nsnull,
    4244           30950 :                                         JSPROP_PERMANENT | JSPROP_READONLY);
    4245                 : }
    4246                 : 
    4247                 : /* void lookupMethod (); */
    4248                 : NS_IMETHODIMP
    4249               0 : nsXPCComponents::LookupMethod(const JS::Value& object,
    4250                 :                               const JS::Value& name,
    4251                 :                               JSContext *cx,
    4252                 :                               JS::Value *retval)
    4253                 : {
    4254               0 :     NS_WARNING("Components.lookupMethod deprecated, use Components.utils.lookupMethod");
    4255                 : 
    4256               0 :     nsCOMPtr<nsIXPCComponents_Utils> utils;
    4257               0 :     nsresult rv = GetUtils(getter_AddRefs(utils));
    4258               0 :     if (NS_FAILED(rv))
    4259               0 :         return rv;
    4260                 : 
    4261               0 :     return utils->LookupMethod(object, name, cx, retval);
    4262                 : }
    4263                 : 
    4264                 : /* void reportError (); */
    4265               0 : NS_IMETHODIMP nsXPCComponents::ReportError(const JS::Value &error, JSContext *cx)
    4266                 : {
    4267               0 :     NS_WARNING("Components.reportError deprecated, use Components.utils.reportError");
    4268                 : 
    4269               0 :     nsCOMPtr<nsIXPCComponents_Utils> utils;
    4270               0 :     nsresult rv = GetUtils(getter_AddRefs(utils));
    4271               0 :     if (NS_FAILED(rv))
    4272               0 :         return rv;
    4273                 : 
    4274               0 :     return utils->ReportError(error, cx);
    4275                 : }
    4276                 : 
    4277                 : /* string canCreateWrapper (in nsIIDPtr iid); */
    4278                 : NS_IMETHODIMP
    4279            3468 : nsXPCComponents::CanCreateWrapper(const nsIID * iid, char **_retval)
    4280                 : {
    4281                 :     // We let anyone do this...
    4282            3468 :     *_retval = xpc_CloneAllAccess();
    4283            3468 :     return NS_OK;
    4284                 : }
    4285                 : 
    4286                 : /* string canCallMethod (in nsIIDPtr iid, in wstring methodName); */
    4287                 : NS_IMETHODIMP
    4288               0 : nsXPCComponents::CanCallMethod(const nsIID * iid, const PRUnichar *methodName, char **_retval)
    4289                 : {
    4290                 :     static const char* allowed[] = { "isSuccessCode", "lookupMethod", nsnull };
    4291               0 :     *_retval = xpc_CheckAccessList(methodName, allowed);
    4292               0 :     return NS_OK;
    4293                 : }
    4294                 : 
    4295                 : /* string canGetProperty (in nsIIDPtr iid, in wstring propertyName); */
    4296                 : NS_IMETHODIMP
    4297               0 : nsXPCComponents::CanGetProperty(const nsIID * iid, const PRUnichar *propertyName, char **_retval)
    4298                 : {
    4299                 :     static const char* allowed[] = { "interfaces", "interfacesByID", "results", nsnull};
    4300               0 :     *_retval = xpc_CheckAccessList(propertyName, allowed);
    4301               0 :     return NS_OK;
    4302                 : }
    4303                 : 
    4304                 : /* string canSetProperty (in nsIIDPtr iid, in wstring propertyName); */
    4305                 : NS_IMETHODIMP
    4306               0 : nsXPCComponents::CanSetProperty(const nsIID * iid, const PRUnichar *propertyName, char **_retval)
    4307                 : {
    4308                 :     // If you have to ask, then the answer is NO
    4309               0 :     *_retval = nsnull;
    4310               0 :     return NS_OK;
    4311                 : }

Generated by: LCOV version 1.7