Back to index

lightning-sunbird  0.9+nobinonly
xpcprivate.h
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
00002  * vim: set ts=8 sw=4 et tw=78:
00003  *
00004  * ***** BEGIN LICENSE BLOCK *****
00005  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00006  *
00007  * The contents of this file are subject to the Mozilla Public License Version
00008  * 1.1 (the "License"); you may not use this file except in compliance with
00009  * the License. You may obtain a copy of the License at
00010  * http://www.mozilla.org/MPL/
00011  *
00012  * Software distributed under the License is distributed on an "AS IS" basis,
00013  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00014  * for the specific language governing rights and limitations under the
00015  * License.
00016  *
00017  * The Original Code is Mozilla Communicator client code, released
00018  * March 31, 1998.
00019  *
00020  * The Initial Developer of the Original Code is
00021  * Netscape Communications Corporation.
00022  * Portions created by the Initial Developer are Copyright (C) 1998
00023  * the Initial Developer. All Rights Reserved.
00024  *
00025  * Contributor(s):
00026  *   John Bandhauer <jband@netscape.com> (original author)
00027  *   Mike Shaver <shaver@mozilla.org>
00028  *   Mark Hammond <MarkH@ActiveState.com>
00029  *
00030  * Alternatively, the contents of this file may be used under the terms of
00031  * either of the GNU General Public License Version 2 or later (the "GPL"),
00032  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00033  * in which case the provisions of the GPL or the LGPL are applicable instead
00034  * of those above. If you wish to allow use of your version of this file only
00035  * under the terms of either the GPL or the LGPL, and not to allow others to
00036  * use your version of this file under the terms of the MPL, indicate your
00037  * decision by deleting the provisions above and replace them with the notice
00038  * and other provisions required by the GPL or the LGPL. If you do not delete
00039  * the provisions above, a recipient may use your version of this file under
00040  * the terms of any one of the MPL, the GPL or the LGPL.
00041  *
00042  * ***** END LICENSE BLOCK ***** */
00043 
00044 /* All the XPConnect private declarations - only include locally. */
00045 
00046 #ifndef xpcprivate_h___
00047 #define xpcprivate_h___
00048 
00049 #include <string.h>
00050 #include <stdlib.h>
00051 #include <stdarg.h>
00052 #include <math.h>
00053 #include "nscore.h"
00054 #include "nsXPCOM.h"
00055 #include "nsAutoPtr.h"
00056 #include "nsISupports.h"
00057 #include "nsIServiceManager.h"
00058 #include "nsIClassInfo.h"
00059 #include "nsIComponentManager.h"
00060 #include "nsIComponentRegistrar.h"
00061 #include "nsISupportsPrimitives.h"
00062 #include "nsIGenericFactory.h"
00063 #include "nsMemory.h"
00064 #include "nsIXPConnect.h"
00065 #include "nsIInterfaceInfo.h"
00066 #include "nsIInterfaceInfoManager.h"
00067 #include "nsIXPCScriptable.h"
00068 #include "nsIXPCSecurityManager.h"
00069 #include "nsIJSRuntimeService.h"
00070 #include "nsWeakReference.h"
00071 #include "nsCOMPtr.h"
00072 #include "nsIModule.h"
00073 #include "nsAutoLock.h"
00074 #include "xptcall.h"
00075 #include "jsapi.h"
00076 #include "jsdhash.h"
00077 #include "jsprf.h"
00078 #include "prprf.h"
00079 #include "jsinterp.h"
00080 #include "jscntxt.h"
00081 #include "jsdbgapi.h"
00082 #include "jsgc.h"
00083 #include "xptinfo.h"
00084 #include "xpcforwards.h"
00085 #include "xpclog.h"
00086 #include "xpccomponents.h"
00087 #include "xpcexception.h"
00088 #include "xpcjsid.h"
00089 #include "prlong.h"
00090 #include "prmem.h"
00091 #include "prenv.h"
00092 #include "nsString.h"
00093 #include "nsReadableUtils.h"
00094 #include "nsXPIDLString.h"
00095 
00096 #include "nsIThread.h"
00097 #include "nsIJSContextStack.h"
00098 #include "prthread.h"
00099 #include "nsDeque.h"
00100 #include "nsVoidArray.h"
00101 
00102 #include "nsIConsoleService.h"
00103 #include "nsIScriptError.h"
00104 #include "nsIExceptionService.h"
00105 
00106 #include "nsVariant.h"
00107 #include "nsIPropertyBag.h"
00108 #include "nsIProperty.h"
00109 #include "nsSupportsArray.h"
00110 #include "nsTArray.h"
00111 
00112 #include "nsIXPCScriptNotify.h"  // used to notify: ScriptEvaluated
00113 #ifndef XPCONNECT_STANDALONE
00114 #define XPC_USE_SECURITY_CHECKED_COMPONENT
00115 #endif
00116 
00117 #ifdef XPC_USE_SECURITY_CHECKED_COMPONENT
00118 #include "nsISecurityCheckedComponent.h"
00119 #endif
00120 
00121 #ifdef XPC_TOOLS_SUPPORT
00122 #include "nsIXPCToolsProfiler.h"
00123 #endif
00124 
00125 #include "nsIEventQueueListener.h"
00126 
00127 #ifdef XPC_IDISPATCH_SUPPORT
00128 // This goop was added because of EXCEPINFO in ThrowCOMError
00129 // This include is here, because it needs to occur before the undefines below
00130 #include <atlbase.h>
00131 #include "oaidl.h"
00132 // Nasty MS defines
00133 #undef GetClassInfo
00134 #undef GetClassName
00135 #undef GetMessage
00136 #endif
00137 
00138 /***************************************************************************/
00139 // Compile time switches for instrumentation and stuff....
00140 
00141 // Note that one would not normally turn *any* of these on in a non-DEBUG build.
00142 
00143 #if defined(DEBUG_jband) || defined(DEBUG_jst) || defined(DEBUG_dbradley) || defined(DEBUG_shaver_no) || defined(DEBUG_timeless)
00144 #define DEBUG_xpc_hacker
00145 #endif
00146 
00147 #if defined(DEBUG_brendan) || defined(DEBUG_bzbarsky)
00148 #define DEBUG_XPCNativeWrapper 1
00149 #endif
00150 
00151 #ifdef DEBUG
00152 #define XPC_DETECT_LEADING_UPPERCASE_ACCESS_ERRORS
00153 #define XPC_CHECK_WRAPPER_THREADSAFETY
00154 #endif
00155 
00156 #if defined(DEBUG_xpc_hacker)
00157 #define XPC_DUMP_AT_SHUTDOWN
00158 #define XPC_TRACK_WRAPPER_STATS
00159 #define XPC_TRACK_SCOPE_STATS
00160 #define XPC_TRACK_PROTO_STATS
00161 #define XPC_TRACK_DEFERRED_RELEASES
00162 #define XPC_CHECK_WRAPPERS_AT_SHUTDOWN
00163 #define XPC_REPORT_SHADOWED_WRAPPED_NATIVE_MEMBERS
00164 #define XPC_CHECK_CLASSINFO_CLAIMS
00165 #if defined(DEBUG_jst)
00166 #define XPC_ASSERT_CLASSINFO_CLAIMS
00167 #endif
00168 //#define DEBUG_stats_jband 1
00169 //#define XPC_REPORT_NATIVE_INTERFACE_AND_SET_FLUSHING
00170 //#define XPC_REPORT_JSCLASS_FLUSHING
00171 //#define XPC_TRACK_AUTOMARKINGPTR_STATS
00172 #endif
00173 
00174 #if defined(DEBUG_dbaron) // only part of DEBUG_xpc_hacker!
00175 #define XPC_DUMP_AT_SHUTDOWN
00176 #endif
00177 
00178 /***************************************************************************/
00179 // conditional forward declarations....
00180 
00181 #ifdef XPC_REPORT_SHADOWED_WRAPPED_NATIVE_MEMBERS
00182 void DEBUG_ReportShadowedMembers(XPCNativeSet* set,
00183                                  XPCWrappedNative* wrapper,
00184                                  XPCWrappedNativeProto* proto);
00185 #else
00186 #define DEBUG_ReportShadowedMembers(set, wrapper, proto) ((void)0)
00187 #endif
00188 
00189 #ifdef XPC_CHECK_WRAPPER_THREADSAFETY
00190 void DEBUG_ReportWrapperThreadSafetyError(XPCCallContext& ccx,
00191                                           const char* msg,
00192                                           const XPCWrappedNative* wrapper);
00193 void DEBUG_CheckWrapperThreadSafety(const XPCWrappedNative* wrapper);
00194 #else
00195 #define DEBUG_CheckWrapperThreadSafety(w) ((void)0)
00196 #endif
00197 
00198 /***************************************************************************/
00199 
00200 // Defeat possible Windows macro-mangling of the name
00201 #ifdef GetClassInfo
00202 #undef GetClassInfo
00203 #endif
00204 
00205 /***************************************************************************/
00206 // default initial sizes for maps (hashtables)
00207 
00208 #define XPC_CONTEXT_MAP_SIZE                16
00209 #define XPC_JS_MAP_SIZE                     64
00210 #define XPC_JS_CLASS_MAP_SIZE               64
00211 
00212 #define XPC_NATIVE_MAP_SIZE                 64
00213 #define XPC_NATIVE_PROTO_MAP_SIZE           16
00214 #define XPC_DYING_NATIVE_PROTO_MAP_SIZE     16
00215 #define XPC_DETACHED_NATIVE_PROTO_MAP_SIZE  32
00216 #define XPC_NATIVE_INTERFACE_MAP_SIZE       64
00217 #define XPC_NATIVE_SET_MAP_SIZE             64
00218 #define XPC_NATIVE_JSCLASS_MAP_SIZE         32
00219 #define XPC_THIS_TRANSLATOR_MAP_SIZE         8
00220 #define XPC_NATIVE_WRAPPER_MAP_SIZE         16
00221 
00222 /***************************************************************************/
00223 // data declarations...
00224 extern const char* XPC_ARG_FORMATTER_FORMAT_STRINGS[]; // format strings
00225 extern const char XPC_CONTEXT_STACK_CONTRACTID[];
00226 extern const char XPC_RUNTIME_CONTRACTID[];
00227 extern const char XPC_EXCEPTION_CONTRACTID[];
00228 extern const char XPC_CONSOLE_CONTRACTID[];
00229 extern const char XPC_SCRIPT_ERROR_CONTRACTID[];
00230 extern const char XPC_ID_CONTRACTID[];
00231 extern const char XPC_XPCONNECT_CONTRACTID[];
00232 
00233 /***************************************************************************/
00234 // useful macros...
00235 
00236 #define XPC_STRING_GETTER_BODY(dest, src) \
00237     NS_ENSURE_ARG_POINTER(dest); \
00238     char* result; \
00239     if(src) \
00240         result = (char*) nsMemory::Clone(src, \
00241                                 sizeof(char)*(strlen(src)+1)); \
00242     else \
00243         result = nsnull; \
00244     *dest = result; \
00245     return (result || !src) ? NS_OK : NS_ERROR_OUT_OF_MEMORY
00246 
00247 /***************************************************************************/
00248 // Auto locking support class...
00249 
00250 // We PROMISE to never screw this up.
00251 #ifdef _MSC_VER
00252 #pragma warning(disable : 4355) // OK to pass "this" in member initializer
00253 #endif
00254 
00255 typedef PRMonitor XPCLock;
00256 
00257 static inline void xpc_Wait(XPCLock* lock) 
00258     {
00259         NS_ASSERTION(lock, "xpc_Wait called with null lock!");
00260 #ifdef DEBUG
00261         PRStatus result = 
00262 #endif
00263         PR_Wait(lock, PR_INTERVAL_NO_TIMEOUT);
00264         NS_ASSERTION(PR_SUCCESS == result, "bad result from PR_Wait!");
00265     }
00266 
00267 static inline void xpc_NotifyAll(XPCLock* lock) 
00268     {
00269         NS_ASSERTION(lock, "xpc_NotifyAll called with null lock!");
00270 #ifdef DEBUG
00271         PRStatus result = 
00272 #endif    
00273         PR_NotifyAll(lock);
00274         NS_ASSERTION(PR_SUCCESS == result, "bad result from PR_NotifyAll!");
00275     }
00276 
00277 // This is a cloned subset of nsAutoMonitor. We want the use of a monitor -
00278 // mostly because we need reenterability - but we also want to support passing
00279 // a null monitor in without things blowing up. This is used for wrappers that
00280 // are guaranteed to be used only on one thread. We avoid lock overhead by
00281 // using a null monitor. By changing this class we can avoid having multiplte
00282 // code paths or (conditional) manual calls to PR_{Enter,Exit}Monitor.
00283 //
00284 // Note that xpconnect only makes *one* monitor and *mostly* holds it locked
00285 // only through very small critical sections.
00286 
00287 class XPCAutoLock : public nsAutoLockBase {
00288 public:
00289 
00290     static XPCLock* NewLock(const char* name)
00291                         {return nsAutoMonitor::NewMonitor(name);}
00292     static void     DestroyLock(XPCLock* lock)
00293                         {nsAutoMonitor::DestroyMonitor(lock);}
00294 
00295     XPCAutoLock(XPCLock* lock)
00296 #ifdef DEBUG
00297         : nsAutoLockBase(lock ? (void*) lock : (void*) this, eAutoMonitor),
00298 #else
00299         : nsAutoLockBase(lock, eAutoMonitor),
00300 #endif
00301           mLock(lock)
00302     {
00303         if(mLock)
00304             PR_EnterMonitor(mLock);
00305     }
00306 
00307     ~XPCAutoLock()
00308     {
00309         if(mLock)
00310         {
00311 #ifdef DEBUG
00312             PRStatus status =
00313 #endif
00314                 PR_ExitMonitor(mLock);
00315             NS_ASSERTION(status == PR_SUCCESS, "PR_ExitMonitor failed");
00316         }
00317     }
00318 
00319 private:
00320     XPCLock*  mLock;
00321 
00322     // Not meant to be implemented. This makes it a compiler error to
00323     // construct or assign an XPCAutoLock object incorrectly.
00324     XPCAutoLock(void) {}
00325     XPCAutoLock(XPCAutoLock& /*aMon*/) {}
00326     XPCAutoLock& operator =(XPCAutoLock& /*aMon*/) {
00327         return *this;
00328     }
00329 
00330     // Not meant to be implemented. This makes it a compiler error to
00331     // attempt to create an XPCAutoLock object on the heap.
00332     static void* operator new(size_t /*size*/) CPP_THROW_NEW {
00333         return nsnull;
00334     }
00335     static void operator delete(void* /*memory*/) {}
00336 };
00337 
00338 /************************************************/
00339 
00340 class XPCAutoUnlock : public nsAutoUnlockBase {
00341 public:
00342     XPCAutoUnlock(XPCLock* lock)
00343         : nsAutoUnlockBase(lock),
00344           mLock(lock)
00345     {
00346         if(mLock)
00347         {
00348 #ifdef DEBUG
00349             PRStatus status =
00350 #endif
00351                 PR_ExitMonitor(mLock);
00352             NS_ASSERTION(status == PR_SUCCESS, "PR_ExitMonitor failed");
00353         }
00354     }
00355 
00356     ~XPCAutoUnlock()
00357     {
00358         if(mLock)
00359             PR_EnterMonitor(mLock);
00360     }
00361 
00362 private:
00363     XPCLock*  mLock;
00364 
00365     // Not meant to be implemented. This makes it a compiler error to
00366     // construct or assign an XPCAutoUnlock object incorrectly.
00367     XPCAutoUnlock(void) {}
00368     XPCAutoUnlock(XPCAutoUnlock& /*aMon*/) {}
00369     XPCAutoUnlock& operator =(XPCAutoUnlock& /*aMon*/) {
00370         return *this;
00371     }
00372 
00373     // Not meant to be implemented. This makes it a compiler error to
00374     // attempt to create an XPCAutoUnlock object on the heap.
00375     static void* operator new(size_t /*size*/) CPP_THROW_NEW {
00376         return nsnull;
00377     }
00378     static void operator delete(void* /*memory*/) {}
00379 };
00380 
00381 // A helper class to deal with temporary JS contexts. It destroys the context
00382 // when it goes out of scope.
00383 class XPCAutoJSContext
00384 {
00385 public:
00386     XPCAutoJSContext(JSContext *aContext, PRBool aGCOnDestroy)
00387         : mContext(aContext), mGCOnDestroy(aGCOnDestroy)
00388     {
00389     }
00390 
00391     ~XPCAutoJSContext()
00392     {
00393         if(!mContext)
00394             return;
00395 
00396         if(mGCOnDestroy)
00397             JS_DestroyContext(mContext);
00398         else
00399             JS_DestroyContextNoGC(mContext);
00400     }
00401 
00402     operator JSContext * () {return mContext;}
00403 
00404 private:
00405     JSContext *mContext;
00406     PRBool mGCOnDestroy;
00407 };
00408 
00409 /***************************************************************************
00410 ****************************************************************************
00411 *
00412 * Core runtime and context classes...
00413 *
00414 ****************************************************************************
00415 ***************************************************************************/
00416 
00417 // We have a general rule internally that getters that return addref'd interface
00418 // pointer generally do so using an 'out' parm. When interface pointers are
00419 // returned as function call result values they are not addref'd. Exceptions
00420 // to this rule are noted explicitly.
00421 
00422 const PRBool OBJ_IS_GLOBAL = PR_TRUE;
00423 const PRBool OBJ_IS_NOT_GLOBAL = PR_FALSE;
00424 
00425 class nsXPConnect : public nsIXPConnect_MOZILLA_1_8_BRANCH2,
00426                     public nsIEventQueueListener,
00427                     public nsSupportsWeakReference
00428 {
00429 public:
00430     // all the interface method declarations...
00431     NS_DECL_ISUPPORTS
00432     NS_DECL_NSIXPCONNECT
00433     NS_DECL_NSIXPCONNECT_MOZILLA_1_8_BRANCH
00434     NS_DECL_NSIXPCONNECT_MOZILLA_1_8_BRANCH2
00435     NS_DECL_NSIEVENTQUEUELISTENER
00436 
00437     // non-interface implementation
00438 public:
00439     // These get non-addref'd pointers
00440     static nsXPConnect*  GetXPConnect();
00441     static XPCJSRuntime* GetRuntime(nsXPConnect* xpc = nsnull);
00442     static XPCContext*   GetContext(JSContext* cx, nsXPConnect* xpc = nsnull);
00443     static nsIJSRuntimeService* GetJSRuntimeService(nsXPConnect* xpc = nsnull);
00444 
00445     // Gets addref'd pointer
00446     static nsresult GetInterfaceInfoManager(nsIInterfaceInfoSuperManager** iim,
00447                                             nsXPConnect* xpc = nsnull);
00448 
00449     // Gets addref'd pointer
00450     static nsresult GetContextStack(nsIThreadJSContextStack** stack,
00451                                     nsXPConnect* xpc = nsnull);
00452 
00453     static JSBool IsISupportsDescendant(nsIInterfaceInfo* info);
00454 
00455     static PRThread* GetMainThread()
00456         {return gMainThread ? gMainThread : FindMainThread();}
00457 
00458     nsIXPCSecurityManager* GetDefaultSecurityManager() const
00459         {return mDefaultSecurityManager;}
00460 
00461     PRUint16 GetDefaultSecurityManagerFlags() const
00462         {return mDefaultSecurityManagerFlags;}
00463 
00464     // This returns an AddRef'd pointer. It does not do this with an 'out' param
00465     // only because this form is required by the generic module macro:
00466     // NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR
00467     static nsXPConnect* GetSingleton();
00468 
00469     // Called by module code in dll startup
00470     static void InitStatics() { gSelf = nsnull; gOnceAliveNowDead = JS_FALSE; }
00471     // Called by module code on dll shutdown.
00472     static void ReleaseXPConnectSingleton();
00473 
00474     virtual ~nsXPConnect();
00475 
00476     JSBool IsShuttingDown() const {return mShuttingDown;}
00477 
00478     nsresult GetInfoForIID(const nsIID * aIID, nsIInterfaceInfo** info);
00479     nsresult GetInfoForName(const char * name, nsIInterfaceInfo** info);
00480 
00481 #ifdef XPC_IDISPATCH_SUPPORT
00482 public:
00483     static PRBool IsIDispatchEnabled();
00484 #endif
00485 protected:
00486     nsXPConnect();
00487 
00488 private:
00489     JSBool EnsureRuntime() {return mRuntime ? JS_TRUE : CreateRuntime();}
00490     JSBool CreateRuntime();
00491 
00492     static PRThread* FindMainThread();
00493 
00494 private:
00495     // Singleton instance
00496     static nsXPConnect*      gSelf;
00497     static JSBool            gOnceAliveNowDead;
00498     static PRThread*         gMainThread;
00499 
00500     XPCJSRuntime*            mRuntime;
00501     nsIInterfaceInfoSuperManager* mInterfaceInfoManager;
00502     nsIThreadJSContextStack* mContextStack;
00503     nsIXPCSecurityManager*   mDefaultSecurityManager;
00504     PRUint16                 mDefaultSecurityManagerFlags;
00505     JSBool                   mShuttingDown;
00506 
00507 #ifdef XPC_TOOLS_SUPPORT
00508     nsCOMPtr<nsIXPCToolsProfiler> mProfiler;
00509     nsCOMPtr<nsILocalFile>        mProfilerOutputFile;
00510 #endif
00511 
00512 };
00513 
00514 /***************************************************************************/
00515 
00516 // In the current xpconnect system there can only be one XPCJSRuntime.
00517 // So, xpconnect can only be used on one JSRuntime within the process.
00518 
00519 // no virtuals. no refcounting.
00520 class XPCJSRuntime
00521 {
00522 public:
00523     static XPCJSRuntime* newXPCJSRuntime(nsXPConnect* aXPConnect,
00524                                          nsIJSRuntimeService* aJSRuntimeService);
00525 
00526     JSRuntime*     GetJSRuntime() const {return mJSRuntime;}
00527     nsXPConnect*   GetXPConnect() const {return mXPConnect;}
00528 
00529     nsIJSRuntimeService* GetJSRuntimeService() const {return mJSRuntimeService;}
00530 
00531     JSObject2WrappedJSMap*     GetWrappedJSMap()        const
00532         {return mWrappedJSMap;}
00533 
00534     IID2WrappedJSClassMap*     GetWrappedJSClassMap()   const
00535         {return mWrappedJSClassMap;}
00536 
00537     IID2NativeInterfaceMap* GetIID2NativeInterfaceMap() const
00538         {return mIID2NativeInterfaceMap;}
00539 
00540     ClassInfo2NativeSetMap* GetClassInfo2NativeSetMap() const
00541         {return mClassInfo2NativeSetMap;}
00542 
00543     NativeSetMap* GetNativeSetMap() const
00544         {return mNativeSetMap;}
00545 
00546     IID2ThisTranslatorMap* GetThisTranslatorMap() const
00547         {return mThisTranslatorMap;}
00548 
00549     XPCNativeScriptableSharedMap* GetNativeScriptableSharedMap() const
00550         {return mNativeScriptableSharedMap;}
00551 
00552     XPCWrappedNativeProtoMap* GetDyingWrappedNativeProtoMap() const
00553         {return mDyingWrappedNativeProtoMap;}
00554 
00555     XPCWrappedNativeProtoMap* GetDetachedWrappedNativeProtoMap() const
00556         {return mDetachedWrappedNativeProtoMap;}
00557 
00558     XPCNativeWrapperMap* GetExplicitNativeWrapperMap() const
00559         {return mExplicitNativeWrapperMap;}
00560 
00561     XPCLock* GetMapLock() const {return mMapLock;}
00562 
00563     XPCContext* GetXPCContext(JSContext* cx);
00564     XPCContext* SyncXPCContextList(JSContext* cx = nsnull);
00565 
00566     JSBool GetMainThreadOnlyGC() const   {return mMainThreadOnlyGC;}
00567     void   SetMainThreadOnlyGC(JSBool b) {mMainThreadOnlyGC = b;}
00568     
00569     JSBool GetDeferReleases() const {return mDeferReleases;}
00570     void   SetDeferReleases(JSBool b) 
00571         {/* If deferring is turned off while any are pending they'll leak! */
00572          NS_ASSERTION((mDeferReleases && b) || 
00573                       !mNativesToReleaseArray.Count(), "bad"); 
00574          mDeferReleases = b;}
00575 
00576     JSBool DeferredRelease(nsISupports* obj);
00577 
00578     JSBool GetDoingFinalization() const {return mDoingFinalization;}
00579 
00580     // Mapping of often used strings to jsid atoms that live 'forever'.
00581     //
00582     // To add a new string: add to this list and to XPCJSRuntime::mStrings
00583     // at the top of xpcjsruntime.cpp
00584     enum {
00585         IDX_CONSTRUCTOR             = 0 ,
00586         IDX_TO_STRING               ,
00587         IDX_TO_SOURCE               ,
00588         IDX_LAST_RESULT             ,
00589         IDX_RETURN_CODE             ,
00590         IDX_VALUE                   ,
00591         IDX_QUERY_INTERFACE         ,
00592         IDX_COMPONENTS              ,
00593         IDX_WRAPPED_JSOBJECT        ,
00594         IDX_OBJECT                  ,
00595         IDX_FUNCTION                ,
00596         IDX_PROTOTYPE               ,
00597         IDX_CREATE_INSTANCE         ,
00598         IDX_ITEM                    ,
00599 #ifdef XPC_IDISPATCH_SUPPORT
00600         IDX_ACTIVEX_OBJECT          ,
00601         IDX_COM_OBJECT              ,
00602         IDX_ACTIVEX_SUPPORTS        ,
00603 #endif
00604         IDX_TOTAL_COUNT // just a count of the above
00605     };
00606 
00607     jsid GetStringID(uintN index) const
00608     {
00609         NS_ASSERTION(index < IDX_TOTAL_COUNT, "index out of range");
00610         return mStrIDs[index];
00611     }
00612     jsval GetStringJSVal(uintN index) const
00613     {
00614         NS_ASSERTION(index < IDX_TOTAL_COUNT, "index out of range");
00615         return mStrJSVals[index];
00616     }
00617     const char* GetStringName(uintN index) const
00618     {
00619         NS_ASSERTION(index < IDX_TOTAL_COUNT, "index out of range");
00620         return mStrings[index];
00621     }
00622 
00623     static JSBool JS_DLL_CALLBACK GCCallback(JSContext *cx, JSGCStatus status);
00624 
00625     void DebugDump(PRInt16 depth);
00626 
00627     void SystemIsBeingShutDown(XPCCallContext* ccx);
00628 
00629     PRThread* GetThreadRunningGC() const {return mThreadRunningGC;}
00630 
00631     ~XPCJSRuntime();
00632 
00633 #ifdef XPC_CHECK_WRAPPERS_AT_SHUTDOWN
00634    void DEBUG_AddWrappedNative(nsIXPConnectWrappedNative* wrapper)
00635         {XPCAutoLock lock(GetMapLock());
00636          JSDHashEntryHdr *entry =
00637             JS_DHashTableOperate(DEBUG_WrappedNativeHashtable,
00638                                  wrapper, JS_DHASH_ADD);
00639          if(entry) ((JSDHashEntryStub *)entry)->key = wrapper;}
00640 
00641    void DEBUG_RemoveWrappedNative(nsIXPConnectWrappedNative* wrapper)
00642         {XPCAutoLock lock(GetMapLock());
00643          JS_DHashTableOperate(DEBUG_WrappedNativeHashtable,
00644                               wrapper, JS_DHASH_REMOVE);}
00645 private:
00646    JSDHashTable* DEBUG_WrappedNativeHashtable;
00647 public:
00648 #endif
00649 
00650 private:
00651     XPCJSRuntime(); // no implementation
00652     XPCJSRuntime(nsXPConnect* aXPConnect,
00653                  nsIJSRuntimeService* aJSRuntimeService);
00654 
00655     JSContext2XPCContextMap*  GetContextMap() const {return mContextMap;}
00656     JSBool GenerateStringIDs(JSContext* cx);
00657     void PurgeXPCContextList();
00658 
00659 private:
00660     static const char* mStrings[IDX_TOTAL_COUNT];
00661     jsid mStrIDs[IDX_TOTAL_COUNT];
00662     jsval mStrJSVals[IDX_TOTAL_COUNT];
00663 
00664     nsXPConnect* mXPConnect;
00665     JSRuntime*  mJSRuntime;
00666     nsIJSRuntimeService* mJSRuntimeService; // hold this to hold the JSRuntime
00667     JSContext2XPCContextMap* mContextMap;
00668     JSObject2WrappedJSMap*   mWrappedJSMap;
00669     IID2WrappedJSClassMap*   mWrappedJSClassMap;
00670     IID2NativeInterfaceMap*  mIID2NativeInterfaceMap;
00671     ClassInfo2NativeSetMap*  mClassInfo2NativeSetMap;
00672     NativeSetMap*            mNativeSetMap;
00673     IID2ThisTranslatorMap*   mThisTranslatorMap;
00674     XPCNativeScriptableSharedMap* mNativeScriptableSharedMap;
00675     XPCWrappedNativeProtoMap* mDyingWrappedNativeProtoMap;
00676     XPCWrappedNativeProtoMap* mDetachedWrappedNativeProtoMap;
00677     XPCNativeWrapperMap*     mExplicitNativeWrapperMap;
00678     XPCLock* mMapLock;
00679     PRThread* mThreadRunningGC;
00680     nsVoidArray mWrappedJSToReleaseArray;
00681     nsVoidArray mNativesToReleaseArray;
00682     JSBool mMainThreadOnlyGC;
00683     JSBool mDeferReleases;
00684     JSBool mDoingFinalization;
00685 };
00686 
00687 /***************************************************************************/
00688 /***************************************************************************/
00689 // XPCContext is mostly a dumb class to hold JSContext specific data and
00690 // maps that let us find wrappers created for the given JSContext.
00691 
00692 // no virtuals
00693 class XPCContext
00694 {
00695 public:
00696     static XPCContext* newXPCContext(XPCJSRuntime* aRuntime,
00697                                      JSContext* aJSContext);
00698 
00699     XPCJSRuntime* GetRuntime() const {return mRuntime;}
00700     JSContext* GetJSContext() const {return mJSContext;}
00701 
00702     enum LangType {LANG_UNKNOWN, LANG_JS, LANG_NATIVE};
00703     
00704     // Mark functions used by SyncXPCContextList
00705     void Mark()             {mMarked = (JSPackedBool) JS_TRUE;}
00706     void Unmark()           {mMarked = (JSPackedBool) JS_FALSE;}
00707     JSBool IsMarked() const {return (JSBool) mMarked;}
00708 
00709     LangType GetCallingLangType() const
00710         {
00711             return mCallingLangType;
00712         }
00713     LangType SetCallingLangType(LangType lt)
00714         {
00715             LangType tmp = mCallingLangType; 
00716             mCallingLangType = lt; 
00717             return tmp;
00718         }
00719     JSBool CallerTypeIsJavaScript() const 
00720         {
00721             return LANG_JS == mCallingLangType;
00722         }
00723     JSBool CallerTypeIsNative() const 
00724         {
00725             return LANG_NATIVE == mCallingLangType;
00726         }
00727     JSBool CallerTypeIsKnown() const 
00728         {
00729             return LANG_UNKNOWN != mCallingLangType;
00730         }
00731 
00732     nsresult GetException(nsIException** e)
00733         {
00734             NS_IF_ADDREF(mException);
00735             *e = mException;
00736             return NS_OK;
00737         }
00738     void SetException(nsIException* e)
00739         {
00740             NS_IF_ADDREF(e);
00741             NS_IF_RELEASE(mException);
00742             mException = e;
00743         }
00744 
00745     nsresult GetLastResult() {return mLastResult;}
00746     void SetLastResult(nsresult rc) {mLastResult = rc;}
00747 
00748     nsresult GetPendingResult() {return mPendingResult;}
00749     void SetPendingResult(nsresult rc) {mPendingResult = rc;}
00750 
00751     nsIXPCSecurityManager* GetSecurityManager() const
00752         {return mSecurityManager;}
00753     void SetSecurityManager(nsIXPCSecurityManager* aSecurityManager)
00754         {mSecurityManager = aSecurityManager;}
00755 
00756     PRUint16 GetSecurityManagerFlags() const
00757         {return mSecurityManagerFlags;}
00758     void SetSecurityManagerFlags(PRUint16 f)
00759         {mSecurityManagerFlags = f;}
00760 
00761     nsIXPCSecurityManager* GetAppropriateSecurityManager(PRUint16 flags) const
00762         {
00763             NS_WARN_IF_FALSE(CallerTypeIsKnown(),"missing caller type set somewhere");
00764             if(!CallerTypeIsJavaScript())
00765                 return nsnull;
00766             if(mSecurityManager)
00767             {
00768                 if(flags & mSecurityManagerFlags)
00769                     return mSecurityManager;
00770             }
00771             else
00772             {
00773                 nsIXPCSecurityManager* mgr;
00774                 nsXPConnect* xpc = mRuntime->GetXPConnect();
00775                 mgr = xpc->GetDefaultSecurityManager();
00776                 if(mgr && (flags & xpc->GetDefaultSecurityManagerFlags()))
00777                     return mgr;
00778             }
00779             return nsnull;
00780         }
00781 
00782     void DebugDump(PRInt16 depth);
00783 
00784     ~XPCContext();
00785 
00786 private:
00787     XPCContext();    // no implementation
00788     XPCContext(XPCJSRuntime* aRuntime, JSContext* aJSContext);
00789 
00790 private:
00791     XPCJSRuntime* mRuntime;
00792     JSContext*  mJSContext;
00793     nsresult mLastResult;
00794     nsresult mPendingResult;
00795     nsIXPCSecurityManager* mSecurityManager;
00796     nsIException* mException;
00797     LangType mCallingLangType;
00798     PRUint16 mSecurityManagerFlags;
00799     JSPackedBool mMarked;
00800 };
00801 
00802 /***************************************************************************/
00803 
00804 #define NATIVE_CALLER  XPCContext::LANG_NATIVE
00805 #define JS_CALLER      XPCContext::LANG_JS
00806 
00807 // No virtuals
00808 // XPCCallContext is ALWAYS declared as a local variable in some function;
00809 // i.e. instance lifetime is always controled by some C++ function returning.
00810 //
00811 // These things are created frequently in many places. We *intentionally* do
00812 // not inialialize all members in order to save on construction overhead.
00813 // Some constructor pass more valid params than others. We init what must be
00814 // init'd and leave other members undefined. In debug builds the accessors
00815 // use a CHECK_STATE macro to track whether or not the object is in a valid
00816 // state to answer the question a caller might be asking. As long as this
00817 // class is maintained correctly it can do its job without a bunch of added
00818 // overhead from useless initializations and non-DEBUG error checking.
00819 //
00820 // Note that most accessors are inlined.
00821 
00822 class XPCCallContext : public nsIXPCNativeCallContext
00823 {
00824 public:
00825     NS_DECL_ISUPPORTS
00826     NS_DECL_NSIXPCNATIVECALLCONTEXT
00827 
00828     enum {NO_ARGS = (uintN) -1};
00829 
00830     XPCCallContext(XPCContext::LangType callerLanguage,
00831                    JSContext* cx    = nsnull,
00832                    JSObject* obj    = nsnull,
00833                    JSObject* funobj = nsnull,
00834                    jsval id         = 0,
00835                    uintN argc       = NO_ARGS,
00836                    jsval *argv      = nsnull,
00837                    jsval *rval      = nsnull);
00838 
00839     virtual ~XPCCallContext();
00840 
00841     inline JSBool                       IsValid() const ;
00842 
00843     inline nsXPConnect*                 GetXPConnect() const ;
00844     inline XPCJSRuntime*                GetRuntime() const ;
00845     inline XPCPerThreadData*            GetThreadData() const ;
00846     inline XPCContext*                  GetXPCContext() const ;
00847     inline JSContext*                   GetJSContext() const ;
00848     inline JSContext*                   GetSafeJSContext() const ;
00849     inline JSBool                       GetContextPopRequired() const ;
00850     inline XPCContext::LangType         GetCallerLanguage() const ;
00851     inline XPCContext::LangType         GetPrevCallerLanguage() const ;
00852     inline XPCCallContext*              GetPrevCallContext() const ;
00853 
00854     inline JSObject*                    GetOperandJSObject() const ;
00855     inline JSObject*                    GetCurrentJSObject() const ;
00856     inline JSObject*                    GetFlattenedJSObject() const ;
00857 
00858     inline nsISupports*                 GetIdentityObject() const ;
00859     inline XPCWrappedNative*            GetWrapper() const ;
00860 
00861     inline JSBool                       CanGetTearOff() const ;
00862     inline XPCWrappedNativeTearOff*     GetTearOff() const ;
00863 
00864     inline XPCNativeScriptableInfo*     GetScriptableInfo() const ;
00865     inline JSBool                       CanGetSet() const ;
00866     inline XPCNativeSet*                GetSet() const ;
00867     inline JSBool                       CanGetInterface() const ;
00868     inline XPCNativeInterface*          GetInterface() const ;
00869     inline XPCNativeMember*             GetMember() const ;
00870     inline JSBool                       HasInterfaceAndMember() const ;
00871     inline jsval                        GetName() const ;
00872     inline JSBool                       GetStaticMemberIsLocal() const ;
00873     inline uintN                        GetArgc() const ;
00874     inline jsval*                       GetArgv() const ;
00875     inline jsval*                       GetRetVal() const ;
00876     inline JSBool                       GetExceptionWasThrown() const ;
00877     inline JSBool                       GetReturnValueWasSet() const ;
00878 
00879     inline PRUint16                     GetMethodIndex() const ;
00880     inline void                         SetMethodIndex(PRUint16 index) ;
00881 
00882     inline JSBool   GetDestroyJSContextInDestructor() const;
00883     inline void     SetDestroyJSContextInDestructor(JSBool b);
00884 
00885     inline jsval GetResolveName() const;
00886     inline jsval SetResolveName(jsval name);
00887 
00888     inline XPCWrappedNative* GetResolvingWrapper() const;
00889     inline XPCWrappedNative* SetResolvingWrapper(XPCWrappedNative* w);
00890 
00891     inline void SetRetVal(jsval val);
00892 
00893     inline JSObject* GetCallee() const;
00894     inline void SetCallee(JSObject* callee);
00895 
00896     void SetName(jsval name);
00897     void SetArgsAndResultPtr(uintN argc, jsval *argv, jsval *rval);
00898     void SetCallInfo(XPCNativeInterface* iface, XPCNativeMember* member,
00899                      JSBool isSetter);
00900 
00901     nsresult  CanCallNow();
00902 
00903     void SystemIsBeingShutDown();
00904 
00905     operator JSContext*() const {return GetJSContext();}
00906 
00907 #ifdef XPC_IDISPATCH_SUPPORT
00908 
00913     void SetIDispatchInfo(XPCNativeInterface* iface, void * member);
00914     void* GetIDispatchMember() const { return mIDispatchMember; }
00915 #endif
00916 private:
00917 
00918     // no copy ctor or assignment allowed
00919     XPCCallContext(const XPCCallContext& r); // not implemented
00920     XPCCallContext& operator= (const XPCCallContext& r); // not implemented
00921 
00922 private:
00923     // posible values for mState
00924     enum State {
00925         INIT_FAILED,
00926         SYSTEM_SHUTDOWN,
00927         HAVE_CONTEXT,
00928         HAVE_OBJECT,
00929         HAVE_NAME,
00930         HAVE_ARGS,
00931         READY_TO_CALL,
00932         CALL_DONE
00933     };
00934 
00935 #ifdef DEBUG
00936 inline void CHECK_STATE(int s) const {NS_ASSERTION(mState >= s, "bad state");}
00937 #else
00938 #define CHECK_STATE(s) ((void)0)
00939 #endif
00940 
00941 private:
00942     State                           mState;
00943 
00944     nsXPConnect*                    mXPC;
00945 
00946     XPCPerThreadData*               mThreadData;
00947     XPCContext*                     mXPCContext;
00948     JSContext*                      mJSContext;
00949     JSBool                          mContextPopRequired;
00950     JSBool                          mDestroyJSContextInDestructor;
00951 
00952     XPCContext::LangType            mCallerLanguage;
00953 
00954     // ctor does not necessarily init the following. BEWARE!
00955 
00956     XPCContext::LangType            mPrevCallerLanguage;
00957 
00958     XPCCallContext*                 mPrevCallContext;
00959 
00960     JSObject*                       mOperandJSObject;
00961     JSObject*                       mCurrentJSObject;
00962     JSObject*                       mFlattenedJSObject;
00963     XPCWrappedNative*               mWrapper;
00964     XPCWrappedNativeTearOff*        mTearOff;
00965 
00966     XPCNativeScriptableInfo*        mScriptableInfo;
00967 
00968     XPCNativeSet*                   mSet;
00969     XPCNativeInterface*             mInterface;
00970     XPCNativeMember*                mMember;
00971 
00972     jsval                           mName;
00973     JSBool                          mStaticMemberIsLocal;
00974 
00975     uintN                           mArgc;
00976     jsval*                          mArgv;
00977     jsval*                          mRetVal;
00978 
00979     JSBool                          mExceptionWasThrown;
00980     JSBool                          mReturnValueWasSet;
00981 #ifdef XPC_IDISPATCH_SUPPORT
00982     void*                           mIDispatchMember;
00983 #endif
00984     PRUint16                        mMethodIndex;
00985 
00986     // If not null, this is the function object of the function we're going to
00987     // call.  This member only makes sense when CallerTypeIsNative() on our
00988     // XPCContext returns true.  We're not responsible for rooting this object;
00989     // whoever sets it on us needs to deal with that.
00990     JSObject*                       mCallee;
00991 };
00992 
00993 
00994 /***************************************************************************
00995 ****************************************************************************
00996 *
00997 * Core classes for wrapped native objects for use from JavaScript...
00998 *
00999 ****************************************************************************
01000 ***************************************************************************/
01001 
01002 // These are the various JSClasses and callbacks whose use that required
01003 // visibility from more than one .cpp file.
01004 
01005 extern JSExtendedClass XPC_WN_NoHelper_JSClass;
01006 extern JSClass XPC_WN_NoMods_Proto_JSClass;
01007 extern JSClass XPC_WN_ModsAllowed_Proto_JSClass;
01008 extern JSClass XPC_WN_Tearoff_JSClass;
01009 
01010 extern JSObjectOps * JS_DLL_CALLBACK
01011 XPC_WN_GetObjectOpsNoCall(JSContext *cx, JSClass *clazz);
01012 
01013 extern JSObjectOps * JS_DLL_CALLBACK
01014 XPC_WN_GetObjectOpsWithCall(JSContext *cx, JSClass *clazz);
01015 
01016 extern JSBool JS_DLL_CALLBACK
01017 XPC_WN_CallMethod(JSContext *cx, JSObject *obj,
01018                   uintN argc, jsval *argv, jsval *vp);
01019 
01020 extern JSBool JS_DLL_CALLBACK
01021 XPC_WN_GetterSetter(JSContext *cx, JSObject *obj,
01022                     uintN argc, jsval *argv, jsval *vp);
01023 
01024 extern JSBool
01025 xpc_InitWrappedNativeJSOps();
01026 
01027 #define IS_PROTO_CLASS(clazz)                                                 \
01028           ((clazz) == &XPC_WN_NoMods_Proto_JSClass ||                         \
01029            (clazz) == &XPC_WN_ModsAllowed_Proto_JSClass)
01030 
01031 // Comes from xpcwrappednativeops.cpp
01032 extern void
01033 xpc_MarkForValidWrapper(JSContext *cx, XPCWrappedNative* wrapper, void *arg);
01034 
01035 /***************************************************************************/
01036 
01037 /***************************************************************************/
01038 // XPCWrappedNativeScope is one-to-one with a JS global object.
01039 
01040 class XPCWrappedNativeScope
01041 {
01042 public:
01043 
01044     static XPCWrappedNativeScope*
01045     GetNewOrUsed(XPCCallContext& ccx, JSObject* aGlobal);
01046 
01047     XPCJSRuntime*
01048     GetRuntime() const {return mRuntime;}
01049 
01050     Native2WrappedNativeMap*
01051     GetWrappedNativeMap() const {return mWrappedNativeMap;}
01052 
01053     ClassInfo2WrappedNativeProtoMap*
01054     GetWrappedNativeProtoMap() const {return mWrappedNativeProtoMap;}
01055 
01056     nsXPCComponents*
01057     GetComponents() const {return mComponents;}
01058 
01059     JSObject*
01060     GetGlobalJSObject() const {return mGlobalJSObject;}
01061 
01062     JSObject*
01063     GetPrototypeJSObject() const {return mPrototypeJSObject;}
01064 
01065     JSObject*
01066     GetPrototypeJSFunction() const {return mPrototypeJSFunction;}
01067 
01068     void RemoveWrappedNativeProtos();
01069 
01070     static XPCWrappedNativeScope*
01071     FindInJSObjectScope(XPCCallContext& ccx, JSObject* obj,
01072                         JSBool OKIfNotInitialized = JS_FALSE);
01073 
01074     static void
01075     SystemIsBeingShutDown(XPCCallContext& ccx);
01076 
01077     static void
01078     FinishedMarkPhaseOfGC(JSContext* cx, XPCJSRuntime* rt);
01079 
01080     static void
01081     FinishedFinalizationPhaseOfGC(JSContext* cx);
01082 
01083     static void
01084     MarkAllWrappedNativesAndProtos();
01085 
01086     static nsresult
01087     ClearAllWrappedNativeSecurityPolicies(XPCCallContext& ccx);
01088 
01089 #ifdef DEBUG
01090     static void
01091     ASSERT_NoInterfaceSetsAreMarked();
01092 #endif
01093 
01094     static void
01095     SweepAllWrappedNativeTearOffs();
01096 
01097     static void
01098     DebugDumpAllScopes(PRInt16 depth);
01099 
01100     void
01101     DebugDump(PRInt16 depth);
01102 
01103     JSBool
01104     IsValid() const {return mRuntime != nsnull;}
01105 
01106     void SetComponents(nsXPCComponents* aComponents);
01107     void SetGlobal(XPCCallContext& ccx, JSObject* aGlobal);
01108 
01109     static void InitStatics() { gScopes = nsnull; gDyingScopes = nsnull; }
01110 
01111 protected:
01112     XPCWrappedNativeScope(XPCCallContext& ccx, JSObject* aGlobal);
01113     virtual ~XPCWrappedNativeScope();
01114 
01115     static void KillDyingScopes();
01116 
01117     XPCWrappedNativeScope(); // not implemented
01118 
01119 private:
01120     static XPCWrappedNativeScope* gScopes;
01121     static XPCWrappedNativeScope* gDyingScopes;
01122 
01123     XPCJSRuntime*                    mRuntime;
01124     Native2WrappedNativeMap*         mWrappedNativeMap;
01125     ClassInfo2WrappedNativeProtoMap* mWrappedNativeProtoMap;
01126     nsXPCComponents*                 mComponents;
01127     XPCWrappedNativeScope*           mNext;
01128     JSObject*                        mGlobalJSObject;
01129     JSObject*                        mPrototypeJSObject;
01130     JSObject*                        mPrototypeJSFunction;
01131 };
01132 
01133 /***************************************************************************/
01134 // XPCNativeMember represents a single idl declared method, attribute or
01135 // constant.
01136 
01137 // Tight. No virtual methods. Can be bitwise copied (until any resolution done).
01138 
01139 class XPCNativeMember
01140 {
01141 public:
01142     static JSBool GetCallInfo(XPCCallContext& ccx,
01143                               JSObject* funobj,
01144                               XPCNativeInterface** pInterface,
01145                               XPCNativeMember**    pMember);
01146 
01147     jsval   GetName() const {return mName;}
01148 
01149     PRUint16 GetIndex() const {return mIndex;}
01150 
01151     JSBool GetValue(XPCCallContext& ccx, XPCNativeInterface* iface, jsval* pval)
01152         {if(!IsResolved() && !Resolve(ccx, iface)) return JS_FALSE;
01153          *pval = mVal; return JS_TRUE;}
01154 
01155     JSBool IsMethod() const
01156         {return 0 != (mFlags & METHOD);}
01157 
01158     JSBool IsConstant() const
01159         {return 0 != (mFlags & CONSTANT);}
01160 
01161     JSBool IsAttribute() const
01162         {return 0 != (mFlags & GETTER);}
01163 
01164     JSBool IsWritableAttribute() const
01165         {return 0 != (mFlags & SETTER_TOO);}
01166 
01167     JSBool IsReadOnlyAttribute() const
01168         {return IsAttribute() && !IsWritableAttribute();}
01169 
01170 
01171     void SetName(jsval a) {mName = a;}
01172 
01173     void SetMethod(PRUint16 index)
01174         {mVal = JSVAL_NULL; mFlags = METHOD; mIndex = index;}
01175 
01176     void SetConstant(PRUint16 index)
01177         {mVal = JSVAL_NULL; mFlags = CONSTANT; mIndex = index;}
01178 
01179     void SetReadOnlyAttribute(PRUint16 index)
01180         {mVal = JSVAL_NULL; mFlags = GETTER; mIndex = index;}
01181 
01182     void SetWritableAttribute()
01183         {NS_ASSERTION(mFlags == GETTER,"bad"); mFlags = GETTER | SETTER_TOO;}
01184 
01185     /* default ctor - leave random contents */
01186     XPCNativeMember()  {MOZ_COUNT_CTOR(XPCNativeMember);}
01187     ~XPCNativeMember() {MOZ_COUNT_DTOR(XPCNativeMember);}
01188 
01189     void DealWithDyingGCThings(JSContext* cx, XPCJSRuntime* rt)
01190         {if(IsResolved() && JSVAL_IS_GCTHING(mVal) &&
01191            JS_IsAboutToBeFinalized(cx, JSVAL_TO_GCTHING(mVal)))
01192            {mVal = JSVAL_NULL; mFlags &= ~RESOLVED;}}
01193 
01194 private:
01195     JSBool IsResolved() const {return mFlags & RESOLVED;}
01196     JSBool Resolve(XPCCallContext& ccx, XPCNativeInterface* iface);
01197 
01198     enum {
01199         RESOLVED    = 0x01,
01200         METHOD      = 0x02,
01201         CONSTANT    = 0x04,
01202         GETTER      = 0x08,
01203         SETTER_TOO  = 0x10
01204     };
01205 
01206 private:
01207     // our only data...
01208     jsval    mName;
01209     jsval    mVal;
01210     PRUint16 mIndex;
01211     PRUint16 mFlags;
01212 };
01213 
01214 /***************************************************************************/
01215 // XPCNativeInterface represents a single idl declared interface. This is
01216 // primarily the set of XPCNativeMembers.
01217 
01218 // Tight. No virtual methods.
01219 
01220 class XPCNativeInterface
01221 {
01222 public:
01223     static XPCNativeInterface* GetNewOrUsed(XPCCallContext& ccx,
01224                                             const nsIID* iid);
01225     static XPCNativeInterface* GetNewOrUsed(XPCCallContext& ccx,
01226                                             nsIInterfaceInfo* info);
01227     static XPCNativeInterface* GetNewOrUsed(XPCCallContext& ccx,
01228                                             const char* name);
01229     static XPCNativeInterface* GetISupports(XPCCallContext& ccx);
01230 
01231     inline nsIInterfaceInfo* GetInterfaceInfo() const {return mInfo.get();}
01232     inline jsval             GetName()          const {return mName;}
01233 
01234     inline const nsIID* GetIID() const;
01235     inline const char*  GetNameString() const;
01236     inline XPCNativeMember* FindMember(jsval name) const;
01237 
01238     inline JSBool HasAncestor(const nsIID* iid) const;
01239 
01240     const char* GetMemberName(XPCCallContext& ccx,
01241                               const XPCNativeMember* member) const;
01242 
01243     PRUint16 GetMemberCount() const
01244         {NS_ASSERTION(!IsMarked(), "bad"); return mMemberCount;}
01245     XPCNativeMember* GetMemberAt(PRUint16 i)
01246         {NS_ASSERTION(i < mMemberCount, "bad index"); return &mMembers[i];}
01247 
01248     inline void DealWithDyingGCThings(JSContext* cx, XPCJSRuntime* rt);
01249 
01250     void DebugDump(PRInt16 depth);
01251 
01252 #define XPC_NATIVE_IFACE_MARK_FLAG ((PRUint16)JS_BIT(15)) // only high bit of 16 is set
01253 
01254     void Mark()     {mMemberCount |= XPC_NATIVE_IFACE_MARK_FLAG;}
01255     void Unmark()   {mMemberCount &= ~XPC_NATIVE_IFACE_MARK_FLAG;}
01256     JSBool IsMarked() const
01257                     {return 0 != (mMemberCount & XPC_NATIVE_IFACE_MARK_FLAG);}
01258 
01259     // NOP. This is just here to make the AutoMarkingPtr code compile.
01260     inline void MarkBeforeJSFinalize(JSContext*) {}
01261     inline void AutoMark(JSContext*) {}
01262 
01263     static void DestroyInstance(JSContext* cx, XPCJSRuntime* rt,
01264                                 XPCNativeInterface* inst);
01265 
01266 protected:
01267     static XPCNativeInterface* NewInstance(XPCCallContext& ccx,
01268                                            nsIInterfaceInfo* aInfo);
01269 
01270     XPCNativeInterface();   // not implemented
01271     XPCNativeInterface(nsIInterfaceInfo* aInfo, jsval aName)
01272         : mInfo(aInfo), mName(aName), mMemberCount(0)
01273                           {MOZ_COUNT_CTOR(XPCNativeInterface);}
01274     ~XPCNativeInterface() {MOZ_COUNT_DTOR(XPCNativeInterface);}
01275 
01276     void* operator new(size_t, void* p) CPP_THROW_NEW {return p;}
01277 
01278     XPCNativeInterface(const XPCNativeInterface& r); // not implemented
01279     XPCNativeInterface& operator= (const XPCNativeInterface& r); // not implemented
01280 
01281 private:
01282     nsCOMPtr<nsIInterfaceInfo> mInfo;
01283     jsval                      mName;
01284     PRUint16          mMemberCount;
01285     XPCNativeMember   mMembers[1]; // always last - object sized for array
01286 };
01287 
01288 /***************************************************************************/
01289 // XPCNativeSetKey is used to key a XPCNativeSet in a NativeSetMap.
01290 
01291 class XPCNativeSetKey
01292 {
01293 public:
01294     XPCNativeSetKey(XPCNativeSet*       BaseSet  = nsnull,
01295                     XPCNativeInterface* Addition = nsnull,
01296                     PRUint16            Position = 0)
01297         : mIsAKey(IS_A_KEY), mPosition(Position), mBaseSet(BaseSet),
01298           mAddition(Addition) {}
01299     ~XPCNativeSetKey() {}
01300 
01301     XPCNativeSet*           GetBaseSet()  const {return mBaseSet;}
01302     XPCNativeInterface*     GetAddition() const {return mAddition;}
01303     PRUint16                GetPosition() const {return mPosition;}
01304 
01305     // This is a fun little hack...
01306     // We build these keys only on the stack. We use them for lookup in
01307     // NativeSetMap. Becasue we don't want to pay the cost of cloning a key and
01308     // sticking it into the hashtable, when the XPCNativeSet actually
01309     // gets added to the table the 'key' in the table is a pointer to the
01310     // set itself and not this key. Our key compare function expects to get
01311     // a key and a set. When we do external lookups in the map we pass in one
01312     // of these keys and our compare function gets passed a key and a set.
01313     // (see compare_NativeKeyToSet in xpcmaps.cpp). This is all well and good.
01314     // Except, when the table decides to resize itself. Then it tries to use
01315     // our compare function with the 'keys' that are in the hashtable (which are
01316     // really XPCNativeSet objects and not XPCNativeSetKey objects!
01317     //
01318     // So, the hack is to have the compare function assume it is getting a
01319     // XPCNativeSetKey pointer and call this IsAKey method. If that fails then
01320     // it realises that it really has a XPCNativeSet pointer and deals with that
01321     // fact. This is safe because we know that both of these classes have no
01322     // virtual methods and their first data member is a PRUint16. We are
01323     // confident that XPCNativeSet->mMemberCount will never be 0xffff.
01324 
01325     JSBool                  IsAKey() const {return mIsAKey == IS_A_KEY;}
01326 
01327     enum {IS_A_KEY = 0xffff};
01328 
01329     // Allow shallow copy
01330 
01331 private:
01332     PRUint16                mIsAKey;    // must be first data member
01333     PRUint16                mPosition;
01334     XPCNativeSet*           mBaseSet;
01335     XPCNativeInterface*     mAddition;
01336 };
01337 
01338 /***************************************************************************/
01339 // XPCNativeSet represents an ordered collection of XPCNativeInterface pointers.
01340 
01341 class XPCNativeSet
01342 {
01343 public:
01344     static XPCNativeSet* GetNewOrUsed(XPCCallContext& ccx, const nsIID* iid);
01345     static XPCNativeSet* GetNewOrUsed(XPCCallContext& ccx,
01346                                       nsIClassInfo* classInfo);
01347     static XPCNativeSet* GetNewOrUsed(XPCCallContext& ccx,
01348                                       XPCNativeSet* otherSet,
01349                                       XPCNativeInterface* newInterface,
01350                                       PRUint16 position);
01351 
01352     static void ClearCacheEntryForClassInfo(nsIClassInfo* classInfo);
01353 
01354     inline JSBool FindMember(jsval name, XPCNativeMember** pMember,
01355                              PRUint16* pInterfaceIndex) const;
01356 
01357     inline JSBool FindMember(jsval name, XPCNativeMember** pMember,
01358                              XPCNativeInterface** pInterface) const;
01359 
01360     inline JSBool FindMember(jsval name,
01361                              XPCNativeMember** pMember,
01362                              XPCNativeInterface** pInterface,
01363                              XPCNativeSet* protoSet,
01364                              JSBool* pIsLocal) const;
01365 
01366     inline JSBool HasInterface(XPCNativeInterface* aInterface) const;
01367     inline JSBool HasInterfaceWithAncestor(XPCNativeInterface* aInterface) const;
01368 
01369     inline XPCNativeInterface* FindInterfaceWithIID(const nsIID& iid) const;
01370 
01371     inline XPCNativeInterface* FindNamedInterface(jsval name) const;
01372 
01373     PRUint16 GetMemberCount() const {return mMemberCount;}
01374     PRUint16 GetInterfaceCount() const
01375         {NS_ASSERTION(!IsMarked(), "bad"); return mInterfaceCount;}
01376     XPCNativeInterface** GetInterfaceArray() {return mInterfaces;}
01377 
01378     XPCNativeInterface* GetInterfaceAt(PRUint16 i)
01379         {NS_ASSERTION(i < mInterfaceCount, "bad index"); return mInterfaces[i];}
01380 
01381     inline JSBool MatchesSetUpToInterface(const XPCNativeSet* other,
01382                                           XPCNativeInterface* iface) const;
01383 
01384 #define XPC_NATIVE_SET_MARK_FLAG ((PRUint16)JS_BIT(15)) // only high bit of 16 is set
01385 
01386     inline void Mark();
01387 
01388     // NOP. This is just here to make the AutoMarkingPtr code compile.
01389     inline void MarkBeforeJSFinalize(JSContext*) {}
01390     inline void AutoMark(JSContext*) {}
01391 
01392 private:
01393     void MarkSelfOnly() {mInterfaceCount |= XPC_NATIVE_SET_MARK_FLAG;}
01394 public:
01395     void Unmark()       {mInterfaceCount &= ~XPC_NATIVE_SET_MARK_FLAG;}
01396     JSBool IsMarked() const
01397                   {return 0 != (mInterfaceCount & XPC_NATIVE_SET_MARK_FLAG);}
01398 
01399 #ifdef DEBUG
01400     inline void ASSERT_NotMarked();
01401 #endif
01402 
01403     void DebugDump(PRInt16 depth);
01404 
01405     static void DestroyInstance(XPCNativeSet* inst);
01406 
01407 protected:
01408     static XPCNativeSet* NewInstance(XPCCallContext& ccx,
01409                                      XPCNativeInterface** array,
01410                                      PRUint16 count);
01411     static XPCNativeSet* NewInstanceMutate(XPCNativeSet*       otherSet,
01412                                            XPCNativeInterface* newInterface,
01413                                            PRUint16            position);
01414     XPCNativeSet()  {MOZ_COUNT_CTOR(XPCNativeSet);}
01415     ~XPCNativeSet() {MOZ_COUNT_DTOR(XPCNativeSet);}
01416     void* operator new(size_t, void* p) CPP_THROW_NEW {return p;}
01417 
01418 private:
01419     PRUint16                mMemberCount;
01420     PRUint16                mInterfaceCount;
01421     XPCNativeInterface*     mInterfaces[1];  // always last - object sized for array
01422 };
01423 
01424 /***************************************************************************/
01425 // XPCNativeScriptableFlags is a wrapper class that holds the flags returned
01426 // from calls to nsIXPCScriptable::GetScriptableFlags(). It has convenience
01427 // methods to check for particular bitflags. Since we also use this class as
01428 // a member of the gc'd class XPCNativeScriptableShared, this class holds the
01429 // bit and exposes the inlined methods to support marking.
01430 
01431 #define XPC_WN_SJSFLAGS_MARK_FLAG JS_BIT(31) // only high bit of 32 is set
01432 
01433 class XPCNativeScriptableFlags
01434 {
01435 private:
01436     JSUint32 mFlags;
01437 
01438 public:
01439 
01440     XPCNativeScriptableFlags(JSUint32 flags = 0) : mFlags(flags) {}
01441 
01442     JSUint32 GetFlags() const {return mFlags & ~XPC_WN_SJSFLAGS_MARK_FLAG;}
01443     void     SetFlags(JSUint32 flags) {mFlags = flags;}
01444 
01445     operator JSUint32() const {return GetFlags();}
01446 
01447     XPCNativeScriptableFlags(const XPCNativeScriptableFlags& r)
01448         {mFlags = r.GetFlags();}
01449 
01450     XPCNativeScriptableFlags& operator= (const XPCNativeScriptableFlags& r)
01451         {mFlags = r.GetFlags(); return *this;}
01452 
01453     void Mark()       {mFlags |= XPC_WN_SJSFLAGS_MARK_FLAG;}
01454     void Unmark()     {mFlags &= ~XPC_WN_SJSFLAGS_MARK_FLAG;}
01455     JSBool IsMarked() const {return 0 != (mFlags & XPC_WN_SJSFLAGS_MARK_FLAG);}
01456 
01457 #ifdef GET_IT
01458 #undef GET_IT
01459 #endif
01460 #define GET_IT(f_) const {return 0 != (mFlags & nsIXPCScriptable:: f_ );}
01461 
01462     JSBool WantPreCreate()                GET_IT(WANT_PRECREATE)
01463     JSBool WantCreate()                   GET_IT(WANT_CREATE)
01464     JSBool WantPostCreate()               GET_IT(WANT_POSTCREATE)
01465     JSBool WantAddProperty()              GET_IT(WANT_ADDPROPERTY)
01466     JSBool WantDelProperty()              GET_IT(WANT_DELPROPERTY)
01467     JSBool WantGetProperty()              GET_IT(WANT_GETPROPERTY)
01468     JSBool WantSetProperty()              GET_IT(WANT_SETPROPERTY)
01469     JSBool WantEnumerate()                GET_IT(WANT_ENUMERATE)
01470     JSBool WantNewEnumerate()             GET_IT(WANT_NEWENUMERATE)
01471     JSBool WantNewResolve()               GET_IT(WANT_NEWRESOLVE)
01472     JSBool WantConvert()                  GET_IT(WANT_CONVERT)
01473     JSBool WantFinalize()                 GET_IT(WANT_FINALIZE)
01474     JSBool WantCheckAccess()              GET_IT(WANT_CHECKACCESS)
01475     JSBool WantCall()                     GET_IT(WANT_CALL)
01476     JSBool WantConstruct()                GET_IT(WANT_CONSTRUCT)
01477     JSBool WantHasInstance()              GET_IT(WANT_HASINSTANCE)
01478     JSBool WantMark()                     GET_IT(WANT_MARK)
01479     JSBool WantEquality()                 GET_IT(WANT_EQUALITY)
01480     JSBool WantOuterObject()              GET_IT(WANT_OUTER_OBJECT)
01481     JSBool WantInnerObject()              GET_IT(WANT_INNER_OBJECT)
01482     JSBool UseJSStubForAddProperty()      GET_IT(USE_JSSTUB_FOR_ADDPROPERTY)
01483     JSBool UseJSStubForDelProperty()      GET_IT(USE_JSSTUB_FOR_DELPROPERTY)
01484     JSBool UseJSStubForSetProperty()      GET_IT(USE_JSSTUB_FOR_SETPROPERTY)
01485     JSBool DontEnumStaticProps()          GET_IT(DONT_ENUM_STATIC_PROPS)
01486     JSBool DontEnumQueryInterface()       GET_IT(DONT_ENUM_QUERY_INTERFACE)
01487     JSBool DontAskInstanceForScriptable() GET_IT(DONT_ASK_INSTANCE_FOR_SCRIPTABLE)
01488     JSBool ClassInfoInterfacesOnly()      GET_IT(CLASSINFO_INTERFACES_ONLY)
01489     JSBool AllowPropModsDuringResolve()   GET_IT(ALLOW_PROP_MODS_DURING_RESOLVE)
01490     JSBool AllowPropModsToPrototype()     GET_IT(ALLOW_PROP_MODS_TO_PROTOTYPE)
01491     JSBool DontSharePrototype()           GET_IT(DONT_SHARE_PROTOTYPE)
01492     JSBool DontReflectInterfaceNames()    GET_IT(DONT_REFLECT_INTERFACE_NAMES)
01493 
01494 #undef GET_IT
01495 };
01496 
01497 /***************************************************************************/
01498 
01499 // XPCNativeScriptableShared is used to hold the JSClass and the
01500 // associated scriptable flags for XPCWrappedNatives. These are shared across
01501 // the runtime and are garbage collected by xpconnect. We *used* to just store
01502 // this inside the XPCNativeScriptableInfo (usually owned by instances of
01503 // XPCWrappedNativeProto. This had two problems... It was wasteful, and it
01504 // was a big problem when wrappers are reparented to different scopes (and
01505 // thus different protos (the DOM does this).
01506 
01507 class XPCNativeScriptableShared
01508 {
01509 public:
01510     const XPCNativeScriptableFlags& GetFlags() const {return mFlags;}
01511     JSClass*                        GetJSClass() {return &mJSClass.base;}
01512 
01513     XPCNativeScriptableShared(JSUint32 aFlags = 0, char* aName = nsnull)
01514         : mFlags(aFlags)
01515         {memset(&mJSClass, 0, sizeof(mJSClass));
01516          mJSClass.base.name = aName;  // take ownership
01517          MOZ_COUNT_CTOR(XPCNativeScriptableShared);}
01518 
01519     ~XPCNativeScriptableShared()
01520         {if(mJSClass.base.name)nsMemory::Free((void*)mJSClass.base.name);
01521          MOZ_COUNT_DTOR(XPCNativeScriptableShared);}
01522 
01523     char* TransferNameOwnership()
01524         {char* name=(char*)mJSClass.base.name; mJSClass.base.name = nsnull;
01525         return name;}
01526 
01527     void PopulateJSClass(JSBool isGlobal);
01528 
01529     void Mark()       {mFlags.Mark();}
01530     void Unmark()     {mFlags.Unmark();}
01531     JSBool IsMarked() const {return mFlags.IsMarked();}
01532 
01533 private:
01534     XPCNativeScriptableFlags mFlags;
01535     JSExtendedClass          mJSClass;
01536 };
01537 
01538 /***************************************************************************/
01539 // XPCNativeScriptableInfo is used to hold the nsIXPCScriptable state for a
01540 // given class or instance.
01541 
01542 class XPCNativeScriptableInfo
01543 {
01544 public:
01545     static XPCNativeScriptableInfo*
01546     Construct(XPCCallContext& ccx, JSBool isGlobal,
01547               const XPCNativeScriptableCreateInfo* sci);
01548 
01549     nsIXPCScriptable*
01550     GetCallback() const {return mCallback;}
01551 
01552     const XPCNativeScriptableFlags&
01553     GetFlags() const      {return mShared->GetFlags();}
01554 
01555     JSClass*
01556     GetJSClass()          {return mShared->GetJSClass();}
01557 
01558     XPCNativeScriptableShared*
01559     GetScriptableShared() {return mShared;}
01560 
01561     void
01562     SetCallback(nsIXPCScriptable* s) {mCallback = s;}
01563 
01564     void
01565     SetScriptableShared(XPCNativeScriptableShared* shared) {mShared = shared;}
01566 
01567     void Mark() {if(mShared) mShared->Mark();}
01568 
01569 protected:
01570     XPCNativeScriptableInfo(nsIXPCScriptable* scriptable = nsnull,
01571                             XPCNativeScriptableShared* shared = nsnull)
01572         : mCallback(scriptable), mShared(shared)
01573                                {MOZ_COUNT_CTOR(XPCNativeScriptableInfo);}
01574 public:
01575     ~XPCNativeScriptableInfo() {MOZ_COUNT_DTOR(XPCNativeScriptableInfo);}
01576 private:
01577 
01578     // disable copy ctor and assignment
01579     XPCNativeScriptableInfo(const XPCNativeScriptableInfo& r); // not implemented
01580     XPCNativeScriptableInfo& operator= (const XPCNativeScriptableInfo& r); // not implemented
01581 
01582 private:
01583     nsCOMPtr<nsIXPCScriptable>  mCallback;
01584     XPCNativeScriptableShared*  mShared;
01585 };
01586 
01587 /***************************************************************************/
01588 // XPCNativeScriptableCreateInfo is used in creating new wrapper and protos.
01589 // it abstracts out the scriptable interface pointer and the flags. After
01590 // creation these are factored differently using XPCNativeScriptableInfo.
01591 
01592 class XPCNativeScriptableCreateInfo
01593 {
01594 public:
01595 
01596     XPCNativeScriptableCreateInfo(const XPCNativeScriptableInfo& si)
01597         : mCallback(si.GetCallback()), mFlags(si.GetFlags()) {}
01598 
01599     XPCNativeScriptableCreateInfo(nsIXPCScriptable* callback = nsnull,
01600                                   XPCNativeScriptableFlags flags = 0)
01601         : mCallback(callback), mFlags(flags) {}
01602 
01603     nsIXPCScriptable*
01604     GetCallback() const {return mCallback;}
01605 
01606     const XPCNativeScriptableFlags&
01607     GetFlags() const      {return mFlags;}
01608 
01609     void
01610     SetCallback(nsIXPCScriptable* callback) {mCallback = callback;}
01611 
01612     void
01613     SetFlags(const XPCNativeScriptableFlags& flags)  {mFlags = flags;}
01614 
01615 private:
01616     nsCOMPtr<nsIXPCScriptable>  mCallback;
01617     XPCNativeScriptableFlags    mFlags;
01618 };
01619 
01620 /***********************************************/
01621 // XPCWrappedNativeProto hold the additional (potentially shared) wrapper data
01622 // for XPCWrappedNative whose native objects expose nsIClassInfo.
01623 
01624 class XPCWrappedNativeProto
01625 {
01626 public:
01627     static XPCWrappedNativeProto*
01628     GetNewOrUsed(XPCCallContext& ccx,
01629                  XPCWrappedNativeScope* Scope,
01630                  nsIClassInfo* ClassInfo,
01631                  const XPCNativeScriptableCreateInfo* ScriptableCreateInfo,
01632                  JSBool ForceNoSharing,
01633                  JSBool isGlobal);
01634 
01635     XPCWrappedNativeScope*
01636     GetScope()   const {return mScope;}
01637 
01638     XPCJSRuntime*
01639     GetRuntime() const {return mScope->GetRuntime();}
01640 
01641     JSObject*
01642     GetJSProtoObject() const {return mJSProtoObject;}
01643 
01644     nsIClassInfo*
01645     GetClassInfo()     const {return mClassInfo;}
01646 
01647     XPCNativeSet*
01648     GetSet()           const {return mSet;}
01649 
01650     XPCNativeScriptableInfo*
01651     GetScriptableInfo()   {return mScriptableInfo;}
01652 
01653     void**
01654     GetSecurityInfoAddr() {return &mSecurityInfo;}
01655 
01656     JSUint32
01657     GetClassInfoFlags() const {return mClassInfoFlags;}
01658 
01659 #ifdef GET_IT
01660 #undef GET_IT
01661 #endif
01662 #define GET_IT(f_) const {return (JSBool)(mClassInfoFlags & nsIClassInfo:: f_ );}
01663 
01664     JSBool ClassIsSingleton()           GET_IT(SINGLETON)
01665     JSBool ClassIsThreadSafe()          GET_IT(THREADSAFE)
01666     JSBool ClassIsMainThreadOnly()      GET_IT(MAIN_THREAD_ONLY)
01667     JSBool ClassIsDOMObject()           GET_IT(DOM_OBJECT)
01668     JSBool ClassIsPluginObject()        GET_IT(PLUGIN_OBJECT)
01669 
01670 #undef GET_IT
01671 
01672 #define XPC_PROTO_DONT_SHARE JS_BIT(31) // only high bit of 32 is set
01673 
01674     JSBool
01675     IsShared() const {return !(mClassInfoFlags & XPC_PROTO_DONT_SHARE);}
01676 
01677     XPCLock* GetLock() const
01678         {return ClassIsThreadSafe() ? GetRuntime()->GetMapLock() : nsnull;}
01679 
01680     void SetScriptableInfo(XPCNativeScriptableInfo* si)
01681         {NS_ASSERTION(!mScriptableInfo, "leak here!"); mScriptableInfo = si;}
01682 
01683     void JSProtoObjectFinalized(JSContext *cx, JSObject *obj);
01684 
01685     void SystemIsBeingShutDown(XPCCallContext& ccx);
01686 
01687     void DebugDump(PRInt16 depth);
01688 
01689     // This is called in the 'early' phase by AutoMarkingWrappedNativeProtoPtr.
01690     // 'early' meaning after JSGC_MARK_END and before JSGC_FINALIZE_END.
01691     // At this point in time we can still mark JSObjects in the JS gc heap.
01692     void MarkBeforeJSFinalize(JSContext* cx)
01693         {if(mJSProtoObject)
01694             JS_MarkGCThing(cx, mJSProtoObject, 
01695                            "XPCWrappedNativeProto::mJSProtoObject", nsnull);
01696          if(mScriptableInfo) mScriptableInfo->Mark();}
01697     // NOP. This is just here to make the AutoMarkingPtr code compile.
01698     inline void AutoMark(JSContext*) {}
01699 
01700     // Yes, we *do* need to mark the mScriptableInfo in both cases.
01701     void Mark() const
01702         {mSet->Mark(); 
01703          if(mScriptableInfo) mScriptableInfo->Mark();}
01704 
01705 #ifdef DEBUG
01706     void ASSERT_SetNotMarked() const {mSet->ASSERT_NotMarked();}
01707 #endif
01708 
01709     ~XPCWrappedNativeProto();
01710 
01711 protected:
01712     // disable copy ctor and assignment
01713     XPCWrappedNativeProto(const XPCWrappedNativeProto& r); // not implemented
01714     XPCWrappedNativeProto& operator= (const XPCWrappedNativeProto& r); // not implemented
01715 
01716     // hide ctor
01717     XPCWrappedNativeProto(XPCWrappedNativeScope* Scope,
01718                           nsIClassInfo* ClassInfo,
01719                           PRUint32 ClassInfoFlags,
01720                           XPCNativeSet* Set);
01721 
01722     JSBool Init(XPCCallContext& ccx, JSBool isGlobal,
01723                 const XPCNativeScriptableCreateInfo* scriptableCreateInfo);
01724 
01725 private:
01726 #if defined(DEBUG_xpc_hacker) || defined(DEBUG)
01727     static PRInt32 gDEBUG_LiveProtoCount;
01728 #endif
01729 
01730 private:
01731     XPCWrappedNativeScope*   mScope;
01732     JSObject*                mJSProtoObject;
01733     nsCOMPtr<nsIClassInfo>   mClassInfo;
01734     PRUint32                 mClassInfoFlags;
01735     XPCNativeSet*            mSet;
01736     void*                    mSecurityInfo;
01737     XPCNativeScriptableInfo* mScriptableInfo;
01738 };
01739 
01740 
01741 /***********************************************/
01742 // XPCWrappedNativeTearOff represents the info needed to make calls to one
01743 // interface on the underlying native object of a XPCWrappedNative.
01744 
01745 class XPCWrappedNativeTearOff
01746 {
01747 public:
01748     JSBool IsAvailable() const {return mInterface == nsnull;}
01749     JSBool IsReserved()  const {return mInterface == (XPCNativeInterface*)1;}
01750     JSBool IsValid()     const {return !IsAvailable() && !IsReserved();}
01751     void   SetReserved()       {mInterface = (XPCNativeInterface*)1;}
01752 
01753     XPCNativeInterface* GetInterface() const {return mInterface;}
01754     nsISupports*        GetNative()    const {return mNative;}
01755     JSObject*           GetJSObject()  const;
01756     void SetInterface(XPCNativeInterface*  Interface) {mInterface = Interface;}
01757     void SetNative(nsISupports*  Native)              {mNative = Native;}
01758     void SetJSObject(JSObject*  JSObj);
01759 
01760     void JSObjectFinalized() {SetJSObject(nsnull);}
01761 
01762     XPCWrappedNativeTearOff()
01763         : mInterface(nsnull), mNative(nsnull), mJSObject(nsnull) {}
01764     ~XPCWrappedNativeTearOff();
01765 
01766     // NOP. This is just here to make the AutoMarkingPtr code compile.
01767     inline void MarkBeforeJSFinalize(JSContext*) {}
01768     inline void AutoMark(JSContext*) {}
01769 
01770     void Mark()       {mJSObject = (JSObject*)(((jsword)mJSObject) | 1);}
01771     void Unmark()     {mJSObject = (JSObject*)(((jsword)mJSObject) & ~1);}
01772     JSBool IsMarked() const {return (JSBool)(((jsword)mJSObject) & 1);}
01773 
01774 #ifdef XPC_IDISPATCH_SUPPORT
01775     enum JSObject_flags
01776     {
01777         IDISPATCH_BIT = 2,
01778         JSOBJECT_MASK = 3
01779     };
01780     void                SetIDispatch(JSContext* cx);
01781     JSBool              IsIDispatch() const;
01782     XPCDispInterface*   GetIDispatchInfo() const;
01783 #endif
01784 private:
01785     XPCWrappedNativeTearOff(const XPCWrappedNativeTearOff& r); // not implemented
01786     XPCWrappedNativeTearOff& operator= (const XPCWrappedNativeTearOff& r); // not implemented
01787 
01788 private:
01789     XPCNativeInterface* mInterface;
01790     nsISupports*        mNative;
01791     JSObject*           mJSObject;
01792 };
01793 
01794 /***********************************************/
01795 // XPCWrappedNativeTearOffChunk is a collections of XPCWrappedNativeTearOff
01796 // objects. It lets us allocate a set of XPCWrappedNativeTearOff objects and
01797 // link the sets - rather than only having the option of linking single
01798 // XPCWrappedNativeTearOff objects.
01799 //
01800 // The value of XPC_WRAPPED_NATIVE_TEAROFFS_PER_CHUNK can be tuned at buildtime
01801 // to balance between the code of allocations of additional chunks and the waste
01802 // of space for ununsed XPCWrappedNativeTearOff objects.
01803 
01804 #define XPC_WRAPPED_NATIVE_TEAROFFS_PER_CHUNK 1
01805 
01806 class XPCWrappedNativeTearOffChunk
01807 {
01808 friend class XPCWrappedNative;
01809 private:
01810     XPCWrappedNativeTearOffChunk() : mNextChunk(nsnull) {}
01811     ~XPCWrappedNativeTearOffChunk() {delete mNextChunk;}
01812 
01813 private:
01814     XPCWrappedNativeTearOff mTearOffs[XPC_WRAPPED_NATIVE_TEAROFFS_PER_CHUNK];
01815     XPCWrappedNativeTearOffChunk* mNextChunk;
01816 };
01817 
01818 /***************************************************************************/
01819 // XPCWrappedNative the wrapper around one instance of a native xpcom object
01820 // to be used from JavaScript.
01821 
01822 class XPCWrappedNative : public nsIXPConnectWrappedNative
01823 {
01824 public:
01825     NS_DECL_ISUPPORTS
01826     NS_DECL_NSIXPCONNECTJSOBJECTHOLDER
01827     NS_DECL_NSIXPCONNECTWRAPPEDNATIVE
01828 
01829     JSBool
01830     IsValid() const {return nsnull != mFlatJSObject;}
01831 
01832 #define XPC_SCOPE_TAG     ((jsword)0x1)
01833 #define XPC_SCOPE_WORD(s) ((jsword)(s))
01834 
01835     static inline JSBool
01836     IsTaggedScope(XPCWrappedNativeScope* s)
01837         {return XPC_SCOPE_WORD(s) & XPC_SCOPE_TAG;}
01838 
01839     static inline XPCWrappedNativeScope*
01840     TagScope(XPCWrappedNativeScope* s)
01841         {NS_ASSERTION(!IsTaggedScope(s), "bad pointer!");
01842          return (XPCWrappedNativeScope*)(XPC_SCOPE_WORD(s) | XPC_SCOPE_TAG);}
01843 
01844     static inline XPCWrappedNativeScope*
01845     UnTagScope(XPCWrappedNativeScope* s)
01846         {return (XPCWrappedNativeScope*)(XPC_SCOPE_WORD(s) & ~XPC_SCOPE_TAG);}
01847 
01848     JSBool
01849     HasProto() const {return !IsTaggedScope(mMaybeScope);}
01850 
01851     XPCWrappedNativeProto*
01852     GetProto() const {return HasProto() ? mMaybeProto : nsnull;}
01853 
01854     XPCWrappedNativeScope*
01855     GetScope() const {return HasProto() ?
01856                            mMaybeProto->GetScope() : UnTagScope(mMaybeScope);}
01857 
01858     nsISupports*
01859     GetIdentityObject() const {return mIdentity;}
01860 
01861     JSObject*
01862     GetFlatJSObject()   const {return mFlatJSObject;}
01863 
01864     XPCLock*
01865     GetLock() const {return IsValid() && HasProto() ?
01866                                 mMaybeProto->GetLock() : nsnull;}
01867 
01868     XPCNativeSet*
01869     GetSet() const {XPCAutoLock al(GetLock()); return mSet;}
01870 
01871 private:
01872     void
01873     SetSet(XPCNativeSet* set) {XPCAutoLock al(GetLock()); mSet = set;}
01874 public:
01875 
01876     XPCNativeScriptableInfo*
01877     GetScriptableInfo() const {return mScriptableInfo;}
01878 
01879     nsIXPCScriptable*      // call this wrong and you deserve to crash
01880     GetScriptableCallback() const  {return mScriptableInfo->GetCallback();}
01881 
01882     void**
01883     GetSecurityInfoAddr() {return HasProto() ?
01884                                    mMaybeProto->GetSecurityInfoAddr() : nsnull;}
01885 
01886     nsIClassInfo*
01887     GetClassInfo() const {return IsValid() && HasProto() ?
01888                             mMaybeProto->GetClassInfo() : nsnull;}
01889 
01890     JSBool
01891     HasSharedProto() const {return IsValid() && HasProto() &&
01892                             mMaybeProto->IsShared();}
01893 
01894     JSBool
01895     HasMutatedSet() const {return IsValid() &&
01896                                   (!HasProto() ||
01897                                    GetSet() != mMaybeProto->GetSet());}
01898 
01899     XPCJSRuntime*
01900     GetRuntime() const {XPCWrappedNativeScope* scope = GetScope();
01901                         return scope ? scope->GetRuntime() : nsnull;}
01902 
01903     static nsresult
01904     GetNewOrUsed(XPCCallContext& ccx,
01905                  nsISupports* Object,
01906                  XPCWrappedNativeScope* Scope,
01907                  XPCNativeInterface* Interface,
01908                  JSBool isGlobal,
01909                  XPCWrappedNative** wrapper);
01910 
01911 public:
01912     static nsresult
01913     GetUsedOnly(XPCCallContext& ccx,
01914                 nsISupports* Object,
01915                 XPCWrappedNativeScope* Scope,
01916                 XPCNativeInterface* Interface,
01917                 XPCWrappedNative** wrapper);
01918 
01919     static XPCWrappedNative*
01920     GetWrappedNativeOfJSObject(JSContext* cx, JSObject* obj,
01921                                JSObject* funobj = nsnull,
01922                                JSObject** pobj2 = nsnull,
01923                                XPCWrappedNativeTearOff** pTearOff = nsnull);
01924 
01925     static nsresult
01926     ReparentWrapperIfFound(XPCCallContext& ccx,
01927                            XPCWrappedNativeScope* aOldScope,
01928                            XPCWrappedNativeScope* aNewScope,
01929                            JSObject* aNewParent,
01930                            nsISupports* aCOMObj,
01931                            XPCWrappedNative** aWrapper);
01932 
01933     void FlatJSObjectFinalized(JSContext *cx, JSObject *obj);
01934 
01935     void SystemIsBeingShutDown(XPCCallContext& ccx);
01936 
01937 #ifdef XPC_DETECT_LEADING_UPPERCASE_ACCESS_ERRORS
01938     // This will try to find a member that is of the form "camelCased"
01939     // but was accessed from JS using "CamelCased". This is here to catch
01940     // mistakes caused by the confusion magnet that JS methods are by
01941     // convention 'foo' while C++ members are by convention 'Foo'.
01942     static void
01943     HandlePossibleNameCaseError(XPCCallContext& ccx,
01944                                 XPCNativeSet* set,
01945                                 XPCNativeInterface* iface,
01946                                 jsval name);
01947     static void
01948     HandlePossibleNameCaseError(JSContext* cx,
01949                                 XPCNativeSet* set,
01950                                 XPCNativeInterface* iface,
01951                                 jsval name);
01952 
01953 #define  HANDLE_POSSIBLE_NAME_CASE_ERROR(context, set, iface, name) \
01954     XPCWrappedNative::HandlePossibleNameCaseError(context, set, iface, name)
01955 #else
01956 #define  HANDLE_POSSIBLE_NAME_CASE_ERROR(context, set, iface, name) ((void)0)
01957 #endif
01958 
01959     enum CallMode {CALL_METHOD, CALL_GETTER, CALL_SETTER};
01960 
01961     static JSBool CallMethod(XPCCallContext& ccx,
01962                              CallMode mode = CALL_METHOD);
01963 
01964     static JSBool GetAttribute(XPCCallContext& ccx)
01965         {return CallMethod(ccx, CALL_GETTER);}
01966 
01967     static JSBool SetAttribute(XPCCallContext& ccx)
01968         {return CallMethod(ccx, CALL_SETTER);}
01969 
01970     inline JSBool HasInterfaceNoQI(XPCNativeInterface* aInterface);
01971     inline JSBool HasInterfaceNoQI(const nsIID& iid);
01972 
01973     XPCWrappedNativeTearOff* LocateTearOff(XPCCallContext& ccx,
01974                                            XPCNativeInterface* aInterface);
01975     XPCWrappedNativeTearOff* FindTearOff(XPCCallContext& ccx,
01976                                          XPCNativeInterface* aInterface,
01977                                          JSBool needJSObject = JS_FALSE,
01978                                          nsresult* pError = nsnull);
01979     void Mark() const
01980     {
01981         mSet->Mark();
01982         if(mScriptableInfo) mScriptableInfo->Mark();
01983         if(HasProto()) mMaybeProto->Mark();
01984     }
01985 
01986     // Yes, we *do* need to mark the mScriptableInfo in both cases.
01987     inline void MarkBeforeJSFinalize(JSContext* cx)
01988     {
01989         if(mScriptableInfo) mScriptableInfo->Mark();
01990         if(HasProto()) mMaybeProto->MarkBeforeJSFinalize(cx);
01991         if(mNativeWrapper)
01992         {
01993             JS_MarkGCThing(cx, mNativeWrapper, 
01994                            "XPCWrappedNative::mNativeWrapper", nsnull);
01995         }
01996     }
01997 
01998     inline void AutoMark(JSContext* cx)
01999     {
02000         // If this got called, we're being kept alive by someone who really
02001         // needs us alive and whole.  Do not let our mFlatJSObject go away.
02002         // This is the only time we should be marking our mFlatJSObject;
02003         // normally we just go away quietly when it does.  Be careful not to
02004         // mark the bogus JSVAL_ONE value we can have during init, though.
02005         if(mFlatJSObject && mFlatJSObject != (JSObject*)JSVAL_ONE)
02006         {
02007             ::JS_MarkGCThing(cx, mFlatJSObject,
02008                              "XPCWrappedNative::mFlatJSObject", nsnull);
02009         }
02010     }
02011 
02012 #ifdef DEBUG
02013     void ASSERT_SetsNotMarked() const
02014         {mSet->ASSERT_NotMarked();
02015          if(HasProto()){mMaybeProto->ASSERT_SetNotMarked();}}
02016 
02017     int DEBUG_CountOfTearoffChunks() const
02018         {int i = 0; const XPCWrappedNativeTearOffChunk* to;
02019          for(to = &mFirstChunk; to; to = to->mNextChunk) {i++;} return i;}
02020 #endif
02021 
02022     inline void SweepTearOffs();
02023 
02024     // Returns a string that shuld be free'd using JS_smprintf_free (or null).
02025     char* ToString(XPCCallContext& ccx,
02026                    XPCWrappedNativeTearOff* to = nsnull) const;
02027 
02028     static nsresult GatherProtoScriptableCreateInfo(
02029                         nsIClassInfo* classInfo,
02030                         XPCNativeScriptableCreateInfo* sciProto);
02031 
02032     JSBool HasExternalReference() const {return mRefCnt > 1;}
02033 
02034     JSObject* GetNativeWrapper()              { return mNativeWrapper; }
02035     void      SetNativeWrapper(JSObject *obj) { mNativeWrapper = obj; }
02036 
02037     // Make ctor and dtor protected (rather than private) to placate nsCOMPtr.
02038 protected:
02039     XPCWrappedNative(); // not implemented
02040 
02041     // This ctor is used if this object will have a proto.
02042     XPCWrappedNative(nsISupports* aIdentity,
02043                      XPCWrappedNativeProto* aProto);
02044 
02045     // This ctor is used if this object will NOT have a proto.
02046     XPCWrappedNative(nsISupports* aIdentity,
02047                      XPCWrappedNativeScope* aScope,
02048                      XPCNativeSet* aSet);
02049 
02050     virtual ~XPCWrappedNative();
02051 
02052 private:
02053     JSBool Init(XPCCallContext& ccx, JSObject* parent, JSBool isGlobal,
02054                 const XPCNativeScriptableCreateInfo* sci);
02055 
02056     JSBool ExtendSet(XPCCallContext& ccx, XPCNativeInterface* aInterface);
02057 
02058     nsresult InitTearOff(XPCCallContext& ccx,
02059                          XPCWrappedNativeTearOff* aTearOff,
02060                          XPCNativeInterface* aInterface,
02061                          JSBool needJSObject);
02062 
02063     JSBool InitTearOffJSObject(XPCCallContext& ccx,
02064                                 XPCWrappedNativeTearOff* to);
02065 
02066 public:
02067     static nsresult GatherScriptableCreateInfo(
02068                         nsISupports* obj,
02069                         nsIClassInfo* classInfo,
02070                         XPCNativeScriptableCreateInfo* sciProto,
02071                         XPCNativeScriptableCreateInfo* sciWrapper);
02072 
02073 private:
02074     union
02075     {
02076         XPCWrappedNativeScope*   mMaybeScope;
02077         XPCWrappedNativeProto*   mMaybeProto;
02078     };
02079     XPCNativeSet*                mSet;
02080     JSObject*                    mFlatJSObject;
02081     XPCNativeScriptableInfo*     mScriptableInfo;
02082     XPCWrappedNativeTearOffChunk mFirstChunk;
02083     JSObject*                    mNativeWrapper;
02084 
02085 #ifdef XPC_CHECK_WRAPPER_THREADSAFETY
02086 public:
02087     PRThread*          mThread; // Don't want to overload _mOwningThread
02088     static PRThread*   gMainThread;
02089 #endif
02090 };
02091 
02092 /***************************************************************************
02093 ****************************************************************************
02094 *
02095 * Core classes for wrapped JSObject for use from native code...
02096 *
02097 ****************************************************************************
02098 ***************************************************************************/
02099 
02100 // this interfaces exists so we can refcount nsXPCWrappedJSClass
02101 // {2453EBA0-A9B8-11d2-BA64-00805F8A5DD7}
02102 #define NS_IXPCONNECT_WRAPPED_JS_CLASS_IID  \
02103 { 0x2453eba0, 0xa9b8, 0x11d2,               \
02104   { 0xba, 0x64, 0x0, 0x80, 0x5f, 0x8a, 0x5d, 0xd7 } }
02105 
02106 class nsIXPCWrappedJSClass : public nsISupports
02107 {
02108 public:
02109     NS_DEFINE_STATIC_IID_ACCESSOR(NS_IXPCONNECT_WRAPPED_JS_CLASS_IID)
02110     NS_IMETHOD DebugDump(PRInt16 depth) = 0;
02111 };
02112 
02113 /*************************/
02114 // nsXPCWrappedJSClass represents the sharable factored out common code and
02115 // data for nsXPCWrappedJS instances for the same interface type.
02116 
02117 class nsXPCWrappedJSClass : public nsIXPCWrappedJSClass
02118 {
02119     // all the interface method declarations...
02120     NS_DECL_ISUPPORTS
02121     NS_IMETHOD DebugDump(PRInt16 depth);
02122 public:
02123 
02124     static nsresult
02125     GetNewOrUsed(XPCCallContext& ccx,
02126                  REFNSIID aIID,
02127                  nsXPCWrappedJSClass** clazz);
02128 
02129     REFNSIID GetIID() const {return mIID;}
02130     XPCJSRuntime* GetRuntime() const {return mRuntime;}
02131     nsIInterfaceInfo* GetInterfaceInfo() const {return mInfo;}
02132     const char* GetInterfaceName();
02133 
02134     static JSBool IsWrappedJS(nsISupports* aPtr);
02135 
02136     NS_IMETHOD DelegatedQueryInterface(nsXPCWrappedJS* self, REFNSIID aIID,
02137                                        void** aInstancePtr);
02138 
02139     JSObject* GetRootJSObject(XPCCallContext& ccx, JSObject* aJSObj);
02140 
02141     NS_IMETHOD CallMethod(nsXPCWrappedJS* wrapper, uint16 methodIndex,
02142                           const nsXPTMethodInfo* info,
02143                           nsXPTCMiniVariant* params);
02144 
02145     JSObject*  CallQueryInterfaceOnJSObject(XPCCallContext& ccx,
02146                                             JSObject* jsobj, REFNSIID aIID);
02147 
02148     static nsresult BuildPropertyEnumerator(XPCCallContext& ccx,
02149                                             JSObject* aJSObj,
02150                                             nsISimpleEnumerator** aEnumerate);
02151 
02152     static nsresult GetNamedPropertyAsVariant(XPCCallContext& ccx, 
02153                                               JSObject* aJSObj,
02154                                               jsval aName, 
02155                                               nsIVariant** aResult);
02156 
02157     virtual ~nsXPCWrappedJSClass();
02158 
02159     static nsresult CheckForException(XPCCallContext & ccx,
02160                                       const char * aPropertyName,
02161                                       const char * anInterfaceName);
02162 private:
02163     nsXPCWrappedJSClass();   // not implemented
02164     nsXPCWrappedJSClass(XPCCallContext& ccx, REFNSIID aIID,
02165                         nsIInterfaceInfo* aInfo);
02166 
02167     JSObject*  NewOutObject(JSContext* cx);
02168 
02169     JSBool IsReflectable(uint16 i) const
02170         {return (JSBool)(mDescriptors[i/32] & (1 << (i%32)));}
02171     void SetReflectable(uint16 i, JSBool b)
02172         {if(b) mDescriptors[i/32] |= (1 << (i%32));
02173          else mDescriptors[i/32] &= ~(1 << (i%32));}
02174 
02175     enum SizeMode {GET_SIZE, GET_LENGTH};
02176 
02177     JSBool GetArraySizeFromParam(JSContext* cx,
02178                                  const nsXPTMethodInfo* method,
02179                                  const nsXPTParamInfo& param,
02180                                  uint16 methodIndex,
02181                                  uint8 paramIndex,
02182                                  SizeMode mode,
02183                                  nsXPTCMiniVariant* params,
02184                                  JSUint32* result);
02185 
02186     JSBool GetInterfaceTypeFromParam(JSContext* cx,
02187                                      const nsXPTMethodInfo* method,
02188                                      const nsXPTParamInfo& param,
02189                                      uint16 methodIndex,
02190                                      const nsXPTType& type,
02191                                      nsXPTCMiniVariant* params,
02192                                      nsID* result);
02193 
02194     void CleanupPointerArray(const nsXPTType& datum_type,
02195                              JSUint32 array_count,
02196                              void** arrayp);
02197 
02198     void CleanupPointerTypeObject(const nsXPTType& type,
02199                                   void** pp);
02200 
02201 private:
02202     XPCJSRuntime* mRuntime;
02203     nsIInterfaceInfo* mInfo;
02204     char* mName;
02205     nsIID mIID;
02206     uint32* mDescriptors;
02207 };
02208 
02209 /*************************/
02210 // nsXPCWrappedJS is a wrapper for a single JSObject for use from native code.
02211 // nsXPCWrappedJS objects are chained together to represent the various
02212 // interface on the single underlying (possibly aggregate) JSObject.
02213 
02214 class nsXPCWrappedJS : public nsXPTCStubBase,
02215                        public nsWeakRefToIXPConnectWrappedJS,
02216                        public nsSupportsWeakReference,
02217                        public nsIPropertyBag
02218 {
02219 public:
02220     NS_DECL_ISUPPORTS
02221     NS_DECL_NSIXPCONNECTJSOBJECTHOLDER
02222     NS_DECL_NSIXPCONNECTWRAPPEDJS
02223     NS_DECL_NSIXPCONNECTWRAPPEDJS_MOZILLA_1_8_BRANCH
02224     //NS_DECL_NSISUPPORTSWEAKREFERENCE // methods also on nsIXPConnectWrappedJS
02225     NS_DECL_NSIPROPERTYBAG
02226 
02227     // Note that both nsXPTCStubBase and nsIXPConnectWrappedJS declare
02228     // GetInterfaceInfo methods with the same sig. So, the declaration
02229     // for it here comes from the NS_DECL_NSIXPCONNECTWRAPPEDJS macro
02230 
02231     NS_IMETHOD CallMethod(PRUint16 methodIndex,
02232                           const nsXPTMethodInfo* info,
02233                           nsXPTCMiniVariant* params);
02234 
02235     /*
02236     * This is rarely called directly. Instead one usually calls
02237     * XPCConvert::JSObject2NativeInterface which will handles cases where the
02238     * JS object is already a wrapped native or a DOM object.
02239     */
02240 
02241     static nsresult
02242     GetNewOrUsed(XPCCallContext& ccx,
02243                  JSObject* aJSObj,
02244                  REFNSIID aIID,
02245                  nsISupports* aOuter,
02246                  nsXPCWrappedJS** wrapper);
02247 
02248     JSObject* GetJSObject() const {return mJSObj;}
02249     nsXPCWrappedJSClass*  GetClass() const {return mClass;}
02250     REFNSIID GetIID() const {return GetClass()->GetIID();}
02251     nsXPCWrappedJS* GetRootWrapper() const {return mRoot;}
02252     nsXPCWrappedJS* GetNextWrapper() const {return mNext;}
02253 
02254     nsXPCWrappedJS* Find(REFNSIID aIID);
02255     nsXPCWrappedJS* FindInherited(REFNSIID aIID);
02256 
02257     JSBool IsValid() const {return mJSObj != nsnull;}
02258     void SystemIsBeingShutDown(JSRuntime* rt);
02259 
02260     // This is used by XPCJSRuntime::GCCallback to find wrappers that no
02261     // longer root their JSObject and are only still alive because they
02262     // were being used via nsSupportsWeakReference at the time when their
02263     // last (outside) reference was released. Wrappers that fit into that
02264     // category are only deleted when we see that their corresponding JSObject
02265     // is to be finalized.
02266     JSBool IsSubjectToFinalization() const {return IsValid() && mRefCnt == 1;}
02267 
02268     JSBool IsAggregatedToNative() const {return mRoot->mOuter != nsnull;}
02269     nsISupports* GetAggregatedNativeObject() const {return mRoot->mOuter;}
02270 
02271     virtual ~nsXPCWrappedJS();
02272 protected:
02273     nsXPCWrappedJS();   // not implemented
02274     nsXPCWrappedJS(XPCCallContext& ccx,
02275                    JSObject* aJSObj,
02276                    nsXPCWrappedJSClass* aClass,
02277                    nsXPCWrappedJS* root,
02278                    nsISupports* aOuter);
02279 
02280 private:
02281     JSObject* mJSObj;
02282     nsXPCWrappedJSClass* mClass;
02283     nsXPCWrappedJS* mRoot;
02284     nsXPCWrappedJS* mNext;
02285     nsISupports* mOuter;    // only set in root
02286 #ifdef GC_MARK_DEBUG
02287     char *mGCRootName;
02288 #endif
02289 };
02290 
02291 /***************************************************************************/
02292 
02293 class XPCJSObjectHolder : public nsIXPConnectJSObjectHolder
02294 {
02295 public:
02296     // all the interface method declarations...
02297     NS_DECL_ISUPPORTS
02298     NS_DECL_NSIXPCONNECTJSOBJECTHOLDER
02299 
02300     // non-interface implementation
02301 
02302 public:
02303     static XPCJSObjectHolder* newHolder(JSContext* cx, JSObject* obj);
02304 
02305     virtual ~XPCJSObjectHolder();
02306 
02307 private:
02308     XPCJSObjectHolder(JSContext* cx, JSObject* obj);
02309     XPCJSObjectHolder(); // not implemented
02310 
02311     JSRuntime* mRuntime;
02312     JSObject* mJSObj;
02313 };
02314 
02315 /***************************************************************************
02316 ****************************************************************************
02317 *
02318 * All manner of utility classes follow...
02319 *
02320 ****************************************************************************
02321 ***************************************************************************/
02322 
02323 class xpcProperty : public nsIProperty
02324 {
02325 public:
02326   NS_DECL_ISUPPORTS
02327   NS_DECL_NSIPROPERTY
02328 
02329   xpcProperty(const PRUnichar* aName, PRUint32 aNameLen, nsIVariant* aValue);
02330   virtual ~xpcProperty() {}
02331 
02332 private:
02333     nsString             mName;
02334     nsCOMPtr<nsIVariant> mValue;
02335 };
02336 
02337 class xpcPropertyBagEnumerator : public nsISimpleEnumerator
02338 {
02339 public:
02340     NS_DECL_ISUPPORTS
02341     NS_DECL_NSISIMPLEENUMERATOR
02342 
02343     xpcPropertyBagEnumerator(PRUint32 count);
02344     virtual ~xpcPropertyBagEnumerator() {}
02345 
02346     JSBool AppendElement(nsISupports* element);
02347 
02348 private:
02349     nsSupportsArray mArray;
02350     PRUint32        mIndex;
02351     PRUint32        mCount;
02352 };
02353 
02354 /***************************************************************************/
02355 // data conversion
02356 
02357 // class here just for static methods
02358 class XPCConvert
02359 {
02360 public:
02361     static JSBool IsMethodReflectable(const nsXPTMethodInfo& info);
02362 
02375     static JSBool NativeData2JS(XPCCallContext& ccx, jsval* d, const void* s,
02376                                 const nsXPTType& type, const nsID* iid,
02377                                 JSObject* scope, nsresult* pErr);
02378 
02379     static JSBool JSData2Native(XPCCallContext& ccx, void* d, jsval s,
02380                                 const nsXPTType& type,
02381                                 JSBool useAllocator, const nsID* iid,
02382                                 nsresult* pErr);
02383 
02397     static JSBool NativeInterface2JSObject(XPCCallContext& ccx,
02398                                            nsIXPConnectJSObjectHolder** dest,
02399                                            nsISupports* src,
02400                                            const nsID* iid,
02401                                            JSObject* scope,
02402                                            PRBool allowNativeWrapper,
02403                                            PRBool isGlobal,
02404                                            nsresult* pErr);
02405 
02406     static JSBool GetNativeInterfaceFromJSObject(XPCCallContext& ccx,
02407                                                  void** dest, JSObject* src,
02408                                                  const nsID* iid, 
02409                                                  nsresult* pErr);
02410     static JSBool JSObject2NativeInterface(XPCCallContext& ccx,
02411                                            void** dest, JSObject* src,
02412                                            const nsID* iid,
02413                                            nsISupports* aOuter,
02414                                            nsresult* pErr);
02415 
02429     static JSBool NativeArray2JS(XPCCallContext& ccx,
02430                                  jsval* d, const void** s,
02431                                  const nsXPTType& type, const nsID* iid,
02432                                  JSUint32 count, JSObject* scope,
02433                                  nsresult* pErr);
02434 
02435     static JSBool JSArray2Native(XPCCallContext& ccx, void** d, jsval s,
02436                                  JSUint32 count, JSUint32 capacity,
02437                                  const nsXPTType& type,
02438                                  JSBool useAllocator, const nsID* iid,
02439                                  uintN* pErr);
02440 
02441     static JSBool NativeStringWithSize2JS(XPCCallContext& ccx,
02442                                           jsval* d, const void* s,
02443                                           const nsXPTType& type,
02444                                           JSUint32 count,
02445                                           nsresult* pErr);
02446 
02447     static JSBool JSStringWithSize2Native(XPCCallContext& ccx, void* d, jsval s,
02448                                           JSUint32 count, JSUint32 capacity,
02449                                           const nsXPTType& type,
02450                                           JSBool useAllocator,
02451                                           uintN* pErr);
02452 
02453     static nsresult JSValToXPCException(XPCCallContext& ccx,
02454                                         jsval s,
02455                                         const char* ifaceName,
02456                                         const char* methodName,
02457                                         nsIException** exception);
02458 
02459     static nsresult JSErrorToXPCException(XPCCallContext& ccx,
02460                                           const char* message,
02461                                           const char* ifaceName,
02462                                           const char* methodName,
02463                                           const JSErrorReport* report,
02464                                           nsIException** exception);
02465 
02466     static nsresult ConstructException(nsresult rv, const char* message,
02467                                        const char* ifaceName,
02468                                        const char* methodName,
02469                                        nsISupports* data,                                       
02470                                        nsIException** exception);
02471 
02472     static void RemoveXPCOMUCStringFinalizer();
02473 
02474 private:
02475     XPCConvert(); // not implemented
02476 
02477 };
02478 
02479 /***************************************************************************/
02480 
02481 // class to export a JSString as an const nsAString, no refcounting :(
02482 class XPCReadableJSStringWrapper : public nsDependentString
02483 {
02484 public:
02485     typedef nsDependentString::char_traits char_traits;
02486 
02487     XPCReadableJSStringWrapper(PRUnichar *chars, size_t length) :
02488         nsDependentString(chars, length)
02489     { }
02490 
02491     XPCReadableJSStringWrapper() :
02492         nsDependentString(char_traits::sEmptyBuffer, char_traits::sEmptyBuffer)
02493     { SetIsVoid(PR_TRUE); }
02494 };
02495 
02496 // readable string conversions, static methods only
02497 class XPCStringConvert
02498 {
02499 public:
02500 
02501     static JSString *ReadableToJSString(JSContext *cx,
02502                                         const nsAString &readable);
02503 
02504     static XPCReadableJSStringWrapper *JSStringToReadable(JSString *str);
02505 
02506     static void ShutdownDOMStringFinalizer();
02507 
02508 private:
02509     XPCStringConvert();         // not implemented
02510 };
02511 
02512 extern JSBool JS_DLL_CALLBACK
02513 XPC_JSArgumentFormatter(JSContext *cx, const char *format,
02514                         JSBool fromJS, jsval **vpp, va_list *app);
02515 
02516 
02517 /***************************************************************************/
02518 // code for throwing exceptions into JS
02519 
02520 class XPCThrower
02521 {
02522 public:
02523     static void Throw(nsresult rv, JSContext* cx);
02524     static void Throw(nsresult rv, XPCCallContext& ccx);
02525     static void ThrowBadResult(nsresult rv, nsresult result, XPCCallContext& ccx);
02526     static void ThrowBadParam(nsresult rv, uintN paramNum, XPCCallContext& ccx);
02527 #ifdef XPC_IDISPATCH_SUPPORT
02528     static void ThrowCOMError(JSContext* cx, unsigned long COMErrorCode, 
02529                               nsresult rv = NS_ERROR_XPC_COM_ERROR,
02530                               const EXCEPINFO * exception = nsnull);
02531 #endif
02532     static JSBool SetVerbosity(JSBool state)
02533         {JSBool old = sVerbose; sVerbose = state; return old;}
02534 
02535 private:
02536     static void Verbosify(XPCCallContext& ccx,
02537                           char** psz, PRBool own);
02538 
02539     static void BuildAndThrowException(JSContext* cx, nsresult rv, const char* sz);
02540     static JSBool ThrowExceptionObject(JSContext* cx, nsIException* e);
02541     static JSBool CheckForPendingException(nsresult result, XPCCallContext &ccx);
02542 
02543 private:
02544     static JSBool sVerbose;
02545 };
02546 
02547 
02548 /***************************************************************************/
02549 
02550 class XPCJSStack
02551 {
02552 public:
02553     static nsresult
02554     CreateStack(JSContext* cx, nsIStackFrame** stack);
02555 
02556     static nsresult
02557     CreateStackFrameLocation(PRUint32 aLanguage,
02558                              const char* aFilename,
02559                              const char* aFunctionName,
02560                              PRInt32 aLineNumber,
02561                              nsIStackFrame* aCaller,
02562                              nsIStackFrame** stack);
02563 private:
02564     XPCJSStack();   // not implemented
02565 };
02566 
02567 /***************************************************************************/
02568 
02569 class nsXPCException :
02570             public nsIXPCException
02571 #ifdef XPC_USE_SECURITY_CHECKED_COMPONENT
02572           , public nsISecurityCheckedComponent
02573 #endif
02574 {
02575 public:
02576     NS_DEFINE_STATIC_CID_ACCESSOR(NS_XPCEXCEPTION_CID)
02577 
02578     NS_DECL_ISUPPORTS
02579     NS_DECL_NSIEXCEPTION
02580     NS_DECL_NSIXPCEXCEPTION
02581 #ifdef XPC_USE_SECURITY_CHECKED_COMPONENT
02582     NS_DECL_NSISECURITYCHECKEDCOMPONENT
02583 #endif
02584 
02585     static nsresult NewException(const char *aMessage,
02586                                  nsresult aResult,
02587                                  nsIStackFrame *aLocation,
02588                                  nsISupports *aData,
02589                                  nsIException** exception);
02590 
02591     static JSBool NameAndFormatForNSResult(nsresult rv,
02592                                            const char** name,
02593                                            const char** format);
02594 
02595     static void* IterateNSResults(nsresult* rv,
02596                                   const char** name,
02597                                   const char** format,
02598                                   void** iterp);
02599 
02600     static PRUint32 GetNSResultCount();
02601 
02602     nsXPCException();
02603     virtual ~nsXPCException();
02604 
02605     static void InitStatics() { sEverMadeOneFromFactory = JS_FALSE; }
02606 
02607 protected:
02608     void Reset();
02609 private:
02610     char*           mMessage;
02611     nsresult        mResult;
02612     char*           mName;
02613     nsIStackFrame*  mLocation;
02614     nsISupports*    mData;
02615     char*           mFilename;
02616     int             mLineNumber;
02617     nsIException*   mInner;
02618     PRBool          mInitialized;
02619 
02620     static JSBool sEverMadeOneFromFactory;
02621 };
02622 
02623 /***************************************************************************/
02624 /*
02625 * nsJSID implements nsIJSID. It is also used by nsJSIID and nsJSCID as a
02626 * member (as a hidden implementaion detail) to which they delegate many calls.
02627 */
02628 
02629 extern JSBool xpc_InitJSxIDClassObjects();
02630 extern void xpc_DestroyJSxIDClassObjects();
02631 
02632 
02633 class nsJSID : public nsIJSID
02634 {
02635 public:
02636     NS_DEFINE_STATIC_CID_ACCESSOR(NS_JS_ID_CID)
02637 
02638     NS_DECL_ISUPPORTS
02639     NS_DECL_NSIJSID
02640 
02641     PRBool InitWithName(const nsID& id, const char *nameString);
02642     PRBool SetName(const char* name);
02643     void   SetNameToNoString()
02644         {NS_ASSERTION(!mName, "name already set"); mName = gNoString;}
02645     PRBool NameIsSet() const {return nsnull != mName;}
02646     const nsID* GetID() const {return &mID;}
02647 
02648     PRBool IsValid() const {return !mID.Equals(GetInvalidIID());}
02649 
02650     static nsJSID* NewID(const char* str);
02651 
02652     nsJSID();
02653     virtual ~nsJSID();
02654 protected:
02655 
02656     void Reset();
02657     const nsID& GetInvalidIID() const;
02658 
02659 protected:
02660     static char gNoString[];
02661     nsID    mID;
02662     char*   mNumber;
02663     char*   mName;
02664 };
02665 
02666 // nsJSIID
02667 
02668 class nsJSIID : public nsIJSIID, public nsIXPCScriptable
02669 #ifdef XPC_USE_SECURITY_CHECKED_COMPONENT
02670           , public nsISecurityCheckedComponent
02671 #endif
02672 {
02673 public:
02674     NS_DECL_ISUPPORTS
02675 
02676     // we manually delagate these to nsJSID
02677     NS_DECL_NSIJSID
02678 
02679     // we implement the rest...
02680     NS_DECL_NSIJSIID
02681     NS_DECL_NSIXPCSCRIPTABLE
02682 #ifdef XPC_USE_SECURITY_CHECKED_COMPONENT
02683     NS_DECL_NSISECURITYCHECKEDCOMPONENT
02684 #endif
02685 
02686     static nsJSIID* NewID(nsIInterfaceInfo* aInfo);
02687 
02688     nsJSIID(nsIInterfaceInfo* aInfo);
02689     nsJSIID(); // not implemented
02690     virtual ~nsJSIID();
02691 
02692 private:
02693     nsCOMPtr<nsIInterfaceInfo> mInfo;
02694 };
02695 
02696 // nsJSCID
02697 
02698 class nsJSCID : public nsIJSCID, public nsIXPCScriptable
02699 {
02700 public:
02701     NS_DECL_ISUPPORTS
02702 
02703     // we manually delagate these to nsJSID
02704     NS_DECL_NSIJSID
02705 
02706     // we implement the rest...
02707     NS_DECL_NSIJSCID
02708     NS_DECL_NSIXPCSCRIPTABLE
02709 
02710     static nsJSCID* NewID(const char* str);
02711 
02712     nsJSCID();
02713     virtual ~nsJSCID();
02714 
02715 private:
02716     void ResolveName();
02717 
02718 private:
02719     nsJSID mDetails;
02720 };
02721 
02722 
02723 /***************************************************************************/
02724 // XPCJSContextStack is not actually an xpcom object, but xpcom calls are
02725 // delegated to it as an implementation detail.
02726 struct JSContextAndFrame {
02727     JSContextAndFrame(JSContext* aCx) :
02728         cx(aCx),
02729         frame(nsnull)
02730     {}
02731     JSContext* cx;
02732     JSStackFrame* frame;  // Frame to be restored when this JSContext becomes
02733                           // the topmost one.
02734 };
02735 
02736 class XPCJSContextStack
02737 {
02738 public:
02739     NS_DECL_NSIJSCONTEXTSTACK
02740     NS_DECL_NSITHREADJSCONTEXTSTACK
02741 
02742     XPCJSContextStack();
02743     virtual ~XPCJSContextStack();
02744 
02745 #ifdef DEBUG
02746     JSBool DEBUG_StackHasJSContext(JSContext*  aJSContext);
02747 #endif
02748 
02749     const nsTArray<JSContextAndFrame>* GetStack()
02750     { return &mStack; }
02751 
02752 private:
02753     void SyncJSContexts();
02754 
02755 private:
02756     nsTArray<JSContextAndFrame> mStack;
02757     JSContext*  mSafeJSContext;
02758 
02759     // If non-null, we own it; same as mSafeJSContext if SetSafeJSContext
02760     // not called.
02761     JSContext*  mOwnSafeJSContext;
02762 };
02763 
02764 /***************************************************************************/
02765 
02766 #define NS_XPC_JSCONTEXT_STACK_ITERATOR_CID \
02767 { 0x05bae29d, 0x8aef, 0x486d, \
02768   { 0x84, 0xaa, 0x53, 0xf4, 0x8f, 0x14, 0x68, 0x11 } }
02769 
02770 class nsXPCJSContextStackIterator : public nsIJSContextStackIterator
02771 {
02772 public:
02773     NS_DECL_ISUPPORTS
02774     NS_DECL_NSIJSCONTEXTSTACKITERATOR
02775 
02776 private:
02777     const nsTArray<JSContextAndFrame> *mStack;
02778     PRUint32 mPosition;
02779 };
02780 
02781 /**************************************************************/
02782 // All of our thread local storage.
02783 
02784 #define BAD_TLS_INDEX ((PRUint32) -1)
02785 
02786 class XPCPerThreadData
02787 {
02788 public:
02789     // Get the instance of this object for the current thread
02790     static XPCPerThreadData* GetData();
02791     static void CleanupAllThreads();
02792 
02793     ~XPCPerThreadData();
02794 
02795     nsresult GetException(nsIException** aException)
02796     {
02797         if(EnsureExceptionManager())
02798             return mExceptionManager->GetCurrentException(aException);
02799 
02800         NS_IF_ADDREF(mException);
02801         *aException = mException;
02802         return NS_OK;
02803     }
02804 
02805     nsresult SetException(nsIException* aException)
02806     {
02807         if(EnsureExceptionManager())
02808             return mExceptionManager->SetCurrentException(aException);
02809 
02810         NS_IF_ADDREF(aException);
02811         NS_IF_RELEASE(mException);
02812         mException = aException;
02813         return NS_OK;
02814     }
02815 
02816     nsIExceptionManager* GetExceptionManager()
02817     {
02818         if(EnsureExceptionManager())
02819             return mExceptionManager;
02820         return nsnull;
02821     }
02822 
02823     JSBool EnsureExceptionManager()
02824     {
02825         if(mExceptionManager)
02826             return JS_TRUE;
02827 
02828         if(mExceptionManagerNotAvailable)
02829             return JS_FALSE;
02830 
02831         nsCOMPtr<nsIExceptionService> xs =
02832             do_GetService(NS_EXCEPTIONSERVICE_CONTRACTID);
02833         if(xs)
02834             xs->GetCurrentExceptionManager(&mExceptionManager);
02835         if(mExceptionManager)
02836             return JS_TRUE;
02837 
02838         mExceptionManagerNotAvailable = JS_TRUE;
02839         return JS_FALSE;
02840     }
02841 
02842     XPCJSContextStack* GetJSContextStack() {return mJSContextStack;}
02843 
02844     XPCCallContext*  GetCallContext() const {return mCallContext;}
02845     XPCCallContext*  SetCallContext(XPCCallContext* ccx)
02846         {XPCCallContext* old = mCallContext; mCallContext = ccx; return old;}
02847 
02848     jsval GetResolveName() const {return mResolveName;}
02849     jsval SetResolveName(jsval name)
02850         {jsval old = mResolveName; mResolveName = name; return old;}
02851 
02852     XPCWrappedNative* GetResolvingWrapper() const {return mResolvingWrapper;}
02853     XPCWrappedNative* SetResolvingWrapper(XPCWrappedNative* w)
02854         {XPCWrappedNative* old = mResolvingWrapper;
02855          mResolvingWrapper = w; return old;}
02856 
02857     void Cleanup();
02858 
02859     PRBool IsValid() const {return mJSContextStack != nsnull;}
02860 
02861     static PRLock* GetLock() {return gLock;}
02862     // Must be called with the threads locked.
02863     static XPCPerThreadData* IterateThreads(XPCPerThreadData** iteratorp);
02864 
02865     XPCContext* GetRecentXPCContext(JSContext* cx) const
02866         {return cx == mMostRecentJSContext ? mMostRecentXPCContext : nsnull;}
02867 
02868     void SetRecentContext(JSContext* cx, XPCContext* xpcc)
02869         {mMostRecentJSContext = cx; mMostRecentXPCContext = xpcc;}
02870 
02871     void ClearRecentContext()
02872         {mMostRecentJSContext = nsnull; mMostRecentXPCContext = nsnull;}
02873 
02874     AutoMarkingPtr**  GetAutoRootsAdr() {return &mAutoRoots;}
02875 
02876     void MarkAutoRootsBeforeJSFinalize(JSContext* cx);
02877     void MarkAutoRootsAfterJSFinalize();
02878 
02879     jsuword GetStackLimit() const { return mStackLimit; }
02880 
02881     static void InitStatics()
02882         { gLock = nsnull; gThreads = nsnull; gTLSIndex = BAD_TLS_INDEX; }
02883 
02884 #ifdef XPC_CHECK_WRAPPER_THREADSAFETY
02885     JSUint32  IncrementWrappedNativeThreadsafetyReportDepth()
02886         {return ++mWrappedNativeThreadsafetyReportDepth;}
02887     void      ClearWrappedNativeThreadsafetyReportDepth()
02888         {mWrappedNativeThreadsafetyReportDepth = 0;}
02889 #endif
02890 
02891 private:
02892     XPCPerThreadData();
02893 
02894 private:
02895     XPCJSContextStack*   mJSContextStack;
02896     XPCPerThreadData*    mNextThread;
02897     XPCCallContext*      mCallContext;
02898     jsval                mResolveName;
02899     XPCWrappedNative*    mResolvingWrapper;
02900 
02901     JSContext*           mMostRecentJSContext;
02902     XPCContext*          mMostRecentXPCContext;
02903 
02904     nsIExceptionManager* mExceptionManager;
02905     nsIException*        mException;
02906     JSBool               mExceptionManagerNotAvailable;
02907     AutoMarkingPtr*      mAutoRoots;
02908 
02909     jsuword              mStackLimit;
02910 
02911 #ifdef XPC_CHECK_WRAPPER_THREADSAFETY
02912     JSUint32             mWrappedNativeThreadsafetyReportDepth;
02913 #endif
02914 
02915     static PRLock*           gLock;
02916     static XPCPerThreadData* gThreads;
02917     static PRUintn           gTLSIndex;
02918 };
02919 
02920 /**************************************************************/
02921 
02922 #define NS_XPC_THREAD_JSCONTEXT_STACK_CID  \
02923 { 0xff8c4d10, 0x3194, 0x11d3, \
02924     { 0x98, 0x85, 0x0, 0x60, 0x8, 0x96, 0x24, 0x22 } }
02925 
02926 class nsXPCThreadJSContextStackImpl : public nsIThreadJSContextStack,
02927                                       public nsSupportsWeakReference
02928 {
02929 public:
02930     NS_DECL_ISUPPORTS
02931     NS_DECL_NSIJSCONTEXTSTACK
02932     NS_DECL_NSITHREADJSCONTEXTSTACK
02933 
02934     // This returns and AddRef'd pointer. It does not do this with an out param
02935     // only because this form  is required by generic module macro:
02936     // NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR
02937     static nsXPCThreadJSContextStackImpl* GetSingleton();
02938 
02939     static void InitStatics() { gXPCThreadJSContextStack = nsnull; }
02940     static void FreeSingleton();
02941 
02942     nsXPCThreadJSContextStackImpl();
02943     virtual ~nsXPCThreadJSContextStackImpl();
02944 
02945 private:
02946     XPCJSContextStack* GetStackForCurrentThread()
02947         {XPCPerThreadData* data = XPCPerThreadData::GetData();
02948          return data ? data->GetJSContextStack() : nsnull;}
02949 
02950     static nsXPCThreadJSContextStackImpl* gXPCThreadJSContextStack;
02951     friend class nsXPCJSContextStackIterator;
02952 };
02953 
02954 /***************************************************************************/
02955 #define NS_JS_RUNTIME_SERVICE_CID \
02956 {0xb5e65b52, 0x1dd1, 0x11b2, \
02957     { 0xae, 0x8f, 0xf0, 0x92, 0x8e, 0xd8, 0x84, 0x82 }}
02958 
02959 #ifndef XPCONNECT_STANDALONE
02960 #include "nsIScriptSecurityManager.h"
02961 #include "nsIPrincipal.h"
02962 #include "nsIScriptObjectPrincipal.h"
02963 
02964 class BackstagePass : public nsIScriptObjectPrincipal, public nsIXPCScriptable
02965 {
02966 public:
02967   NS_DECL_ISUPPORTS
02968   NS_DECL_NSIXPCSCRIPTABLE
02969   
02970   virtual nsIPrincipal* GetPrincipal() {
02971     return mPrincipal;
02972   }
02973 
02974   BackstagePass(nsIPrincipal *prin) :
02975     mPrincipal(prin)
02976   {
02977   }
02978 
02979   virtual ~BackstagePass() { }
02980 
02981 private:
02982   nsCOMPtr<nsIPrincipal> mPrincipal;
02983 };
02984 
02985 #else
02986 
02987 class BackstagePass : public nsIXPCScriptable
02988 {
02989 public:
02990   NS_DECL_ISUPPORTS
02991   NS_DECL_NSIXPCSCRIPTABLE
02992 
02993   BackstagePass()
02994   {
02995   }
02996 
02997   virtual ~BackstagePass() { }
02998 };
02999 
03000 #endif
03001 
03002 class nsJSRuntimeServiceImpl : public nsIJSRuntimeService,
03003                                public nsSupportsWeakReference
03004 {
03005  public:
03006     NS_DECL_ISUPPORTS
03007     NS_DECL_NSIJSRUNTIMESERVICE
03008 
03009     // This returns an AddRef'd pointer. It does not do this with an out param
03010     // only because this form  is required by generic module macro:
03011     // NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR
03012     static nsJSRuntimeServiceImpl* GetSingleton();
03013 
03014     static void FreeSingleton();
03015 
03016     nsJSRuntimeServiceImpl();
03017     virtual ~nsJSRuntimeServiceImpl();
03018 
03019     static void InitStatics() { gJSRuntimeService = nsnull; }
03020  protected:
03021     JSRuntime *mRuntime;
03022     static nsJSRuntimeServiceImpl* gJSRuntimeService;
03023     nsCOMPtr<nsIXPCScriptable> mBackstagePass;
03024 };
03025 
03026 /***************************************************************************/
03027 // 'Components' object
03028 
03029 class nsXPCComponents : public nsIXPCComponents,
03030                         public nsIXPCScriptable
03031 #ifdef XPC_USE_SECURITY_CHECKED_COMPONENT
03032                       , public nsISecurityCheckedComponent
03033 #endif
03034 {
03035 public:
03036     NS_DECL_ISUPPORTS
03037     NS_DECL_NSIXPCCOMPONENTS
03038     NS_DECL_NSIXPCSCRIPTABLE
03039 
03040 #ifdef XPC_USE_SECURITY_CHECKED_COMPONENT
03041     NS_DECL_NSISECURITYCHECKEDCOMPONENT
03042 #endif
03043 
03044 public:
03045     static JSBool
03046     AttachNewComponentsObject(XPCCallContext& ccx,
03047                               XPCWrappedNativeScope* aScope,
03048                               JSObject* aGlobal);
03049 
03050     void SystemIsBeingShutDown() {ClearMembers();}
03051 
03052     virtual ~nsXPCComponents();
03053 
03054 private:
03055     nsXPCComponents();
03056     void ClearMembers();
03057 
03058 private:
03059     nsXPCComponents_Interfaces*     mInterfaces;
03060     nsXPCComponents_InterfacesByID* mInterfacesByID;
03061     nsXPCComponents_Classes*        mClasses;
03062     nsXPCComponents_ClassesByID*    mClassesByID;
03063     nsXPCComponents_Results*        mResults;
03064     nsXPCComponents_ID*             mID;
03065     nsXPCComponents_Exception*      mException;
03066     nsXPCComponents_Constructor*    mConstructor;
03067     nsXPCComponents_Utils*          mUtils;
03068 };
03069 
03070 /***************************************************************************/
03071 
03072 class nsXPCComponents_Interfaces :
03073             public nsIScriptableInterfaces,
03074             public nsIXPCScriptable
03075 #ifdef XPC_USE_SECURITY_CHECKED_COMPONENT
03076           , public nsISecurityCheckedComponent
03077 #endif
03078 {
03079 public:
03080     // all the interface method declarations...
03081     NS_DECL_ISUPPORTS
03082     NS_DECL_NSISCRIPTABLEINTERFACES
03083     NS_DECL_NSIXPCSCRIPTABLE
03084 #ifdef XPC_USE_SECURITY_CHECKED_COMPONENT
03085     NS_DECL_NSISECURITYCHECKEDCOMPONENT
03086 #endif
03087 
03088 public:
03089     nsXPCComponents_Interfaces();
03090     virtual ~nsXPCComponents_Interfaces();
03091 
03092 private:
03093     nsCOMPtr<nsIInterfaceInfoManager> mManager;
03094 };
03095 
03096 
03097 /***************************************************************************/
03098 
03099 extern JSObject*
03100 xpc_NewIDObject(JSContext *cx, JSObject* jsobj, const nsID& aID);
03101 
03102 extern nsID*
03103 xpc_JSObjectToID(JSContext *cx, JSObject* obj);
03104 
03105 extern JSBool
03106 xpc_JSObjectIsID(JSContext *cx, JSObject* obj);
03107 
03108 /***************************************************************************/
03109 // in xpcdebug.cpp
03110 
03111 extern JSBool
03112 xpc_DumpJSStack(JSContext* cx, JSBool showArgs, JSBool showLocals,
03113                 JSBool showThisProps);
03114 
03115 extern JSBool
03116 xpc_DumpEvalInJSStackFrame(JSContext* cx, JSUint32 frameno, const char* text);
03117 
03118 extern JSBool
03119 xpc_DumpJSObject(JSObject* obj);
03120 
03121 extern JSBool
03122 xpc_InstallJSDebuggerKeywordHandler(JSRuntime* rt);
03123 
03124 /***************************************************************************/
03125 
03126 // Definition of nsScriptError, defined here because we lack a place to put
03127 // XPCOM objects associated with the JavaScript engine.
03128 class nsScriptError : public nsIScriptError {
03129 public:
03130     nsScriptError();
03131 
03132     virtual ~nsScriptError();
03133 
03134   // TODO - do something reasonable on getting null from these babies.
03135 
03136     NS_DECL_ISUPPORTS
03137     NS_DECL_NSICONSOLEMESSAGE
03138     NS_DECL_NSISCRIPTERROR
03139 
03140 private:
03141     nsString mMessage;
03142     nsString mSourceName;
03143     PRUint32 mLineNumber;
03144     nsString mSourceLine;
03145     PRUint32 mColumnNumber;
03146     PRUint32 mFlags;
03147     nsCString mCategory;
03148 };
03149 
03150 /***************************************************************************/
03151 // XXX allowing for future notifications to XPCCallContext
03152 
03153 class AutoJSRequest
03154 {
03155 public:
03156     AutoJSRequest(XPCCallContext& aCCX)
03157       : mCCX(aCCX), mCX(aCCX.GetJSContext()) {BeginRequest();}
03158     ~AutoJSRequest() {EndRequest();}
03159 
03160     void EndRequest() {
03161         if(mCX) {
03162             JS_EndRequest(mCX);
03163             mCX = nsnull;
03164         }
03165     }
03166 private:
03167     void BeginRequest() {
03168         if(JS_GetContextThread(mCX))
03169             JS_BeginRequest(mCX);
03170         else
03171             mCX = nsnull;
03172     }
03173 private:
03174     XPCCallContext& mCCX;
03175     JSContext* mCX;
03176 };
03177 
03178 class AutoJSSuspendRequest
03179 {
03180 public:
03181     AutoJSSuspendRequest(XPCCallContext& aCCX)
03182       : mCCX(aCCX), mCX(aCCX.GetJSContext()) {SuspendRequest();}
03183     ~AutoJSSuspendRequest() {ResumeRequest();}
03184 
03185     void ResumeRequest() {
03186         if(mCX) {
03187             JS_ResumeRequest(mCX, mDepth);
03188             mCX = nsnull;
03189         }
03190     }
03191 private:
03192     void SuspendRequest() {
03193         if(JS_GetContextThread(mCX))
03194             mDepth = JS_SuspendRequest(mCX);
03195         else
03196             mCX = nsnull;
03197     }
03198 private:
03199     XPCCallContext& mCCX;
03200     JSContext* mCX;
03201     jsrefcount mDepth;
03202 };
03203 
03204 class AutoJSSuspendRequestWithNoCallContext
03205 {
03206 public:
03207     AutoJSSuspendRequestWithNoCallContext(JSContext *aCX)
03208       : mCX(aCX) {SuspendRequest();}
03209     ~AutoJSSuspendRequestWithNoCallContext() {ResumeRequest();}
03210 
03211     void ResumeRequest() {
03212         if(mCX) {
03213             JS_ResumeRequest(mCX, mDepth);
03214             mCX = nsnull;
03215         }
03216     }
03217 private:
03218     void SuspendRequest() {
03219         if(JS_GetContextThread(mCX))
03220             mDepth = JS_SuspendRequest(mCX);
03221         else
03222             mCX = nsnull;
03223     }
03224 private:
03225     JSContext* mCX;
03226     jsrefcount mDepth;
03227 };
03228 
03229 /*****************************************/
03230 
03231 class AutoJSRequestWithNoCallContext
03232 {
03233 public:
03234     AutoJSRequestWithNoCallContext(JSContext* aCX) : mCX(aCX) {BeginRequest();}
03235     ~AutoJSRequestWithNoCallContext() {EndRequest();}
03236 
03237     void EndRequest() {
03238         if(mCX) {
03239             JS_EndRequest(mCX);
03240             mCX = nsnull;
03241         }
03242     }
03243 private:
03244     void BeginRequest() {
03245         if(JS_GetContextThread(mCX))
03246             JS_BeginRequest(mCX);
03247         else
03248             mCX = nsnull;
03249     }
03250 private:
03251     JSContext* mCX;
03252 };
03253 
03254 /***************************************************************************/
03255 class AutoJSErrorAndExceptionEater
03256 {
03257 public:
03258     AutoJSErrorAndExceptionEater(JSContext* aCX)
03259         : mCX(aCX),
03260           mOldErrorReporter(JS_SetErrorReporter(mCX, nsnull)),
03261           mOldExceptionState(JS_SaveExceptionState(mCX)) {}
03262     ~AutoJSErrorAndExceptionEater()
03263     {
03264         JS_SetErrorReporter(mCX, mOldErrorReporter);
03265         JS_RestoreExceptionState(mCX, mOldExceptionState);
03266     }
03267 private:
03268     JSContext*        mCX;
03269     JSErrorReporter   mOldErrorReporter;
03270     JSExceptionState* mOldExceptionState;
03271 };
03272 
03273 /******************************************************************************
03274  * Handles pre/post script processing and the setting/resetting the error
03275  * reporter
03276  */
03277 class AutoScriptEvaluate
03278 {
03279 public:
03284     AutoScriptEvaluate(JSContext * cx)
03285          : mJSContext(cx), mState(0), mEvaluated(PR_FALSE), 
03286            mContextHasThread(0) {}
03287 
03295     void StartEvaluating(JSErrorReporter errorReporter = nsnull);
03299     ~AutoScriptEvaluate();
03300 private:
03301     JSContext* mJSContext;
03302     JSExceptionState* mState;
03303     JSErrorReporter mOldErrorReporter;
03304     PRBool mEvaluated;
03305     jsword mContextHasThread;
03306 
03307     // No copying or assignment allowed
03308     AutoScriptEvaluate(const AutoScriptEvaluate &);
03309     AutoScriptEvaluate & operator =(const AutoScriptEvaluate &);
03310 };
03311 
03312 /***************************************************************************/
03313 class AutoResolveName
03314 {
03315 public:
03316     AutoResolveName(XPCCallContext& ccx, jsval name)
03317         : mTLS(ccx.GetThreadData()),
03318           mOld(mTLS->SetResolveName(name)),
03319           mCheck(name) {}
03320     ~AutoResolveName()
03321         {
03322 #ifdef DEBUG
03323             jsval old = 
03324 #endif
03325             mTLS->SetResolveName(mOld);
03326             NS_ASSERTION(old == mCheck, "Bad Nesting!");
03327         }
03328 
03329 private:
03330     XPCPerThreadData* mTLS;
03331     jsval mOld;
03332     jsval mCheck;
03333 };
03334 
03335 /***************************************************************************/
03336 class XPCMarkableJSVal
03337 {
03338 public:
03339     XPCMarkableJSVal(jsval val) : mVal(val), mValPtr(&mVal) {}
03340     XPCMarkableJSVal(jsval *pval) : mVal(0), mValPtr(pval) {}
03341     ~XPCMarkableJSVal() {}
03342     void Mark() {}
03343     void MarkBeforeJSFinalize(JSContext* cx)
03344         {if(JSVAL_IS_GCTHING(*mValPtr))
03345             JS_MarkGCThing(cx, JSVAL_TO_GCTHING(*mValPtr), 
03346                            "XPCMarkableJSVal", nsnull);}
03347     void AutoMark(JSContext*) {}
03348 private:
03349     XPCMarkableJSVal(); // not implemented    
03350     jsval  mVal;
03351     jsval* mValPtr;
03352 }; 
03353 
03354 /***************************************************************************/
03355 // AutoMarkingPtr is the base class for the various AutoMarking pointer types 
03356 // below. This system allows us to temporarily protect instances of our garbage 
03357 // collected types after they are constructed but before they are safely 
03358 // attached to other rooted objects.
03359 // This base class has pure virtual support for marking. 
03360 
03361 class AutoMarkingPtr
03362 {
03363 public:
03364     AutoMarkingPtr(XPCCallContext& ccx)
03365         : mNext(nsnull), mTLS(ccx.GetThreadData()) {Link();}
03366 
03367     virtual ~AutoMarkingPtr() {Unlink();}
03368     
03369     void Link() 
03370         {if(!mTLS) return;
03371          AutoMarkingPtr** list = mTLS->GetAutoRootsAdr(); 
03372          mNext = *list; *list = this;}
03373 
03374     void Unlink() 
03375         {if(!mTLS) return;
03376          AutoMarkingPtr** cur = mTLS->GetAutoRootsAdr(); 
03377          while(*cur != this) {
03378             NS_ASSERTION(*cur, "This object not in list!");
03379             cur = &(*cur)->mNext;
03380          }
03381          *cur = mNext;
03382          mTLS = nsnull;
03383         }
03384 
03385     AutoMarkingPtr* GetNext() {return mNext;}
03386     
03387     virtual void MarkBeforeJSFinalize(JSContext* cx) = 0;
03388     virtual void MarkAfterJSFinalize() = 0;
03389 
03390 protected:
03391     AutoMarkingPtr* mNext;
03392     XPCPerThreadData* mTLS;
03393 };
03394 
03395 // More joy of macros...
03396 
03397 #define DEFINE_AUTO_MARKING_PTR_TYPE(class_, type_)                          \
03398 class class_ : public AutoMarkingPtr                                         \
03399 {                                                                            \
03400 public:                                                                      \
03401     class_ (XPCCallContext& ccx, type_ * ptr = nsnull)                       \
03402         : AutoMarkingPtr(ccx), mPtr(ptr) {}                                  \
03403     virtual ~ class_ () {}                                                   \
03404                                                                              \
03405     virtual void MarkBeforeJSFinalize(JSContext* cx)                         \
03406         {if(mPtr) {                                                          \
03407            mPtr->MarkBeforeJSFinalize(cx);                                   \
03408            mPtr->AutoMark(cx);                                               \
03409          }                                                                   \
03410          if(mNext) mNext->MarkBeforeJSFinalize(cx);}                         \
03411                                                                              \
03412     virtual void MarkAfterJSFinalize()                                       \
03413         {if(mPtr) mPtr->Mark();                                              \
03414          if(mNext) mNext->MarkAfterJSFinalize();}                            \
03415                                                                              \
03416     type_ * get()        const  {return mPtr;}                               \
03417     operator type_ *()   const  {return mPtr;}                               \
03418     type_ * operator->() const  {return mPtr;}                               \
03419                                                                              \
03420     class_ & operator =(type_ * p)                                           \
03421         {mPtr = p; return *this;}                                            \
03422                                                                              \
03423 protected:                                                                   \
03424     type_ * mPtr;                                                            \
03425 };
03426 
03427 // Use the macro above to define our AutoMarking types...
03428 
03429 DEFINE_AUTO_MARKING_PTR_TYPE(AutoMarkingNativeInterfacePtr, XPCNativeInterface)
03430 DEFINE_AUTO_MARKING_PTR_TYPE(AutoMarkingNativeSetPtr, XPCNativeSet)
03431 DEFINE_AUTO_MARKING_PTR_TYPE(AutoMarkingWrappedNativePtr, XPCWrappedNative)
03432 DEFINE_AUTO_MARKING_PTR_TYPE(AutoMarkingWrappedNativeTearOffPtr, XPCWrappedNativeTearOff)
03433 DEFINE_AUTO_MARKING_PTR_TYPE(AutoMarkingWrappedNativeProtoPtr, XPCWrappedNativeProto)
03434 DEFINE_AUTO_MARKING_PTR_TYPE(AutoMarkingJSVal, XPCMarkableJSVal)
03435                                     
03436 #define DEFINE_AUTO_MARKING_ARRAY_PTR_TYPE(class_, type_)                    \
03437 class class_ : public AutoMarkingPtr                                         \
03438 {                                                                            \
03439 public:                                                                      \
03440     class_ (XPCCallContext& ccx)                                             \
03441         : AutoMarkingPtr(ccx), mPtr(nsnull), mCount(0) {}                    \
03442     class_ (XPCCallContext& ccx, type_** aPtr, PRUint32 aCount,              \
03443             PRBool aClear = PR_FALSE)                                        \
03444         : AutoMarkingPtr(ccx), mPtr(aPtr), mCount(aCount)                    \
03445     {                                                                        \
03446         if(!mPtr) mCount = 0;                                                \
03447         else if(aClear) memset(mPtr, 0, mCount*sizeof(type_*));              \
03448     }                                                                        \
03449     virtual ~ class_ () {}                                                   \
03450                                                                              \
03451     virtual void MarkBeforeJSFinalize(JSContext* cx)                         \
03452     {                                                                        \
03453         for(PRUint32 i = 0; i < mCount; ++i)                                 \
03454         {                                                                    \
03455             type_* cur = mPtr[i];                                            \
03456             if(cur)                                                          \
03457             {                                                                \
03458                 cur->MarkBeforeJSFinalize(cx);                               \
03459                 cur->AutoMark(cx);                                           \
03460             }                                                                \
03461         }                                                                    \
03462         if(mNext) mNext->MarkBeforeJSFinalize(cx);                           \
03463     }                                                                        \
03464                                                                              \
03465     virtual void MarkAfterJSFinalize()                                       \
03466     {                                                                        \
03467         for(PRUint32 i = 0; i < mCount; ++i)                                 \
03468         {                                                                    \
03469             type_* cur = mPtr[i];                                            \
03470             if(cur)                                                          \
03471                 cur->Mark();                                                 \
03472         }                                                                    \
03473         if(mNext) mNext->MarkAfterJSFinalize();                              \
03474     }                                                                        \
03475                                                                              \
03476     type_ ** get()       const  {return mPtr;}                               \
03477     operator type_ **()  const  {return mPtr;}                               \
03478     type_ ** operator->() const  {return mPtr;}                              \
03479                                                                              \
03480     class_ & operator =(const class_ & inst)                                 \
03481         {mPtr = inst.mPtr; mCount = inst.mCount; return *this;}              \
03482                                                                              \
03483 protected:                                                                   \
03484     type_ ** mPtr;                                                           \
03485     PRUint32 mCount;                                                         \
03486 };
03487 
03488 DEFINE_AUTO_MARKING_ARRAY_PTR_TYPE(AutoMarkingNativeInterfacePtrArrayPtr,
03489                                    XPCNativeInterface)
03490     
03491 // Note: It looked like I would need one of these AutoMarkingPtr types for
03492 // XPCNativeScriptableInfo in order to manage marking its 
03493 // XPCNativeScriptableShared member during construction. But AFAICT we build
03494 // these and bind them to rooted things so immediately that this just is not
03495 // needed.
03496 
03497 #define AUTO_MARK_JSVAL_HELPER2(tok, line) tok##line
03498 #define AUTO_MARK_JSVAL_HELPER(tok, line) AUTO_MARK_JSVAL_HELPER2(tok, line)
03499 
03500 #define AUTO_MARK_JSVAL(ccx, val)                                            \
03501     XPCMarkableJSVal AUTO_MARK_JSVAL_HELPER(_val_,__LINE__)(val);            \
03502     AutoMarkingJSVal AUTO_MARK_JSVAL_HELPER(_automarker_,__LINE__)           \
03503     (ccx, &AUTO_MARK_JSVAL_HELPER(_val_,__LINE__))
03504 
03505 #ifdef XPC_USE_SECURITY_CHECKED_COMPONENT
03506 /***************************************************************************/
03507 // Allocates a string that grants all access ("AllAccess")
03508 
03509 extern char* xpc_CloneAllAccess();
03510 /***************************************************************************/
03511 // Returns access if wideName is in list
03512 
03513 extern char * xpc_CheckAccessList(const PRUnichar* wideName, const char* list[]);
03514 #endif
03515 
03516 /***************************************************************************/
03517 // in xpcvariant.cpp...
03518 
03519 // {1809FD50-91E8-11d5-90F9-0010A4E73D9A}
03520 #define XPCVARIANT_IID \
03521     {0x1809fd50, 0x91e8, 0x11d5, \
03522       { 0x90, 0xf9, 0x0, 0x10, 0xa4, 0xe7, 0x3d, 0x9a } }
03523 
03524 class XPCVariant : public nsIVariant
03525 {
03526 public:
03527     NS_DECL_ISUPPORTS
03528     NS_DECL_NSIVARIANT
03529 
03530     // We #define and iid so that out module local code can use QI to detect 
03531     // if a given nsIVariant is in fact an XPCVariant. 
03532     NS_DEFINE_STATIC_IID_ACCESSOR(XPCVARIANT_IID)
03533 
03534     static XPCVariant* newVariant(XPCCallContext& ccx, jsval aJSVal);
03535 
03536     jsval GetJSVal() const {return mJSVal;}
03537 
03538     XPCVariant();
03539 
03550     static JSBool VariantDataToJS(XPCCallContext& ccx, 
03551                                   nsIVariant* variant,
03552                                   JSObject* scope, nsresult* pErr,
03553                                   jsval* pJSVal);
03554 
03555 protected:
03556     virtual ~XPCVariant();
03557 
03558     JSBool InitializeData(XPCCallContext& ccx);
03559 
03560 protected:
03561     nsDiscriminatedUnion mData;
03562     jsval                mJSVal;
03563 };
03564 
03565 /***************************************************************************/
03566 // Utilities
03567 
03568 JSBool xpc_IsReportableErrorCode(nsresult code);
03569 
03570 JSObject* xpc_CloneJSFunction(XPCCallContext &ccx, JSObject *funobj,
03571                               JSObject *parent);
03572 
03573 #ifndef XPCONNECT_STANDALONE
03574 
03575 // Helper for creating a sandbox object to use for evaluating
03576 // untrusted code completely separated from all other code in the
03577 // system using xpc_EvalInSandbox(). Takes the JSContext on which to
03578 // do setup etc on, puts the sandbox object in *vp (which must be
03579 // rooted by the caller), and uses the principal that's either
03580 // directly passed in prinOrSop or indirectly as an
03581 // nsIScriptObjectPrincipal holding the principal. If no principal is
03582 // reachable through prinOrSop, a new null principal will be created
03583 // and used.
03584 nsresult
03585 xpc_CreateSandboxObject(JSContext * cx, jsval * vp, nsISupports *prinOrSop);
03586 
03587 // Helper for evaluating scripts in a sandbox object created with
03588 // xpc_CreateSandboxObject(). The caller is responsible of ensuring
03589 // that *rval doesn't get collected during the call or usage after the
03590 // call. This helper will use filename and lineNo for error reporting,
03591 // and if no filename is provided it will use the codebase from the
03592 // principal and line number 1 as a fallback. if returnStringOnly is
03593 // true, then the result in *rval, or the exception in cx->exception
03594 // will be coerced into strings. If an exception is thrown converting
03595 // an exception to a string, evalInSandbox will return an NS_ERROR_*
03596 // result, and cx->exception will be empty.
03597 nsresult
03598 xpc_EvalInSandbox(JSContext *cx, JSObject *sandbox, const nsAString& source,
03599                   const char *filename, PRInt32 lineNo,
03600                   PRBool returnStringOnly, jsval *rval);
03601 #endif /* !XPCONNECT_STANDALONE */
03602 
03603 /***************************************************************************/
03604 // Inlined utilities.
03605 
03606 inline JSBool
03607 xpc_ForcePropertyResolve(JSContext* cx, JSObject* obj, jsval idval);
03608 
03609 #ifdef XPC_IDISPATCH_SUPPORT
03610 // IDispatch specific classes
03611 #include "XPCDispPrivate.h"
03612 #endif
03613 
03614 /***************************************************************************/
03615 // Inlines use the above - include last.
03616 
03617 #include "xpcinlines.h"
03618 
03619 /***************************************************************************/
03620 // Maps have inlines that use the above - include last.
03621 
03622 #include "xpcmaps.h"
03623 
03624 /***************************************************************************/
03625 
03626 #endif /* xpcprivate_h___ */