LCOV - code coverage report
Current view: directory - js/xpconnect/src - xpcprivate.h (source / functions) Found Hit Coverage
Test: app.info Lines: 846 728 86.1 %
Date: 2012-06-02 Functions: 464 395 85.1 %

       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                 :  *   Mike Shaver <shaver@mozilla.org>
      28                 :  *   Mark Hammond <MarkH@ActiveState.com>
      29                 :  *
      30                 :  * Alternatively, the contents of this file may be used under the terms of
      31                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      32                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      33                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      34                 :  * of those above. If you wish to allow use of your version of this file only
      35                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      36                 :  * use your version of this file under the terms of the MPL, indicate your
      37                 :  * decision by deleting the provisions above and replace them with the notice
      38                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      39                 :  * the provisions above, a recipient may use your version of this file under
      40                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      41                 :  *
      42                 :  * ***** END LICENSE BLOCK ***** */
      43                 : 
      44                 : /* All the XPConnect private declarations - only include locally. */
      45                 : 
      46                 : #ifndef xpcprivate_h___
      47                 : #define xpcprivate_h___
      48                 : 
      49                 : #include "mozilla/Assertions.h"
      50                 : #include "mozilla/Attributes.h"
      51                 : #include "mozilla/Util.h"
      52                 : 
      53                 : #include <string.h>
      54                 : #include <stdlib.h>
      55                 : #include <stdarg.h>
      56                 : #include <math.h>
      57                 : #include "xpcpublic.h"
      58                 : #include "jsapi.h"
      59                 : #include "jsdhash.h"
      60                 : #include "jsprf.h"
      61                 : #include "prprf.h"
      62                 : #include "jsdbgapi.h"
      63                 : #include "jsfriendapi.h"
      64                 : #include "jsgc.h"
      65                 : #include "jswrapper.h"
      66                 : #include "nscore.h"
      67                 : #include "nsXPCOM.h"
      68                 : #include "nsAutoPtr.h"
      69                 : #include "nsCycleCollectionParticipant.h"
      70                 : #include "nsCycleCollector.h"
      71                 : #include "nsDebug.h"
      72                 : #include "nsISupports.h"
      73                 : #include "nsIServiceManager.h"
      74                 : #include "nsIClassInfoImpl.h"
      75                 : #include "nsIComponentManager.h"
      76                 : #include "nsIComponentRegistrar.h"
      77                 : #include "nsISupportsPrimitives.h"
      78                 : #include "nsMemory.h"
      79                 : #include "nsIXPConnect.h"
      80                 : #include "nsIInterfaceInfo.h"
      81                 : #include "nsIInterfaceInfoManager.h"
      82                 : #include "nsIXPCScriptable.h"
      83                 : #include "nsIXPCSecurityManager.h"
      84                 : #include "nsIJSRuntimeService.h"
      85                 : #include "nsWeakReference.h"
      86                 : #include "nsCOMPtr.h"
      87                 : #include "nsXPTCUtils.h"
      88                 : #include "xptinfo.h"
      89                 : #include "XPCForwards.h"
      90                 : #include "XPCLog.h"
      91                 : #include "xpccomponents.h"
      92                 : #include "xpcexception.h"
      93                 : #include "xpcjsid.h"
      94                 : #include "prlong.h"
      95                 : #include "prmem.h"
      96                 : #include "prenv.h"
      97                 : #include "prclist.h"
      98                 : #include "nsString.h"
      99                 : #include "nsReadableUtils.h"
     100                 : #include "nsXPIDLString.h"
     101                 : #include "nsAutoJSValHolder.h"
     102                 : #include "mozilla/GuardObjects.h"
     103                 : #include "mozilla/ReentrantMonitor.h"
     104                 : #include "mozilla/Mutex.h"
     105                 : #include "nsDataHashtable.h"
     106                 : 
     107                 : #include "nsThreadUtils.h"
     108                 : #include "nsIJSContextStack.h"
     109                 : #include "nsIJSEngineTelemetryStats.h"
     110                 : #include "nsDeque.h"
     111                 : 
     112                 : #include "nsIConsoleService.h"
     113                 : #include "nsIScriptError.h"
     114                 : #include "nsIExceptionService.h"
     115                 : 
     116                 : #include "nsVariant.h"
     117                 : #include "nsIPropertyBag.h"
     118                 : #include "nsIProperty.h"
     119                 : #include "nsCOMArray.h"
     120                 : #include "nsTArray.h"
     121                 : #include "nsBaseHashtable.h"
     122                 : #include "nsHashKeys.h"
     123                 : #include "nsWrapperCache.h"
     124                 : #include "nsStringBuffer.h"
     125                 : 
     126                 : #include "nsIScriptSecurityManager.h"
     127                 : #include "nsNetUtil.h"
     128                 : 
     129                 : #include "nsIXPCScriptNotify.h"  // used to notify: ScriptEvaluated
     130                 : 
     131                 : #include "nsIScriptObjectPrincipal.h"
     132                 : #include "nsIPrincipal.h"
     133                 : #include "nsISecurityCheckedComponent.h"
     134                 : 
     135                 : #include "nsIThreadInternal.h"
     136                 : 
     137                 : #ifdef XP_WIN
     138                 : // Nasty MS defines
     139                 : #ifdef GetClassInfo
     140                 : #undef GetClassInfo
     141                 : #endif
     142                 : #ifdef GetClassName
     143                 : #undef GetClassName
     144                 : #endif
     145                 : #endif /* XP_WIN */
     146                 : 
     147                 : #include "nsINode.h"
     148                 : 
     149                 : /***************************************************************************/
     150                 : // Compile time switches for instrumentation and stuff....
     151                 : 
     152                 : // Note that one would not normally turn *any* of these on in a non-DEBUG build.
     153                 : 
     154                 : #if defined(DEBUG_jband) || defined(DEBUG_jst) || defined(DEBUG_dbradley) || defined(DEBUG_shaver_no) || defined(DEBUG_timeless)
     155                 : #define DEBUG_xpc_hacker
     156                 : #endif
     157                 : 
     158                 : #if defined(DEBUG_brendan)
     159                 : #define DEBUG_XPCNativeWrapper 1
     160                 : #endif
     161                 : 
     162                 : #ifdef DEBUG
     163                 : #define XPC_DETECT_LEADING_UPPERCASE_ACCESS_ERRORS
     164                 : #endif
     165                 : #define XPC_CHECK_WRAPPER_THREADSAFETY
     166                 : 
     167                 : #if defined(DEBUG_xpc_hacker)
     168                 : #define XPC_DUMP_AT_SHUTDOWN
     169                 : #define XPC_TRACK_WRAPPER_STATS
     170                 : #define XPC_TRACK_SCOPE_STATS
     171                 : #define XPC_TRACK_PROTO_STATS
     172                 : #define XPC_TRACK_DEFERRED_RELEASES
     173                 : #define XPC_CHECK_WRAPPERS_AT_SHUTDOWN
     174                 : #define XPC_REPORT_SHADOWED_WRAPPED_NATIVE_MEMBERS
     175                 : #define XPC_CHECK_CLASSINFO_CLAIMS
     176                 : #if defined(DEBUG_jst)
     177                 : #define XPC_ASSERT_CLASSINFO_CLAIMS
     178                 : #endif
     179                 : //#define DEBUG_stats_jband 1
     180                 : //#define XPC_REPORT_NATIVE_INTERFACE_AND_SET_FLUSHING
     181                 : //#define XPC_REPORT_JSCLASS_FLUSHING
     182                 : //#define XPC_TRACK_AUTOMARKINGPTR_STATS
     183                 : #endif
     184                 : 
     185                 : #if defined(DEBUG_dbaron) || defined(DEBUG_bzbarsky) // only part of DEBUG_xpc_hacker!
     186                 : #define XPC_DUMP_AT_SHUTDOWN
     187                 : #endif
     188                 : 
     189                 : /***************************************************************************/
     190                 : // conditional forward declarations....
     191                 : 
     192                 : #ifdef XPC_REPORT_SHADOWED_WRAPPED_NATIVE_MEMBERS
     193                 : void DEBUG_ReportShadowedMembers(XPCNativeSet* set,
     194                 :                                  XPCWrappedNative* wrapper,
     195                 :                                  XPCWrappedNativeProto* proto);
     196                 : #else
     197                 : #define DEBUG_ReportShadowedMembers(set, wrapper, proto) ((void)0)
     198                 : #endif
     199                 : 
     200                 : #ifdef XPC_CHECK_WRAPPER_THREADSAFETY
     201                 : void DEBUG_ReportWrapperThreadSafetyError(XPCCallContext& ccx,
     202                 :                                           const char* msg,
     203                 :                                           const XPCWrappedNative* wrapper);
     204                 : void DEBUG_CheckWrapperThreadSafety(const XPCWrappedNative* wrapper);
     205                 : #else
     206                 : #define DEBUG_CheckWrapperThreadSafety(w) ((void)0)
     207                 : #endif
     208                 : 
     209                 : /***************************************************************************/
     210                 : // default initial sizes for maps (hashtables)
     211                 : 
     212                 : #define XPC_CONTEXT_MAP_SIZE                16
     213                 : #define XPC_JS_MAP_SIZE                     64
     214                 : #define XPC_JS_CLASS_MAP_SIZE               64
     215                 : 
     216                 : #define XPC_NATIVE_MAP_SIZE                 64
     217                 : #define XPC_NATIVE_PROTO_MAP_SIZE           16
     218                 : #define XPC_DYING_NATIVE_PROTO_MAP_SIZE     16
     219                 : #define XPC_DETACHED_NATIVE_PROTO_MAP_SIZE  32
     220                 : #define XPC_NATIVE_INTERFACE_MAP_SIZE       64
     221                 : #define XPC_NATIVE_SET_MAP_SIZE             64
     222                 : #define XPC_NATIVE_JSCLASS_MAP_SIZE         32
     223                 : #define XPC_THIS_TRANSLATOR_MAP_SIZE         8
     224                 : #define XPC_NATIVE_WRAPPER_MAP_SIZE         16
     225                 : #define XPC_WRAPPER_MAP_SIZE                16
     226                 : 
     227                 : /***************************************************************************/
     228                 : // data declarations...
     229                 : extern const char XPC_CONTEXT_STACK_CONTRACTID[];
     230                 : extern const char XPC_RUNTIME_CONTRACTID[];
     231                 : extern const char XPC_EXCEPTION_CONTRACTID[];
     232                 : extern const char XPC_CONSOLE_CONTRACTID[];
     233                 : extern const char XPC_SCRIPT_ERROR_CONTRACTID[];
     234                 : extern const char XPC_ID_CONTRACTID[];
     235                 : extern const char XPC_XPCONNECT_CONTRACTID[];
     236                 : 
     237                 : namespace xpc {
     238                 : 
     239                 : class PtrAndPrincipalHashKey : public PLDHashEntryHdr
     240                 : {
     241                 :   public:
     242                 :     typedef PtrAndPrincipalHashKey *KeyType;
     243                 :     typedef const PtrAndPrincipalHashKey *KeyTypePointer;
     244                 : 
     245            3369 :     PtrAndPrincipalHashKey(const PtrAndPrincipalHashKey *aKey)
     246                 :       : mPtr(aKey->mPtr), mPrincipal(aKey->mPrincipal),
     247            3369 :         mSavedHash(aKey->mSavedHash)
     248                 :     {
     249            3369 :         MOZ_COUNT_CTOR(PtrAndPrincipalHashKey);
     250            3369 :     }
     251                 : 
     252           18564 :     PtrAndPrincipalHashKey(nsISupports *aPtr, nsIPrincipal *aPrincipal)
     253           18564 :       : mPtr(aPtr), mPrincipal(aPrincipal)
     254                 :     {
     255           18564 :         MOZ_COUNT_CTOR(PtrAndPrincipalHashKey);
     256           37128 :         nsCOMPtr<nsIURI> uri;
     257           18564 :         aPrincipal->GetURI(getter_AddRefs(uri));
     258                 :         mSavedHash = uri
     259            2828 :                      ? NS_SecurityHashURI(uri)
     260           21392 :                      : (NS_PTR_TO_UINT32(mPtr.get()) >> 2);
     261           18564 :     }
     262                 : 
     263           21929 :     ~PtrAndPrincipalHashKey()
     264           21929 :     {
     265           21929 :         MOZ_COUNT_DTOR(PtrAndPrincipalHashKey);
     266           21929 :     }
     267                 : 
     268           58428 :     PtrAndPrincipalHashKey* GetKey() const
     269                 :     {
     270           58428 :         return const_cast<PtrAndPrincipalHashKey*>(this);
     271                 :     }
     272                 :     const PtrAndPrincipalHashKey* GetKeyPointer() const { return this; }
     273                 : 
     274                 :     inline bool KeyEquals(const PtrAndPrincipalHashKey* aKey) const;
     275                 : 
     276                 :     static const PtrAndPrincipalHashKey*
     277           25298 :     KeyToPointer(PtrAndPrincipalHashKey* aKey) { return aKey; }
     278           25298 :     static PLDHashNumber HashKey(const PtrAndPrincipalHashKey* aKey)
     279                 :     {
     280           25298 :         return aKey->mSavedHash;
     281                 :     }
     282                 : 
     283               0 :     nsISupports* GetPtr()
     284                 :     {
     285               0 :         return mPtr;
     286                 :     }
     287                 : 
     288                 :     enum { ALLOW_MEMMOVE = true };
     289                 : 
     290                 :   protected:
     291                 :     nsCOMPtr<nsISupports> mPtr;
     292                 :     nsCOMPtr<nsIPrincipal> mPrincipal;
     293                 : 
     294                 :     // During shutdown, when we GC, we need to remove these keys from the hash
     295                 :     // table. However, computing the saved hash, NS_SecurityHashURI calls back
     296                 :     // into XPCOM (which is illegal during shutdown). In order to avoid this,
     297                 :     // we compute the hash up front, so when we're in GC during shutdown, we
     298                 :     // don't have to call into XPCOM.
     299                 :     PLDHashNumber mSavedHash;
     300                 : };
     301                 : 
     302                 : }
     303                 : 
     304                 : // This map is only used on the main thread.
     305                 : typedef nsDataHashtable<xpc::PtrAndPrincipalHashKey, JSCompartment *> XPCCompartmentMap;
     306                 : 
     307                 : /***************************************************************************/
     308                 : // Useful macros...
     309                 : 
     310                 : #define XPC_STRING_GETTER_BODY(dest, src)                                     \
     311                 :     NS_ENSURE_ARG_POINTER(dest);                                              \
     312                 :     char* result;                                                             \
     313                 :     if (src)                                                                  \
     314                 :         result = (char*) nsMemory::Clone(src,                                 \
     315                 :                                          sizeof(char)*(strlen(src)+1));       \
     316                 :     else                                                                      \
     317                 :         result = nsnull;                                                      \
     318                 :     *dest = result;                                                           \
     319                 :     return (result || !src) ? NS_OK : NS_ERROR_OUT_OF_MEMORY
     320                 : 
     321                 : 
     322                 : #define WRAPPER_SLOTS (JSCLASS_HAS_PRIVATE | JSCLASS_IMPLEMENTS_BARRIERS | \
     323                 :                        JSCLASS_HAS_RESERVED_SLOTS(1))
     324                 : 
     325                 : #define INVALID_OBJECT ((JSObject *)1)
     326                 : 
     327                 : /***************************************************************************/
     328                 : // Auto locking support class...
     329                 : 
     330                 : // We PROMISE to never screw this up.
     331                 : #ifdef _MSC_VER
     332                 : #pragma warning(disable : 4355) // OK to pass "this" in member initializer
     333                 : #endif
     334                 : 
     335                 : typedef mozilla::ReentrantMonitor XPCLock;
     336                 : 
     337                 : static inline void xpc_Wait(XPCLock* lock)
     338                 :     {
     339                 :         NS_ASSERTION(lock, "xpc_Wait called with null lock!");
     340                 :         lock->Wait();
     341                 :     }
     342                 : 
     343           14728 : static inline void xpc_NotifyAll(XPCLock* lock)
     344                 :     {
     345           14728 :         NS_ASSERTION(lock, "xpc_NotifyAll called with null lock!");
     346           14728 :         lock->NotifyAll();
     347           14728 :     }
     348                 : 
     349                 : // This is a cloned subset of nsAutoMonitor. We want the use of a monitor -
     350                 : // mostly because we need reenterability - but we also want to support passing
     351                 : // a null monitor in without things blowing up. This is used for wrappers that
     352                 : // are guaranteed to be used only on one thread. We avoid lock overhead by
     353                 : // using a null monitor. By changing this class we can avoid having multiplte
     354                 : // code paths or (conditional) manual calls to PR_{Enter,Exit}Monitor.
     355                 : //
     356                 : // Note that xpconnect only makes *one* monitor and *mostly* holds it locked
     357                 : // only through very small critical sections.
     358                 : 
     359                 : class NS_STACK_CLASS XPCAutoLock {
     360                 : public:
     361                 : 
     362            1404 :     static XPCLock* NewLock(const char* name)
     363            1404 :                         {return new mozilla::ReentrantMonitor(name);}
     364            1403 :     static void     DestroyLock(XPCLock* lock)
     365            2806 :                         {delete lock;}
     366                 : 
     367        32759450 :     XPCAutoLock(XPCLock* lock MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
     368        32759450 :         : mLock(lock)
     369                 :     {
     370        32759450 :         MOZ_GUARD_OBJECT_NOTIFIER_INIT;
     371        32759450 :         if (mLock)
     372        16397565 :             mLock->Enter();
     373        32759450 :     }
     374                 : 
     375        32759450 :     ~XPCAutoLock()
     376        32759450 :     {
     377        32759450 :         if (mLock) {
     378        16397565 :             mLock->Exit();
     379                 :         }
     380        32759450 :     }
     381                 : 
     382                 : private:
     383                 :     XPCLock*  mLock;
     384                 :     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
     385                 : 
     386                 :     // Not meant to be implemented. This makes it a compiler error to
     387                 :     // construct or assign an XPCAutoLock object incorrectly.
     388                 :     XPCAutoLock(void) {}
     389                 :     XPCAutoLock(XPCAutoLock& /*aMon*/) {}
     390                 :     XPCAutoLock& operator =(XPCAutoLock& /*aMon*/) {
     391                 :         return *this;
     392                 :     }
     393                 : 
     394                 :     // Not meant to be implemented. This makes it a compiler error to
     395                 :     // attempt to create an XPCAutoLock object on the heap.
     396                 :     static void* operator new(size_t /*size*/) CPP_THROW_NEW {
     397                 :         return nsnull;
     398                 :     }
     399                 :     static void operator delete(void* /*memory*/) {}
     400                 : };
     401                 : 
     402                 : /************************************************/
     403                 : 
     404                 : class NS_STACK_CLASS XPCAutoUnlock {
     405                 : public:
     406         1522567 :     XPCAutoUnlock(XPCLock* lock MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
     407         1522567 :         : mLock(lock)
     408                 :     {
     409         1522567 :         MOZ_GUARD_OBJECT_NOTIFIER_INIT;
     410         1522567 :         if (mLock) {
     411          348503 :             mLock->Exit();
     412                 :         }
     413         1522567 :     }
     414                 : 
     415         1522567 :     ~XPCAutoUnlock()
     416         1522567 :     {
     417         1522567 :         if (mLock)
     418          348503 :             mLock->Enter();
     419         1522567 :     }
     420                 : 
     421                 : private:
     422                 :     XPCLock*  mLock;
     423                 :     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
     424                 : 
     425                 :     // Not meant to be implemented. This makes it a compiler error to
     426                 :     // construct or assign an XPCAutoUnlock object incorrectly.
     427                 :     XPCAutoUnlock(void) {}
     428                 :     XPCAutoUnlock(XPCAutoUnlock& /*aMon*/) {}
     429                 :     XPCAutoUnlock& operator =(XPCAutoUnlock& /*aMon*/) {
     430                 :         return *this;
     431                 :     }
     432                 : 
     433                 :     // Not meant to be implemented. This makes it a compiler error to
     434                 :     // attempt to create an XPCAutoUnlock object on the heap.
     435                 :     static void* operator new(size_t /*size*/) CPP_THROW_NEW {
     436                 :         return nsnull;
     437                 :     }
     438                 :     static void operator delete(void* /*memory*/) {}
     439                 : };
     440                 : 
     441                 : /***************************************************************************
     442                 : ****************************************************************************
     443                 : *
     444                 : * Core runtime and context classes...
     445                 : *
     446                 : ****************************************************************************
     447                 : ***************************************************************************/
     448                 : 
     449                 : // We have a general rule internally that getters that return addref'd interface
     450                 : // pointer generally do so using an 'out' parm. When interface pointers are
     451                 : // returned as function call result values they are not addref'd. Exceptions
     452                 : // to this rule are noted explicitly.
     453                 : 
     454                 : // JSTRACE_XML can recursively hold on to more JSTRACE_XML objects, adding it to
     455                 : // the cycle collector avoids stack overflow.
     456                 : inline bool
     457         4738826 : AddToCCKind(JSGCTraceKind kind)
     458                 : {
     459         4738826 :     return kind == JSTRACE_OBJECT || kind == JSTRACE_XML || kind == JSTRACE_SCRIPT;
     460                 : }
     461                 : 
     462                 : class nsXPConnect : public nsIXPConnect,
     463                 :                     public nsIThreadObserver,
     464                 :                     public nsSupportsWeakReference,
     465                 :                     public nsCycleCollectionJSRuntime,
     466                 :                     public nsCycleCollectionParticipant,
     467                 :                     public nsIJSRuntimeService,
     468                 :                     public nsIThreadJSContextStack,
     469                 :                     public nsIJSEngineTelemetryStats
     470                 : {
     471                 : public:
     472                 :     // all the interface method declarations...
     473                 :     NS_DECL_ISUPPORTS
     474                 :     NS_DECL_NSIXPCONNECT
     475                 :     NS_DECL_NSITHREADOBSERVER
     476                 :     NS_DECL_NSIJSRUNTIMESERVICE
     477                 :     NS_DECL_NSIJSCONTEXTSTACK
     478                 :     NS_DECL_NSITHREADJSCONTEXTSTACK
     479                 :     NS_DECL_NSIJSENGINETELEMETRYSTATS
     480                 : 
     481                 :     // non-interface implementation
     482                 : public:
     483                 :     // These get non-addref'd pointers
     484                 :     static nsXPConnect*  GetXPConnect();
     485             321 :     static nsXPConnect*  FastGetXPConnect() { return gSelf ? gSelf : GetXPConnect(); }
     486                 :     static XPCJSRuntime* GetRuntimeInstance();
     487         2504789 :     XPCJSRuntime* GetRuntime() {return mRuntime;}
     488                 : 
     489                 :     // Gets addref'd pointer
     490                 :     static nsresult GetInterfaceInfoManager(nsIInterfaceInfoSuperManager** iim,
     491                 :                                             nsXPConnect* xpc = nsnull);
     492                 : 
     493                 :     static JSBool IsISupportsDescendant(nsIInterfaceInfo* info);
     494                 : 
     495         1639069 :     nsIXPCSecurityManager* GetDefaultSecurityManager() const
     496                 :     {
     497                 :         // mDefaultSecurityManager is main-thread only.
     498         1639069 :         if (!NS_IsMainThread()) {
     499               0 :             return nsnull;
     500                 :         }
     501         1639069 :         return mDefaultSecurityManager;
     502                 :     }
     503                 : 
     504         1636899 :     PRUint16 GetDefaultSecurityManagerFlags() const
     505         1636899 :         {return mDefaultSecurityManagerFlags;}
     506                 : 
     507                 :     // This returns an AddRef'd pointer. It does not do this with an 'out' param
     508                 :     // only because this form is required by the generic module macro:
     509                 :     // NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR
     510                 :     static nsXPConnect* GetSingleton();
     511                 : 
     512                 :     // Called by module code in dll startup
     513            1404 :     static void InitStatics() { gSelf = nsnull; gOnceAliveNowDead = false; }
     514                 :     // Called by module code on dll shutdown.
     515                 :     static void ReleaseXPConnectSingleton();
     516                 : 
     517                 :     virtual ~nsXPConnect();
     518                 : 
     519           58912 :     JSBool IsShuttingDown() const {return mShuttingDown;}
     520                 : 
     521               0 :     void EnsureGCBeforeCC() { mNeedGCBeforeCC = true; }
     522           14728 :     void ClearGCBeforeCC() { mNeedGCBeforeCC = false; }
     523                 : 
     524                 :     nsresult GetInfoForIID(const nsIID * aIID, nsIInterfaceInfo** info);
     525                 :     nsresult GetInfoForName(const char * name, nsIInterfaceInfo** info);
     526                 : 
     527                 :     // nsCycleCollectionParticipant
     528                 :     NS_IMETHOD Root(void *p);
     529                 :     NS_IMETHOD Unlink(void *p);
     530                 :     NS_IMETHOD Unroot(void *p);
     531                 :     NS_IMETHOD Traverse(void *p,
     532                 :                         nsCycleCollectionTraversalCallback &cb);
     533                 : 
     534                 :     // nsCycleCollectionLanguageRuntime
     535                 :     virtual bool NotifyLeaveMainThread();
     536                 :     virtual void NotifyEnterCycleCollectionThread();
     537                 :     virtual void NotifyLeaveCycleCollectionThread();
     538                 :     virtual void NotifyEnterMainThread();
     539                 :     virtual nsresult BeginCycleCollection(nsCycleCollectionTraversalCallback &cb,
     540                 :                                           bool explainExpectedLiveGarbage);
     541                 :     virtual nsresult FinishTraverse();
     542                 :     virtual nsresult FinishCycleCollection();
     543                 :     virtual nsCycleCollectionParticipant *ToParticipant(void *p);
     544                 :     virtual bool NeedCollect();
     545                 :     virtual void Collect(PRUint32 reason, PRUint32 kind);
     546                 : #ifdef DEBUG_CC
     547                 :     virtual void PrintAllReferencesTo(void *p);
     548                 : #endif
     549                 : 
     550                 :     XPCCallContext *GetCycleCollectionContext()
     551                 :     {
     552                 :         return mCycleCollectionContext;
     553                 :     }
     554                 : 
     555                 :     unsigned GetOutstandingRequests(JSContext* cx);
     556                 : 
     557                 :     // This returns the singleton nsCycleCollectionParticipant for JSContexts.
     558                 :     static nsCycleCollectionParticipant *JSContextParticipant();
     559                 : 
     560                 :     virtual nsIPrincipal* GetPrincipal(JSObject* obj,
     561                 :                                        bool allowShortCircuit) const;
     562                 : 
     563                 :     void RecordTraversal(void *p, nsISupports *s);
     564                 :     virtual char* DebugPrintJSStack(bool showArgs,
     565                 :                                     bool showLocals,
     566                 :                                     bool showThisProps);
     567                 : 
     568                 : 
     569            6434 :     static bool ReportAllJSExceptions()
     570                 :     {
     571            6434 :       return gReportAllJSExceptions > 0;
     572                 :     }
     573                 : 
     574                 :     static void CheckForDebugMode(JSRuntime *rt);
     575                 : 
     576                 : protected:
     577                 :     nsXPConnect();
     578                 : 
     579                 : private:
     580                 :     static PRThread* FindMainThread();
     581                 : 
     582                 : private:
     583                 :     // Singleton instance
     584                 :     static nsXPConnect*      gSelf;
     585                 :     static JSBool            gOnceAliveNowDead;
     586                 : 
     587                 :     XPCJSRuntime*            mRuntime;
     588                 :     nsCOMPtr<nsIInterfaceInfoSuperManager> mInterfaceInfoManager;
     589                 :     nsIXPCSecurityManager*   mDefaultSecurityManager;
     590                 :     PRUint16                 mDefaultSecurityManagerFlags;
     591                 :     JSBool                   mShuttingDown;
     592                 :     JSBool                   mNeedGCBeforeCC;
     593                 : 
     594                 :     // nsIThreadInternal doesn't remember which observers it called
     595                 :     // OnProcessNextEvent on when it gets around to calling AfterProcessNextEvent.
     596                 :     // So if XPConnect gets initialized mid-event (which can happen), we'll get
     597                 :     // an 'after' notification without getting an 'on' notification. If we don't
     598                 :     // watch out for this, we'll do an unmatched |pop| on the context stack.
     599                 :     PRUint16                   mEventDepth;
     600                 : #ifdef DEBUG_CC
     601                 :     PLDHashTable             mJSRoots;
     602                 : #endif
     603                 :     nsAutoPtr<XPCCallContext> mCycleCollectionContext;
     604                 : 
     605                 :     typedef nsBaseHashtable<nsVoidPtrHashKey, nsISupports*, nsISupports*> ScopeSet;
     606                 :     ScopeSet mScopes;
     607                 :     nsCOMPtr<nsIXPCScriptable> mBackstagePass;
     608                 : 
     609                 :     static PRUint32 gReportAllJSExceptions;
     610                 :     static JSBool gDebugMode;
     611                 :     static JSBool gDesiredDebugMode;
     612                 : 
     613                 : public:
     614                 :     static nsIScriptSecurityManager *gScriptSecurityManager;
     615                 : };
     616                 : 
     617                 : /***************************************************************************/
     618                 : 
     619                 : class XPCRootSetElem
     620                 : {
     621                 : public:
     622          110263 :     XPCRootSetElem()
     623                 :     {
     624                 : #ifdef DEBUG
     625          110263 :         mNext = nsnull;
     626          110263 :         mSelfp = nsnull;
     627                 : #endif
     628          110263 :     }
     629                 : 
     630          109982 :     ~XPCRootSetElem()
     631                 :     {
     632          109982 :         NS_ASSERTION(!mNext, "Must be unlinked");
     633          109982 :         NS_ASSERTION(!mSelfp, "Must be unlinked");
     634          109982 :     }
     635                 : 
     636          161048 :     inline XPCRootSetElem* GetNextRoot() { return mNext; }
     637                 :     void AddToRootSet(XPCLock *lock, XPCRootSetElem **listHead);
     638                 :     void RemoveFromRootSet(XPCLock *lock);
     639                 : 
     640                 : private:
     641                 :     XPCRootSetElem *mNext;
     642                 :     XPCRootSetElem **mSelfp;
     643                 : };
     644                 : 
     645                 : /***************************************************************************/
     646                 : 
     647                 : // In the current xpconnect system there can only be one XPCJSRuntime.
     648                 : // So, xpconnect can only be used on one JSRuntime within the process.
     649                 : 
     650                 : // no virtuals. no refcounting.
     651                 : class XPCJSRuntime
     652                 : {
     653                 : public:
     654                 :     static XPCJSRuntime* newXPCJSRuntime(nsXPConnect* aXPConnect);
     655                 : 
     656         1790145 :     JSRuntime*     GetJSRuntime() const {return mJSRuntime;}
     657         1844435 :     nsXPConnect*   GetXPConnect() const {return mXPConnect;}
     658                 :     JSContext*     GetJSCycleCollectionContext();
     659                 : 
     660          335219 :     JSObject2WrappedJSMap*     GetWrappedJSMap()        const
     661          335219 :         {return mWrappedJSMap;}
     662                 : 
     663          223193 :     IID2WrappedJSClassMap*     GetWrappedJSClassMap()   const
     664          223193 :         {return mWrappedJSClassMap;}
     665                 : 
     666         2560804 :     IID2NativeInterfaceMap* GetIID2NativeInterfaceMap() const
     667         2560804 :         {return mIID2NativeInterfaceMap;}
     668                 : 
     669          375119 :     ClassInfo2NativeSetMap* GetClassInfo2NativeSetMap() const
     670          375119 :         {return mClassInfo2NativeSetMap;}
     671                 : 
     672         1194982 :     NativeSetMap* GetNativeSetMap() const
     673         1194982 :         {return mNativeSetMap;}
     674                 : 
     675            9176 :     IID2ThisTranslatorMap* GetThisTranslatorMap() const
     676            9176 :         {return mThisTranslatorMap;}
     677                 : 
     678          251192 :     XPCNativeScriptableSharedMap* GetNativeScriptableSharedMap() const
     679          251192 :         {return mNativeScriptableSharedMap;}
     680                 : 
     681          188185 :     XPCWrappedNativeProtoMap* GetDyingWrappedNativeProtoMap() const
     682          188185 :         {return mDyingWrappedNativeProtoMap;}
     683                 : 
     684          191297 :     XPCWrappedNativeProtoMap* GetDetachedWrappedNativeProtoMap() const
     685          191297 :         {return mDetachedWrappedNativeProtoMap;}
     686                 : 
     687            1404 :     XPCNativeWrapperMap* GetExplicitNativeWrapperMap() const
     688            1404 :         {return mExplicitNativeWrapperMap;}
     689                 : 
     690           49928 :     XPCCompartmentMap& GetCompartmentMap()
     691           49928 :         {return mCompartmentMap;}
     692                 : 
     693        16587562 :     XPCLock* GetMapLock() const {return mMapLock;}
     694                 : 
     695                 :     JSBool OnJSContextNew(JSContext* cx);
     696                 : 
     697                 :     JSBool DeferredRelease(nsISupports* obj);
     698                 : 
     699         1255492 :     JSBool GetDoingFinalization() const {return mDoingFinalization;}
     700                 : 
     701                 :     // Mapping of often used strings to jsid atoms that live 'forever'.
     702                 :     //
     703                 :     // To add a new string: add to this list and to XPCJSRuntime::mStrings
     704                 :     // at the top of xpcjsruntime.cpp
     705                 :     enum {
     706                 :         IDX_CONSTRUCTOR             = 0 ,
     707                 :         IDX_TO_STRING               ,
     708                 :         IDX_TO_SOURCE               ,
     709                 :         IDX_LAST_RESULT             ,
     710                 :         IDX_RETURN_CODE             ,
     711                 :         IDX_VALUE                   ,
     712                 :         IDX_QUERY_INTERFACE         ,
     713                 :         IDX_COMPONENTS              ,
     714                 :         IDX_WRAPPED_JSOBJECT        ,
     715                 :         IDX_OBJECT                  ,
     716                 :         IDX_FUNCTION                ,
     717                 :         IDX_PROTOTYPE               ,
     718                 :         IDX_CREATE_INSTANCE         ,
     719                 :         IDX_ITEM                    ,
     720                 :         IDX_PROTO                   ,
     721                 :         IDX_ITERATOR                ,
     722                 :         IDX_EXPOSEDPROPS            ,
     723                 :         IDX_SCRIPTONLY              ,
     724                 :         IDX_BASEURIOBJECT           ,
     725                 :         IDX_NODEPRINCIPAL           ,
     726                 :         IDX_DOCUMENTURIOBJECT       ,
     727                 :         IDX_TOTAL_COUNT // just a count of the above
     728                 :     };
     729                 : 
     730        12865156 :     jsid GetStringID(unsigned index) const
     731                 :     {
     732        12865156 :         NS_ASSERTION(index < IDX_TOTAL_COUNT, "index out of range");
     733        12865156 :         return mStrIDs[index];
     734                 :     }
     735                 :     jsval GetStringJSVal(unsigned index) const
     736                 :     {
     737                 :         NS_ASSERTION(index < IDX_TOTAL_COUNT, "index out of range");
     738                 :         return mStrJSVals[index];
     739                 :     }
     740            1888 :     const char* GetStringName(unsigned index) const
     741                 :     {
     742            1888 :         NS_ASSERTION(index < IDX_TOTAL_COUNT, "index out of range");
     743            1888 :         return mStrings[index];
     744                 :     }
     745                 : 
     746                 :     static void TraceBlackJS(JSTracer* trc, void* data);
     747                 :     static void TraceGrayJS(JSTracer* trc, void* data);
     748                 :     void TraceXPConnectRoots(JSTracer *trc);
     749                 :     void AddXPConnectRoots(nsCycleCollectionTraversalCallback& cb);
     750                 :     void UnmarkSkippableJSHolders();
     751                 : 
     752                 :     static void GCCallback(JSRuntime *rt, JSGCStatus status);
     753                 :     static void FinalizeCallback(JSContext *cx, JSFinalizeStatus status);
     754                 : 
     755                 :     inline void AddVariantRoot(XPCTraceableVariant* variant);
     756                 :     inline void AddWrappedJSRoot(nsXPCWrappedJS* wrappedJS);
     757                 :     inline void AddObjectHolderRoot(XPCJSObjectHolder* holder);
     758                 : 
     759                 :     nsresult AddJSHolder(void* aHolder, nsScriptObjectTracer* aTracer);
     760                 :     nsresult RemoveJSHolder(void* aHolder);
     761                 : 
     762                 :     static void SuspectWrappedNative(XPCWrappedNative *wrapper,
     763                 :                                      nsCycleCollectionTraversalCallback &cb);
     764                 : 
     765                 :     void DebugDump(PRInt16 depth);
     766                 : 
     767                 :     void SystemIsBeingShutDown();
     768                 : 
     769         2007018 :     PRThread* GetThreadRunningGC() const {return mThreadRunningGC;}
     770                 : 
     771                 :     ~XPCJSRuntime();
     772                 : 
     773                 : #ifdef XPC_CHECK_WRAPPERS_AT_SHUTDOWN
     774                 :    void DEBUG_AddWrappedNative(nsIXPConnectWrappedNative* wrapper)
     775                 :         {XPCAutoLock lock(GetMapLock());
     776                 :          JSDHashEntryHdr *entry =
     777                 :             JS_DHashTableOperate(DEBUG_WrappedNativeHashtable,
     778                 :                                  wrapper, JS_DHASH_ADD);
     779                 :          if (entry) ((JSDHashEntryStub *)entry)->key = wrapper;}
     780                 : 
     781                 :    void DEBUG_RemoveWrappedNative(nsIXPConnectWrappedNative* wrapper)
     782                 :         {XPCAutoLock lock(GetMapLock());
     783                 :          JS_DHashTableOperate(DEBUG_WrappedNativeHashtable,
     784                 :                               wrapper, JS_DHASH_REMOVE);}
     785                 : private:
     786                 :    JSDHashTable* DEBUG_WrappedNativeHashtable;
     787                 : public:
     788                 : #endif
     789                 : 
     790                 :     void AddGCCallback(JSGCCallback cb);
     791                 :     void RemoveGCCallback(JSGCCallback cb);
     792                 : 
     793                 :     static void ActivityCallback(void *arg, JSBool active);
     794                 : 
     795           15475 :     bool NewDOMBindingsEnabled()
     796                 :     {
     797           15475 :         return gNewDOMBindingsEnabled;
     798                 :     }
     799                 : 
     800                 :     size_t SizeOfIncludingThis(nsMallocSizeOfFun mallocSizeOf);
     801                 : 
     802                 : private:
     803                 :     XPCJSRuntime(); // no implementation
     804                 :     XPCJSRuntime(nsXPConnect* aXPConnect);
     805                 : 
     806                 :     // The caller must be holding the GC lock
     807                 :     void RescheduleWatchdog(XPCContext* ccx);
     808                 : 
     809                 :     static void WatchdogMain(void *arg);
     810                 : 
     811                 :     static bool gNewDOMBindingsEnabled;
     812                 : 
     813                 :     static const char* mStrings[IDX_TOTAL_COUNT];
     814                 :     jsid mStrIDs[IDX_TOTAL_COUNT];
     815                 :     jsval mStrJSVals[IDX_TOTAL_COUNT];
     816                 : 
     817                 :     nsXPConnect*             mXPConnect;
     818                 :     JSRuntime*               mJSRuntime;
     819                 :     JSContext*               mJSCycleCollectionContext;
     820                 :     JSObject2WrappedJSMap*   mWrappedJSMap;
     821                 :     IID2WrappedJSClassMap*   mWrappedJSClassMap;
     822                 :     IID2NativeInterfaceMap*  mIID2NativeInterfaceMap;
     823                 :     ClassInfo2NativeSetMap*  mClassInfo2NativeSetMap;
     824                 :     NativeSetMap*            mNativeSetMap;
     825                 :     IID2ThisTranslatorMap*   mThisTranslatorMap;
     826                 :     XPCNativeScriptableSharedMap* mNativeScriptableSharedMap;
     827                 :     XPCWrappedNativeProtoMap* mDyingWrappedNativeProtoMap;
     828                 :     XPCWrappedNativeProtoMap* mDetachedWrappedNativeProtoMap;
     829                 :     XPCNativeWrapperMap*     mExplicitNativeWrapperMap;
     830                 :     XPCCompartmentMap        mCompartmentMap;
     831                 :     XPCLock* mMapLock;
     832                 :     PRThread* mThreadRunningGC;
     833                 :     nsTArray<nsXPCWrappedJS*> mWrappedJSToReleaseArray;
     834                 :     nsTArray<nsISupports*> mNativesToReleaseArray;
     835                 :     JSBool mDoingFinalization;
     836                 :     XPCRootSetElem *mVariantRoots;
     837                 :     XPCRootSetElem *mWrappedJSRoots;
     838                 :     XPCRootSetElem *mObjectHolderRoots;
     839                 :     JSDHashTable mJSHolders;
     840                 :     PRLock *mWatchdogLock;
     841                 :     PRCondVar *mWatchdogWakeup;
     842                 :     PRThread *mWatchdogThread;
     843                 :     nsTArray<JSGCCallback> extraGCCallbacks;
     844                 :     bool mWatchdogHibernating;
     845                 :     PRTime mLastActiveTime; // -1 if active NOW
     846                 : 
     847                 :     friend class AutoLockWatchdog;
     848                 : };
     849                 : 
     850                 : /***************************************************************************/
     851                 : /***************************************************************************/
     852                 : // XPCContext is mostly a dumb class to hold JSContext specific data and
     853                 : // maps that let us find wrappers created for the given JSContext.
     854                 : 
     855                 : // no virtuals
     856                 : class XPCContext
     857                 : {
     858                 :     friend class XPCJSRuntime;
     859                 : public:
     860        16067049 :     static XPCContext* GetXPCContext(JSContext* aJSContext)
     861                 :         {
     862        16067049 :             NS_ASSERTION(JS_GetSecondContextPrivate(aJSContext), "should already have XPCContext");
     863        16067049 :             return static_cast<XPCContext *>(JS_GetSecondContextPrivate(aJSContext));
     864                 :         }
     865                 : 
     866        14136287 :     XPCJSRuntime* GetRuntime() const {return mRuntime;}
     867           94253 :     JSContext* GetJSContext() const {return mJSContext;}
     868                 : 
     869                 :     enum LangType {LANG_UNKNOWN, LANG_JS, LANG_NATIVE};
     870                 : 
     871                 :     LangType GetCallingLangType() const
     872                 :         {
     873                 :             return mCallingLangType;
     874                 :         }
     875        31749366 :     LangType SetCallingLangType(LangType lt)
     876                 :         {
     877        31749366 :             LangType tmp = mCallingLangType;
     878        31749366 :             mCallingLangType = lt;
     879        31749366 :             return tmp;
     880                 :         }
     881        15213089 :     JSBool CallerTypeIsJavaScript() const
     882                 :         {
     883        15213089 :             return LANG_JS == mCallingLangType;
     884                 :         }
     885                 :     JSBool CallerTypeIsNative() const
     886                 :         {
     887                 :             return LANG_NATIVE == mCallingLangType;
     888                 :         }
     889         8460745 :     JSBool CallerTypeIsKnown() const
     890                 :         {
     891         8460745 :             return LANG_UNKNOWN != mCallingLangType;
     892                 :         }
     893                 : 
     894            6889 :     nsresult GetException(nsIException** e)
     895                 :         {
     896            6889 :             NS_IF_ADDREF(mException);
     897            6889 :             *e = mException;
     898            6889 :             return NS_OK;
     899                 :         }
     900         1225740 :     void SetException(nsIException* e)
     901                 :         {
     902         1225740 :             NS_IF_ADDREF(e);
     903         1225740 :             NS_IF_RELEASE(mException);
     904         1225740 :             mException = e;
     905         1225740 :         }
     906                 : 
     907               2 :     nsresult GetLastResult() {return mLastResult;}
     908        13504660 :     void SetLastResult(nsresult rc) {mLastResult = rc;}
     909                 : 
     910            6889 :     nsresult GetPendingResult() {return mPendingResult;}
     911         1225564 :     void SetPendingResult(nsresult rc) {mPendingResult = rc;}
     912                 : 
     913            1387 :     nsIXPCSecurityManager* GetSecurityManager() const
     914            1387 :         {return mSecurityManager;}
     915            1387 :     void SetSecurityManager(nsIXPCSecurityManager* aSecurityManager)
     916            1387 :         {mSecurityManager = aSecurityManager;}
     917                 : 
     918               0 :     PRUint16 GetSecurityManagerFlags() const
     919               0 :         {return mSecurityManagerFlags;}
     920            1387 :     void SetSecurityManagerFlags(PRUint16 f)
     921            1387 :         {mSecurityManagerFlags = f;}
     922                 : 
     923         8460745 :     nsIXPCSecurityManager* GetAppropriateSecurityManager(PRUint16 flags) const
     924                 :         {
     925         8460745 :             NS_ASSERTION(CallerTypeIsKnown(),"missing caller type set somewhere");
     926         8460745 :             if (!CallerTypeIsJavaScript())
     927          597769 :                 return nsnull;
     928         7862976 :             if (mSecurityManager) {
     929         6226077 :                 if (flags & mSecurityManagerFlags)
     930         6226077 :                     return mSecurityManager;
     931                 :             } else {
     932                 :                 nsIXPCSecurityManager* mgr;
     933         1636899 :                 nsXPConnect* xpc = mRuntime->GetXPConnect();
     934         1636899 :                 mgr = xpc->GetDefaultSecurityManager();
     935         1636899 :                 if (mgr && (flags & xpc->GetDefaultSecurityManagerFlags()))
     936         1636899 :                     return mgr;
     937                 :             }
     938               0 :             return nsnull;
     939                 :         }
     940                 : 
     941                 :     void DebugDump(PRInt16 depth);
     942           15475 :     void AddScope(PRCList *scope) { PR_INSERT_AFTER(scope, &mScopes); }
     943            1639 :     void RemoveScope(PRCList *scope) { PR_REMOVE_LINK(scope); }
     944                 : 
     945                 :     ~XPCContext();
     946                 : 
     947                 : private:
     948                 :     XPCContext();    // no implementation
     949                 :     XPCContext(XPCJSRuntime* aRuntime, JSContext* aJSContext);
     950                 : 
     951                 :     static XPCContext* newXPCContext(XPCJSRuntime* aRuntime,
     952                 :                                      JSContext* aJSContext);
     953                 : private:
     954                 :     XPCJSRuntime* mRuntime;
     955                 :     JSContext*  mJSContext;
     956                 :     nsresult mLastResult;
     957                 :     nsresult mPendingResult;
     958                 :     nsIXPCSecurityManager* mSecurityManager;
     959                 :     nsIException* mException;
     960                 :     LangType mCallingLangType;
     961                 :     PRUint16 mSecurityManagerFlags;
     962                 : 
     963                 :     // A linked list of scopes to notify when we are destroyed.
     964                 :     PRCList mScopes;
     965                 : };
     966                 : 
     967                 : /***************************************************************************/
     968                 : 
     969                 : #define NATIVE_CALLER  XPCContext::LANG_NATIVE
     970                 : #define JS_CALLER      XPCContext::LANG_JS
     971                 : 
     972                 : // class to export a JSString as an const nsAString, no refcounting :(
     973                 : class XPCReadableJSStringWrapper : public nsDependentString
     974          241865 : {
     975                 : public:
     976                 :     typedef nsDependentString::char_traits char_traits;
     977                 : 
     978          258385 :     XPCReadableJSStringWrapper(const PRUnichar *chars, size_t length) :
     979          258385 :         nsDependentString(chars, length)
     980          258385 :     { }
     981                 : 
     982           22486 :     XPCReadableJSStringWrapper() :
     983           22486 :         nsDependentString(char_traits::sEmptyBuffer, char_traits::sEmptyBuffer)
     984           22486 :     { SetIsVoid(true); }
     985                 : 
     986                 :     JSBool init(JSContext* aContext, JSString* str)
     987                 :     {
     988                 :         size_t length;
     989                 :         const jschar* chars = JS_GetStringCharsZAndLength(aContext, str, &length);
     990                 :         if (!chars)
     991                 :             return false;
     992                 : 
     993                 :         NS_ASSERTION(IsEmpty(), "init() on initialized string");
     994                 :         new(static_cast<nsDependentString *>(this)) nsDependentString(chars, length);
     995                 :         return true;
     996                 :     }
     997                 : };
     998                 : 
     999                 : // No virtuals
    1000                 : // XPCCallContext is ALWAYS declared as a local variable in some function;
    1001                 : // i.e. instance lifetime is always controled by some C++ function returning.
    1002                 : //
    1003                 : // These things are created frequently in many places. We *intentionally* do
    1004                 : // not inialialize all members in order to save on construction overhead.
    1005                 : // Some constructor pass more valid params than others. We init what must be
    1006                 : // init'd and leave other members undefined. In debug builds the accessors
    1007                 : // use a CHECK_STATE macro to track whether or not the object is in a valid
    1008                 : // state to answer the question a caller might be asking. As long as this
    1009                 : // class is maintained correctly it can do its job without a bunch of added
    1010                 : // overhead from useless initializations and non-DEBUG error checking.
    1011                 : //
    1012                 : // Note that most accessors are inlined.
    1013                 : 
    1014                 : class XPCCallContext : public nsAXPCNativeCallContext
    1015                 : {
    1016                 : public:
    1017                 :     NS_IMETHOD GetCallee(nsISupports **aResult);
    1018                 :     NS_IMETHOD GetCalleeMethodIndex(PRUint16 *aResult);
    1019                 :     NS_IMETHOD GetCalleeWrapper(nsIXPConnectWrappedNative **aResult);
    1020                 :     NS_IMETHOD GetJSContext(JSContext **aResult);
    1021                 :     NS_IMETHOD GetArgc(PRUint32 *aResult);
    1022                 :     NS_IMETHOD GetArgvPtr(jsval **aResult);
    1023                 :     NS_IMETHOD GetCalleeInterface(nsIInterfaceInfo **aResult);
    1024                 :     NS_IMETHOD GetCalleeClassInfo(nsIClassInfo **aResult);
    1025                 :     NS_IMETHOD GetPreviousCallContext(nsAXPCNativeCallContext **aResult);
    1026                 :     NS_IMETHOD GetLanguage(PRUint16 *aResult);
    1027                 : 
    1028                 :     enum {NO_ARGS = (unsigned) -1};
    1029                 : 
    1030                 :     XPCCallContext(XPCContext::LangType callerLanguage,
    1031                 :                    JSContext* cx    = nsnull,
    1032                 :                    JSObject* obj    = nsnull,
    1033                 :                    JSObject* funobj = nsnull,
    1034                 :                    jsid id          = JSID_VOID,
    1035                 :                    unsigned argc       = NO_ARGS,
    1036                 :                    jsval *argv      = nsnull,
    1037                 :                    jsval *rval      = nsnull);
    1038                 : 
    1039                 :     virtual ~XPCCallContext();
    1040                 : 
    1041                 :     inline JSBool                       IsValid() const ;
    1042                 : 
    1043                 :     inline nsXPConnect*                 GetXPConnect() const ;
    1044                 :     inline XPCJSRuntime*                GetRuntime() const ;
    1045                 :     inline XPCPerThreadData*            GetThreadData() const ;
    1046                 :     inline XPCContext*                  GetXPCContext() const ;
    1047                 :     inline JSContext*                   GetJSContext() const ;
    1048                 :     inline JSBool                       GetContextPopRequired() const ;
    1049                 :     inline XPCContext::LangType         GetCallerLanguage() const ;
    1050                 :     inline XPCContext::LangType         GetPrevCallerLanguage() const ;
    1051                 :     inline XPCCallContext*              GetPrevCallContext() const ;
    1052                 : 
    1053                 :     /*
    1054                 :      * The 'scope for new JSObjects' will be the scope for objects created when
    1055                 :      * carrying out a JS/C++ call. This member is only available if HAVE_SCOPE.
    1056                 :      * The object passed to the ccx constructor is used as the scope for new
    1057                 :      * JSObjects. However, this object is also queried for a wrapper, so
    1058                 :      * clients that don't want a wrapper (and thus pass NULL to the ccx
    1059                 :      * constructor) need to manually call SetScopeForNewJSObjects.
    1060                 :      */
    1061                 :     inline JSObject*                    GetScopeForNewJSObjects() const ;
    1062                 :     inline void                         SetScopeForNewJSObjects(JSObject *obj) ;
    1063                 : 
    1064                 :     inline JSObject*                    GetFlattenedJSObject() const ;
    1065                 :     inline nsISupports*                 GetIdentityObject() const ;
    1066                 :     inline XPCWrappedNative*            GetWrapper() const ;
    1067                 :     inline XPCWrappedNativeProto*       GetProto() const ;
    1068                 : 
    1069                 :     inline JSBool                       CanGetTearOff() const ;
    1070                 :     inline XPCWrappedNativeTearOff*     GetTearOff() const ;
    1071                 : 
    1072                 :     inline XPCNativeScriptableInfo*     GetScriptableInfo() const ;
    1073                 :     inline JSBool                       CanGetSet() const ;
    1074                 :     inline XPCNativeSet*                GetSet() const ;
    1075                 :     inline JSBool                       CanGetInterface() const ;
    1076                 :     inline XPCNativeInterface*          GetInterface() const ;
    1077                 :     inline XPCNativeMember*             GetMember() const ;
    1078                 :     inline JSBool                       HasInterfaceAndMember() const ;
    1079                 :     inline jsid                         GetName() const ;
    1080                 :     inline JSBool                       GetStaticMemberIsLocal() const ;
    1081                 :     inline unsigned                        GetArgc() const ;
    1082                 :     inline jsval*                       GetArgv() const ;
    1083                 :     inline jsval*                       GetRetVal() const ;
    1084                 : 
    1085                 :     inline PRUint16                     GetMethodIndex() const ;
    1086                 :     inline void                         SetMethodIndex(PRUint16 index) ;
    1087                 : 
    1088                 :     inline JSBool   GetDestroyJSContextInDestructor() const;
    1089                 :     inline void     SetDestroyJSContextInDestructor(JSBool b);
    1090                 : 
    1091                 :     inline jsid GetResolveName() const;
    1092                 :     inline jsid SetResolveName(jsid name);
    1093                 : 
    1094                 :     inline XPCWrappedNative* GetResolvingWrapper() const;
    1095                 :     inline XPCWrappedNative* SetResolvingWrapper(XPCWrappedNative* w);
    1096                 : 
    1097                 :     inline void SetRetVal(jsval val);
    1098                 : 
    1099                 :     void SetName(jsid name);
    1100                 :     void SetArgsAndResultPtr(unsigned argc, jsval *argv, jsval *rval);
    1101                 :     void SetCallInfo(XPCNativeInterface* iface, XPCNativeMember* member,
    1102                 :                      JSBool isSetter);
    1103                 : 
    1104                 :     nsresult  CanCallNow();
    1105                 : 
    1106                 :     void SystemIsBeingShutDown();
    1107                 : 
    1108        39810616 :     operator JSContext*() const {return GetJSContext();}
    1109                 : 
    1110                 :     XPCReadableJSStringWrapper *NewStringWrapper(const PRUnichar *str, PRUint32 len);
    1111                 :     void DeleteString(nsAString *string);
    1112                 : 
    1113                 : private:
    1114                 : 
    1115                 :     // no copy ctor or assignment allowed
    1116                 :     XPCCallContext(const XPCCallContext& r); // not implemented
    1117                 :     XPCCallContext& operator= (const XPCCallContext& r); // not implemented
    1118                 : 
    1119                 :     friend class XPCLazyCallContext;
    1120                 :     XPCCallContext(XPCContext::LangType callerLanguage,
    1121                 :                    JSContext* cx,
    1122                 :                    JSBool callBeginRequest,
    1123                 :                    JSObject* obj,
    1124                 :                    JSObject* flattenedJSObject,
    1125                 :                    XPCWrappedNative* wn,
    1126                 :                    XPCWrappedNativeTearOff* tearoff);
    1127                 : 
    1128                 :     enum WrapperInitOptions {
    1129                 :         WRAPPER_PASSED_TO_CONSTRUCTOR,
    1130                 :         INIT_SHOULD_LOOKUP_WRAPPER
    1131                 :     };
    1132                 : 
    1133                 :     void Init(XPCContext::LangType callerLanguage,
    1134                 :               JSBool callBeginRequest,
    1135                 :               JSObject* obj,
    1136                 :               JSObject* funobj,
    1137                 :               WrapperInitOptions wrapperInitOptions,
    1138                 :               jsid name,
    1139                 :               unsigned argc,
    1140                 :               jsval *argv,
    1141                 :               jsval *rval);
    1142                 : 
    1143                 : private:
    1144                 :     // posible values for mState
    1145                 :     enum State {
    1146                 :         INIT_FAILED,
    1147                 :         SYSTEM_SHUTDOWN,
    1148                 :         HAVE_CONTEXT,
    1149                 :         HAVE_SCOPE,
    1150                 :         HAVE_OBJECT,
    1151                 :         HAVE_NAME,
    1152                 :         HAVE_ARGS,
    1153                 :         READY_TO_CALL,
    1154                 :         CALL_DONE
    1155                 :     };
    1156                 : 
    1157                 : #ifdef DEBUG
    1158       297806288 : inline void CHECK_STATE(int s) const {NS_ASSERTION(mState >= s, "bad state");}
    1159                 : #else
    1160                 : #define CHECK_STATE(s) ((void)0)
    1161                 : #endif
    1162                 : 
    1163                 : private:
    1164                 :     State                           mState;
    1165                 : 
    1166                 :     nsXPConnect*                    mXPC;
    1167                 : 
    1168                 :     XPCPerThreadData*               mThreadData;
    1169                 :     XPCContext*                     mXPCContext;
    1170                 :     JSContext*                      mJSContext;
    1171                 :     JSBool                          mContextPopRequired;
    1172                 :     JSBool                          mDestroyJSContextInDestructor;
    1173                 : 
    1174                 :     XPCContext::LangType            mCallerLanguage;
    1175                 : 
    1176                 :     // ctor does not necessarily init the following. BEWARE!
    1177                 : 
    1178                 :     XPCContext::LangType            mPrevCallerLanguage;
    1179                 : 
    1180                 :     XPCCallContext*                 mPrevCallContext;
    1181                 : 
    1182                 :     JSObject*                       mScopeForNewJSObjects;
    1183                 :     JSObject*                       mFlattenedJSObject;
    1184                 :     XPCWrappedNative*               mWrapper;
    1185                 :     XPCWrappedNativeTearOff*        mTearOff;
    1186                 : 
    1187                 :     XPCNativeScriptableInfo*        mScriptableInfo;
    1188                 : 
    1189                 :     XPCNativeSet*                   mSet;
    1190                 :     XPCNativeInterface*             mInterface;
    1191                 :     XPCNativeMember*                mMember;
    1192                 : 
    1193                 :     jsid                            mName;
    1194                 :     JSBool                          mStaticMemberIsLocal;
    1195                 : 
    1196                 :     unsigned                           mArgc;
    1197                 :     jsval*                          mArgv;
    1198                 :     jsval*                          mRetVal;
    1199                 : 
    1200                 :     PRUint16                        mMethodIndex;
    1201                 : 
    1202                 : #define XPCCCX_STRING_CACHE_SIZE 2
    1203                 : 
    1204                 :     // String wrapper entry, holds a string, and a boolean that tells
    1205                 :     // whether the string is in use or not.
    1206                 :     //
    1207                 :     // NB: The string is not stored by value so that we avoid the cost of
    1208                 :     // construction/destruction.
    1209                 :     struct StringWrapperEntry
    1210                 :     {
    1211        31749366 :         StringWrapperEntry() : mInUse(false) { }
    1212                 : 
    1213                 :         js::AlignedStorage2<XPCReadableJSStringWrapper> mString;
    1214                 :         bool mInUse;
    1215                 :     };
    1216                 : 
    1217                 :     StringWrapperEntry mScratchStrings[XPCCCX_STRING_CACHE_SIZE];
    1218                 : };
    1219                 : 
    1220                 : class XPCLazyCallContext
    1221                 : {
    1222                 : public:
    1223        20940305 :     XPCLazyCallContext(XPCCallContext& ccx)
    1224                 :         : mCallBeginRequest(DONT_CALL_BEGINREQUEST),
    1225                 :           mCcx(&ccx),
    1226                 :           mCcxToDestroy(nsnull)
    1227                 : #ifdef DEBUG
    1228                 :           , mCx(nsnull)
    1229                 :           , mCallerLanguage(JS_CALLER)
    1230                 :           , mObj(nsnull)
    1231                 :           , mFlattenedJSObject(nsnull)
    1232                 :           , mWrapper(nsnull)
    1233        20940305 :           , mTearOff(nsnull)
    1234                 : #endif
    1235                 :     {
    1236        20940305 :     }
    1237          142781 :     XPCLazyCallContext(XPCContext::LangType callerLanguage, JSContext* cx,
    1238                 :                        JSObject* obj = nsnull,
    1239                 :                        JSObject* flattenedJSObject = nsnull,
    1240                 :                        XPCWrappedNative* wrapper = nsnull,
    1241                 :                        XPCWrappedNativeTearOff* tearoff = nsnull)
    1242                 :         : mCallBeginRequest(callerLanguage == NATIVE_CALLER ?
    1243                 :                             CALL_BEGINREQUEST : DONT_CALL_BEGINREQUEST),
    1244                 :           mCcx(nsnull),
    1245                 :           mCcxToDestroy(nsnull),
    1246                 :           mCx(cx),
    1247                 :           mCallerLanguage(callerLanguage),
    1248                 :           mObj(obj),
    1249                 :           mFlattenedJSObject(flattenedJSObject),
    1250                 :           mWrapper(wrapper),
    1251          142781 :           mTearOff(tearoff)
    1252                 :     {
    1253          142781 :         NS_ASSERTION(cx, "Need a JS context!");
    1254          142781 :         NS_ASSERTION(callerLanguage == NATIVE_CALLER ||
    1255                 :                      callerLanguage == JS_CALLER,
    1256                 :                      "Can't deal with unknown caller language!");
    1257                 : #ifdef DEBUG
    1258          142781 :         AssertContextIsTopOfStack(cx);
    1259                 : #endif
    1260          142781 :     }
    1261        21083086 :     ~XPCLazyCallContext()
    1262                 :     {
    1263        21083086 :         if (mCcxToDestroy)
    1264          132930 :             mCcxToDestroy->~XPCCallContext();
    1265        20950156 :         else if (mCallBeginRequest == CALLED_BEGINREQUEST)
    1266               0 :             JS_EndRequest(mCx);
    1267        21083086 :     }
    1268                 :     void SetWrapper(XPCWrappedNative* wrapper,
    1269                 :                     XPCWrappedNativeTearOff* tearoff);
    1270                 :     void SetWrapper(JSObject* flattenedJSObject);
    1271                 : 
    1272        25219838 :     JSContext *GetJSContext()
    1273                 :     {
    1274        25219838 :         if (mCcx)
    1275        24955205 :             return mCcx->GetJSContext();
    1276                 : 
    1277          264633 :         if (mCallBeginRequest == CALL_BEGINREQUEST) {
    1278          103009 :             JS_BeginRequest(mCx);
    1279          103009 :             mCallBeginRequest = CALLED_BEGINREQUEST;
    1280                 :         }
    1281                 : 
    1282          264633 :         return mCx;
    1283                 :     }
    1284         8820036 :     JSObject *GetScopeForNewJSObjects() const
    1285                 :     {
    1286         8820036 :         if (mCcx)
    1287         8544038 :             return mCcx->GetScopeForNewJSObjects();
    1288                 : 
    1289          275998 :         return mObj;
    1290                 :     }
    1291          648602 :     void SetScopeForNewJSObjects(JSObject *obj)
    1292                 :     {
    1293          648602 :         if (mCcx) {
    1294          545593 :             mCcx->SetScopeForNewJSObjects(obj);
    1295          545593 :             return;
    1296                 :         }
    1297          103009 :         NS_ABORT_IF_FALSE(!mObj, "already set!");
    1298          103009 :         mObj = obj;
    1299                 :     }
    1300                 :     JSObject *GetFlattenedJSObject() const
    1301                 :     {
    1302                 :         if (mCcx)
    1303                 :             return mCcx->GetFlattenedJSObject();
    1304                 : 
    1305                 :         return mFlattenedJSObject;
    1306                 :     }
    1307         5505747 :     XPCCallContext &GetXPCCallContext()
    1308                 :     {
    1309         5505747 :         if (!mCcx) {
    1310                 :             mCcxToDestroy = mCcx =
    1311                 :                 new (mData) XPCCallContext(mCallerLanguage, mCx,
    1312                 :                                            mCallBeginRequest == CALL_BEGINREQUEST,
    1313                 :                                            mObj,
    1314                 :                                            mFlattenedJSObject, mWrapper,
    1315          132930 :                                            mTearOff);
    1316          132930 :             if (!mCcx->IsValid()) {
    1317               0 :                 NS_ERROR("This is not supposed to fail!");
    1318                 :             }
    1319                 :         }
    1320                 : 
    1321         5505747 :         return *mCcx;
    1322                 :     }
    1323                 : 
    1324                 : private:
    1325                 : #ifdef DEBUG
    1326                 :     static void AssertContextIsTopOfStack(JSContext* cx);
    1327                 : #endif
    1328                 : 
    1329                 :     enum {
    1330                 :         DONT_CALL_BEGINREQUEST,
    1331                 :         CALL_BEGINREQUEST,
    1332                 :         CALLED_BEGINREQUEST
    1333                 :     } mCallBeginRequest;
    1334                 : 
    1335                 :     XPCCallContext *mCcx;
    1336                 :     XPCCallContext *mCcxToDestroy;
    1337                 :     JSContext *mCx;
    1338                 :     XPCContext::LangType mCallerLanguage;
    1339                 :     JSObject *mObj;
    1340                 :     JSObject *mFlattenedJSObject;
    1341                 :     XPCWrappedNative *mWrapper;
    1342                 :     XPCWrappedNativeTearOff *mTearOff;
    1343                 :     char mData[sizeof(XPCCallContext)];
    1344                 : };
    1345                 : 
    1346                 : /***************************************************************************
    1347                 : ****************************************************************************
    1348                 : *
    1349                 : * Core classes for wrapped native objects for use from JavaScript...
    1350                 : *
    1351                 : ****************************************************************************
    1352                 : ***************************************************************************/
    1353                 : 
    1354                 : // These are the various JSClasses and callbacks whose use that required
    1355                 : // visibility from more than one .cpp file.
    1356                 : 
    1357                 : struct XPCWrappedNativeJSClass;
    1358                 : extern XPCWrappedNativeJSClass XPC_WN_NoHelper_JSClass;
    1359                 : extern js::Class XPC_WN_NoMods_WithCall_Proto_JSClass;
    1360                 : extern js::Class XPC_WN_NoMods_NoCall_Proto_JSClass;
    1361                 : extern js::Class XPC_WN_ModsAllowed_WithCall_Proto_JSClass;
    1362                 : extern js::Class XPC_WN_ModsAllowed_NoCall_Proto_JSClass;
    1363                 : extern js::Class XPC_WN_Tearoff_JSClass;
    1364                 : extern js::Class XPC_WN_NoHelper_Proto_JSClass;
    1365                 : 
    1366                 : extern JSBool
    1367                 : XPC_WN_Equality(JSContext *cx, JSObject *obj, const jsval *v, JSBool *bp);
    1368                 : 
    1369                 : extern JSBool
    1370                 : XPC_WN_CallMethod(JSContext *cx, unsigned argc, jsval *vp);
    1371                 : 
    1372                 : extern JSBool
    1373                 : XPC_WN_GetterSetter(JSContext *cx, unsigned argc, jsval *vp);
    1374                 : 
    1375                 : extern JSBool
    1376                 : XPC_WN_JSOp_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
    1377                 :                       jsval *statep, jsid *idp);
    1378                 : 
    1379                 : extern JSType
    1380                 : XPC_WN_JSOp_TypeOf_Object(JSContext *cx, JSObject *obj);
    1381                 : 
    1382                 : extern JSType
    1383                 : XPC_WN_JSOp_TypeOf_Function(JSContext *cx, JSObject *obj);
    1384                 : 
    1385                 : extern void
    1386                 : XPC_WN_JSOp_Clear(JSContext *cx, JSObject *obj);
    1387                 : 
    1388                 : extern JSObject*
    1389                 : XPC_WN_JSOp_ThisObject(JSContext *cx, JSObject *obj);
    1390                 : 
    1391                 : // Macros to initialize Object or Function like XPC_WN classes
    1392                 : #define XPC_WN_WithCall_ObjectOps                                             \
    1393                 :     {                                                                         \
    1394                 :         nsnull, /* lookupGeneric */                                           \
    1395                 :         nsnull, /* lookupProperty */                                          \
    1396                 :         nsnull, /* lookupElement */                                           \
    1397                 :         nsnull, /* lookupSpecial */                                           \
    1398                 :         nsnull, /* defineGeneric */                                           \
    1399                 :         nsnull, /* defineProperty */                                          \
    1400                 :         nsnull, /* defineElement */                                           \
    1401                 :         nsnull, /* defineSpecial */                                           \
    1402                 :         nsnull, /* getGeneric    */                                           \
    1403                 :         nsnull, /* getProperty    */                                          \
    1404                 :         nsnull, /* getElement    */                                           \
    1405                 :         nsnull, /* getElementIfPresent */                                     \
    1406                 :         nsnull, /* getSpecial    */                                           \
    1407                 :         nsnull, /* setGeneric    */                                           \
    1408                 :         nsnull, /* setProperty    */                                          \
    1409                 :         nsnull, /* setElement    */                                           \
    1410                 :         nsnull, /* setSpecial    */                                           \
    1411                 :         nsnull, /* getGenericAttributes  */                                   \
    1412                 :         nsnull, /* getAttributes  */                                          \
    1413                 :         nsnull, /* getElementAttributes  */                                   \
    1414                 :         nsnull, /* getSpecialAttributes  */                                   \
    1415                 :         nsnull, /* setGenericAttributes  */                                   \
    1416                 :         nsnull, /* setAttributes  */                                          \
    1417                 :         nsnull, /* setElementAttributes  */                                   \
    1418                 :         nsnull, /* setSpecialAttributes  */                                   \
    1419                 :         nsnull, /* deleteProperty */                                          \
    1420                 :         nsnull, /* deleteElement */                                           \
    1421                 :         nsnull, /* deleteSpecial */                                           \
    1422                 :         XPC_WN_JSOp_Enumerate,                                                \
    1423                 :         XPC_WN_JSOp_TypeOf_Function,                                          \
    1424                 :         nsnull, /* fix            */                                          \
    1425                 :         XPC_WN_JSOp_ThisObject,                                               \
    1426                 :         XPC_WN_JSOp_Clear                                                     \
    1427                 :     }
    1428                 : 
    1429                 : #define XPC_WN_NoCall_ObjectOps                                               \
    1430                 :     {                                                                         \
    1431                 :         nsnull, /* lookupGeneric */                                           \
    1432                 :         nsnull, /* lookupProperty */                                          \
    1433                 :         nsnull, /* lookupElement */                                           \
    1434                 :         nsnull, /* lookupSpecial */                                           \
    1435                 :         nsnull, /* defineGeneric */                                           \
    1436                 :         nsnull, /* defineProperty */                                          \
    1437                 :         nsnull, /* defineElement */                                           \
    1438                 :         nsnull, /* defineSpecial */                                           \
    1439                 :         nsnull, /* getGeneric    */                                           \
    1440                 :         nsnull, /* getProperty    */                                          \
    1441                 :         nsnull, /* getElement    */                                           \
    1442                 :         nsnull, /* getElementIfPresent */                                     \
    1443                 :         nsnull, /* getSpecial    */                                           \
    1444                 :         nsnull, /* setGeneric    */                                           \
    1445                 :         nsnull, /* setProperty    */                                          \
    1446                 :         nsnull, /* setElement    */                                           \
    1447                 :         nsnull, /* setSpecial    */                                           \
    1448                 :         nsnull, /* getGenericAttributes  */                                   \
    1449                 :         nsnull, /* getAttributes  */                                          \
    1450                 :         nsnull, /* getElementAttributes  */                                   \
    1451                 :         nsnull, /* getSpecialAttributes  */                                   \
    1452                 :         nsnull, /* setGenericAttributes  */                                   \
    1453                 :         nsnull, /* setAttributes  */                                          \
    1454                 :         nsnull, /* setElementAttributes  */                                   \
    1455                 :         nsnull, /* setSpecialAttributes  */                                   \
    1456                 :         nsnull, /* deleteProperty */                                          \
    1457                 :         nsnull, /* deleteElement */                                           \
    1458                 :         nsnull, /* deleteSpecial */                                           \
    1459                 :         XPC_WN_JSOp_Enumerate,                                                \
    1460                 :         XPC_WN_JSOp_TypeOf_Object,                                            \
    1461                 :         nsnull, /* fix            */                                          \
    1462                 :         XPC_WN_JSOp_ThisObject,                                               \
    1463                 :         XPC_WN_JSOp_Clear                                                     \
    1464                 :     }
    1465                 : 
    1466                 : // Maybe this macro should check for class->enumerate ==
    1467                 : // XPC_WN_Shared_Proto_Enumerate or something rather than checking for
    1468                 : // 4 classes?
    1469         6731238 : static inline bool IS_PROTO_CLASS(js::Class *clazz)
    1470                 : {
    1471                 :     return clazz == &XPC_WN_NoMods_WithCall_Proto_JSClass ||
    1472                 :            clazz == &XPC_WN_NoMods_NoCall_Proto_JSClass ||
    1473                 :            clazz == &XPC_WN_ModsAllowed_WithCall_Proto_JSClass ||
    1474         6731238 :            clazz == &XPC_WN_ModsAllowed_NoCall_Proto_JSClass;
    1475                 : }
    1476                 : 
    1477                 : /***************************************************************************/
    1478                 : 
    1479                 : namespace XPCWrapper {
    1480                 : 
    1481                 : enum WrapperType {
    1482                 :     UNKNOWN         = 0,
    1483                 :     NONE            = 0,
    1484                 :     XPCNW_IMPLICIT  = 1 << 0,
    1485                 :     XPCNW_EXPLICIT  = 1 << 1,
    1486                 :     XPCNW           = (XPCNW_IMPLICIT | XPCNW_EXPLICIT),
    1487                 :     SJOW            = 1 << 2,
    1488                 :     // SJOW must be the last wrapper type that can be returned to chrome.
    1489                 : 
    1490                 :     XOW             = 1 << 3,
    1491                 :     COW             = 1 << 4,
    1492                 :     SOW             = 1 << 5
    1493                 : };
    1494                 : 
    1495                 : }
    1496                 : 
    1497                 : /***************************************************************************/
    1498                 : // XPCWrappedNativeScope is one-to-one with a JS global object.
    1499                 : 
    1500                 : class XPCWrappedNativeScope : public PRCList
    1501                 : {
    1502                 : public:
    1503                 : 
    1504                 :     static XPCWrappedNativeScope*
    1505                 :     GetNewOrUsed(XPCCallContext& ccx, JSObject* aGlobal, nsISupports* aNative = nsnull);
    1506                 : 
    1507                 :     XPCJSRuntime*
    1508        15630829 :     GetRuntime() const {return mRuntime;}
    1509                 : 
    1510                 :     Native2WrappedNativeMap*
    1511         4518813 :     GetWrappedNativeMap() const {return mWrappedNativeMap;}
    1512                 : 
    1513                 :     ClassInfo2WrappedNativeProtoMap*
    1514          569855 :     GetWrappedNativeProtoMap(JSBool aMainThreadOnly) const
    1515                 :         {return aMainThreadOnly ?
    1516                 :                 mMainThreadWrappedNativeProtoMap :
    1517          569855 :                 mWrappedNativeProtoMap;}
    1518                 : 
    1519                 :     nsXPCComponents*
    1520            4556 :     GetComponents() const {return mComponents;}
    1521                 : 
    1522                 :     JSObject*
    1523         4979154 :     GetGlobalJSObject() const {return mGlobalJSObject;}
    1524                 : 
    1525                 :     JSObject*
    1526         3363691 :     GetPrototypeJSObject() const {return mPrototypeJSObject;}
    1527                 : 
    1528                 :     // Getter for the prototype that we use for wrappers that have no
    1529                 :     // helper.
    1530                 :     JSObject*
    1531                 :     GetPrototypeNoHelper(XPCCallContext& ccx);
    1532                 : 
    1533                 :     nsIPrincipal*
    1534         1867645 :     GetPrincipal() const
    1535                 :     {return mScriptObjectPrincipal ?
    1536         1867645 :          mScriptObjectPrincipal->GetPrincipal() : nsnull;}
    1537                 : 
    1538                 :     void RemoveWrappedNativeProtos();
    1539                 : 
    1540                 :     static XPCWrappedNativeScope*
    1541                 :     FindInJSObjectScope(JSContext* cx, JSObject* obj,
    1542                 :                         JSBool OKIfNotInitialized = false,
    1543                 :                         XPCJSRuntime* runtime = nsnull);
    1544                 : 
    1545                 :     static XPCWrappedNativeScope*
    1546          129480 :     FindInJSObjectScope(XPCCallContext& ccx, JSObject* obj,
    1547                 :                         JSBool OKIfNotInitialized = false)
    1548                 :     {
    1549                 :         return FindInJSObjectScope(ccx, obj, OKIfNotInitialized,
    1550          129480 :                                    ccx.GetRuntime());
    1551                 :     }
    1552                 : 
    1553                 :     static void
    1554                 :     SystemIsBeingShutDown();
    1555                 : 
    1556                 :     static void
    1557                 :     TraceJS(JSTracer* trc, XPCJSRuntime* rt);
    1558                 : 
    1559                 :     static void
    1560                 :     SuspectAllWrappers(XPCJSRuntime* rt, nsCycleCollectionTraversalCallback &cb);
    1561                 : 
    1562                 :     static void
    1563                 :     FinishedMarkPhaseOfGC(JSContext* cx, XPCJSRuntime* rt);
    1564                 : 
    1565                 :     static void
    1566                 :     FinishedFinalizationPhaseOfGC(JSContext* cx);
    1567                 : 
    1568                 :     static void
    1569                 :     MarkAllWrappedNativesAndProtos();
    1570                 : 
    1571                 :     static nsresult
    1572                 :     ClearAllWrappedNativeSecurityPolicies(XPCCallContext& ccx);
    1573                 : 
    1574                 : #ifdef DEBUG
    1575                 :     static void
    1576                 :     ASSERT_NoInterfaceSetsAreMarked();
    1577                 : #endif
    1578                 : 
    1579                 :     static void
    1580                 :     SweepAllWrappedNativeTearOffs();
    1581                 : 
    1582                 :     static void
    1583                 :     DebugDumpAllScopes(PRInt16 depth);
    1584                 : 
    1585                 :     void
    1586                 :     DebugDump(PRInt16 depth);
    1587                 : 
    1588                 :     static size_t
    1589                 :     SizeOfAllScopesIncludingThis(nsMallocSizeOfFun mallocSizeOf);
    1590                 : 
    1591                 :     size_t
    1592                 :     SizeOfIncludingThis(nsMallocSizeOfFun mallocSizeOf);
    1593                 : 
    1594                 :     JSBool
    1595                 :     IsValid() const {return mRuntime != nsnull;}
    1596                 : 
    1597                 :     static JSBool
    1598                 :     IsDyingScope(XPCWrappedNativeScope *scope);
    1599                 : 
    1600                 :     void SetComponents(nsXPCComponents* aComponents);
    1601                 :     void SetGlobal(XPCCallContext& ccx, JSObject* aGlobal, nsISupports* aNative);
    1602                 : 
    1603            1404 :     static void InitStatics() { gScopes = nsnull; gDyingScopes = nsnull; }
    1604                 : 
    1605           94291 :     XPCContext *GetContext() { return mContext; }
    1606           13835 :     void SetContext(XPCContext *xpcc) { mContext = nsnull; }
    1607                 : 
    1608           20027 :     nsDataHashtable<nsDepCharHashKey, JSObject*>& GetCachedDOMPrototypes()
    1609                 :     {
    1610           20027 :         return mCachedDOMPrototypes;
    1611                 :     }
    1612                 : 
    1613          757498 :     static XPCWrappedNativeScope *GetNativeScope(JSObject *obj)
    1614                 :     {
    1615          757498 :         MOZ_ASSERT(js::GetObjectClass(obj)->flags & JSCLASS_XPCONNECT_GLOBAL);
    1616                 : 
    1617          757498 :         const js::Value &v = js::GetObjectSlot(obj, JSCLASS_GLOBAL_SLOT_COUNT);
    1618          757498 :         return v.isUndefined()
    1619                 :                ? nsnull
    1620          757498 :                : static_cast<XPCWrappedNativeScope *>(v.toPrivate());
    1621                 :     }
    1622                 :     void TraceDOMPrototypes(JSTracer *trc);
    1623                 : 
    1624               0 :     JSBool NewDOMBindingsEnabled()
    1625                 :     {
    1626               0 :         return mNewDOMBindingsEnabled;
    1627                 :     }
    1628                 : 
    1629                 : protected:
    1630                 :     XPCWrappedNativeScope(XPCCallContext& ccx, JSObject* aGlobal, nsISupports* aNative);
    1631                 :     virtual ~XPCWrappedNativeScope();
    1632                 : 
    1633                 :     static void KillDyingScopes();
    1634                 : 
    1635                 :     XPCWrappedNativeScope(); // not implemented
    1636                 : 
    1637                 : private:
    1638                 :     static XPCWrappedNativeScope* gScopes;
    1639                 :     static XPCWrappedNativeScope* gDyingScopes;
    1640                 : 
    1641                 :     XPCJSRuntime*                    mRuntime;
    1642                 :     Native2WrappedNativeMap*         mWrappedNativeMap;
    1643                 :     ClassInfo2WrappedNativeProtoMap* mWrappedNativeProtoMap;
    1644                 :     ClassInfo2WrappedNativeProtoMap* mMainThreadWrappedNativeProtoMap;
    1645                 :     nsXPCComponents*                 mComponents;
    1646                 :     XPCWrappedNativeScope*           mNext;
    1647                 :     // The JS global object for this scope.  If non-null, this will be the
    1648                 :     // default parent for the XPCWrappedNatives that have us as the scope,
    1649                 :     // unless a PreCreate hook overrides it.  Note that this _may_ be null (see
    1650                 :     // constructor).
    1651                 :     js::ObjectPtr                    mGlobalJSObject;
    1652                 : 
    1653                 :     // Cached value of Object.prototype
    1654                 :     js::ObjectPtr                    mPrototypeJSObject;
    1655                 :     // Prototype to use for wrappers with no helper.
    1656                 :     JSObject*                        mPrototypeNoHelper;
    1657                 : 
    1658                 :     XPCContext*                      mContext;
    1659                 : 
    1660                 :     // The script object principal instance corresponding to our current global
    1661                 :     // JS object.
    1662                 :     // XXXbz what happens if someone calls JS_SetPrivate on mGlobalJSObject.
    1663                 :     // How do we deal?  Do we need to?  I suspect this isn't worth worrying
    1664                 :     // about, since all of our scope objects are verified as not doing that.
    1665                 :     nsIScriptObjectPrincipal* mScriptObjectPrincipal;
    1666                 : 
    1667                 :     nsDataHashtable<nsDepCharHashKey, JSObject*> mCachedDOMPrototypes;
    1668                 : 
    1669                 :     JSBool mNewDOMBindingsEnabled;
    1670                 : };
    1671                 : 
    1672                 : /***************************************************************************/
    1673                 : // XPCNativeMember represents a single idl declared method, attribute or
    1674                 : // constant.
    1675                 : 
    1676                 : // Tight. No virtual methods. Can be bitwise copied (until any resolution done).
    1677                 : 
    1678                 : class XPCNativeMember
    1679                 : {
    1680                 : public:
    1681                 :     static JSBool GetCallInfo(XPCCallContext& ccx,
    1682                 :                               JSObject* funobj,
    1683                 :                               XPCNativeInterface** pInterface,
    1684                 :                               XPCNativeMember**    pMember);
    1685                 : 
    1686        71547090 :     jsid   GetName() const {return mName;}
    1687                 : 
    1688        10145937 :     PRUint16 GetIndex() const {return mIndex;}
    1689                 : 
    1690           20080 :     JSBool GetConstantValue(XPCCallContext& ccx, XPCNativeInterface* iface,
    1691                 :                             jsval* pval)
    1692           20080 :         {NS_ASSERTION(IsConstant(),
    1693                 :                       "Only call this if you're sure this is a constant!");
    1694           20080 :          return Resolve(ccx, iface, nsnull, pval);}
    1695                 : 
    1696                 :     JSBool NewFunctionObject(XPCCallContext& ccx, XPCNativeInterface* iface,
    1697                 :                              JSObject *parent, jsval* pval);
    1698                 : 
    1699         3452412 :     JSBool IsMethod() const
    1700         3452412 :         {return 0 != (mFlags & METHOD);}
    1701                 : 
    1702         8447680 :     JSBool IsConstant() const
    1703         8447680 :         {return 0 != (mFlags & CONSTANT);}
    1704                 : 
    1705         1194789 :     JSBool IsAttribute() const
    1706         1194789 :         {return 0 != (mFlags & GETTER);}
    1707                 : 
    1708         1297124 :     JSBool IsWritableAttribute() const
    1709         1297124 :         {return 0 != (mFlags & SETTER_TOO);}
    1710                 : 
    1711          172725 :     JSBool IsReadOnlyAttribute() const
    1712          172725 :         {return IsAttribute() && !IsWritableAttribute();}
    1713                 : 
    1714                 : 
    1715         1701890 :     void SetName(jsid a) {mName = a;}
    1716                 : 
    1717          810166 :     void SetMethod(PRUint16 index)
    1718          810166 :         {mFlags = METHOD; mIndex = index;}
    1719                 : 
    1720          388193 :     void SetConstant(PRUint16 index)
    1721          388193 :         {mFlags = CONSTANT; mIndex = index;}
    1722                 : 
    1723          503531 :     void SetReadOnlyAttribute(PRUint16 index)
    1724          503531 :         {mFlags = GETTER; mIndex = index;}
    1725                 : 
    1726          172725 :     void SetWritableAttribute()
    1727          172725 :         {NS_ASSERTION(mFlags == GETTER,"bad"); mFlags = GETTER | SETTER_TOO;}
    1728                 : 
    1729                 :     /* default ctor - leave random contents */
    1730         4699200 :     XPCNativeMember()  {MOZ_COUNT_CTOR(XPCNativeMember);}
    1731         4699180 :     ~XPCNativeMember() {MOZ_COUNT_DTOR(XPCNativeMember);}
    1732                 : 
    1733                 : private:
    1734                 :     JSBool Resolve(XPCCallContext& ccx, XPCNativeInterface* iface,
    1735                 :                    JSObject *parent, jsval *vp);
    1736                 : 
    1737                 :     enum {
    1738                 :         METHOD      = 0x01,
    1739                 :         CONSTANT    = 0x02,
    1740                 :         GETTER      = 0x04,
    1741                 :         SETTER_TOO  = 0x08
    1742                 :     };
    1743                 : 
    1744                 : private:
    1745                 :     // our only data...
    1746                 :     jsid     mName;
    1747                 :     PRUint16 mIndex;
    1748                 :     PRUint16 mFlags;
    1749                 : };
    1750                 : 
    1751                 : /***************************************************************************/
    1752                 : // XPCNativeInterface represents a single idl declared interface. This is
    1753                 : // primarily the set of XPCNativeMembers.
    1754                 : 
    1755                 : // Tight. No virtual methods.
    1756                 : 
    1757                 : class XPCNativeInterface
    1758                 : {
    1759                 : public:
    1760                 :     static XPCNativeInterface* GetNewOrUsed(XPCCallContext& ccx,
    1761                 :                                             const nsIID* iid);
    1762                 :     static XPCNativeInterface* GetNewOrUsed(XPCCallContext& ccx,
    1763                 :                                             nsIInterfaceInfo* info);
    1764                 :     static XPCNativeInterface* GetNewOrUsed(XPCCallContext& ccx,
    1765                 :                                             const char* name);
    1766                 :     static XPCNativeInterface* GetISupports(XPCCallContext& ccx);
    1767                 : 
    1768         7461279 :     inline nsIInterfaceInfo* GetInterfaceInfo() const {return mInfo.get();}
    1769        12426824 :     inline jsid              GetName()          const {return mName;}
    1770                 : 
    1771                 :     inline const nsIID* GetIID() const;
    1772                 :     inline const char*  GetNameString() const;
    1773                 :     inline XPCNativeMember* FindMember(jsid name) const;
    1774                 : 
    1775                 :     inline JSBool HasAncestor(const nsIID* iid) const;
    1776                 : 
    1777          299148 :     PRUint16 GetMemberCount() const
    1778          299148 :         {NS_ASSERTION(!IsMarked(), "bad"); return mMemberCount;}
    1779           10200 :     XPCNativeMember* GetMemberAt(PRUint16 i)
    1780           10200 :         {NS_ASSERTION(i < mMemberCount, "bad index"); return &mMembers[i];}
    1781                 : 
    1782                 :     void DebugDump(PRInt16 depth);
    1783                 : 
    1784                 : #define XPC_NATIVE_IFACE_MARK_FLAG ((PRUint16)JS_BIT(15)) // only high bit of 16 is set
    1785                 : 
    1786          546637 :     void Mark()     {mMemberCount |= XPC_NATIVE_IFACE_MARK_FLAG;}
    1787          275830 :     void Unmark()   {mMemberCount &= ~XPC_NATIVE_IFACE_MARK_FLAG;}
    1788        13817650 :     JSBool IsMarked() const
    1789        13817650 :                     {return 0 != (mMemberCount & XPC_NATIVE_IFACE_MARK_FLAG);}
    1790                 : 
    1791                 :     // NOP. This is just here to make the AutoMarkingPtr code compile.
    1792               0 :     inline void TraceJS(JSTracer* trc) {}
    1793               0 :     inline void AutoTrace(JSTracer* trc) {}
    1794                 : 
    1795                 :     static void DestroyInstance(XPCNativeInterface* inst);
    1796                 : 
    1797                 :     size_t SizeOfIncludingThis(nsMallocSizeOfFun mallocSizeOf);
    1798                 : 
    1799                 : protected:
    1800                 :     static XPCNativeInterface* NewInstance(XPCCallContext& ccx,
    1801                 :                                            nsIInterfaceInfo* aInfo);
    1802                 : 
    1803                 :     XPCNativeInterface();   // not implemented
    1804          127559 :     XPCNativeInterface(nsIInterfaceInfo* aInfo, jsid aName)
    1805          127559 :         : mInfo(aInfo), mName(aName), mMemberCount(0)
    1806          127559 :                           {MOZ_COUNT_CTOR(XPCNativeInterface);}
    1807          127539 :     ~XPCNativeInterface() {MOZ_COUNT_DTOR(XPCNativeInterface);}
    1808                 : 
    1809          127559 :     void* operator new(size_t, void* p) CPP_THROW_NEW {return p;}
    1810                 : 
    1811                 :     XPCNativeInterface(const XPCNativeInterface& r); // not implemented
    1812                 :     XPCNativeInterface& operator= (const XPCNativeInterface& r); // not implemented
    1813                 : 
    1814                 : private:
    1815                 :     nsCOMPtr<nsIInterfaceInfo> mInfo;
    1816                 :     jsid                       mName;
    1817                 :     PRUint16          mMemberCount;
    1818                 :     XPCNativeMember   mMembers[1]; // always last - object sized for array
    1819                 : };
    1820                 : 
    1821                 : /***************************************************************************/
    1822                 : // XPCNativeSetKey is used to key a XPCNativeSet in a NativeSetMap.
    1823                 : 
    1824                 : class XPCNativeSetKey
    1825                 : {
    1826                 : public:
    1827         1193578 :     XPCNativeSetKey(XPCNativeSet*       BaseSet  = nsnull,
    1828                 :                     XPCNativeInterface* Addition = nsnull,
    1829                 :                     PRUint16            Position = 0)
    1830                 :         : mIsAKey(IS_A_KEY), mPosition(Position), mBaseSet(BaseSet),
    1831         1193578 :           mAddition(Addition) {}
    1832         1193578 :     ~XPCNativeSetKey() {}
    1833                 : 
    1834         2372350 :     XPCNativeSet*           GetBaseSet()  const {return mBaseSet;}
    1835         2372350 :     XPCNativeInterface*     GetAddition() const {return mAddition;}
    1836         1507862 :     PRUint16                GetPosition() const {return mPosition;}
    1837                 : 
    1838                 :     // This is a fun little hack...
    1839                 :     // We build these keys only on the stack. We use them for lookup in
    1840                 :     // NativeSetMap. Becasue we don't want to pay the cost of cloning a key and
    1841                 :     // sticking it into the hashtable, when the XPCNativeSet actually
    1842                 :     // gets added to the table the 'key' in the table is a pointer to the
    1843                 :     // set itself and not this key. Our key compare function expects to get
    1844                 :     // a key and a set. When we do external lookups in the map we pass in one
    1845                 :     // of these keys and our compare function gets passed a key and a set.
    1846                 :     // (see compare_NativeKeyToSet in xpcmaps.cpp). This is all well and good.
    1847                 :     // Except, when the table decides to resize itself. Then it tries to use
    1848                 :     // our compare function with the 'keys' that are in the hashtable (which are
    1849                 :     // really XPCNativeSet objects and not XPCNativeSetKey objects!
    1850                 :     //
    1851                 :     // So, the hack is to have the compare function assume it is getting a
    1852                 :     // XPCNativeSetKey pointer and call this IsAKey method. If that fails then
    1853                 :     // it realises that it really has a XPCNativeSet pointer and deals with that
    1854                 :     // fact. This is safe because we know that both of these classes have no
    1855                 :     // virtual methods and their first data member is a PRUint16. We are
    1856                 :     // confident that XPCNativeSet->mMemberCount will never be 0xffff.
    1857                 : 
    1858         2372350 :     JSBool                  IsAKey() const {return mIsAKey == IS_A_KEY;}
    1859                 : 
    1860                 :     enum {IS_A_KEY = 0xffff};
    1861                 : 
    1862                 :     // Allow shallow copy
    1863                 : 
    1864                 : private:
    1865                 :     PRUint16                mIsAKey;    // must be first data member
    1866                 :     PRUint16                mPosition;
    1867                 :     XPCNativeSet*           mBaseSet;
    1868                 :     XPCNativeInterface*     mAddition;
    1869                 : };
    1870                 : 
    1871                 : /***************************************************************************/
    1872                 : // XPCNativeSet represents an ordered collection of XPCNativeInterface pointers.
    1873                 : 
    1874                 : class XPCNativeSet
    1875                 : {
    1876                 : public:
    1877                 :     static XPCNativeSet* GetNewOrUsed(XPCCallContext& ccx, const nsIID* iid);
    1878                 :     static XPCNativeSet* GetNewOrUsed(XPCCallContext& ccx,
    1879                 :                                       nsIClassInfo* classInfo);
    1880                 :     static XPCNativeSet* GetNewOrUsed(XPCCallContext& ccx,
    1881                 :                                       XPCNativeSet* otherSet,
    1882                 :                                       XPCNativeInterface* newInterface,
    1883                 :                                       PRUint16 position);
    1884                 : 
    1885                 :     static void ClearCacheEntryForClassInfo(nsIClassInfo* classInfo);
    1886                 : 
    1887                 :     inline JSBool FindMember(jsid name, XPCNativeMember** pMember,
    1888                 :                              PRUint16* pInterfaceIndex) const;
    1889                 : 
    1890                 :     inline JSBool FindMember(jsid name, XPCNativeMember** pMember,
    1891                 :                              XPCNativeInterface** pInterface) const;
    1892                 : 
    1893                 :     inline JSBool FindMember(jsid name,
    1894                 :                              XPCNativeMember** pMember,
    1895                 :                              XPCNativeInterface** pInterface,
    1896                 :                              XPCNativeSet* protoSet,
    1897                 :                              JSBool* pIsLocal) const;
    1898                 : 
    1899                 :     inline JSBool HasInterface(XPCNativeInterface* aInterface) const;
    1900                 :     inline JSBool HasInterfaceWithAncestor(XPCNativeInterface* aInterface) const;
    1901                 :     inline JSBool HasInterfaceWithAncestor(const nsIID* iid) const;
    1902                 : 
    1903                 :     inline XPCNativeInterface* FindInterfaceWithIID(const nsIID& iid) const;
    1904                 : 
    1905                 :     inline XPCNativeInterface* FindNamedInterface(jsid name) const;
    1906                 : 
    1907           25631 :     PRUint16 GetMemberCount() const {return mMemberCount;}
    1908         2585356 :     PRUint16 GetInterfaceCount() const
    1909         2585356 :         {NS_ASSERTION(!IsMarked(), "bad"); return mInterfaceCount;}
    1910          762837 :     XPCNativeInterface** GetInterfaceArray() {return mInterfaces;}
    1911                 : 
    1912          864487 :     XPCNativeInterface* GetInterfaceAt(PRUint16 i)
    1913          864487 :         {NS_ASSERTION(i < mInterfaceCount, "bad index"); return mInterfaces[i];}
    1914                 : 
    1915                 :     inline JSBool MatchesSetUpToInterface(const XPCNativeSet* other,
    1916                 :                                           XPCNativeInterface* iface) const;
    1917                 : 
    1918                 : #define XPC_NATIVE_SET_MARK_FLAG ((PRUint16)JS_BIT(15)) // only high bit of 16 is set
    1919                 : 
    1920                 :     inline void Mark();
    1921                 : 
    1922                 :     // NOP. This is just here to make the AutoMarkingPtr code compile.
    1923               0 :     inline void TraceJS(JSTracer* trc) {}
    1924               0 :     inline void AutoTrace(JSTracer* trc) {}
    1925                 : 
    1926                 : private:
    1927          221767 :     void MarkSelfOnly() {mInterfaceCount |= XPC_NATIVE_SET_MARK_FLAG;}
    1928                 : public:
    1929          221767 :     void Unmark()       {mInterfaceCount &= ~XPC_NATIVE_SET_MARK_FLAG;}
    1930        13565231 :     JSBool IsMarked() const
    1931        13565231 :                   {return 0 != (mInterfaceCount & XPC_NATIVE_SET_MARK_FLAG);}
    1932                 : 
    1933                 : #ifdef DEBUG
    1934                 :     inline void ASSERT_NotMarked();
    1935                 : #endif
    1936                 : 
    1937                 :     void DebugDump(PRInt16 depth);
    1938                 : 
    1939                 :     static void DestroyInstance(XPCNativeSet* inst);
    1940                 : 
    1941                 :     size_t SizeOfIncludingThis(nsMallocSizeOfFun mallocSizeOf);
    1942                 : 
    1943                 : protected:
    1944                 :     static XPCNativeSet* NewInstance(XPCCallContext& ccx,
    1945                 :                                      XPCNativeInterface** array,
    1946                 :                                      PRUint16 count);
    1947                 :     static XPCNativeSet* NewInstanceMutate(XPCNativeSet*       otherSet,
    1948                 :                                            XPCNativeInterface* newInterface,
    1949                 :                                            PRUint16            position);
    1950          192276 :     XPCNativeSet()  {MOZ_COUNT_CTOR(XPCNativeSet);}
    1951          192264 :     ~XPCNativeSet() {MOZ_COUNT_DTOR(XPCNativeSet);}
    1952          192276 :     void* operator new(size_t, void* p) CPP_THROW_NEW {return p;}
    1953                 : 
    1954                 : private:
    1955                 :     PRUint16                mMemberCount;
    1956                 :     PRUint16                mInterfaceCount;
    1957                 :     XPCNativeInterface*     mInterfaces[1];  // always last - object sized for array
    1958                 : };
    1959                 : 
    1960                 : /***************************************************************************/
    1961                 : // XPCNativeScriptableFlags is a wrapper class that holds the flags returned
    1962                 : // from calls to nsIXPCScriptable::GetScriptableFlags(). It has convenience
    1963                 : // methods to check for particular bitflags. Since we also use this class as
    1964                 : // a member of the gc'd class XPCNativeScriptableShared, this class holds the
    1965                 : // bit and exposes the inlined methods to support marking.
    1966                 : 
    1967                 : #define XPC_WN_SJSFLAGS_MARK_FLAG JS_BIT(31) // only high bit of 32 is set
    1968                 : 
    1969                 : class XPCNativeScriptableFlags
    1970                 : {
    1971                 : private:
    1972                 :     uint32_t mFlags;
    1973                 : 
    1974                 : public:
    1975                 : 
    1976         3178754 :     XPCNativeScriptableFlags(uint32_t flags = 0) : mFlags(flags) {}
    1977                 : 
    1978         1395727 :     uint32_t GetFlags() const {return mFlags & ~XPC_WN_SJSFLAGS_MARK_FLAG;}
    1979                 :     void     SetFlags(uint32_t flags) {mFlags = flags;}
    1980                 : 
    1981          977921 :     operator uint32_t() const {return GetFlags();}
    1982                 : 
    1983           30310 :     XPCNativeScriptableFlags(const XPCNativeScriptableFlags& r)
    1984           30310 :         {mFlags = r.GetFlags();}
    1985                 : 
    1986          387496 :     XPCNativeScriptableFlags& operator= (const XPCNativeScriptableFlags& r)
    1987          387496 :         {mFlags = r.GetFlags(); return *this;}
    1988                 : 
    1989         5526377 :     void Mark()       {mFlags |= XPC_WN_SJSFLAGS_MARK_FLAG;}
    1990          101050 :     void Unmark()     {mFlags &= ~XPC_WN_SJSFLAGS_MARK_FLAG;}
    1991          122164 :     JSBool IsMarked() const {return 0 != (mFlags & XPC_WN_SJSFLAGS_MARK_FLAG);}
    1992                 : 
    1993                 : #ifdef GET_IT
    1994                 : #undef GET_IT
    1995                 : #endif
    1996                 : #define GET_IT(f_) const {return 0 != (mFlags & nsIXPCScriptable:: f_ );}
    1997                 : 
    1998         1491909 :     JSBool WantPreCreate()                GET_IT(WANT_PRECREATE)
    1999          276837 :     JSBool WantCreate()                   GET_IT(WANT_CREATE)
    2000          276837 :     JSBool WantPostCreate()               GET_IT(WANT_POSTCREATE)
    2001           21231 :     JSBool WantAddProperty()              GET_IT(WANT_ADDPROPERTY)
    2002           21231 :     JSBool WantDelProperty()              GET_IT(WANT_DELPROPERTY)
    2003           21231 :     JSBool WantGetProperty()              GET_IT(WANT_GETPROPERTY)
    2004           21231 :     JSBool WantSetProperty()              GET_IT(WANT_SETPROPERTY)
    2005           16380 :     JSBool WantEnumerate()                GET_IT(WANT_ENUMERATE)
    2006           21549 :     JSBool WantNewEnumerate()             GET_IT(WANT_NEWENUMERATE)
    2007         1538913 :     JSBool WantNewResolve()               GET_IT(WANT_NEWRESOLVE)
    2008           21231 :     JSBool WantConvert()                  GET_IT(WANT_CONVERT)
    2009           21231 :     JSBool WantFinalize()                 GET_IT(WANT_FINALIZE)
    2010           21231 :     JSBool WantCheckAccess()              GET_IT(WANT_CHECKACCESS)
    2011           41076 :     JSBool WantCall()                     GET_IT(WANT_CALL)
    2012           22901 :     JSBool WantConstruct()                GET_IT(WANT_CONSTRUCT)
    2013           21231 :     JSBool WantHasInstance()              GET_IT(WANT_HASINSTANCE)
    2014            2371 :     JSBool WantEquality()                 GET_IT(WANT_EQUALITY)
    2015           21231 :     JSBool WantOuterObject()              GET_IT(WANT_OUTER_OBJECT)
    2016           19433 :     JSBool UseJSStubForAddProperty()      GET_IT(USE_JSSTUB_FOR_ADDPROPERTY)
    2017           21228 :     JSBool UseJSStubForDelProperty()      GET_IT(USE_JSSTUB_FOR_DELPROPERTY)
    2018           19326 :     JSBool UseJSStubForSetProperty()      GET_IT(USE_JSSTUB_FOR_SETPROPERTY)
    2019          522303 :     JSBool DontEnumStaticProps()          GET_IT(DONT_ENUM_STATIC_PROPS)
    2020          278777 :     JSBool DontEnumQueryInterface()       GET_IT(DONT_ENUM_QUERY_INTERFACE)
    2021          622802 :     JSBool DontAskInstanceForScriptable() GET_IT(DONT_ASK_INSTANCE_FOR_SCRIPTABLE)
    2022          587448 :     JSBool ClassInfoInterfacesOnly()      GET_IT(CLASSINFO_INTERFACES_ONLY)
    2023         1851393 :     JSBool AllowPropModsDuringResolve()   GET_IT(ALLOW_PROP_MODS_DURING_RESOLVE)
    2024          257255 :     JSBool AllowPropModsToPrototype()     GET_IT(ALLOW_PROP_MODS_TO_PROTOTYPE)
    2025          278786 :     JSBool IsGlobalObject()               GET_IT(IS_GLOBAL_OBJECT)
    2026           25385 :     JSBool DontReflectInterfaceNames()    GET_IT(DONT_REFLECT_INTERFACE_NAMES)
    2027           21231 :     JSBool UseStubEqualityHook()          GET_IT(USE_STUB_EQUALITY_HOOK)
    2028                 : 
    2029                 : #undef GET_IT
    2030                 : };
    2031                 : 
    2032                 : /***************************************************************************/
    2033                 : 
    2034                 : // XPCNativeScriptableShared is used to hold the JSClass and the
    2035                 : // associated scriptable flags for XPCWrappedNatives. These are shared across
    2036                 : // the runtime and are garbage collected by xpconnect. We *used* to just store
    2037                 : // this inside the XPCNativeScriptableInfo (usually owned by instances of
    2038                 : // XPCWrappedNativeProto. This had two problems... It was wasteful, and it
    2039                 : // was a big problem when wrappers are reparented to different scopes (and
    2040                 : // thus different protos (the DOM does this).
    2041                 : 
    2042                 : // We maintain the invariant that every JSClass for which ext.isWrappedNative
    2043                 : // is true is a contained in an instance of this struct, and can thus be cast
    2044                 : // to it.
    2045                 : struct XPCWrappedNativeJSClass
    2046                 : {
    2047                 :     js::Class base;
    2048                 :     PRUint32 interfacesBitmap;
    2049                 : };
    2050                 : 
    2051                 : class XPCNativeScriptableShared
    2052                 : {
    2053                 : public:
    2054         4990101 :     const XPCNativeScriptableFlags& GetFlags() const {return mFlags;}
    2055          457114 :     PRUint32                        GetInterfacesBitmap() const
    2056          457114 :         {return mJSClass.interfacesBitmap;}
    2057         2929964 :     JSClass*                        GetJSClass()
    2058         2929964 :         {return Jsvalify(&mJSClass.base);}
    2059           15155 :     JSClass*                        GetSlimJSClass()
    2060           15155 :         {if (mCanBeSlim) return GetJSClass(); return nsnull;}
    2061                 : 
    2062          271019 :     XPCNativeScriptableShared(uint32_t aFlags, char* aName,
    2063                 :                               PRUint32 interfacesBitmap)
    2064                 :         : mFlags(aFlags),
    2065          271019 :           mCanBeSlim(false)
    2066          271019 :         {memset(&mJSClass, 0, sizeof(mJSClass));
    2067          271019 :          mJSClass.base.name = aName;  // take ownership
    2068          271019 :          mJSClass.interfacesBitmap = interfacesBitmap;
    2069          271019 :          MOZ_COUNT_CTOR(XPCNativeScriptableShared);}
    2070                 : 
    2071          270902 :     ~XPCNativeScriptableShared()
    2072          270902 :         {if (mJSClass.base.name)nsMemory::Free((void*)mJSClass.base.name);
    2073          270902 :          MOZ_COUNT_DTOR(XPCNativeScriptableShared);}
    2074                 : 
    2075           21231 :     char* TransferNameOwnership()
    2076           21231 :         {char* name=(char*)mJSClass.base.name; mJSClass.base.name = nsnull;
    2077           21231 :         return name;}
    2078                 : 
    2079                 :     void PopulateJSClass();
    2080                 : 
    2081         5526377 :     void Mark()       {mFlags.Mark();}
    2082          101050 :     void Unmark()     {mFlags.Unmark();}
    2083          122164 :     JSBool IsMarked() const {return mFlags.IsMarked();}
    2084                 : 
    2085                 : private:
    2086                 :     XPCNativeScriptableFlags mFlags;
    2087                 :     XPCWrappedNativeJSClass  mJSClass;
    2088                 :     JSBool                   mCanBeSlim;
    2089                 : };
    2090                 : 
    2091                 : /***************************************************************************/
    2092                 : // XPCNativeScriptableInfo is used to hold the nsIXPCScriptable state for a
    2093                 : // given class or instance.
    2094                 : 
    2095                 : class XPCNativeScriptableInfo
    2096                 : {
    2097                 : public:
    2098                 :     static XPCNativeScriptableInfo*
    2099                 :     Construct(XPCCallContext& ccx, const XPCNativeScriptableCreateInfo* sci);
    2100                 : 
    2101                 :     nsIXPCScriptable*
    2102         2041899 :     GetCallback() const {return mCallback;}
    2103                 : 
    2104                 :     const XPCNativeScriptableFlags&
    2105         4283199 :     GetFlags() const      {return mShared->GetFlags();}
    2106                 : 
    2107                 :     PRUint32
    2108               0 :     GetInterfacesBitmap() const {return mShared->GetInterfacesBitmap();}
    2109                 : 
    2110                 :     JSClass*
    2111         2207907 :     GetJSClass()          {return mShared->GetJSClass();}
    2112                 : 
    2113                 :     JSClass*
    2114           15155 :     GetSlimJSClass()      {return mShared->GetSlimJSClass();}
    2115                 : 
    2116                 :     XPCNativeScriptableShared*
    2117               0 :     GetScriptableShared() {return mShared;}
    2118                 : 
    2119                 :     void
    2120                 :     SetCallback(nsIXPCScriptable* s) {mCallback = s;}
    2121                 :     void
    2122                 :     SetCallback(already_AddRefed<nsIXPCScriptable> s) {mCallback = s;}
    2123                 : 
    2124                 :     void
    2125          249788 :     SetScriptableShared(XPCNativeScriptableShared* shared) {mShared = shared;}
    2126                 : 
    2127         5526377 :     void Mark() {
    2128         5526377 :         if (mShared)
    2129         5526377 :             mShared->Mark();
    2130         5526377 :     }
    2131                 : 
    2132               0 :     void TraceJS(JSTracer *trc) {}
    2133               0 :     void AutoTrace(JSTracer *trc) {}
    2134                 : 
    2135                 : protected:
    2136          249788 :     XPCNativeScriptableInfo(nsIXPCScriptable* scriptable = nsnull,
    2137                 :                             XPCNativeScriptableShared* shared = nsnull)
    2138          249788 :         : mCallback(scriptable), mShared(shared)
    2139          249788 :                                {MOZ_COUNT_CTOR(XPCNativeScriptableInfo);}
    2140                 : public:
    2141          249739 :     ~XPCNativeScriptableInfo() {MOZ_COUNT_DTOR(XPCNativeScriptableInfo);}
    2142                 : private:
    2143                 : 
    2144                 :     // disable copy ctor and assignment
    2145                 :     XPCNativeScriptableInfo(const XPCNativeScriptableInfo& r); // not implemented
    2146                 :     XPCNativeScriptableInfo& operator= (const XPCNativeScriptableInfo& r); // not implemented
    2147                 : 
    2148                 : private:
    2149                 :     nsCOMPtr<nsIXPCScriptable>  mCallback;
    2150                 :     XPCNativeScriptableShared*  mShared;
    2151                 : };
    2152                 : 
    2153                 : /***************************************************************************/
    2154                 : // XPCNativeScriptableCreateInfo is used in creating new wrapper and protos.
    2155                 : // it abstracts out the scriptable interface pointer and the flags. After
    2156                 : // creation these are factored differently using XPCNativeScriptableInfo.
    2157                 : 
    2158                 : class NS_STACK_CLASS XPCNativeScriptableCreateInfo
    2159         2515633 : {
    2160                 : public:
    2161                 : 
    2162               0 :     XPCNativeScriptableCreateInfo(const XPCNativeScriptableInfo& si)
    2163               0 :         : mCallback(si.GetCallback()), mFlags(si.GetFlags()),
    2164               0 :           mInterfacesBitmap(si.GetInterfacesBitmap()) {}
    2165                 : 
    2166           15155 :     XPCNativeScriptableCreateInfo(already_AddRefed<nsIXPCScriptable> callback,
    2167                 :                                   XPCNativeScriptableFlags flags,
    2168                 :                                   PRUint32 interfacesBitmap)
    2169                 :         : mCallback(callback), mFlags(flags),
    2170           15155 :           mInterfacesBitmap(interfacesBitmap) {}
    2171                 : 
    2172         2500478 :     XPCNativeScriptableCreateInfo()
    2173         2500478 :         : mFlags(0), mInterfacesBitmap(0) {}
    2174                 : 
    2175                 : 
    2176                 :     nsIXPCScriptable*
    2177         4074908 :     GetCallback() const {return mCallback;}
    2178                 : 
    2179                 :     const XPCNativeScriptableFlags&
    2180         3828028 :     GetFlags() const      {return mFlags;}
    2181                 : 
    2182                 :     PRUint32
    2183          249788 :     GetInterfacesBitmap() const     {return mInterfacesBitmap;}
    2184                 : 
    2185                 :     void
    2186          362111 :     SetCallback(already_AddRefed<nsIXPCScriptable> callback)
    2187          362111 :         {mCallback = callback;}
    2188                 : 
    2189                 :     void
    2190          362111 :     SetFlags(const XPCNativeScriptableFlags& flags)  {mFlags = flags;}
    2191                 : 
    2192                 :     void
    2193           11682 :     SetInterfacesBitmap(PRUint32 interfacesBitmap)
    2194           11682 :         {mInterfacesBitmap = interfacesBitmap;}
    2195                 : 
    2196                 : private:
    2197                 :     nsCOMPtr<nsIXPCScriptable>  mCallback;
    2198                 :     XPCNativeScriptableFlags    mFlags;
    2199                 :     PRUint32                    mInterfacesBitmap;
    2200                 : };
    2201                 : 
    2202                 : /***********************************************/
    2203                 : // XPCWrappedNativeProto hold the additional shared wrapper data
    2204                 : // for XPCWrappedNative whose native objects expose nsIClassInfo.
    2205                 : 
    2206                 : #define UNKNOWN_OFFSETS ((QITableEntry*)1)
    2207                 : 
    2208                 : class XPCWrappedNativeProto
    2209                 : {
    2210                 : public:
    2211                 :     static XPCWrappedNativeProto*
    2212                 :     GetNewOrUsed(XPCCallContext& ccx,
    2213                 :                  XPCWrappedNativeScope* scope,
    2214                 :                  nsIClassInfo* classInfo,
    2215                 :                  const XPCNativeScriptableCreateInfo* scriptableCreateInfo,
    2216                 :                  QITableEntry* offsets = UNKNOWN_OFFSETS,
    2217                 :                  bool callPostCreatePrototype = true);
    2218                 : 
    2219                 :     XPCWrappedNativeScope*
    2220         8831657 :     GetScope()   const {return mScope;}
    2221                 : 
    2222                 :     XPCJSRuntime*
    2223         5007776 :     GetRuntime() const {return mScope->GetRuntime();}
    2224                 : 
    2225                 :     JSObject*
    2226          396291 :     GetJSProtoObject() const {return mJSProtoObject;}
    2227                 : 
    2228                 :     nsIClassInfo*
    2229         2730812 :     GetClassInfo()     const {return mClassInfo;}
    2230                 : 
    2231                 :     XPCNativeSet*
    2232         3059923 :     GetSet()           const {return mSet;}
    2233                 : 
    2234                 :     XPCNativeScriptableInfo*
    2235         1641566 :     GetScriptableInfo()   {return mScriptableInfo;}
    2236                 : 
    2237                 :     void**
    2238         1549264 :     GetSecurityInfoAddr() {return &mSecurityInfo;}
    2239                 : 
    2240                 :     uint32_t
    2241                 :     GetClassInfoFlags() const {return mClassInfoFlags;}
    2242                 : 
    2243                 :     QITableEntry*
    2244           33559 :     GetOffsets()
    2245                 :     {
    2246           33559 :         return InitedOffsets() ? mOffsets : nsnull;
    2247                 :     }
    2248                 :     QITableEntry*
    2249               0 :     GetOffsetsMasked()
    2250                 :     {
    2251               0 :         return mOffsets;
    2252                 :     }
    2253                 :     void
    2254          383074 :     CacheOffsets(nsISupports* identity)
    2255                 :     {
    2256                 :         static NS_DEFINE_IID(kThisPtrOffsetsSID, NS_THISPTROFFSETS_SID);
    2257                 : 
    2258                 : #ifdef DEBUG
    2259          383074 :         if (InitedOffsets() && mOffsets) {
    2260                 :             QITableEntry* offsets;
    2261           13260 :             identity->QueryInterface(kThisPtrOffsetsSID, (void**)&offsets);
    2262           13260 :             NS_ASSERTION(offsets == mOffsets,
    2263                 :                          "We can't deal with objects that have the same "
    2264                 :                          "classinfo but different offset tables.");
    2265                 :         }
    2266                 : #endif
    2267                 : 
    2268          383074 :         if (!InitedOffsets()) {
    2269          186922 :             if (mClassInfoFlags & nsIClassInfo::CONTENT_NODE) {
    2270             898 :                 identity->QueryInterface(kThisPtrOffsetsSID, (void**)&mOffsets);
    2271                 :             } else {
    2272          186024 :                 mOffsets = nsnull;
    2273                 :             }
    2274                 :         }
    2275          383074 :     }
    2276                 : 
    2277                 : #ifdef GET_IT
    2278                 : #undef GET_IT
    2279                 : #endif
    2280                 : #define GET_IT(f_) const {return !!(mClassInfoFlags & nsIClassInfo:: f_ );}
    2281                 : 
    2282                 :     JSBool ClassIsSingleton()           GET_IT(SINGLETON)
    2283         9169773 :     JSBool ClassIsThreadSafe()          GET_IT(THREADSAFE)
    2284         1094151 :     JSBool ClassIsMainThreadOnly()      GET_IT(MAIN_THREAD_ONLY)
    2285           30679 :     JSBool ClassIsDOMObject()           GET_IT(DOM_OBJECT)
    2286                 :     JSBool ClassIsPluginObject()        GET_IT(PLUGIN_OBJECT)
    2287                 : 
    2288                 : #undef GET_IT
    2289                 : 
    2290         5659564 :     XPCLock* GetLock() const
    2291         5659564 :         {return ClassIsThreadSafe() ? GetRuntime()->GetMapLock() : nsnull;}
    2292                 : 
    2293                 :     void SetScriptableInfo(XPCNativeScriptableInfo* si)
    2294                 :         {NS_ASSERTION(!mScriptableInfo, "leak here!"); mScriptableInfo = si;}
    2295                 : 
    2296                 :     bool CallPostCreatePrototype(XPCCallContext& ccx);
    2297                 :     void JSProtoObjectFinalized(JSContext *cx, JSObject *obj);
    2298                 : 
    2299                 :     void SystemIsBeingShutDown();
    2300                 : 
    2301                 :     void DebugDump(PRInt16 depth);
    2302                 : 
    2303         1895324 :     void TraceJS(JSTracer* trc)
    2304                 :     {
    2305         1895324 :         if (mJSProtoObject) {
    2306         1895324 :             JS_CALL_OBJECT_TRACER(trc, mJSProtoObject,
    2307                 :                                   "XPCWrappedNativeProto::mJSProtoObject");
    2308                 :         }
    2309         1895324 :         if (mScriptableInfo && JS_IsGCMarkingTracer(trc))
    2310          818539 :             mScriptableInfo->Mark();
    2311         1895324 :     }
    2312                 : 
    2313               0 :     void WriteBarrierPre(JSRuntime* rt)
    2314                 :     {
    2315               0 :         if (js::IsIncrementalBarrierNeeded(rt) && mJSProtoObject)
    2316               0 :             mJSProtoObject.writeBarrierPre(rt);
    2317               0 :     }
    2318                 : 
    2319                 :     // NOP. This is just here to make the AutoMarkingPtr code compile.
    2320               0 :     inline void AutoTrace(JSTracer* trc) {}
    2321                 : 
    2322                 :     // Yes, we *do* need to mark the mScriptableInfo in both cases.
    2323         2728036 :     void Mark() const
    2324         2728036 :         {mSet->Mark();
    2325         2728036 :          if (mScriptableInfo) mScriptableInfo->Mark();}
    2326                 : 
    2327                 : #ifdef DEBUG
    2328         2728036 :     void ASSERT_SetNotMarked() const {mSet->ASSERT_NotMarked();}
    2329                 : #endif
    2330                 : 
    2331                 :     ~XPCWrappedNativeProto();
    2332                 : 
    2333                 : protected:
    2334                 :     // disable copy ctor and assignment
    2335                 :     XPCWrappedNativeProto(const XPCWrappedNativeProto& r); // not implemented
    2336                 :     XPCWrappedNativeProto& operator= (const XPCWrappedNativeProto& r); // not implemented
    2337                 : 
    2338                 :     // hide ctor
    2339                 :     XPCWrappedNativeProto(XPCWrappedNativeScope* Scope,
    2340                 :                           nsIClassInfo* ClassInfo,
    2341                 :                           PRUint32 ClassInfoFlags,
    2342                 :                           XPCNativeSet* Set,
    2343                 :                           QITableEntry* offsets);
    2344                 : 
    2345                 :     JSBool Init(XPCCallContext& ccx,
    2346                 :                 const XPCNativeScriptableCreateInfo* scriptableCreateInfo,
    2347                 :                 bool callPostCreatePrototype);
    2348                 : 
    2349                 : private:
    2350                 : #if defined(DEBUG_xpc_hacker) || defined(DEBUG)
    2351                 :     static PRInt32 gDEBUG_LiveProtoCount;
    2352                 : #endif
    2353                 : 
    2354                 : private:
    2355                 :     bool
    2356          799707 :     InitedOffsets()
    2357                 :     {
    2358          799707 :         return mOffsets != UNKNOWN_OFFSETS;
    2359                 :     }
    2360                 : 
    2361                 :     XPCWrappedNativeScope*   mScope;
    2362                 :     js::ObjectPtr            mJSProtoObject;
    2363                 :     nsCOMPtr<nsIClassInfo>   mClassInfo;
    2364                 :     PRUint32                 mClassInfoFlags;
    2365                 :     XPCNativeSet*            mSet;
    2366                 :     void*                    mSecurityInfo;
    2367                 :     XPCNativeScriptableInfo* mScriptableInfo;
    2368                 :     QITableEntry*            mOffsets;
    2369                 : };
    2370                 : 
    2371                 : class xpcObjectHelper;
    2372                 : extern JSBool ConstructSlimWrapper(XPCCallContext &ccx,
    2373                 :                                    xpcObjectHelper &aHelper,
    2374                 :                                    XPCWrappedNativeScope* xpcScope,
    2375                 :                                    jsval *rval);
    2376                 : extern JSBool MorphSlimWrapper(JSContext *cx, JSObject *obj);
    2377                 : 
    2378                 : static inline XPCWrappedNativeProto*
    2379           35487 : GetSlimWrapperProto(JSObject *obj)
    2380                 : {
    2381           35487 :   const js::Value &v = js::GetReservedSlot(obj, 0);
    2382           35487 :   return static_cast<XPCWrappedNativeProto*>(v.toPrivate());
    2383                 : }
    2384                 : 
    2385                 : 
    2386                 : /***********************************************/
    2387                 : // XPCWrappedNativeTearOff represents the info needed to make calls to one
    2388                 : // interface on the underlying native object of a XPCWrappedNative.
    2389                 : 
    2390                 : class XPCWrappedNativeTearOff
    2391                 : {
    2392                 : public:
    2393         2252548 :     JSBool IsAvailable() const {return mInterface == nsnull;}
    2394                 :     JSBool IsReserved()  const {return mInterface == (XPCNativeInterface*)1;}
    2395                 :     JSBool IsValid()     const {return !IsAvailable() && !IsReserved();}
    2396         1522567 :     void   SetReserved()       {mInterface = (XPCNativeInterface*)1;}
    2397                 : 
    2398        17740440 :     XPCNativeInterface* GetInterface() const {return mInterface;}
    2399        12196185 :     nsISupports*        GetNative()    const {return mNative;}
    2400                 :     JSObject*           GetJSObject();
    2401                 :     JSObject*           GetJSObjectPreserveColor() const;
    2402         5525419 :     void SetInterface(XPCNativeInterface*  Interface) {mInterface = Interface;}
    2403         3043760 :     void SetNative(nsISupports*  Native)              {mNative = Native;}
    2404                 :     void SetJSObject(JSObject*  JSObj);
    2405                 : 
    2406              60 :     void JSObjectFinalized() {SetJSObject(nsnull);}
    2407                 : 
    2408         1442283 :     XPCWrappedNativeTearOff()
    2409         1442283 :         : mInterface(nsnull), mNative(nsnull), mJSObject(nsnull) {}
    2410                 :     ~XPCWrappedNativeTearOff();
    2411                 : 
    2412                 :     // NOP. This is just here to make the AutoMarkingPtr code compile.
    2413               0 :     inline void TraceJS(JSTracer* trc) {}
    2414               0 :     inline void AutoTrace(JSTracer* trc) {}
    2415                 : 
    2416            3877 :     void Mark()       {mJSObject = (JSObject*)(intptr_t(mJSObject) | 1);}
    2417         4092129 :     void Unmark()     {mJSObject = (JSObject*)(intptr_t(mJSObject) & ~1);}
    2418         2564542 :     bool IsMarked() const {return !!(intptr_t(mJSObject) & 1);}
    2419                 : 
    2420                 : private:
    2421                 :     XPCWrappedNativeTearOff(const XPCWrappedNativeTearOff& r) MOZ_DELETE;
    2422                 :     XPCWrappedNativeTearOff& operator= (const XPCWrappedNativeTearOff& r) MOZ_DELETE;
    2423                 : 
    2424                 : private:
    2425                 :     XPCNativeInterface* mInterface;
    2426                 :     nsISupports*        mNative;
    2427                 :     JSObject*           mJSObject;
    2428                 : };
    2429                 : 
    2430                 : /***********************************************/
    2431                 : // XPCWrappedNativeTearOffChunk is a collections of XPCWrappedNativeTearOff
    2432                 : // objects. It lets us allocate a set of XPCWrappedNativeTearOff objects and
    2433                 : // link the sets - rather than only having the option of linking single
    2434                 : // XPCWrappedNativeTearOff objects.
    2435                 : //
    2436                 : // The value of XPC_WRAPPED_NATIVE_TEAROFFS_PER_CHUNK can be tuned at buildtime
    2437                 : // to balance between the code of allocations of additional chunks and the waste
    2438                 : // of space for ununsed XPCWrappedNativeTearOff objects.
    2439                 : 
    2440                 : #define XPC_WRAPPED_NATIVE_TEAROFFS_PER_CHUNK 1
    2441                 : 
    2442                 : class XPCWrappedNativeTearOffChunk
    2443                 : {
    2444                 : friend class XPCWrappedNative;
    2445                 : private:
    2446         1442283 :     XPCWrappedNativeTearOffChunk() : mNextChunk(nsnull) {}
    2447         2882938 :     ~XPCWrappedNativeTearOffChunk() {delete mNextChunk;}
    2448                 : 
    2449                 : private:
    2450                 :     XPCWrappedNativeTearOff mTearOffs[XPC_WRAPPED_NATIVE_TEAROFFS_PER_CHUNK];
    2451                 :     XPCWrappedNativeTearOffChunk* mNextChunk;
    2452                 : };
    2453                 : 
    2454                 : void *xpc_GetJSPrivate(JSObject *obj);
    2455                 : 
    2456                 : /***************************************************************************/
    2457                 : // XPCWrappedNative the wrapper around one instance of a native xpcom object
    2458                 : // to be used from JavaScript.
    2459                 : 
    2460                 : class XPCWrappedNative : public nsIXPConnectWrappedNative
    2461                 : {
    2462                 : public:
    2463                 :     NS_DECL_ISUPPORTS
    2464                 :     NS_DECL_NSIXPCONNECTJSOBJECTHOLDER
    2465                 :     NS_DECL_NSIXPCONNECTWRAPPEDNATIVE
    2466                 :     // No need to unlink the JS objects, if the XPCWrappedNative will be cycle
    2467                 :     // collected then its mFlatJSObject will be cycle collected too and
    2468                 :     // finalization of the mFlatJSObject will unlink the js objects (see
    2469                 :     // XPC_WN_NoHelper_Finalize and FlatJSObjectFinalized).
    2470                 :     // We also give XPCWrappedNative empty Root/Unroot methods, to avoid
    2471                 :     // root/unrooting the JS objects from addrefing/releasing the
    2472                 :     // XPCWrappedNative during unlinking, which would make the JS objects
    2473                 :     // uncollectable to the JS GC.
    2474                 :     class NS_CYCLE_COLLECTION_INNERCLASS
    2475                 :      : public nsXPCOMCycleCollectionParticipant
    2476            1464 :     {
    2477             363 :       NS_DECL_CYCLE_COLLECTION_CLASS_BODY_NO_UNLINK(XPCWrappedNative,
    2478                 :                                                     XPCWrappedNative)
    2479             322 :       NS_IMETHOD Root(void *p) { return NS_OK; }
    2480                 :       NS_IMETHOD Unlink(void *p);
    2481             322 :       NS_IMETHOD Unroot(void *p) { return NS_OK; }
    2482                 :     };
    2483                 :     NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
    2484               0 :     NS_DECL_CYCLE_COLLECTION_UNMARK_PURPLE_STUB(XPCWrappedNative)
    2485                 : 
    2486                 :     nsIPrincipal* GetObjectPrincipal() const;
    2487                 : 
    2488                 :     JSBool
    2489        46998400 :     IsValid() const {return nsnull != mFlatJSObject;}
    2490                 : 
    2491                 : #define XPC_SCOPE_WORD(s)   (intptr_t(s))
    2492                 : #define XPC_SCOPE_MASK      (intptr_t(0x3))
    2493                 : #define XPC_SCOPE_TAG       (intptr_t(0x1))
    2494                 : #define XPC_WRAPPER_EXPIRED (intptr_t(0x2))
    2495                 : 
    2496                 :     static inline JSBool
    2497       105845901 :     IsTaggedScope(XPCWrappedNativeScope* s)
    2498       105845901 :         {return XPC_SCOPE_WORD(s) & XPC_SCOPE_TAG;}
    2499                 : 
    2500                 :     static inline XPCWrappedNativeScope*
    2501          882319 :     TagScope(XPCWrappedNativeScope* s)
    2502          882319 :         {NS_ASSERTION(!IsTaggedScope(s), "bad pointer!");
    2503          882319 :          return (XPCWrappedNativeScope*)(XPC_SCOPE_WORD(s) | XPC_SCOPE_TAG);}
    2504                 : 
    2505                 :     static inline XPCWrappedNativeScope*
    2506                 :     UnTagScope(XPCWrappedNativeScope* s)
    2507                 :         {return (XPCWrappedNativeScope*)(XPC_SCOPE_WORD(s) & ~XPC_SCOPE_TAG);}
    2508                 : 
    2509                 :     inline JSBool
    2510         1270383 :     IsWrapperExpired() const
    2511         1270383 :         {return XPC_SCOPE_WORD(mMaybeScope) & XPC_WRAPPER_EXPIRED;}
    2512                 : 
    2513                 :     JSBool
    2514       104963582 :     HasProto() const {return !IsTaggedScope(mMaybeScope);}
    2515                 : 
    2516                 :     XPCWrappedNativeProto*
    2517        53114223 :     GetProto() const
    2518        53114223 :         {return HasProto() ?
    2519                 :          (XPCWrappedNativeProto*)
    2520        53114223 :          (XPC_SCOPE_WORD(mMaybeProto) & ~XPC_SCOPE_MASK) : nsnull;}
    2521                 : 
    2522                 :     void SetProto(XPCWrappedNativeProto* p);
    2523                 : 
    2524                 :     XPCWrappedNativeScope*
    2525        14471147 :     GetScope() const
    2526        21097003 :         {return GetProto() ? GetProto()->GetScope() :
    2527                 :          (XPCWrappedNativeScope*)
    2528        21097003 :          (XPC_SCOPE_WORD(mMaybeScope) & ~XPC_SCOPE_MASK);}
    2529                 : 
    2530                 :     nsISupports*
    2531        13401020 :     GetIdentityObject() const {return mIdentity;}
    2532                 : 
    2533                 :     /**
    2534                 :      * This getter clears the gray bit before handing out the JSObject which
    2535                 :      * means that the object is guaranteed to be kept alive past the next CC.
    2536                 :      */
    2537                 :     JSObject*
    2538        16027718 :     GetFlatJSObject() const
    2539        16027718 :         {if (mFlatJSObject != INVALID_OBJECT)
    2540        16027718 :              xpc_UnmarkGrayObject(mFlatJSObject);
    2541        16027718 :          return mFlatJSObject;}
    2542                 : 
    2543                 :     /**
    2544                 :      * This getter does not change the color of the JSObject meaning that the
    2545                 :      * object returned is not guaranteed to be kept alive past the next CC.
    2546                 :      *
    2547                 :      * This should only be called if you are certain that the return value won't
    2548                 :      * be passed into a JS API function and that it won't be stored without
    2549                 :      * being rooted (or otherwise signaling the stored value to the CC).
    2550                 :      */
    2551                 :     JSObject*
    2552           14891 :     GetFlatJSObjectPreserveColor() const {return mFlatJSObject;}
    2553                 : 
    2554                 :     XPCLock*
    2555        44089256 :     GetLock() const {return IsValid() && HasProto() ?
    2556        44089256 :                                 GetProto()->GetLock() : nsnull;}
    2557                 : 
    2558                 :     XPCNativeSet*
    2559        11724518 :     GetSet() const {XPCAutoLock al(GetLock()); return mSet;}
    2560                 : 
    2561                 :     void
    2562             158 :     SetSet(XPCNativeSet* set) {XPCAutoLock al(GetLock()); mSet = set;}
    2563                 : 
    2564                 : private:
    2565                 :     inline void
    2566             322 :     ExpireWrapper()
    2567                 :         {mMaybeScope = (XPCWrappedNativeScope*)
    2568             322 :                        (XPC_SCOPE_WORD(mMaybeScope) | XPC_WRAPPER_EXPIRED);}
    2569                 : 
    2570                 : public:
    2571                 : 
    2572                 :     XPCNativeScriptableInfo*
    2573        14637652 :     GetScriptableInfo() const {return mScriptableInfo;}
    2574                 : 
    2575                 :     nsIXPCScriptable*      // call this wrong and you deserve to crash
    2576          506128 :     GetScriptableCallback() const  {return mScriptableInfo->GetCallback();}
    2577                 : 
    2578                 :     void**
    2579         7685879 :     GetSecurityInfoAddr() {return HasProto() ?
    2580         7685879 :                                    GetProto()->GetSecurityInfoAddr() : nsnull;}
    2581                 : 
    2582                 :     nsIClassInfo*
    2583        15373878 :     GetClassInfo() const {return IsValid() && HasProto() ?
    2584        15373878 :                             GetProto()->GetClassInfo() : nsnull;}
    2585                 : 
    2586                 :     JSBool
    2587         1309608 :     HasMutatedSet() const {return IsValid() &&
    2588         1309608 :                                   (!HasProto() ||
    2589         2619216 :                                    GetSet() != GetProto()->GetSet());}
    2590                 : 
    2591                 :     XPCJSRuntime*
    2592         5040256 :     GetRuntime() const {XPCWrappedNativeScope* scope = GetScope();
    2593         5040256 :                         return scope ? scope->GetRuntime() : nsnull;}
    2594                 : 
    2595                 :     static nsresult
    2596                 :     WrapNewGlobal(XPCCallContext &ccx, xpcObjectHelper &nativeHelper,
    2597                 :                   nsIPrincipal *principal, bool initStandardClasses,
    2598                 :                   XPCWrappedNative **wrappedGlobal);
    2599                 : 
    2600                 :     static nsresult
    2601                 :     GetNewOrUsed(XPCCallContext& ccx,
    2602                 :                  xpcObjectHelper& helper,
    2603                 :                  XPCWrappedNativeScope* Scope,
    2604                 :                  XPCNativeInterface* Interface,
    2605                 :                  XPCWrappedNative** wrapper);
    2606                 : 
    2607                 :     static nsresult
    2608                 :     Morph(XPCCallContext& ccx,
    2609                 :           JSObject* existingJSObject,
    2610                 :           XPCNativeInterface* Interface,
    2611                 :           nsWrapperCache *cache,
    2612                 :           XPCWrappedNative** resultWrapper);
    2613                 : 
    2614                 : public:
    2615                 :     static nsresult
    2616                 :     GetUsedOnly(XPCCallContext& ccx,
    2617                 :                 nsISupports* Object,
    2618                 :                 XPCWrappedNativeScope* Scope,
    2619                 :                 XPCNativeInterface* Interface,
    2620                 :                 XPCWrappedNative** wrapper);
    2621                 : 
    2622                 :     // If pobj2 is not null and *pobj2 is not null after the call then *pobj2
    2623                 :     // points to an object for which IS_SLIM_WRAPPER_OBJECT is true.
    2624                 :     // cx is null when invoked from the marking phase of the GC. In this case
    2625                 :     // fubobj must be null as well.
    2626                 :     static XPCWrappedNative*
    2627                 :     GetWrappedNativeOfJSObject(JSContext* cx, JSObject* obj,
    2628                 :                                JSObject* funobj = nsnull,
    2629                 :                                JSObject** pobj2 = nsnull,
    2630                 :                                XPCWrappedNativeTearOff** pTearOff = nsnull);
    2631                 :     static XPCWrappedNative*
    2632          237254 :     GetAndMorphWrappedNativeOfJSObject(JSContext* cx, JSObject* obj)
    2633                 :     {
    2634          237254 :         JSObject *obj2 = nsnull;
    2635                 :         XPCWrappedNative* wrapper =
    2636          237254 :             GetWrappedNativeOfJSObject(cx, obj, nsnull, &obj2);
    2637          237254 :         if (wrapper || !obj2)
    2638          237254 :             return wrapper;
    2639                 : 
    2640               0 :         NS_ASSERTION(IS_SLIM_WRAPPER(obj2),
    2641                 :                      "Hmm, someone changed GetWrappedNativeOfJSObject?");
    2642                 :         SLIM_LOG_WILL_MORPH(cx, obj2);
    2643               0 :         return MorphSlimWrapper(cx, obj2) ?
    2644               0 :                (XPCWrappedNative*)xpc_GetJSPrivate(obj2) :
    2645               0 :                nsnull;
    2646                 :     }
    2647                 : 
    2648                 :     static nsresult
    2649                 :     ReparentWrapperIfFound(XPCCallContext& ccx,
    2650                 :                            XPCWrappedNativeScope* aOldScope,
    2651                 :                            XPCWrappedNativeScope* aNewScope,
    2652                 :                            JSObject* aNewParent,
    2653                 :                            nsISupports* aCOMObj,
    2654                 :                            XPCWrappedNative** aWrapper);
    2655                 : 
    2656                 :     void FlatJSObjectFinalized();
    2657                 : 
    2658                 :     void SystemIsBeingShutDown();
    2659                 : 
    2660                 :     enum CallMode {CALL_METHOD, CALL_GETTER, CALL_SETTER};
    2661                 : 
    2662                 :     static JSBool CallMethod(XPCCallContext& ccx,
    2663                 :                              CallMode mode = CALL_METHOD);
    2664                 : 
    2665         2255104 :     static JSBool GetAttribute(XPCCallContext& ccx)
    2666         2255104 :         {return CallMethod(ccx, CALL_GETTER);}
    2667                 : 
    2668          102335 :     static JSBool SetAttribute(XPCCallContext& ccx)
    2669          102335 :         {return CallMethod(ccx, CALL_SETTER);}
    2670                 : 
    2671                 :     inline JSBool HasInterfaceNoQI(const nsIID& iid);
    2672                 : 
    2673                 :     XPCWrappedNativeTearOff* LocateTearOff(XPCCallContext& ccx,
    2674                 :                                            XPCNativeInterface* aInterface);
    2675                 :     XPCWrappedNativeTearOff* FindTearOff(XPCCallContext& ccx,
    2676                 :                                          XPCNativeInterface* aInterface,
    2677                 :                                          JSBool needJSObject = false,
    2678                 :                                          nsresult* pError = nsnull);
    2679         2233014 :     void Mark() const
    2680                 :     {
    2681         2233014 :         mSet->Mark();
    2682         2233014 :         if (mScriptableInfo) mScriptableInfo->Mark();
    2683         2233014 :         if (HasProto()) GetProto()->Mark();
    2684         2233014 :     }
    2685                 : 
    2686                 :     // Yes, we *do* need to mark the mScriptableInfo in both cases.
    2687         2285144 :     inline void TraceJS(JSTracer* trc)
    2688                 :     {
    2689         2285144 :         if (mScriptableInfo && JS_IsGCMarkingTracer(trc))
    2690         1891490 :             mScriptableInfo->Mark();
    2691         2285144 :         if (HasProto()) GetProto()->TraceJS(trc);
    2692         2285144 :         JSObject* wrapper = GetWrapperPreserveColor();
    2693         2285144 :         if (wrapper)
    2694               0 :             JS_CALL_OBJECT_TRACER(trc, wrapper, "XPCWrappedNative::mWrapper");
    2695         4221978 :         if (mScriptableInfo &&
    2696         1936834 :             (mScriptableInfo->GetJSClass()->flags & JSCLASS_XPCONNECT_GLOBAL))
    2697          134224 :             TraceXPCGlobal(trc, mFlatJSObject);
    2698                 : 
    2699         2285144 :     }
    2700                 : 
    2701               0 :     inline void AutoTrace(JSTracer* trc)
    2702                 :     {
    2703                 :         // If this got called, we're being kept alive by someone who really
    2704                 :         // needs us alive and whole.  Do not let our mFlatJSObject go away.
    2705                 :         // This is the only time we should be tracing our mFlatJSObject,
    2706                 :         // normally somebody else is doing that. Be careful not to trace the
    2707                 :         // bogus INVALID_OBJECT value we can have during init, though.
    2708               0 :         if (mFlatJSObject && mFlatJSObject != INVALID_OBJECT) {
    2709               0 :             JS_CALL_OBJECT_TRACER(trc, mFlatJSObject,
    2710                 :                                   "XPCWrappedNative::mFlatJSObject");
    2711                 :         }
    2712               0 :     }
    2713                 : 
    2714                 : #ifdef DEBUG
    2715         2233014 :     void ASSERT_SetsNotMarked() const
    2716         2233014 :         {mSet->ASSERT_NotMarked();
    2717         2233014 :          if (HasProto()){GetProto()->ASSERT_SetNotMarked();}}
    2718                 : 
    2719                 :     int DEBUG_CountOfTearoffChunks() const
    2720                 :         {int i = 0; const XPCWrappedNativeTearOffChunk* to;
    2721                 :          for (to = &mFirstChunk; to; to = to->mNextChunk) {i++;} return i;}
    2722                 : #endif
    2723                 : 
    2724                 :     inline void SweepTearOffs();
    2725                 : 
    2726                 :     // Returns a string that shuld be free'd using JS_smprintf_free (or null).
    2727                 :     char* ToString(XPCCallContext& ccx,
    2728                 :                    XPCWrappedNativeTearOff* to = nsnull) const;
    2729                 : 
    2730                 :     static void GatherProtoScriptableCreateInfo(nsIClassInfo* classInfo,
    2731                 :                                                 XPCNativeScriptableCreateInfo& sciProto);
    2732                 : 
    2733         3852297 :     JSBool HasExternalReference() const {return mRefCnt > 1;}
    2734                 : 
    2735         1464581 :     JSBool NeedsSOW() { return !!(mWrapperWord & NEEDS_SOW); }
    2736               0 :     void SetNeedsSOW() { mWrapperWord |= NEEDS_SOW; }
    2737                 :     JSBool NeedsCOW() { return !!(mWrapperWord & NEEDS_COW); }
    2738               0 :     void SetNeedsCOW() { mWrapperWord |= NEEDS_COW; }
    2739             363 :     JSBool MightHaveExpandoObject() { return !!(mWrapperWord & MIGHT_HAVE_EXPANDO); }
    2740               0 :     void SetHasExpandoObject() { mWrapperWord |= MIGHT_HAVE_EXPANDO; }
    2741                 : 
    2742         2285144 :     JSObject* GetWrapperPreserveColor() const
    2743         2285144 :         {return (JSObject*)(mWrapperWord & (size_t)~(size_t)FLAG_MASK);}
    2744                 : 
    2745               0 :     JSObject* GetWrapper()
    2746                 :     {
    2747               0 :         JSObject* wrapper = GetWrapperPreserveColor();
    2748               0 :         if (wrapper) {
    2749               0 :             xpc_UnmarkGrayObject(wrapper);
    2750                 :             // Call this to unmark mFlatJSObject.
    2751               0 :             GetFlatJSObject();
    2752                 :         }
    2753               0 :         return wrapper;
    2754                 :     }
    2755               0 :     void SetWrapper(JSObject *obj)
    2756                 :     {
    2757               0 :         js::IncrementalReferenceBarrier(GetWrapperPreserveColor());
    2758               0 :         PRWord newval = PRWord(obj) | (mWrapperWord & FLAG_MASK);
    2759               0 :         mWrapperWord = newval;
    2760               0 :     }
    2761                 : 
    2762                 :     void NoteTearoffs(nsCycleCollectionTraversalCallback& cb);
    2763                 : 
    2764           30679 :     QITableEntry* GetOffsets()
    2765                 :     {
    2766           30679 :         if (!HasProto() || !GetProto()->ClassIsDOMObject())
    2767               0 :             return nsnull;
    2768                 : 
    2769           30679 :         XPCWrappedNativeProto* proto = GetProto();
    2770           30679 :         QITableEntry* offsets = proto->GetOffsets();
    2771           30679 :         if (!offsets) {
    2772                 :             static NS_DEFINE_IID(kThisPtrOffsetsSID, NS_THISPTROFFSETS_SID);
    2773           28756 :             mIdentity->QueryInterface(kThisPtrOffsetsSID, (void**)&offsets);
    2774                 :         }
    2775           30679 :         return offsets;
    2776                 :     }
    2777                 : 
    2778                 :     // Make ctor and dtor protected (rather than private) to placate nsCOMPtr.
    2779                 : protected:
    2780                 :     XPCWrappedNative(); // not implemented
    2781                 : 
    2782                 :     // This ctor is used if this object will have a proto.
    2783                 :     XPCWrappedNative(already_AddRefed<nsISupports> aIdentity,
    2784                 :                      XPCWrappedNativeProto* aProto);
    2785                 : 
    2786                 :     // This ctor is used if this object will NOT have a proto.
    2787                 :     XPCWrappedNative(already_AddRefed<nsISupports> aIdentity,
    2788                 :                      XPCWrappedNativeScope* aScope,
    2789                 :                      XPCNativeSet* aSet);
    2790                 : 
    2791                 :     virtual ~XPCWrappedNative();
    2792                 :     void Destroy();
    2793                 : 
    2794                 :     void UpdateScriptableInfo(XPCNativeScriptableInfo *si);
    2795                 : 
    2796                 : private:
    2797                 :     enum {
    2798                 :         NEEDS_SOW = JS_BIT(0),
    2799                 :         NEEDS_COW = JS_BIT(1),
    2800                 :         MIGHT_HAVE_EXPANDO = JS_BIT(2),
    2801                 :         FLAG_MASK = JS_BITMASK(3)
    2802                 :     };
    2803                 : 
    2804                 : private:
    2805                 : 
    2806                 :     JSBool Init(XPCCallContext& ccx, JSObject* parent, const XPCNativeScriptableCreateInfo* sci);
    2807                 :     JSBool Init(XPCCallContext &ccx, JSObject *existingJSObject);
    2808                 :     JSBool FinishInit(XPCCallContext &ccx);
    2809                 : 
    2810                 :     JSBool ExtendSet(XPCCallContext& ccx, XPCNativeInterface* aInterface);
    2811                 : 
    2812                 :     nsresult InitTearOff(XPCCallContext& ccx,
    2813                 :                          XPCWrappedNativeTearOff* aTearOff,
    2814                 :                          XPCNativeInterface* aInterface,
    2815                 :                          JSBool needJSObject);
    2816                 : 
    2817                 :     JSBool InitTearOffJSObject(XPCCallContext& ccx,
    2818                 :                                XPCWrappedNativeTearOff* to);
    2819                 : 
    2820                 : public:
    2821                 :     static const XPCNativeScriptableCreateInfo& GatherScriptableCreateInfo(nsISupports* obj,
    2822                 :                                                                            nsIClassInfo* classInfo,
    2823                 :                                                                            XPCNativeScriptableCreateInfo& sciProto,
    2824                 :                                                                            XPCNativeScriptableCreateInfo& sciWrapper);
    2825                 : 
    2826                 : private:
    2827                 :     union
    2828                 :     {
    2829                 :         XPCWrappedNativeScope*   mMaybeScope;
    2830                 :         XPCWrappedNativeProto*   mMaybeProto;
    2831                 :     };
    2832                 :     XPCNativeSet*                mSet;
    2833                 :     JSObject*                    mFlatJSObject;
    2834                 :     XPCNativeScriptableInfo*     mScriptableInfo;
    2835                 :     XPCWrappedNativeTearOffChunk mFirstChunk;
    2836                 :     PRWord                       mWrapperWord;
    2837                 : 
    2838                 : #ifdef XPC_CHECK_WRAPPER_THREADSAFETY
    2839                 : public:
    2840                 :     // Don't want to overload _mOwningThread
    2841                 :     PRThread*                    mThread;
    2842                 : #endif
    2843                 : };
    2844                 : 
    2845                 : /***************************************************************************
    2846                 : ****************************************************************************
    2847                 : *
    2848                 : * Core classes for wrapped JSObject for use from native code...
    2849                 : *
    2850                 : ****************************************************************************
    2851                 : ***************************************************************************/
    2852                 : 
    2853                 : // this interfaces exists so we can refcount nsXPCWrappedJSClass
    2854                 : // {2453EBA0-A9B8-11d2-BA64-00805F8A5DD7}
    2855                 : #define NS_IXPCONNECT_WRAPPED_JS_CLASS_IID                                    \
    2856                 : { 0x2453eba0, 0xa9b8, 0x11d2,                                                 \
    2857                 :   { 0xba, 0x64, 0x0, 0x80, 0x5f, 0x8a, 0x5d, 0xd7 } }
    2858                 : 
    2859                 : class nsIXPCWrappedJSClass : public nsISupports
    2860           32512 : {
    2861                 : public:
    2862                 :     NS_DECLARE_STATIC_IID_ACCESSOR(NS_IXPCONNECT_WRAPPED_JS_CLASS_IID)
    2863                 :     NS_IMETHOD DebugDump(PRInt16 depth) = 0;
    2864                 : };
    2865                 : 
    2866                 : NS_DEFINE_STATIC_IID_ACCESSOR(nsIXPCWrappedJSClass,
    2867                 :                               NS_IXPCONNECT_WRAPPED_JS_CLASS_IID)
    2868                 : 
    2869                 : /*************************/
    2870                 : // nsXPCWrappedJSClass represents the sharable factored out common code and
    2871                 : // data for nsXPCWrappedJS instances for the same interface type.
    2872                 : 
    2873                 : class nsXPCWrappedJSClass : public nsIXPCWrappedJSClass
    2874                 : {
    2875                 :     // all the interface method declarations...
    2876                 :     NS_DECL_ISUPPORTS
    2877                 :     NS_IMETHOD DebugDump(PRInt16 depth);
    2878                 : public:
    2879                 : 
    2880                 :     static nsresult
    2881                 :     GetNewOrUsed(XPCCallContext& ccx,
    2882                 :                  REFNSIID aIID,
    2883                 :                  nsXPCWrappedJSClass** clazz);
    2884                 : 
    2885          649462 :     REFNSIID GetIID() const {return mIID;}
    2886          114050 :     XPCJSRuntime* GetRuntime() const {return mRuntime;}
    2887          554674 :     nsIInterfaceInfo* GetInterfaceInfo() const {return mInfo;}
    2888                 :     const char* GetInterfaceName();
    2889                 : 
    2890                 :     static JSBool IsWrappedJS(nsISupports* aPtr);
    2891                 : 
    2892                 :     NS_IMETHOD DelegatedQueryInterface(nsXPCWrappedJS* self, REFNSIID aIID,
    2893                 :                                        void** aInstancePtr);
    2894                 : 
    2895                 :     JSObject* GetRootJSObject(XPCCallContext& ccx, JSObject* aJSObj);
    2896                 : 
    2897                 :     NS_IMETHOD CallMethod(nsXPCWrappedJS* wrapper, uint16_t methodIndex,
    2898                 :                           const XPTMethodDescriptor* info,
    2899                 :                           nsXPTCMiniVariant* params);
    2900                 : 
    2901                 :     JSObject*  CallQueryInterfaceOnJSObject(XPCCallContext& ccx,
    2902                 :                                             JSObject* jsobj, REFNSIID aIID);
    2903                 : 
    2904                 :     static nsresult BuildPropertyEnumerator(XPCCallContext& ccx,
    2905                 :                                             JSObject* aJSObj,
    2906                 :                                             nsISimpleEnumerator** aEnumerate);
    2907                 : 
    2908                 :     static nsresult GetNamedPropertyAsVariant(XPCCallContext& ccx,
    2909                 :                                               JSObject* aJSObj,
    2910                 :                                               const nsAString& aName,
    2911                 :                                               nsIVariant** aResult);
    2912                 : 
    2913                 :     virtual ~nsXPCWrappedJSClass();
    2914                 : 
    2915                 :     static nsresult CheckForException(XPCCallContext & ccx,
    2916                 :                                       const char * aPropertyName,
    2917                 :                                       const char * anInterfaceName,
    2918                 :                                       bool aForceReport);
    2919                 : private:
    2920                 :     nsXPCWrappedJSClass();   // not implemented
    2921                 :     nsXPCWrappedJSClass(XPCCallContext& ccx, REFNSIID aIID,
    2922                 :                         nsIInterfaceInfo* aInfo);
    2923                 : 
    2924                 :     JSObject*  NewOutObject(JSContext* cx, JSObject* scope);
    2925                 : 
    2926         1225569 :     JSBool IsReflectable(uint16_t i) const
    2927         1225569 :         {return (JSBool)(mDescriptors[i/32] & (1 << (i%32)));}
    2928          183090 :     void SetReflectable(uint16_t i, JSBool b)
    2929          183090 :         {if (b) mDescriptors[i/32] |= (1 << (i%32));
    2930           65874 :          else mDescriptors[i/32] &= ~(1 << (i%32));}
    2931                 : 
    2932                 :     JSBool GetArraySizeFromParam(JSContext* cx,
    2933                 :                                  const XPTMethodDescriptor* method,
    2934                 :                                  const nsXPTParamInfo& param,
    2935                 :                                  uint16_t methodIndex,
    2936                 :                                  uint8_t paramIndex,
    2937                 :                                  nsXPTCMiniVariant* params,
    2938                 :                                  uint32_t* result);
    2939                 : 
    2940                 :     JSBool GetInterfaceTypeFromParam(JSContext* cx,
    2941                 :                                      const XPTMethodDescriptor* method,
    2942                 :                                      const nsXPTParamInfo& param,
    2943                 :                                      uint16_t methodIndex,
    2944                 :                                      const nsXPTType& type,
    2945                 :                                      nsXPTCMiniVariant* params,
    2946                 :                                      nsID* result);
    2947                 : 
    2948                 :     void CleanupPointerArray(const nsXPTType& datum_type,
    2949                 :                              uint32_t array_count,
    2950                 :                              void** arrayp);
    2951                 : 
    2952                 :     void CleanupPointerTypeObject(const nsXPTType& type,
    2953                 :                                   void** pp);
    2954                 : 
    2955                 : private:
    2956                 :     XPCJSRuntime* mRuntime;
    2957                 :     nsIInterfaceInfo* mInfo;
    2958                 :     char* mName;
    2959                 :     nsIID mIID;
    2960                 :     uint32_t* mDescriptors;
    2961                 : };
    2962                 : 
    2963                 : /*************************/
    2964                 : // nsXPCWrappedJS is a wrapper for a single JSObject for use from native code.
    2965                 : // nsXPCWrappedJS objects are chained together to represent the various
    2966                 : // interface on the single underlying (possibly aggregate) JSObject.
    2967                 : 
    2968                 : class nsXPCWrappedJS : protected nsAutoXPTCStub,
    2969                 :                        public nsIXPConnectWrappedJS,
    2970                 :                        public nsSupportsWeakReference,
    2971                 :                        public nsIPropertyBag,
    2972                 :                        public XPCRootSetElem
    2973                 : {
    2974                 : public:
    2975                 :     NS_DECL_ISUPPORTS
    2976                 :     NS_DECL_NSIXPCONNECTJSOBJECTHOLDER
    2977                 :     NS_DECL_NSIXPCONNECTWRAPPEDJS
    2978                 :     NS_DECL_NSISUPPORTSWEAKREFERENCE
    2979                 :     NS_DECL_NSIPROPERTYBAG
    2980                 : 
    2981           32625 :     NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsXPCWrappedJS, nsIXPConnectWrappedJS)
    2982               0 :     NS_DECL_CYCLE_COLLECTION_UNMARK_PURPLE_STUB(nsXPCWrappedJS)
    2983                 : 
    2984                 :     NS_IMETHOD CallMethod(PRUint16 methodIndex,
    2985                 :                           const XPTMethodDescriptor *info,
    2986                 :                           nsXPTCMiniVariant* params);
    2987                 : 
    2988                 :     /*
    2989                 :     * This is rarely called directly. Instead one usually calls
    2990                 :     * XPCConvert::JSObject2NativeInterface which will handles cases where the
    2991                 :     * JS object is already a wrapped native or a DOM object.
    2992                 :     */
    2993                 : 
    2994                 :     static nsresult
    2995                 :     GetNewOrUsed(XPCCallContext& ccx,
    2996                 :                  JSObject* aJSObj,
    2997                 :                  REFNSIID aIID,
    2998                 :                  nsISupports* aOuter,
    2999                 :                  nsXPCWrappedJS** wrapper);
    3000                 : 
    3001          485518 :     nsISomeInterface* GetXPTCStub() { return mXPTCStub; }
    3002                 : 
    3003                 :     /**
    3004                 :      * This getter clears the gray bit before handing out the JSObject which
    3005                 :      * means that the object is guaranteed to be kept alive past the next CC.
    3006                 :      */
    3007         3279232 :     JSObject* GetJSObject() const {xpc_UnmarkGrayObject(mJSObj);
    3008         3279232 :                                    return mJSObj;}
    3009                 : 
    3010                 :     /**
    3011                 :      * This getter does not change the color of the JSObject meaning that the
    3012                 :      * object returned is not guaranteed to be kept alive past the next CC.
    3013                 :      *
    3014                 :      * This should only be called if you are certain that the return value won't
    3015                 :      * be passed into a JS API function and that it won't be stored without
    3016                 :      * being rooted (or otherwise signaling the stored value to the CC).
    3017                 :      */
    3018          498800 :     JSObject* GetJSObjectPreserveColor() const {return mJSObj;}
    3019                 : 
    3020         1986403 :     nsXPCWrappedJSClass*  GetClass() const {return mClass;}
    3021          477652 :     REFNSIID GetIID() const {return GetClass()->GetIID();}
    3022           13784 :     nsXPCWrappedJS* GetRootWrapper() const {return mRoot;}
    3023          217151 :     nsXPCWrappedJS* GetNextWrapper() const {return mNext;}
    3024                 : 
    3025                 :     nsXPCWrappedJS* Find(REFNSIID aIID);
    3026                 :     nsXPCWrappedJS* FindInherited(REFNSIID aIID);
    3027                 : 
    3028         3001382 :     JSBool IsValid() const {return mJSObj != nsnull;}
    3029                 :     void SystemIsBeingShutDown(JSRuntime* rt);
    3030                 : 
    3031                 :     // This is used by XPCJSRuntime::GCCallback to find wrappers that no
    3032                 :     // longer root their JSObject and are only still alive because they
    3033                 :     // were being used via nsSupportsWeakReference at the time when their
    3034                 :     // last (outside) reference was released. Wrappers that fit into that
    3035                 :     // category are only deleted when we see that their corresponding JSObject
    3036                 :     // is to be finalized.
    3037          218343 :     JSBool IsSubjectToFinalization() const {return IsValid() && mRefCnt == 1;}
    3038                 : 
    3039            1062 :     JSBool IsAggregatedToNative() const {return mRoot->mOuter != nsnull;}
    3040          949112 :     nsISupports* GetAggregatedNativeObject() const {return mRoot->mOuter;}
    3041                 : 
    3042           88714 :     void SetIsMainThreadOnly() {
    3043           88714 :         MOZ_ASSERT(mMainThread);
    3044           88714 :         mMainThreadOnly = true;
    3045           88714 :     }
    3046           88800 :     bool IsMainThreadOnly() const {return mMainThreadOnly;}
    3047                 : 
    3048                 :     void TraceJS(JSTracer* trc);
    3049                 : #ifdef DEBUG
    3050                 :     static void PrintTraceName(JSTracer* trc, char *buf, size_t bufsize);
    3051                 : #endif
    3052                 : 
    3053                 :     virtual ~nsXPCWrappedJS();
    3054                 : protected:
    3055                 :     nsXPCWrappedJS();   // not implemented
    3056                 :     nsXPCWrappedJS(XPCCallContext& ccx,
    3057                 :                    JSObject* aJSObj,
    3058                 :                    nsXPCWrappedJSClass* aClass,
    3059                 :                    nsXPCWrappedJS* root,
    3060                 :                    nsISupports* aOuter);
    3061                 : 
    3062                 :    void Unlink();
    3063                 : 
    3064                 : private:
    3065                 :     JSObject* mJSObj;
    3066                 :     nsXPCWrappedJSClass* mClass;
    3067                 :     nsXPCWrappedJS* mRoot;
    3068                 :     nsXPCWrappedJS* mNext;
    3069                 :     nsISupports* mOuter;    // only set in root
    3070                 :     bool mMainThread;
    3071                 :     bool mMainThreadOnly;
    3072                 : };
    3073                 : 
    3074                 : /***************************************************************************/
    3075                 : 
    3076                 : class XPCJSObjectHolder : public nsIXPConnectJSObjectHolder,
    3077                 :                           public XPCRootSetElem
    3078                 : {
    3079                 : public:
    3080                 :     // all the interface method declarations...
    3081                 :     NS_DECL_ISUPPORTS
    3082                 :     NS_DECL_NSIXPCONNECTJSOBJECTHOLDER
    3083                 : 
    3084                 :     // non-interface implementation
    3085                 : 
    3086                 : public:
    3087                 :     static XPCJSObjectHolder* newHolder(XPCCallContext& ccx, JSObject* obj);
    3088                 : 
    3089                 :     virtual ~XPCJSObjectHolder();
    3090                 : 
    3091                 :     void TraceJS(JSTracer *trc);
    3092                 : #ifdef DEBUG
    3093                 :     static void PrintTraceName(JSTracer* trc, char *buf, size_t bufsize);
    3094                 : #endif
    3095                 : 
    3096                 : private:
    3097                 :     XPCJSObjectHolder(XPCCallContext& ccx, JSObject* obj);
    3098                 :     XPCJSObjectHolder(); // not implemented
    3099                 : 
    3100                 :     JSObject* mJSObj;
    3101                 : };
    3102                 : 
    3103                 : /***************************************************************************
    3104                 : ****************************************************************************
    3105                 : *
    3106                 : * All manner of utility classes follow...
    3107                 : *
    3108                 : ****************************************************************************
    3109                 : ***************************************************************************/
    3110                 : 
    3111                 : class xpcProperty : public nsIProperty
    3112                 : {
    3113                 : public:
    3114                 :   NS_DECL_ISUPPORTS
    3115                 :   NS_DECL_NSIPROPERTY
    3116                 : 
    3117                 :   xpcProperty(const PRUnichar* aName, PRUint32 aNameLen, nsIVariant* aValue);
    3118               0 :   virtual ~xpcProperty() {}
    3119                 : 
    3120                 : private:
    3121                 :     nsString             mName;
    3122                 :     nsCOMPtr<nsIVariant> mValue;
    3123                 : };
    3124                 : 
    3125                 : /***************************************************************************/
    3126                 : // data conversion
    3127                 : 
    3128                 : class xpcObjectHelper
    3129         2055846 : {
    3130                 : public:
    3131         2020856 :     xpcObjectHelper(nsISupports *aObject, nsWrapperCache *aCache = nsnull)
    3132                 :     : mCanonical(nsnull),
    3133                 :       mObject(aObject),
    3134                 :       mCache(aCache),
    3135         2020856 :       mIsNode(false)
    3136                 :     {
    3137         2020856 :         if (!mCache) {
    3138         2020854 :             if (aObject)
    3139         2020854 :                 CallQueryInterface(aObject, &mCache);
    3140                 :             else
    3141               0 :                 mCache = nsnull;
    3142                 :         }
    3143         2020856 :     }
    3144                 : 
    3145         3252494 :     nsISupports* Object()
    3146                 :     {
    3147         3252494 :         return mObject;
    3148                 :     }
    3149                 : 
    3150         2081389 :     nsISupports* GetCanonical()
    3151                 :     {
    3152         2081389 :         if (!mCanonical) {
    3153         2022978 :             mCanonicalStrong = do_QueryInterface(mObject);
    3154         2022978 :             mCanonical = mCanonicalStrong;
    3155                 :         }
    3156         2081389 :         return mCanonical;
    3157                 :     }
    3158                 : 
    3159         1265393 :     already_AddRefed<nsISupports> forgetCanonical()
    3160                 :     {
    3161         1265393 :         NS_ASSERTION(mCanonical, "Huh, no canonical to forget?");
    3162                 : 
    3163         1265393 :         if (!mCanonicalStrong)
    3164           12204 :             mCanonicalStrong = mCanonical;
    3165         1265393 :         mCanonical = nsnull;
    3166         1265393 :         return mCanonicalStrong.forget();
    3167                 :     }
    3168                 : 
    3169         1263456 :     nsIClassInfo *GetClassInfo()
    3170                 :     {
    3171         1263456 :         if (mXPCClassInfo)
    3172            4607 :           return mXPCClassInfo;
    3173         1258849 :         if (!mClassInfo)
    3174         1245632 :             mClassInfo = do_QueryInterface(mObject);
    3175         1258849 :         return mClassInfo;
    3176                 :     }
    3177           61350 :     nsXPCClassInfo *GetXPCClassInfo()
    3178                 :     {
    3179           61350 :         if (!mXPCClassInfo) {
    3180           46195 :             if (mIsNode)
    3181           14959 :                 mXPCClassInfo = static_cast<nsINode*>(GetCanonical())->GetClassInfo();
    3182                 :             else
    3183           31236 :                 CallQueryInterface(mObject, getter_AddRefs(mXPCClassInfo));
    3184                 :         }
    3185           61350 :         return mXPCClassInfo;
    3186                 :     }
    3187                 : 
    3188           15155 :     already_AddRefed<nsXPCClassInfo> forgetXPCClassInfo()
    3189                 :     {
    3190           15155 :         GetXPCClassInfo();
    3191                 : 
    3192           15155 :         return mXPCClassInfo.forget();
    3193                 :     }
    3194                 : 
    3195                 :     // We assert that we can reach an nsIXPCScriptable somehow.
    3196           26434 :     PRUint32 GetScriptableFlags()
    3197                 :     {
    3198                 :         // Try getting an nsXPCClassInfo - this handles DOM scriptable helpers.
    3199           52868 :         nsCOMPtr<nsIXPCScriptable> sinfo = GetXPCClassInfo();
    3200                 : 
    3201                 :         // If that didn't work, try just QI-ing. This handles BackstagePass.
    3202           26434 :         if (!sinfo)
    3203           26434 :             sinfo = do_QueryInterface(GetCanonical());
    3204                 : 
    3205                 :         // We should have something by now.
    3206           26434 :         MOZ_ASSERT(sinfo);
    3207                 : 
    3208                 :         // Grab the flags. This should not fail.
    3209                 :         PRUint32 flags;
    3210           52868 :         mozilla::DebugOnly<nsresult> rv = sinfo->GetScriptableFlags(&flags);
    3211           26434 :         MOZ_ASSERT(NS_SUCCEEDED(rv));
    3212                 : 
    3213           26434 :         return flags;
    3214                 :     }
    3215                 : 
    3216         4075761 :     nsWrapperCache *GetWrapperCache()
    3217                 :     {
    3218         4075761 :         return mCache;
    3219                 :     }
    3220                 : 
    3221                 : protected:
    3222           34990 :     xpcObjectHelper(nsISupports *aObject, nsISupports *aCanonical,
    3223                 :                     nsWrapperCache *aCache, bool aIsNode)
    3224                 :     : mCanonical(aCanonical),
    3225                 :       mObject(aObject),
    3226                 :       mCache(aCache),
    3227           34990 :       mIsNode(aIsNode)
    3228                 :     {
    3229           34990 :         if (!mCache && aObject)
    3230           16696 :             CallQueryInterface(aObject, &mCache);
    3231           34990 :     }
    3232                 : 
    3233                 :     nsCOMPtr<nsISupports>    mCanonicalStrong;
    3234                 :     nsISupports*             mCanonical;
    3235                 : 
    3236                 : private:
    3237                 :     xpcObjectHelper(xpcObjectHelper& aOther);
    3238                 : 
    3239                 :     nsISupports*             mObject;
    3240                 :     nsWrapperCache*          mCache;
    3241                 :     nsCOMPtr<nsIClassInfo>   mClassInfo;
    3242                 :     nsRefPtr<nsXPCClassInfo> mXPCClassInfo;
    3243                 :     bool                     mIsNode;
    3244                 : };
    3245                 : 
    3246                 : // class here just for static methods
    3247                 : class XPCConvert
    3248                 : {
    3249                 : public:
    3250                 :     static JSBool IsMethodReflectable(const XPTMethodDescriptor& info);
    3251                 : 
    3252                 :     /**
    3253                 :      * Convert a native object into a jsval.
    3254                 :      *
    3255                 :      * @param ccx the context for the whole procedure
    3256                 :      * @param d [out] the resulting jsval
    3257                 :      * @param s the native object we're working with
    3258                 :      * @param type the type of object that s is
    3259                 :      * @param iid the interface of s that we want
    3260                 :      * @param scope the default scope to put on the new JSObject's parent
    3261                 :      *        chain
    3262                 :      * @param pErr [out] relevant error code, if any.
    3263                 :      */
    3264        20351834 :     static JSBool NativeData2JS(XPCCallContext& ccx, jsval* d, const void* s,
    3265                 :                                 const nsXPTType& type, const nsID* iid,
    3266                 :                                 nsresult* pErr)
    3267                 :     {
    3268        40703668 :         XPCLazyCallContext lccx(ccx);
    3269        20351834 :         return NativeData2JS(lccx, d, s, type, iid, pErr);
    3270                 :     }
    3271                 :     static JSBool NativeData2JS(XPCLazyCallContext& lccx, jsval* d,
    3272                 :                                 const void* s, const nsXPTType& type,
    3273                 :                                 const nsID* iid, nsresult* pErr);
    3274                 : 
    3275                 :     static JSBool JSData2Native(XPCCallContext& ccx, void* d, jsval s,
    3276                 :                                 const nsXPTType& type,
    3277                 :                                 JSBool useAllocator, const nsID* iid,
    3278                 :                                 nsresult* pErr);
    3279                 : 
    3280                 :     /**
    3281                 :      * Convert a native nsISupports into a JSObject.
    3282                 :      *
    3283                 :      * @param ccx the context for the whole procedure
    3284                 :      * @param dest [out] the resulting JSObject
    3285                 :      * @param src the native object we're working with
    3286                 :      * @param iid the interface of src that we want (may be null)
    3287                 :      * @param Interface the interface of src that we want
    3288                 :      * @param cache the wrapper cache for src (may be null, in which case src
    3289                 :      *              will be QI'ed to get the cache)
    3290                 :      * @param allowNativeWrapper if true, this method may wrap the resulting
    3291                 :      *        JSObject in an XPCNativeWrapper and return that, as needed.
    3292                 :      * @param pErr [out] relevant error code, if any.
    3293                 :      * @param src_is_identity optional performance hint. Set to true only
    3294                 :      *                        if src is the identity pointer.
    3295                 :      */
    3296            3965 :     static JSBool NativeInterface2JSObject(XPCCallContext& ccx,
    3297                 :                                            jsval* d,
    3298                 :                                            nsIXPConnectJSObjectHolder** dest,
    3299                 :                                            xpcObjectHelper& aHelper,
    3300                 :                                            const nsID* iid,
    3301                 :                                            XPCNativeInterface** Interface,
    3302                 :                                            bool allowNativeWrapper,
    3303                 :                                            nsresult* pErr)
    3304                 :     {
    3305            7930 :         XPCLazyCallContext lccx(ccx);
    3306                 :         return NativeInterface2JSObject(lccx, d, dest, aHelper, iid, Interface,
    3307            3965 :                                         allowNativeWrapper, pErr);
    3308                 :     }
    3309                 :     static JSBool NativeInterface2JSObject(XPCLazyCallContext& lccx,
    3310                 :                                            jsval* d,
    3311                 :                                            nsIXPConnectJSObjectHolder** dest,
    3312                 :                                            xpcObjectHelper& aHelper,
    3313                 :                                            const nsID* iid,
    3314                 :                                            XPCNativeInterface** Interface,
    3315                 :                                            bool allowNativeWrapper,
    3316                 :                                            nsresult* pErr);
    3317                 : 
    3318                 :     static JSBool GetNativeInterfaceFromJSObject(XPCCallContext& ccx,
    3319                 :                                                  void** dest, JSObject* src,
    3320                 :                                                  const nsID* iid,
    3321                 :                                                  nsresult* pErr);
    3322                 :     static JSBool JSObject2NativeInterface(XPCCallContext& ccx,
    3323                 :                                            void** dest, JSObject* src,
    3324                 :                                            const nsID* iid,
    3325                 :                                            nsISupports* aOuter,
    3326                 :                                            nsresult* pErr);
    3327                 :     static JSBool GetISupportsFromJSObject(JSObject* obj, nsISupports** iface);
    3328                 : 
    3329                 :     /**
    3330                 :      * Convert a native array into a jsval.
    3331                 :      *
    3332                 :      * @param ccx the context for the whole procedure
    3333                 :      * @param d [out] the resulting jsval
    3334                 :      * @param s the native array we're working with
    3335                 :      * @param type the type of objects in the array
    3336                 :      * @param iid the interface of each object in the array that we want
    3337                 :      * @param count the number of items in the array
    3338                 :      * @param scope the default scope to put on the new JSObjects' parent chain
    3339                 :      * @param pErr [out] relevant error code, if any.
    3340                 :      */
    3341                 :     static JSBool NativeArray2JS(XPCLazyCallContext& ccx,
    3342                 :                                  jsval* d, const void** s,
    3343                 :                                  const nsXPTType& type, const nsID* iid,
    3344                 :                                  uint32_t count, nsresult* pErr);
    3345                 : 
    3346                 :     static JSBool JSArray2Native(XPCCallContext& ccx, void** d, jsval s,
    3347                 :                                  uint32_t count, const nsXPTType& type,
    3348                 :                                  const nsID* iid, nsresult* pErr);
    3349                 : 
    3350                 :     static JSBool JSTypedArray2Native(XPCCallContext& ccx,
    3351                 :                                       void** d,
    3352                 :                                       JSObject* jsarray,
    3353                 :                                       uint32_t count,
    3354                 :                                       const nsXPTType& type,
    3355                 :                                       nsresult* pErr);
    3356                 : 
    3357                 :     static JSBool NativeStringWithSize2JS(JSContext* cx,
    3358                 :                                           jsval* d, const void* s,
    3359                 :                                           const nsXPTType& type,
    3360                 :                                           uint32_t count,
    3361                 :                                           nsresult* pErr);
    3362                 : 
    3363                 :     static JSBool JSStringWithSize2Native(XPCCallContext& ccx, void* d, jsval s,
    3364                 :                                           uint32_t count, const nsXPTType& type,
    3365                 :                                           unsigned* pErr);
    3366                 : 
    3367                 :     static nsresult JSValToXPCException(XPCCallContext& ccx,
    3368                 :                                         jsval s,
    3369                 :                                         const char* ifaceName,
    3370                 :                                         const char* methodName,
    3371                 :                                         nsIException** exception);
    3372                 : 
    3373                 :     static nsresult JSErrorToXPCException(XPCCallContext& ccx,
    3374                 :                                           const char* message,
    3375                 :                                           const char* ifaceName,
    3376                 :                                           const char* methodName,
    3377                 :                                           const JSErrorReport* report,
    3378                 :                                           nsIException** exception);
    3379                 : 
    3380                 :     static nsresult ConstructException(nsresult rv, const char* message,
    3381                 :                                        const char* ifaceName,
    3382                 :                                        const char* methodName,
    3383                 :                                        nsISupports* data,
    3384                 :                                        nsIException** exception,
    3385                 :                                        JSContext* cx,
    3386                 :                                        jsval *jsExceptionPtr);
    3387                 : 
    3388                 : private:
    3389                 :     XPCConvert(); // not implemented
    3390                 : 
    3391                 : };
    3392                 : 
    3393                 : /***************************************************************************/
    3394                 : 
    3395                 : // readable string conversions, static methods only
    3396                 : class XPCStringConvert
    3397                 : {
    3398                 : public:
    3399                 : 
    3400                 :     // If the string shares the readable's buffer, that buffer will
    3401                 :     // get assigned to *sharedBuffer.  Otherwise null will be
    3402                 :     // assigned.
    3403                 :     static jsval ReadableToJSVal(JSContext *cx, const nsAString &readable,
    3404                 :                                  nsStringBuffer** sharedBuffer);
    3405                 : 
    3406                 : private:
    3407                 :     XPCStringConvert();         // not implemented
    3408                 : };
    3409                 : 
    3410                 : /***************************************************************************/
    3411                 : // code for throwing exceptions into JS
    3412                 : 
    3413                 : class XPCThrower
    3414                 : {
    3415                 : public:
    3416                 :     static void Throw(nsresult rv, JSContext* cx);
    3417                 :     static void Throw(nsresult rv, XPCCallContext& ccx);
    3418                 :     static void ThrowBadResult(nsresult rv, nsresult result, XPCCallContext& ccx);
    3419                 :     static void ThrowBadParam(nsresult rv, unsigned paramNum, XPCCallContext& ccx);
    3420                 :     static JSBool SetVerbosity(JSBool state)
    3421                 :         {JSBool old = sVerbose; sVerbose = state; return old;}
    3422                 : 
    3423                 :     static void BuildAndThrowException(JSContext* cx, nsresult rv, const char* sz);
    3424                 :     static JSBool CheckForPendingException(nsresult result, JSContext *cx);
    3425                 : 
    3426                 : private:
    3427                 :     static void Verbosify(XPCCallContext& ccx,
    3428                 :                           char** psz, bool own);
    3429                 : 
    3430                 :     static JSBool ThrowExceptionObject(JSContext* cx, nsIException* e);
    3431                 : 
    3432                 : private:
    3433                 :     static JSBool sVerbose;
    3434                 : };
    3435                 : 
    3436                 : 
    3437                 : /***************************************************************************/
    3438                 : 
    3439                 : class XPCJSStack
    3440                 : {
    3441                 : public:
    3442                 :     static nsresult
    3443                 :     CreateStack(JSContext* cx, nsIStackFrame** stack);
    3444                 : 
    3445                 :     static nsresult
    3446                 :     CreateStackFrameLocation(PRUint32 aLanguage,
    3447                 :                              const char* aFilename,
    3448                 :                              const char* aFunctionName,
    3449                 :                              PRInt32 aLineNumber,
    3450                 :                              nsIStackFrame* aCaller,
    3451                 :                              nsIStackFrame** stack);
    3452                 : private:
    3453                 :     XPCJSStack();   // not implemented
    3454                 : };
    3455                 : 
    3456                 : /***************************************************************************/
    3457                 : 
    3458                 : class nsXPCException :
    3459                 :             public nsIXPCException
    3460                 : {
    3461                 : public:
    3462             108 :     NS_DEFINE_STATIC_CID_ACCESSOR(NS_XPCEXCEPTION_CID)
    3463                 : 
    3464                 :     NS_DECL_ISUPPORTS
    3465                 :     NS_DECL_NSIEXCEPTION
    3466                 :     NS_DECL_NSIXPCEXCEPTION
    3467                 : 
    3468                 :     static nsresult NewException(const char *aMessage,
    3469                 :                                  nsresult aResult,
    3470                 :                                  nsIStackFrame *aLocation,
    3471                 :                                  nsISupports *aData,
    3472                 :                                  nsIException** exception);
    3473                 : 
    3474                 :     static JSBool NameAndFormatForNSResult(nsresult rv,
    3475                 :                                            const char** name,
    3476                 :                                            const char** format);
    3477                 : 
    3478                 :     static void* IterateNSResults(nsresult* rv,
    3479                 :                                   const char** name,
    3480                 :                                   const char** format,
    3481                 :                                   void** iterp);
    3482                 : 
    3483                 :     static PRUint32 GetNSResultCount();
    3484                 : 
    3485                 :     nsXPCException();
    3486                 :     virtual ~nsXPCException();
    3487                 : 
    3488            1404 :     static void InitStatics() { sEverMadeOneFromFactory = false; }
    3489                 : 
    3490                 : protected:
    3491                 :     void Reset();
    3492                 : private:
    3493                 :     char*           mMessage;
    3494                 :     nsresult        mResult;
    3495                 :     char*           mName;
    3496                 :     nsIStackFrame*  mLocation;
    3497                 :     nsISupports*    mData;
    3498                 :     char*           mFilename;
    3499                 :     int             mLineNumber;
    3500                 :     nsIException*   mInner;
    3501                 :     bool            mInitialized;
    3502                 : 
    3503                 :     nsAutoJSValHolder mThrownJSVal;
    3504                 : 
    3505                 :     static JSBool sEverMadeOneFromFactory;
    3506                 : };
    3507                 : 
    3508                 : /***************************************************************************/
    3509                 : /*
    3510                 : * nsJSID implements nsIJSID. It is also used by nsJSIID and nsJSCID as a
    3511                 : * member (as a hidden implementaion detail) to which they delegate many calls.
    3512                 : */
    3513                 : 
    3514                 : // Initialization is done on demand, and calling the destructor below is always
    3515                 : // safe.
    3516                 : extern void xpc_DestroyJSxIDClassObjects();
    3517                 : 
    3518                 : class nsJSID : public nsIJSID
    3519                 : {
    3520                 : public:
    3521            3257 :     NS_DEFINE_STATIC_CID_ACCESSOR(NS_JS_ID_CID)
    3522                 : 
    3523                 :     NS_DECL_ISUPPORTS
    3524                 :     NS_DECL_NSIJSID
    3525                 : 
    3526                 :     bool InitWithName(const nsID& id, const char *nameString);
    3527                 :     bool SetName(const char* name);
    3528               0 :     void   SetNameToNoString()
    3529               0 :         {NS_ASSERTION(!mName, "name already set"); mName = gNoString;}
    3530             364 :     bool NameIsSet() const {return nsnull != mName;}
    3531          339742 :     const nsID& ID() const {return mID;}
    3532          169176 :     bool IsValid() const {return !mID.Equals(GetInvalidIID());}
    3533                 : 
    3534                 :     static nsJSID* NewID(const char* str);
    3535                 :     static nsJSID* NewID(const nsID& id);
    3536                 : 
    3537                 :     nsJSID();
    3538                 :     virtual ~nsJSID();
    3539                 : protected:
    3540                 : 
    3541                 :     void Reset();
    3542                 :     const nsID& GetInvalidIID() const;
    3543                 : 
    3544                 : protected:
    3545                 :     static char gNoString[];
    3546                 :     nsID    mID;
    3547                 :     char*   mNumber;
    3548                 :     char*   mName;
    3549                 : };
    3550                 : 
    3551                 : // nsJSIID
    3552                 : 
    3553                 : class nsJSIID : public nsIJSIID,
    3554                 :                 public nsIXPCScriptable,
    3555                 :                 public nsISecurityCheckedComponent
    3556                 : {
    3557                 : public:
    3558                 :     NS_DECL_ISUPPORTS
    3559                 : 
    3560                 :     // we manually delagate these to nsJSID
    3561                 :     NS_DECL_NSIJSID
    3562                 : 
    3563                 :     // we implement the rest...
    3564                 :     NS_DECL_NSIJSIID
    3565                 :     NS_DECL_NSIXPCSCRIPTABLE
    3566                 :     NS_DECL_NSISECURITYCHECKEDCOMPONENT
    3567                 : 
    3568                 :     static nsJSIID* NewID(nsIInterfaceInfo* aInfo);
    3569                 : 
    3570                 :     nsJSIID(nsIInterfaceInfo* aInfo);
    3571                 :     nsJSIID(); // not implemented
    3572                 :     virtual ~nsJSIID();
    3573                 : 
    3574                 : private:
    3575                 :     nsCOMPtr<nsIInterfaceInfo> mInfo;
    3576                 : };
    3577                 : 
    3578                 : // nsJSCID
    3579                 : 
    3580                 : class nsJSCID : public nsIJSCID, public nsIXPCScriptable
    3581                 : {
    3582                 : public:
    3583                 :     NS_DECL_ISUPPORTS
    3584                 : 
    3585                 :     // we manually delagate these to nsJSID
    3586                 :     NS_DECL_NSIJSID
    3587                 : 
    3588                 :     // we implement the rest...
    3589                 :     NS_DECL_NSIJSCID
    3590                 :     NS_DECL_NSIXPCSCRIPTABLE
    3591                 : 
    3592                 :     static nsJSCID* NewID(const char* str);
    3593                 : 
    3594                 :     nsJSCID();
    3595                 :     virtual ~nsJSCID();
    3596                 : 
    3597                 : private:
    3598                 :     void ResolveName();
    3599                 : 
    3600                 : private:
    3601                 :     nsJSID mDetails;
    3602                 : };
    3603                 : 
    3604                 : 
    3605                 : /***************************************************************************/
    3606                 : // XPCJSContextStack is not actually an xpcom object, but xpcom calls are
    3607                 : // delegated to it as an implementation detail.
    3608          435334 : struct XPCJSContextInfo {
    3609          435334 :     XPCJSContextInfo(JSContext* aCx) :
    3610                 :         cx(aCx),
    3611                 :         savedFrameChain(false),
    3612          435334 :         suspendDepth(0)
    3613          435334 :     {}
    3614                 :     JSContext* cx;
    3615                 : 
    3616                 :     // Whether the frame chain was saved
    3617                 :     bool savedFrameChain;
    3618                 : 
    3619                 :     // Greater than 0 if a request was suspended.
    3620                 :     unsigned suspendDepth;
    3621                 : };
    3622                 : 
    3623                 : class XPCJSContextStack
    3624                 : {
    3625                 : public:
    3626            1407 :     XPCJSContextStack()
    3627                 :       : mSafeJSContext(NULL)
    3628            1407 :       , mOwnSafeJSContext(NULL)
    3629            1407 :     { }
    3630                 : 
    3631                 :     virtual ~XPCJSContextStack();
    3632                 : 
    3633               0 :     uint32_t Count()
    3634                 :     {
    3635               0 :         return mStack.Length();
    3636                 :     }
    3637                 : 
    3638        18658805 :     JSContext *Peek()
    3639                 :     {
    3640        18658805 :         return mStack.IsEmpty() ? NULL : mStack[mStack.Length() - 1].cx;
    3641                 :     }
    3642                 : 
    3643                 :     JSContext *Pop();
    3644                 :     bool Push(JSContext *cx);
    3645                 :     JSContext *GetSafeJSContext();
    3646                 : 
    3647                 : #ifdef DEBUG
    3648                 :     bool DEBUG_StackHasJSContext(JSContext *cx);
    3649                 : #endif
    3650                 : 
    3651               0 :     const InfallibleTArray<XPCJSContextInfo>* GetStack()
    3652               0 :     { return &mStack; }
    3653                 : 
    3654                 : private:
    3655                 :     AutoInfallibleTArray<XPCJSContextInfo, 16> mStack;
    3656                 :     JSContext*  mSafeJSContext;
    3657                 :     JSContext*  mOwnSafeJSContext;
    3658                 : };
    3659                 : 
    3660                 : /***************************************************************************/
    3661                 : 
    3662                 : #define NS_XPC_JSCONTEXT_STACK_ITERATOR_CID                                   \
    3663                 : { 0x05bae29d, 0x8aef, 0x486d,                                                 \
    3664                 :   { 0x84, 0xaa, 0x53, 0xf4, 0x8f, 0x14, 0x68, 0x11 } }
    3665                 : 
    3666                 : class nsXPCJSContextStackIterator : public nsIJSContextStackIterator
    3667               0 : {
    3668                 : public:
    3669                 :     NS_DECL_ISUPPORTS
    3670                 :     NS_DECL_NSIJSCONTEXTSTACKITERATOR
    3671                 : 
    3672                 : private:
    3673                 :     const InfallibleTArray<XPCJSContextInfo> *mStack;
    3674                 :     PRUint32 mPosition;
    3675                 : };
    3676                 : 
    3677                 : /**************************************************************/
    3678                 : // All of our thread local storage.
    3679                 : 
    3680                 : class XPCPerThreadData
    3681                 : {
    3682                 :     typedef mozilla::Mutex Mutex;
    3683                 : 
    3684                 : public:
    3685                 :     // Get the instance of this object for the current thread
    3686        19440155 :     static inline XPCPerThreadData* GetData(JSContext *cx)
    3687                 :     {
    3688                 :         // Do a release-mode assert that we're not doing anything significant in
    3689                 :         // XPConnect off the main thread. If you're an extension developer hitting
    3690                 :         // this, you need to change your code. See bug 716167.
    3691        19440155 :         if (!NS_LIKELY(NS_IsMainThread() || NS_IsCycleCollectorThread()))
    3692               0 :             MOZ_Assert("NS_IsMainThread()", __FILE__, __LINE__);
    3693                 : 
    3694        19440155 :         if (cx) {
    3695        14345909 :             if (js::GetOwnerThread(cx) == sMainJSThread)
    3696        14344501 :                 return sMainThreadData;
    3697         5094246 :         } else if (sMainThreadData && sMainThreadData->mThread == PR_GetCurrentThread()) {
    3698         5092842 :             return sMainThreadData;
    3699                 :         }
    3700                 : 
    3701            2812 :         return GetDataImpl(cx);
    3702                 :     }
    3703                 : 
    3704                 :     static void CleanupAllThreads();
    3705                 : 
    3706                 :     ~XPCPerThreadData();
    3707                 : 
    3708           38278 :     nsresult GetException(nsIException** aException)
    3709                 :     {
    3710           38278 :         if (EnsureExceptionManager())
    3711           38278 :             return mExceptionManager->GetCurrentException(aException);
    3712                 : 
    3713               0 :         NS_IF_ADDREF(mException);
    3714               0 :         *aException = mException;
    3715               0 :         return NS_OK;
    3716                 :     }
    3717                 : 
    3718         9203732 :     nsresult SetException(nsIException* aException)
    3719                 :     {
    3720         9203732 :         if (EnsureExceptionManager())
    3721         9203732 :             return mExceptionManager->SetCurrentException(aException);
    3722                 : 
    3723               0 :         NS_IF_ADDREF(aException);
    3724               0 :         NS_IF_RELEASE(mException);
    3725               0 :         mException = aException;
    3726               0 :         return NS_OK;
    3727                 :     }
    3728                 : 
    3729           38074 :     nsIExceptionManager* GetExceptionManager()
    3730                 :     {
    3731           38074 :         if (EnsureExceptionManager())
    3732           38074 :             return mExceptionManager;
    3733               0 :         return nsnull;
    3734                 :     }
    3735                 : 
    3736         9280084 :     JSBool EnsureExceptionManager()
    3737                 :     {
    3738         9280084 :         if (mExceptionManager)
    3739         9278693 :             return true;
    3740                 : 
    3741            1391 :         if (mExceptionManagerNotAvailable)
    3742               0 :             return false;
    3743                 : 
    3744                 :         nsCOMPtr<nsIExceptionService> xs =
    3745            2782 :             do_GetService(NS_EXCEPTIONSERVICE_CONTRACTID);
    3746            1391 :         if (xs)
    3747            1391 :             xs->GetCurrentExceptionManager(&mExceptionManager);
    3748            1391 :         if (mExceptionManager)
    3749            1391 :             return true;
    3750                 : 
    3751               0 :         mExceptionManagerNotAvailable = true;
    3752               0 :         return false;
    3753                 :     }
    3754                 : 
    3755        19339368 :     XPCJSContextStack* GetJSContextStack() {return mJSContextStack;}
    3756                 : 
    3757          235739 :     XPCCallContext*  GetCallContext() const {return mCallContext;}
    3758        31749366 :     XPCCallContext*  SetCallContext(XPCCallContext* ccx)
    3759        31749366 :         {XPCCallContext* old = mCallContext; mCallContext = ccx; return old;}
    3760                 : 
    3761         1692821 :     jsid GetResolveName() const {return mResolveName;}
    3762         6501348 :     jsid SetResolveName(jsid name)
    3763         6501348 :         {jsid old = mResolveName; mResolveName = name; return old;}
    3764                 : 
    3765          224081 :     XPCWrappedNative* GetResolvingWrapper() const {return mResolvingWrapper;}
    3766         1037978 :     XPCWrappedNative* SetResolvingWrapper(XPCWrappedNative* w)
    3767         1037978 :         {XPCWrappedNative* old = mResolvingWrapper;
    3768         1037978 :          mResolvingWrapper = w; return old;}
    3769                 : 
    3770                 :     void Cleanup();
    3771                 :     void ReleaseNatives();
    3772                 : 
    3773            1407 :     bool IsValid() const {return mJSContextStack != nsnull;}
    3774                 : 
    3775           35766 :     static Mutex* GetLock() {return gLock;}
    3776                 :     // Must be called with the threads locked.
    3777                 :     static XPCPerThreadData* IterateThreads(XPCPerThreadData** iteratorp);
    3778                 : 
    3779        45535894 :     AutoMarkingPtr**  GetAutoRootsAdr() {return &mAutoRoots;}
    3780                 : 
    3781                 :     void TraceJS(JSTracer* trc);
    3782                 :     void MarkAutoRootsAfterJSFinalize();
    3783                 : 
    3784            1404 :     static void InitStatics()
    3785            1404 :         { gLock = nsnull; gThreads = nsnull; gTLSIndex = BAD_TLS_INDEX; }
    3786                 : 
    3787                 : #ifdef XPC_CHECK_WRAPPER_THREADSAFETY
    3788               0 :     uint32_t  IncrementWrappedNativeThreadsafetyReportDepth()
    3789               0 :         {return ++mWrappedNativeThreadsafetyReportDepth;}
    3790               0 :     void      ClearWrappedNativeThreadsafetyReportDepth()
    3791               0 :         {mWrappedNativeThreadsafetyReportDepth = 0;}
    3792                 : #endif
    3793                 : 
    3794            1403 :     static void ShutDown()
    3795            1403 :         {sMainJSThread = nsnull; sMainThreadData = nsnull;}
    3796                 : 
    3797        12879431 :     static bool IsMainThread(JSContext *cx)
    3798        12879431 :         { return js::GetOwnerThread(cx) == sMainJSThread; }
    3799                 : 
    3800                 : private:
    3801                 :     XPCPerThreadData();
    3802                 :     static XPCPerThreadData* GetDataImpl(JSContext *cx);
    3803                 : 
    3804                 : private:
    3805                 :     XPCJSContextStack*   mJSContextStack;
    3806                 :     XPCPerThreadData*    mNextThread;
    3807                 :     XPCCallContext*      mCallContext;
    3808                 :     jsid                 mResolveName;
    3809                 :     XPCWrappedNative*    mResolvingWrapper;
    3810                 : 
    3811                 :     nsIExceptionManager* mExceptionManager;
    3812                 :     nsIException*        mException;
    3813                 :     JSBool               mExceptionManagerNotAvailable;
    3814                 :     AutoMarkingPtr*      mAutoRoots;
    3815                 : 
    3816                 : #ifdef XPC_CHECK_WRAPPER_THREADSAFETY
    3817                 :     uint32_t             mWrappedNativeThreadsafetyReportDepth;
    3818                 : #endif
    3819                 :     PRThread*            mThread;
    3820                 : 
    3821                 :     static Mutex*            gLock;
    3822                 :     static XPCPerThreadData* gThreads;
    3823                 :     static PRUintn           gTLSIndex;
    3824                 : 
    3825                 :     // Cached value of cx->thread on the main thread.
    3826                 :     static void *sMainJSThread;
    3827                 : 
    3828                 :     // Cached per thread data for the main thread. Only safe to access
    3829                 :     // if cx->thread == sMainJSThread.
    3830                 :     static XPCPerThreadData *sMainThreadData;
    3831                 : };
    3832                 : 
    3833                 : /***************************************************************************/
    3834                 : #include "nsIScriptSecurityManager.h"
    3835                 : 
    3836                 : class BackstagePass : public nsIScriptObjectPrincipal,
    3837                 :                       public nsIXPCScriptable,
    3838                 :                       public nsIClassInfo
    3839                 : {
    3840                 : public:
    3841                 :   NS_DECL_ISUPPORTS
    3842                 :   NS_DECL_NSIXPCSCRIPTABLE
    3843                 :   NS_DECL_NSICLASSINFO
    3844                 : 
    3845         5603479 :   virtual nsIPrincipal* GetPrincipal() {
    3846         5603479 :     return mPrincipal;
    3847                 :   }
    3848                 : 
    3849            1391 :   BackstagePass(nsIPrincipal *prin) :
    3850            1391 :     mPrincipal(prin)
    3851                 :   {
    3852            1391 :   }
    3853                 : 
    3854            5492 :   virtual ~BackstagePass() { }
    3855                 : 
    3856                 : private:
    3857                 :   nsCOMPtr<nsIPrincipal> mPrincipal;
    3858                 : };
    3859                 : // 'Components' object
    3860                 : 
    3861                 : class nsXPCComponents : public nsIXPCComponents,
    3862                 :                         public nsIXPCScriptable,
    3863                 :                         public nsIClassInfo,
    3864                 :                         public nsISecurityCheckedComponent
    3865                 : {
    3866                 : public:
    3867                 :     NS_DECL_ISUPPORTS
    3868                 :     NS_DECL_NSIXPCCOMPONENTS
    3869                 :     NS_DECL_NSIXPCSCRIPTABLE
    3870                 :     NS_DECL_NSICLASSINFO
    3871                 :     NS_DECL_NSISECURITYCHECKEDCOMPONENT
    3872                 : 
    3873                 : public:
    3874                 :     static JSBool
    3875                 :     AttachNewComponentsObject(XPCCallContext& ccx,
    3876                 :                               XPCWrappedNativeScope* aScope,
    3877                 :                               JSObject* aGlobal);
    3878                 : 
    3879              24 :     void SystemIsBeingShutDown() {ClearMembers();}
    3880                 : 
    3881                 :     virtual ~nsXPCComponents();
    3882                 : 
    3883                 : private:
    3884                 :     nsXPCComponents();
    3885                 :     void ClearMembers();
    3886                 : 
    3887                 : private:
    3888                 :     nsXPCComponents_Interfaces*     mInterfaces;
    3889                 :     nsXPCComponents_InterfacesByID* mInterfacesByID;
    3890                 :     nsXPCComponents_Classes*        mClasses;
    3891                 :     nsXPCComponents_ClassesByID*    mClassesByID;
    3892                 :     nsXPCComponents_Results*        mResults;
    3893                 :     nsXPCComponents_ID*             mID;
    3894                 :     nsXPCComponents_Exception*      mException;
    3895                 :     nsXPCComponents_Constructor*    mConstructor;
    3896                 :     nsXPCComponents_Utils*          mUtils;
    3897                 : };
    3898                 : 
    3899                 : 
    3900                 : /***************************************************************************/
    3901                 : 
    3902                 : extern JSObject*
    3903                 : xpc_NewIDObject(JSContext *cx, JSObject* jsobj, const nsID& aID);
    3904                 : 
    3905                 : extern const nsID*
    3906                 : xpc_JSObjectToID(JSContext *cx, JSObject* obj);
    3907                 : 
    3908                 : extern JSBool
    3909                 : xpc_JSObjectIsID(JSContext *cx, JSObject* obj);
    3910                 : 
    3911                 : /***************************************************************************/
    3912                 : // in xpcdebug.cpp
    3913                 : 
    3914                 : extern JSBool
    3915                 : xpc_DumpJSStack(JSContext* cx, JSBool showArgs, JSBool showLocals,
    3916                 :                 JSBool showThisProps);
    3917                 : 
    3918                 : // Return a newly-allocated string containing a representation of the
    3919                 : // current JS stack.  It is the *caller's* responsibility to free this
    3920                 : // string with JS_smprintf_free().
    3921                 : extern char*
    3922                 : xpc_PrintJSStack(JSContext* cx, JSBool showArgs, JSBool showLocals,
    3923                 :                  JSBool showThisProps);
    3924                 : 
    3925                 : extern JSBool
    3926                 : xpc_DumpEvalInJSStackFrame(JSContext* cx, uint32_t frameno, const char* text);
    3927                 : 
    3928                 : extern JSBool
    3929                 : xpc_DumpJSObject(JSObject* obj);
    3930                 : 
    3931                 : extern JSBool
    3932                 : xpc_InstallJSDebuggerKeywordHandler(JSRuntime* rt);
    3933                 : 
    3934                 : /***************************************************************************/
    3935                 : 
    3936                 : // Definition of nsScriptError, defined here because we lack a place to put
    3937                 : // XPCOM objects associated with the JavaScript engine.
    3938                 : class nsScriptError : public nsIScriptError {
    3939                 : public:
    3940                 :     nsScriptError();
    3941                 : 
    3942                 :     virtual ~nsScriptError();
    3943                 : 
    3944                 :   // TODO - do something reasonable on getting null from these babies.
    3945                 : 
    3946                 :     NS_DECL_ISUPPORTS
    3947                 :     NS_DECL_NSICONSOLEMESSAGE
    3948                 :     NS_DECL_NSISCRIPTERROR
    3949                 : 
    3950                 : private:
    3951                 :     nsString mMessage;
    3952                 :     nsString mSourceName;
    3953                 :     PRUint32 mLineNumber;
    3954                 :     nsString mSourceLine;
    3955                 :     PRUint32 mColumnNumber;
    3956                 :     PRUint32 mFlags;
    3957                 :     nsCString mCategory;
    3958                 :     PRUint64 mOuterWindowID;
    3959                 :     PRUint64 mInnerWindowID;
    3960                 :     PRInt64 mTimeStamp;
    3961                 : };
    3962                 : 
    3963                 : /******************************************************************************
    3964                 :  * Handles pre/post script processing and the setting/resetting the error
    3965                 :  * reporter
    3966                 :  */
    3967                 : class NS_STACK_CLASS AutoScriptEvaluate
    3968                 : {
    3969                 : public:
    3970                 :     /**
    3971                 :      * Saves the JSContext as well as initializing our state
    3972                 :      * @param cx The JSContext, this can be null, we don't do anything then
    3973                 :      */
    3974         1520912 :     AutoScriptEvaluate(JSContext * cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
    3975                 :          : mJSContext(cx), mState(0), mErrorReporterSet(false),
    3976         1520912 :            mEvaluated(false), mContextHasThread(0) {
    3977         1520912 :         MOZ_GUARD_OBJECT_NOTIFIER_INIT;
    3978         1520912 :     }
    3979                 : 
    3980                 :     /**
    3981                 :      * Does the pre script evaluation and sets the error reporter if given
    3982                 :      * This function should only be called once, and will assert if called
    3983                 :      * more than once
    3984                 :      * @param errorReporter the error reporter callback function to set
    3985                 :      */
    3986                 : 
    3987                 :     bool StartEvaluating(JSObject *scope, JSErrorReporter errorReporter = nsnull);
    3988                 :     /**
    3989                 :      * Does the post script evaluation and resets the error reporter
    3990                 :      */
    3991                 :     ~AutoScriptEvaluate();
    3992                 : private:
    3993                 :     JSContext* mJSContext;
    3994                 :     JSExceptionState* mState;
    3995                 :     bool mErrorReporterSet;
    3996                 :     bool mEvaluated;
    3997                 :     intptr_t mContextHasThread;
    3998                 :     JSAutoEnterCompartment mEnterCompartment;
    3999                 :     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
    4000                 : 
    4001                 :     // No copying or assignment allowed
    4002                 :     AutoScriptEvaluate(const AutoScriptEvaluate &) MOZ_DELETE;
    4003                 :     AutoScriptEvaluate & operator =(const AutoScriptEvaluate &) MOZ_DELETE;
    4004                 : };
    4005                 : 
    4006                 : /***************************************************************************/
    4007                 : class NS_STACK_CLASS AutoResolveName
    4008                 : {
    4009                 : public:
    4010         1719228 :     AutoResolveName(XPCCallContext& ccx, jsid name
    4011                 :                     MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
    4012         1719228 :         : mTLS(ccx.GetThreadData()),
    4013         1719228 :           mOld(mTLS->SetResolveName(name)),
    4014         3438456 :           mCheck(name) {
    4015         1719228 :         MOZ_GUARD_OBJECT_NOTIFIER_INIT;
    4016         1719228 :     }
    4017         1719228 :     ~AutoResolveName()
    4018         1719228 :         {
    4019                 : #ifdef DEBUG
    4020                 :             jsid old =
    4021                 : #endif
    4022         1719228 :             mTLS->SetResolveName(mOld);
    4023         1719228 :             NS_ASSERTION(old == mCheck, "Bad Nesting!");
    4024         1719228 :         }
    4025                 : 
    4026                 : private:
    4027                 :     XPCPerThreadData* mTLS;
    4028                 :     jsid mOld;
    4029                 :     jsid mCheck;
    4030                 :     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
    4031                 : };
    4032                 : 
    4033                 : /***************************************************************************/
    4034                 : class XPCMarkableJSVal
    4035                 : {
    4036                 : public:
    4037         1873201 :     XPCMarkableJSVal(jsval val) : mVal(val), mValPtr(&mVal) {}
    4038         8140419 :     XPCMarkableJSVal(jsval *pval) : mVal(JSVAL_VOID), mValPtr(pval) {}
    4039        10013620 :     ~XPCMarkableJSVal() {}
    4040               7 :     void Mark() {}
    4041               7 :     void TraceJS(JSTracer* trc)
    4042                 :     {
    4043               7 :         JS_CALL_VALUE_TRACER(trc, *mValPtr, "XPCMarkableJSVal");
    4044               7 :     }
    4045               7 :     void AutoTrace(JSTracer* trc) {}
    4046                 : private:
    4047                 :     XPCMarkableJSVal(); // not implemented
    4048                 :     jsval  mVal;
    4049                 :     jsval* mValPtr;
    4050                 : };
    4051                 : 
    4052                 : /***************************************************************************/
    4053                 : // AutoMarkingPtr is the base class for the various AutoMarking pointer types
    4054                 : // below. This system allows us to temporarily protect instances of our garbage
    4055                 : // collected types after they are constructed but before they are safely
    4056                 : // attached to other rooted objects.
    4057                 : // This base class has pure virtual support for marking.
    4058                 : 
    4059                 : class AutoMarkingPtr
    4060                 : {
    4061                 : public:
    4062        20772830 :     AutoMarkingPtr(XPCCallContext& ccx)
    4063        20772830 :         : mNext(nsnull), mTLS(ccx.GetThreadData()) {Link();}
    4064         2001182 :     AutoMarkingPtr()
    4065         2001182 :         : mNext(nsnull), mTLS(nsnull) {}
    4066                 : 
    4067        45548024 :     virtual ~AutoMarkingPtr() {Unlink();}
    4068                 : 
    4069         1995117 :     void Init(XPCCallContext& ccx)
    4070         1995117 :         {NS_ASSERTION(!mTLS, "Already init'ed!");
    4071         1995117 :          mTLS = ccx.GetThreadData();
    4072         1995117 :          Link();}
    4073                 : 
    4074        22767947 :     void Link()
    4075        22767947 :         {if (!mTLS) return;
    4076        22767947 :          AutoMarkingPtr** list = mTLS->GetAutoRootsAdr();
    4077        22767947 :          mNext = *list; *list = this;}
    4078                 : 
    4079        22774012 :     void Unlink()
    4080        22774012 :         {if (!mTLS) return;
    4081        22767947 :          AutoMarkingPtr** cur = mTLS->GetAutoRootsAdr();
    4082        45535894 :          while (*cur != this) {
    4083               0 :             NS_ASSERTION(*cur, "This object not in list!");
    4084               0 :             cur = &(*cur)->mNext;
    4085                 :          }
    4086        22767947 :          *cur = mNext;
    4087        22767947 :          mTLS = nsnull;
    4088                 :         }
    4089                 : 
    4090                 :     AutoMarkingPtr* GetNext() {return mNext;}
    4091                 : 
    4092                 :     virtual void TraceJS(JSTracer* trc) = 0;
    4093                 :     virtual void MarkAfterJSFinalize() = 0;
    4094                 : 
    4095                 : protected:
    4096                 :     AutoMarkingPtr* mNext;
    4097                 :     XPCPerThreadData* mTLS;
    4098                 : };
    4099                 : 
    4100                 : // More joy of macros...
    4101                 : 
    4102                 : #define DEFINE_AUTO_MARKING_PTR_TYPE(class_, type_)                           \
    4103                 : class class_ : public AutoMarkingPtr                                          \
    4104                 : {                                                                             \
    4105                 : public:                                                                       \
    4106                 :     class_ ()                                                                 \
    4107                 :         : AutoMarkingPtr(), mPtr(nsnull) {}                                   \
    4108                 :     class_ (XPCCallContext& ccx, type_ * ptr = nsnull)                        \
    4109                 :         : AutoMarkingPtr(ccx), mPtr(ptr) {}                                   \
    4110                 :     virtual ~ class_ () {}                                                    \
    4111                 :                                                                               \
    4112                 :     virtual void TraceJS(JSTracer* trc)                                       \
    4113                 :         {if (mPtr) {                                                          \
    4114                 :            mPtr->TraceJS(trc);                                                \
    4115                 :            mPtr->AutoTrace(trc);                                              \
    4116                 :          }                                                                    \
    4117                 :          if (mNext) mNext->TraceJS(trc);}                                     \
    4118                 :                                                                               \
    4119                 :     virtual void MarkAfterJSFinalize()                                        \
    4120                 :         {if (mPtr) mPtr->Mark();                                              \
    4121                 :          if (mNext) mNext->MarkAfterJSFinalize();}                            \
    4122                 :                                                                               \
    4123                 :     type_ * get()        const  {return mPtr;}                                \
    4124                 :     operator type_ *()   const  {return mPtr;}                                \
    4125                 :     type_ * operator->() const  {return mPtr;}                                \
    4126                 :                                                                               \
    4127                 :     class_ & operator =(type_ * p)                                            \
    4128                 :         {NS_ASSERTION(mTLS, "Hasn't been init'ed!");                          \
    4129                 :          mPtr = p; return *this;}                                             \
    4130                 :                                                                               \
    4131                 : protected:                                                                    \
    4132                 :     type_ * mPtr;                                                             \
    4133                 : };
    4134                 : 
    4135                 : // Use the macro above to define our AutoMarking types...
    4136                 : 
    4137        35066094 : DEFINE_AUTO_MARKING_PTR_TYPE(AutoMarkingNativeInterfacePtr, XPCNativeInterface)
    4138        16566700 : DEFINE_AUTO_MARKING_PTR_TYPE(AutoMarkingNativeSetPtr, XPCNativeSet)
    4139         3768909 : DEFINE_AUTO_MARKING_PTR_TYPE(AutoMarkingWrappedNativePtr, XPCWrappedNative)
    4140         4582761 : DEFINE_AUTO_MARKING_PTR_TYPE(AutoMarkingWrappedNativeTearOffPtr, XPCWrappedNativeTearOff)
    4141         8312398 : DEFINE_AUTO_MARKING_PTR_TYPE(AutoMarkingWrappedNativeProtoPtr, XPCWrappedNativeProto)
    4142        30040874 : DEFINE_AUTO_MARKING_PTR_TYPE(AutoMarkingJSVal, XPCMarkableJSVal)
    4143           79302 : DEFINE_AUTO_MARKING_PTR_TYPE(AutoMarkingNativeScriptableInfoPtr, XPCNativeScriptableInfo)
    4144                 : 
    4145                 : #define DEFINE_AUTO_MARKING_ARRAY_PTR_TYPE(class_, type_)                     \
    4146                 : class class_ : public AutoMarkingPtr                                          \
    4147                 : {                                                                             \
    4148                 : public:                                                                       \
    4149                 :     class_ (XPCCallContext& ccx)                                              \
    4150                 :         : AutoMarkingPtr(ccx), mPtr(nsnull), mCount(0) {}                     \
    4151                 :     class_ (XPCCallContext& ccx, type_** aPtr, PRUint32 aCount,               \
    4152                 :             bool aClear = false)                                              \
    4153                 :         : AutoMarkingPtr(ccx), mPtr(aPtr), mCount(aCount)                     \
    4154                 :     {                                                                         \
    4155                 :         if (!mPtr) mCount = 0;                                                \
    4156                 :         else if (aClear) memset(mPtr, 0, mCount*sizeof(type_*));              \
    4157                 :     }                                                                         \
    4158                 :     virtual ~ class_ () {}                                                    \
    4159                 :                                                                               \
    4160                 :     virtual void TraceJS(JSTracer* trc)                                       \
    4161                 :     {                                                                         \
    4162                 :         for (PRUint32 i = 0; i < mCount; ++i) {                               \
    4163                 :             type_* cur = mPtr[i];                                             \
    4164                 :             if (cur) {                                                        \
    4165                 :                 cur->TraceJS(trc);                                            \
    4166                 :                 cur->AutoTrace(trc);                                          \
    4167                 :             }                                                                 \
    4168                 :         }                                                                     \
    4169                 :         if (mNext) mNext->TraceJS(trc);                                       \
    4170                 :     }                                                                         \
    4171                 :                                                                               \
    4172                 :     virtual void MarkAfterJSFinalize()                                        \
    4173                 :     {                                                                         \
    4174                 :         for (PRUint32 i = 0; i < mCount; ++i) {                               \
    4175                 :             type_* cur = mPtr[i];                                             \
    4176                 :             if (cur)                                                          \
    4177                 :                 cur->Mark();                                                  \
    4178                 :         }                                                                     \
    4179                 :         if (mNext) mNext->MarkAfterJSFinalize();                              \
    4180                 :     }                                                                         \
    4181                 :                                                                               \
    4182                 :     type_ ** get()       const  {return mPtr;}                                \
    4183                 :     operator type_ **()  const  {return mPtr;}                                \
    4184                 :     type_ ** operator->() const  {return mPtr;}                               \
    4185                 :                                                                               \
    4186                 :     class_ & operator =(const class_ & inst)                                  \
    4187                 :         {mPtr = inst.mPtr; mCount = inst.mCount; return *this;}               \
    4188                 :                                                                               \
    4189                 : protected:                                                                    \
    4190                 :     type_ ** mPtr;                                                            \
    4191                 :     PRUint32 mCount;                                                          \
    4192                 : };
    4193                 : 
    4194         1438302 : DEFINE_AUTO_MARKING_ARRAY_PTR_TYPE(AutoMarkingNativeInterfacePtrArrayPtr,
    4195                 :                                    XPCNativeInterface)
    4196                 : 
    4197                 : // Note: It looked like I would need one of these AutoMarkingPtr types for
    4198                 : // XPCNativeScriptableInfo in order to manage marking its
    4199                 : // XPCNativeScriptableShared member during construction. But AFAICT we build
    4200                 : // these and bind them to rooted things so immediately that this just is not
    4201                 : // needed.
    4202                 : 
    4203                 : #define AUTO_MARK_JSVAL_HELPER2(tok, line) tok##line
    4204                 : #define AUTO_MARK_JSVAL_HELPER(tok, line) AUTO_MARK_JSVAL_HELPER2(tok, line)
    4205                 : 
    4206                 : #define AUTO_MARK_JSVAL(ccx, val)                                             \
    4207                 :     XPCMarkableJSVal AUTO_MARK_JSVAL_HELPER(_val_,__LINE__)(val);             \
    4208                 :     AutoMarkingJSVal AUTO_MARK_JSVAL_HELPER(_automarker_,__LINE__)            \
    4209                 :     (ccx, &AUTO_MARK_JSVAL_HELPER(_val_,__LINE__))
    4210                 : 
    4211                 : /***************************************************************************/
    4212                 : // Allocates a string that grants all access ("AllAccess")
    4213                 : 
    4214                 : extern char* xpc_CloneAllAccess();
    4215                 : /***************************************************************************/
    4216                 : // Returns access if wideName is in list
    4217                 : 
    4218                 : extern char * xpc_CheckAccessList(const PRUnichar* wideName, const char* list[]);
    4219                 : 
    4220                 : /***************************************************************************/
    4221                 : // in xpcvariant.cpp...
    4222                 : 
    4223                 : // {1809FD50-91E8-11d5-90F9-0010A4E73D9A}
    4224                 : #define XPCVARIANT_IID                                                        \
    4225                 :     {0x1809fd50, 0x91e8, 0x11d5,                                              \
    4226                 :       { 0x90, 0xf9, 0x0, 0x10, 0xa4, 0xe7, 0x3d, 0x9a } }
    4227                 : 
    4228                 : // {DC524540-487E-4501-9AC7-AAA784B17C1C}
    4229                 : #define XPCVARIANT_CID                                                        \
    4230                 :     {0xdc524540, 0x487e, 0x4501,                                              \
    4231                 :       { 0x9a, 0xc7, 0xaa, 0xa7, 0x84, 0xb1, 0x7c, 0x1c } }
    4232                 : 
    4233                 : class XPCVariant : public nsIVariant
    4234                 : {
    4235                 : public:
    4236               2 :     NS_DECL_CYCLE_COLLECTING_ISUPPORTS
    4237                 :     NS_DECL_NSIVARIANT
    4238           31123 :     NS_DECL_CYCLE_COLLECTION_CLASS(XPCVariant)
    4239                 : 
    4240                 :     // If this class ever implements nsIWritableVariant, take special care with
    4241                 :     // the case when mJSVal is JSVAL_STRING, since we don't own the data in
    4242                 :     // that case.
    4243                 : 
    4244                 :     // We #define and iid so that out module local code can use QI to detect
    4245                 :     // if a given nsIVariant is in fact an XPCVariant.
    4246                 :     NS_DECLARE_STATIC_IID_ACCESSOR(XPCVARIANT_IID)
    4247                 : 
    4248                 :     static XPCVariant* newVariant(XPCCallContext& ccx, jsval aJSVal);
    4249                 : 
    4250                 :     /**
    4251                 :      * This getter clears the gray bit before handing out the jsval if the jsval
    4252                 :      * represents a JSObject. That means that the object is guaranteed to be
    4253                 :      * kept alive past the next CC.
    4254                 :      */
    4255            8002 :     jsval GetJSVal() const
    4256            8002 :         {if (!JSVAL_IS_PRIMITIVE(mJSVal))
    4257            1533 :              xpc_UnmarkGrayObject(JSVAL_TO_OBJECT(mJSVal));
    4258            8002 :          return mJSVal;}
    4259                 : 
    4260                 :     /**
    4261                 :      * This getter does not change the color of the jsval (if it represents a
    4262                 :      * JSObject) meaning that the value returned is not guaranteed to be kept
    4263                 :      * alive past the next CC.
    4264                 :      *
    4265                 :      * This should only be called if you are certain that the return value won't
    4266                 :      * be passed into a JS API function and that it won't be stored without
    4267                 :      * being rooted (or otherwise signaling the stored value to the CC).
    4268                 :      */
    4269            4016 :     jsval GetJSValPreserveColor() const {return mJSVal;}
    4270                 : 
    4271                 :     XPCVariant(XPCCallContext& ccx, jsval aJSVal);
    4272                 : 
    4273                 :     /**
    4274                 :      * Convert a variant into a jsval.
    4275                 :      *
    4276                 :      * @param ccx the context for the whole procedure
    4277                 :      * @param variant the variant to convert
    4278                 :      * @param scope the default scope to put on the new JSObject's parent chain
    4279                 :      * @param pErr [out] relevant error code, if any.
    4280                 :      * @param pJSVal [out] the resulting jsval.
    4281                 :      */
    4282                 :     static JSBool VariantDataToJS(XPCLazyCallContext& lccx,
    4283                 :                                   nsIVariant* variant,
    4284                 :                                   nsresult* pErr, jsval* pJSVal);
    4285                 : 
    4286               0 :     bool IsPurple()
    4287                 :     {
    4288               0 :         return mRefCnt.IsPurple();
    4289                 :     }
    4290                 : 
    4291               0 :     void RemovePurple()
    4292                 :     {
    4293               0 :         mRefCnt.RemovePurple();
    4294               0 :     }
    4295                 : 
    4296               0 :     void SetCCGeneration(PRUint32 aGen)
    4297                 :     {
    4298               0 :         mCCGeneration = aGen;
    4299               0 :     }
    4300                 : 
    4301               0 :     PRUint32 CCGeneration() { return mCCGeneration; }
    4302                 : protected:
    4303           19134 :     virtual ~XPCVariant() { }
    4304                 : 
    4305                 :     JSBool InitializeData(XPCCallContext& ccx);
    4306                 : 
    4307                 : protected:
    4308                 :     nsDiscriminatedUnion mData;
    4309                 :     jsval                mJSVal;
    4310                 :     bool                 mReturnRawObject : 1;
    4311                 :     PRUint32             mCCGeneration : 31;
    4312                 : };
    4313                 : 
    4314                 : NS_DEFINE_STATIC_IID_ACCESSOR(XPCVariant, XPCVARIANT_IID)
    4315                 : 
    4316                 : class XPCTraceableVariant: public XPCVariant,
    4317                 :                            public XPCRootSetElem
    4318                 : {
    4319                 : public:
    4320            3463 :     XPCTraceableVariant(XPCCallContext& ccx, jsval aJSVal)
    4321            3463 :         : XPCVariant(ccx, aJSVal)
    4322                 :     {
    4323            3463 :         ccx.GetRuntime()->AddVariantRoot(this);
    4324            3463 :     }
    4325                 : 
    4326                 :     virtual ~XPCTraceableVariant();
    4327                 : 
    4328                 :     void TraceJS(JSTracer* trc);
    4329                 : #ifdef DEBUG
    4330                 :     static void PrintTraceName(JSTracer* trc, char *buf, size_t bufsize);
    4331                 : #endif
    4332                 : };
    4333                 : 
    4334                 : /***************************************************************************/
    4335                 : 
    4336                 : #define PRINCIPALHOLDER_IID \
    4337                 : {0xbf109f49, 0xf94a, 0x43d8, {0x93, 0xdb, 0xe4, 0x66, 0x49, 0xc5, 0xd9, 0x7d}}
    4338                 : 
    4339                 : class PrincipalHolder : public nsIScriptObjectPrincipal
    4340                 : {
    4341                 : public:
    4342                 :     NS_DECLARE_STATIC_IID_ACCESSOR(PRINCIPALHOLDER_IID)
    4343                 : 
    4344            1706 :     PrincipalHolder(nsIPrincipal *holdee)
    4345            1706 :         : mHoldee(holdee)
    4346                 :     {
    4347            1706 :     }
    4348            6820 :     virtual ~PrincipalHolder() { }
    4349                 : 
    4350                 :     NS_DECL_ISUPPORTS
    4351                 : 
    4352                 :     nsIPrincipal *GetPrincipal();
    4353                 : 
    4354                 : private:
    4355                 :     nsCOMPtr<nsIPrincipal> mHoldee;
    4356                 : };
    4357                 : 
    4358                 : NS_DEFINE_STATIC_IID_ACCESSOR(PrincipalHolder, PRINCIPALHOLDER_IID)
    4359                 : 
    4360                 : /***************************************************************************/
    4361                 : // Utilities
    4362                 : 
    4363                 : inline void *
    4364         9026462 : xpc_GetJSPrivate(JSObject *obj)
    4365                 : {
    4366         9026462 :     return js::GetObjectPrivate(obj);
    4367                 : }
    4368                 : 
    4369                 : 
    4370                 : // Helper for creating a sandbox object to use for evaluating
    4371                 : // untrusted code completely separated from all other code in the
    4372                 : // system using xpc_EvalInSandbox(). Takes the JSContext on which to
    4373                 : // do setup etc on, puts the sandbox object in *vp (which must be
    4374                 : // rooted by the caller), and uses the principal that's either
    4375                 : // directly passed in prinOrSop or indirectly as an
    4376                 : // nsIScriptObjectPrincipal holding the principal. If no principal is
    4377                 : // reachable through prinOrSop, a new null principal will be created
    4378                 : // and used.
    4379                 : nsresult
    4380                 : xpc_CreateSandboxObject(JSContext * cx, jsval * vp, nsISupports *prinOrSop,
    4381                 :                         JSObject *proto, bool preferXray, const nsACString &sandboxName,
    4382                 :                         nsISupports *identityPtr = nsnull);
    4383                 : // Helper for evaluating scripts in a sandbox object created with
    4384                 : // xpc_CreateSandboxObject(). The caller is responsible of ensuring
    4385                 : // that *rval doesn't get collected during the call or usage after the
    4386                 : // call. This helper will use filename and lineNo for error reporting,
    4387                 : // and if no filename is provided it will use the codebase from the
    4388                 : // principal and line number 1 as a fallback. if returnStringOnly is
    4389                 : // true, then the result in *rval, or the exception in cx->exception
    4390                 : // will be coerced into strings. If an exception is thrown converting
    4391                 : // an exception to a string, evalInSandbox will return an NS_ERROR_*
    4392                 : // result, and cx->exception will be empty.
    4393                 : nsresult
    4394                 : xpc_EvalInSandbox(JSContext *cx, JSObject *sandbox, const nsAString& source,
    4395                 :                   const char *filename, PRInt32 lineNo,
    4396                 :                   JSVersion jsVersion, bool returnStringOnly, jsval *rval);
    4397                 : 
    4398                 : /***************************************************************************/
    4399                 : // Inlined utilities.
    4400                 : 
    4401                 : inline JSBool
    4402                 : xpc_ForcePropertyResolve(JSContext* cx, JSObject* obj, jsid id);
    4403                 : 
    4404                 : inline jsid
    4405                 : GetRTIdByIndex(JSContext *cx, unsigned index);
    4406                 : 
    4407                 : // Wrapper for JS_NewObject to mark the new object as system when parent is
    4408                 : // also a system object. If uniqueType is specified then a new type object will
    4409                 : // be created which is used only by the result, so that its property types
    4410                 : // will be tracked precisely.
    4411                 : inline JSObject*
    4412                 : xpc_NewSystemInheritingJSObject(JSContext *cx, JSClass *clasp, JSObject *proto,
    4413                 :                                 bool uniqueType, JSObject *parent);
    4414                 : 
    4415                 : nsISupports *
    4416                 : XPC_GetIdentityObject(JSContext *cx, JSObject *obj);
    4417                 : 
    4418                 : namespace xpc {
    4419                 : 
    4420                 : struct CompartmentPrivate
    4421                 : {
    4422            3369 :     CompartmentPrivate(PtrAndPrincipalHashKey *key, bool wantXrays)
    4423                 :         : key(key),
    4424            3369 :           wantXrays(wantXrays)
    4425                 :     {
    4426            3369 :         MOZ_COUNT_CTOR(xpc::CompartmentPrivate);
    4427            3369 :     }
    4428                 : 
    4429                 :     ~CompartmentPrivate();
    4430                 : 
    4431                 :     nsAutoPtr<PtrAndPrincipalHashKey> key;
    4432                 :     bool wantXrays;
    4433                 :     nsAutoPtr<JSObject2JSObjectMap> waiverWrapperMap;
    4434                 :     // NB: we don't want this map to hold a strong reference to the wrapper.
    4435                 :     nsAutoPtr<nsDataHashtable<nsPtrHashKey<XPCWrappedNative>, JSObject *> > expandoMap;
    4436                 :     nsAutoPtr<nsTHashtable<nsPtrHashKey<JSObject> > > domExpandoMap;
    4437                 :     nsCString location;
    4438                 : 
    4439               0 :     bool RegisterExpandoObject(XPCWrappedNative *wn, JSObject *expando) {
    4440               0 :         if (!expandoMap) {
    4441               0 :             expandoMap = new nsDataHashtable<nsPtrHashKey<XPCWrappedNative>, JSObject *>();
    4442               0 :             if (!expandoMap->Init(8)) {
    4443               0 :                 expandoMap = nsnull;
    4444               0 :                 return false;
    4445                 :             }
    4446                 :         }
    4447               0 :         wn->SetHasExpandoObject();
    4448               0 :         return expandoMap->Put(wn, expando);
    4449                 :     }
    4450                 : 
    4451                 :     /**
    4452                 :      * This lookup does not change the color of the JSObject meaning that the
    4453                 :      * object returned is not guaranteed to be kept alive past the next CC.
    4454                 :      *
    4455                 :      * This should only be called if you are certain that the return value won't
    4456                 :      * be passed into a JS API function and that it won't be stored without
    4457                 :      * being rooted (or otherwise signaling the stored value to the CC).
    4458                 :      */
    4459               0 :     JSObject *LookupExpandoObjectPreserveColor(XPCWrappedNative *wn) {
    4460               0 :         return expandoMap ? expandoMap->Get(wn) : nsnull;
    4461                 :     }
    4462                 : 
    4463                 :     /**
    4464                 :      * This lookup clears the gray bit before handing out the JSObject which
    4465                 :      * means that the object is guaranteed to be kept alive past the next CC.
    4466                 :      */
    4467               0 :     JSObject *LookupExpandoObject(XPCWrappedNative *wn) {
    4468               0 :         JSObject *obj = LookupExpandoObjectPreserveColor(wn);
    4469               0 :         xpc_UnmarkGrayObject(obj);
    4470               0 :         return obj;
    4471                 :     }
    4472                 : 
    4473               0 :     bool RegisterDOMExpandoObject(JSObject *expando) {
    4474               0 :         if (!domExpandoMap) {
    4475               0 :             domExpandoMap = new nsTHashtable<nsPtrHashKey<JSObject> >();
    4476               0 :             if (!domExpandoMap->Init(8)) {
    4477               0 :                 domExpandoMap = nsnull;
    4478               0 :                 return false;
    4479                 :             }
    4480                 :         }
    4481               0 :         return domExpandoMap->PutEntry(expando);
    4482                 :     }
    4483               0 :     void RemoveDOMExpandoObject(JSObject *expando) {
    4484               0 :         if (domExpandoMap)
    4485               0 :             domExpandoMap->RemoveEntry(expando);
    4486               0 :     }
    4487                 : };
    4488                 : 
    4489                 : }
    4490                 : 
    4491                 : /***************************************************************************/
    4492                 : // Inlines use the above - include last.
    4493                 : 
    4494                 : #include "XPCInlines.h"
    4495                 : 
    4496                 : /***************************************************************************/
    4497                 : // Maps have inlines that use the above - include last.
    4498                 : 
    4499                 : #include "XPCMaps.h"
    4500                 : 
    4501                 : /***************************************************************************/
    4502                 : 
    4503                 : #endif /* xpcprivate_h___ */

Generated by: LCOV version 1.7