Back to index

lightning-sunbird  0.9+nobinonly
xpcruntimesvc.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
00002  *
00003  * ***** BEGIN LICENSE BLOCK *****
00004  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00005  *
00006  * The contents of this file are subject to the Mozilla Public License Version
00007  * 1.1 (the "License"); you may not use this file except in compliance with
00008  * the License. You may obtain a copy of the License at
00009  * http://www.mozilla.org/MPL/
00010  *
00011  * Software distributed under the License is distributed on an "AS IS" basis,
00012  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00013  * for the specific language governing rights and limitations under the
00014  * License.
00015  *
00016  * The Original Code is Mozilla Communicator client code, released
00017  * March 31, 1998.
00018  *
00019  * The Initial Developer of the Original Code is
00020  * Netscape Communications Corporation.
00021  * Portions created by the Initial Developer are Copyright (C) 1999
00022  * the Initial Developer. All Rights Reserved.
00023  *
00024  * Contributor(s):
00025  *   Mike Shaver <shaver@mozilla.org>
00026  *   John Bandhauer <jband@netscape.com>
00027  *
00028  * Alternatively, the contents of this file may be used under the terms of
00029  * either of the GNU General Public License Version 2 or later (the "GPL"),
00030  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00031  * in which case the provisions of the GPL or the LGPL are applicable instead
00032  * of those above. If you wish to allow use of your version of this file only
00033  * under the terms of either the GPL or the LGPL, and not to allow others to
00034  * use your version of this file under the terms of the MPL, indicate your
00035  * decision by deleting the provisions above and replace them with the notice
00036  * and other provisions required by the GPL or the LGPL. If you do not delete
00037  * the provisions above, a recipient may use your version of this file under
00038  * the terms of any one of the MPL, the GPL or the LGPL.
00039  *
00040  * ***** END LICENSE BLOCK ***** */
00041 
00042 #include "xpcprivate.h"
00043 
00044 #ifndef XPCONNECT_STANDALONE
00045 NS_IMPL_THREADSAFE_ISUPPORTS2(BackstagePass, nsIScriptObjectPrincipal, nsIXPCScriptable)
00046 #else
00047 NS_IMPL_THREADSAFE_ISUPPORTS1(BackstagePass, nsIXPCScriptable)
00048 #endif
00049 
00050 // The nsIXPCScriptable map declaration that will generate stubs for us...
00051 #define XPC_MAP_CLASSNAME           BackstagePass
00052 #define XPC_MAP_QUOTED_CLASSNAME   "BackstagePass"
00053 #define                             XPC_MAP_WANT_NEWRESOLVE
00054 #define XPC_MAP_FLAGS       nsIXPCScriptable::USE_JSSTUB_FOR_ADDPROPERTY   | \
00055                             nsIXPCScriptable::USE_JSSTUB_FOR_DELPROPERTY   | \
00056                             nsIXPCScriptable::USE_JSSTUB_FOR_SETPROPERTY   | \
00057                             nsIXPCScriptable::DONT_ENUM_STATIC_PROPS       | \
00058                             nsIXPCScriptable::DONT_ENUM_QUERY_INTERFACE    | \
00059                             nsIXPCScriptable::DONT_REFLECT_INTERFACE_NAMES
00060 #include "xpc_map_end.h" /* This will #undef the above */
00061 
00062 /* PRBool newResolve (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in JSVal id, in PRUint32 flags, out JSObjectPtr objp); */
00063 NS_IMETHODIMP
00064 BackstagePass::NewResolve(nsIXPConnectWrappedNative *wrapper,
00065                           JSContext * cx, JSObject * obj,
00066                           jsval id, PRUint32 flags, 
00067                           JSObject * *objp, PRBool *_retval)
00068 {
00069     JSBool resolved;
00070 
00071     *_retval = JS_ResolveStandardClass(cx, obj, id, &resolved);
00072     if(*_retval && resolved)
00073         *objp = obj;
00074     return NS_OK;
00075 }
00076 
00077 /*
00078  * This object holds state that we don't want to lose!
00079  *
00080  * The plan is that once created this object never goes away. We do an
00081  * intentional extra addref at construction to keep it around even if no one
00082  * is using it.
00083  */
00084 
00085 nsJSRuntimeServiceImpl::nsJSRuntimeServiceImpl() :
00086     mRuntime(0)
00087 {
00088 }
00089 
00090 nsJSRuntimeServiceImpl::~nsJSRuntimeServiceImpl() {
00091     if(mRuntime)
00092     {
00093         JS_DestroyRuntime(mRuntime);
00094         JS_ShutDown();
00095 #ifdef DEBUG_shaver_off
00096         fprintf(stderr, "nJRSI: destroyed runtime %p\n", (void *)mRuntime);
00097 #endif
00098     }
00099 }
00100 
00101 NS_IMPL_THREADSAFE_ISUPPORTS2(nsJSRuntimeServiceImpl,
00102                               nsIJSRuntimeService,
00103                               nsISupportsWeakReference)
00104 
00105 nsJSRuntimeServiceImpl*
00106 nsJSRuntimeServiceImpl::gJSRuntimeService = nsnull;
00107 
00108 nsJSRuntimeServiceImpl*
00109 nsJSRuntimeServiceImpl::GetSingleton()
00110 {
00111     if(!gJSRuntimeService)
00112     {
00113         gJSRuntimeService = new nsJSRuntimeServiceImpl();
00114         // hold an extra reference to lock it down
00115         NS_IF_ADDREF(gJSRuntimeService);
00116 
00117     }
00118     NS_IF_ADDREF(gJSRuntimeService);
00119 
00120     return gJSRuntimeService;
00121 }
00122 
00123 void
00124 nsJSRuntimeServiceImpl::FreeSingleton()
00125 {
00126     NS_IF_RELEASE(gJSRuntimeService);
00127 }
00128 
00129 const uint32 gGCSize = 4L * 1024L * 1024L; /* pref? */
00130 
00131 /* attribute JSRuntime runtime; */
00132 NS_IMETHODIMP
00133 nsJSRuntimeServiceImpl::GetRuntime(JSRuntime **runtime)
00134 {
00135     if(!runtime)
00136         return NS_ERROR_NULL_POINTER;
00137 
00138     if(!mRuntime)
00139     {
00140         // Call XPCPerThreadData::GetData to initialize 
00141         // XPCPerThreadData::gTLSIndex before initializing 
00142         // JSRuntime::threadTPIndex in JS_NewRuntime.
00143         //
00144         // XPConnect uses a thread local storage (XPCPerThreadData) indexed by
00145         // XPCPerThreadData::gTLSIndex, and SpiderMonkey GC uses a thread local 
00146         // storage indexed by JSRuntime::threadTPIndex.
00147         //
00148         // The destructor for XPCPerThreadData::gTLSIndex may access 
00149         // thread local storage indexed by JSRuntime::threadTPIndex. 
00150         // Thus, the destructor for JSRuntime::threadTPIndex must be called 
00151         // later than the one for XPCPerThreadData::gTLSIndex.
00152         //
00153         // We rely on the implementation of NSPR that calls destructors at 
00154         // the same order of calling PR_NewThreadPrivateIndex.
00155         XPCPerThreadData::GetData();
00156         
00157         mRuntime = JS_NewRuntime(gGCSize);
00158         if(!mRuntime)
00159             return NS_ERROR_OUT_OF_MEMORY;
00160 
00161         // Unconstrain the runtime's threshold on nominal heap size, to avoid
00162         // triggering GC too often if operating continuously near an arbitrary
00163         // finite threshold (0xffffffff is infinity for uint32 parameters).
00164         // This leaves the maximum-JS_malloc-bytes threshold still in effect
00165         // to cause period, and we hope hygienic, last-ditch GCs from within
00166         // the GC's allocator.
00167         JS_SetGCParameter(mRuntime, JSGC_MAX_BYTES, 0xffffffff);
00168     }
00169     *runtime = mRuntime;
00170     return NS_OK;
00171 }
00172 
00173 /* attribute nsIXPCScriptable backstagePass; */
00174 NS_IMETHODIMP
00175 nsJSRuntimeServiceImpl::GetBackstagePass(nsIXPCScriptable **bsp)
00176 {
00177     if(!mBackstagePass) {
00178 #ifndef XPCONNECT_STANDALONE
00179         nsCOMPtr<nsIPrincipal> sysprin;
00180         nsCOMPtr<nsIScriptSecurityManager> secman = 
00181             do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID);
00182         if(!secman)
00183             return NS_ERROR_NOT_AVAILABLE;
00184         if(NS_FAILED(secman->GetSystemPrincipal(getter_AddRefs(sysprin))))
00185             return NS_ERROR_NOT_AVAILABLE;
00186         
00187         mBackstagePass = new BackstagePass(sysprin);
00188 #else
00189         mBackstagePass = new BackstagePass();
00190 #endif
00191         if(!mBackstagePass)
00192             return NS_ERROR_OUT_OF_MEMORY;
00193     }
00194     NS_ADDREF(*bsp = mBackstagePass);
00195     return NS_OK;
00196 }