LCOV - code coverage report
Current view: directory - js/xpconnect/src - xpcprivate.h (source / functions) Found Hit Coverage
Test: app.info Lines: 840 724 86.2 %
Date: 2012-04-21 Functions: 454 390 85.9 %

       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            3304 :     PtrAndPrincipalHashKey(const PtrAndPrincipalHashKey *aKey)
     246                 :       : mPtr(aKey->mPtr), mPrincipal(aKey->mPrincipal),
     247            3304 :         mSavedHash(aKey->mSavedHash)
     248                 :     {
     249            3304 :         MOZ_COUNT_CTOR(PtrAndPrincipalHashKey);
     250            3304 :     }
     251                 : 
     252           18415 :     PtrAndPrincipalHashKey(nsISupports *aPtr, nsIPrincipal *aPrincipal)
     253           18415 :       : mPtr(aPtr), mPrincipal(aPrincipal)
     254                 :     {
     255           18415 :         MOZ_COUNT_CTOR(PtrAndPrincipalHashKey);
     256           36830 :         nsCOMPtr<nsIURI> uri;
     257           18415 :         aPrincipal->GetURI(getter_AddRefs(uri));
     258                 :         mSavedHash = uri
     259            2750 :                      ? NS_SecurityHashURI(uri)
     260           21165 :                      : (NS_PTR_TO_UINT32(mPtr.get()) >> 2);
     261           18415 :     }
     262                 : 
     263           21715 :     ~PtrAndPrincipalHashKey()
     264           21715 :     {
     265           21715 :         MOZ_COUNT_DTOR(PtrAndPrincipalHashKey);
     266           21715 :     }
     267                 : 
     268           57850 :     PtrAndPrincipalHashKey* GetKey() const
     269                 :     {
     270           57850 :         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           25019 :     KeyToPointer(PtrAndPrincipalHashKey* aKey) { return aKey; }
     278           25019 :     static PLDHashNumber HashKey(const PtrAndPrincipalHashKey* aKey)
     279                 :     {
     280           25019 :         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           14509 : static inline void xpc_NotifyAll(XPCLock* lock)
     344                 :     {
     345           14509 :         NS_ASSERTION(lock, "xpc_NotifyAll called with null lock!");
     346           14509 :         lock->NotifyAll();
     347           14509 :     }
     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            1365 :     static XPCLock* NewLock(const char* name)
     363            1365 :                         {return new mozilla::ReentrantMonitor(name);}
     364            1364 :     static void     DestroyLock(XPCLock* lock)
     365            2728 :                         {delete lock;}
     366                 : 
     367        34351767 :     XPCAutoLock(XPCLock* lock MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
     368        34351767 :         : mLock(lock)
     369                 :     {
     370        34351767 :         MOZ_GUARD_OBJECT_NOTIFIER_INIT;
     371        34351767 :         if (mLock)
     372        17981064 :             mLock->Enter();
     373        34351767 :     }
     374                 : 
     375        34351767 :     ~XPCAutoLock()
     376        34351767 :     {
     377        34351767 :         if (mLock) {
     378        17981064 :             mLock->Exit();
     379                 :         }
     380        34351767 :     }
     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         1504858 :     XPCAutoUnlock(XPCLock* lock MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
     407         1504858 :         : mLock(lock)
     408                 :     {
     409         1504858 :         MOZ_GUARD_OBJECT_NOTIFIER_INIT;
     410         1504858 :         if (mLock) {
     411          346831 :             mLock->Exit();
     412                 :         }
     413         1504858 :     }
     414                 : 
     415         1504858 :     ~XPCAutoUnlock()
     416         1504858 :     {
     417         1504858 :         if (mLock)
     418          346831 :             mLock->Enter();
     419         1504858 :     }
     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         5064630 : AddToCCKind(JSGCTraceKind kind)
     458                 : {
     459         5064630 :     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         2621686 :     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         1984810 :     nsIXPCSecurityManager* GetDefaultSecurityManager() const
     496                 :     {
     497                 :         // mDefaultSecurityManager is main-thread only.
     498         1984810 :         if (!NS_IsMainThread()) {
     499               0 :             return nsnull;
     500                 :         }
     501         1984810 :         return mDefaultSecurityManager;
     502                 :     }
     503                 : 
     504         1982603 :     PRUint16 GetDefaultSecurityManagerFlags() const
     505         1982603 :         {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            1365 :     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           58036 :     JSBool IsShuttingDown() const {return mShuttingDown;}
     520                 : 
     521               0 :     void EnsureGCBeforeCC() { mNeedGCBeforeCC = true; }
     522           14509 :     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            6312 :     static bool ReportAllJSExceptions()
     570                 :     {
     571            6312 :       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          127491 :     XPCRootSetElem()
     623                 :     {
     624                 : #ifdef DEBUG
     625          127491 :         mNext = nsnull;
     626          127491 :         mSelfp = nsnull;
     627                 : #endif
     628          127491 :     }
     629                 : 
     630          127210 :     ~XPCRootSetElem()
     631                 :     {
     632          127210 :         NS_ASSERTION(!mNext, "Must be unlinked");
     633          127210 :         NS_ASSERTION(!mSelfp, "Must be unlinked");
     634          127210 :     }
     635                 : 
     636          158037 :     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         1817797 :     JSRuntime*     GetJSRuntime() const {return mJSRuntime;}
     657         2188511 :     nsXPConnect*   GetXPConnect() const {return mXPConnect;}
     658                 :     JSContext*     GetJSCycleCollectionContext();
     659                 : 
     660          390439 :     JSObject2WrappedJSMap*     GetWrappedJSMap()        const
     661          390439 :         {return mWrappedJSMap;}
     662                 : 
     663          240707 :     IID2WrappedJSClassMap*     GetWrappedJSClassMap()   const
     664          240707 :         {return mWrappedJSClassMap;}
     665                 : 
     666         2640144 :     IID2NativeInterfaceMap* GetIID2NativeInterfaceMap() const
     667         2640144 :         {return mIID2NativeInterfaceMap;}
     668                 : 
     669          373254 :     ClassInfo2NativeSetMap* GetClassInfo2NativeSetMap() const
     670          373254 :         {return mClassInfo2NativeSetMap;}
     671                 : 
     672         1157926 :     NativeSetMap* GetNativeSetMap() const
     673         1157926 :         {return mNativeSetMap;}
     674                 : 
     675            9314 :     IID2ThisTranslatorMap* GetThisTranslatorMap() const
     676            9314 :         {return mThisTranslatorMap;}
     677                 : 
     678          250296 :     XPCNativeScriptableSharedMap* GetNativeScriptableSharedMap() const
     679          250296 :         {return mNativeScriptableSharedMap;}
     680                 : 
     681          187233 :     XPCWrappedNativeProtoMap* GetDyingWrappedNativeProtoMap() const
     682          187233 :         {return mDyingWrappedNativeProtoMap;}
     683                 : 
     684          190300 :     XPCWrappedNativeProtoMap* GetDetachedWrappedNativeProtoMap() const
     685          190300 :         {return mDetachedWrappedNativeProtoMap;}
     686                 : 
     687            1365 :     XPCNativeWrapperMap* GetExplicitNativeWrapperMap() const
     688            1365 :         {return mExplicitNativeWrapperMap;}
     689                 : 
     690           49323 :     XPCCompartmentMap& GetCompartmentMap()
     691           49323 :         {return mCompartmentMap;}
     692                 : 
     693        18169428 :     XPCLock* GetMapLock() const {return mMapLock;}
     694                 : 
     695                 :     JSBool OnJSContextNew(JSContext* cx);
     696                 : 
     697                 :     JSBool DeferredRelease(nsISupports* obj);
     698                 : 
     699         1241226 :     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        13554285 :     jsid GetStringID(unsigned index) const
     731                 :     {
     732        13554285 :         NS_ASSERTION(index < IDX_TOTAL_COUNT, "index out of range");
     733        13554285 :         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         2089352 :     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           15388 :     bool NewDOMBindingsEnabled()
     796                 :     {
     797           15388 :         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        16765765 :     static XPCContext* GetXPCContext(JSContext* aJSContext)
     861                 :         {
     862        16765765 :             NS_ASSERTION(JS_GetSecondContextPrivate(aJSContext), "should already have XPCContext");
     863        16765765 :             return static_cast<XPCContext *>(JS_GetSecondContextPrivate(aJSContext));
     864                 :         }
     865                 : 
     866        14873411 :     XPCJSRuntime* GetRuntime() const {return mRuntime;}
     867          116105 :     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        33113150 :     LangType SetCallingLangType(LangType lt)
     876                 :         {
     877        33113150 :             LangType tmp = mCallingLangType;
     878        33113150 :             mCallingLangType = lt;
     879        33113150 :             return tmp;
     880                 :         }
     881        16451375 :     JSBool CallerTypeIsJavaScript() const
     882                 :         {
     883        16451375 :             return LANG_JS == mCallingLangType;
     884                 :         }
     885                 :     JSBool CallerTypeIsNative() const
     886                 :         {
     887                 :             return LANG_NATIVE == mCallingLangType;
     888                 :         }
     889         9079552 :     JSBool CallerTypeIsKnown() const
     890                 :         {
     891         9079552 :             return LANG_UNKNOWN != mCallingLangType;
     892                 :         }
     893                 : 
     894            6784 :     nsresult GetException(nsIException** e)
     895                 :         {
     896            6784 :             NS_IF_ADDREF(mException);
     897            6784 :             *e = mException;
     898            6784 :             return NS_OK;
     899                 :         }
     900         1220005 :     void SetException(nsIException* e)
     901                 :         {
     902         1220005 :             NS_IF_ADDREF(e);
     903         1220005 :             NS_IF_RELEASE(mException);
     904         1220005 :             mException = e;
     905         1220005 :         }
     906                 : 
     907               2 :     nsresult GetLastResult() {return mLastResult;}
     908        14743618 :     void SetLastResult(nsresult rc) {mLastResult = rc;}
     909                 : 
     910            6784 :     nsresult GetPendingResult() {return mPendingResult;}
     911         1219821 :     void SetPendingResult(nsresult rc) {mPendingResult = rc;}
     912                 : 
     913            1365 :     nsIXPCSecurityManager* GetSecurityManager() const
     914            1365 :         {return mSecurityManager;}
     915            1365 :     void SetSecurityManager(nsIXPCSecurityManager* aSecurityManager)
     916            1365 :         {mSecurityManager = aSecurityManager;}
     917                 : 
     918               0 :     PRUint16 GetSecurityManagerFlags() const
     919               0 :         {return mSecurityManagerFlags;}
     920            1365 :     void SetSecurityManagerFlags(PRUint16 f)
     921            1365 :         {mSecurityManagerFlags = f;}
     922                 : 
     923         9079552 :     nsIXPCSecurityManager* GetAppropriateSecurityManager(PRUint16 flags) const
     924                 :         {
     925         9079552 :             NS_ASSERTION(CallerTypeIsKnown(),"missing caller type set somewhere");
     926         9079552 :             if (!CallerTypeIsJavaScript())
     927          562118 :                 return nsnull;
     928         8517434 :             if (mSecurityManager) {
     929         6534831 :                 if (flags & mSecurityManagerFlags)
     930         6534831 :                     return mSecurityManager;
     931                 :             } else {
     932                 :                 nsIXPCSecurityManager* mgr;
     933         1982603 :                 nsXPConnect* xpc = mRuntime->GetXPConnect();
     934         1982603 :                 mgr = xpc->GetDefaultSecurityManager();
     935         1982603 :                 if (mgr && (flags & xpc->GetDefaultSecurityManagerFlags()))
     936         1982603 :                     return mgr;
     937                 :             }
     938               0 :             return nsnull;
     939                 :         }
     940                 : 
     941                 :     void DebugDump(PRInt16 depth);
     942           15388 :     void AddScope(PRCList *scope) { PR_INSERT_AFTER(scope, &mScopes); }
     943            1638 :     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          210038 : {
     975                 : public:
     976                 :     typedef nsDependentString::char_traits char_traits;
     977                 : 
     978          226558 :     XPCReadableJSStringWrapper(const PRUnichar *chars, size_t length) :
     979          226558 :         nsDependentString(chars, length)
     980          226558 :     { }
     981                 : 
     982           22481 :     XPCReadableJSStringWrapper() :
     983           22481 :         nsDependentString(char_traits::sEmptyBuffer, char_traits::sEmptyBuffer)
     984           22481 :     { 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        41809898 :     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       314864354 : 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        33113150 :         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        21497555 :     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        21497555 :           , mTearOff(nsnull)
    1234                 : #endif
    1235                 :     {
    1236        21497555 :     }
    1237          139812 :     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          139812 :           mTearOff(tearoff)
    1252                 :     {
    1253          139812 :         NS_ASSERTION(cx, "Need a JS context!");
    1254          139812 :         NS_ASSERTION(callerLanguage == NATIVE_CALLER ||
    1255                 :                      callerLanguage == JS_CALLER,
    1256                 :                      "Can't deal with unknown caller language!");
    1257                 : #ifdef DEBUG
    1258          139812 :         AssertContextIsTopOfStack(cx);
    1259                 : #endif
    1260          139812 :     }
    1261        21637367 :     ~XPCLazyCallContext()
    1262                 :     {
    1263        21637367 :         if (mCcxToDestroy)
    1264          129979 :             mCcxToDestroy->~XPCCallContext();
    1265        21507388 :         else if (mCallBeginRequest == CALLED_BEGINREQUEST)
    1266               0 :             JS_EndRequest(mCx);
    1267        21637367 :     }
    1268                 :     void SetWrapper(XPCWrappedNative* wrapper,
    1269                 :                     XPCWrappedNativeTearOff* tearoff);
    1270                 :     void SetWrapper(JSObject* flattenedJSObject);
    1271                 : 
    1272        25932845 :     JSContext *GetJSContext()
    1273                 :     {
    1274        25932845 :         if (mCcx)
    1275        25674126 :             return mCcx->GetJSContext();
    1276                 : 
    1277          258719 :         if (mCallBeginRequest == CALL_BEGINREQUEST) {
    1278           99172 :             JS_BeginRequest(mCx);
    1279           99172 :             mCallBeginRequest = CALLED_BEGINREQUEST;
    1280                 :         }
    1281                 : 
    1282          258719 :         return mCx;
    1283                 :     }
    1284         9045299 :     JSObject *GetScopeForNewJSObjects() const
    1285                 :     {
    1286         9045299 :         if (mCcx)
    1287         8775215 :             return mCcx->GetScopeForNewJSObjects();
    1288                 : 
    1289          270084 :         return mObj;
    1290                 :     }
    1291          637580 :     void SetScopeForNewJSObjects(JSObject *obj)
    1292                 :     {
    1293          637580 :         if (mCcx) {
    1294          538408 :             mCcx->SetScopeForNewJSObjects(obj);
    1295          538408 :             return;
    1296                 :         }
    1297           99172 :         NS_ABORT_IF_FALSE(!mObj, "already set!");
    1298           99172 :         mObj = obj;
    1299                 :     }
    1300                 :     JSObject *GetFlattenedJSObject() const
    1301                 :     {
    1302                 :         if (mCcx)
    1303                 :             return mCcx->GetFlattenedJSObject();
    1304                 : 
    1305                 :         return mFlattenedJSObject;
    1306                 :     }
    1307         5761675 :     XPCCallContext &GetXPCCallContext()
    1308                 :     {
    1309         5761675 :         if (!mCcx) {
    1310                 :             mCcxToDestroy = mCcx =
    1311                 :                 new (mData) XPCCallContext(mCallerLanguage, mCx,
    1312                 :                                            mCallBeginRequest == CALL_BEGINREQUEST,
    1313                 :                                            mObj,
    1314                 :                                            mFlattenedJSObject, mWrapper,
    1315          129979 :                                            mTearOff);
    1316          129979 :             if (!mCcx->IsValid()) {
    1317               0 :                 NS_ERROR("This is not supposed to fail!");
    1318                 :             }
    1319                 :         }
    1320                 : 
    1321         5761675 :         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         7351529 : 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         7351529 :            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        17040280 :     GetRuntime() const {return mRuntime;}
    1509                 : 
    1510                 :     Native2WrappedNativeMap*
    1511         4572615 :     GetWrappedNativeMap() const {return mWrappedNativeMap;}
    1512                 : 
    1513                 :     ClassInfo2WrappedNativeProtoMap*
    1514          569668 :     GetWrappedNativeProtoMap(JSBool aMainThreadOnly) const
    1515                 :         {return aMainThreadOnly ?
    1516                 :                 mMainThreadWrappedNativeProtoMap :
    1517          569668 :                 mWrappedNativeProtoMap;}
    1518                 : 
    1519                 :     nsXPCComponents*
    1520            4547 :     GetComponents() const {return mComponents;}
    1521                 : 
    1522                 :     JSObject*
    1523         4963659 :     GetGlobalJSObject() const {return mGlobalJSObject;}
    1524                 : 
    1525                 :     JSObject*
    1526         3367083 :     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         2194253 :     GetPrincipal() const
    1535                 :     {return mScriptObjectPrincipal ?
    1536         2194253 :          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          151223 :     FindInJSObjectScope(XPCCallContext& ccx, JSObject* obj,
    1547                 :                         JSBool OKIfNotInitialized = false)
    1548                 :     {
    1549                 :         return FindInJSObjectScope(ccx, obj, OKIfNotInitialized,
    1550          151223 :                                    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            1365 :     static void InitStatics() { gScopes = nsnull; gDyingScopes = nsnull; }
    1604                 : 
    1605          116145 :     XPCContext *GetContext() { return mContext; }
    1606           13749 :     void SetContext(XPCContext *xpcc) { mContext = nsnull; }
    1607                 : 
    1608           19940 :     nsDataHashtable<nsDepCharHashKey, JSObject*>& GetCachedDOMPrototypes()
    1609                 :     {
    1610           19940 :         return mCachedDOMPrototypes;
    1611                 :     }
    1612                 : 
    1613          766620 :     static XPCWrappedNativeScope *GetNativeScope(JSObject *obj)
    1614                 :     {
    1615          766620 :         MOZ_ASSERT(js::GetObjectClass(obj)->flags & JSCLASS_XPCONNECT_GLOBAL);
    1616                 : 
    1617          766620 :         const js::Value &v = js::GetObjectSlot(obj, JSCLASS_GLOBAL_SLOT_COUNT);
    1618          766620 :         return v.isUndefined()
    1619                 :                ? nsnull
    1620          766620 :                : 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        72276138 :     jsid   GetName() const {return mName;}
    1687                 : 
    1688        10721502 :     PRUint16 GetIndex() const {return mIndex;}
    1689                 : 
    1690           20110 :     JSBool GetConstantValue(XPCCallContext& ccx, XPCNativeInterface* iface,
    1691                 :                             jsval* pval)
    1692           20110 :         {NS_ASSERTION(IsConstant(),
    1693                 :                       "Only call this if you're sure this is a constant!");
    1694           20110 :          return Resolve(ccx, iface, nsnull, pval);}
    1695                 : 
    1696                 :     JSBool NewFunctionObject(XPCCallContext& ccx, XPCNativeInterface* iface,
    1697                 :                              JSObject *parent, jsval* pval);
    1698                 : 
    1699         3408155 :     JSBool IsMethod() const
    1700         3408155 :         {return 0 != (mFlags & METHOD);}
    1701                 : 
    1702         8338253 :     JSBool IsConstant() const
    1703         8338253 :         {return 0 != (mFlags & CONSTANT);}
    1704                 : 
    1705         1190135 :     JSBool IsAttribute() const
    1706         1190135 :         {return 0 != (mFlags & GETTER);}
    1707                 : 
    1708         1286007 :     JSBool IsWritableAttribute() const
    1709         1286007 :         {return 0 != (mFlags & SETTER_TOO);}
    1710                 : 
    1711          172012 :     JSBool IsReadOnlyAttribute() const
    1712          172012 :         {return IsAttribute() && !IsWritableAttribute();}
    1713                 : 
    1714                 : 
    1715         1698385 :     void SetName(jsid a) {mName = a;}
    1716                 : 
    1717          807763 :     void SetMethod(PRUint16 index)
    1718          807763 :         {mFlags = METHOD; mIndex = index;}
    1719                 : 
    1720          388446 :     void SetConstant(PRUint16 index)
    1721          388446 :         {mFlags = CONSTANT; mIndex = index;}
    1722                 : 
    1723          502176 :     void SetReadOnlyAttribute(PRUint16 index)
    1724          502176 :         {mFlags = GETTER; mIndex = index;}
    1725                 : 
    1726          172012 :     void SetWritableAttribute()
    1727          172012 :         {NS_ASSERTION(mFlags == GETTER,"bad"); mFlags = GETTER | SETTER_TOO;}
    1728                 : 
    1729                 :     /* default ctor - leave random contents */
    1730         4684966 :     XPCNativeMember()  {MOZ_COUNT_CTOR(XPCNativeMember);}
    1731         4684946 :     ~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         8062748 :     inline nsIInterfaceInfo* GetInterfaceInfo() const {return mInfo.get();}
    1769        12332354 :     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          299127 :     PRUint16 GetMemberCount() const
    1778          299127 :         {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          547476 :     void Mark()     {mMemberCount |= XPC_NATIVE_IFACE_MARK_FLAG;}
    1787          276244 :     void Unmark()   {mMemberCount &= ~XPC_NATIVE_IFACE_MARK_FLAG;}
    1788        13846385 :     JSBool IsMarked() const
    1789        13846385 :                     {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          127133 :     XPCNativeInterface(nsIInterfaceInfo* aInfo, jsid aName)
    1805          127133 :         : mInfo(aInfo), mName(aName), mMemberCount(0)
    1806          127133 :                           {MOZ_COUNT_CTOR(XPCNativeInterface);}
    1807          127113 :     ~XPCNativeInterface() {MOZ_COUNT_DTOR(XPCNativeInterface);}
    1808                 : 
    1809          127133 :     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         1156561 :     XPCNativeSetKey(XPCNativeSet*       BaseSet  = nsnull,
    1828                 :                     XPCNativeInterface* Addition = nsnull,
    1829                 :                     PRUint16            Position = 0)
    1830                 :         : mIsAKey(IS_A_KEY), mPosition(Position), mBaseSet(BaseSet),
    1831         1156561 :           mAddition(Addition) {}
    1832         1156561 :     ~XPCNativeSetKey() {}
    1833                 : 
    1834         2296604 :     XPCNativeSet*           GetBaseSet()  const {return mBaseSet;}
    1835         2296604 :     XPCNativeInterface*     GetAddition() const {return mAddition;}
    1836         1447706 :     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         2296604 :     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           25589 :     PRUint16 GetMemberCount() const {return mMemberCount;}
    1908         2465851 :     PRUint16 GetInterfaceCount() const
    1909         2465851 :         {NS_ASSERTION(!IsMarked(), "bad"); return mInterfaceCount;}
    1910          695166 :     XPCNativeInterface** GetInterfaceArray() {return mInterfaces;}
    1911                 : 
    1912          848896 :     XPCNativeInterface* GetInterfaceAt(PRUint16 i)
    1913          848896 :         {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          221994 :     void MarkSelfOnly() {mInterfaceCount |= XPC_NATIVE_SET_MARK_FLAG;}
    1928                 : public:
    1929          221994 :     void Unmark()       {mInterfaceCount &= ~XPC_NATIVE_SET_MARK_FLAG;}
    1930        13460477 :     JSBool IsMarked() const
    1931        13460477 :                   {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          192195 :     XPCNativeSet()  {MOZ_COUNT_CTOR(XPCNativeSet);}
    1951          192183 :     ~XPCNativeSet() {MOZ_COUNT_DTOR(XPCNativeSet);}
    1952          192195 :     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         3170290 :     XPCNativeScriptableFlags(uint32_t flags = 0) : mFlags(flags) {}
    1977                 : 
    1978         1413327 :     uint32_t GetFlags() const {return mFlags & ~XPC_WN_SJSFLAGS_MARK_FLAG;}
    1979                 :     void     SetFlags(uint32_t flags) {mFlags = flags;}
    1980                 : 
    1981          974731 :     operator uint32_t() const {return GetFlags();}
    1982                 : 
    1983           30286 :     XPCNativeScriptableFlags(const XPCNativeScriptableFlags& r)
    1984           30286 :         {mFlags = r.GetFlags();}
    1985                 : 
    1986          408310 :     XPCNativeScriptableFlags& operator= (const XPCNativeScriptableFlags& r)
    1987          408310 :         {mFlags = r.GetFlags(); return *this;}
    1988                 : 
    1989         5546109 :     void Mark()       {mFlags |= XPC_WN_SJSFLAGS_MARK_FLAG;}
    1990          101003 :     void Unmark()     {mFlags &= ~XPC_WN_SJSFLAGS_MARK_FLAG;}
    1991          121879 :     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         1477223 :     JSBool WantPreCreate()                GET_IT(WANT_PRECREATE)
    1999          298008 :     JSBool WantCreate()                   GET_IT(WANT_CREATE)
    2000          298008 :     JSBool WantPostCreate()               GET_IT(WANT_POSTCREATE)
    2001           20993 :     JSBool WantAddProperty()              GET_IT(WANT_ADDPROPERTY)
    2002           20993 :     JSBool WantDelProperty()              GET_IT(WANT_DELPROPERTY)
    2003           20993 :     JSBool WantGetProperty()              GET_IT(WANT_GETPROPERTY)
    2004           20993 :     JSBool WantSetProperty()              GET_IT(WANT_SETPROPERTY)
    2005           16219 :     JSBool WantEnumerate()                GET_IT(WANT_ENUMERATE)
    2006           21310 :     JSBool WantNewEnumerate()             GET_IT(WANT_NEWENUMERATE)
    2007         1577265 :     JSBool WantNewResolve()               GET_IT(WANT_NEWRESOLVE)
    2008           20993 :     JSBool WantConvert()                  GET_IT(WANT_CONVERT)
    2009           20993 :     JSBool WantFinalize()                 GET_IT(WANT_FINALIZE)
    2010           20993 :     JSBool WantCheckAccess()              GET_IT(WANT_CHECKACCESS)
    2011           40761 :     JSBool WantCall()                     GET_IT(WANT_CALL)
    2012           22637 :     JSBool WantConstruct()                GET_IT(WANT_CONSTRUCT)
    2013           20993 :     JSBool WantHasInstance()              GET_IT(WANT_HASINSTANCE)
    2014            1439 :     JSBool WantEquality()                 GET_IT(WANT_EQUALITY)
    2015           20993 :     JSBool WantOuterObject()              GET_IT(WANT_OUTER_OBJECT)
    2016           19203 :     JSBool UseJSStubForAddProperty()      GET_IT(USE_JSSTUB_FOR_ADDPROPERTY)
    2017           20990 :     JSBool UseJSStubForDelProperty()      GET_IT(USE_JSSTUB_FOR_DELPROPERTY)
    2018           19126 :     JSBool UseJSStubForSetProperty()      GET_IT(USE_JSSTUB_FOR_SETPROPERTY)
    2019          520786 :     JSBool DontEnumStaticProps()          GET_IT(DONT_ENUM_STATIC_PROPS)
    2020          277891 :     JSBool DontEnumQueryInterface()       GET_IT(DONT_ENUM_QUERY_INTERFACE)
    2021          623075 :     JSBool DontAskInstanceForScriptable() GET_IT(DONT_ASK_INSTANCE_FOR_SCRIPTABLE)
    2022          608208 :     JSBool ClassInfoInterfacesOnly()      GET_IT(CLASSINFO_INTERFACES_ONLY)
    2023         1888415 :     JSBool AllowPropModsDuringResolve()   GET_IT(ALLOW_PROP_MODS_DURING_RESOLVE)
    2024          256329 :     JSBool AllowPropModsToPrototype()     GET_IT(ALLOW_PROP_MODS_TO_PROTOTYPE)
    2025          299764 :     JSBool IsGlobalObject()               GET_IT(IS_GLOBAL_OBJECT)
    2026           25392 :     JSBool DontReflectInterfaceNames()    GET_IT(DONT_REFLECT_INTERFACE_NAMES)
    2027           20993 :     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         5149411 :     const XPCNativeScriptableFlags& GetFlags() const {return mFlags;}
    2055          455876 :     PRUint32                        GetInterfacesBitmap() const
    2056          455876 :         {return mJSClass.interfacesBitmap;}
    2057         2957503 :     JSClass*                        GetJSClass()
    2058         2957503 :         {return Jsvalify(&mJSClass.base);}
    2059           15143 :     JSClass*                        GetSlimJSClass()
    2060           15143 :         {if (mCanBeSlim) return GetJSClass(); return nsnull;}
    2061                 : 
    2062          269924 :     XPCNativeScriptableShared(uint32_t aFlags, char* aName,
    2063                 :                               PRUint32 interfacesBitmap)
    2064                 :         : mFlags(aFlags),
    2065          269924 :           mCanBeSlim(false)
    2066          269924 :         {memset(&mJSClass, 0, sizeof(mJSClass));
    2067          269924 :          mJSClass.base.name = aName;  // take ownership
    2068          269924 :          mJSClass.interfacesBitmap = interfacesBitmap;
    2069          269924 :          MOZ_COUNT_CTOR(XPCNativeScriptableShared);}
    2070                 : 
    2071          269807 :     ~XPCNativeScriptableShared()
    2072          269807 :         {if (mJSClass.base.name)nsMemory::Free((void*)mJSClass.base.name);
    2073          269807 :          MOZ_COUNT_DTOR(XPCNativeScriptableShared);}
    2074                 : 
    2075           20993 :     char* TransferNameOwnership()
    2076           20993 :         {char* name=(char*)mJSClass.base.name; mJSClass.base.name = nsnull;
    2077           20993 :         return name;}
    2078                 : 
    2079                 :     void PopulateJSClass();
    2080                 : 
    2081         5546109 :     void Mark()       {mFlags.Mark();}
    2082          101003 :     void Unmark()     {mFlags.Unmark();}
    2083          121879 :     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         2102725 :     GetCallback() const {return mCallback;}
    2103                 : 
    2104                 :     const XPCNativeScriptableFlags&
    2105         4444604 :     GetFlags() const      {return mShared->GetFlags();}
    2106                 : 
    2107                 :     PRUint32
    2108               0 :     GetInterfacesBitmap() const {return mShared->GetInterfacesBitmap();}
    2109                 : 
    2110                 :     JSClass*
    2111         2237553 :     GetJSClass()          {return mShared->GetJSClass();}
    2112                 : 
    2113                 :     JSClass*
    2114           15143 :     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          248931 :     SetScriptableShared(XPCNativeScriptableShared* shared) {mShared = shared;}
    2126                 : 
    2127         5546109 :     void Mark() {if (mShared) mShared->Mark();}
    2128                 : 
    2129                 : protected:
    2130          248931 :     XPCNativeScriptableInfo(nsIXPCScriptable* scriptable = nsnull,
    2131                 :                             XPCNativeScriptableShared* shared = nsnull)
    2132          248931 :         : mCallback(scriptable), mShared(shared)
    2133          248931 :                                {MOZ_COUNT_CTOR(XPCNativeScriptableInfo);}
    2134                 : public:
    2135          248882 :     ~XPCNativeScriptableInfo() {MOZ_COUNT_DTOR(XPCNativeScriptableInfo);}
    2136                 : private:
    2137                 : 
    2138                 :     // disable copy ctor and assignment
    2139                 :     XPCNativeScriptableInfo(const XPCNativeScriptableInfo& r); // not implemented
    2140                 :     XPCNativeScriptableInfo& operator= (const XPCNativeScriptableInfo& r); // not implemented
    2141                 : 
    2142                 : private:
    2143                 :     nsCOMPtr<nsIXPCScriptable>  mCallback;
    2144                 :     XPCNativeScriptableShared*  mShared;
    2145                 : };
    2146                 : 
    2147                 : /***************************************************************************/
    2148                 : // XPCNativeScriptableCreateInfo is used in creating new wrapper and protos.
    2149                 : // it abstracts out the scriptable interface pointer and the flags. After
    2150                 : // creation these are factored differently using XPCNativeScriptableInfo.
    2151                 : 
    2152                 : class NS_STACK_CLASS XPCNativeScriptableCreateInfo
    2153         2487087 : {
    2154                 : public:
    2155                 : 
    2156               0 :     XPCNativeScriptableCreateInfo(const XPCNativeScriptableInfo& si)
    2157               0 :         : mCallback(si.GetCallback()), mFlags(si.GetFlags()),
    2158               0 :           mInterfacesBitmap(si.GetInterfacesBitmap()) {}
    2159                 : 
    2160           15143 :     XPCNativeScriptableCreateInfo(already_AddRefed<nsIXPCScriptable> callback,
    2161                 :                                   XPCNativeScriptableFlags flags,
    2162                 :                                   PRUint32 interfacesBitmap)
    2163                 :         : mCallback(callback), mFlags(flags),
    2164           15143 :           mInterfacesBitmap(interfacesBitmap) {}
    2165                 : 
    2166         2471944 :     XPCNativeScriptableCreateInfo()
    2167         2471944 :         : mFlags(0), mInterfacesBitmap(0) {}
    2168                 : 
    2169                 : 
    2170                 :     nsIXPCScriptable*
    2171         4065571 :     GetCallback() const {return mCallback;}
    2172                 : 
    2173                 :     const XPCNativeScriptableFlags&
    2174         3806814 :     GetFlags() const      {return mFlags;}
    2175                 : 
    2176                 :     PRUint32
    2177          248931 :     GetInterfacesBitmap() const     {return mInterfacesBitmap;}
    2178                 : 
    2179                 :     void
    2180          382918 :     SetCallback(already_AddRefed<nsIXPCScriptable> callback)
    2181          382918 :         {mCallback = callback;}
    2182                 : 
    2183                 :     void
    2184          382918 :     SetFlags(const XPCNativeScriptableFlags& flags)  {mFlags = flags;}
    2185                 : 
    2186                 :     void
    2187           12398 :     SetInterfacesBitmap(PRUint32 interfacesBitmap)
    2188           12398 :         {mInterfacesBitmap = interfacesBitmap;}
    2189                 : 
    2190                 : private:
    2191                 :     nsCOMPtr<nsIXPCScriptable>  mCallback;
    2192                 :     XPCNativeScriptableFlags    mFlags;
    2193                 :     PRUint32                    mInterfacesBitmap;
    2194                 : };
    2195                 : 
    2196                 : /***********************************************/
    2197                 : // XPCWrappedNativeProto hold the additional shared wrapper data
    2198                 : // for XPCWrappedNative whose native objects expose nsIClassInfo.
    2199                 : 
    2200                 : #define UNKNOWN_OFFSETS ((QITableEntry*)1)
    2201                 : 
    2202                 : class XPCWrappedNativeProto
    2203                 : {
    2204                 : public:
    2205                 :     static XPCWrappedNativeProto*
    2206                 :     GetNewOrUsed(XPCCallContext& ccx,
    2207                 :                  XPCWrappedNativeScope* scope,
    2208                 :                  nsIClassInfo* classInfo,
    2209                 :                  const XPCNativeScriptableCreateInfo* scriptableCreateInfo,
    2210                 :                  QITableEntry* offsets = UNKNOWN_OFFSETS,
    2211                 :                  bool callPostCreatePrototype = true);
    2212                 : 
    2213                 :     XPCWrappedNativeScope*
    2214         9295603 :     GetScope()   const {return mScope;}
    2215                 : 
    2216                 :     XPCJSRuntime*
    2217         6322849 :     GetRuntime() const {return mScope->GetRuntime();}
    2218                 : 
    2219                 :     JSObject*
    2220          396972 :     GetJSProtoObject() const {return mJSProtoObject;}
    2221                 : 
    2222                 :     nsIClassInfo*
    2223         4085857 :     GetClassInfo()     const {return mClassInfo;}
    2224                 : 
    2225                 :     XPCNativeSet*
    2226         3142708 :     GetSet()           const {return mSet;}
    2227                 : 
    2228                 :     XPCNativeScriptableInfo*
    2229         1726420 :     GetScriptableInfo()   {return mScriptableInfo;}
    2230                 : 
    2231                 :     void**
    2232         2236884 :     GetSecurityInfoAddr() {return &mSecurityInfo;}
    2233                 : 
    2234                 :     uint32_t
    2235                 :     GetClassInfoFlags() const {return mClassInfoFlags;}
    2236                 : 
    2237                 :     QITableEntry*
    2238           34995 :     GetOffsets()
    2239                 :     {
    2240           34995 :         return InitedOffsets() ? mOffsets : nsnull;
    2241                 :     }
    2242                 :     QITableEntry*
    2243               0 :     GetOffsetsMasked()
    2244                 :     {
    2245               0 :         return mOffsets;
    2246                 :     }
    2247                 :     void
    2248          383800 :     CacheOffsets(nsISupports* identity)
    2249                 :     {
    2250                 :         static NS_DEFINE_IID(kThisPtrOffsetsSID, NS_THISPTROFFSETS_SID);
    2251                 : 
    2252                 : #ifdef DEBUG
    2253          383800 :         if (InitedOffsets() && mOffsets) {
    2254                 :             QITableEntry* offsets;
    2255           13248 :             identity->QueryInterface(kThisPtrOffsetsSID, (void**)&offsets);
    2256           13248 :             NS_ASSERTION(offsets == mOffsets,
    2257                 :                          "We can't deal with objects that have the same "
    2258                 :                          "classinfo but different offset tables.");
    2259                 :         }
    2260                 : #endif
    2261                 : 
    2262          383800 :         if (!InitedOffsets()) {
    2263          186009 :             if (mClassInfoFlags & nsIClassInfo::CONTENT_NODE) {
    2264             897 :                 identity->QueryInterface(kThisPtrOffsetsSID, (void**)&mOffsets);
    2265                 :             } else {
    2266          185112 :                 mOffsets = nsnull;
    2267                 :             }
    2268                 :         }
    2269          383800 :     }
    2270                 : 
    2271                 : #ifdef GET_IT
    2272                 : #undef GET_IT
    2273                 : #endif
    2274                 : #define GET_IT(f_) const {return !!(mClassInfoFlags & nsIClassInfo:: f_ );}
    2275                 : 
    2276                 :     JSBool ClassIsSingleton()           GET_IT(SINGLETON)
    2277        11469290 :     JSBool ClassIsThreadSafe()          GET_IT(THREADSAFE)
    2278         1179421 :     JSBool ClassIsMainThreadOnly()      GET_IT(MAIN_THREAD_ONLY)
    2279           32115 :     JSBool ClassIsDOMObject()           GET_IT(DOM_OBJECT)
    2280                 :     JSBool ClassIsPluginObject()        GET_IT(PLUGIN_OBJECT)
    2281                 : 
    2282                 : #undef GET_IT
    2283                 : 
    2284         7149327 :     XPCLock* GetLock() const
    2285         7149327 :         {return ClassIsThreadSafe() ? GetRuntime()->GetMapLock() : nsnull;}
    2286                 : 
    2287                 :     void SetScriptableInfo(XPCNativeScriptableInfo* si)
    2288                 :         {NS_ASSERTION(!mScriptableInfo, "leak here!"); mScriptableInfo = si;}
    2289                 : 
    2290                 :     bool CallPostCreatePrototype(XPCCallContext& ccx);
    2291                 :     void JSProtoObjectFinalized(JSContext *cx, JSObject *obj);
    2292                 : 
    2293                 :     void SystemIsBeingShutDown();
    2294                 : 
    2295                 :     void DebugDump(PRInt16 depth);
    2296                 : 
    2297         1902633 :     void TraceJS(JSTracer* trc)
    2298                 :     {
    2299         1902633 :         if (mJSProtoObject) {
    2300         1902633 :             JS_CALL_OBJECT_TRACER(trc, mJSProtoObject,
    2301                 :                                   "XPCWrappedNativeProto::mJSProtoObject");
    2302                 :         }
    2303         1902633 :         if (mScriptableInfo && JS_IsGCMarkingTracer(trc))
    2304          821588 :             mScriptableInfo->Mark();
    2305         1902633 :     }
    2306                 : 
    2307               0 :     void WriteBarrierPre(JSRuntime* rt)
    2308                 :     {
    2309               0 :         if (js::IsIncrementalBarrierNeeded(rt) && mJSProtoObject)
    2310               0 :             mJSProtoObject.writeBarrierPre(rt);
    2311               0 :     }
    2312                 : 
    2313                 :     // NOP. This is just here to make the AutoMarkingPtr code compile.
    2314               0 :     inline void AutoTrace(JSTracer* trc) {}
    2315                 : 
    2316                 :     // Yes, we *do* need to mark the mScriptableInfo in both cases.
    2317         2735029 :     void Mark() const
    2318         2735029 :         {mSet->Mark();
    2319         2735029 :          if (mScriptableInfo) mScriptableInfo->Mark();}
    2320                 : 
    2321                 : #ifdef DEBUG
    2322         2735029 :     void ASSERT_SetNotMarked() const {mSet->ASSERT_NotMarked();}
    2323                 : #endif
    2324                 : 
    2325                 :     ~XPCWrappedNativeProto();
    2326                 : 
    2327                 : protected:
    2328                 :     // disable copy ctor and assignment
    2329                 :     XPCWrappedNativeProto(const XPCWrappedNativeProto& r); // not implemented
    2330                 :     XPCWrappedNativeProto& operator= (const XPCWrappedNativeProto& r); // not implemented
    2331                 : 
    2332                 :     // hide ctor
    2333                 :     XPCWrappedNativeProto(XPCWrappedNativeScope* Scope,
    2334                 :                           nsIClassInfo* ClassInfo,
    2335                 :                           PRUint32 ClassInfoFlags,
    2336                 :                           XPCNativeSet* Set,
    2337                 :                           QITableEntry* offsets);
    2338                 : 
    2339                 :     JSBool Init(XPCCallContext& ccx,
    2340                 :                 const XPCNativeScriptableCreateInfo* scriptableCreateInfo,
    2341                 :                 bool callPostCreatePrototype);
    2342                 : 
    2343                 : private:
    2344                 : #if defined(DEBUG_xpc_hacker) || defined(DEBUG)
    2345                 :     static PRInt32 gDEBUG_LiveProtoCount;
    2346                 : #endif
    2347                 : 
    2348                 : private:
    2349                 :     bool
    2350          802595 :     InitedOffsets()
    2351                 :     {
    2352          802595 :         return mOffsets != UNKNOWN_OFFSETS;
    2353                 :     }
    2354                 : 
    2355                 :     XPCWrappedNativeScope*   mScope;
    2356                 :     js::ObjectPtr            mJSProtoObject;
    2357                 :     nsCOMPtr<nsIClassInfo>   mClassInfo;
    2358                 :     PRUint32                 mClassInfoFlags;
    2359                 :     XPCNativeSet*            mSet;
    2360                 :     void*                    mSecurityInfo;
    2361                 :     XPCNativeScriptableInfo* mScriptableInfo;
    2362                 :     QITableEntry*            mOffsets;
    2363                 : };
    2364                 : 
    2365                 : class xpcObjectHelper;
    2366                 : extern JSBool ConstructSlimWrapper(XPCCallContext &ccx,
    2367                 :                                    xpcObjectHelper &aHelper,
    2368                 :                                    XPCWrappedNativeScope* xpcScope,
    2369                 :                                    jsval *rval);
    2370                 : extern JSBool MorphSlimWrapper(JSContext *cx, JSObject *obj);
    2371                 : 
    2372                 : static inline XPCWrappedNativeProto*
    2373           35406 : GetSlimWrapperProto(JSObject *obj)
    2374                 : {
    2375           35406 :   const js::Value &v = js::GetReservedSlot(obj, 0);
    2376           35406 :   return static_cast<XPCWrappedNativeProto*>(v.toPrivate());
    2377                 : }
    2378                 : 
    2379                 : 
    2380                 : /***********************************************/
    2381                 : // XPCWrappedNativeTearOff represents the info needed to make calls to one
    2382                 : // interface on the underlying native object of a XPCWrappedNative.
    2383                 : 
    2384                 : class XPCWrappedNativeTearOff
    2385                 : {
    2386                 : public:
    2387         2212418 :     JSBool IsAvailable() const {return mInterface == nsnull;}
    2388                 :     JSBool IsReserved()  const {return mInterface == (XPCNativeInterface*)1;}
    2389                 :     JSBool IsValid()     const {return !IsAvailable() && !IsReserved();}
    2390         1504858 :     void   SetReserved()       {mInterface = (XPCNativeInterface*)1;}
    2391                 : 
    2392        19021631 :     XPCNativeInterface* GetInterface() const {return mInterface;}
    2393        12776268 :     nsISupports*        GetNative()    const {return mNative;}
    2394                 :     JSObject*           GetJSObject();
    2395                 :     JSObject*           GetJSObjectPreserveColor() const;
    2396         5486559 :     void SetInterface(XPCNativeInterface*  Interface) {mInterface = Interface;}
    2397         3008342 :     void SetNative(nsISupports*  Native)              {mNative = Native;}
    2398                 :     void SetJSObject(JSObject*  JSObj);
    2399                 : 
    2400              60 :     void JSObjectFinalized() {SetJSObject(nsnull);}
    2401                 : 
    2402         1424036 :     XPCWrappedNativeTearOff()
    2403         1424036 :         : mInterface(nsnull), mNative(nsnull), mJSObject(nsnull) {}
    2404                 :     ~XPCWrappedNativeTearOff();
    2405                 : 
    2406                 :     // NOP. This is just here to make the AutoMarkingPtr code compile.
    2407               0 :     inline void TraceJS(JSTracer* trc) {}
    2408               0 :     inline void AutoTrace(JSTracer* trc) {}
    2409                 : 
    2410            3898 :     void Mark()       {mJSObject = (JSObject*)(intptr_t(mJSObject) | 1);}
    2411         4071535 :     void Unmark()     {mJSObject = (JSObject*)(intptr_t(mJSObject) & ~1);}
    2412         2561657 :     bool IsMarked() const {return !!(intptr_t(mJSObject) & 1);}
    2413                 : 
    2414                 : private:
    2415                 :     XPCWrappedNativeTearOff(const XPCWrappedNativeTearOff& r) MOZ_DELETE;
    2416                 :     XPCWrappedNativeTearOff& operator= (const XPCWrappedNativeTearOff& r) MOZ_DELETE;
    2417                 : 
    2418                 : private:
    2419                 :     XPCNativeInterface* mInterface;
    2420                 :     nsISupports*        mNative;
    2421                 :     JSObject*           mJSObject;
    2422                 : };
    2423                 : 
    2424                 : /***********************************************/
    2425                 : // XPCWrappedNativeTearOffChunk is a collections of XPCWrappedNativeTearOff
    2426                 : // objects. It lets us allocate a set of XPCWrappedNativeTearOff objects and
    2427                 : // link the sets - rather than only having the option of linking single
    2428                 : // XPCWrappedNativeTearOff objects.
    2429                 : //
    2430                 : // The value of XPC_WRAPPED_NATIVE_TEAROFFS_PER_CHUNK can be tuned at buildtime
    2431                 : // to balance between the code of allocations of additional chunks and the waste
    2432                 : // of space for ununsed XPCWrappedNativeTearOff objects.
    2433                 : 
    2434                 : #define XPC_WRAPPED_NATIVE_TEAROFFS_PER_CHUNK 1
    2435                 : 
    2436                 : class XPCWrappedNativeTearOffChunk
    2437                 : {
    2438                 : friend class XPCWrappedNative;
    2439                 : private:
    2440         1424036 :     XPCWrappedNativeTearOffChunk() : mNextChunk(nsnull) {}
    2441         2846444 :     ~XPCWrappedNativeTearOffChunk() {delete mNextChunk;}
    2442                 : 
    2443                 : private:
    2444                 :     XPCWrappedNativeTearOff mTearOffs[XPC_WRAPPED_NATIVE_TEAROFFS_PER_CHUNK];
    2445                 :     XPCWrappedNativeTearOffChunk* mNextChunk;
    2446                 : };
    2447                 : 
    2448                 : void *xpc_GetJSPrivate(JSObject *obj);
    2449                 : 
    2450                 : /***************************************************************************/
    2451                 : // XPCWrappedNative the wrapper around one instance of a native xpcom object
    2452                 : // to be used from JavaScript.
    2453                 : 
    2454                 : class XPCWrappedNative : public nsIXPConnectWrappedNative
    2455                 : {
    2456                 : public:
    2457                 :     NS_DECL_ISUPPORTS
    2458                 :     NS_DECL_NSIXPCONNECTJSOBJECTHOLDER
    2459                 :     NS_DECL_NSIXPCONNECTWRAPPEDNATIVE
    2460                 :     // No need to unlink the JS objects, if the XPCWrappedNative will be cycle
    2461                 :     // collected then its mFlatJSObject will be cycle collected too and
    2462                 :     // finalization of the mFlatJSObject will unlink the js objects (see
    2463                 :     // XPC_WN_NoHelper_Finalize and FlatJSObjectFinalized).
    2464                 :     // We also give XPCWrappedNative empty Root/Unroot methods, to avoid
    2465                 :     // root/unrooting the JS objects from addrefing/releasing the
    2466                 :     // XPCWrappedNative during unlinking, which would make the JS objects
    2467                 :     // uncollectable to the JS GC.
    2468                 :     class NS_CYCLE_COLLECTION_INNERCLASS
    2469                 :      : public nsXPCOMCycleCollectionParticipant
    2470            1396 :     {
    2471             365 :       NS_DECL_CYCLE_COLLECTION_CLASS_BODY_NO_UNLINK(XPCWrappedNative,
    2472                 :                                                     XPCWrappedNative)
    2473             322 :       NS_IMETHOD Root(void *p) { return NS_OK; }
    2474                 :       NS_IMETHOD Unlink(void *p);
    2475             322 :       NS_IMETHOD Unroot(void *p) { return NS_OK; }
    2476                 :     };
    2477                 :     NS_CYCLE_COLLECTION_PARTICIPANT_INSTANCE
    2478               0 :     NS_DECL_CYCLE_COLLECTION_UNMARK_PURPLE_STUB(XPCWrappedNative)
    2479                 : 
    2480                 :     nsIPrincipal* GetObjectPrincipal() const;
    2481                 : 
    2482                 :     JSBool
    2483        49586206 :     IsValid() const {return nsnull != mFlatJSObject;}
    2484                 : 
    2485                 : #define XPC_SCOPE_WORD(s)   (intptr_t(s))
    2486                 : #define XPC_SCOPE_MASK      (intptr_t(0x3))
    2487                 : #define XPC_SCOPE_TAG       (intptr_t(0x1))
    2488                 : #define XPC_WRAPPER_EXPIRED (intptr_t(0x2))
    2489                 : 
    2490                 :     static inline JSBool
    2491       113479713 :     IsTaggedScope(XPCWrappedNativeScope* s)
    2492       113479713 :         {return XPC_SCOPE_WORD(s) & XPC_SCOPE_TAG;}
    2493                 : 
    2494                 :     static inline XPCWrappedNativeScope*
    2495          867315 :     TagScope(XPCWrappedNativeScope* s)
    2496          867315 :         {NS_ASSERTION(!IsTaggedScope(s), "bad pointer!");
    2497          867315 :          return (XPCWrappedNativeScope*)(XPC_SCOPE_WORD(s) | XPC_SCOPE_TAG);}
    2498                 : 
    2499                 :     static inline XPCWrappedNativeScope*
    2500                 :     UnTagScope(XPCWrappedNativeScope* s)
    2501                 :         {return (XPCWrappedNativeScope*)(XPC_SCOPE_WORD(s) & ~XPC_SCOPE_TAG);}
    2502                 : 
    2503                 :     inline JSBool
    2504         1256286 :     IsWrapperExpired() const
    2505         1256286 :         {return XPC_SCOPE_WORD(mMaybeScope) & XPC_WRAPPER_EXPIRED;}
    2506                 : 
    2507                 :     JSBool
    2508       112612398 :     HasProto() const {return !IsTaggedScope(mMaybeScope);}
    2509                 : 
    2510                 :     XPCWrappedNativeProto*
    2511        58164994 :     GetProto() const
    2512        58164994 :         {return HasProto() ?
    2513                 :          (XPCWrappedNativeProto*)
    2514        58164994 :          (XPC_SCOPE_WORD(mMaybeProto) & ~XPC_SCOPE_MASK) : nsnull;}
    2515                 : 
    2516                 :     void SetProto(XPCWrappedNativeProto* p);
    2517                 : 
    2518                 :     XPCWrappedNativeScope*
    2519        14787718 :     GetScope() const
    2520        21833501 :         {return GetProto() ? GetProto()->GetScope() :
    2521                 :          (XPCWrappedNativeScope*)
    2522        21833501 :          (XPC_SCOPE_WORD(mMaybeScope) & ~XPC_SCOPE_MASK);}
    2523                 : 
    2524                 :     nsISupports*
    2525        13942223 :     GetIdentityObject() const {return mIdentity;}
    2526                 : 
    2527                 :     /**
    2528                 :      * This getter clears the gray bit before handing out the JSObject which
    2529                 :      * means that the object is guaranteed to be kept alive past the next CC.
    2530                 :      */
    2531                 :     JSObject*
    2532        16722835 :     GetFlatJSObject() const
    2533        16722835 :         {if (mFlatJSObject != INVALID_OBJECT)
    2534        16722835 :              xpc_UnmarkGrayObject(mFlatJSObject);
    2535        16722835 :          return mFlatJSObject;}
    2536                 : 
    2537                 :     /**
    2538                 :      * This getter does not change the color of the JSObject meaning that the
    2539                 :      * object returned is not guaranteed to be kept alive past the next CC.
    2540                 :      *
    2541                 :      * This should only be called if you are certain that the return value won't
    2542                 :      * be passed into a JS API function and that it won't be stored without
    2543                 :      * being rooted (or otherwise signaling the stored value to the CC).
    2544                 :      */
    2545                 :     JSObject*
    2546           15060 :     GetFlatJSObjectPreserveColor() const {return mFlatJSObject;}
    2547                 : 
    2548                 :     XPCLock*
    2549        46710080 :     GetLock() const {return IsValid() && HasProto() ?
    2550        46710080 :                                 GetProto()->GetLock() : nsnull;}
    2551                 : 
    2552                 :     XPCNativeSet*
    2553        12350517 :     GetSet() const {XPCAutoLock al(GetLock()); return mSet;}
    2554                 : 
    2555                 :     void
    2556             158 :     SetSet(XPCNativeSet* set) {XPCAutoLock al(GetLock()); mSet = set;}
    2557                 : 
    2558                 : private:
    2559                 :     inline void
    2560             322 :     ExpireWrapper()
    2561                 :         {mMaybeScope = (XPCWrappedNativeScope*)
    2562             322 :                        (XPC_SCOPE_WORD(mMaybeScope) | XPC_WRAPPER_EXPIRED);}
    2563                 : 
    2564                 : public:
    2565                 : 
    2566                 :     XPCNativeScriptableInfo*
    2567        15275550 :     GetScriptableInfo() const {return mScriptableInfo;}
    2568                 : 
    2569                 :     nsIXPCScriptable*      // call this wrong and you deserve to crash
    2570          506347 :     GetScriptableCallback() const  {return mScriptableInfo->GetCallback();}
    2571                 : 
    2572                 :     void**
    2573         8323300 :     GetSecurityInfoAddr() {return HasProto() ?
    2574         8323300 :                                    GetProto()->GetSecurityInfoAddr() : nsnull;}
    2575                 : 
    2576                 :     nsIClassInfo*
    2577        16648720 :     GetClassInfo() const {return IsValid() && HasProto() ?
    2578        16648720 :                             GetProto()->GetClassInfo() : nsnull;}
    2579                 : 
    2580                 :     JSBool
    2581         1348573 :     HasMutatedSet() const {return IsValid() &&
    2582         1348573 :                                   (!HasProto() ||
    2583         2697146 :                                    GetSet() != GetProto()->GetSet());}
    2584                 : 
    2585                 :     XPCJSRuntime*
    2586         4983576 :     GetRuntime() const {XPCWrappedNativeScope* scope = GetScope();
    2587         4983576 :                         return scope ? scope->GetRuntime() : nsnull;}
    2588                 : 
    2589                 :     static nsresult
    2590                 :     WrapNewGlobal(XPCCallContext &ccx, xpcObjectHelper &nativeHelper,
    2591                 :                   nsIPrincipal *principal, bool initStandardClasses,
    2592                 :                   XPCWrappedNative **wrappedGlobal);
    2593                 : 
    2594                 :     static nsresult
    2595                 :     GetNewOrUsed(XPCCallContext& ccx,
    2596                 :                  xpcObjectHelper& helper,
    2597                 :                  XPCWrappedNativeScope* Scope,
    2598                 :                  XPCNativeInterface* Interface,
    2599                 :                  XPCWrappedNative** wrapper);
    2600                 : 
    2601                 :     static nsresult
    2602                 :     Morph(XPCCallContext& ccx,
    2603                 :           JSObject* existingJSObject,
    2604                 :           XPCNativeInterface* Interface,
    2605                 :           nsWrapperCache *cache,
    2606                 :           XPCWrappedNative** resultWrapper);
    2607                 : 
    2608                 : public:
    2609                 :     static nsresult
    2610                 :     GetUsedOnly(XPCCallContext& ccx,
    2611                 :                 nsISupports* Object,
    2612                 :                 XPCWrappedNativeScope* Scope,
    2613                 :                 XPCNativeInterface* Interface,
    2614                 :                 XPCWrappedNative** wrapper);
    2615                 : 
    2616                 :     // If pobj2 is not null and *pobj2 is not null after the call then *pobj2
    2617                 :     // points to an object for which IS_SLIM_WRAPPER_OBJECT is true.
    2618                 :     // cx is null when invoked from the marking phase of the GC. In this case
    2619                 :     // fubobj must be null as well.
    2620                 :     static XPCWrappedNative*
    2621                 :     GetWrappedNativeOfJSObject(JSContext* cx, JSObject* obj,
    2622                 :                                JSObject* funobj = nsnull,
    2623                 :                                JSObject** pobj2 = nsnull,
    2624                 :                                XPCWrappedNativeTearOff** pTearOff = nsnull);
    2625                 :     static XPCWrappedNative*
    2626          237391 :     GetAndMorphWrappedNativeOfJSObject(JSContext* cx, JSObject* obj)
    2627                 :     {
    2628          237391 :         JSObject *obj2 = nsnull;
    2629                 :         XPCWrappedNative* wrapper =
    2630          237391 :             GetWrappedNativeOfJSObject(cx, obj, nsnull, &obj2);
    2631          237391 :         if (wrapper || !obj2)
    2632          237391 :             return wrapper;
    2633                 : 
    2634               0 :         NS_ASSERTION(IS_SLIM_WRAPPER(obj2),
    2635                 :                      "Hmm, someone changed GetWrappedNativeOfJSObject?");
    2636                 :         SLIM_LOG_WILL_MORPH(cx, obj2);
    2637               0 :         return MorphSlimWrapper(cx, obj2) ?
    2638               0 :                (XPCWrappedNative*)xpc_GetJSPrivate(obj2) :
    2639               0 :                nsnull;
    2640                 :     }
    2641                 : 
    2642                 :     static nsresult
    2643                 :     ReparentWrapperIfFound(XPCCallContext& ccx,
    2644                 :                            XPCWrappedNativeScope* aOldScope,
    2645                 :                            XPCWrappedNativeScope* aNewScope,
    2646                 :                            JSObject* aNewParent,
    2647                 :                            nsISupports* aCOMObj,
    2648                 :                            XPCWrappedNative** aWrapper);
    2649                 : 
    2650                 :     void FlatJSObjectFinalized();
    2651                 : 
    2652                 :     void SystemIsBeingShutDown();
    2653                 : 
    2654                 :     enum CallMode {CALL_METHOD, CALL_GETTER, CALL_SETTER};
    2655                 : 
    2656                 :     static JSBool CallMethod(XPCCallContext& ccx,
    2657                 :                              CallMode mode = CALL_METHOD);
    2658                 : 
    2659         2331607 :     static JSBool GetAttribute(XPCCallContext& ccx)
    2660         2331607 :         {return CallMethod(ccx, CALL_GETTER);}
    2661                 : 
    2662           95872 :     static JSBool SetAttribute(XPCCallContext& ccx)
    2663           95872 :         {return CallMethod(ccx, CALL_SETTER);}
    2664                 : 
    2665                 :     inline JSBool HasInterfaceNoQI(const nsIID& iid);
    2666                 : 
    2667                 :     XPCWrappedNativeTearOff* LocateTearOff(XPCCallContext& ccx,
    2668                 :                                            XPCNativeInterface* aInterface);
    2669                 :     XPCWrappedNativeTearOff* FindTearOff(XPCCallContext& ccx,
    2670                 :                                          XPCNativeInterface* aInterface,
    2671                 :                                          JSBool needJSObject = false,
    2672                 :                                          nsresult* pError = nsnull);
    2673         2232933 :     void Mark() const
    2674                 :     {
    2675         2232933 :         mSet->Mark();
    2676         2232933 :         if (mScriptableInfo) mScriptableInfo->Mark();
    2677         2232933 :         if (HasProto()) GetProto()->Mark();
    2678         2232933 :     }
    2679                 : 
    2680                 :     // Yes, we *do* need to mark the mScriptableInfo in both cases.
    2681         2287106 :     inline void TraceJS(JSTracer* trc)
    2682                 :     {
    2683         2287106 :         if (mScriptableInfo && JS_IsGCMarkingTracer(trc))
    2684         1898151 :             mScriptableInfo->Mark();
    2685         2287106 :         if (HasProto()) GetProto()->TraceJS(trc);
    2686         2287106 :         JSObject* wrapper = GetWrapperPreserveColor();
    2687         2287106 :         if (wrapper)
    2688               0 :             JS_CALL_OBJECT_TRACER(trc, wrapper, "XPCWrappedNative::mWrapper");
    2689         4232415 :         if (mScriptableInfo &&
    2690         1945309 :             (mScriptableInfo->GetJSClass()->flags & JSCLASS_XPCONNECT_GLOBAL))
    2691          134677 :             TraceXPCGlobal(trc, mFlatJSObject);
    2692                 : 
    2693         2287106 :     }
    2694                 : 
    2695               0 :     inline void AutoTrace(JSTracer* trc)
    2696                 :     {
    2697                 :         // If this got called, we're being kept alive by someone who really
    2698                 :         // needs us alive and whole.  Do not let our mFlatJSObject go away.
    2699                 :         // This is the only time we should be tracing our mFlatJSObject,
    2700                 :         // normally somebody else is doing that. Be careful not to trace the
    2701                 :         // bogus INVALID_OBJECT value we can have during init, though.
    2702               0 :         if (mFlatJSObject && mFlatJSObject != INVALID_OBJECT) {
    2703               0 :             JS_CALL_OBJECT_TRACER(trc, mFlatJSObject,
    2704                 :                                   "XPCWrappedNative::mFlatJSObject");
    2705                 :         }
    2706               0 :     }
    2707                 : 
    2708                 : #ifdef DEBUG
    2709         2232933 :     void ASSERT_SetsNotMarked() const
    2710         2232933 :         {mSet->ASSERT_NotMarked();
    2711         2232933 :          if (HasProto()){GetProto()->ASSERT_SetNotMarked();}}
    2712                 : 
    2713                 :     int DEBUG_CountOfTearoffChunks() const
    2714                 :         {int i = 0; const XPCWrappedNativeTearOffChunk* to;
    2715                 :          for (to = &mFirstChunk; to; to = to->mNextChunk) {i++;} return i;}
    2716                 : #endif
    2717                 : 
    2718                 :     inline void SweepTearOffs();
    2719                 : 
    2720                 :     // Returns a string that shuld be free'd using JS_smprintf_free (or null).
    2721                 :     char* ToString(XPCCallContext& ccx,
    2722                 :                    XPCWrappedNativeTearOff* to = nsnull) const;
    2723                 : 
    2724                 :     static void GatherProtoScriptableCreateInfo(nsIClassInfo* classInfo,
    2725                 :                                                 XPCNativeScriptableCreateInfo& sciProto);
    2726                 : 
    2727         3876890 :     JSBool HasExternalReference() const {return mRefCnt > 1;}
    2728                 : 
    2729         1554521 :     JSBool NeedsSOW() { return !!(mWrapperWord & NEEDS_SOW); }
    2730               0 :     void SetNeedsSOW() { mWrapperWord |= NEEDS_SOW; }
    2731                 :     JSBool NeedsCOW() { return !!(mWrapperWord & NEEDS_COW); }
    2732               0 :     void SetNeedsCOW() { mWrapperWord |= NEEDS_COW; }
    2733             365 :     JSBool MightHaveExpandoObject() { return !!(mWrapperWord & MIGHT_HAVE_EXPANDO); }
    2734               0 :     void SetHasExpandoObject() { mWrapperWord |= MIGHT_HAVE_EXPANDO; }
    2735                 : 
    2736         2287106 :     JSObject* GetWrapperPreserveColor() const
    2737         2287106 :         {return (JSObject*)(mWrapperWord & (size_t)~(size_t)FLAG_MASK);}
    2738                 : 
    2739               0 :     JSObject* GetWrapper()
    2740                 :     {
    2741               0 :         JSObject* wrapper = GetWrapperPreserveColor();
    2742               0 :         if (wrapper) {
    2743               0 :             xpc_UnmarkGrayObject(wrapper);
    2744                 :             // Call this to unmark mFlatJSObject.
    2745               0 :             GetFlatJSObject();
    2746                 :         }
    2747               0 :         return wrapper;
    2748                 :     }
    2749               0 :     void SetWrapper(JSObject *obj)
    2750                 :     {
    2751               0 :         js::IncrementalReferenceBarrier(GetWrapperPreserveColor());
    2752               0 :         PRWord newval = PRWord(obj) | (mWrapperWord & FLAG_MASK);
    2753               0 :         mWrapperWord = newval;
    2754               0 :     }
    2755                 : 
    2756                 :     void NoteTearoffs(nsCycleCollectionTraversalCallback& cb);
    2757                 : 
    2758           32115 :     QITableEntry* GetOffsets()
    2759                 :     {
    2760           32115 :         if (!HasProto() || !GetProto()->ClassIsDOMObject())
    2761               0 :             return nsnull;
    2762                 : 
    2763           32115 :         XPCWrappedNativeProto* proto = GetProto();
    2764           32115 :         QITableEntry* offsets = proto->GetOffsets();
    2765           32115 :         if (!offsets) {
    2766                 :             static NS_DEFINE_IID(kThisPtrOffsetsSID, NS_THISPTROFFSETS_SID);
    2767           30192 :             mIdentity->QueryInterface(kThisPtrOffsetsSID, (void**)&offsets);
    2768                 :         }
    2769           32115 :         return offsets;
    2770                 :     }
    2771                 : 
    2772                 :     // Make ctor and dtor protected (rather than private) to placate nsCOMPtr.
    2773                 : protected:
    2774                 :     XPCWrappedNative(); // not implemented
    2775                 : 
    2776                 :     // This ctor is used if this object will have a proto.
    2777                 :     XPCWrappedNative(already_AddRefed<nsISupports> aIdentity,
    2778                 :                      XPCWrappedNativeProto* aProto);
    2779                 : 
    2780                 :     // This ctor is used if this object will NOT have a proto.
    2781                 :     XPCWrappedNative(already_AddRefed<nsISupports> aIdentity,
    2782                 :                      XPCWrappedNativeScope* aScope,
    2783                 :                      XPCNativeSet* aSet);
    2784                 : 
    2785                 :     virtual ~XPCWrappedNative();
    2786                 :     void Destroy();
    2787                 : 
    2788                 :     void UpdateScriptableInfo(XPCNativeScriptableInfo *si);
    2789                 : 
    2790                 : private:
    2791                 :     enum {
    2792                 :         NEEDS_SOW = JS_BIT(0),
    2793                 :         NEEDS_COW = JS_BIT(1),
    2794                 :         MIGHT_HAVE_EXPANDO = JS_BIT(2),
    2795                 :         FLAG_MASK = JS_BITMASK(3)
    2796                 :     };
    2797                 : 
    2798                 : private:
    2799                 : 
    2800                 :     JSBool Init(XPCCallContext& ccx, JSObject* parent, const XPCNativeScriptableCreateInfo* sci);
    2801                 :     JSBool Init(XPCCallContext &ccx, JSObject *existingJSObject);
    2802                 :     JSBool FinishInit(XPCCallContext &ccx);
    2803                 : 
    2804                 :     JSBool ExtendSet(XPCCallContext& ccx, XPCNativeInterface* aInterface);
    2805                 : 
    2806                 :     nsresult InitTearOff(XPCCallContext& ccx,
    2807                 :                          XPCWrappedNativeTearOff* aTearOff,
    2808                 :                          XPCNativeInterface* aInterface,
    2809                 :                          JSBool needJSObject);
    2810                 : 
    2811                 :     JSBool InitTearOffJSObject(XPCCallContext& ccx,
    2812                 :                                XPCWrappedNativeTearOff* to);
    2813                 : 
    2814                 : public:
    2815                 :     static const XPCNativeScriptableCreateInfo& GatherScriptableCreateInfo(nsISupports* obj,
    2816                 :                                                                            nsIClassInfo* classInfo,
    2817                 :                                                                            XPCNativeScriptableCreateInfo& sciProto,
    2818                 :                                                                            XPCNativeScriptableCreateInfo& sciWrapper);
    2819                 : 
    2820                 : private:
    2821                 :     union
    2822                 :     {
    2823                 :         XPCWrappedNativeScope*   mMaybeScope;
    2824                 :         XPCWrappedNativeProto*   mMaybeProto;
    2825                 :     };
    2826                 :     XPCNativeSet*                mSet;
    2827                 :     JSObject*                    mFlatJSObject;
    2828                 :     XPCNativeScriptableInfo*     mScriptableInfo;
    2829                 :     XPCWrappedNativeTearOffChunk mFirstChunk;
    2830                 :     PRWord                       mWrapperWord;
    2831                 : 
    2832                 : #ifdef XPC_CHECK_WRAPPER_THREADSAFETY
    2833                 : public:
    2834                 :     // Don't want to overload _mOwningThread
    2835                 :     PRThread*                    mThread;
    2836                 : #endif
    2837                 : };
    2838                 : 
    2839                 : /***************************************************************************
    2840                 : ****************************************************************************
    2841                 : *
    2842                 : * Core classes for wrapped JSObject for use from native code...
    2843                 : *
    2844                 : ****************************************************************************
    2845                 : ***************************************************************************/
    2846                 : 
    2847                 : // this interfaces exists so we can refcount nsXPCWrappedJSClass
    2848                 : // {2453EBA0-A9B8-11d2-BA64-00805F8A5DD7}
    2849                 : #define NS_IXPCONNECT_WRAPPED_JS_CLASS_IID                                    \
    2850                 : { 0x2453eba0, 0xa9b8, 0x11d2,                                                 \
    2851                 :   { 0xba, 0x64, 0x0, 0x80, 0x5f, 0x8a, 0x5d, 0xd7 } }
    2852                 : 
    2853                 : class nsIXPCWrappedJSClass : public nsISupports
    2854           32582 : {
    2855                 : public:
    2856                 :     NS_DECLARE_STATIC_IID_ACCESSOR(NS_IXPCONNECT_WRAPPED_JS_CLASS_IID)
    2857                 :     NS_IMETHOD DebugDump(PRInt16 depth) = 0;
    2858                 : };
    2859                 : 
    2860                 : NS_DEFINE_STATIC_IID_ACCESSOR(nsIXPCWrappedJSClass,
    2861                 :                               NS_IXPCONNECT_WRAPPED_JS_CLASS_IID)
    2862                 : 
    2863                 : /*************************/
    2864                 : // nsXPCWrappedJSClass represents the sharable factored out common code and
    2865                 : // data for nsXPCWrappedJS instances for the same interface type.
    2866                 : 
    2867                 : class nsXPCWrappedJSClass : public nsIXPCWrappedJSClass
    2868                 : {
    2869                 :     // all the interface method declarations...
    2870                 :     NS_DECL_ISUPPORTS
    2871                 :     NS_IMETHOD DebugDump(PRInt16 depth);
    2872                 : public:
    2873                 : 
    2874                 :     static nsresult
    2875                 :     GetNewOrUsed(XPCCallContext& ccx,
    2876                 :                  REFNSIID aIID,
    2877                 :                  nsXPCWrappedJSClass** clazz);
    2878                 : 
    2879          691234 :     REFNSIID GetIID() const {return mIID;}
    2880          131266 :     XPCJSRuntime* GetRuntime() const {return mRuntime;}
    2881          555585 :     nsIInterfaceInfo* GetInterfaceInfo() const {return mInfo;}
    2882                 :     const char* GetInterfaceName();
    2883                 : 
    2884                 :     static JSBool IsWrappedJS(nsISupports* aPtr);
    2885                 : 
    2886                 :     NS_IMETHOD DelegatedQueryInterface(nsXPCWrappedJS* self, REFNSIID aIID,
    2887                 :                                        void** aInstancePtr);
    2888                 : 
    2889                 :     JSObject* GetRootJSObject(XPCCallContext& ccx, JSObject* aJSObj);
    2890                 : 
    2891                 :     NS_IMETHOD CallMethod(nsXPCWrappedJS* wrapper, uint16_t methodIndex,
    2892                 :                           const XPTMethodDescriptor* info,
    2893                 :                           nsXPTCMiniVariant* params);
    2894                 : 
    2895                 :     JSObject*  CallQueryInterfaceOnJSObject(XPCCallContext& ccx,
    2896                 :                                             JSObject* jsobj, REFNSIID aIID);
    2897                 : 
    2898                 :     static nsresult BuildPropertyEnumerator(XPCCallContext& ccx,
    2899                 :                                             JSObject* aJSObj,
    2900                 :                                             nsISimpleEnumerator** aEnumerate);
    2901                 : 
    2902                 :     static nsresult GetNamedPropertyAsVariant(XPCCallContext& ccx,
    2903                 :                                               JSObject* aJSObj,
    2904                 :                                               const nsAString& aName,
    2905                 :                                               nsIVariant** aResult);
    2906                 : 
    2907                 :     virtual ~nsXPCWrappedJSClass();
    2908                 : 
    2909                 :     static nsresult CheckForException(XPCCallContext & ccx,
    2910                 :                                       const char * aPropertyName,
    2911                 :                                       const char * anInterfaceName,
    2912                 :                                       bool aForceReport);
    2913                 : private:
    2914                 :     nsXPCWrappedJSClass();   // not implemented
    2915                 :     nsXPCWrappedJSClass(XPCCallContext& ccx, REFNSIID aIID,
    2916                 :                         nsIInterfaceInfo* aInfo);
    2917                 : 
    2918                 :     JSObject*  NewOutObject(JSContext* cx, JSObject* scope);
    2919                 : 
    2920         1219826 :     JSBool IsReflectable(uint16_t i) const
    2921         1219826 :         {return (JSBool)(mDescriptors[i/32] & (1 << (i%32)));}
    2922          183263 :     void SetReflectable(uint16_t i, JSBool b)
    2923          183263 :         {if (b) mDescriptors[i/32] |= (1 << (i%32));
    2924           66022 :          else mDescriptors[i/32] &= ~(1 << (i%32));}
    2925                 : 
    2926                 :     JSBool GetArraySizeFromParam(JSContext* cx,
    2927                 :                                  const XPTMethodDescriptor* method,
    2928                 :                                  const nsXPTParamInfo& param,
    2929                 :                                  uint16_t methodIndex,
    2930                 :                                  uint8_t paramIndex,
    2931                 :                                  nsXPTCMiniVariant* params,
    2932                 :                                  uint32_t* result);
    2933                 : 
    2934                 :     JSBool GetInterfaceTypeFromParam(JSContext* cx,
    2935                 :                                      const XPTMethodDescriptor* method,
    2936                 :                                      const nsXPTParamInfo& param,
    2937                 :                                      uint16_t methodIndex,
    2938                 :                                      const nsXPTType& type,
    2939                 :                                      nsXPTCMiniVariant* params,
    2940                 :                                      nsID* result);
    2941                 : 
    2942                 :     void CleanupPointerArray(const nsXPTType& datum_type,
    2943                 :                              uint32_t array_count,
    2944                 :                              void** arrayp);
    2945                 : 
    2946                 :     void CleanupPointerTypeObject(const nsXPTType& type,
    2947                 :                                   void** pp);
    2948                 : 
    2949                 : private:
    2950                 :     XPCJSRuntime* mRuntime;
    2951                 :     nsIInterfaceInfo* mInfo;
    2952                 :     char* mName;
    2953                 :     nsIID mIID;
    2954                 :     uint32_t* mDescriptors;
    2955                 : };
    2956                 : 
    2957                 : /*************************/
    2958                 : // nsXPCWrappedJS is a wrapper for a single JSObject for use from native code.
    2959                 : // nsXPCWrappedJS objects are chained together to represent the various
    2960                 : // interface on the single underlying (possibly aggregate) JSObject.
    2961                 : 
    2962                 : class nsXPCWrappedJS : protected nsAutoXPTCStub,
    2963                 :                        public nsIXPConnectWrappedJS,
    2964                 :                        public nsSupportsWeakReference,
    2965                 :                        public nsIPropertyBag,
    2966                 :                        public XPCRootSetElem
    2967                 : {
    2968                 : public:
    2969                 :     NS_DECL_ISUPPORTS
    2970                 :     NS_DECL_NSIXPCONNECTJSOBJECTHOLDER
    2971                 :     NS_DECL_NSIXPCONNECTWRAPPEDJS
    2972                 :     NS_DECL_NSISUPPORTSWEAKREFERENCE
    2973                 :     NS_DECL_NSIPROPERTYBAG
    2974                 : 
    2975           35173 :     NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsXPCWrappedJS, nsIXPConnectWrappedJS)
    2976               0 :     NS_DECL_CYCLE_COLLECTION_UNMARK_PURPLE_STUB(nsXPCWrappedJS)
    2977                 : 
    2978                 :     NS_IMETHOD CallMethod(PRUint16 methodIndex,
    2979                 :                           const XPTMethodDescriptor *info,
    2980                 :                           nsXPTCMiniVariant* params);
    2981                 : 
    2982                 :     /*
    2983                 :     * This is rarely called directly. Instead one usually calls
    2984                 :     * XPCConvert::JSObject2NativeInterface which will handles cases where the
    2985                 :     * JS object is already a wrapped native or a DOM object.
    2986                 :     */
    2987                 : 
    2988                 :     static nsresult
    2989                 :     GetNewOrUsed(XPCCallContext& ccx,
    2990                 :                  JSObject* aJSObj,
    2991                 :                  REFNSIID aIID,
    2992                 :                  nsISupports* aOuter,
    2993                 :                  nsXPCWrappedJS** wrapper);
    2994                 : 
    2995          490965 :     nsISomeInterface* GetXPTCStub() { return mXPTCStub; }
    2996                 : 
    2997                 :     /**
    2998                 :      * This getter clears the gray bit before handing out the JSObject which
    2999                 :      * means that the object is guaranteed to be kept alive past the next CC.
    3000                 :      */
    3001         3295888 :     JSObject* GetJSObject() const {xpc_UnmarkGrayObject(mJSObj);
    3002         3295888 :                                    return mJSObj;}
    3003                 : 
    3004                 :     /**
    3005                 :      * This getter does not change the color of the JSObject meaning that the
    3006                 :      * object returned is not guaranteed to be kept alive past the next CC.
    3007                 :      *
    3008                 :      * This should only be called if you are certain that the return value won't
    3009                 :      * be passed into a JS API function and that it won't be stored without
    3010                 :      * being rooted (or otherwise signaling the stored value to the CC).
    3011                 :      */
    3012          552872 :     JSObject* GetJSObjectPreserveColor() const {return mJSObj;}
    3013                 : 
    3014         2031269 :     nsXPCWrappedJSClass*  GetClass() const {return mClass;}
    3015          502057 :     REFNSIID GetIID() const {return GetClass()->GetIID();}
    3016           15065 :     nsXPCWrappedJS* GetRootWrapper() const {return mRoot;}
    3017          212946 :     nsXPCWrappedJS* GetNextWrapper() const {return mNext;}
    3018                 : 
    3019                 :     nsXPCWrappedJS* Find(REFNSIID aIID);
    3020                 :     nsXPCWrappedJS* FindInherited(REFNSIID aIID);
    3021                 : 
    3022         3037050 :     JSBool IsValid() const {return mJSObj != nsnull;}
    3023                 :     void SystemIsBeingShutDown(JSRuntime* rt);
    3024                 : 
    3025                 :     // This is used by XPCJSRuntime::GCCallback to find wrappers that no
    3026                 :     // longer root their JSObject and are only still alive because they
    3027                 :     // were being used via nsSupportsWeakReference at the time when their
    3028                 :     // last (outside) reference was released. Wrappers that fit into that
    3029                 :     // category are only deleted when we see that their corresponding JSObject
    3030                 :     // is to be finalized.
    3031          214984 :     JSBool IsSubjectToFinalization() const {return IsValid() && mRefCnt == 1;}
    3032                 : 
    3033            1787 :     JSBool IsAggregatedToNative() const {return mRoot->mOuter != nsnull;}
    3034          958712 :     nsISupports* GetAggregatedNativeObject() const {return mRoot->mOuter;}
    3035                 : 
    3036          107637 :     void SetIsMainThreadOnly() {
    3037          107637 :         MOZ_ASSERT(mMainThread);
    3038          107637 :         mMainThreadOnly = true;
    3039          107637 :     }
    3040          107723 :     bool IsMainThreadOnly() const {return mMainThreadOnly;}
    3041                 : 
    3042                 :     void TraceJS(JSTracer* trc);
    3043                 : #ifdef DEBUG
    3044                 :     static void PrintTraceName(JSTracer* trc, char *buf, size_t bufsize);
    3045                 : #endif
    3046                 : 
    3047                 :     virtual ~nsXPCWrappedJS();
    3048                 : protected:
    3049                 :     nsXPCWrappedJS();   // not implemented
    3050                 :     nsXPCWrappedJS(XPCCallContext& ccx,
    3051                 :                    JSObject* aJSObj,
    3052                 :                    nsXPCWrappedJSClass* aClass,
    3053                 :                    nsXPCWrappedJS* root,
    3054                 :                    nsISupports* aOuter);
    3055                 : 
    3056                 :    void Unlink();
    3057                 : 
    3058                 : private:
    3059                 :     JSObject* mJSObj;
    3060                 :     nsXPCWrappedJSClass* mClass;
    3061                 :     nsXPCWrappedJS* mRoot;
    3062                 :     nsXPCWrappedJS* mNext;
    3063                 :     nsISupports* mOuter;    // only set in root
    3064                 :     bool mMainThread;
    3065                 :     bool mMainThreadOnly;
    3066                 : };
    3067                 : 
    3068                 : /***************************************************************************/
    3069                 : 
    3070                 : class XPCJSObjectHolder : public nsIXPConnectJSObjectHolder,
    3071                 :                           public XPCRootSetElem
    3072                 : {
    3073                 : public:
    3074                 :     // all the interface method declarations...
    3075                 :     NS_DECL_ISUPPORTS
    3076                 :     NS_DECL_NSIXPCONNECTJSOBJECTHOLDER
    3077                 : 
    3078                 :     // non-interface implementation
    3079                 : 
    3080                 : public:
    3081                 :     static XPCJSObjectHolder* newHolder(XPCCallContext& ccx, JSObject* obj);
    3082                 : 
    3083                 :     virtual ~XPCJSObjectHolder();
    3084                 : 
    3085                 :     void TraceJS(JSTracer *trc);
    3086                 : #ifdef DEBUG
    3087                 :     static void PrintTraceName(JSTracer* trc, char *buf, size_t bufsize);
    3088                 : #endif
    3089                 : 
    3090                 : private:
    3091                 :     XPCJSObjectHolder(XPCCallContext& ccx, JSObject* obj);
    3092                 :     XPCJSObjectHolder(); // not implemented
    3093                 : 
    3094                 :     JSObject* mJSObj;
    3095                 : };
    3096                 : 
    3097                 : /***************************************************************************
    3098                 : ****************************************************************************
    3099                 : *
    3100                 : * All manner of utility classes follow...
    3101                 : *
    3102                 : ****************************************************************************
    3103                 : ***************************************************************************/
    3104                 : 
    3105                 : class xpcProperty : public nsIProperty
    3106                 : {
    3107                 : public:
    3108                 :   NS_DECL_ISUPPORTS
    3109                 :   NS_DECL_NSIPROPERTY
    3110                 : 
    3111                 :   xpcProperty(const PRUnichar* aName, PRUint32 aNameLen, nsIVariant* aValue);
    3112               0 :   virtual ~xpcProperty() {}
    3113                 : 
    3114                 : private:
    3115                 :     nsString             mName;
    3116                 :     nsCOMPtr<nsIVariant> mValue;
    3117                 : };
    3118                 : 
    3119                 : /***************************************************************************/
    3120                 : // data conversion
    3121                 : 
    3122                 : class xpcObjectHelper
    3123         2138641 : {
    3124                 : public:
    3125         2102771 :     xpcObjectHelper(nsISupports *aObject, nsWrapperCache *aCache = nsnull)
    3126                 :     : mCanonical(nsnull),
    3127                 :       mObject(aObject),
    3128                 :       mCache(aCache),
    3129         2102771 :       mIsNode(false)
    3130                 :     {
    3131         2102771 :         if (!mCache) {
    3132         2102769 :             if (aObject)
    3133         2102769 :                 CallQueryInterface(aObject, &mCache);
    3134                 :             else
    3135               0 :                 mCache = nsnull;
    3136                 :         }
    3137         2102771 :     }
    3138                 : 
    3139         3320483 :     nsISupports* Object()
    3140                 :     {
    3141         3320483 :         return mObject;
    3142                 :     }
    3143                 : 
    3144         2163927 :     nsISupports* GetCanonical()
    3145                 :     {
    3146         2163927 :         if (!mCanonical) {
    3147         2105265 :             mCanonicalStrong = do_QueryInterface(mObject);
    3148         2105265 :             mCanonical = mCanonicalStrong;
    3149                 :         }
    3150         2163927 :         return mCanonical;
    3151                 :     }
    3152                 : 
    3153         1251115 :     already_AddRefed<nsISupports> forgetCanonical()
    3154                 :     {
    3155         1251115 :         NS_ASSERTION(mCanonical, "Huh, no canonical to forget?");
    3156                 : 
    3157         1251115 :         if (!mCanonicalStrong)
    3158           12204 :             mCanonicalStrong = mCanonical;
    3159         1251115 :         mCanonical = nsnull;
    3160         1251115 :         return mCanonicalStrong.forget();
    3161                 :     }
    3162                 : 
    3163         1249144 :     nsIClassInfo *GetClassInfo()
    3164                 :     {
    3165         1249144 :         if (mXPCClassInfo)
    3166            4969 :           return mXPCClassInfo;
    3167         1244175 :         if (!mClassInfo)
    3168         1231003 :             mClassInfo = do_QueryInterface(mObject);
    3169         1244175 :         return mClassInfo;
    3170                 :     }
    3171           61599 :     nsXPCClassInfo *GetXPCClassInfo()
    3172                 :     {
    3173           61599 :         if (!mXPCClassInfo) {
    3174           46456 :             if (mIsNode)
    3175           14947 :                 mXPCClassInfo = static_cast<nsINode*>(GetCanonical())->GetClassInfo();
    3176                 :             else
    3177           31509 :                 CallQueryInterface(mObject, getter_AddRefs(mXPCClassInfo));
    3178                 :         }
    3179           61599 :         return mXPCClassInfo;
    3180                 :     }
    3181                 : 
    3182           15143 :     already_AddRefed<nsXPCClassInfo> forgetXPCClassInfo()
    3183                 :     {
    3184           15143 :         GetXPCClassInfo();
    3185                 : 
    3186           15143 :         return mXPCClassInfo.forget();
    3187                 :     }
    3188                 : 
    3189                 :     // We assert that we can reach an nsIXPCScriptable somehow.
    3190           26344 :     PRUint32 GetScriptableFlags()
    3191                 :     {
    3192                 :         // Try getting an nsXPCClassInfo - this handles DOM scriptable helpers.
    3193           52688 :         nsCOMPtr<nsIXPCScriptable> sinfo = GetXPCClassInfo();
    3194                 : 
    3195                 :         // If that didn't work, try just QI-ing. This handles BackstagePass.
    3196           26344 :         if (!sinfo)
    3197           26344 :             sinfo = do_QueryInterface(GetCanonical());
    3198                 : 
    3199                 :         // We should have something by now.
    3200           26344 :         MOZ_ASSERT(sinfo);
    3201                 : 
    3202                 :         // Grab the flags. This should not fail.
    3203                 :         PRUint32 flags;
    3204           52688 :         mozilla::DebugOnly<nsresult> rv = sinfo->GetScriptableFlags(&flags);
    3205           26344 :         MOZ_ASSERT(NS_SUCCEEDED(rv));
    3206                 : 
    3207           26344 :         return flags;
    3208                 :     }
    3209                 : 
    3210         4240920 :     nsWrapperCache *GetWrapperCache()
    3211                 :     {
    3212         4240920 :         return mCache;
    3213                 :     }
    3214                 : 
    3215                 : protected:
    3216           35870 :     xpcObjectHelper(nsISupports *aObject, nsISupports *aCanonical,
    3217                 :                     nsWrapperCache *aCache, bool aIsNode)
    3218                 :     : mCanonical(aCanonical),
    3219                 :       mObject(aObject),
    3220                 :       mCache(aCache),
    3221           35870 :       mIsNode(aIsNode)
    3222                 :     {
    3223           35870 :         if (!mCache && aObject)
    3224           17585 :             CallQueryInterface(aObject, &mCache);
    3225           35870 :     }
    3226                 : 
    3227                 :     nsCOMPtr<nsISupports>    mCanonicalStrong;
    3228                 :     nsISupports*             mCanonical;
    3229                 : 
    3230                 : private:
    3231                 :     xpcObjectHelper(xpcObjectHelper& aOther);
    3232                 : 
    3233                 :     nsISupports*             mObject;
    3234                 :     nsWrapperCache*          mCache;
    3235                 :     nsCOMPtr<nsIClassInfo>   mClassInfo;
    3236                 :     nsRefPtr<nsXPCClassInfo> mXPCClassInfo;
    3237                 :     bool                     mIsNode;
    3238                 : };
    3239                 : 
    3240                 : // class here just for static methods
    3241                 : class XPCConvert
    3242                 : {
    3243                 : public:
    3244                 :     static JSBool IsMethodReflectable(const XPTMethodDescriptor& info);
    3245                 : 
    3246                 :     /**
    3247                 :      * Convert a native object into a jsval.
    3248                 :      *
    3249                 :      * @param ccx the context for the whole procedure
    3250                 :      * @param d [out] the resulting jsval
    3251                 :      * @param s the native object we're working with
    3252                 :      * @param type the type of object that s is
    3253                 :      * @param iid the interface of s that we want
    3254                 :      * @param scope the default scope to put on the new JSObject's parent
    3255                 :      *        chain
    3256                 :      * @param pErr [out] relevant error code, if any.
    3257                 :      */
    3258        20916012 :     static JSBool NativeData2JS(XPCCallContext& ccx, jsval* d, const void* s,
    3259                 :                                 const nsXPTType& type, const nsID* iid,
    3260                 :                                 nsresult* pErr)
    3261                 :     {
    3262        41832024 :         XPCLazyCallContext lccx(ccx);
    3263        20916012 :         return NativeData2JS(lccx, d, s, type, iid, pErr);
    3264                 :     }
    3265                 :     static JSBool NativeData2JS(XPCLazyCallContext& lccx, jsval* d,
    3266                 :                                 const void* s, const nsXPTType& type,
    3267                 :                                 const nsID* iid, nsresult* pErr);
    3268                 : 
    3269                 :     static JSBool JSData2Native(XPCCallContext& ccx, void* d, jsval s,
    3270                 :                                 const nsXPTType& type,
    3271                 :                                 JSBool useAllocator, const nsID* iid,
    3272                 :                                 nsresult* pErr);
    3273                 : 
    3274                 :     /**
    3275                 :      * Convert a native nsISupports into a JSObject.
    3276                 :      *
    3277                 :      * @param ccx the context for the whole procedure
    3278                 :      * @param dest [out] the resulting JSObject
    3279                 :      * @param src the native object we're working with
    3280                 :      * @param iid the interface of src that we want (may be null)
    3281                 :      * @param Interface the interface of src that we want
    3282                 :      * @param cache the wrapper cache for src (may be null, in which case src
    3283                 :      *              will be QI'ed to get the cache)
    3284                 :      * @param allowNativeWrapper if true, this method may wrap the resulting
    3285                 :      *        JSObject in an XPCNativeWrapper and return that, as needed.
    3286                 :      * @param pErr [out] relevant error code, if any.
    3287                 :      * @param src_is_identity optional performance hint. Set to true only
    3288                 :      *                        if src is the identity pointer.
    3289                 :      */
    3290            4144 :     static JSBool NativeInterface2JSObject(XPCCallContext& ccx,
    3291                 :                                            jsval* d,
    3292                 :                                            nsIXPConnectJSObjectHolder** dest,
    3293                 :                                            xpcObjectHelper& aHelper,
    3294                 :                                            const nsID* iid,
    3295                 :                                            XPCNativeInterface** Interface,
    3296                 :                                            bool allowNativeWrapper,
    3297                 :                                            nsresult* pErr)
    3298                 :     {
    3299            8288 :         XPCLazyCallContext lccx(ccx);
    3300                 :         return NativeInterface2JSObject(lccx, d, dest, aHelper, iid, Interface,
    3301            4144 :                                         allowNativeWrapper, pErr);
    3302                 :     }
    3303                 :     static JSBool NativeInterface2JSObject(XPCLazyCallContext& lccx,
    3304                 :                                            jsval* d,
    3305                 :                                            nsIXPConnectJSObjectHolder** dest,
    3306                 :                                            xpcObjectHelper& aHelper,
    3307                 :                                            const nsID* iid,
    3308                 :                                            XPCNativeInterface** Interface,
    3309                 :                                            bool allowNativeWrapper,
    3310                 :                                            nsresult* pErr);
    3311                 : 
    3312                 :     static JSBool GetNativeInterfaceFromJSObject(XPCCallContext& ccx,
    3313                 :                                                  void** dest, JSObject* src,
    3314                 :                                                  const nsID* iid,
    3315                 :                                                  nsresult* pErr);
    3316                 :     static JSBool JSObject2NativeInterface(XPCCallContext& ccx,
    3317                 :                                            void** dest, JSObject* src,
    3318                 :                                            const nsID* iid,
    3319                 :                                            nsISupports* aOuter,
    3320                 :                                            nsresult* pErr);
    3321                 :     static JSBool GetISupportsFromJSObject(JSObject* obj, nsISupports** iface);
    3322                 : 
    3323                 :     /**
    3324                 :      * Convert a native array into a jsval.
    3325                 :      *
    3326                 :      * @param ccx the context for the whole procedure
    3327                 :      * @param d [out] the resulting jsval
    3328                 :      * @param s the native array we're working with
    3329                 :      * @param type the type of objects in the array
    3330                 :      * @param iid the interface of each object in the array that we want
    3331                 :      * @param count the number of items in the array
    3332                 :      * @param scope the default scope to put on the new JSObjects' parent chain
    3333                 :      * @param pErr [out] relevant error code, if any.
    3334                 :      */
    3335                 :     static JSBool NativeArray2JS(XPCLazyCallContext& ccx,
    3336                 :                                  jsval* d, const void** s,
    3337                 :                                  const nsXPTType& type, const nsID* iid,
    3338                 :                                  uint32_t count, nsresult* pErr);
    3339                 : 
    3340                 :     static JSBool JSArray2Native(XPCCallContext& ccx, void** d, jsval s,
    3341                 :                                  uint32_t count, const nsXPTType& type,
    3342                 :                                  const nsID* iid, nsresult* pErr);
    3343                 : 
    3344                 :     static JSBool JSTypedArray2Native(XPCCallContext& ccx,
    3345                 :                                       void** d,
    3346                 :                                       JSObject* jsarray,
    3347                 :                                       uint32_t count,
    3348                 :                                       const nsXPTType& type,
    3349                 :                                       nsresult* pErr);
    3350                 : 
    3351                 :     static JSBool NativeStringWithSize2JS(JSContext* cx,
    3352                 :                                           jsval* d, const void* s,
    3353                 :                                           const nsXPTType& type,
    3354                 :                                           uint32_t count,
    3355                 :                                           nsresult* pErr);
    3356                 : 
    3357                 :     static JSBool JSStringWithSize2Native(XPCCallContext& ccx, void* d, jsval s,
    3358                 :                                           uint32_t count, const nsXPTType& type,
    3359                 :                                           unsigned* pErr);
    3360                 : 
    3361                 :     static nsresult JSValToXPCException(XPCCallContext& ccx,
    3362                 :                                         jsval s,
    3363                 :                                         const char* ifaceName,
    3364                 :                                         const char* methodName,
    3365                 :                                         nsIException** exception);
    3366                 : 
    3367                 :     static nsresult JSErrorToXPCException(XPCCallContext& ccx,
    3368                 :                                           const char* message,
    3369                 :                                           const char* ifaceName,
    3370                 :                                           const char* methodName,
    3371                 :                                           const JSErrorReport* report,
    3372                 :                                           nsIException** exception);
    3373                 : 
    3374                 :     static nsresult ConstructException(nsresult rv, const char* message,
    3375                 :                                        const char* ifaceName,
    3376                 :                                        const char* methodName,
    3377                 :                                        nsISupports* data,
    3378                 :                                        nsIException** exception,
    3379                 :                                        JSContext* cx,
    3380                 :                                        jsval *jsExceptionPtr);
    3381                 : 
    3382                 : private:
    3383                 :     XPCConvert(); // not implemented
    3384                 : 
    3385                 : };
    3386                 : 
    3387                 : /***************************************************************************/
    3388                 : 
    3389                 : // readable string conversions, static methods only
    3390                 : class XPCStringConvert
    3391                 : {
    3392                 : public:
    3393                 : 
    3394                 :     // If the string shares the readable's buffer, that buffer will
    3395                 :     // get assigned to *sharedBuffer.  Otherwise null will be
    3396                 :     // assigned.
    3397                 :     static jsval ReadableToJSVal(JSContext *cx, const nsAString &readable,
    3398                 :                                  nsStringBuffer** sharedBuffer);
    3399                 : 
    3400                 : private:
    3401                 :     XPCStringConvert();         // not implemented
    3402                 : };
    3403                 : 
    3404                 : /***************************************************************************/
    3405                 : // code for throwing exceptions into JS
    3406                 : 
    3407                 : class XPCThrower
    3408                 : {
    3409                 : public:
    3410                 :     static void Throw(nsresult rv, JSContext* cx);
    3411                 :     static void Throw(nsresult rv, XPCCallContext& ccx);
    3412                 :     static void ThrowBadResult(nsresult rv, nsresult result, XPCCallContext& ccx);
    3413                 :     static void ThrowBadParam(nsresult rv, unsigned paramNum, XPCCallContext& ccx);
    3414                 :     static JSBool SetVerbosity(JSBool state)
    3415                 :         {JSBool old = sVerbose; sVerbose = state; return old;}
    3416                 : 
    3417                 :     static void BuildAndThrowException(JSContext* cx, nsresult rv, const char* sz);
    3418                 :     static JSBool CheckForPendingException(nsresult result, JSContext *cx);
    3419                 : 
    3420                 : private:
    3421                 :     static void Verbosify(XPCCallContext& ccx,
    3422                 :                           char** psz, bool own);
    3423                 : 
    3424                 :     static JSBool ThrowExceptionObject(JSContext* cx, nsIException* e);
    3425                 : 
    3426                 : private:
    3427                 :     static JSBool sVerbose;
    3428                 : };
    3429                 : 
    3430                 : 
    3431                 : /***************************************************************************/
    3432                 : 
    3433                 : class XPCJSStack
    3434                 : {
    3435                 : public:
    3436                 :     static nsresult
    3437                 :     CreateStack(JSContext* cx, nsIStackFrame** stack);
    3438                 : 
    3439                 :     static nsresult
    3440                 :     CreateStackFrameLocation(PRUint32 aLanguage,
    3441                 :                              const char* aFilename,
    3442                 :                              const char* aFunctionName,
    3443                 :                              PRInt32 aLineNumber,
    3444                 :                              nsIStackFrame* aCaller,
    3445                 :                              nsIStackFrame** stack);
    3446                 : private:
    3447                 :     XPCJSStack();   // not implemented
    3448                 : };
    3449                 : 
    3450                 : /***************************************************************************/
    3451                 : 
    3452                 : class nsXPCException :
    3453                 :             public nsIXPCException
    3454                 : {
    3455                 : public:
    3456             108 :     NS_DEFINE_STATIC_CID_ACCESSOR(NS_XPCEXCEPTION_CID)
    3457                 : 
    3458                 :     NS_DECL_ISUPPORTS
    3459                 :     NS_DECL_NSIEXCEPTION
    3460                 :     NS_DECL_NSIXPCEXCEPTION
    3461                 : 
    3462                 :     static nsresult NewException(const char *aMessage,
    3463                 :                                  nsresult aResult,
    3464                 :                                  nsIStackFrame *aLocation,
    3465                 :                                  nsISupports *aData,
    3466                 :                                  nsIException** exception);
    3467                 : 
    3468                 :     static JSBool NameAndFormatForNSResult(nsresult rv,
    3469                 :                                            const char** name,
    3470                 :                                            const char** format);
    3471                 : 
    3472                 :     static void* IterateNSResults(nsresult* rv,
    3473                 :                                   const char** name,
    3474                 :                                   const char** format,
    3475                 :                                   void** iterp);
    3476                 : 
    3477                 :     static PRUint32 GetNSResultCount();
    3478                 : 
    3479                 :     nsXPCException();
    3480                 :     virtual ~nsXPCException();
    3481                 : 
    3482            1365 :     static void InitStatics() { sEverMadeOneFromFactory = false; }
    3483                 : 
    3484                 : protected:
    3485                 :     void Reset();
    3486                 : private:
    3487                 :     char*           mMessage;
    3488                 :     nsresult        mResult;
    3489                 :     char*           mName;
    3490                 :     nsIStackFrame*  mLocation;
    3491                 :     nsISupports*    mData;
    3492                 :     char*           mFilename;
    3493                 :     int             mLineNumber;
    3494                 :     nsIException*   mInner;
    3495                 :     bool            mInitialized;
    3496                 : 
    3497                 :     nsAutoJSValHolder mThrownJSVal;
    3498                 : 
    3499                 :     static JSBool sEverMadeOneFromFactory;
    3500                 : };
    3501                 : 
    3502                 : /***************************************************************************/
    3503                 : /*
    3504                 : * nsJSID implements nsIJSID. It is also used by nsJSIID and nsJSCID as a
    3505                 : * member (as a hidden implementaion detail) to which they delegate many calls.
    3506                 : */
    3507                 : 
    3508                 : // Initialization is done on demand, and calling the destructor below is always
    3509                 : // safe.
    3510                 : extern void xpc_DestroyJSxIDClassObjects();
    3511                 : 
    3512                 : class nsJSID : public nsIJSID
    3513                 : {
    3514                 : public:
    3515            3241 :     NS_DEFINE_STATIC_CID_ACCESSOR(NS_JS_ID_CID)
    3516                 : 
    3517                 :     NS_DECL_ISUPPORTS
    3518                 :     NS_DECL_NSIJSID
    3519                 : 
    3520                 :     bool InitWithName(const nsID& id, const char *nameString);
    3521                 :     bool SetName(const char* name);
    3522               0 :     void   SetNameToNoString()
    3523               0 :         {NS_ASSERTION(!mName, "name already set"); mName = gNoString;}
    3524               0 :     bool NameIsSet() const {return nsnull != mName;}
    3525          373845 :     const nsID& ID() const {return mID;}
    3526          186238 :     bool IsValid() const {return !mID.Equals(GetInvalidIID());}
    3527                 : 
    3528                 :     static nsJSID* NewID(const char* str);
    3529                 :     static nsJSID* NewID(const nsID& id);
    3530                 : 
    3531                 :     nsJSID();
    3532                 :     virtual ~nsJSID();
    3533                 : protected:
    3534                 : 
    3535                 :     void Reset();
    3536                 :     const nsID& GetInvalidIID() const;
    3537                 : 
    3538                 : protected:
    3539                 :     static char gNoString[];
    3540                 :     nsID    mID;
    3541                 :     char*   mNumber;
    3542                 :     char*   mName;
    3543                 : };
    3544                 : 
    3545                 : // nsJSIID
    3546                 : 
    3547                 : class nsJSIID : public nsIJSIID,
    3548                 :                 public nsIXPCScriptable,
    3549                 :                 public nsISecurityCheckedComponent
    3550                 : {
    3551                 : public:
    3552                 :     NS_DECL_ISUPPORTS
    3553                 : 
    3554                 :     // we manually delagate these to nsJSID
    3555                 :     NS_DECL_NSIJSID
    3556                 : 
    3557                 :     // we implement the rest...
    3558                 :     NS_DECL_NSIJSIID
    3559                 :     NS_DECL_NSIXPCSCRIPTABLE
    3560                 :     NS_DECL_NSISECURITYCHECKEDCOMPONENT
    3561                 : 
    3562                 :     static nsJSIID* NewID(nsIInterfaceInfo* aInfo);
    3563                 : 
    3564                 :     nsJSIID(nsIInterfaceInfo* aInfo);
    3565                 :     nsJSIID(); // not implemented
    3566                 :     virtual ~nsJSIID();
    3567                 : 
    3568                 : private:
    3569                 :     nsCOMPtr<nsIInterfaceInfo> mInfo;
    3570                 : };
    3571                 : 
    3572                 : // nsJSCID
    3573                 : 
    3574                 : class nsJSCID : public nsIJSCID, public nsIXPCScriptable
    3575                 : {
    3576                 : public:
    3577                 :     NS_DECL_ISUPPORTS
    3578                 : 
    3579                 :     // we manually delagate these to nsJSID
    3580                 :     NS_DECL_NSIJSID
    3581                 : 
    3582                 :     // we implement the rest...
    3583                 :     NS_DECL_NSIJSCID
    3584                 :     NS_DECL_NSIXPCSCRIPTABLE
    3585                 : 
    3586                 :     static nsJSCID* NewID(const char* str);
    3587                 : 
    3588                 :     nsJSCID();
    3589                 :     virtual ~nsJSCID();
    3590                 : 
    3591                 : private:
    3592                 :     void ResolveName();
    3593                 : 
    3594                 : private:
    3595                 :     nsJSID mDetails;
    3596                 : };
    3597                 : 
    3598                 : 
    3599                 : /***************************************************************************/
    3600                 : // XPCJSContextStack is not actually an xpcom object, but xpcom calls are
    3601                 : // delegated to it as an implementation detail.
    3602          616204 : struct XPCJSContextInfo {
    3603          616204 :     XPCJSContextInfo(JSContext* aCx) :
    3604                 :         cx(aCx),
    3605                 :         savedFrameChain(false),
    3606          616204 :         suspendDepth(0)
    3607          616204 :     {}
    3608                 :     JSContext* cx;
    3609                 : 
    3610                 :     // Whether the frame chain was saved
    3611                 :     bool savedFrameChain;
    3612                 : 
    3613                 :     // Greater than 0 if a request was suspended.
    3614                 :     unsigned suspendDepth;
    3615                 : };
    3616                 : 
    3617                 : class XPCJSContextStack
    3618                 : {
    3619                 : public:
    3620            1367 :     XPCJSContextStack()
    3621                 :       : mSafeJSContext(NULL)
    3622            1367 :       , mOwnSafeJSContext(NULL)
    3623            1367 :     { }
    3624                 : 
    3625                 :     virtual ~XPCJSContextStack();
    3626                 : 
    3627               0 :     uint32_t Count()
    3628                 :     {
    3629               0 :         return mStack.Length();
    3630                 :     }
    3631                 : 
    3632        19315371 :     JSContext *Peek()
    3633                 :     {
    3634        19315371 :         return mStack.IsEmpty() ? NULL : mStack[mStack.Length() - 1].cx;
    3635                 :     }
    3636                 : 
    3637                 :     JSContext *Pop();
    3638                 :     bool Push(JSContext *cx);
    3639                 :     JSContext *GetSafeJSContext();
    3640                 : 
    3641                 : #ifdef DEBUG
    3642                 :     bool DEBUG_StackHasJSContext(JSContext *cx);
    3643                 : #endif
    3644                 : 
    3645               0 :     const InfallibleTArray<XPCJSContextInfo>* GetStack()
    3646               0 :     { return &mStack; }
    3647                 : 
    3648                 : private:
    3649                 :     AutoInfallibleTArray<XPCJSContextInfo, 16> mStack;
    3650                 :     JSContext*  mSafeJSContext;
    3651                 :     JSContext*  mOwnSafeJSContext;
    3652                 : };
    3653                 : 
    3654                 : /***************************************************************************/
    3655                 : 
    3656                 : #define NS_XPC_JSCONTEXT_STACK_ITERATOR_CID                                   \
    3657                 : { 0x05bae29d, 0x8aef, 0x486d,                                                 \
    3658                 :   { 0x84, 0xaa, 0x53, 0xf4, 0x8f, 0x14, 0x68, 0x11 } }
    3659                 : 
    3660                 : class nsXPCJSContextStackIterator : public nsIJSContextStackIterator
    3661               0 : {
    3662                 : public:
    3663                 :     NS_DECL_ISUPPORTS
    3664                 :     NS_DECL_NSIJSCONTEXTSTACKITERATOR
    3665                 : 
    3666                 : private:
    3667                 :     const InfallibleTArray<XPCJSContextInfo> *mStack;
    3668                 :     PRUint32 mPosition;
    3669                 : };
    3670                 : 
    3671                 : /**************************************************************/
    3672                 : // All of our thread local storage.
    3673                 : 
    3674                 : class XPCPerThreadData
    3675                 : {
    3676                 :     typedef mozilla::Mutex Mutex;
    3677                 : 
    3678                 : public:
    3679                 :     // Get the instance of this object for the current thread
    3680        20349765 :     static inline XPCPerThreadData* GetData(JSContext *cx)
    3681                 :     {
    3682                 :         // Do a release-mode assert that we're not doing anything significant in
    3683                 :         // XPConnect off the main thread. If you're an extension developer hitting
    3684                 :         // this, you need to change your code. See bug 716167.
    3685        20349765 :         if (!NS_LIKELY(NS_IsMainThread() || NS_IsCycleCollectorThread()))
    3686               0 :             MOZ_Assert("NS_IsMainThread()", __FILE__, __LINE__);
    3687                 : 
    3688        20349765 :         if (cx) {
    3689        14992753 :             if (js::GetOwnerThread(cx) == sMainJSThread)
    3690        14991384 :                 return sMainThreadData;
    3691         5357012 :         } else if (sMainThreadData && sMainThreadData->mThread == PR_GetCurrentThread()) {
    3692         5355647 :             return sMainThreadData;
    3693                 :         }
    3694                 : 
    3695            2734 :         return GetDataImpl(cx);
    3696                 :     }
    3697                 : 
    3698                 :     static void CleanupAllThreads();
    3699                 : 
    3700                 :     ~XPCPerThreadData();
    3701                 : 
    3702           18998 :     nsresult GetException(nsIException** aException)
    3703                 :     {
    3704           18998 :         if (EnsureExceptionManager())
    3705           18998 :             return mExceptionManager->GetCurrentException(aException);
    3706                 : 
    3707               0 :         NS_IF_ADDREF(mException);
    3708               0 :         *aException = mException;
    3709               0 :         return NS_OK;
    3710                 :     }
    3711                 : 
    3712         9811725 :     nsresult SetException(nsIException* aException)
    3713                 :     {
    3714         9811725 :         if (EnsureExceptionManager())
    3715         9811725 :             return mExceptionManager->SetCurrentException(aException);
    3716                 : 
    3717               0 :         NS_IF_ADDREF(aException);
    3718               0 :         NS_IF_RELEASE(mException);
    3719               0 :         mException = aException;
    3720               0 :         return NS_OK;
    3721                 :     }
    3722                 : 
    3723           18793 :     nsIExceptionManager* GetExceptionManager()
    3724                 :     {
    3725           18793 :         if (EnsureExceptionManager())
    3726           18793 :             return mExceptionManager;
    3727               0 :         return nsnull;
    3728                 :     }
    3729                 : 
    3730         9849516 :     JSBool EnsureExceptionManager()
    3731                 :     {
    3732         9849516 :         if (mExceptionManager)
    3733         9848151 :             return true;
    3734                 : 
    3735            1365 :         if (mExceptionManagerNotAvailable)
    3736               0 :             return false;
    3737                 : 
    3738                 :         nsCOMPtr<nsIExceptionService> xs =
    3739            2730 :             do_GetService(NS_EXCEPTIONSERVICE_CONTRACTID);
    3740            1365 :         if (xs)
    3741            1365 :             xs->GetCurrentExceptionManager(&mExceptionManager);
    3742            1365 :         if (mExceptionManager)
    3743            1365 :             return true;
    3744                 : 
    3745               0 :         mExceptionManagerNotAvailable = true;
    3746               0 :         return false;
    3747                 :     }
    3748                 : 
    3749        20314225 :     XPCJSContextStack* GetJSContextStack() {return mJSContextStack;}
    3750                 : 
    3751          252510 :     XPCCallContext*  GetCallContext() const {return mCallContext;}
    3752        33113150 :     XPCCallContext*  SetCallContext(XPCCallContext* ccx)
    3753        33113150 :         {XPCCallContext* old = mCallContext; mCallContext = ccx; return old;}
    3754                 : 
    3755         1670908 :     jsid GetResolveName() const {return mResolveName;}
    3756         6534346 :     jsid SetResolveName(jsid name)
    3757         6534346 :         {jsid old = mResolveName; mResolveName = name; return old;}
    3758                 : 
    3759          223550 :     XPCWrappedNative* GetResolvingWrapper() const {return mResolvingWrapper;}
    3760         1030760 :     XPCWrappedNative* SetResolvingWrapper(XPCWrappedNative* w)
    3761         1030760 :         {XPCWrappedNative* old = mResolvingWrapper;
    3762         1030760 :          mResolvingWrapper = w; return old;}
    3763                 : 
    3764                 :     void Cleanup();
    3765                 :     void ReleaseNatives();
    3766                 : 
    3767            1367 :     bool IsValid() const {return mJSContextStack != nsnull;}
    3768                 : 
    3769           35343 :     static Mutex* GetLock() {return gLock;}
    3770                 :     // Must be called with the threads locked.
    3771                 :     static XPCPerThreadData* IterateThreads(XPCPerThreadData** iteratorp);
    3772                 : 
    3773        46566302 :     AutoMarkingPtr**  GetAutoRootsAdr() {return &mAutoRoots;}
    3774                 : 
    3775                 :     void TraceJS(JSTracer* trc);
    3776                 :     void MarkAutoRootsAfterJSFinalize();
    3777                 : 
    3778            1365 :     static void InitStatics()
    3779            1365 :         { gLock = nsnull; gThreads = nsnull; gTLSIndex = BAD_TLS_INDEX; }
    3780                 : 
    3781                 : #ifdef XPC_CHECK_WRAPPER_THREADSAFETY
    3782               0 :     uint32_t  IncrementWrappedNativeThreadsafetyReportDepth()
    3783               0 :         {return ++mWrappedNativeThreadsafetyReportDepth;}
    3784               0 :     void      ClearWrappedNativeThreadsafetyReportDepth()
    3785               0 :         {mWrappedNativeThreadsafetyReportDepth = 0;}
    3786                 : #endif
    3787                 : 
    3788            1364 :     static void ShutDown()
    3789            1364 :         {sMainJSThread = nsnull; sMainThreadData = nsnull;}
    3790                 : 
    3791        13659981 :     static bool IsMainThread(JSContext *cx)
    3792        13659981 :         { return js::GetOwnerThread(cx) == sMainJSThread; }
    3793                 : 
    3794                 : private:
    3795                 :     XPCPerThreadData();
    3796                 :     static XPCPerThreadData* GetDataImpl(JSContext *cx);
    3797                 : 
    3798                 : private:
    3799                 :     XPCJSContextStack*   mJSContextStack;
    3800                 :     XPCPerThreadData*    mNextThread;
    3801                 :     XPCCallContext*      mCallContext;
    3802                 :     jsid                 mResolveName;
    3803                 :     XPCWrappedNative*    mResolvingWrapper;
    3804                 : 
    3805                 :     nsIExceptionManager* mExceptionManager;
    3806                 :     nsIException*        mException;
    3807                 :     JSBool               mExceptionManagerNotAvailable;
    3808                 :     AutoMarkingPtr*      mAutoRoots;
    3809                 : 
    3810                 : #ifdef XPC_CHECK_WRAPPER_THREADSAFETY
    3811                 :     uint32_t             mWrappedNativeThreadsafetyReportDepth;
    3812                 : #endif
    3813                 :     PRThread*            mThread;
    3814                 : 
    3815                 :     static Mutex*            gLock;
    3816                 :     static XPCPerThreadData* gThreads;
    3817                 :     static PRUintn           gTLSIndex;
    3818                 : 
    3819                 :     // Cached value of cx->thread on the main thread.
    3820                 :     static void *sMainJSThread;
    3821                 : 
    3822                 :     // Cached per thread data for the main thread. Only safe to access
    3823                 :     // if cx->thread == sMainJSThread.
    3824                 :     static XPCPerThreadData *sMainThreadData;
    3825                 : };
    3826                 : 
    3827                 : /***************************************************************************/
    3828                 : #include "nsIScriptSecurityManager.h"
    3829                 : 
    3830                 : class BackstagePass : public nsIScriptObjectPrincipal,
    3831                 :                       public nsIXPCScriptable,
    3832                 :                       public nsIClassInfo
    3833                 : {
    3834                 : public:
    3835                 :   NS_DECL_ISUPPORTS
    3836                 :   NS_DECL_NSIXPCSCRIPTABLE
    3837                 :   NS_DECL_NSICLASSINFO
    3838                 : 
    3839         6583303 :   virtual nsIPrincipal* GetPrincipal() {
    3840         6583303 :     return mPrincipal;
    3841                 :   }
    3842                 : 
    3843            1365 :   BackstagePass(nsIPrincipal *prin) :
    3844            1365 :     mPrincipal(prin)
    3845                 :   {
    3846            1365 :   }
    3847                 : 
    3848            5388 :   virtual ~BackstagePass() { }
    3849                 : 
    3850                 : private:
    3851                 :   nsCOMPtr<nsIPrincipal> mPrincipal;
    3852                 : };
    3853                 : // 'Components' object
    3854                 : 
    3855                 : class nsXPCComponents : public nsIXPCComponents,
    3856                 :                         public nsIXPCScriptable,
    3857                 :                         public nsIClassInfo,
    3858                 :                         public nsISecurityCheckedComponent
    3859                 : {
    3860                 : public:
    3861                 :     NS_DECL_ISUPPORTS
    3862                 :     NS_DECL_NSIXPCCOMPONENTS
    3863                 :     NS_DECL_NSIXPCSCRIPTABLE
    3864                 :     NS_DECL_NSICLASSINFO
    3865                 :     NS_DECL_NSISECURITYCHECKEDCOMPONENT
    3866                 : 
    3867                 : public:
    3868                 :     static JSBool
    3869                 :     AttachNewComponentsObject(XPCCallContext& ccx,
    3870                 :                               XPCWrappedNativeScope* aScope,
    3871                 :                               JSObject* aGlobal);
    3872                 : 
    3873              24 :     void SystemIsBeingShutDown() {ClearMembers();}
    3874                 : 
    3875                 :     virtual ~nsXPCComponents();
    3876                 : 
    3877                 : private:
    3878                 :     nsXPCComponents();
    3879                 :     void ClearMembers();
    3880                 : 
    3881                 : private:
    3882                 :     nsXPCComponents_Interfaces*     mInterfaces;
    3883                 :     nsXPCComponents_InterfacesByID* mInterfacesByID;
    3884                 :     nsXPCComponents_Classes*        mClasses;
    3885                 :     nsXPCComponents_ClassesByID*    mClassesByID;
    3886                 :     nsXPCComponents_Results*        mResults;
    3887                 :     nsXPCComponents_ID*             mID;
    3888                 :     nsXPCComponents_Exception*      mException;
    3889                 :     nsXPCComponents_Constructor*    mConstructor;
    3890                 :     nsXPCComponents_Utils*          mUtils;
    3891                 : };
    3892                 : 
    3893                 : 
    3894                 : /***************************************************************************/
    3895                 : 
    3896                 : extern JSObject*
    3897                 : xpc_NewIDObject(JSContext *cx, JSObject* jsobj, const nsID& aID);
    3898                 : 
    3899                 : extern const nsID*
    3900                 : xpc_JSObjectToID(JSContext *cx, JSObject* obj);
    3901                 : 
    3902                 : extern JSBool
    3903                 : xpc_JSObjectIsID(JSContext *cx, JSObject* obj);
    3904                 : 
    3905                 : /***************************************************************************/
    3906                 : // in xpcdebug.cpp
    3907                 : 
    3908                 : extern JSBool
    3909                 : xpc_DumpJSStack(JSContext* cx, JSBool showArgs, JSBool showLocals,
    3910                 :                 JSBool showThisProps);
    3911                 : 
    3912                 : // Return a newly-allocated string containing a representation of the
    3913                 : // current JS stack.  It is the *caller's* responsibility to free this
    3914                 : // string with JS_smprintf_free().
    3915                 : extern char*
    3916                 : xpc_PrintJSStack(JSContext* cx, JSBool showArgs, JSBool showLocals,
    3917                 :                  JSBool showThisProps);
    3918                 : 
    3919                 : extern JSBool
    3920                 : xpc_DumpEvalInJSStackFrame(JSContext* cx, uint32_t frameno, const char* text);
    3921                 : 
    3922                 : extern JSBool
    3923                 : xpc_DumpJSObject(JSObject* obj);
    3924                 : 
    3925                 : extern JSBool
    3926                 : xpc_InstallJSDebuggerKeywordHandler(JSRuntime* rt);
    3927                 : 
    3928                 : /***************************************************************************/
    3929                 : 
    3930                 : // Definition of nsScriptError, defined here because we lack a place to put
    3931                 : // XPCOM objects associated with the JavaScript engine.
    3932                 : class nsScriptError : public nsIScriptError {
    3933                 : public:
    3934                 :     nsScriptError();
    3935                 : 
    3936                 :     virtual ~nsScriptError();
    3937                 : 
    3938                 :   // TODO - do something reasonable on getting null from these babies.
    3939                 : 
    3940                 :     NS_DECL_ISUPPORTS
    3941                 :     NS_DECL_NSICONSOLEMESSAGE
    3942                 :     NS_DECL_NSISCRIPTERROR
    3943                 : 
    3944                 : private:
    3945                 :     nsString mMessage;
    3946                 :     nsString mSourceName;
    3947                 :     PRUint32 mLineNumber;
    3948                 :     nsString mSourceLine;
    3949                 :     PRUint32 mColumnNumber;
    3950                 :     PRUint32 mFlags;
    3951                 :     nsCString mCategory;
    3952                 :     PRUint64 mOuterWindowID;
    3953                 :     PRUint64 mInnerWindowID;
    3954                 :     PRInt64 mTimeStamp;
    3955                 : };
    3956                 : 
    3957                 : /******************************************************************************
    3958                 :  * Handles pre/post script processing and the setting/resetting the error
    3959                 :  * reporter
    3960                 :  */
    3961                 : class NS_STACK_CLASS AutoScriptEvaluate
    3962                 : {
    3963                 : public:
    3964                 :     /**
    3965                 :      * Saves the JSContext as well as initializing our state
    3966                 :      * @param cx The JSContext, this can be null, we don't do anything then
    3967                 :      */
    3968         1546789 :     AutoScriptEvaluate(JSContext * cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
    3969                 :          : mJSContext(cx), mState(0), mErrorReporterSet(false),
    3970         1546789 :            mEvaluated(false), mContextHasThread(0) {
    3971         1546789 :         MOZ_GUARD_OBJECT_NOTIFIER_INIT;
    3972         1546789 :     }
    3973                 : 
    3974                 :     /**
    3975                 :      * Does the pre script evaluation and sets the error reporter if given
    3976                 :      * This function should only be called once, and will assert if called
    3977                 :      * more than once
    3978                 :      * @param errorReporter the error reporter callback function to set
    3979                 :      */
    3980                 : 
    3981                 :     bool StartEvaluating(JSObject *scope, JSErrorReporter errorReporter = nsnull);
    3982                 :     /**
    3983                 :      * Does the post script evaluation and resets the error reporter
    3984                 :      */
    3985                 :     ~AutoScriptEvaluate();
    3986                 : private:
    3987                 :     JSContext* mJSContext;
    3988                 :     JSExceptionState* mState;
    3989                 :     bool mErrorReporterSet;
    3990                 :     bool mEvaluated;
    3991                 :     intptr_t mContextHasThread;
    3992                 :     JSAutoEnterCompartment mEnterCompartment;
    3993                 :     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
    3994                 : 
    3995                 :     // No copying or assignment allowed
    3996                 :     AutoScriptEvaluate(const AutoScriptEvaluate &) MOZ_DELETE;
    3997                 :     AutoScriptEvaluate & operator =(const AutoScriptEvaluate &) MOZ_DELETE;
    3998                 : };
    3999                 : 
    4000                 : /***************************************************************************/
    4001                 : class NS_STACK_CLASS AutoResolveName
    4002                 : {
    4003                 : public:
    4004         1697306 :     AutoResolveName(XPCCallContext& ccx, jsid name
    4005                 :                     MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
    4006         1697306 :         : mTLS(ccx.GetThreadData()),
    4007         1697306 :           mOld(mTLS->SetResolveName(name)),
    4008         3394612 :           mCheck(name) {
    4009         1697306 :         MOZ_GUARD_OBJECT_NOTIFIER_INIT;
    4010         1697306 :     }
    4011         1697306 :     ~AutoResolveName()
    4012         1697306 :         {
    4013                 : #ifdef DEBUG
    4014                 :             jsid old =
    4015                 : #endif
    4016         1697306 :             mTLS->SetResolveName(mOld);
    4017         1697306 :             NS_ASSERTION(old == mCheck, "Bad Nesting!");
    4018         1697306 :         }
    4019                 : 
    4020                 : private:
    4021                 :     XPCPerThreadData* mTLS;
    4022                 :     jsid mOld;
    4023                 :     jsid mCheck;
    4024                 :     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
    4025                 : };
    4026                 : 
    4027                 : /***************************************************************************/
    4028                 : class XPCMarkableJSVal
    4029                 : {
    4030                 : public:
    4031         1842203 :     XPCMarkableJSVal(jsval val) : mVal(val), mValPtr(&mVal) {}
    4032         8676136 :     XPCMarkableJSVal(jsval *pval) : mVal(JSVAL_VOID), mValPtr(pval) {}
    4033        10518339 :     ~XPCMarkableJSVal() {}
    4034               6 :     void Mark() {}
    4035               6 :     void TraceJS(JSTracer* trc)
    4036                 :     {
    4037               6 :         JS_CALL_VALUE_TRACER(trc, *mValPtr, "XPCMarkableJSVal");
    4038               6 :     }
    4039               6 :     void AutoTrace(JSTracer* trc) {}
    4040                 : private:
    4041                 :     XPCMarkableJSVal(); // not implemented
    4042                 :     jsval  mVal;
    4043                 :     jsval* mValPtr;
    4044                 : };
    4045                 : 
    4046                 : /***************************************************************************/
    4047                 : // AutoMarkingPtr is the base class for the various AutoMarking pointer types
    4048                 : // below. This system allows us to temporarily protect instances of our garbage
    4049                 : // collected types after they are constructed but before they are safely
    4050                 : // attached to other rooted objects.
    4051                 : // This base class has pure virtual support for marking.
    4052                 : 
    4053                 : class AutoMarkingPtr
    4054                 : {
    4055                 : public:
    4056        21205264 :     AutoMarkingPtr(XPCCallContext& ccx)
    4057        21205264 :         : mNext(nsnull), mTLS(ccx.GetThreadData()) {Link();}
    4058         2084131 :     AutoMarkingPtr()
    4059         2084131 :         : mNext(nsnull), mTLS(nsnull) {}
    4060                 : 
    4061        46578790 :     virtual ~AutoMarkingPtr() {Unlink();}
    4062                 : 
    4063         2077887 :     void Init(XPCCallContext& ccx)
    4064         2077887 :         {NS_ASSERTION(!mTLS, "Already init'ed!");
    4065         2077887 :          mTLS = ccx.GetThreadData();
    4066         2077887 :          Link();}
    4067                 : 
    4068        23283151 :     void Link()
    4069        23283151 :         {if (!mTLS) return;
    4070        23283151 :          AutoMarkingPtr** list = mTLS->GetAutoRootsAdr();
    4071        23283151 :          mNext = *list; *list = this;}
    4072                 : 
    4073        23289395 :     void Unlink()
    4074        23289395 :         {if (!mTLS) return;
    4075        23283151 :          AutoMarkingPtr** cur = mTLS->GetAutoRootsAdr();
    4076        46566302 :          while (*cur != this) {
    4077               0 :             NS_ASSERTION(*cur, "This object not in list!");
    4078               0 :             cur = &(*cur)->mNext;
    4079                 :          }
    4080        23283151 :          *cur = mNext;
    4081        23283151 :          mTLS = nsnull;
    4082                 :         }
    4083                 : 
    4084                 :     AutoMarkingPtr* GetNext() {return mNext;}
    4085                 : 
    4086                 :     virtual void TraceJS(JSTracer* trc) = 0;
    4087                 :     virtual void MarkAfterJSFinalize() = 0;
    4088                 : 
    4089                 : protected:
    4090                 :     AutoMarkingPtr* mNext;
    4091                 :     XPCPerThreadData* mTLS;
    4092                 : };
    4093                 : 
    4094                 : // More joy of macros...
    4095                 : 
    4096                 : #define DEFINE_AUTO_MARKING_PTR_TYPE(class_, type_)                           \
    4097                 : class class_ : public AutoMarkingPtr                                          \
    4098                 : {                                                                             \
    4099                 : public:                                                                       \
    4100                 :     class_ ()                                                                 \
    4101                 :         : AutoMarkingPtr(), mPtr(nsnull) {}                                   \
    4102                 :     class_ (XPCCallContext& ccx, type_ * ptr = nsnull)                        \
    4103                 :         : AutoMarkingPtr(ccx), mPtr(ptr) {}                                   \
    4104                 :     virtual ~ class_ () {}                                                    \
    4105                 :                                                                               \
    4106                 :     virtual void TraceJS(JSTracer* trc)                                       \
    4107                 :         {if (mPtr) {                                                          \
    4108                 :            mPtr->TraceJS(trc);                                                \
    4109                 :            mPtr->AutoTrace(trc);                                              \
    4110                 :          }                                                                    \
    4111                 :          if (mNext) mNext->TraceJS(trc);}                                     \
    4112                 :                                                                               \
    4113                 :     virtual void MarkAfterJSFinalize()                                        \
    4114                 :         {if (mPtr) mPtr->Mark();                                              \
    4115                 :          if (mNext) mNext->MarkAfterJSFinalize();}                            \
    4116                 :                                                                               \
    4117                 :     type_ * get()        const  {return mPtr;}                                \
    4118                 :     operator type_ *()   const  {return mPtr;}                                \
    4119                 :     type_ * operator->() const  {return mPtr;}                                \
    4120                 :                                                                               \
    4121                 :     class_ & operator =(type_ * p)                                            \
    4122                 :         {NS_ASSERTION(mTLS, "Hasn't been init'ed!");                          \
    4123                 :          mPtr = p; return *this;}                                             \
    4124                 :                                                                               \
    4125                 : protected:                                                                    \
    4126                 :     type_ * mPtr;                                                             \
    4127                 : };
    4128                 : 
    4129                 : // Use the macro above to define our AutoMarking types...
    4130                 : 
    4131        36032442 : DEFINE_AUTO_MARKING_PTR_TYPE(AutoMarkingNativeInterfacePtr, XPCNativeInterface)
    4132        16113154 : DEFINE_AUTO_MARKING_PTR_TYPE(AutoMarkingNativeSetPtr, XPCNativeSet)
    4133         3726111 : DEFINE_AUTO_MARKING_PTR_TYPE(AutoMarkingWrappedNativePtr, XPCWrappedNative)
    4134         4529634 : DEFINE_AUTO_MARKING_PTR_TYPE(AutoMarkingWrappedNativeTearOffPtr, XPCWrappedNativeTearOff)
    4135         8273463 : DEFINE_AUTO_MARKING_PTR_TYPE(AutoMarkingWrappedNativeProtoPtr, XPCWrappedNativeProto)
    4136        31555029 : DEFINE_AUTO_MARKING_PTR_TYPE(AutoMarkingJSVal, XPCMarkableJSVal)
    4137                 : 
    4138                 : #define DEFINE_AUTO_MARKING_ARRAY_PTR_TYPE(class_, type_)                     \
    4139                 : class class_ : public AutoMarkingPtr                                          \
    4140                 : {                                                                             \
    4141                 : public:                                                                       \
    4142                 :     class_ (XPCCallContext& ccx)                                              \
    4143                 :         : AutoMarkingPtr(ccx), mPtr(nsnull), mCount(0) {}                     \
    4144                 :     class_ (XPCCallContext& ccx, type_** aPtr, PRUint32 aCount,               \
    4145                 :             bool aClear = false)                                              \
    4146                 :         : AutoMarkingPtr(ccx), mPtr(aPtr), mCount(aCount)                     \
    4147                 :     {                                                                         \
    4148                 :         if (!mPtr) mCount = 0;                                                \
    4149                 :         else if (aClear) memset(mPtr, 0, mCount*sizeof(type_*));              \
    4150                 :     }                                                                         \
    4151                 :     virtual ~ class_ () {}                                                    \
    4152                 :                                                                               \
    4153                 :     virtual void TraceJS(JSTracer* trc)                                       \
    4154                 :     {                                                                         \
    4155                 :         for (PRUint32 i = 0; i < mCount; ++i) {                               \
    4156                 :             type_* cur = mPtr[i];                                             \
    4157                 :             if (cur) {                                                        \
    4158                 :                 cur->TraceJS(trc);                                            \
    4159                 :                 cur->AutoTrace(trc);                                          \
    4160                 :             }                                                                 \
    4161                 :         }                                                                     \
    4162                 :         if (mNext) mNext->TraceJS(trc);                                       \
    4163                 :     }                                                                         \
    4164                 :                                                                               \
    4165                 :     virtual void MarkAfterJSFinalize()                                        \
    4166                 :     {                                                                         \
    4167                 :         for (PRUint32 i = 0; i < mCount; ++i) {                               \
    4168                 :             type_* cur = mPtr[i];                                             \
    4169                 :             if (cur)                                                          \
    4170                 :                 cur->Mark();                                                  \
    4171                 :         }                                                                     \
    4172                 :         if (mNext) mNext->MarkAfterJSFinalize();                              \
    4173                 :     }                                                                         \
    4174                 :                                                                               \
    4175                 :     type_ ** get()       const  {return mPtr;}                                \
    4176                 :     operator type_ **()  const  {return mPtr;}                                \
    4177                 :     type_ ** operator->() const  {return mPtr;}                               \
    4178                 :                                                                               \
    4179                 :     class_ & operator =(const class_ & inst)                                  \
    4180                 :         {mPtr = inst.mPtr; mCount = inst.mCount; return *this;}               \
    4181                 :                                                                               \
    4182                 : protected:                                                                    \
    4183                 :     type_ ** mPtr;                                                            \
    4184                 :     PRUint32 mCount;                                                          \
    4185                 : };
    4186                 : 
    4187         1434832 : DEFINE_AUTO_MARKING_ARRAY_PTR_TYPE(AutoMarkingNativeInterfacePtrArrayPtr,
    4188                 :                                    XPCNativeInterface)
    4189                 : 
    4190                 : // Note: It looked like I would need one of these AutoMarkingPtr types for
    4191                 : // XPCNativeScriptableInfo in order to manage marking its
    4192                 : // XPCNativeScriptableShared member during construction. But AFAICT we build
    4193                 : // these and bind them to rooted things so immediately that this just is not
    4194                 : // needed.
    4195                 : 
    4196                 : #define AUTO_MARK_JSVAL_HELPER2(tok, line) tok##line
    4197                 : #define AUTO_MARK_JSVAL_HELPER(tok, line) AUTO_MARK_JSVAL_HELPER2(tok, line)
    4198                 : 
    4199                 : #define AUTO_MARK_JSVAL(ccx, val)                                             \
    4200                 :     XPCMarkableJSVal AUTO_MARK_JSVAL_HELPER(_val_,__LINE__)(val);             \
    4201                 :     AutoMarkingJSVal AUTO_MARK_JSVAL_HELPER(_automarker_,__LINE__)            \
    4202                 :     (ccx, &AUTO_MARK_JSVAL_HELPER(_val_,__LINE__))
    4203                 : 
    4204                 : /***************************************************************************/
    4205                 : // Allocates a string that grants all access ("AllAccess")
    4206                 : 
    4207                 : extern char* xpc_CloneAllAccess();
    4208                 : /***************************************************************************/
    4209                 : // Returns access if wideName is in list
    4210                 : 
    4211                 : extern char * xpc_CheckAccessList(const PRUnichar* wideName, const char* list[]);
    4212                 : 
    4213                 : /***************************************************************************/
    4214                 : // in xpcvariant.cpp...
    4215                 : 
    4216                 : // {1809FD50-91E8-11d5-90F9-0010A4E73D9A}
    4217                 : #define XPCVARIANT_IID                                                        \
    4218                 :     {0x1809fd50, 0x91e8, 0x11d5,                                              \
    4219                 :       { 0x90, 0xf9, 0x0, 0x10, 0xa4, 0xe7, 0x3d, 0x9a } }
    4220                 : 
    4221                 : // {DC524540-487E-4501-9AC7-AAA784B17C1C}
    4222                 : #define XPCVARIANT_CID                                                        \
    4223                 :     {0xdc524540, 0x487e, 0x4501,                                              \
    4224                 :       { 0x9a, 0xc7, 0xaa, 0xa7, 0x84, 0xb1, 0x7c, 0x1c } }
    4225                 : 
    4226                 : class XPCVariant : public nsIVariant
    4227                 : {
    4228                 : public:
    4229             362 :     NS_DECL_CYCLE_COLLECTING_ISUPPORTS
    4230                 :     NS_DECL_NSIVARIANT
    4231           32340 :     NS_DECL_CYCLE_COLLECTION_CLASS(XPCVariant)
    4232                 : 
    4233                 :     // If this class ever implements nsIWritableVariant, take special care with
    4234                 :     // the case when mJSVal is JSVAL_STRING, since we don't own the data in
    4235                 :     // that case.
    4236                 : 
    4237                 :     // We #define and iid so that out module local code can use QI to detect
    4238                 :     // if a given nsIVariant is in fact an XPCVariant.
    4239                 :     NS_DECLARE_STATIC_IID_ACCESSOR(XPCVARIANT_IID)
    4240                 : 
    4241                 :     static XPCVariant* newVariant(XPCCallContext& ccx, jsval aJSVal);
    4242                 : 
    4243                 :     /**
    4244                 :      * This getter clears the gray bit before handing out the jsval if the jsval
    4245                 :      * represents a JSObject. That means that the object is guaranteed to be
    4246                 :      * kept alive past the next CC.
    4247                 :      */
    4248            8004 :     jsval GetJSVal() const
    4249            8004 :         {if (!JSVAL_IS_PRIMITIVE(mJSVal))
    4250            1537 :              xpc_UnmarkGrayObject(JSVAL_TO_OBJECT(mJSVal));
    4251            8004 :          return mJSVal;}
    4252                 : 
    4253                 :     /**
    4254                 :      * This getter does not change the color of the jsval (if it represents a
    4255                 :      * JSObject) meaning that the value returned is not guaranteed to be kept
    4256                 :      * alive past the next CC.
    4257                 :      *
    4258                 :      * This should only be called if you are certain that the return value won't
    4259                 :      * be passed into a JS API function and that it won't be stored without
    4260                 :      * being rooted (or otherwise signaling the stored value to the CC).
    4261                 :      */
    4262            4537 :     jsval GetJSValPreserveColor() const {return mJSVal;}
    4263                 : 
    4264                 :     XPCVariant(XPCCallContext& ccx, jsval aJSVal);
    4265                 : 
    4266                 :     /**
    4267                 :      * Convert a variant into a jsval.
    4268                 :      *
    4269                 :      * @param ccx the context for the whole procedure
    4270                 :      * @param variant the variant to convert
    4271                 :      * @param scope the default scope to put on the new JSObject's parent chain
    4272                 :      * @param pErr [out] relevant error code, if any.
    4273                 :      * @param pJSVal [out] the resulting jsval.
    4274                 :      */
    4275                 :     static JSBool VariantDataToJS(XPCLazyCallContext& lccx,
    4276                 :                                   nsIVariant* variant,
    4277                 :                                   nsresult* pErr, jsval* pJSVal);
    4278                 : 
    4279               0 :     bool IsPurple()
    4280                 :     {
    4281               0 :         return mRefCnt.IsPurple();
    4282                 :     }
    4283                 : 
    4284               0 :     void RemovePurple()
    4285                 :     {
    4286               0 :         mRefCnt.RemovePurple();
    4287               0 :     }
    4288                 : 
    4289               0 :     void SetCCGeneration(PRUint32 aGen)
    4290                 :     {
    4291               0 :         mCCGeneration = aGen;
    4292               0 :     }
    4293                 : 
    4294             160 :     PRUint32 CCGeneration() { return mCCGeneration; }
    4295                 : protected:
    4296           19136 :     virtual ~XPCVariant() { }
    4297                 : 
    4298                 :     JSBool InitializeData(XPCCallContext& ccx);
    4299                 : 
    4300                 : protected:
    4301                 :     nsDiscriminatedUnion mData;
    4302                 :     jsval                mJSVal;
    4303                 :     bool                 mReturnRawObject : 1;
    4304                 :     PRUint32             mCCGeneration : 31;
    4305                 : };
    4306                 : 
    4307                 : NS_DEFINE_STATIC_IID_ACCESSOR(XPCVariant, XPCVARIANT_IID)
    4308                 : 
    4309                 : class XPCTraceableVariant: public XPCVariant,
    4310                 :                            public XPCRootSetElem
    4311                 : {
    4312                 : public:
    4313            3464 :     XPCTraceableVariant(XPCCallContext& ccx, jsval aJSVal)
    4314            3464 :         : XPCVariant(ccx, aJSVal)
    4315                 :     {
    4316            3464 :         ccx.GetRuntime()->AddVariantRoot(this);
    4317            3464 :     }
    4318                 : 
    4319                 :     virtual ~XPCTraceableVariant();
    4320                 : 
    4321                 :     void TraceJS(JSTracer* trc);
    4322                 : #ifdef DEBUG
    4323                 :     static void PrintTraceName(JSTracer* trc, char *buf, size_t bufsize);
    4324                 : #endif
    4325                 : };
    4326                 : 
    4327                 : /***************************************************************************/
    4328                 : 
    4329                 : #define PRINCIPALHOLDER_IID \
    4330                 : {0xbf109f49, 0xf94a, 0x43d8, {0x93, 0xdb, 0xe4, 0x66, 0x49, 0xc5, 0xd9, 0x7d}}
    4331                 : 
    4332                 : class PrincipalHolder : public nsIScriptObjectPrincipal
    4333                 : {
    4334                 : public:
    4335                 :     NS_DECLARE_STATIC_IID_ACCESSOR(PRINCIPALHOLDER_IID)
    4336                 : 
    4337            1667 :     PrincipalHolder(nsIPrincipal *holdee)
    4338            1667 :         : mHoldee(holdee)
    4339                 :     {
    4340            1667 :     }
    4341            6664 :     virtual ~PrincipalHolder() { }
    4342                 : 
    4343                 :     NS_DECL_ISUPPORTS
    4344                 : 
    4345                 :     nsIPrincipal *GetPrincipal();
    4346                 : 
    4347                 : private:
    4348                 :     nsCOMPtr<nsIPrincipal> mHoldee;
    4349                 : };
    4350                 : 
    4351                 : NS_DEFINE_STATIC_IID_ACCESSOR(PrincipalHolder, PRINCIPALHOLDER_IID)
    4352                 : 
    4353                 : /***************************************************************************/
    4354                 : // Utilities
    4355                 : 
    4356                 : inline void *
    4357         9807467 : xpc_GetJSPrivate(JSObject *obj)
    4358                 : {
    4359         9807467 :     return js::GetObjectPrivate(obj);
    4360                 : }
    4361                 : 
    4362                 : 
    4363                 : // Helper for creating a sandbox object to use for evaluating
    4364                 : // untrusted code completely separated from all other code in the
    4365                 : // system using xpc_EvalInSandbox(). Takes the JSContext on which to
    4366                 : // do setup etc on, puts the sandbox object in *vp (which must be
    4367                 : // rooted by the caller), and uses the principal that's either
    4368                 : // directly passed in prinOrSop or indirectly as an
    4369                 : // nsIScriptObjectPrincipal holding the principal. If no principal is
    4370                 : // reachable through prinOrSop, a new null principal will be created
    4371                 : // and used.
    4372                 : nsresult
    4373                 : xpc_CreateSandboxObject(JSContext * cx, jsval * vp, nsISupports *prinOrSop,
    4374                 :                         JSObject *proto, bool preferXray, const nsACString &sandboxName,
    4375                 :                         nsISupports *identityPtr = nsnull);
    4376                 : // Helper for evaluating scripts in a sandbox object created with
    4377                 : // xpc_CreateSandboxObject(). The caller is responsible of ensuring
    4378                 : // that *rval doesn't get collected during the call or usage after the
    4379                 : // call. This helper will use filename and lineNo for error reporting,
    4380                 : // and if no filename is provided it will use the codebase from the
    4381                 : // principal and line number 1 as a fallback. if returnStringOnly is
    4382                 : // true, then the result in *rval, or the exception in cx->exception
    4383                 : // will be coerced into strings. If an exception is thrown converting
    4384                 : // an exception to a string, evalInSandbox will return an NS_ERROR_*
    4385                 : // result, and cx->exception will be empty.
    4386                 : nsresult
    4387                 : xpc_EvalInSandbox(JSContext *cx, JSObject *sandbox, const nsAString& source,
    4388                 :                   const char *filename, PRInt32 lineNo,
    4389                 :                   JSVersion jsVersion, bool returnStringOnly, jsval *rval);
    4390                 : 
    4391                 : /***************************************************************************/
    4392                 : // Inlined utilities.
    4393                 : 
    4394                 : inline JSBool
    4395                 : xpc_ForcePropertyResolve(JSContext* cx, JSObject* obj, jsid id);
    4396                 : 
    4397                 : inline jsid
    4398                 : GetRTIdByIndex(JSContext *cx, unsigned index);
    4399                 : 
    4400                 : // Wrapper for JS_NewObject to mark the new object as system when parent is
    4401                 : // also a system object. If uniqueType is specified then a new type object will
    4402                 : // be created which is used only by the result, so that its property types
    4403                 : // will be tracked precisely.
    4404                 : inline JSObject*
    4405                 : xpc_NewSystemInheritingJSObject(JSContext *cx, JSClass *clasp, JSObject *proto,
    4406                 :                                 bool uniqueType, JSObject *parent);
    4407                 : 
    4408                 : nsISupports *
    4409                 : XPC_GetIdentityObject(JSContext *cx, JSObject *obj);
    4410                 : 
    4411                 : namespace xpc {
    4412                 : 
    4413                 : struct CompartmentPrivate
    4414                 : {
    4415            3304 :     CompartmentPrivate(PtrAndPrincipalHashKey *key, bool wantXrays)
    4416                 :         : key(key),
    4417            3304 :           wantXrays(wantXrays)
    4418                 :     {
    4419            3304 :         MOZ_COUNT_CTOR(xpc::CompartmentPrivate);
    4420            3304 :     }
    4421                 : 
    4422                 :     ~CompartmentPrivate();
    4423                 : 
    4424                 :     nsAutoPtr<PtrAndPrincipalHashKey> key;
    4425                 :     bool wantXrays;
    4426                 :     nsAutoPtr<JSObject2JSObjectMap> waiverWrapperMap;
    4427                 :     // NB: we don't want this map to hold a strong reference to the wrapper.
    4428                 :     nsAutoPtr<nsDataHashtable<nsPtrHashKey<XPCWrappedNative>, JSObject *> > expandoMap;
    4429                 :     nsAutoPtr<nsTHashtable<nsPtrHashKey<JSObject> > > domExpandoMap;
    4430                 :     nsCString location;
    4431                 : 
    4432               0 :     bool RegisterExpandoObject(XPCWrappedNative *wn, JSObject *expando) {
    4433               0 :         if (!expandoMap) {
    4434               0 :             expandoMap = new nsDataHashtable<nsPtrHashKey<XPCWrappedNative>, JSObject *>();
    4435               0 :             if (!expandoMap->Init(8)) {
    4436               0 :                 expandoMap = nsnull;
    4437               0 :                 return false;
    4438                 :             }
    4439                 :         }
    4440               0 :         wn->SetHasExpandoObject();
    4441               0 :         return expandoMap->Put(wn, expando);
    4442                 :     }
    4443                 : 
    4444                 :     /**
    4445                 :      * This lookup does not change the color of the JSObject meaning that the
    4446                 :      * object returned is not guaranteed to be kept alive past the next CC.
    4447                 :      *
    4448                 :      * This should only be called if you are certain that the return value won't
    4449                 :      * be passed into a JS API function and that it won't be stored without
    4450                 :      * being rooted (or otherwise signaling the stored value to the CC).
    4451                 :      */
    4452               0 :     JSObject *LookupExpandoObjectPreserveColor(XPCWrappedNative *wn) {
    4453               0 :         return expandoMap ? expandoMap->Get(wn) : nsnull;
    4454                 :     }
    4455                 : 
    4456                 :     /**
    4457                 :      * This lookup clears the gray bit before handing out the JSObject which
    4458                 :      * means that the object is guaranteed to be kept alive past the next CC.
    4459                 :      */
    4460               0 :     JSObject *LookupExpandoObject(XPCWrappedNative *wn) {
    4461               0 :         JSObject *obj = LookupExpandoObjectPreserveColor(wn);
    4462               0 :         xpc_UnmarkGrayObject(obj);
    4463               0 :         return obj;
    4464                 :     }
    4465                 : 
    4466               0 :     bool RegisterDOMExpandoObject(JSObject *expando) {
    4467               0 :         if (!domExpandoMap) {
    4468               0 :             domExpandoMap = new nsTHashtable<nsPtrHashKey<JSObject> >();
    4469               0 :             if (!domExpandoMap->Init(8)) {
    4470               0 :                 domExpandoMap = nsnull;
    4471               0 :                 return false;
    4472                 :             }
    4473                 :         }
    4474               0 :         return domExpandoMap->PutEntry(expando);
    4475                 :     }
    4476               0 :     void RemoveDOMExpandoObject(JSObject *expando) {
    4477               0 :         if (domExpandoMap)
    4478               0 :             domExpandoMap->RemoveEntry(expando);
    4479               0 :     }
    4480                 : };
    4481                 : 
    4482                 : }
    4483                 : 
    4484                 : /***************************************************************************/
    4485                 : // Inlines use the above - include last.
    4486                 : 
    4487                 : #include "XPCInlines.h"
    4488                 : 
    4489                 : /***************************************************************************/
    4490                 : // Maps have inlines that use the above - include last.
    4491                 : 
    4492                 : #include "XPCMaps.h"
    4493                 : 
    4494                 : /***************************************************************************/
    4495                 : 
    4496                 : #endif /* xpcprivate_h___ */

Generated by: LCOV version 1.7