2003-11-15 00:11:16 +00:00
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* * * * * * BEGIN LICENSE BLOCK * * * * *
* Version : MPL 1.1 / GPL 2.0 / LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 ( the " License " ) ; you may not use this file except in compliance with
* the License . You may obtain a copy of the License at
1999-09-07 06:18:08 +00:00
* http : //www.mozilla.org/MPL/
*
2003-11-15 00:11:16 +00:00
* Software distributed under the License is distributed on an " AS IS " basis ,
* WITHOUT WARRANTY OF ANY KIND , either express or implied . See the License
1999-09-07 06:18:08 +00:00
* for the specific language governing rights and limitations under the
2003-11-15 00:11:16 +00:00
* License .
*
* The Original Code is Mozilla Communicator client code , released
* March 31 , 1998.
1999-09-07 06:18:08 +00:00
*
2003-11-15 00:11:16 +00:00
* The Initial Developer of the Original Code is
* Netscape Communications Corporation .
* Portions created by the Initial Developer are Copyright ( C ) 1999
* the Initial Developer . All Rights Reserved .
2000-05-02 22:44:23 +00:00
*
2000-08-16 04:01:02 +00:00
* Contributors :
* Mike Shaver < shaver @ zeroknowledge . com >
* John Bandhauer < jband @ netscape . com >
2001-03-21 01:35:39 +00:00
* IBM Corp .
2001-03-14 02:41:55 +00:00
* Robert Ginda < rginda @ netscape . com >
2003-11-15 00:11:16 +00:00
*
* Alternatively , the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later ( the " GPL " ) ,
* or the GNU Lesser General Public License Version 2.1 or later ( the " LGPL " ) ,
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above . If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL , and not to allow others to
* use your version of this file under the terms of the MPL , indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL . If you do not delete
* the provisions above , a recipient may use your version of this file under
* the terms of any one of the MPL , the GPL or the LGPL .
*
* * * * * * END LICENSE BLOCK * * * * * */
1999-09-07 06:18:08 +00:00
2000-05-15 18:07:36 +00:00
# include "prlog.h"
2000-05-26 04:56:23 +00:00
# include "nsCOMPtr.h"
# include "nsICategoryManager.h"
1999-09-07 06:18:08 +00:00
# include "nsIComponentLoader.h"
# include "nsIComponentManager.h"
2004-11-23 20:53:38 +00:00
# include "nsIComponentManagerObsolete.h"
2000-05-26 04:56:23 +00:00
# include "nsIGenericFactory.h"
# include "nsILocalFile.h"
# include "nsIModule.h"
1999-09-07 06:18:08 +00:00
# include "nsIServiceManager.h"
# include "nsISupports.h"
# include "mozJSComponentLoader.h"
# include "nsIJSRuntimeService.h"
1999-11-10 00:34:26 +00:00
# include "nsIJSContextStack.h"
1999-09-07 06:18:08 +00:00
# include "nsIXPConnect.h"
# include "nsCRT.h"
2000-06-03 09:46:12 +00:00
# include "nsMemory.h"
1999-11-10 00:34:26 +00:00
# include "nsXPIDLString.h"
2000-05-16 05:09:31 +00:00
# include "nsIObserverService.h"
2000-08-16 04:01:02 +00:00
# include "nsIXPCScriptable.h"
2003-08-02 19:33:52 +00:00
# include "nsString.h"
2000-05-26 04:56:23 +00:00
# ifndef XPCONNECT_STANDALONE
# include "nsIScriptSecurityManager.h"
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 17:42:36 +00:00
# include "nsIScriptObjectPrincipal.h"
2001-03-27 05:35:52 +00:00
# include "nsIURL.h"
2002-03-06 07:48:55 +00:00
# include "nsIStandardURL.h"
2002-01-08 01:31:25 +00:00
# include "nsNetUtil.h"
2000-05-26 04:56:23 +00:00
# endif
2002-06-14 21:33:05 +00:00
# include "nsIComponentLoaderManager.h"
2000-03-31 11:19:51 +00:00
// For reporting errors with the console service
# include "nsIScriptError.h"
# include "nsIConsoleService.h"
2000-09-13 23:57:52 +00:00
const char mozJSComponentLoaderContractID [ ] = " @mozilla.org/moz/jsloader;1 " ;
1999-09-07 06:18:08 +00:00
const char jsComponentTypeName [ ] = " text/javascript " ;
2000-03-11 03:08:04 +00:00
2001-06-20 20:21:49 +00:00
// same as in nsComponentManager.cpp (but without the JS)
const char JSfileSizeValueName [ ] = " FileSize " ;
const char JSlastModValueName [ ] = " LastModTimeStamp " ;
const char JSxpcomKeyName [ ] = " software/mozilla/XPCOM/components " ;
1999-09-07 06:18:08 +00:00
2000-09-13 23:57:52 +00:00
const char kJSRuntimeServiceContractID [ ] = " @mozilla.org/js/xpc/RuntimeService;1 " ;
const char kXPConnectServiceContractID [ ] = " @mozilla.org/js/xpc/XPConnect;1 " ;
const char kJSContextStackContractID [ ] = " @mozilla.org/js/xpc/ContextStack;1 " ;
2000-09-21 04:30:32 +00:00
const char kConsoleServiceContractID [ ] = " @mozilla.org/consoleservice;1 " ;
const char kScriptErrorContractID [ ] = " @mozilla.org/scripterror;1 " ;
2001-10-22 22:01:27 +00:00
const char kObserverServiceContractID [ ] = " @mozilla.org/observer-service;1 " ;
2000-09-21 04:30:32 +00:00
# ifndef XPCONNECT_STANDALONE
const char kScriptSecurityManagerContractID [ ] = NS_SCRIPTSECURITYMANAGER_CONTRACTID ;
2001-03-27 05:35:52 +00:00
const char kStandardURLContractID [ ] = " @mozilla.org/network/standard-url;1 " ;
2000-09-21 04:30:32 +00:00
# endif
1999-11-10 00:34:26 +00:00
2001-03-27 05:35:52 +00:00
JS_STATIC_DLL_CALLBACK ( void )
Reporter ( JSContext * cx , const char * message , JSErrorReport * rep )
{
nsresult rv ;
/* Use the console service to register the error. */
nsCOMPtr < nsIConsoleService > consoleService =
do_GetService ( kConsoleServiceContractID ) ;
/*
* Make an nsIScriptError , populate it with information from this
* error , then log it with the console service . The UI can then
* poll the service to update the JavaScript console .
*/
nsCOMPtr < nsIScriptError > errorObject =
do_CreateInstance ( kScriptErrorContractID ) ;
if ( consoleService & & errorObject ) {
/*
* Got an error object ; prepare appropriate - width versions of
* various arguments to it .
*/
nsAutoString fileUni ;
fileUni . AssignWithConversion ( rep - > filename ) ;
PRUint32 column = rep - > uctokenptr - rep - > uclinebuf ;
rv = errorObject - > Init ( NS_REINTERPRET_CAST ( const PRUnichar * ,
rep - > ucmessage ) ,
fileUni . get ( ) ,
NS_REINTERPRET_CAST ( const PRUnichar * ,
rep - > uclinebuf ) ,
rep - > lineno , column , rep - > flags ,
" component javascript " ) ;
if ( NS_SUCCEEDED ( rv ) ) {
rv = consoleService - > LogMessage ( errorObject ) ;
if ( NS_SUCCEEDED ( rv ) ) {
// We're done! Skip return to fall thru to stderr
// printout, for the benefit of those invoking the
// browser with -console
// return;
}
}
}
/*
* If any of the above fails for some reason , fall back to
* printing to stderr .
*/
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 17:42:36 +00:00
# ifdef DEBUG
2001-03-27 05:35:52 +00:00
fprintf ( stderr , " JS Component Loader: %s %s:%d \n "
" %s \n " ,
JSREPORT_IS_WARNING ( rep - > flags ) ? " WARNING " : " ERROR " ,
rep - > filename , rep - > lineno ,
message ? message : " <no message> " ) ;
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 17:42:36 +00:00
# endif
2001-03-27 05:35:52 +00:00
}
2001-03-21 01:35:39 +00:00
JS_STATIC_DLL_CALLBACK ( JSBool )
1999-09-07 06:18:08 +00:00
Dump ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval )
{
JSString * str ;
if ( ! argc )
return JS_TRUE ;
str = JS_ValueToString ( cx , argv [ 0 ] ) ;
if ( ! str )
return JS_FALSE ;
char * bytes = JS_GetStringBytes ( str ) ;
bytes = nsCRT : : strdup ( bytes ) ;
# ifdef XP_MAC
for ( char * c = bytes ; * c ; c + + )
if ( * c = = ' \r ' )
1999-09-21 14:36:40 +00:00
* c = ' \n ' ;
1999-09-07 06:18:08 +00:00
# endif
fputs ( bytes , stderr ) ;
2000-06-03 09:46:12 +00:00
nsMemory : : Free ( bytes ) ;
1999-09-07 06:18:08 +00:00
return JS_TRUE ;
}
2001-03-21 01:35:39 +00:00
JS_STATIC_DLL_CALLBACK ( JSBool )
2000-05-26 04:56:23 +00:00
Debug ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval )
{
# ifdef DEBUG
2001-03-27 05:35:52 +00:00
return Dump ( cx , obj , argc , argv , rval ) ;
2000-05-26 04:56:23 +00:00
# else
2001-03-27 05:35:52 +00:00
return JS_TRUE ;
2000-05-26 04:56:23 +00:00
# endif
}
2001-03-27 05:35:52 +00:00
# ifndef XPCONNECT_STANDALONE
static JSFunctionSpec gSandboxFun [ ] = {
{ " dump " , Dump , 1 } ,
{ " debug " , Debug , 1 } ,
{ 0 }
} ;
2001-03-27 16:37:01 +00:00
JS_STATIC_DLL_CALLBACK ( JSBool )
2001-03-27 05:35:52 +00:00
sandbox_enumerate ( JSContext * cx , JSObject * obj )
{
return JS_EnumerateStandardClasses ( cx , obj ) ;
}
2001-03-27 16:37:01 +00:00
JS_STATIC_DLL_CALLBACK ( JSBool )
2001-03-27 05:35:52 +00:00
sandbox_resolve ( JSContext * cx , JSObject * obj , jsval id )
{
JSBool resolved ;
return JS_ResolveStandardClass ( cx , obj , id , & resolved ) ;
}
static JSClass js_SandboxClass = {
" Sandbox " , 0 ,
JS_PropertyStub , JS_PropertyStub , JS_PropertyStub , JS_PropertyStub ,
sandbox_enumerate , sandbox_resolve , JS_ConvertStub , JS_FinalizeStub ,
JSCLASS_NO_OPTIONAL_MEMBERS
} ;
JS_STATIC_DLL_CALLBACK ( JSBool )
NewSandbox ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv , jsval * rval )
{
nsresult rv ;
nsCOMPtr < nsIXPConnect > xpc = do_GetService ( kXPConnectServiceContractID ,
& rv ) ;
if ( ! xpc ) {
JS_ReportError ( cx , " Unable to get XPConnect service: %08lx " , rv ) ;
return JS_FALSE ;
}
/*
* We ' re not likely to see much action on this context , so keep stack - arena
* chunk size small to reduce bloat .
*/
JSContext * sandcx = JS_NewContext ( JS_GetRuntime ( cx ) , 1024 ) ;
if ( ! sandcx ) {
JS_ReportOutOfMemory ( cx ) ;
return JS_FALSE ;
}
JSBool ok = JS_FALSE ;
JSObject * sandbox = JS_NewObject ( sandcx , & js_SandboxClass , nsnull , nsnull ) ;
if ( ! sandbox )
goto out ;
JS_SetGlobalObject ( sandcx , sandbox ) ;
ok = JS_DefineFunctions ( sandcx , sandbox , gSandboxFun ) & &
NS_SUCCEEDED ( xpc - > InitClasses ( sandcx , sandbox ) ) ;
* rval = OBJECT_TO_JSVAL ( sandbox ) ;
out :
JS_DestroyContext ( sandcx ) ;
return ok ;
}
JS_STATIC_DLL_CALLBACK ( JSBool )
EvalInSandbox ( JSContext * cx , JSObject * obj , uintN argc , jsval * argv ,
jsval * rval )
{
JSPrincipals * jsPrincipals ;
JSString * source ;
const jschar * URL ;
JSObject * sandbox ;
if ( ! JS_ConvertArguments ( cx , argc , argv , " SoW " , & source , & sandbox , & URL ) )
return JS_FALSE ;
if ( ! JS_InstanceOf ( cx , sandbox , & js_SandboxClass , NULL ) ) {
JSClass * clasp = JS_GetClass ( cx , sandbox ) ;
const char * className = clasp ? clasp - > name : " <unknown!> " ;
JS_ReportError ( cx ,
" evalInSandbox passed object of class %s instead of Sandbox " , className ) ;
return JS_FALSE ;
}
NS_ConvertUCS2toUTF8 URL8 ( ( const PRUnichar * ) URL ) ;
nsCOMPtr < nsIURL > iURL ;
nsCOMPtr < nsIStandardURL > stdUrl =
do_CreateInstance ( kStandardURLContractID ) ;
if ( ! stdUrl | |
NS_FAILED ( stdUrl - > Init ( nsIStandardURL : : URLTYPE_STANDARD , 80 ,
2002-03-06 07:48:55 +00:00
URL8 , nsnull , nsnull ) ) | |
2001-03-27 05:35:52 +00:00
! ( iURL = do_QueryInterface ( stdUrl ) ) ) {
JS_ReportError ( cx , " Can't create URL for evalInSandbox " ) ;
return JS_FALSE ;
}
nsCOMPtr < nsIPrincipal > principal ;
nsCOMPtr < nsIScriptSecurityManager > secman =
do_GetService ( kScriptSecurityManagerContractID ) ;
if ( ! secman | |
NS_FAILED ( secman - > GetCodebasePrincipal ( iURL ,
getter_AddRefs ( principal ) ) ) | |
! principal | |
2003-11-03 04:26:55 +00:00
NS_FAILED ( principal - > GetJSPrincipals ( cx , & jsPrincipals ) ) | |
2001-03-27 05:35:52 +00:00
! jsPrincipals ) {
JS_ReportError ( cx , " Can't get principals for evalInSandbox " ) ;
return JS_FALSE ;
}
2003-03-23 07:22:18 +00:00
JSBool ok ;
2001-03-27 05:35:52 +00:00
JSContext * sandcx = JS_NewContext ( JS_GetRuntime ( cx ) , 8192 ) ;
if ( ! sandcx ) {
JS_ReportError ( cx , " Can't prepare context for evalInSandbox " ) ;
2003-03-23 07:22:18 +00:00
ok = JS_FALSE ;
} else {
JS_SetGlobalObject ( sandcx , sandbox ) ;
JS_SetErrorReporter ( sandcx , Reporter ) ;
ok = JS_EvaluateUCScriptForPrincipals ( sandcx , sandbox , jsPrincipals ,
JS_GetStringChars ( source ) ,
JS_GetStringLength ( source ) ,
URL8 . get ( ) , 1 , rval ) ;
JS_DestroyContext ( sandcx ) ;
2001-03-27 05:35:52 +00:00
}
2003-03-23 07:22:18 +00:00
JSPRINCIPALS_DROP ( cx , jsPrincipals ) ;
2001-03-27 05:35:52 +00:00
return ok ;
}
# endif /* XPCONNECT_STANDALONE */
1999-09-07 06:18:08 +00:00
static JSFunctionSpec gGlobalFun [ ] = {
{ " dump " , Dump , 1 } ,
2000-05-26 04:56:23 +00:00
{ " debug " , Debug , 1 } ,
2001-03-27 05:35:52 +00:00
# ifndef XPCONNECT_STANDALONE
{ " Sandbox " , NewSandbox , 0 } ,
{ " evalInSandbox " , EvalInSandbox , 3 } ,
# endif
1999-09-07 06:18:08 +00:00
{ 0 }
} ;
2000-08-16 04:01:02 +00:00
# ifndef XPCONNECT_STANDALONE
class BackstagePass : public nsIScriptObjectPrincipal , public nsIXPCScriptable
{
public :
NS_DECL_ISUPPORTS
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 17:42:36 +00:00
NS_DECL_NSIXPCSCRIPTABLE
2000-08-16 04:01:02 +00:00
2004-04-18 00:28:47 +00:00
virtual nsIPrincipal * GetPrincipal ( ) {
return mPrincipal ;
2000-08-16 04:01:02 +00:00
}
BackstagePass ( nsIPrincipal * prin ) :
mPrincipal ( prin )
{
}
virtual ~ BackstagePass ( ) { }
private :
nsCOMPtr < nsIPrincipal > mPrincipal ;
} ;
2003-09-07 22:37:27 +00:00
NS_IMPL_THREADSAFE_ISUPPORTS2 ( BackstagePass , nsIScriptObjectPrincipal , nsIXPCScriptable )
2000-08-16 04:01:02 +00:00
# else
class BackstagePass : public nsIXPCScriptable
{
public :
NS_DECL_ISUPPORTS
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 17:42:36 +00:00
NS_DECL_NSIXPCSCRIPTABLE
2000-08-16 04:01:02 +00:00
BackstagePass ( )
{
}
virtual ~ BackstagePass ( ) { }
} ;
2003-09-07 22:37:27 +00:00
NS_IMPL_THREADSAFE_ISUPPORTS1 ( BackstagePass , nsIXPCScriptable )
2000-08-16 04:01:02 +00:00
# endif
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 17:42:36 +00:00
// The nsIXPCScriptable map declaration that will generate stubs for us...
# define XPC_MAP_CLASSNAME BackstagePass
# define XPC_MAP_QUOTED_CLASSNAME "BackstagePass"
# define XPC_MAP_WANT_NEWRESOLVE
# define XPC_MAP_FLAGS nsIXPCScriptable::USE_JSSTUB_FOR_ADDPROPERTY | \
nsIXPCScriptable : : USE_JSSTUB_FOR_DELPROPERTY | \
nsIXPCScriptable : : USE_JSSTUB_FOR_SETPROPERTY | \
nsIXPCScriptable : : DONT_ENUM_STATIC_PROPS | \
nsIXPCScriptable : : DONT_ENUM_QUERY_INTERFACE | \
nsIXPCScriptable : : DONT_REFLECT_INTERFACE_NAMES
# include "xpc_map_end.h" /* This will #undef the above */
/* PRBool newResolve (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in JSVal id, in PRUint32 flags, out JSObjectPtr objp); */
NS_IMETHODIMP
BackstagePass : : NewResolve ( nsIXPConnectWrappedNative * wrapper ,
JSContext * cx , JSObject * obj ,
jsval id , PRUint32 flags ,
JSObject * * objp , PRBool * _retval )
{
JSBool resolved ;
2003-03-23 07:22:18 +00:00
* _retval = JS_ResolveStandardClass ( cx , obj , id , & resolved ) ;
if ( * _retval & & resolved )
* objp = obj ;
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 17:42:36 +00:00
return NS_OK ;
}
2000-08-16 04:01:02 +00:00
1999-09-25 20:07:20 +00:00
mozJSComponentLoader : : mozJSComponentLoader ( )
2002-06-14 21:33:05 +00:00
: mRuntime ( nsnull ) ,
1999-09-25 20:07:20 +00:00
mModules ( nsnull ) ,
mGlobals ( nsnull ) ,
mInitialized ( PR_FALSE )
1999-09-07 06:18:08 +00:00
{
}
2000-05-02 22:44:23 +00:00
static PRIntn PR_CALLBACK
1999-11-10 00:34:26 +00:00
UnrootGlobals ( PLHashEntry * he , PRIntn i , void * arg )
1999-09-07 06:18:08 +00:00
{
2000-09-21 04:30:32 +00:00
JSRuntime * rt = ( JSRuntime * ) arg ;
JS_RemoveRootRT ( rt , & he - > value ) ;
1999-11-18 15:39:28 +00:00
nsCRT : : free ( ( char * ) he - > key ) ;
1999-11-10 00:34:26 +00:00
return HT_ENUMERATE_REMOVE ;
1999-09-07 06:18:08 +00:00
}
2000-05-02 22:44:23 +00:00
static PRIntn PR_CALLBACK
1999-11-10 00:34:26 +00:00
UnloadAndReleaseModules ( PLHashEntry * he , PRIntn i , void * arg )
1999-09-07 06:18:08 +00:00
{
1999-11-10 00:34:26 +00:00
nsIModule * module = NS_STATIC_CAST ( nsIModule * , he - > value ) ;
nsIComponentManager * mgr = NS_STATIC_CAST ( nsIComponentManager * , arg ) ;
PRBool canUnload ;
2003-03-23 07:22:18 +00:00
nsresult rv = module - > CanUnload ( mgr , & canUnload ) ;
NS_ASSERTION ( NS_SUCCEEDED ( rv ) , " module CanUnload failed " ) ;
if ( NS_SUCCEEDED ( rv ) & & canUnload ) {
1999-11-10 00:34:26 +00:00
NS_RELEASE ( module ) ;
/* XXX need to unroot the global for the module as well */
1999-11-18 15:39:28 +00:00
nsCRT : : free ( ( char * ) he - > key ) ;
1999-11-10 00:34:26 +00:00
return HT_ENUMERATE_REMOVE ;
}
1999-09-07 06:18:08 +00:00
return HT_ENUMERATE_NEXT ;
}
mozJSComponentLoader : : ~ mozJSComponentLoader ( )
{
}
2003-09-07 22:37:27 +00:00
NS_IMPL_THREADSAFE_ISUPPORTS1 ( mozJSComponentLoader , nsIComponentLoader )
1999-09-07 06:18:08 +00:00
NS_IMETHODIMP
mozJSComponentLoader : : GetFactory ( const nsIID & aCID ,
const char * aLocation ,
const char * aType ,
nsIFactory * * _retval )
{
if ( ! _retval )
return NS_ERROR_NULL_POINTER ;
1999-11-10 00:34:26 +00:00
# ifdef DEBUG_shaver_off
1999-09-07 06:18:08 +00:00
char * cidString = aCID . ToString ( ) ;
fprintf ( stderr , " mJCL::GetFactory(%s,%s,%s) \n " , cidString , aLocation , aType ) ;
delete [ ] cidString ;
# endif
1999-09-07 20:30:25 +00:00
nsIModule * module = ModuleForLocation ( aLocation , 0 ) ;
if ( ! module ) {
1999-11-10 00:34:26 +00:00
# ifdef DEBUG_shaver_off
1999-09-07 06:18:08 +00:00
fprintf ( stderr , " ERROR: couldn't get module for %s \n " , aLocation ) ;
# endif
return NS_ERROR_FACTORY_NOT_LOADED ;
}
nsresult rv = module - > GetClassObject ( mCompMgr , aCID ,
NS_GET_IID ( nsIFactory ) ,
( void * * ) _retval ) ;
1999-11-10 00:34:26 +00:00
# ifdef DEBUG_shaver_off
1999-09-07 06:18:08 +00:00
fprintf ( stderr , " GetClassObject %s \n " , NS_FAILED ( rv ) ? " FAILED " : " ok " ) ;
# endif
return rv ;
}
NS_IMETHODIMP
mozJSComponentLoader : : Init ( nsIComponentManager * aCompMgr , nsISupports * aReg )
{
mCompMgr = aCompMgr ;
2002-06-14 21:33:05 +00:00
1999-09-07 06:18:08 +00:00
nsresult rv ;
2002-06-14 21:33:05 +00:00
mLoaderManager = do_QueryInterface ( mCompMgr , & rv ) ;
if ( NS_FAILED ( rv ) )
return rv ;
1999-09-07 20:30:25 +00:00
1999-09-24 01:37:44 +00:00
return NS_OK ;
}
1999-09-07 20:30:25 +00:00
1999-09-24 02:52:46 +00:00
nsresult
1999-09-24 01:37:44 +00:00
mozJSComponentLoader : : ReallyInit ( )
{
nsresult rv ;
1999-11-10 00:34:26 +00:00
/*
* Get the JSRuntime from the runtime svc , if possible .
* We keep a reference around , because it ' s a Bad Thing if the runtime
* service gets shut down before we ' re done . Bad !
*/
2000-09-21 04:30:32 +00:00
2000-09-13 23:57:52 +00:00
mRuntimeService = do_GetService ( kJSRuntimeServiceContractID , & rv ) ;
1999-11-18 15:39:28 +00:00
if ( NS_FAILED ( rv ) | |
NS_FAILED ( rv = mRuntimeService - > GetRuntime ( & mRuntime ) ) )
1999-09-07 20:30:25 +00:00
return rv ;
1999-11-10 00:34:26 +00:00
2000-08-16 04:01:02 +00:00
# ifndef XPCONNECT_STANDALONE
2000-09-21 04:30:32 +00:00
nsCOMPtr < nsIScriptSecurityManager > secman =
do_GetService ( kScriptSecurityManagerContractID ) ;
if ( ! secman )
2000-08-16 04:01:02 +00:00
return NS_ERROR_FAILURE ;
rv = secman - > GetSystemPrincipal ( getter_AddRefs ( mSystemPrincipal ) ) ;
if ( NS_FAILED ( rv ) | | ! mSystemPrincipal )
return NS_ERROR_FAILURE ;
# endif
1999-11-18 15:39:28 +00:00
mModules = PL_NewHashTable ( 16 , PL_HashString , PL_CompareStrings ,
PL_CompareValues , 0 , 0 ) ;
1999-09-07 06:18:08 +00:00
if ( ! mModules )
return NS_ERROR_OUT_OF_MEMORY ;
2000-10-05 04:15:43 +00:00
1999-09-07 06:18:08 +00:00
mGlobals = PL_NewHashTable ( 16 , PL_HashString , PL_CompareStrings ,
PL_CompareValues , 0 , 0 ) ;
if ( ! mGlobals )
return NS_ERROR_OUT_OF_MEMORY ;
1999-11-10 00:34:26 +00:00
# ifdef DEBUG_shaver_off
2000-10-05 04:15:43 +00:00
fprintf ( stderr , " mJCL: ReallyInit success! \n " ) ;
1999-09-07 06:18:08 +00:00
# endif
1999-09-24 01:37:44 +00:00
mInitialized = PR_TRUE ;
1999-11-10 00:34:26 +00:00
1999-09-07 06:18:08 +00:00
return NS_OK ;
}
NS_IMETHODIMP
mozJSComponentLoader : : AutoRegisterComponents ( PRInt32 when ,
2000-01-24 21:28:28 +00:00
nsIFile * aDirectory )
1999-09-07 06:18:08 +00:00
{
return RegisterComponentsInDir ( when , aDirectory ) ;
}
nsresult
2000-01-24 21:28:28 +00:00
mozJSComponentLoader : : RegisterComponentsInDir ( PRInt32 when , nsIFile * dir )
1999-09-07 06:18:08 +00:00
{
nsresult rv ;
PRBool isDir ;
if ( NS_FAILED ( rv = dir - > IsDirectory ( & isDir ) ) )
return rv ;
if ( ! isDir )
return NS_ERROR_INVALID_ARG ;
2000-01-24 21:28:28 +00:00
// Create a directory iterator
nsCOMPtr < nsISimpleEnumerator > dirIterator ;
rv = dir - > GetDirectoryEntries ( getter_AddRefs ( dirIterator ) ) ;
1999-09-07 06:18:08 +00:00
2000-01-24 21:28:28 +00:00
if ( NS_FAILED ( rv ) ) return rv ;
// whip through the directory to register every file
nsIFile * dirEntry = NULL ;
PRBool more = PR_FALSE ;
rv = dirIterator - > HasMoreElements ( & more ) ;
if ( NS_FAILED ( rv ) ) return rv ;
while ( more = = PR_TRUE )
{
rv = dirIterator - > GetNext ( ( nsISupports * * ) & dirEntry ) ;
if ( NS_SUCCEEDED ( rv ) )
{
rv = dirEntry - > IsDirectory ( & isDir ) ;
if ( NS_SUCCEEDED ( rv ) )
{
if ( isDir = = PR_TRUE )
{
// This is a directory. Grovel for components into the directory.
rv = RegisterComponentsInDir ( when , dirEntry ) ;
}
else
{
PRBool registered ;
// This is a file. Try to register it.
rv = AutoRegisterComponent ( when , dirEntry , & registered ) ;
}
}
NS_RELEASE ( dirEntry ) ;
1999-09-07 06:18:08 +00:00
}
2000-01-24 21:28:28 +00:00
rv = dirIterator - > HasMoreElements ( & more ) ;
if ( NS_FAILED ( rv ) ) return rv ;
1999-09-07 06:18:08 +00:00
}
return NS_OK ;
}
2000-04-18 05:26:40 +00:00
1999-09-07 20:30:25 +00:00
nsresult
mozJSComponentLoader : : SetRegistryInfo ( const char * registryLocation ,
2000-01-24 21:28:28 +00:00
nsIFile * component )
1999-09-07 20:30:25 +00:00
{
2000-05-16 05:09:31 +00:00
nsresult rv ;
2002-06-14 21:33:05 +00:00
if ( ! mLoaderManager )
return NS_ERROR_FAILURE ;
2000-01-24 21:28:28 +00:00
PRInt64 modDate ;
2002-06-14 21:33:05 +00:00
rv = component - > GetLastModifiedTime ( & modDate ) ;
if ( NS_FAILED ( rv ) )
1999-09-07 20:30:25 +00:00
return rv ;
1999-11-10 00:34:26 +00:00
# ifdef DEBUG_shaver_off
1999-09-27 02:22:25 +00:00
fprintf ( stderr , " SetRegistryInfo(%s) => (%d,%d) \n " , registryLocation ,
modDate , fileSize ) ;
# endif
2002-06-14 21:33:05 +00:00
return mLoaderManager - > SaveFileInfo ( component , registryLocation , modDate ) ;
1999-09-07 20:30:25 +00:00
}
2000-04-18 05:26:40 +00:00
nsresult
2002-06-14 21:33:05 +00:00
mozJSComponentLoader : : RemoveRegistryInfo ( nsIFile * component , const char * registryLocation )
2000-04-18 05:26:40 +00:00
{
2002-06-14 21:33:05 +00:00
if ( ! mLoaderManager )
return NS_ERROR_FAILURE ;
return mLoaderManager - > RemoveFileInfo ( component , registryLocation ) ;
2000-04-18 05:26:40 +00:00
}
2000-05-16 05:09:31 +00:00
1999-09-07 20:30:25 +00:00
PRBool
mozJSComponentLoader : : HasChanged ( const char * registryLocation ,
2000-01-24 21:28:28 +00:00
nsIFile * component )
1999-09-07 20:30:25 +00:00
{
2002-06-14 21:33:05 +00:00
if ( ! mLoaderManager )
return NS_ERROR_FAILURE ;
2000-01-24 21:28:28 +00:00
2002-06-14 21:33:05 +00:00
PRInt64 lastTime ;
component - > GetLastModifiedTime ( & lastTime ) ;
PRBool hasChanged = PR_TRUE ;
mLoaderManager - > HasFileChanged ( component , registryLocation , lastTime , & hasChanged ) ;
return hasChanged ;
1999-09-07 20:30:25 +00:00
}
1999-09-07 06:18:08 +00:00
NS_IMETHODIMP
mozJSComponentLoader : : AutoRegisterComponent ( PRInt32 when ,
2000-01-24 21:28:28 +00:00
nsIFile * component ,
1999-09-07 06:18:08 +00:00
PRBool * registered )
{
nsresult rv ;
if ( ! registered )
return NS_ERROR_NULL_POINTER ;
1999-09-21 22:10:03 +00:00
const char jsExtension [ ] = " .js " ;
1999-09-27 02:22:25 +00:00
int jsExtensionLen = 3 ;
2002-04-27 05:33:09 +00:00
nsCAutoString leafName ;
1999-09-07 06:18:08 +00:00
* registered = PR_FALSE ;
/* we only do files */
PRBool isFile = PR_FALSE ;
if ( NS_FAILED ( rv = component - > IsFile ( & isFile ) ) | | ! isFile )
return rv ;
2002-04-27 05:33:09 +00:00
if ( NS_FAILED ( rv = component - > GetNativeLeafName ( leafName ) ) )
1999-09-07 06:18:08 +00:00
return rv ;
2002-04-27 05:33:09 +00:00
int len = leafName . Length ( ) ;
1999-09-07 06:18:08 +00:00
1999-11-10 00:34:26 +00:00
/* if it's not *.js, return now */
1999-09-07 06:18:08 +00:00
if ( len < jsExtensionLen | | // too short
2002-04-27 05:33:09 +00:00
PL_strcasecmp ( leafName . get ( ) + len - jsExtensionLen , jsExtension ) )
1999-11-10 00:34:26 +00:00
return NS_OK ;
1999-09-07 06:18:08 +00:00
1999-11-10 00:34:26 +00:00
# ifdef DEBUG_shaver_off
fprintf ( stderr , " mJCL: registering JS component %s \n " ,
2002-04-27 05:33:09 +00:00
leafName . get ( ) ) ;
1999-09-07 06:18:08 +00:00
# endif
2000-05-17 01:54:18 +00:00
1999-11-10 00:34:26 +00:00
rv = AttemptRegistration ( component , PR_FALSE ) ;
2001-03-27 05:35:52 +00:00
# ifdef DEBUG_shaver_off
1999-11-10 00:34:26 +00:00
if ( NS_SUCCEEDED ( rv ) )
2002-04-27 05:33:09 +00:00
fprintf ( stderr , " registered module %s \n " , leafName . get ( ) ) ;
1999-11-10 00:34:26 +00:00
else if ( rv = = NS_ERROR_FACTORY_REGISTER_AGAIN )
2002-04-27 05:33:09 +00:00
fprintf ( stderr , " deferred module %s \n " , leafName . get ( ) ) ;
1999-11-10 00:34:26 +00:00
else
2002-04-27 05:33:09 +00:00
fprintf ( stderr , " failed to register %s \n " , leafName . get ( ) ) ;
1999-11-10 00:34:26 +00:00
# endif
* registered = ( PRBool ) NS_SUCCEEDED ( rv ) ;
return NS_OK ;
}
1999-09-07 06:18:08 +00:00
2000-04-18 05:26:40 +00:00
NS_IMETHODIMP
mozJSComponentLoader : : AutoUnregisterComponent ( PRInt32 when ,
nsIFile * component ,
PRBool * unregistered )
{
nsresult rv ;
if ( ! unregistered )
return NS_ERROR_NULL_POINTER ;
const char jsExtension [ ] = " .js " ;
int jsExtensionLen = 3 ;
2002-04-27 05:33:09 +00:00
nsCAutoString leafName ;
2000-04-18 05:26:40 +00:00
* unregistered = PR_FALSE ;
/* we only do files */
PRBool isFile = PR_FALSE ;
if ( NS_FAILED ( rv = component - > IsFile ( & isFile ) ) | | ! isFile )
return rv ;
2002-04-27 05:33:09 +00:00
if ( NS_FAILED ( rv = component - > GetNativeLeafName ( leafName ) ) )
2000-04-18 05:26:40 +00:00
return rv ;
2002-04-27 05:33:09 +00:00
int len = leafName . Length ( ) ;
2000-04-18 05:26:40 +00:00
/* if it's not *.js, return now */
if ( len < jsExtensionLen | | // too short
2002-04-27 05:33:09 +00:00
PL_strcasecmp ( leafName . get ( ) + len - jsExtensionLen , jsExtension ) )
2000-04-18 05:26:40 +00:00
return NS_OK ;
rv = UnregisterComponent ( component ) ;
# ifdef DEBUG_dp
if ( NS_SUCCEEDED ( rv ) )
2002-04-27 05:33:09 +00:00
fprintf ( stderr , " unregistered module %s \n " , leafName . get ( ) ) ;
2000-04-18 05:26:40 +00:00
else
2002-04-27 05:33:09 +00:00
fprintf ( stderr , " failed to unregister %s \n " , leafName . get ( ) ) ;
2000-04-18 05:26:40 +00:00
# endif
* unregistered = ( PRBool ) NS_SUCCEEDED ( rv ) ;
return NS_OK ;
}
1999-11-10 00:34:26 +00:00
nsresult
2000-01-24 21:28:28 +00:00
mozJSComponentLoader : : AttemptRegistration ( nsIFile * component ,
1999-11-10 00:34:26 +00:00
PRBool deferred )
{
nsXPIDLCString registryLocation ;
nsresult rv ;
nsIModule * module ;
2001-12-19 00:12:41 +00:00
// what I want to do here is QI for a Component Registration Manager. Since this
// has not been invented yet, QI to the obsolete manager. Kids, don't do this at home.
nsCOMPtr < nsIComponentManagerObsolete > obsoleteManager = do_QueryInterface ( mCompMgr , & rv ) ;
if ( obsoleteManager )
rv = obsoleteManager - > RegistryLocationForSpec ( component ,
getter_Copies ( registryLocation ) ) ;
1999-09-07 06:18:08 +00:00
if ( NS_FAILED ( rv ) )
1999-11-10 00:34:26 +00:00
return rv ;
1999-09-07 06:18:08 +00:00
1999-11-10 00:34:26 +00:00
/* no need to check registry data on deferred reg */
if ( ! deferred & & ! HasChanged ( registryLocation , component ) )
2002-06-14 21:33:05 +00:00
return NS_OK ;
1999-11-10 00:34:26 +00:00
1999-09-27 02:22:25 +00:00
module = ModuleForLocation ( registryLocation , component ) ;
if ( ! module )
goto out ;
2000-05-17 01:54:18 +00:00
{
// Notify observers, if any, of autoregistration work
2000-09-21 04:30:32 +00:00
nsCOMPtr < nsIObserverService > observerService =
do_GetService ( kObserverServiceContractID ) ;
if ( observerService )
2000-05-17 01:54:18 +00:00
{
2001-10-16 03:35:52 +00:00
nsCOMPtr < nsIServiceManager > mgr ;
rv = NS_GetServiceManager ( getter_AddRefs ( mgr ) ) ;
2000-05-17 01:54:18 +00:00
if ( NS_SUCCEEDED ( rv ) )
{
2001-11-14 01:33:42 +00:00
// this string can't come from a string bundle, because we
// don't have string bundles yet.
2000-05-17 01:54:18 +00:00
NS_ConvertASCIItoUCS2 fileName ( " (no name) " ) ;
// get the file name
if ( component )
{
2002-05-07 23:07:19 +00:00
component - > GetLeafName ( fileName ) ;
2000-05-17 01:54:18 +00:00
}
2001-11-14 01:33:42 +00:00
// this string can't come from a string bundle, because we
// don't have string bundles yet.
( void ) observerService - >
NotifyObservers ( mgr ,
NS_XPCOM_AUTOREGISTRATION_OBSERVER_ID ,
PromiseFlatString ( NS_LITERAL_STRING ( " Registering JS component " ) +
fileName ) . get ( ) ) ;
2000-05-17 01:54:18 +00:00
}
}
}
1999-09-22 03:18:27 +00:00
rv = module - > RegisterSelf ( mCompMgr , component , registryLocation ,
jsComponentTypeName ) ;
1999-11-10 00:34:26 +00:00
if ( rv = = NS_ERROR_FACTORY_REGISTER_AGAIN ) {
if ( ! deferred )
mDeferredComponents . AppendElement ( component ) ;
/*
* we don ' t enter in the registry because we may want to
* try again on a later autoreg , in case a dependency has
* become available .
*/
} else {
out :
SetRegistryInfo ( registryLocation , component ) ;
1999-09-07 06:18:08 +00:00
}
1999-09-07 20:30:25 +00:00
1999-11-10 00:34:26 +00:00
return rv ;
}
2000-04-18 05:26:40 +00:00
nsresult
mozJSComponentLoader : : UnregisterComponent ( nsIFile * component )
{
nsXPIDLCString registryLocation ;
nsresult rv ;
nsIModule * module ;
2001-12-19 00:12:41 +00:00
// what I want to do here is QI for a Component Registration Manager. Since this
// has not been invented yet, QI to the obsolete manager. Kids, don't do this at home.
nsCOMPtr < nsIComponentManagerObsolete > obsoleteManager = do_QueryInterface ( mCompMgr , & rv ) ;
if ( obsoleteManager )
rv = obsoleteManager - > RegistryLocationForSpec ( component ,
getter_Copies ( registryLocation ) ) ;
2000-04-18 05:26:40 +00:00
if ( NS_FAILED ( rv ) )
return rv ;
module = ModuleForLocation ( registryLocation , component ) ;
if ( ! module )
return NS_ERROR_FAILURE ;
2000-05-17 01:54:18 +00:00
{
// Notify observers, if any, of autoregistration work
2000-09-21 04:30:32 +00:00
nsCOMPtr < nsIObserverService > observerService =
do_GetService ( kObserverServiceContractID ) ;
if ( observerService )
2000-05-17 01:54:18 +00:00
{
2001-10-16 03:35:52 +00:00
nsCOMPtr < nsIServiceManager > mgr ;
rv = NS_GetServiceManager ( getter_AddRefs ( mgr ) ) ;
2000-05-17 01:54:18 +00:00
if ( NS_SUCCEEDED ( rv ) )
{
2001-10-19 20:52:59 +00:00
( void ) observerService - > NotifyObservers ( mgr ,
NS_XPCOM_AUTOREGISTRATION_OBSERVER_ID ,
2001-11-14 01:33:42 +00:00
NS_LITERAL_STRING ( " Unregistering JS component " ) . get ( ) ) ;
2000-05-17 01:54:18 +00:00
}
}
}
2000-04-18 05:26:40 +00:00
rv = module - > UnregisterSelf ( mCompMgr , component , registryLocation ) ;
if ( NS_SUCCEEDED ( rv ) )
{
// Remove any autoreg specific info. Ignore error.
2002-06-14 21:33:05 +00:00
RemoveRegistryInfo ( component , registryLocation ) ;
2000-04-18 05:26:40 +00:00
}
return rv ;
}
1999-11-10 00:34:26 +00:00
nsresult
mozJSComponentLoader : : RegisterDeferredComponents ( PRInt32 aWhen ,
PRBool * aRegistered )
{
nsresult rv ;
* aRegistered = PR_FALSE ;
PRUint32 count ;
rv = mDeferredComponents . Count ( & count ) ;
2001-03-27 05:35:52 +00:00
# ifdef DEBUG_shaver_off
1999-11-10 00:34:26 +00:00
fprintf ( stderr , " mJCL: registering deferred (%d) \n " , count ) ;
# endif
if ( NS_FAILED ( rv ) | | ! count )
return NS_OK ;
for ( PRUint32 i = 0 ; i < count ; i + + ) {
2000-01-24 21:28:28 +00:00
nsCOMPtr < nsIFile > component ;
2000-08-24 04:10:47 +00:00
rv = mDeferredComponents . QueryElementAt ( i , NS_GET_IID ( nsIFile ) , getter_AddRefs ( component ) ) ;
1999-11-10 00:34:26 +00:00
if ( NS_FAILED ( rv ) )
continue ;
2000-08-24 07:50:27 +00:00
1999-11-10 00:34:26 +00:00
rv = AttemptRegistration ( component , PR_TRUE /* deferred */ ) ;
if ( rv ! = NS_ERROR_FACTORY_REGISTER_AGAIN ) {
if ( NS_SUCCEEDED ( rv ) )
* aRegistered = PR_TRUE ;
mDeferredComponents . RemoveElementAt ( i ) ;
}
}
1999-09-07 20:30:25 +00:00
2001-03-27 05:35:52 +00:00
# ifdef DEBUG_shaver_off
1999-11-10 00:34:26 +00:00
rv = mDeferredComponents . Count ( & count ) ;
if ( NS_SUCCEEDED ( rv ) ) {
if ( * aRegistered )
fprintf ( stderr , " mJCL: registered deferred, %d left \n " ,
count ) ;
else
fprintf ( stderr , " mJCL: didn't register any components, %d left \n " ,
count ) ;
}
# endif
/* are there any fatal errors? */
return NS_OK ;
1999-09-07 20:30:25 +00:00
}
2000-04-18 05:26:40 +00:00
1999-09-07 20:30:25 +00:00
nsIModule *
mozJSComponentLoader : : ModuleForLocation ( const char * registryLocation ,
2000-01-24 21:28:28 +00:00
nsIFile * component )
1999-09-07 20:30:25 +00:00
{
2000-10-05 04:15:43 +00:00
nsresult rv ;
1999-11-18 15:39:28 +00:00
nsIModule * module = nsnull ;
1999-09-27 02:22:25 +00:00
if ( ! mInitialized & &
NS_FAILED ( ReallyInit ( ) ) )
1999-11-18 15:39:28 +00:00
return nsnull ;
1999-09-27 02:22:25 +00:00
1999-09-07 20:30:25 +00:00
PLHashNumber hash = PL_HashString ( registryLocation ) ;
PLHashEntry * * hep = PL_HashTableRawLookup ( mModules , hash ,
( void * ) registryLocation ) ;
PLHashEntry * he = * hep ;
if ( he )
return ( nsIModule * ) he - > value ;
2000-10-05 04:15:43 +00:00
JSObject * global = GlobalForLocation ( registryLocation , component ) ;
if ( ! global ) {
1999-09-07 06:18:08 +00:00
# ifdef DEBUG_shaver
1999-09-07 20:30:25 +00:00
fprintf ( stderr , " GlobalForLocation failed! \n " ) ;
1999-09-07 06:18:08 +00:00
# endif
1999-09-07 20:30:25 +00:00
return nsnull ;
1999-09-07 06:18:08 +00:00
}
2000-09-13 23:57:52 +00:00
nsCOMPtr < nsIXPConnect > xpc = do_GetService ( kXPConnectServiceContractID ) ;
2000-08-24 07:50:27 +00:00
if ( ! xpc )
return nsnull ;
2000-09-21 04:30:32 +00:00
JSCLAutoContext cx ( mRuntime ) ;
if ( NS_FAILED ( cx . GetError ( ) ) )
1999-11-18 15:39:28 +00:00
return nsnull ;
2000-10-05 04:15:43 +00:00
JSObject * cm_jsobj ;
nsCOMPtr < nsIXPConnectJSObjectHolder > cm_holder ;
rv = xpc - > WrapNative ( cx , global , mCompMgr ,
NS_GET_IID ( nsIComponentManager ) ,
getter_AddRefs ( cm_holder ) ) ;
if ( NS_FAILED ( rv ) ) {
# ifdef DEBUG_shaver
fprintf ( stderr , " WrapNative(%p,%p,nsIComponentManager) failed: %x \n " ,
2001-03-27 05:35:52 +00:00
( void * ) ( JSContext * ) cx , ( void * ) mCompMgr , rv ) ;
2000-10-05 04:15:43 +00:00
# endif
return nsnull ;
}
rv = cm_holder - > GetJSObject ( & cm_jsobj ) ;
if ( NS_FAILED ( rv ) ) {
# ifdef DEBUG_shaver
fprintf ( stderr , " GetJSObject of ComponentManager failed \n " ) ;
# endif
return nsnull ;
}
2000-09-21 04:30:32 +00:00
JSCLAutoErrorReporterSetter aers ( cx , Reporter ) ;
1999-11-18 15:39:28 +00:00
2004-10-12 03:37:20 +00:00
jsval argv [ 2 ] , retval , NSGetModule_val ;
if ( ! JS_GetProperty ( cx , global , " NSGetModule " , & NSGetModule_val ) | |
2004-10-12 03:49:28 +00:00
JSVAL_IS_VOID ( NSGetModule_val ) ) {
2004-10-12 03:37:20 +00:00
return nsnull ;
}
if ( JS_TypeOfValue ( cx , NSGetModule_val ) ! = JSTYPE_FUNCTION ) {
JS_ReportError ( cx , " %s has NSGetModule property that is not a function " ,
registryLocation ) ;
return nsnull ;
}
2000-10-05 04:15:43 +00:00
argv [ 0 ] = OBJECT_TO_JSVAL ( cm_jsobj ) ;
2000-09-21 04:30:32 +00:00
argv [ 1 ] = STRING_TO_JSVAL ( JS_NewStringCopyZ ( cx , registryLocation ) ) ;
2004-10-12 03:37:20 +00:00
if ( ! JS_CallFunctionValue ( cx , global , NSGetModule_val , 2 , argv , & retval ) )
2000-09-21 04:30:32 +00:00
return nsnull ;
1999-09-07 06:18:08 +00:00
1999-11-10 00:34:26 +00:00
# ifdef DEBUG_shaver_off
2000-09-21 04:30:32 +00:00
JSString * s = JS_ValueToString ( cx , retval ) ;
1999-09-07 06:18:08 +00:00
fprintf ( stderr , " mJCL: %s::NSGetModule returned %s \n " ,
1999-09-07 20:30:25 +00:00
registryLocation , JS_GetStringBytes ( s ) ) ;
1999-09-07 06:18:08 +00:00
# endif
1999-09-07 20:30:25 +00:00
JSObject * jsModuleObj ;
2000-09-21 04:30:32 +00:00
if ( ! JS_ValueToObject ( cx , retval , & jsModuleObj ) ) {
1999-09-07 20:30:25 +00:00
/* XXX report error properly */
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 17:42:36 +00:00
# ifdef DEBUG
1999-09-07 06:18:08 +00:00
fprintf ( stderr , " mJCL: couldn't convert %s's nsIModule to obj \n " ,
1999-09-07 20:30:25 +00:00
registryLocation ) ;
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 17:42:36 +00:00
# endif
2000-09-21 04:30:32 +00:00
return nsnull ;
1999-09-07 06:18:08 +00:00
}
2000-09-21 04:30:32 +00:00
if ( NS_FAILED ( xpc - > WrapJS ( cx , jsModuleObj , NS_GET_IID ( nsIModule ) ,
2000-08-24 07:50:27 +00:00
( void * * ) & module ) ) ) {
1999-09-07 20:30:25 +00:00
/* XXX report error properly */
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 17:42:36 +00:00
# ifdef DEBUG
1999-09-07 06:18:08 +00:00
fprintf ( stderr , " mJCL: couldn't get nsIModule from jsval \n " ) ;
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 17:42:36 +00:00
# endif
2000-09-21 04:30:32 +00:00
return nsnull ;
1999-09-07 06:18:08 +00:00
}
/* we hand our reference to the hash table, it'll be released much later */
1999-11-18 15:39:28 +00:00
he = PL_HashTableRawAdd ( mModules , hep , hash ,
nsCRT : : strdup ( registryLocation ) , module ) ;
2000-09-21 04:30:32 +00:00
1999-09-07 20:30:25 +00:00
return module ;
1999-09-07 06:18:08 +00:00
}
JSObject *
1999-09-07 20:30:25 +00:00
mozJSComponentLoader : : GlobalForLocation ( const char * aLocation ,
2000-01-24 21:28:28 +00:00
nsIFile * component )
1999-09-07 06:18:08 +00:00
{
2000-10-05 04:15:43 +00:00
JSObject * global = nsnull ;
1999-09-07 20:30:25 +00:00
PRBool needRelease = PR_FALSE ;
2003-03-23 07:22:18 +00:00
JSScript * script = nsnull ;
1999-09-07 06:18:08 +00:00
PLHashNumber hash = PL_HashString ( aLocation ) ;
PLHashEntry * * hep = PL_HashTableRawLookup ( mGlobals , hash ,
( void * ) aLocation ) ;
PLHashEntry * he = * hep ;
if ( he )
return ( JSObject * ) he - > value ;
1999-09-24 01:37:44 +00:00
2003-03-23 07:22:18 +00:00
if ( ! mInitialized & & NS_FAILED ( ReallyInit ( ) ) )
1999-09-24 01:37:44 +00:00
return nsnull ;
1999-09-07 06:18:08 +00:00
2000-02-16 06:26:21 +00:00
nsresult rv ;
2000-05-26 04:56:23 +00:00
JSPrincipals * jsPrincipals = nsnull ;
2000-02-16 06:26:21 +00:00
2003-03-23 07:22:18 +00:00
JSCLAutoContext cx ( mRuntime ) ;
if ( NS_FAILED ( cx . GetError ( ) ) )
return nsnull ;
2000-08-16 04:01:02 +00:00
# ifndef XPCONNECT_STANDALONE
nsCOMPtr < nsIScriptObjectPrincipal > backstagePass =
new BackstagePass ( mSystemPrincipal ) ;
2000-02-16 06:26:21 +00:00
2003-11-03 04:26:55 +00:00
rv = mSystemPrincipal - > GetJSPrincipals ( cx , & jsPrincipals ) ;
2000-08-16 04:01:02 +00:00
if ( NS_FAILED ( rv ) | | ! jsPrincipals )
2003-03-23 07:22:18 +00:00
return nsnull ;
2000-02-16 06:26:21 +00:00
2000-08-16 04:01:02 +00:00
# else
2000-08-31 10:44:28 +00:00
nsCOMPtr < nsISupports > backstagePass = new BackstagePass ( ) ;
2000-08-16 04:01:02 +00:00
# endif
2000-05-26 04:56:23 +00:00
2003-03-23 07:22:18 +00:00
JSCLAutoErrorReporterSetter aers ( cx , Reporter ) ;
nsCOMPtr < nsIXPConnectJSObjectHolder > holder ;
2000-09-13 23:57:52 +00:00
nsCOMPtr < nsIXPConnect > xpc = do_GetService ( kXPConnectServiceContractID ) ;
2000-08-24 07:50:27 +00:00
if ( ! xpc )
2003-03-23 07:22:18 +00:00
goto out ;
2000-09-21 04:30:32 +00:00
2000-10-05 04:15:43 +00:00
rv = xpc - > InitClassesWithNewWrappedGlobal ( cx , backstagePass ,
NS_GET_IID ( nsISupports ) ,
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 17:42:36 +00:00
PR_FALSE ,
2000-10-05 04:15:43 +00:00
getter_AddRefs ( holder ) ) ;
2000-08-16 04:01:02 +00:00
if ( NS_FAILED ( rv ) )
2003-03-23 07:22:18 +00:00
goto out ;
2000-10-05 04:15:43 +00:00
rv = holder - > GetJSObject ( & global ) ;
2003-03-23 07:22:18 +00:00
if ( NS_FAILED ( rv ) ) {
NS_ASSERTION ( global = = nsnull , " bad GetJSObject? " ) ;
goto out ;
}
1999-09-07 20:30:25 +00:00
Landing the XPCDOM_20010329_BRANCH branch, changes mostly done by jband@netscape.com and jst@netscape.com, also some changes done by shaver@mozilla.org, peterv@netscape.com and markh@activestate.com. r= and sr= by vidur@netscape.com, jband@netscape.com, jst@netscpae.com, danm@netscape.com, hyatt@netscape.com, shaver@mozilla.org, dbradley@netscape.com, rpotts@netscape.com.
2001-05-08 17:42:36 +00:00
if ( ! JS_DefineFunctions ( cx , global , gGlobalFun ) ) {
2003-03-23 07:22:18 +00:00
global = nsnull ;
goto out ;
2000-10-05 04:15:43 +00:00
}
2000-08-16 04:01:02 +00:00
1999-09-07 20:30:25 +00:00
if ( ! component ) {
2001-12-19 00:12:41 +00:00
// what I want to do here is QI for a Component Registration Manager. Since this
// has not been invented yet, QI to the obsolete manager. Kids, don't do this at home.
nsCOMPtr < nsIComponentManagerObsolete > obsoleteManager = do_QueryInterface ( mCompMgr , & rv ) ;
2003-03-23 07:22:18 +00:00
if ( ! obsoleteManager ) {
global = nsnull ;
goto out ;
}
2001-12-19 00:12:41 +00:00
2003-03-23 07:22:18 +00:00
if ( NS_FAILED ( obsoleteManager - > SpecForRegistryLocation ( aLocation , & component ) ) ) {
global = nsnull ;
goto out ;
}
1999-09-07 20:30:25 +00:00
needRelease = PR_TRUE ;
}
2003-03-23 07:22:18 +00:00
{
nsCOMPtr < nsILocalFile > localFile = do_QueryInterface ( component ) ;
if ( ! localFile ) {
global = nsnull ;
goto out ;
}
2001-09-28 21:49:00 +00:00
2003-03-23 07:22:18 +00:00
// Quick hack to unbust XPCONNECT_STANDALONE.
// This leaves the jsdebugger with a non-URL pathname in the
// XPCONNECT_STANDALONE case - but at least it builds and runs otherwise.
// See: http://bugzilla.mozilla.org/show_bug.cgi?id=121438
{
nsCAutoString nativePath ;
FILE * fileHandle ;
2002-02-03 20:05:22 +00:00
# ifdef XPCONNECT_STANDALONE
2003-03-23 07:22:18 +00:00
localFile - > GetNativePath ( nativePath ) ;
2002-02-03 20:05:22 +00:00
# else
2003-03-23 07:22:18 +00:00
NS_GetURLSpecFromFile ( localFile , nativePath ) ;
2002-02-03 20:05:22 +00:00
# endif
2003-03-23 07:22:18 +00:00
rv = localFile - > OpenANSIFileDesc ( " r " , & fileHandle ) ;
if ( NS_FAILED ( rv ) ) {
global = nsnull ;
goto out ;
}
2000-01-24 21:28:28 +00:00
2003-03-23 07:22:18 +00:00
script =
JS_CompileFileHandleForPrincipals ( cx , global , nativePath . get ( ) ,
fileHandle , jsPrincipals ) ;
2000-01-24 21:28:28 +00:00
2003-03-23 07:22:18 +00:00
/* JS will close the filehandle after compilation is complete. */
2000-01-24 21:28:28 +00:00
2003-03-23 07:22:18 +00:00
if ( ! script ) {
1999-11-10 00:34:26 +00:00
# ifdef DEBUG_shaver_off
2003-03-23 07:22:18 +00:00
fprintf ( stderr , " mJCL: script compilation of %s FAILED \n " ,
nativePath . get ( ) ) ;
1999-09-07 20:30:25 +00:00
# endif
2003-03-23 07:22:18 +00:00
global = nsnull ;
goto out ;
}
1999-09-07 20:30:25 +00:00
1999-11-10 00:34:26 +00:00
# ifdef DEBUG_shaver_off
2003-03-23 07:22:18 +00:00
fprintf ( stderr , " mJCL: compiled JS component %s \n " ,
nativePath . get ( ) ) ;
1999-09-07 20:30:25 +00:00
# endif
2003-03-23 07:22:18 +00:00
jsval retval ;
if ( ! JS_ExecuteScript ( cx , global , script , & retval ) ) {
1999-11-10 00:34:26 +00:00
# ifdef DEBUG_shaver_off
2003-03-23 07:22:18 +00:00
fprintf ( stderr , " mJCL: failed to execute %s \n " ,
nativePath . get ( ) ) ;
1999-09-07 20:30:25 +00:00
# endif
2003-03-23 07:22:18 +00:00
global = nsnull ;
goto out ;
}
}
1999-09-07 20:30:25 +00:00
}
2003-03-23 07:22:18 +00:00
{
/* freed when we remove from the table */
char * location = nsCRT : : strdup ( aLocation ) ;
he = PL_HashTableRawAdd ( mGlobals , hep , hash , location , global ) ;
JS_AddNamedRoot ( cx , & he - > value , location ) ;
}
1999-09-07 20:30:25 +00:00
out :
2003-03-23 07:22:18 +00:00
if ( jsPrincipals )
JSPRINCIPALS_DROP ( cx , jsPrincipals ) ;
2000-02-23 06:09:04 +00:00
if ( script )
2000-09-21 04:30:32 +00:00
JS_DestroyScript ( cx , script ) ;
1999-09-07 20:30:25 +00:00
if ( needRelease )
NS_RELEASE ( component ) ;
2000-09-21 04:30:32 +00:00
2000-10-05 04:15:43 +00:00
return global ;
1999-09-07 06:18:08 +00:00
}
NS_IMETHODIMP
mozJSComponentLoader : : OnRegister ( const nsIID & aCID , const char * aType ,
2000-09-13 23:57:52 +00:00
const char * aClassName , const char * aContractID ,
1999-09-07 06:18:08 +00:00
const char * aLocation ,
PRBool aReplace , PRBool aPersist )
{
1999-11-10 00:34:26 +00:00
# ifdef DEBUG_shaver_off
2000-09-13 23:57:52 +00:00
fprintf ( stderr , " mJCL: registered %s/%s in %s \n " , aClassName , aContractID ,
1999-09-07 06:18:08 +00:00
aLocation ) ;
# endif
return NS_OK ;
}
NS_IMETHODIMP
mozJSComponentLoader : : UnloadAll ( PRInt32 aWhen )
{
1999-11-10 00:34:26 +00:00
if ( mInitialized ) {
2003-03-23 07:22:18 +00:00
mInitialized = PR_FALSE ;
1999-11-10 00:34:26 +00:00
// stabilize the component manager, etc.
nsCOMPtr < nsIComponentManager > kungFuDeathGrip = mCompMgr ;
2003-03-23 07:22:18 +00:00
PL_HashTableEnumerateEntries ( mModules ,
UnloadAndReleaseModules ,
1999-11-10 00:34:26 +00:00
mCompMgr ) ;
2003-03-23 07:22:18 +00:00
PL_HashTableDestroy ( mModules ) ;
mModules = nsnull ;
PL_HashTableEnumerateEntries ( mGlobals , UnrootGlobals , mRuntime ) ;
PL_HashTableDestroy ( mGlobals ) ;
mGlobals = nsnull ;
2003-02-23 07:03:11 +00:00
JSContext * cx = JS_NewContext ( mRuntime , 256 ) ;
if ( cx ) {
2003-03-23 07:22:18 +00:00
JS_GC ( cx ) ;
2003-02-23 07:03:11 +00:00
JS_DestroyContext ( cx ) ;
}
2003-03-23 07:22:18 +00:00
mRuntimeService = nsnull ;
1999-11-10 00:34:26 +00:00
}
2001-03-27 05:35:52 +00:00
# ifdef DEBUG_shaver_off
1999-09-07 06:18:08 +00:00
fprintf ( stderr , " mJCL: UnloadAll(%d) \n " , aWhen ) ;
# endif
1999-11-10 00:34:26 +00:00
1999-09-07 06:18:08 +00:00
return NS_OK ;
}
1999-09-30 21:47:04 +00:00
//----------------------------------------------------------------------
2000-09-21 04:30:32 +00:00
JSCLAutoContext : : JSCLAutoContext ( JSRuntime * rt )
: mContext ( nsnull ) , mError ( NS_OK ) , mPopNeeded ( JS_FALSE ) , mContextThread ( 0 )
{
nsCOMPtr < nsIThreadJSContextStack > cxstack =
do_GetService ( kJSContextStackContractID , & mError ) ;
if ( NS_SUCCEEDED ( mError ) ) {
2000-10-05 04:15:43 +00:00
mError = cxstack - > GetSafeJSContext ( & mContext ) ;
if ( NS_SUCCEEDED ( mError ) & & mContext ) {
mError = cxstack - > Push ( mContext ) ;
2000-09-21 04:30:32 +00:00
if ( NS_SUCCEEDED ( mError ) ) {
2000-10-05 04:15:43 +00:00
mPopNeeded = JS_TRUE ;
2000-09-21 04:30:32 +00:00
}
}
}
if ( mContext ) {
mContextThread = JS_GetContextThread ( mContext ) ;
if ( mContextThread ) {
JS_BeginRequest ( mContext ) ;
}
} else {
if ( NS_SUCCEEDED ( mError ) ) {
mError = NS_ERROR_FAILURE ;
}
}
}
JSCLAutoContext : : ~ JSCLAutoContext ( )
{
if ( mContext & & mContextThread ) {
2003-03-23 07:22:18 +00:00
JS_ClearNewbornRoots ( mContext ) ;
2000-09-21 04:30:32 +00:00
JS_EndRequest ( mContext ) ;
}
if ( mPopNeeded ) {
nsCOMPtr < nsIThreadJSContextStack > cxstack =
do_GetService ( kJSContextStackContractID ) ;
if ( cxstack ) {
JSContext * cx ;
nsresult rv = cxstack - > Pop ( & cx ) ;
NS_ASSERTION ( NS_SUCCEEDED ( rv ) & & cx = = mContext , " push/pop mismatch " ) ;
}
}
}
//----------------------------------------------------------------------
2000-05-26 04:56:23 +00:00
/* XXX this should all be data-driven, via NS_IMPL_GETMODULE_WITH_CATEGORIES */