2007-03-22 10:30:00 -07:00
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim : set ts = 2 sw = 4 et tw = 80 :
*
* * * * * * 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
* http : //www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an " AS IS " basis ,
* WITHOUT WARRANTY OF ANY KIND , either express or implied . See the License
* for the specific language governing rights and limitations under the
* License .
*
* The Original Code is Mozilla Communicator client code , released
* March 31 , 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation .
* Portions created by the Initial Developer are Copyright ( C ) 1998
* the Initial Developer . All Rights Reserved .
*
* Contributor ( s ) :
* John Bandhauer < jband @ netscape . com >
* Pierre Phaneuf < pp @ ludusdesign . com >
* IBM Corp .
* Dan Mosedale < dan . mosedale @ oracle . com >
2009-08-20 08:35:30 -07:00
* Serge Gautherie < sgautherie . bz @ free . fr >
2007-03-22 10:30:00 -07: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 * * * * * */
/* XPConnect JavaScript interactive shell. */
# include <stdio.h>
2011-10-10 23:00:28 -07:00
# include "mozilla/Util.h"
2010-03-03 21:02:55 -08:00
# include "jsapi.h"
# include "jsdbgapi.h"
2011-05-30 13:28:01 -07:00
# include "jsfriendapi.h"
2010-03-03 21:02:55 -08:00
# include "jsprf.h"
2009-01-20 11:56:44 -08:00
# include "nsXULAppAPI.h"
2007-03-22 10:30:00 -07:00
# include "nsServiceManagerUtils.h"
# include "nsComponentManagerUtils.h"
2009-01-20 11:56:44 -08:00
# include "nsStringAPI.h"
2007-03-22 10:30:00 -07:00
# include "nsIXPConnect.h"
# include "nsIXPCScriptable.h"
# include "nsIInterfaceInfo.h"
# include "nsIInterfaceInfoManager.h"
# include "nsIXPCScriptable.h"
# include "nsIServiceManager.h"
# include "nsIComponentManager.h"
# include "nsIComponentRegistrar.h"
2009-01-18 09:01:15 -08:00
# include "nsILocalFile.h"
# include "nsStringAPI.h"
2009-01-20 11:56:44 -08:00
# include "nsIDirectoryService.h"
# include "nsILocalFile.h"
# include "nsDirectoryServiceDefs.h"
2009-07-17 07:41:26 -07:00
# include "nsAppDirectoryServiceDefs.h"
2007-03-22 10:30:00 -07:00
# include "nscore.h"
2009-07-17 07:41:26 -07:00
# include "nsArrayEnumerator.h"
# include "nsCOMArray.h"
# include "nsDirectoryServiceUtils.h"
2007-03-22 10:30:00 -07:00
# include "nsMemory.h"
2009-01-20 11:56:44 -08:00
# include "nsISupportsImpl.h"
2007-03-22 10:30:00 -07:00
# include "nsIJSRuntimeService.h"
# include "nsCOMPtr.h"
2007-06-20 17:10:48 -07:00
# include "nsAutoPtr.h"
2007-03-22 10:30:00 -07:00
# include "nsIXPCSecurityManager.h"
2010-12-06 12:45:00 -08:00
# include "xpcpublic.h"
2008-06-03 03:56:09 -07:00
# ifdef XP_MACOSX
# include "xpcshellMacUtils.h"
# endif
2009-01-18 09:01:15 -08:00
# ifdef XP_WIN
# include <windows.h>
# endif
2007-03-22 10:30:00 -07:00
2011-11-09 16:27:08 -08:00
# ifdef ANDROID
# include <android/log.h>
# endif
2007-03-22 10:30:00 -07:00
# include "nsIScriptSecurityManager.h"
# include "nsIPrincipal.h"
// all this crap is needed to do the interactive shell stuff
# include <stdlib.h>
# include <errno.h>
2009-01-16 14:10:48 -08:00
# ifdef HAVE_IO_H
2007-03-22 10:30:00 -07:00
# include <io.h> /* for isatty() */
2009-01-16 14:10:48 -08:00
# endif
# ifdef HAVE_UNISTD_H
2007-03-22 10:30:00 -07:00
# include <unistd.h> /* for isatty() */
# endif
# include "nsIJSContextStack.h"
2009-08-20 08:35:30 -07:00
# ifdef MOZ_CRASHREPORTER
# include "nsICrashReporter.h"
# endif
2011-10-10 23:00:28 -07:00
using namespace mozilla ;
2009-07-17 07:41:26 -07:00
class XPCShellDirProvider : public nsIDirectoryServiceProvider2
2009-01-20 11:56:44 -08:00
{
public :
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIDIRECTORYSERVICEPROVIDER
2009-07-17 07:41:26 -07:00
NS_DECL_NSIDIRECTORYSERVICEPROVIDER2
2009-01-20 11:56:44 -08:00
XPCShellDirProvider ( ) { }
~ XPCShellDirProvider ( ) { }
2011-09-28 23:19:26 -07:00
bool SetGREDir ( const char * dir ) ;
2009-01-20 11:56:44 -08:00
void ClearGREDir ( ) { mGREDir = nsnull ; }
private :
nsCOMPtr < nsILocalFile > mGREDir ;
} ;
2007-03-22 10:30:00 -07:00
/***************************************************************************/
# ifdef JS_THREADSAFE
# define DoBeginRequest(cx) JS_BeginRequest((cx))
# define DoEndRequest(cx) JS_EndRequest((cx))
# else
# define DoBeginRequest(cx) ((void)0)
# define DoEndRequest(cx) ((void)0)
# endif
/***************************************************************************/
2009-01-18 09:01:15 -08:00
static const char kXPConnectServiceContractID [ ] = " @mozilla.org/js/xpc/XPConnect;1 " ;
2007-03-22 10:30:00 -07:00
# define EXITCODE_RUNTIME_ERROR 3
# define EXITCODE_FILE_NOT_FOUND 4
FILE * gOutFile = NULL ;
FILE * gErrFile = NULL ;
2008-11-27 18:25:35 -08:00
FILE * gInFile = NULL ;
2007-03-22 10:30:00 -07:00
int gExitCode = 0 ;
2011-11-26 02:05:59 -08:00
JSBool gQuitting = false ;
static JSBool reportWarnings = true ;
static JSBool compileOnly = false ;
2007-03-22 10:30:00 -07:00
JSPrincipals * gJSPrincipals = nsnull ;
2009-01-18 09:01:15 -08:00
nsAutoString * gWorkingDirectory = nsnull ;
static JSBool
2010-07-14 23:19:36 -07:00
GetLocationProperty ( JSContext * cx , JSObject * obj , jsid id , jsval * vp )
2009-01-18 09:01:15 -08:00
{
2011-04-09 12:17:53 -07:00
# if !defined(XP_WIN) && !defined(XP_UNIX)
2009-01-18 09:01:15 -08:00
//XXX: your platform should really implement this
2011-11-26 02:05:59 -08:00
return false ;
2009-01-30 01:19:43 -08:00
# else
2009-01-18 09:01:15 -08:00
JSStackFrame * fp = JS_GetScriptedCaller ( cx , NULL ) ;
JSScript * script = JS_GetFrameScript ( cx , fp ) ;
const char * filename = JS_GetScriptFilename ( cx , script ) ;
if ( filename ) {
nsresult rv ;
nsCOMPtr < nsIXPConnect > xpc =
do_GetService ( kXPConnectServiceContractID , & rv ) ;
# if defined(XP_WIN)
// convert from the system codepage to UTF-16
int bufferSize = MultiByteToWideChar ( CP_ACP , 0 , filename ,
- 1 , NULL , 0 ) ;
nsAutoString filenameString ;
filenameString . SetLength ( bufferSize ) ;
MultiByteToWideChar ( CP_ACP , 0 , filename ,
- 1 , ( LPWSTR ) filenameString . BeginWriting ( ) ,
filenameString . Length ( ) ) ;
// remove the null terminator
filenameString . SetLength ( bufferSize - 1 ) ;
// replace forward slashes with backslashes,
// since nsLocalFileWin chokes on them
PRUnichar * start , * end ;
filenameString . BeginWriting ( & start , & end ) ;
2009-06-28 16:01:42 -07:00
2009-01-18 09:01:15 -08:00
while ( start ! = end ) {
if ( * start = = L ' / ' )
* start = L ' \\ ' ;
start + + ;
}
# elif defined(XP_UNIX)
NS_ConvertUTF8toUTF16 filenameString ( filename ) ;
# endif
nsCOMPtr < nsILocalFile > location ;
if ( NS_SUCCEEDED ( rv ) ) {
rv = NS_NewLocalFile ( filenameString ,
2011-10-17 07:59:28 -07:00
false , getter_AddRefs ( location ) ) ;
2009-01-18 09:01:15 -08:00
}
if ( ! location & & gWorkingDirectory ) {
// could be a relative path, try appending it to the cwd
// and then normalize
nsAutoString absolutePath ( * gWorkingDirectory ) ;
absolutePath . Append ( filenameString ) ;
rv = NS_NewLocalFile ( absolutePath ,
2011-10-17 07:59:28 -07:00
false , getter_AddRefs ( location ) ) ;
2009-01-18 09:01:15 -08:00
}
if ( location ) {
nsCOMPtr < nsIXPConnectJSObjectHolder > locationHolder ;
JSObject * locationObj = NULL ;
2011-09-28 23:19:26 -07:00
bool symlink ;
2009-02-02 05:53:23 -08:00
// don't normalize symlinks, because that's kind of confusing
if ( NS_SUCCEEDED ( location - > IsSymlink ( & symlink ) ) & &
! symlink )
location - > Normalize ( ) ;
2009-01-18 09:01:15 -08:00
rv = xpc - > WrapNative ( cx , obj , location ,
NS_GET_IID ( nsILocalFile ) ,
getter_AddRefs ( locationHolder ) ) ;
if ( NS_SUCCEEDED ( rv ) & &
NS_SUCCEEDED ( locationHolder - > GetJSObject ( & locationObj ) ) ) {
* vp = OBJECT_TO_JSVAL ( locationObj ) ;
}
}
}
2011-11-26 02:05:59 -08:00
return true ;
2009-01-30 01:19:43 -08:00
# endif
2009-01-18 09:01:15 -08:00
}
2007-03-22 10:30:00 -07:00
2009-06-29 16:10:54 -07:00
# ifdef EDITLINE
extern " C " {
2011-12-13 11:26:58 -08:00
extern JS_EXPORT_API ( char * ) readline ( const char * prompt ) ;
2010-05-13 00:06:13 -07:00
extern JS_EXPORT_API ( void ) add_history ( char * line ) ;
2009-06-29 16:10:54 -07:00
}
# endif
2008-11-27 18:25:35 -08:00
static JSBool
GetLine ( JSContext * cx , char * bufp , FILE * file , const char * prompt ) {
# ifdef EDITLINE
/*
* Use readline only if file is stdin , because there ' s no way to specify
* another handle . Are other filehandles interactive ?
*/
if ( file = = stdin ) {
char * linep = readline ( prompt ) ;
if ( ! linep )
2011-11-26 02:05:59 -08:00
return false ;
2008-11-27 18:25:35 -08:00
if ( * linep )
add_history ( linep ) ;
strcpy ( bufp , linep ) ;
JS_free ( cx , linep ) ;
bufp + = strlen ( bufp ) ;
* bufp + + = ' \n ' ;
* bufp = ' \0 ' ;
} else
# endif
{
2010-07-15 18:13:00 -07:00
char line [ 256 ] = { ' \0 ' } ;
2009-10-19 08:03:00 -07:00
fputs ( prompt , gOutFile ) ;
2008-11-27 18:25:35 -08:00
fflush ( gOutFile ) ;
2011-09-28 17:57:27 -07:00
if ( ( ! fgets ( line , sizeof line , file ) & & errno ! = EINTR ) | | feof ( file ) )
2011-11-26 02:05:59 -08:00
return false ;
2008-11-27 18:25:35 -08:00
strcpy ( bufp , line ) ;
}
2011-11-26 02:05:59 -08:00
return true ;
2008-11-27 18:25:35 -08:00
}
2008-09-06 15:21:43 -07:00
static void
2007-03-22 10:30:00 -07:00
my_ErrorReporter ( JSContext * cx , const char * message , JSErrorReport * report )
{
int i , j , k , n ;
char * prefix = NULL , * tmp ;
const char * ctmp ;
2008-10-12 11:32:34 -07:00
JSStackFrame * fp = nsnull ;
nsCOMPtr < nsIXPConnect > xpc ;
// Don't report an exception from inner JS frames as the callers may intend
// to handle it.
while ( ( fp = JS_FrameIterator ( cx , & fp ) ) ) {
2010-08-16 12:35:04 -07:00
if ( JS_IsScriptFrame ( cx , fp ) ) {
2008-10-12 11:32:34 -07:00
return ;
}
}
// In some cases cx->fp is null here so use XPConnect to tell us about inner
// frames.
if ( ( xpc = do_GetService ( nsIXPConnect : : GetCID ( ) ) ) ) {
nsAXPCNativeCallContext * cc = nsnull ;
xpc - > GetCurrentNativeCallContext ( & cc ) ;
if ( cc ) {
nsAXPCNativeCallContext * prev = cc ;
while ( NS_SUCCEEDED ( prev - > GetPreviousCallContext ( & prev ) ) & & prev ) {
PRUint16 lang ;
if ( NS_SUCCEEDED ( prev - > GetLanguage ( & lang ) ) & &
lang = = nsAXPCNativeCallContext : : LANG_JS ) {
return ;
}
}
}
}
2007-03-22 10:30:00 -07:00
if ( ! report ) {
fprintf ( gErrFile , " %s \n " , message ) ;
return ;
}
/* Conditionally ignore reported warnings. */
if ( JSREPORT_IS_WARNING ( report - > flags ) & & ! reportWarnings )
return ;
if ( report - > filename )
prefix = JS_smprintf ( " %s: " , report - > filename ) ;
if ( report - > lineno ) {
tmp = prefix ;
prefix = JS_smprintf ( " %s%u: " , tmp ? tmp : " " , report - > lineno ) ;
JS_free ( cx , tmp ) ;
}
if ( JSREPORT_IS_WARNING ( report - > flags ) ) {
tmp = prefix ;
prefix = JS_smprintf ( " %s%swarning: " ,
tmp ? tmp : " " ,
JSREPORT_IS_STRICT ( report - > flags ) ? " strict " : " " ) ;
JS_free ( cx , tmp ) ;
}
/* embedded newlines -- argh! */
while ( ( ctmp = strchr ( message , ' \n ' ) ) ! = 0 ) {
ctmp + + ;
if ( prefix ) fputs ( prefix , gErrFile ) ;
fwrite ( message , 1 , ctmp - message , gErrFile ) ;
message = ctmp ;
}
/* If there were no filename or lineno, the prefix might be empty */
if ( prefix )
fputs ( prefix , gErrFile ) ;
fputs ( message , gErrFile ) ;
if ( ! report - > linebuf ) {
fputc ( ' \n ' , gErrFile ) ;
goto out ;
}
fprintf ( gErrFile , " : \n %s%s \n %s " , prefix , report - > linebuf , prefix ) ;
n = report - > tokenptr - report - > linebuf ;
for ( i = j = 0 ; i < n ; i + + ) {
if ( report - > linebuf [ i ] = = ' \t ' ) {
for ( k = ( j + 8 ) & ~ 7 ; j < k ; j + + ) {
fputc ( ' . ' , gErrFile ) ;
}
continue ;
}
fputc ( ' . ' , gErrFile ) ;
j + + ;
}
fputs ( " ^ \n " , gErrFile ) ;
out :
if ( ! JSREPORT_IS_WARNING ( report - > flags ) )
gExitCode = EXITCODE_RUNTIME_ERROR ;
JS_free ( cx , prefix ) ;
}
2008-11-27 18:25:35 -08:00
static JSBool
2010-08-16 12:35:04 -07:00
ReadLine ( JSContext * cx , uintN argc , jsval * vp )
2008-11-27 18:25:35 -08:00
{
// While 4096 might be quite arbitrary, this is something to be fixed in
// bug 105707. It is also the same limit as in ProcessFile.
char buf [ 4096 ] ;
JSString * str ;
/* If a prompt was specified, construct the string */
if ( argc > 0 ) {
2010-08-16 12:35:04 -07:00
str = JS_ValueToString ( cx , JS_ARGV ( cx , vp ) [ 0 ] ) ;
2008-11-27 18:25:35 -08:00
if ( ! str )
2011-11-26 02:05:59 -08:00
return false ;
2008-11-27 18:25:35 -08:00
} else {
str = JSVAL_TO_STRING ( JS_GetEmptyStringValue ( cx ) ) ;
}
/* Get a line from the infile */
2010-11-11 12:40:29 -08:00
JSAutoByteString strBytes ( cx , str ) ;
if ( ! strBytes | | ! GetLine ( cx , buf , gInFile , strBytes . ptr ( ) ) )
2011-11-26 02:05:59 -08:00
return false ;
2008-11-27 18:25:35 -08:00
/* Strip newline character added by GetLine() */
unsigned int buflen = strlen ( buf ) ;
if ( buflen = = 0 ) {
if ( feof ( gInFile ) ) {
2010-08-16 12:35:04 -07:00
JS_SET_RVAL ( cx , vp , JSVAL_NULL ) ;
2011-11-26 02:05:59 -08:00
return true ;
2008-11-27 18:25:35 -08:00
}
} else if ( buf [ buflen - 1 ] = = ' \n ' ) {
- - buflen ;
}
/* Turn buf into a JSString */
str = JS_NewStringCopyN ( cx , buf , buflen ) ;
if ( ! str )
2011-11-26 02:05:59 -08:00
return false ;
2008-11-27 18:25:35 -08:00
2010-08-16 12:35:04 -07:00
JS_SET_RVAL ( cx , vp , STRING_TO_JSVAL ( str ) ) ;
2011-11-26 02:05:59 -08:00
return true ;
2008-11-27 18:25:35 -08:00
}
2008-09-06 15:21:43 -07:00
static JSBool
2010-08-16 12:35:04 -07:00
Print ( JSContext * cx , uintN argc , jsval * vp )
2007-03-22 10:30:00 -07:00
{
uintN i , n ;
JSString * str ;
2010-08-16 12:35:04 -07:00
jsval * argv = JS_ARGV ( cx , vp ) ;
2007-03-22 10:30:00 -07:00
for ( i = n = 0 ; i < argc ; i + + ) {
str = JS_ValueToString ( cx , argv [ i ] ) ;
if ( ! str )
2011-11-26 02:05:59 -08:00
return false ;
2010-11-11 12:40:29 -08:00
JSAutoByteString strBytes ( cx , str ) ;
if ( ! strBytes )
2011-11-26 02:05:59 -08:00
return false ;
2010-11-11 12:40:29 -08:00
fprintf ( gOutFile , " %s%s " , i ? " " : " " , strBytes . ptr ( ) ) ;
2009-06-28 16:01:42 -07:00
fflush ( gOutFile ) ;
2007-03-22 10:30:00 -07:00
}
n + + ;
if ( n )
fputc ( ' \n ' , gOutFile ) ;
2010-08-16 12:35:04 -07:00
JS_SET_RVAL ( cx , vp , JSVAL_VOID ) ;
2011-11-26 02:05:59 -08:00
return true ;
2007-03-22 10:30:00 -07:00
}
2008-09-06 15:21:43 -07:00
static JSBool
2010-08-16 12:35:04 -07:00
Dump ( JSContext * cx , uintN argc , jsval * vp )
2007-03-22 10:30:00 -07:00
{
2010-08-16 12:35:04 -07:00
JS_SET_RVAL ( cx , vp , JSVAL_VOID ) ;
2007-03-22 10:30:00 -07:00
JSString * str ;
if ( ! argc )
2011-11-26 02:05:59 -08:00
return true ;
2009-06-28 16:01:42 -07:00
2010-08-16 12:35:04 -07:00
str = JS_ValueToString ( cx , JS_ARGV ( cx , vp ) [ 0 ] ) ;
2007-03-22 10:30:00 -07:00
if ( ! str )
2011-11-26 02:05:59 -08:00
return false ;
2007-03-22 10:30:00 -07:00
2010-11-23 05:40:55 -08:00
JSAutoByteString bytes ( cx , str ) ;
if ( ! bytes )
2011-11-26 02:05:59 -08:00
return false ;
2011-10-14 10:52:47 -07:00
2011-11-09 16:27:08 -08:00
# ifdef ANDROID
__android_log_print ( ANDROID_LOG_INFO , " Gecko " , bytes . ptr ( ) ) ;
# endif
2010-11-23 05:40:55 -08:00
fputs ( bytes . ptr ( ) , gOutFile ) ;
2009-06-28 16:01:42 -07:00
fflush ( gOutFile ) ;
2011-11-26 02:05:59 -08:00
return true ;
2007-03-22 10:30:00 -07:00
}
2008-09-06 15:21:43 -07:00
static JSBool
2010-08-16 12:35:04 -07:00
Load ( JSContext * cx , uintN argc , jsval * vp )
2007-03-22 10:30:00 -07:00
{
2010-08-16 12:35:04 -07:00
JSObject * obj = JS_THIS_OBJECT ( cx , vp ) ;
if ( ! obj )
2011-02-03 05:06:21 -08:00
return false ;
2010-08-16 12:35:04 -07:00
jsval * argv = JS_ARGV ( cx , vp ) ;
2011-02-03 05:06:21 -08:00
for ( uintN i = 0 ; i < argc ; i + + ) {
JSString * str = JS_ValueToString ( cx , argv [ i ] ) ;
2007-03-22 10:30:00 -07:00
if ( ! str )
2011-02-03 05:06:21 -08:00
return false ;
2007-03-22 10:30:00 -07:00
argv [ i ] = STRING_TO_JSVAL ( str ) ;
2010-11-11 12:40:29 -08:00
JSAutoByteString filename ( cx , str ) ;
if ( ! filename )
2011-02-03 05:06:21 -08:00
return false ;
FILE * file = fopen ( filename . ptr ( ) , " r " ) ;
2009-03-08 01:38:55 -08:00
if ( ! file ) {
2010-11-11 12:40:29 -08:00
JS_ReportError ( cx , " cannot open file '%s' for reading " ,
filename . ptr ( ) ) ;
2011-02-03 05:06:21 -08:00
return false ;
2009-03-08 01:38:55 -08:00
}
2011-12-16 11:08:59 -08:00
JSScript * script = JS_CompileUTF8FileHandleForPrincipals ( cx , obj , filename . ptr ( ) ,
file , gJSPrincipals ) ;
2009-03-08 01:38:55 -08:00
fclose ( file ) ;
2011-09-01 23:46:00 -07:00
if ( ! script )
2011-02-03 05:06:21 -08:00
return false ;
2009-03-08 01:38:55 -08:00
2011-02-03 05:06:21 -08:00
jsval result ;
2011-09-01 23:46:00 -07:00
if ( ! compileOnly & & ! JS_ExecuteScript ( cx , obj , script , & result ) )
2011-02-03 05:06:21 -08:00
return false ;
2007-03-22 10:30:00 -07:00
}
2010-08-16 12:35:04 -07:00
JS_SET_RVAL ( cx , vp , JSVAL_VOID ) ;
2011-02-03 05:06:21 -08:00
return true ;
2007-03-22 10:30:00 -07:00
}
2008-09-06 15:21:43 -07:00
static JSBool
2010-08-16 12:35:04 -07:00
Version ( JSContext * cx , uintN argc , jsval * vp )
2007-03-22 10:30:00 -07:00
{
2010-08-16 12:35:04 -07:00
if ( argc > 0 & & JSVAL_IS_INT ( JS_ARGV ( cx , vp ) [ 0 ] ) )
JS_SET_RVAL ( cx , vp , INT_TO_JSVAL ( JS_SetVersion ( cx , JSVersion ( JSVAL_TO_INT ( JS_ARGV ( cx , vp ) [ 0 ] ) ) ) ) ) ;
2007-03-22 10:30:00 -07:00
else
2010-08-16 12:35:04 -07:00
JS_SET_RVAL ( cx , vp , INT_TO_JSVAL ( JS_GetVersion ( cx ) ) ) ;
2011-11-26 02:05:59 -08:00
return true ;
2007-03-22 10:30:00 -07:00
}
2008-09-06 15:21:43 -07:00
static JSBool
2010-08-16 12:35:04 -07:00
BuildDate ( JSContext * cx , uintN argc , jsval * vp )
2007-03-22 10:30:00 -07:00
{
fprintf ( gOutFile , " built on %s at %s \n " , __DATE__ , __TIME__ ) ;
2010-08-16 12:35:04 -07:00
JS_SET_RVAL ( cx , vp , JSVAL_VOID ) ;
2011-11-26 02:05:59 -08:00
return true ;
2007-03-22 10:30:00 -07:00
}
2008-09-06 15:21:43 -07:00
static JSBool
2010-08-16 12:35:04 -07:00
Quit ( JSContext * cx , uintN argc , jsval * vp )
2007-03-22 10:30:00 -07:00
{
gExitCode = 0 ;
2010-08-16 12:35:04 -07:00
JS_ConvertArguments ( cx , argc , JS_ARGV ( cx , vp ) , " / i " , & gExitCode ) ;
2007-03-22 10:30:00 -07:00
2011-11-26 02:05:59 -08:00
gQuitting = true ;
2007-03-22 10:30:00 -07:00
// exit(0);
2011-11-26 02:05:59 -08:00
return false ;
2007-03-22 10:30:00 -07:00
}
2008-09-06 15:21:43 -07:00
static JSBool
2010-08-16 12:35:04 -07:00
DumpXPC ( JSContext * cx , uintN argc , jsval * vp )
2007-03-22 10:30:00 -07:00
{
Bug 708735 - Use <stdint.h> types in JSAPI and throughout SpiderMonkey. Continue to provide the {u,}int{8,16,32,64} and JS{Uint,Int}{8,16,32,64} integer types through a single header, however, for a simpler backout strategy -- and also to ease the transition for embedders. r=timeless on switching the jsd API to use the <stdint.h> types, r=luke, r=dmandelin
2011-12-08 19:54:10 -08:00
int32_t depth = 2 ;
2007-03-22 10:30:00 -07:00
if ( argc > 0 ) {
2010-08-16 12:35:04 -07:00
if ( ! JS_ValueToInt32 ( cx , JS_ARGV ( cx , vp ) [ 0 ] , & depth ) )
2011-11-26 02:05:59 -08:00
return false ;
2007-03-22 10:30:00 -07:00
}
nsCOMPtr < nsIXPConnect > xpc = do_GetService ( nsIXPConnect : : GetCID ( ) ) ;
2011-10-14 10:52:48 -07:00
if ( xpc )
Bug 708735 - Use <stdint.h> types in JSAPI and throughout SpiderMonkey. Continue to provide the {u,}int{8,16,32,64} and JS{Uint,Int}{8,16,32,64} integer types through a single header, however, for a simpler backout strategy -- and also to ease the transition for embedders. r=timeless on switching the jsd API to use the <stdint.h> types, r=luke, r=dmandelin
2011-12-08 19:54:10 -08:00
xpc - > DebugDump ( int16_t ( depth ) ) ;
2010-08-16 12:35:04 -07:00
JS_SET_RVAL ( cx , vp , JSVAL_VOID ) ;
2011-11-26 02:05:59 -08:00
return true ;
2007-03-22 10:30:00 -07:00
}
2008-09-06 15:21:43 -07:00
static JSBool
2010-08-16 12:35:04 -07:00
GC ( JSContext * cx , uintN argc , jsval * vp )
2007-03-22 10:30:00 -07:00
{
JS_GC ( cx ) ;
# ifdef JS_GCMETER
2012-01-15 00:13:07 -08:00
js_DumpGCStats ( JS_GetRuntime ( cx ) , stdout ) ;
2007-03-22 10:30:00 -07:00
# endif
2010-08-16 12:35:04 -07:00
JS_SET_RVAL ( cx , vp , JSVAL_VOID ) ;
2011-11-26 02:05:59 -08:00
return true ;
2007-03-22 10:30:00 -07:00
}
2010-03-17 17:05:22 -07:00
# ifdef JS_GC_ZEAL
static JSBool
2010-08-16 12:35:04 -07:00
GCZeal ( JSContext * cx , uintN argc , jsval * vp )
2010-03-17 17:05:22 -07:00
{
Bug 708735 - Use <stdint.h> types in JSAPI and throughout SpiderMonkey. Continue to provide the {u,}int{8,16,32,64} and JS{Uint,Int}{8,16,32,64} integer types through a single header, however, for a simpler backout strategy -- and also to ease the transition for embedders. r=timeless on switching the jsd API to use the <stdint.h> types, r=luke, r=dmandelin
2011-12-08 19:54:10 -08:00
uint32_t zeal ;
2010-08-16 12:35:04 -07:00
if ( ! JS_ValueToECMAUint32 ( cx , argc ? JS_ARGV ( cx , vp ) [ 0 ] : JSVAL_VOID , & zeal ) )
2011-11-26 02:05:59 -08:00
return false ;
2010-03-17 17:05:22 -07:00
Bug 708735 - Use <stdint.h> types in JSAPI and throughout SpiderMonkey. Continue to provide the {u,}int{8,16,32,64} and JS{Uint,Int}{8,16,32,64} integer types through a single header, however, for a simpler backout strategy -- and also to ease the transition for embedders. r=timeless on switching the jsd API to use the <stdint.h> types, r=luke, r=dmandelin
2011-12-08 19:54:10 -08:00
JS_SetGCZeal ( cx , uint8_t ( zeal ) , JS_DEFAULT_ZEAL_FREQ , false ) ;
2010-08-16 12:35:04 -07:00
JS_SET_RVAL ( cx , vp , JSVAL_VOID ) ;
2011-11-26 02:05:59 -08:00
return true ;
2010-03-17 17:05:22 -07:00
}
# endif
2007-04-25 06:43:18 -07:00
# ifdef DEBUG
static JSBool
2010-08-16 12:35:04 -07:00
DumpHeap ( JSContext * cx , uintN argc , jsval * vp )
2007-04-25 06:43:18 -07:00
{
void * startThing = NULL ;
2011-09-01 11:43:46 -07:00
JSGCTraceKind startTraceKind = JSTRACE_OBJECT ;
2007-04-25 06:43:18 -07:00
void * thingToFind = NULL ;
size_t maxDepth = ( size_t ) - 1 ;
void * thingToIgnore = NULL ;
FILE * dumpFile ;
JSBool ok ;
2010-08-16 12:35:04 -07:00
jsval * argv = JS_ARGV ( cx , vp ) ;
JS_SET_RVAL ( cx , vp , JSVAL_VOID ) ;
vp = argv + 0 ;
2010-11-11 12:40:29 -08:00
JSAutoByteString fileName ;
2010-08-16 12:35:04 -07:00
if ( argc > 0 & & * vp ! = JSVAL_NULL & & * vp ! = JSVAL_VOID ) {
2007-04-25 06:43:18 -07:00
JSString * str ;
str = JS_ValueToString ( cx , * vp ) ;
if ( ! str )
2011-11-26 02:05:59 -08:00
return false ;
2007-04-25 06:43:18 -07:00
* vp = STRING_TO_JSVAL ( str ) ;
2010-11-11 12:40:29 -08:00
if ( ! fileName . encode ( cx , str ) )
2011-11-26 02:05:59 -08:00
return false ;
2007-04-25 06:43:18 -07:00
}
2010-08-16 12:35:04 -07:00
vp = argv + 1 ;
if ( argc > 1 & & * vp ! = JSVAL_NULL & & * vp ! = JSVAL_VOID ) {
2007-04-25 06:43:18 -07:00
if ( ! JSVAL_IS_TRACEABLE ( * vp ) )
goto not_traceable_arg ;
startThing = JSVAL_TO_TRACEABLE ( * vp ) ;
startTraceKind = JSVAL_TRACE_KIND ( * vp ) ;
}
2010-08-16 12:35:04 -07:00
vp = argv + 2 ;
if ( argc > 2 & & * vp ! = JSVAL_NULL & & * vp ! = JSVAL_VOID ) {
2007-04-25 06:43:18 -07:00
if ( ! JSVAL_IS_TRACEABLE ( * vp ) )
goto not_traceable_arg ;
thingToFind = JSVAL_TO_TRACEABLE ( * vp ) ;
}
2010-08-16 12:35:04 -07:00
vp = argv + 3 ;
if ( argc > 3 & & * vp ! = JSVAL_NULL & & * vp ! = JSVAL_VOID ) {
Bug 708735 - Use <stdint.h> types in JSAPI and throughout SpiderMonkey. Continue to provide the {u,}int{8,16,32,64} and JS{Uint,Int}{8,16,32,64} integer types through a single header, however, for a simpler backout strategy -- and also to ease the transition for embedders. r=timeless on switching the jsd API to use the <stdint.h> types, r=luke, r=dmandelin
2011-12-08 19:54:10 -08:00
uint32_t depth ;
2007-04-25 06:43:18 -07:00
if ( ! JS_ValueToECMAUint32 ( cx , * vp , & depth ) )
2011-11-26 02:05:59 -08:00
return false ;
2007-04-25 06:43:18 -07:00
maxDepth = depth ;
}
2010-08-16 12:35:04 -07:00
vp = argv + 4 ;
if ( argc > 4 & & * vp ! = JSVAL_NULL & & * vp ! = JSVAL_VOID ) {
2007-04-25 06:43:18 -07:00
if ( ! JSVAL_IS_TRACEABLE ( * vp ) )
goto not_traceable_arg ;
thingToIgnore = JSVAL_TO_TRACEABLE ( * vp ) ;
}
if ( ! fileName ) {
dumpFile = gOutFile ;
} else {
2010-11-11 12:40:29 -08:00
dumpFile = fopen ( fileName . ptr ( ) , " w " ) ;
2007-04-25 06:43:18 -07:00
if ( ! dumpFile ) {
fprintf ( gErrFile , " dumpHeap: can't open %s: %s \n " ,
2010-11-11 12:40:29 -08:00
fileName . ptr ( ) , strerror ( errno ) ) ;
2011-11-26 02:05:59 -08:00
return false ;
2007-04-25 06:43:18 -07:00
}
}
2007-04-29 14:49:00 -07:00
ok = JS_DumpHeap ( cx , dumpFile , startThing , startTraceKind , thingToFind ,
maxDepth , thingToIgnore ) ;
2007-04-25 06:43:18 -07:00
if ( dumpFile ! = gOutFile )
fclose ( dumpFile ) ;
return ok ;
not_traceable_arg :
fprintf ( gErrFile ,
" dumpHeap: argument %u is not null or a heap-allocated thing \n " ,
( unsigned ) ( vp - argv ) ) ;
2011-11-26 02:05:59 -08:00
return false ;
2007-04-25 06:43:18 -07:00
}
# endif /* DEBUG */
2008-09-06 15:21:43 -07:00
static JSBool
2010-08-16 12:35:04 -07:00
Clear ( JSContext * cx , uintN argc , jsval * vp )
2007-03-22 10:30:00 -07:00
{
2010-08-16 12:35:04 -07:00
if ( argc > 0 & & ! JSVAL_IS_PRIMITIVE ( JS_ARGV ( cx , vp ) [ 0 ] ) ) {
JS_ClearScope ( cx , JSVAL_TO_OBJECT ( JS_ARGV ( cx , vp ) [ 0 ] ) ) ;
2007-03-22 10:30:00 -07:00
} else {
JS_ReportError ( cx , " 'clear' requires an object " ) ;
2011-11-26 02:05:59 -08:00
return false ;
2009-06-28 16:01:42 -07:00
}
2010-08-16 12:35:04 -07:00
JS_SET_RVAL ( cx , vp , JSVAL_VOID ) ;
2011-11-26 02:05:59 -08:00
return true ;
2007-03-22 10:30:00 -07:00
}
2009-08-28 16:16:19 -07:00
static JSBool
SendCommand ( JSContext * cx ,
uintN argc ,
2010-08-16 12:35:04 -07:00
jsval * vp )
2009-08-28 16:16:19 -07:00
{
if ( argc = = 0 ) {
JS_ReportError ( cx , " Function takes at least one argument! " ) ;
2011-11-26 02:05:59 -08:00
return false ;
2009-08-28 16:16:19 -07:00
}
2010-08-16 12:35:04 -07:00
jsval * argv = JS_ARGV ( cx , vp ) ;
2009-08-28 16:16:19 -07:00
JSString * str = JS_ValueToString ( cx , argv [ 0 ] ) ;
if ( ! str ) {
JS_ReportError ( cx , " Could not convert argument 1 to string! " ) ;
2011-11-26 02:05:59 -08:00
return false ;
2009-08-28 16:16:19 -07:00
}
if ( argc > 1 & & JS_TypeOfValue ( cx , argv [ 1 ] ) ! = JSTYPE_FUNCTION ) {
JS_ReportError ( cx , " Could not convert argument 2 to function! " ) ;
2011-11-26 02:05:59 -08:00
return false ;
2009-08-28 16:16:19 -07:00
}
if ( ! XRE_SendTestShellCommand ( cx , str , argc > 1 ? & argv [ 1 ] : nsnull ) ) {
JS_ReportError ( cx , " Couldn't send command! " ) ;
2011-11-26 02:05:59 -08:00
return false ;
2009-08-28 16:16:19 -07:00
}
2010-08-16 12:35:04 -07:00
JS_SET_RVAL ( cx , vp , JSVAL_VOID ) ;
2011-11-26 02:05:59 -08:00
return true ;
2009-08-28 16:16:19 -07:00
}
2009-11-06 12:43:39 -08:00
static JSBool
GetChildGlobalObject ( JSContext * cx ,
uintN ,
2010-08-16 12:35:04 -07:00
jsval * vp )
2009-11-06 12:43:39 -08:00
{
JSObject * global ;
if ( XRE_GetChildGlobalObject ( cx , & global ) ) {
2010-08-16 12:35:04 -07:00
JS_SET_RVAL ( cx , vp , OBJECT_TO_JSVAL ( global ) ) ;
2011-11-26 02:05:59 -08:00
return true ;
2009-11-06 12:43:39 -08:00
}
2011-11-26 02:05:59 -08:00
return false ;
2009-11-06 12:43:39 -08:00
}
2009-09-28 11:34:57 -07:00
/*
* JSContext option name to flag map . The option names are in alphabetical
* order for better reporting .
*/
2011-10-10 23:00:28 -07:00
static const struct JSOption {
2009-09-28 11:34:57 -07:00
const char * name ;
2012-01-02 10:05:19 -08:00
uint32_t flag ;
2009-09-28 11:34:57 -07:00
} js_options [ ] = {
{ " atline " , JSOPTION_ATLINE } ,
{ " relimit " , JSOPTION_RELIMIT } ,
{ " strict " , JSOPTION_STRICT } ,
{ " werror " , JSOPTION_WERROR } ,
{ " xml " , JSOPTION_XML } ,
} ;
2012-01-02 10:05:19 -08:00
static uint32_t
2009-09-28 11:34:57 -07:00
MapContextOptionNameToFlag ( JSContext * cx , const char * name )
{
2011-10-10 23:00:28 -07:00
for ( size_t i = 0 ; i < ArrayLength ( js_options ) ; + + i ) {
2009-09-28 11:34:57 -07:00
if ( strcmp ( name , js_options [ i ] . name ) = = 0 )
return js_options [ i ] . flag ;
}
char * msg = JS_sprintf_append ( NULL ,
" unknown option name '%s'. "
" The valid names are " , name ) ;
2011-10-10 23:00:28 -07:00
for ( size_t i = 0 ; i < ArrayLength ( js_options ) ; + + i ) {
2009-09-28 11:34:57 -07:00
if ( ! msg )
break ;
msg = JS_sprintf_append ( msg , " %s%s " , js_options [ i ] . name ,
2011-10-10 23:00:28 -07:00
( i + 2 < ArrayLength ( js_options )
2009-09-28 11:34:57 -07:00
? " , "
2011-10-10 23:00:28 -07:00
: i + 2 = = ArrayLength ( js_options )
2009-09-28 11:34:57 -07:00
? " and "
: " . " ) ) ;
}
if ( ! msg ) {
JS_ReportOutOfMemory ( cx ) ;
} else {
JS_ReportError ( cx , msg ) ;
free ( msg ) ;
}
return 0 ;
}
static JSBool
2010-08-16 12:35:04 -07:00
Options ( JSContext * cx , uintN argc , jsval * vp )
2009-09-28 11:34:57 -07:00
{
Bug 708735 - Use <stdint.h> types in JSAPI and throughout SpiderMonkey. Continue to provide the {u,}int{8,16,32,64} and JS{Uint,Int}{8,16,32,64} integer types through a single header, however, for a simpler backout strategy -- and also to ease the transition for embedders. r=timeless on switching the jsd API to use the <stdint.h> types, r=luke, r=dmandelin
2011-12-08 19:54:10 -08:00
uint32_t optset , flag ;
2009-09-28 11:34:57 -07:00
JSString * str ;
char * names ;
JSBool found ;
optset = 0 ;
2010-08-16 12:35:04 -07:00
jsval * argv = JS_ARGV ( cx , vp ) ;
2009-09-28 11:34:57 -07:00
for ( uintN i = 0 ; i < argc ; i + + ) {
str = JS_ValueToString ( cx , argv [ i ] ) ;
if ( ! str )
2011-11-26 02:05:59 -08:00
return false ;
2009-09-28 11:34:57 -07:00
argv [ i ] = STRING_TO_JSVAL ( str ) ;
2010-11-11 12:40:29 -08:00
JSAutoByteString opt ( cx , str ) ;
2009-09-28 11:34:57 -07:00
if ( ! opt )
2011-11-26 02:05:59 -08:00
return false ;
2010-11-11 12:40:29 -08:00
flag = MapContextOptionNameToFlag ( cx , opt . ptr ( ) ) ;
2009-09-28 11:34:57 -07:00
if ( ! flag )
2011-11-26 02:05:59 -08:00
return false ;
2009-09-28 11:34:57 -07:00
optset | = flag ;
}
optset = JS_ToggleOptions ( cx , optset ) ;
names = NULL ;
2011-11-26 02:05:59 -08:00
found = false ;
2011-10-10 23:00:28 -07:00
for ( size_t i = 0 ; i < ArrayLength ( js_options ) ; i + + ) {
2009-09-28 11:34:57 -07:00
if ( js_options [ i ] . flag & optset ) {
2011-11-26 02:05:59 -08:00
found = true ;
2009-09-28 11:34:57 -07:00
names = JS_sprintf_append ( names , " %s%s " ,
names ? " , " : " " , js_options [ i ] . name ) ;
if ( ! names )
break ;
}
}
if ( ! found )
names = strdup ( " " ) ;
if ( ! names ) {
JS_ReportOutOfMemory ( cx ) ;
2011-11-26 02:05:59 -08:00
return false ;
2009-09-28 11:34:57 -07:00
}
2010-12-09 02:22:15 -08:00
str = JS_NewStringCopyZ ( cx , names ) ;
free ( names ) ;
if ( ! str )
2011-11-26 02:05:59 -08:00
return false ;
2010-08-16 12:35:04 -07:00
JS_SET_RVAL ( cx , vp , STRING_TO_JSVAL ( str ) ) ;
2011-11-26 02:05:59 -08:00
return true ;
2009-09-28 11:34:57 -07:00
}
2010-04-11 13:51:00 -07:00
static JSBool
Parent ( JSContext * cx , uintN argc , jsval * vp )
{
if ( argc ! = 1 ) {
JS_ReportError ( cx , " Wrong number of arguments " ) ;
2011-11-26 02:05:59 -08:00
return false ;
2010-04-11 13:51:00 -07:00
}
jsval v = JS_ARGV ( cx , vp ) [ 0 ] ;
if ( JSVAL_IS_PRIMITIVE ( v ) ) {
JS_ReportError ( cx , " Only objects have parents! " ) ;
2011-11-26 02:05:59 -08:00
return false ;
2010-04-11 13:51:00 -07:00
}
2012-02-05 12:07:23 -08:00
* vp = OBJECT_TO_JSVAL ( JS_GetParent ( JSVAL_TO_OBJECT ( v ) ) ) ;
2011-11-26 02:05:59 -08:00
return true ;
2010-04-11 13:51:00 -07:00
}
2007-03-22 10:30:00 -07:00
static JSFunctionSpec glob_functions [ ] = {
2010-08-16 12:35:04 -07:00
{ " print " , Print , 0 , 0 } ,
{ " readline " , ReadLine , 1 , 0 } ,
{ " load " , Load , 1 , 0 } ,
{ " quit " , Quit , 0 , 0 } ,
{ " version " , Version , 1 , 0 } ,
{ " build " , BuildDate , 0 , 0 } ,
{ " dumpXPC " , DumpXPC , 1 , 0 } ,
{ " dump " , Dump , 1 , 0 } ,
{ " gc " , GC , 0 , 0 } ,
2010-03-17 17:05:22 -07:00
# ifdef JS_GC_ZEAL
2010-08-16 12:35:04 -07:00
{ " gczeal " , GCZeal , 1 , 0 } ,
2010-03-17 17:05:22 -07:00
# endif
2010-08-16 12:35:04 -07:00
{ " clear " , Clear , 1 , 0 } ,
{ " options " , Options , 0 , 0 } ,
2010-04-11 13:51:00 -07:00
JS_FN ( " parent " , Parent , 1 , 0 ) ,
2007-04-25 06:43:18 -07:00
# ifdef DEBUG
2010-08-16 12:35:04 -07:00
{ " dumpHeap " , DumpHeap , 5 , 0 } ,
2008-01-16 12:42:50 -08:00
# endif
2010-08-16 12:35:04 -07:00
{ " sendCommand " , SendCommand , 1 , 0 } ,
{ " getChildGlobalObject " , GetChildGlobalObject , 0 , 0 } ,
{ nsnull , nsnull , 0 , 0 }
2007-03-22 10:30:00 -07:00
} ;
JSClass global_class = {
" global " , 0 ,
2011-02-09 11:31:40 -08:00
JS_PropertyStub , JS_PropertyStub , JS_PropertyStub , JS_StrictPropertyStub ,
2009-07-22 09:23:21 -07:00
JS_EnumerateStub , JS_ResolveStub , JS_ConvertStub , nsnull
2007-03-22 10:30:00 -07:00
} ;
static JSBool
2011-02-09 11:31:40 -08:00
env_setProperty ( JSContext * cx , JSObject * obj , jsid id , JSBool strict , jsval * vp )
2007-03-22 10:30:00 -07:00
{
/* XXX porting may be easy, but these don't seem to supply setenv by default */
Bug 627277 - Remove (broken) BeOS support. r=biesi,dwitte,gavin,joe,jorendorff,josh,khuey,mfinkle,neil,Pike,roc,shaver,smontagu,taras
2011-02-19 11:10:24 -08:00
# if !defined XP_OS2 && !defined SOLARIS
2007-03-22 10:30:00 -07:00
JSString * idstr , * valstr ;
int rv ;
2010-07-14 23:19:36 -07:00
jsval idval ;
if ( ! JS_IdToValue ( cx , id , & idval ) )
2011-11-26 02:05:59 -08:00
return false ;
2011-10-14 10:52:47 -07:00
2010-07-14 23:19:36 -07:00
idstr = JS_ValueToString ( cx , idval ) ;
2007-03-22 10:30:00 -07:00
valstr = JS_ValueToString ( cx , * vp ) ;
if ( ! idstr | | ! valstr )
2011-11-26 02:05:59 -08:00
return false ;
2010-11-11 12:40:29 -08:00
JSAutoByteString name ( cx , idstr ) ;
if ( ! name )
2011-11-26 02:05:59 -08:00
return false ;
2010-11-11 12:40:29 -08:00
JSAutoByteString value ( cx , valstr ) ;
if ( ! value )
2011-11-26 02:05:59 -08:00
return false ;
2011-09-02 07:41:45 -07:00
# if defined XP_WIN || defined HPUX || defined OSF1 || defined SCO
2007-03-22 10:30:00 -07:00
{
2010-11-11 12:40:29 -08:00
char * waste = JS_smprintf ( " %s=%s " , name . ptr ( ) , value . ptr ( ) ) ;
2007-03-22 10:30:00 -07:00
if ( ! waste ) {
JS_ReportOutOfMemory ( cx ) ;
2011-11-26 02:05:59 -08:00
return false ;
2007-03-22 10:30:00 -07:00
}
rv = putenv ( waste ) ;
# ifdef XP_WIN
/*
* HPUX9 at least still has the bad old non - copying putenv .
*
* Per mail from < s . shanmuganathan @ digital . com > , OSF1 also has a putenv
* that will crash if you pass it an auto char array ( so it must place
* its argument directly in the char * environ [ ] array ) .
*/
free ( waste ) ;
# endif
}
# else
2010-11-11 12:40:29 -08:00
rv = setenv ( name . ptr ( ) , value . ptr ( ) , 1 ) ;
2007-03-22 10:30:00 -07:00
# endif
if ( rv < 0 ) {
2010-11-11 12:40:29 -08:00
JS_ReportError ( cx , " can't set envariable %s to %s " , name . ptr ( ) , value . ptr ( ) ) ;
2011-11-26 02:05:59 -08:00
return false ;
2007-03-22 10:30:00 -07:00
}
* vp = STRING_TO_JSVAL ( valstr ) ;
Bug 627277 - Remove (broken) BeOS support. r=biesi,dwitte,gavin,joe,jorendorff,josh,khuey,mfinkle,neil,Pike,roc,shaver,smontagu,taras
2011-02-19 11:10:24 -08:00
# endif /* !defined XP_OS2 && !defined SOLARIS */
2011-11-26 02:05:59 -08:00
return true ;
2007-03-22 10:30:00 -07:00
}
static JSBool
env_enumerate ( JSContext * cx , JSObject * obj )
{
static JSBool reflected ;
char * * evp , * name , * value ;
JSString * valstr ;
JSBool ok ;
if ( reflected )
2011-11-26 02:05:59 -08:00
return true ;
2007-03-22 10:30:00 -07:00
2012-02-05 12:07:23 -08:00
for ( evp = ( char * * ) JS_GetPrivate ( obj ) ; ( name = * evp ) ! = NULL ; evp + + ) {
2007-03-22 10:30:00 -07:00
value = strchr ( name , ' = ' ) ;
if ( ! value )
continue ;
* value + + = ' \0 ' ;
valstr = JS_NewStringCopyZ ( cx , value ) ;
if ( ! valstr ) {
2011-11-26 02:05:59 -08:00
ok = false ;
2007-03-22 10:30:00 -07:00
} else {
ok = JS_DefineProperty ( cx , obj , name , STRING_TO_JSVAL ( valstr ) ,
NULL , NULL , JSPROP_ENUMERATE ) ;
}
value [ - 1 ] = ' = ' ;
if ( ! ok )
2011-11-26 02:05:59 -08:00
return false ;
2007-03-22 10:30:00 -07:00
}
2011-11-26 02:05:59 -08:00
reflected = true ;
return true ;
2007-03-22 10:30:00 -07:00
}
static JSBool
2010-07-14 23:19:36 -07:00
env_resolve ( JSContext * cx , JSObject * obj , jsid id , uintN flags ,
2007-03-22 10:30:00 -07:00
JSObject * * objp )
{
JSString * idstr , * valstr ;
if ( flags & JSRESOLVE_ASSIGNING )
2011-11-26 02:05:59 -08:00
return true ;
2007-03-22 10:30:00 -07:00
2010-07-14 23:19:36 -07:00
jsval idval ;
if ( ! JS_IdToValue ( cx , id , & idval ) )
2011-11-26 02:05:59 -08:00
return false ;
2010-07-14 23:19:36 -07:00
idstr = JS_ValueToString ( cx , idval ) ;
2007-03-22 10:30:00 -07:00
if ( ! idstr )
2011-11-26 02:05:59 -08:00
return false ;
2010-11-11 12:40:29 -08:00
JSAutoByteString name ( cx , idstr ) ;
if ( ! name )
2011-11-26 02:05:59 -08:00
return false ;
2010-11-11 12:40:29 -08:00
const char * value = getenv ( name . ptr ( ) ) ;
2007-03-22 10:30:00 -07:00
if ( value ) {
valstr = JS_NewStringCopyZ ( cx , value ) ;
if ( ! valstr )
2011-11-26 02:05:59 -08:00
return false ;
2010-11-11 12:40:29 -08:00
if ( ! JS_DefinePropertyById ( cx , obj , id , STRING_TO_JSVAL ( valstr ) ,
NULL , NULL , JSPROP_ENUMERATE ) ) {
2011-11-26 02:05:59 -08:00
return false ;
2007-03-22 10:30:00 -07:00
}
* objp = obj ;
}
2011-11-26 02:05:59 -08:00
return true ;
2007-03-22 10:30:00 -07:00
}
static JSClass env_class = {
" environment " , JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE ,
JS_PropertyStub , JS_PropertyStub ,
JS_PropertyStub , env_setProperty ,
env_enumerate , ( JSResolveOp ) env_resolve ,
2009-07-22 09:23:21 -07:00
JS_ConvertStub , nsnull
2007-03-22 10:30:00 -07:00
} ;
/***************************************************************************/
typedef enum JSShellErrNum {
# define MSG_DEF(name, number, count, exception, format) \
name = number ,
# include "jsshell.msg"
# undef MSG_DEF
JSShellErr_Limit
} JSShellErrNum ;
2011-12-28 00:13:37 -08:00
JSErrorFormatString jsShell_ErrorFormatString [ JSShellErr_Limit ] = {
2007-03-22 10:30:00 -07:00
# define MSG_DEF(name, number, count, exception, format) \
{ format , count } ,
# include "jsshell.msg"
# undef MSG_DEF
} ;
2008-09-06 15:21:43 -07:00
static const JSErrorFormatString *
2007-03-22 10:30:00 -07:00
my_GetErrorMessage ( void * userRef , const char * locale , const uintN errorNumber )
{
2011-12-28 00:13:37 -08:00
if ( errorNumber = = 0 | | errorNumber > = JSShellErr_Limit )
return NULL ;
return & jsShell_ErrorFormatString [ errorNumber ] ;
2007-03-22 10:30:00 -07:00
}
static void
ProcessFile ( JSContext * cx , JSObject * obj , const char * filename , FILE * file ,
JSBool forceTTY )
{
2011-09-01 23:46:00 -07:00
JSScript * script ;
2007-03-22 10:30:00 -07:00
jsval result ;
int lineno , startline ;
JSBool ok , hitEOF ;
char * bufp , buffer [ 4096 ] ;
JSString * str ;
if ( forceTTY ) {
file = stdin ;
2011-10-14 10:52:48 -07:00
} else
2009-01-16 14:10:48 -08:00
# ifdef HAVE_ISATTY
2009-02-16 07:27:13 -08:00
if ( ! isatty ( fileno ( file ) ) )
# endif
{
2007-03-22 10:30:00 -07:00
/*
* It ' s not interactive - just execute it .
*
* Support the UNIX # ! shell hack ; gobble the first line if it starts
* with ' # ' . TODO - this isn ' t quite compatible with sharp variables ,
* as a legal js program ( using sharp variables ) might start with ' # ' .
* But that would require multi - character lookahead .
*/
int ch = fgetc ( file ) ;
if ( ch = = ' # ' ) {
2011-10-14 10:52:48 -07:00
while ( ( ch = fgetc ( file ) ) ! = EOF ) {
if ( ch = = ' \n ' | | ch = = ' \r ' )
2007-03-22 10:30:00 -07:00
break ;
}
}
ungetc ( ch , file ) ;
DoBeginRequest ( cx ) ;
2011-12-16 11:08:59 -08:00
script = JS_CompileUTF8FileHandleForPrincipals ( cx , obj , filename , file ,
gJSPrincipals ) ;
2007-03-22 10:30:00 -07:00
2011-09-01 23:46:00 -07:00
if ( script & & ! compileOnly )
( void ) JS_ExecuteScript ( cx , obj , script , & result ) ;
2007-03-22 10:30:00 -07:00
DoEndRequest ( cx ) ;
return ;
}
/* It's an interactive filehandle; drop into read-eval-print loop. */
lineno = 1 ;
2011-11-26 02:05:59 -08:00
hitEOF = false ;
2007-03-22 10:30:00 -07:00
do {
bufp = buffer ;
* bufp = ' \0 ' ;
/*
* Accumulate lines until we get a ' compilable unit ' - one that either
* generates an error ( before running out of source ) or that compiles
* cleanly . This should be whenever we get a complete statement that
* coincides with the end of a line .
*/
startline = lineno ;
do {
if ( ! GetLine ( cx , bufp , file , startline = = lineno ? " js> " : " " ) ) {
2011-11-26 02:05:59 -08:00
hitEOF = true ;
2007-03-22 10:30:00 -07:00
break ;
}
bufp + = strlen ( bufp ) ;
lineno + + ;
2011-11-26 02:05:59 -08:00
} while ( ! JS_BufferIsCompilableUnit ( cx , false , obj , buffer , strlen ( buffer ) ) ) ;
2009-06-28 16:01:42 -07:00
2007-03-22 10:30:00 -07:00
DoBeginRequest ( cx ) ;
/* Clear any pending exception from previous failed compiles. */
JS_ClearPendingException ( cx ) ;
2011-09-01 23:46:00 -07:00
script = JS_CompileScriptForPrincipals ( cx , obj , gJSPrincipals , buffer ,
strlen ( buffer ) , " typein " , startline ) ;
if ( script ) {
2007-03-22 10:30:00 -07:00
JSErrorReporter older ;
if ( ! compileOnly ) {
2011-09-01 23:46:00 -07:00
ok = JS_ExecuteScript ( cx , obj , script , & result ) ;
2007-03-22 10:30:00 -07:00
if ( ok & & result ! = JSVAL_VOID ) {
/* Suppress error reports from JS_ValueToString(). */
older = JS_SetErrorReporter ( cx , NULL ) ;
str = JS_ValueToString ( cx , result ) ;
JS_SetErrorReporter ( cx , older ) ;
2010-11-11 12:40:29 -08:00
JSAutoByteString bytes ;
if ( str & & bytes . encode ( cx , str ) )
fprintf ( gOutFile , " %s \n " , bytes . ptr ( ) ) ;
2007-03-22 10:30:00 -07:00
else
2011-11-26 02:05:59 -08:00
ok = false ;
2007-03-22 10:30:00 -07:00
}
}
}
DoEndRequest ( cx ) ;
} while ( ! hitEOF & & ! gQuitting ) ;
fprintf ( gOutFile , " \n " ) ;
}
static void
Process ( JSContext * cx , JSObject * obj , const char * filename , JSBool forceTTY )
{
FILE * file ;
if ( forceTTY | | ! filename | | strcmp ( filename , " - " ) = = 0 ) {
file = stdin ;
} else {
file = fopen ( filename , " r " ) ;
if ( ! file ) {
JS_ReportErrorNumber ( cx , my_GetErrorMessage , NULL ,
JSSMSG_CANT_OPEN ,
filename , strerror ( errno ) ) ;
gExitCode = EXITCODE_FILE_NOT_FOUND ;
return ;
}
}
ProcessFile ( cx , obj , filename , file , forceTTY ) ;
2009-02-15 08:23:50 -08:00
if ( file ! = stdin )
fclose ( file ) ;
2007-03-22 10:30:00 -07:00
}
static int
usage ( void )
{
fprintf ( gErrFile , " %s \n " , JS_GetImplementationVersion ( ) ) ;
2011-05-06 01:40:51 -07:00
fprintf ( gErrFile , " usage: xpcshell [-g gredir] [-a appdir] [-r manifest]... [-PsSwWxCij] [-v version] [-f scriptfile] [-e script] [scriptfile] [scriptarg...] \n " ) ;
2007-03-22 10:30:00 -07:00
return 2 ;
}
extern JSClass global_class ;
static int
ProcessArgs ( JSContext * cx , JSObject * obj , char * * argv , int argc )
{
const char rcfilename [ ] = " xpcshell.js " ;
FILE * rcfile ;
2011-08-04 19:39:12 -07:00
int i ;
2007-03-22 10:30:00 -07:00
JSObject * argsObj ;
char * filename = NULL ;
2011-11-26 02:05:59 -08:00
JSBool isInteractive = true ;
JSBool forceTTY = false ;
2007-03-22 10:30:00 -07:00
rcfile = fopen ( rcfilename , " r " ) ;
if ( rcfile ) {
printf ( " [loading '%s'...] \n " , rcfilename ) ;
2011-11-26 02:05:59 -08:00
ProcessFile ( cx , obj , rcfilename , rcfile , false ) ;
2009-02-15 08:23:50 -08:00
fclose ( rcfile ) ;
2007-03-22 10:30:00 -07:00
}
/*
* Scan past all optional arguments so we can create the arguments object
* before processing any - f options , which must interleave properly with
* - v and - w options . This requires two passes , and without getopt , we ' ll
* have to keep the option logic here and in the second for loop in sync .
*/
for ( i = 0 ; i < argc ; i + + ) {
if ( argv [ i ] [ 0 ] ! = ' - ' | | argv [ i ] [ 1 ] = = ' \0 ' ) {
+ + i ;
break ;
}
switch ( argv [ i ] [ 1 ] ) {
case ' v ' :
case ' f ' :
case ' e ' :
+ + i ;
break ;
default : ;
}
}
/*
* Create arguments early and define it to root it , so it ' s safe from any
* GC calls nested below , and so it is available to - f < file > arguments .
*/
argsObj = JS_NewArrayObject ( cx , 0 , NULL ) ;
if ( ! argsObj )
return 1 ;
if ( ! JS_DefineProperty ( cx , obj , " arguments " , OBJECT_TO_JSVAL ( argsObj ) ,
NULL , NULL , 0 ) ) {
return 1 ;
}
2011-08-04 19:39:12 -07:00
for ( size_t j = 0 , length = argc - i ; j < length ; j + + ) {
2007-03-22 10:30:00 -07:00
JSString * str = JS_NewStringCopyZ ( cx , argv [ i + + ] ) ;
if ( ! str )
return 1 ;
if ( ! JS_DefineElement ( cx , argsObj , j , STRING_TO_JSVAL ( str ) ,
NULL , NULL , JSPROP_ENUMERATE ) ) {
return 1 ;
}
}
for ( i = 0 ; i < argc ; i + + ) {
if ( argv [ i ] [ 0 ] ! = ' - ' | | argv [ i ] [ 1 ] = = ' \0 ' ) {
filename = argv [ i + + ] ;
2011-11-26 02:05:59 -08:00
isInteractive = false ;
2007-03-22 10:30:00 -07:00
break ;
}
switch ( argv [ i ] [ 1 ] ) {
case ' v ' :
if ( + + i = = argc ) {
return usage ( ) ;
}
JS_SetVersion ( cx , JSVersion ( atoi ( argv [ i ] ) ) ) ;
break ;
case ' W ' :
2011-11-26 02:05:59 -08:00
reportWarnings = false ;
2007-03-22 10:30:00 -07:00
break ;
case ' w ' :
2011-11-26 02:05:59 -08:00
reportWarnings = true ;
2007-03-22 10:30:00 -07:00
break ;
2009-09-28 11:34:57 -07:00
case ' S ' :
JS_ToggleOptions ( cx , JSOPTION_WERROR ) ;
2007-03-22 10:30:00 -07:00
case ' s ' :
JS_ToggleOptions ( cx , JSOPTION_STRICT ) ;
break ;
case ' x ' :
JS_ToggleOptions ( cx , JSOPTION_XML ) ;
break ;
2011-10-06 23:34:21 -07:00
case ' d ' :
xpc_ActivateDebugMode ( ) ;
break ;
2007-03-22 10:30:00 -07:00
case ' P ' :
2012-02-05 12:07:23 -08:00
if ( JS_GetClass ( JS_GetPrototype ( obj ) ) ! = & global_class ) {
2007-03-22 10:30:00 -07:00
JSObject * gobj ;
2010-09-21 11:35:29 -07:00
if ( ! JS_DeepFreezeObject ( cx , obj ) )
2011-11-26 02:05:59 -08:00
return false ;
2010-06-04 16:32:10 -07:00
gobj = JS_NewGlobalObject ( cx , & global_class ) ;
2011-07-15 10:14:07 -07:00
if ( ! gobj | | ! JS_SplicePrototype ( cx , gobj , obj ) )
2011-11-26 02:05:59 -08:00
return false ;
2007-03-22 10:30:00 -07:00
JS_SetParent ( cx , gobj , NULL ) ;
JS_SetGlobalObject ( cx , gobj ) ;
obj = gobj ;
}
break ;
case ' f ' :
if ( + + i = = argc ) {
return usage ( ) ;
}
2011-11-26 02:05:59 -08:00
Process ( cx , obj , argv [ i ] , false ) ;
2007-03-22 10:30:00 -07:00
/*
* XXX : js - f foo . js should interpret foo . js and then
* drop into interactive mode , but that breaks test
* harness . Just execute foo . js for now .
*/
2011-11-26 02:05:59 -08:00
isInteractive = false ;
2007-03-22 10:30:00 -07:00
break ;
case ' i ' :
2011-11-26 02:05:59 -08:00
isInteractive = forceTTY = true ;
2007-03-22 10:30:00 -07:00
break ;
case ' e ' :
{
jsval rval ;
if ( + + i = = argc ) {
return usage ( ) ;
}
2009-03-11 16:13:01 -07:00
JS_EvaluateScriptForPrincipals ( cx , obj , gJSPrincipals , argv [ i ] ,
strlen ( argv [ i ] ) , " -e " , 1 , & rval ) ;
2007-03-22 10:30:00 -07:00
2011-11-26 02:05:59 -08:00
isInteractive = false ;
2007-03-22 10:30:00 -07:00
break ;
}
case ' C ' :
2011-11-26 02:05:59 -08:00
compileOnly = true ;
isInteractive = false ;
2007-03-22 10:30:00 -07:00
break ;
2010-10-12 17:25:37 -07:00
case ' m ' :
JS_ToggleOptions ( cx , JSOPTION_METHODJIT ) ;
break ;
2011-03-03 14:07:48 -08:00
case ' n ' :
JS_ToggleOptions ( cx , JSOPTION_TYPE_INFERENCE ) ;
break ;
2007-03-22 10:30:00 -07:00
default :
return usage ( ) ;
}
}
if ( filename | | isInteractive )
Process ( cx , obj , filename , forceTTY ) ;
return gExitCode ;
}
/***************************************************************************/
2007-06-20 17:10:48 -07:00
class FullTrustSecMan
: public nsIScriptSecurityManager
2007-03-22 10:30:00 -07:00
{
public :
NS_DECL_ISUPPORTS
NS_DECL_NSIXPCSECURITYMANAGER
2007-06-20 17:10:48 -07:00
NS_DECL_NSISCRIPTSECURITYMANAGER
2007-03-22 10:30:00 -07:00
FullTrustSecMan ( ) ;
2007-06-20 17:10:48 -07:00
virtual ~ FullTrustSecMan ( ) ;
void SetSystemPrincipal ( nsIPrincipal * aPrincipal ) {
mSystemPrincipal = aPrincipal ;
}
private :
nsCOMPtr < nsIPrincipal > mSystemPrincipal ;
2007-03-22 10:30:00 -07:00
} ;
2007-06-20 17:10:48 -07:00
NS_INTERFACE_MAP_BEGIN ( FullTrustSecMan )
NS_INTERFACE_MAP_ENTRY ( nsIXPCSecurityManager )
NS_INTERFACE_MAP_ENTRY ( nsIScriptSecurityManager )
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS ( nsISupports , nsIXPCSecurityManager )
NS_INTERFACE_MAP_END
NS_IMPL_ADDREF ( FullTrustSecMan )
NS_IMPL_RELEASE ( FullTrustSecMan )
2007-03-22 10:30:00 -07:00
FullTrustSecMan : : FullTrustSecMan ( )
{
2007-06-20 17:10:48 -07:00
mSystemPrincipal = nsnull ;
}
FullTrustSecMan : : ~ FullTrustSecMan ( )
{
2007-03-22 10:30:00 -07:00
}
NS_IMETHODIMP
2007-06-20 17:10:48 -07:00
FullTrustSecMan : : CanCreateWrapper ( JSContext * aJSContext , const nsIID & aIID ,
nsISupports * aObj , nsIClassInfo * aClassInfo ,
void * * aPolicy )
2007-03-22 10:30:00 -07:00
{
return NS_OK ;
}
NS_IMETHODIMP
FullTrustSecMan : : CanCreateInstance ( JSContext * aJSContext , const nsCID & aCID )
{
return NS_OK ;
}
NS_IMETHODIMP
FullTrustSecMan : : CanGetService ( JSContext * aJSContext , const nsCID & aCID )
{
return NS_OK ;
}
2010-05-12 06:18:51 -07:00
/* void CanAccess (in PRUint32 aAction, in nsIXPCNativeCallContext aCallContext, in JSContextPtr aJSContext, in JSObjectPtr aJSObject, in nsISupports aObj, in nsIClassInfo aClassInfo, in jsval aName, inout voidPtr aPolicy); */
2007-06-20 17:10:48 -07:00
NS_IMETHODIMP
FullTrustSecMan : : CanAccess ( PRUint32 aAction ,
2008-01-15 07:50:57 -08:00
nsAXPCNativeCallContext * aCallContext ,
2007-06-20 17:10:48 -07:00
JSContext * aJSContext , JSObject * aJSObject ,
nsISupports * aObj , nsIClassInfo * aClassInfo ,
2010-07-14 23:19:36 -07:00
jsid aName , void * * aPolicy )
2007-06-20 17:10:48 -07:00
{
return NS_OK ;
}
2010-07-14 23:19:36 -07:00
/* [noscript] void checkPropertyAccess (in JSContextPtr aJSContext, in JSObjectPtr aJSObject, in string aClassName, in jsid aProperty, in PRUint32 aAction); */
2007-06-20 17:10:48 -07:00
NS_IMETHODIMP
FullTrustSecMan : : CheckPropertyAccess ( JSContext * aJSContext ,
JSObject * aJSObject ,
const char * aClassName ,
2010-07-14 23:19:36 -07:00
jsid aProperty , PRUint32 aAction )
2007-03-22 10:30:00 -07:00
{
return NS_OK ;
}
2007-06-20 17:10:48 -07:00
/* [noscript] void checkLoadURIFromScript (in JSContextPtr cx, in nsIURI uri); */
NS_IMETHODIMP
FullTrustSecMan : : CheckLoadURIFromScript ( JSContext * cx , nsIURI * uri )
{
return NS_OK ;
}
/* void checkLoadURIWithPrincipal (in nsIPrincipal aPrincipal, in nsIURI uri, in unsigned long flags); */
NS_IMETHODIMP
FullTrustSecMan : : CheckLoadURIWithPrincipal ( nsIPrincipal * aPrincipal ,
nsIURI * uri , PRUint32 flags )
{
return NS_OK ;
}
/* void checkLoadURI (in nsIURI from, in nsIURI uri, in unsigned long flags); */
NS_IMETHODIMP
FullTrustSecMan : : CheckLoadURI ( nsIURI * from , nsIURI * uri , PRUint32 flags )
{
return NS_OK ;
}
/* void checkLoadURIStrWithPrincipal (in nsIPrincipal aPrincipal, in AUTF8String uri, in unsigned long flags); */
NS_IMETHODIMP
FullTrustSecMan : : CheckLoadURIStrWithPrincipal ( nsIPrincipal * aPrincipal ,
const nsACString & uri ,
PRUint32 flags )
{
return NS_OK ;
}
/* void checkLoadURIStr (in AUTF8String from, in AUTF8String uri, in unsigned long flags); */
NS_IMETHODIMP
FullTrustSecMan : : CheckLoadURIStr ( const nsACString & from ,
const nsACString & uri , PRUint32 flags )
{
return NS_OK ;
}
/* [noscript] void checkFunctionAccess (in JSContextPtr cx, in voidPtr funObj, in voidPtr targetObj); */
NS_IMETHODIMP
FullTrustSecMan : : CheckFunctionAccess ( JSContext * cx , void * funObj ,
void * targetObj )
{
return NS_OK ;
}
/* [noscript] boolean canExecuteScripts (in JSContextPtr cx, in nsIPrincipal principal); */
NS_IMETHODIMP
FullTrustSecMan : : CanExecuteScripts ( JSContext * cx , nsIPrincipal * principal ,
2011-09-28 23:19:26 -07:00
bool * _retval )
2007-06-20 17:10:48 -07:00
{
2011-10-17 07:59:28 -07:00
* _retval = true ;
2007-06-20 17:10:48 -07:00
return NS_OK ;
}
/* [noscript] nsIPrincipal getSubjectPrincipal (); */
NS_IMETHODIMP
FullTrustSecMan : : GetSubjectPrincipal ( nsIPrincipal * * _retval )
{
NS_IF_ADDREF ( * _retval = mSystemPrincipal ) ;
return * _retval ? NS_OK : NS_ERROR_FAILURE ;
}
2009-08-21 18:20:20 -07:00
/* [noscript] void pushContextPrincipal (in JSContextPtr cx, in JSStackFramePtr fp, in nsIPrincipal principal); */
NS_IMETHODIMP
FullTrustSecMan : : PushContextPrincipal ( JSContext * cx , JSStackFrame * fp , nsIPrincipal * principal )
{
return NS_OK ;
}
/* [noscript] void popContextPrincipal (in JSContextPtr cx); */
NS_IMETHODIMP
FullTrustSecMan : : PopContextPrincipal ( JSContext * cx )
{
return NS_OK ;
}
2007-06-20 17:10:48 -07:00
/* [noscript] nsIPrincipal getSystemPrincipal (); */
NS_IMETHODIMP
FullTrustSecMan : : GetSystemPrincipal ( nsIPrincipal * * _retval )
{
NS_IF_ADDREF ( * _retval = mSystemPrincipal ) ;
return * _retval ? NS_OK : NS_ERROR_FAILURE ;
}
/* [noscript] nsIPrincipal getCertificatePrincipal (in AUTF8String aCertFingerprint, in AUTF8String aSubjectName, in AUTF8String aPrettyName, in nsISupports aCert, in nsIURI aURI); */
NS_IMETHODIMP
FullTrustSecMan : : GetCertificatePrincipal ( const nsACString & aCertFingerprint ,
const nsACString & aSubjectName ,
const nsACString & aPrettyName ,
nsISupports * aCert , nsIURI * aURI ,
nsIPrincipal * * _retval )
{
NS_IF_ADDREF ( * _retval = mSystemPrincipal ) ;
return * _retval ? NS_OK : NS_ERROR_FAILURE ;
}
/* [noscript] nsIPrincipal getCodebasePrincipal (in nsIURI aURI); */
NS_IMETHODIMP
FullTrustSecMan : : GetCodebasePrincipal ( nsIURI * aURI , nsIPrincipal * * _retval )
{
NS_IF_ADDREF ( * _retval = mSystemPrincipal ) ;
return * _retval ? NS_OK : NS_ERROR_FAILURE ;
}
/* [noscript] short requestCapability (in nsIPrincipal principal, in string capability); */
NS_IMETHODIMP
FullTrustSecMan : : RequestCapability ( nsIPrincipal * principal ,
const char * capability , PRInt16 * _retval )
{
* _retval = nsIPrincipal : : ENABLE_GRANTED ;
return NS_OK ;
}
/* boolean isCapabilityEnabled (in string capability); */
NS_IMETHODIMP
2011-09-28 23:19:26 -07:00
FullTrustSecMan : : IsCapabilityEnabled ( const char * capability , bool * _retval )
2007-06-20 17:10:48 -07:00
{
2011-10-17 07:59:28 -07:00
* _retval = true ;
2007-06-20 17:10:48 -07:00
return NS_OK ;
}
/* void enableCapability (in string capability); */
NS_IMETHODIMP
FullTrustSecMan : : EnableCapability ( const char * capability )
{
return NS_OK ; ;
}
/* void revertCapability (in string capability); */
NS_IMETHODIMP
FullTrustSecMan : : RevertCapability ( const char * capability )
{
return NS_OK ;
}
/* void disableCapability (in string capability); */
NS_IMETHODIMP
FullTrustSecMan : : DisableCapability ( const char * capability )
{
return NS_OK ;
}
/* void setCanEnableCapability (in AUTF8String certificateFingerprint, in string capability, in short canEnable); */
NS_IMETHODIMP
FullTrustSecMan : : SetCanEnableCapability ( const nsACString & certificateFingerprint ,
const char * capability ,
PRInt16 canEnable )
{
return NS_OK ;
}
/* [noscript] nsIPrincipal getObjectPrincipal (in JSContextPtr cx, in JSObjectPtr obj); */
NS_IMETHODIMP
FullTrustSecMan : : GetObjectPrincipal ( JSContext * cx , JSObject * obj ,
nsIPrincipal * * _retval )
{
NS_IF_ADDREF ( * _retval = mSystemPrincipal ) ;
return * _retval ? NS_OK : NS_ERROR_FAILURE ;
}
/* [noscript] boolean subjectPrincipalIsSystem (); */
NS_IMETHODIMP
2011-09-28 23:19:26 -07:00
FullTrustSecMan : : SubjectPrincipalIsSystem ( bool * _retval )
2007-06-20 17:10:48 -07:00
{
2011-10-17 07:59:28 -07:00
* _retval = true ;
2007-06-20 17:10:48 -07:00
return NS_OK ;
}
/* [noscript] void checkSameOrigin (in JSContextPtr aJSContext, in nsIURI aTargetURI); */
NS_IMETHODIMP
FullTrustSecMan : : CheckSameOrigin ( JSContext * aJSContext , nsIURI * aTargetURI )
{
return NS_OK ;
}
/* void checkSameOriginURI (in nsIURI aSourceURI, in nsIURI aTargetURI); */
NS_IMETHODIMP
2007-10-26 18:46:09 -07:00
FullTrustSecMan : : CheckSameOriginURI ( nsIURI * aSourceURI , nsIURI * aTargetURI ,
2011-09-28 23:19:26 -07:00
bool reportError )
2007-06-20 17:10:48 -07:00
{
return NS_OK ;
}
/* [noscript] nsIPrincipal getPrincipalFromContext (in JSContextPtr cx); */
NS_IMETHODIMP
FullTrustSecMan : : GetPrincipalFromContext ( JSContext * cx , nsIPrincipal * * _retval )
{
NS_IF_ADDREF ( * _retval = mSystemPrincipal ) ;
return * _retval ? NS_OK : NS_ERROR_FAILURE ;
}
/* [noscript] nsIPrincipal getChannelPrincipal (in nsIChannel aChannel); */
NS_IMETHODIMP
FullTrustSecMan : : GetChannelPrincipal ( nsIChannel * aChannel , nsIPrincipal * * _retval )
{
NS_IF_ADDREF ( * _retval = mSystemPrincipal ) ;
return * _retval ? NS_OK : NS_ERROR_FAILURE ;
}
/* boolean isSystemPrincipal (in nsIPrincipal aPrincipal); */
NS_IMETHODIMP
2011-09-28 23:19:26 -07:00
FullTrustSecMan : : IsSystemPrincipal ( nsIPrincipal * aPrincipal , bool * _retval )
2007-06-20 17:10:48 -07:00
{
* _retval = aPrincipal = = mSystemPrincipal ;
return NS_OK ;
}
2008-01-04 15:59:12 -08:00
NS_IMETHODIMP_ ( nsIPrincipal * )
FullTrustSecMan : : GetCxSubjectPrincipal ( JSContext * cx )
{
return mSystemPrincipal ;
}
2008-10-22 13:15:22 -07:00
NS_IMETHODIMP_ ( nsIPrincipal * )
FullTrustSecMan : : GetCxSubjectPrincipalAndFrame ( JSContext * cx , JSStackFrame * * fp )
{
* fp = nsnull ;
return mSystemPrincipal ;
}
2007-03-22 10:30:00 -07:00
/***************************************************************************/
// #define TEST_InitClassesWithNewWrappedGlobal
# ifdef TEST_InitClassesWithNewWrappedGlobal
// XXX hacky test code...
# include "xpctest.h"
class TestGlobal : public nsIXPCTestNoisy , public nsIXPCScriptable
{
public :
NS_DECL_ISUPPORTS
NS_DECL_NSIXPCTESTNOISY
NS_DECL_NSIXPCSCRIPTABLE
TestGlobal ( ) { }
} ;
NS_IMPL_ISUPPORTS2 ( TestGlobal , nsIXPCTestNoisy , nsIXPCScriptable )
// The nsIXPCScriptable map declaration that will generate stubs for us...
# define XPC_MAP_CLASSNAME TestGlobal
# define XPC_MAP_QUOTED_CLASSNAME "TestGlobal"
# define XPC_MAP_FLAGS nsIXPCScriptable::USE_JSSTUB_FOR_ADDPROPERTY |\
nsIXPCScriptable : : USE_JSSTUB_FOR_DELPROPERTY | \
nsIXPCScriptable : : USE_JSSTUB_FOR_SETPROPERTY
# include "xpc_map_end.h" /* This will #undef the above */
NS_IMETHODIMP TestGlobal : : Squawk ( ) { return NS_OK ; }
# endif
// uncomment to install the test 'this' translator
// #define TEST_TranslateThis
# ifdef TEST_TranslateThis
# include "xpctest.h"
class nsXPCFunctionThisTranslator : public nsIXPCFunctionThisTranslator
{
public :
NS_DECL_ISUPPORTS
NS_DECL_NSIXPCFUNCTIONTHISTRANSLATOR
nsXPCFunctionThisTranslator ( ) ;
virtual ~ nsXPCFunctionThisTranslator ( ) ;
/* additional members */
} ;
/* Implementation file */
NS_IMPL_ISUPPORTS1 ( nsXPCFunctionThisTranslator , nsIXPCFunctionThisTranslator )
nsXPCFunctionThisTranslator : : nsXPCFunctionThisTranslator ( )
{
/* member initializers and constructor code */
}
nsXPCFunctionThisTranslator : : ~ nsXPCFunctionThisTranslator ( )
{
/* destructor code */
# ifdef DEBUG_jband
printf ( " destroying nsXPCFunctionThisTranslator \n " ) ;
# endif
}
2011-09-28 23:19:26 -07:00
/* nsISupports TranslateThis (in nsISupports aInitialThis, in nsIInterfaceInfo aInterfaceInfo, in PRUint16 aMethodIndex, out bool aHideFirstParamFromJS, out nsIIDPtr aIIDOfResult); */
2009-06-28 16:01:42 -07:00
NS_IMETHODIMP
nsXPCFunctionThisTranslator : : TranslateThis ( nsISupports * aInitialThis ,
nsIInterfaceInfo * aInterfaceInfo ,
PRUint16 aMethodIndex ,
2011-09-28 23:19:26 -07:00
bool * aHideFirstParamFromJS ,
2009-06-28 16:01:42 -07:00
nsIID * * aIIDOfResult ,
2007-03-22 10:30:00 -07:00
nsISupports * * _retval )
{
NS_IF_ADDREF ( aInitialThis ) ;
* _retval = aInitialThis ;
2011-11-26 02:05:59 -08:00
* aHideFirstParamFromJS = false ;
2007-03-22 10:30:00 -07:00
* aIIDOfResult = nsnull ;
return NS_OK ;
}
# endif
2008-10-11 10:35:39 -07:00
// ContextCallback calls are chained
static JSContextCallback gOldJSContextCallback ;
2008-09-06 15:21:43 -07:00
static JSBool
2008-04-09 00:27:16 -07:00
ContextCallback ( JSContext * cx , uintN contextOp )
{
2008-10-11 10:35:39 -07:00
if ( gOldJSContextCallback & & ! gOldJSContextCallback ( cx , contextOp ) )
2011-11-26 02:05:59 -08:00
return false ;
2008-10-11 10:35:39 -07:00
2008-04-09 00:27:16 -07:00
if ( contextOp = = JSCONTEXT_NEW ) {
JS_SetErrorReporter ( cx , my_ErrorReporter ) ;
JS_SetVersion ( cx , JSVERSION_LATEST ) ;
}
2011-11-26 02:05:59 -08:00
return true ;
2008-04-09 00:27:16 -07:00
}
2009-01-18 09:01:15 -08:00
static bool
GetCurrentWorkingDirectory ( nsAString & workingDirectory )
{
2011-04-09 12:17:53 -07:00
# if !defined(XP_WIN) && !defined(XP_UNIX)
2009-01-18 09:01:15 -08:00
//XXX: your platform should really implement this
return false ;
2009-01-22 07:17:22 -08:00
# elif XP_WIN
2009-01-18 09:01:15 -08:00
DWORD requiredLength = GetCurrentDirectoryW ( 0 , NULL ) ;
workingDirectory . SetLength ( requiredLength ) ;
GetCurrentDirectoryW ( workingDirectory . Length ( ) ,
( LPWSTR ) workingDirectory . BeginWriting ( ) ) ;
// we got a trailing null there
workingDirectory . SetLength ( requiredLength ) ;
workingDirectory . Replace ( workingDirectory . Length ( ) - 1 , 1 , L ' \\ ' ) ;
# elif defined(XP_UNIX)
nsCAutoString cwd ;
// 1024 is just a guess at a sane starting value
size_t bufsize = 1024 ;
char * result = nsnull ;
while ( result = = nsnull ) {
if ( ! cwd . SetLength ( bufsize ) )
return false ;
result = getcwd ( cwd . BeginWriting ( ) , cwd . Length ( ) ) ;
if ( ! result ) {
if ( errno ! = ERANGE )
return false ;
// need to make the buffer bigger
bufsize * = 2 ;
}
}
// size back down to the actual string length
cwd . SetLength ( strlen ( result ) + 1 ) ;
cwd . Replace ( cwd . Length ( ) - 1 , 1 , ' / ' ) ;
workingDirectory = NS_ConvertUTF8toUTF16 ( cwd ) ;
# endif
return true ;
}
2011-05-12 12:12:50 -07:00
static JSPrincipals *
FindObjectPrincipals ( JSContext * cx , JSObject * obj )
{
return gJSPrincipals ;
}
2007-03-22 10:30:00 -07:00
int
main ( int argc , char * * argv , char * * envp )
{
2008-06-03 03:56:09 -07:00
# ifdef XP_MACOSX
InitAutoreleasePool ( ) ;
# endif
2007-03-22 10:30:00 -07:00
JSRuntime * rt ;
JSContext * cx ;
JSObject * glob , * envobj ;
int result ;
nsresult rv ;
2009-01-16 14:10:48 -08:00
# ifdef HAVE_SETBUF
2007-03-22 10:30:00 -07:00
// unbuffer stdout so that output is in the correct order; note that stderr
// is unbuffered by default
setbuf ( stdout , 0 ) ;
2009-01-16 14:10:48 -08:00
# endif
2007-03-22 10:30:00 -07:00
gErrFile = stderr ;
gOutFile = stdout ;
2008-11-27 18:25:35 -08:00
gInFile = stdin ;
2009-01-20 11:56:44 -08:00
NS_LogInit ( ) ;
nsCOMPtr < nsILocalFile > appFile ;
rv = XRE_GetBinaryPath ( argv [ 0 ] , getter_AddRefs ( appFile ) ) ;
if ( NS_FAILED ( rv ) ) {
2009-05-11 18:38:31 -07:00
printf ( " Couldn't find application file. \n " ) ;
2009-01-20 11:56:44 -08:00
return 1 ;
}
nsCOMPtr < nsIFile > appDir ;
rv = appFile - > GetParent ( getter_AddRefs ( appDir ) ) ;
if ( NS_FAILED ( rv ) ) {
printf ( " Couldn't get application directory. \n " ) ;
return 1 ;
}
XPCShellDirProvider dirprovider ;
if ( argc > 1 & & ! strcmp ( argv [ 1 ] , " -g " ) ) {
if ( argc < 3 )
return usage ( ) ;
if ( ! dirprovider . SetGREDir ( argv [ 2 ] ) ) {
printf ( " SetGREDir failed. \n " ) ;
return 1 ;
}
argc - = 2 ;
argv + = 2 ;
}
2011-05-06 01:40:51 -07:00
if ( argc > 1 & & ! strcmp ( argv [ 1 ] , " -a " ) ) {
if ( argc < 3 )
return usage ( ) ;
nsCOMPtr < nsILocalFile > dir ;
rv = XRE_GetFileFromPath ( argv [ 2 ] , getter_AddRefs ( dir ) ) ;
if ( NS_SUCCEEDED ( rv ) ) {
appDir = do_QueryInterface ( dir , & rv ) ;
}
if ( NS_FAILED ( rv ) ) {
printf ( " Couldn't use given appdir. \n " ) ;
return 1 ;
}
argc - = 2 ;
argv + = 2 ;
}
2010-07-22 07:42:43 -07:00
while ( argc > 1 & & ! strcmp ( argv [ 1 ] , " -r " ) ) {
if ( argc < 3 )
return usage ( ) ;
nsCOMPtr < nsILocalFile > lf ;
rv = XRE_GetFileFromPath ( argv [ 2 ] , getter_AddRefs ( lf ) ) ;
if ( NS_FAILED ( rv ) ) {
printf ( " Couldn't get manifest file. \n " ) ;
return 1 ;
}
XRE_AddManifestLocation ( NS_COMPONENT_LOCATION , lf ) ;
argc - = 2 ;
argv + = 2 ;
}
2007-03-22 10:30:00 -07:00
{
2011-06-26 19:05:51 -07:00
if ( argc > 1 & & ! strcmp ( argv [ 1 ] , " --greomni " ) ) {
nsCOMPtr < nsILocalFile > greOmni ;
nsCOMPtr < nsILocalFile > appOmni ;
XRE_GetFileFromPath ( argv [ 2 ] , getter_AddRefs ( greOmni ) ) ;
if ( argc > 3 & & ! strcmp ( argv [ 3 ] , " --appomni " ) ) {
XRE_GetFileFromPath ( argv [ 4 ] , getter_AddRefs ( appOmni ) ) ;
argc - = 2 ;
argv + = 2 ;
2011-08-22 01:00:34 -07:00
} else {
appOmni = greOmni ;
}
2011-10-14 10:52:47 -07:00
2011-06-26 19:05:51 -07:00
XRE_InitOmnijar ( greOmni , appOmni ) ;
argc - = 2 ;
argv + = 2 ;
}
2007-03-22 10:30:00 -07:00
nsCOMPtr < nsIServiceManager > servMan ;
2009-01-20 11:56:44 -08:00
rv = NS_InitXPCOM2 ( getter_AddRefs ( servMan ) , appDir , & dirprovider ) ;
2007-03-22 10:30:00 -07:00
if ( NS_FAILED ( rv ) ) {
2009-08-20 08:35:30 -07:00
printf ( " NS_InitXPCOM2 failed! \n " ) ;
2007-03-22 10:30:00 -07:00
return 1 ;
}
nsCOMPtr < nsIJSRuntimeService > rtsvc = do_GetService ( " @mozilla.org/js/xpc/RuntimeService;1 " ) ;
// get the JSRuntime from the runtime svc
if ( ! rtsvc ) {
printf ( " failed to get nsJSRuntimeService! \n " ) ;
return 1 ;
}
2009-06-28 16:01:42 -07:00
2007-03-22 10:30:00 -07:00
if ( NS_FAILED ( rtsvc - > GetRuntime ( & rt ) ) | | ! rt ) {
printf ( " failed to get JSRuntime from nsJSRuntimeService! \n " ) ;
return 1 ;
}
2008-10-11 10:35:39 -07:00
gOldJSContextCallback = JS_SetContextCallback ( rt , ContextCallback ) ;
2008-04-09 00:27:16 -07:00
2007-03-22 10:30:00 -07:00
cx = JS_NewContext ( rt , 8192 ) ;
if ( ! cx ) {
printf ( " JS_NewContext failed! \n " ) ;
return 1 ;
}
2010-12-06 12:45:00 -08:00
xpc_LocalizeContext ( cx ) ;
2007-03-22 10:30:00 -07:00
nsCOMPtr < nsIXPConnect > xpc = do_GetService ( nsIXPConnect : : GetCID ( ) ) ;
if ( ! xpc ) {
printf ( " failed to get nsXPConnect service! \n " ) ;
return 1 ;
}
// Since the caps security system might set a default security manager
// we will be sure that the secman on this context gives full trust.
2007-06-20 17:10:48 -07:00
nsRefPtr < FullTrustSecMan > secman = new FullTrustSecMan ( ) ;
xpc - > SetSecurityManagerForJSContext ( cx , secman , 0xFFFF ) ;
2007-03-22 10:30:00 -07:00
2010-07-19 13:36:49 -07:00
nsCOMPtr < nsIPrincipal > systemprincipal ;
2007-03-22 10:30:00 -07:00
// Fetch the system principal and store it away in a global, to use for
// script compilation in Load() and ProcessFile() (including interactive
// eval loop)
{
nsCOMPtr < nsIScriptSecurityManager > securityManager =
do_GetService ( NS_SCRIPTSECURITYMANAGER_CONTRACTID , & rv ) ;
if ( NS_SUCCEEDED ( rv ) & & securityManager ) {
2010-07-19 13:36:49 -07:00
rv = securityManager - > GetSystemPrincipal ( getter_AddRefs ( systemprincipal ) ) ;
2007-03-22 10:30:00 -07:00
if ( NS_FAILED ( rv ) ) {
fprintf ( gErrFile , " +++ Failed to obtain SystemPrincipal from ScriptSecurityManager service. \n " ) ;
} else {
// fetch the JS principals and stick in a global
2010-07-19 13:36:49 -07:00
rv = systemprincipal - > GetJSPrincipals ( cx , & gJSPrincipals ) ;
2007-03-22 10:30:00 -07:00
if ( NS_FAILED ( rv ) ) {
fprintf ( gErrFile , " +++ Failed to obtain JS principals from SystemPrincipal. \n " ) ;
}
2010-07-19 13:36:49 -07:00
secman - > SetSystemPrincipal ( systemprincipal ) ;
2007-03-22 10:30:00 -07:00
}
} else {
fprintf ( gErrFile , " +++ Failed to get ScriptSecurityManager service, running without principals " ) ;
}
}
2011-05-12 12:12:50 -07:00
JSSecurityCallbacks * cb = JS_GetRuntimeSecurityCallbacks ( rt ) ;
NS_ASSERTION ( cb , " We are assuming that nsScriptSecurityManager::Init() has been run " ) ;
NS_ASSERTION ( ! cb - > findObjectPrincipals , " Your pigeon is in my hole! " ) ;
cb - > findObjectPrincipals = FindObjectPrincipals ;
2007-03-22 10:30:00 -07:00
# ifdef TEST_TranslateThis
nsCOMPtr < nsIXPCFunctionThisTranslator >
translator ( new nsXPCFunctionThisTranslator ) ;
xpc - > SetFunctionThisTranslator ( NS_GET_IID ( nsITestXPCFunctionCallback ) , translator , nsnull ) ;
# endif
2009-06-28 16:01:42 -07:00
2007-03-22 10:30:00 -07:00
nsCOMPtr < nsIJSContextStack > cxstack = do_GetService ( " @mozilla.org/js/xpc/ContextStack;1 " ) ;
if ( ! cxstack ) {
printf ( " failed to get the nsThreadJSContextStack service! \n " ) ;
return 1 ;
}
2011-10-14 10:52:48 -07:00
if ( NS_FAILED ( cxstack - > Push ( cx ) ) ) {
2007-03-22 10:30:00 -07:00
printf ( " failed to push the current JSContext on the nsThreadJSContextStack! \n " ) ;
return 1 ;
}
nsCOMPtr < nsIXPCScriptable > backstagePass ;
nsresult rv = rtsvc - > GetBackstagePass ( getter_AddRefs ( backstagePass ) ) ;
if ( NS_FAILED ( rv ) ) {
fprintf ( gErrFile , " +++ Failed to get backstage pass from rtsvc: %8x \n " ,
rv ) ;
return 1 ;
}
nsCOMPtr < nsIXPConnectJSObjectHolder > holder ;
rv = xpc - > InitClassesWithNewWrappedGlobal ( cx , backstagePass ,
NS_GET_IID ( nsISupports ) ,
2010-07-19 13:36:49 -07:00
systemprincipal ,
2010-10-26 23:57:31 -07:00
nsnull ,
2007-03-22 10:30:00 -07:00
nsIXPConnect : :
2011-10-14 10:52:48 -07:00
FLAG_SYSTEM_GLOBAL_OBJECT ,
2007-03-22 10:30:00 -07:00
getter_AddRefs ( holder ) ) ;
if ( NS_FAILED ( rv ) )
return 1 ;
2009-06-28 16:01:42 -07:00
2007-03-22 10:30:00 -07:00
rv = holder - > GetJSObject ( & glob ) ;
if ( NS_FAILED ( rv ) ) {
NS_ASSERTION ( glob = = nsnull , " bad GetJSObject? " ) ;
return 1 ;
}
JS_BeginRequest ( cx ) ;
2010-09-08 16:09:23 -07:00
{
2010-09-27 15:55:15 -07:00
JSAutoEnterCompartment ac ;
2010-09-08 16:09:23 -07:00
if ( ! ac . enter ( cx , glob ) ) {
JS_EndRequest ( cx ) ;
2011-09-09 15:11:00 -07:00
return 1 ;
}
if ( ! JS_InitReflect ( cx , glob ) ) {
JS_EndRequest ( cx ) ;
2010-09-08 16:09:23 -07:00
return 1 ;
}
2007-03-22 10:30:00 -07:00
2011-01-14 17:58:40 -08:00
if ( ! JS_DefineFunctions ( cx , glob , glob_functions ) | |
! JS_DefineProfilingFunctions ( cx , glob ) ) {
2010-09-08 16:09:23 -07:00
JS_EndRequest ( cx ) ;
return 1 ;
}
2007-03-22 10:30:00 -07:00
2010-09-08 16:09:23 -07:00
envobj = JS_DefineObject ( cx , glob , " environment " , & env_class , NULL , 0 ) ;
2012-02-05 12:07:23 -08:00
if ( ! envobj ) {
2010-09-08 16:09:23 -07:00
JS_EndRequest ( cx ) ;
return 1 ;
}
2007-03-22 10:30:00 -07:00
2012-02-05 12:07:23 -08:00
JS_SetPrivate ( envobj , envp ) ;
2010-09-08 16:09:23 -07:00
nsAutoString workingDirectory ;
if ( GetCurrentWorkingDirectory ( workingDirectory ) )
gWorkingDirectory = & workingDirectory ;
2009-01-18 09:01:15 -08:00
2010-09-08 16:09:23 -07:00
JS_DefineProperty ( cx , glob , " __LOCATION__ " , JSVAL_VOID ,
GetLocationProperty , NULL , 0 ) ;
2009-01-18 09:01:15 -08:00
2010-09-08 16:09:23 -07:00
argc - - ;
argv + + ;
2007-03-22 10:30:00 -07:00
2010-09-08 16:09:23 -07:00
result = ProcessArgs ( cx , glob , argv , argc ) ;
2007-03-22 10:30:00 -07:00
//#define TEST_CALL_ON_WRAPPED_JS_AFTER_SHUTDOWN 1
# ifdef TEST_CALL_ON_WRAPPED_JS_AFTER_SHUTDOWN
2010-09-08 16:09:23 -07:00
// test of late call and release (see below)
nsCOMPtr < nsIJSContextStack > bogus ;
xpc - > WrapJS ( cx , glob , NS_GET_IID ( nsIJSContextStack ) ,
( void * * ) getter_AddRefs ( bogus ) ) ;
2007-03-22 10:30:00 -07:00
# endif
2010-09-08 16:09:23 -07:00
JSPRINCIPALS_DROP ( cx , gJSPrincipals ) ;
JS_ClearScope ( cx , glob ) ;
JS_GC ( cx ) ;
JSContext * oldcx ;
cxstack - > Pop ( & oldcx ) ;
NS_ASSERTION ( oldcx = = cx , " JS thread context push/pop mismatch " ) ;
cxstack = nsnull ;
JS_GC ( cx ) ;
} //this scopes the JSAutoCrossCompartmentCall
2012-01-30 02:15:13 -08:00
JS_EndRequest ( cx ) ;
2007-03-22 10:30:00 -07:00
JS_DestroyContext ( cx ) ;
} // this scopes the nsCOMPtrs
2009-08-20 08:35:30 -07:00
2009-11-11 00:34:08 -08:00
if ( ! XRE_ShutdownTestShell ( ) )
NS_ERROR ( " problem shutting down testshell " ) ;
2009-08-20 08:35:30 -07:00
# ifdef MOZ_CRASHREPORTER
// Get the crashreporter service while XPCOM is still active.
// This is a special exception: it will remain usable after NS_ShutdownXPCOM().
nsCOMPtr < nsICrashReporter > crashReporter =
do_GetService ( " @mozilla.org/toolkit/crash-reporter;1 " ) ;
# endif
2007-03-22 10:30:00 -07:00
// no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM
rv = NS_ShutdownXPCOM ( NULL ) ;
NS_ASSERTION ( NS_SUCCEEDED ( rv ) , " NS_ShutdownXPCOM failed " ) ;
# ifdef TEST_CALL_ON_WRAPPED_JS_AFTER_SHUTDOWN
// test of late call and release (see above)
JSContext * bogusCX ;
bogus - > Peek ( & bogusCX ) ;
bogus = nsnull ;
# endif
2009-01-20 11:56:44 -08:00
appDir = nsnull ;
appFile = nsnull ;
dirprovider . ClearGREDir ( ) ;
2009-08-20 08:35:30 -07:00
# ifdef MOZ_CRASHREPORTER
// Shut down the crashreporter service to prevent leaking some strings it holds.
if ( crashReporter ) {
2011-10-17 07:59:28 -07:00
crashReporter - > SetEnabled ( false ) ;
2009-08-20 09:07:23 -07:00
crashReporter = nsnull ;
2009-08-20 08:35:30 -07:00
}
# endif
2009-01-20 11:56:44 -08:00
NS_LogTerm ( ) ;
2008-06-03 03:56:09 -07:00
# ifdef XP_MACOSX
FinishAutoreleasePool ( ) ;
# endif
2007-03-22 10:30:00 -07:00
return result ;
}
2009-01-20 11:56:44 -08:00
2011-09-28 23:19:26 -07:00
bool
2009-01-20 11:56:44 -08:00
XPCShellDirProvider : : SetGREDir ( const char * dir )
{
nsresult rv = XRE_GetFileFromPath ( dir , getter_AddRefs ( mGREDir ) ) ;
return NS_SUCCEEDED ( rv ) ;
}
NS_IMETHODIMP_ ( nsrefcnt )
XPCShellDirProvider : : AddRef ( )
{
return 2 ;
}
NS_IMETHODIMP_ ( nsrefcnt )
XPCShellDirProvider : : Release ( )
{
return 1 ;
}
2009-07-17 07:41:26 -07:00
NS_IMPL_QUERY_INTERFACE2 ( XPCShellDirProvider ,
nsIDirectoryServiceProvider ,
nsIDirectoryServiceProvider2 )
2009-01-20 11:56:44 -08:00
NS_IMETHODIMP
2011-09-28 23:19:26 -07:00
XPCShellDirProvider : : GetFile ( const char * prop , bool * persistent ,
2009-01-20 11:56:44 -08:00
nsIFile * * result )
{
if ( mGREDir & & ! strcmp ( prop , NS_GRE_DIR ) ) {
2011-10-17 07:59:28 -07:00
* persistent = true ;
2011-07-21 00:57:07 -07:00
return mGREDir - > Clone ( result ) ;
} else if ( mGREDir & & ! strcmp ( prop , NS_APP_PREF_DEFAULTS_50_DIR ) ) {
nsCOMPtr < nsIFile > file ;
2011-10-17 07:59:28 -07:00
* persistent = true ;
2011-07-21 00:57:07 -07:00
if ( NS_FAILED ( mGREDir - > Clone ( getter_AddRefs ( file ) ) ) | |
NS_FAILED ( file - > AppendNative ( NS_LITERAL_CSTRING ( " defaults " ) ) ) | |
NS_FAILED ( file - > AppendNative ( NS_LITERAL_CSTRING ( " pref " ) ) ) )
return NS_ERROR_FAILURE ;
NS_ADDREF ( * result = file ) ;
2009-01-20 11:56:44 -08:00
return NS_OK ;
}
return NS_ERROR_FAILURE ;
}
2009-07-17 07:41:26 -07:00
NS_IMETHODIMP
XPCShellDirProvider : : GetFiles ( const char * prop , nsISimpleEnumerator * * result )
{
if ( mGREDir & & ! strcmp ( prop , " ChromeML " ) ) {
nsCOMArray < nsIFile > dirs ;
nsCOMPtr < nsIFile > file ;
mGREDir - > Clone ( getter_AddRefs ( file ) ) ;
file - > AppendNative ( NS_LITERAL_CSTRING ( " chrome " ) ) ;
dirs . AppendObject ( file ) ;
nsresult rv = NS_GetSpecialDirectory ( NS_APP_CHROME_DIR ,
getter_AddRefs ( file ) ) ;
if ( NS_SUCCEEDED ( rv ) )
dirs . AppendObject ( file ) ;
return NS_NewArrayEnumerator ( result , dirs ) ;
2011-07-21 00:57:07 -07:00
} else if ( ! strcmp ( prop , NS_APP_PREFS_DEFAULTS_DIR_LIST ) ) {
nsCOMArray < nsIFile > dirs ;
nsCOMPtr < nsIFile > file ;
if ( NS_FAILED ( NS_GetSpecialDirectory ( NS_XPCOM_CURRENT_PROCESS_DIR ,
getter_AddRefs ( file ) ) ) | |
NS_FAILED ( file - > AppendNative ( NS_LITERAL_CSTRING ( " defaults " ) ) ) | |
NS_FAILED ( file - > AppendNative ( NS_LITERAL_CSTRING ( " preferences " ) ) ) )
return NS_ERROR_FAILURE ;
dirs . AppendObject ( file ) ;
return NS_NewArrayEnumerator ( result , dirs ) ;
2009-07-17 07:41:26 -07:00
}
return NS_ERROR_FAILURE ;
}