- Add an environment object, to reflect the shell's environment variables.

- Cleaned up command line argument processing so the arguments object is
  available to all scripts (-f foo.js or the final bar.js non-option arg).
  Also made - work in all cases (-f - or - as the final arg) to mean stdin.
- Miscellaneous formatting and style cleanup.
This commit is contained in:
brendan%mozilla.org 2003-06-13 21:25:10 +00:00
parent 1a8dc91aef
commit e053dfcfc1
2 changed files with 475 additions and 249 deletions

View File

@ -257,8 +257,8 @@ GetLine(JSContext *cx, char *bufp, FILE *file, const char *prompt) {
* another handle. Are other filehandles interactive?
*/
if (file == stdin) {
char *linep;
if ((linep = readline(prompt)) == NULL)
char *linep = readline(prompt);
if (!linep)
return JS_FALSE;
if (linep[0] != '\0')
add_history(linep);
@ -277,7 +277,7 @@ GetLine(JSContext *cx, char *bufp, FILE *file, const char *prompt) {
/* Print a CR after the prompt because MPW grabs the entire line when entering an interactive command */
fputc('\n', gOutFile);
#endif
if (fgets(line, sizeof line, file) == NULL)
if (!fgets(line, sizeof line, file))
return JS_FALSE;
strcpy(bufp, line);
}
@ -297,7 +297,9 @@ Process(JSContext *cx, JSObject *obj, char *filename)
int startline;
FILE *file;
if (filename != NULL && strcmp(filename, "-") != 0) {
if (!filename || strcmp(filename, "-") == 0) {
file = stdin;
} else {
file = fopen(filename, "r");
if (!file) {
JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL,
@ -305,8 +307,6 @@ Process(JSContext *cx, JSObject *obj, char *filename)
gExitCode = EXITCODE_FILE_NOT_FOUND;
return;
}
} else {
file = stdin;
}
if (!isatty(fileno(file))) {
@ -410,101 +410,108 @@ my_BranchCallback(JSContext *cx, JSScript *script)
static int
ProcessArgs(JSContext *cx, JSObject *obj, char **argv, int argc)
{
int i, j;
char *filename = NULL;
jsint length;
jsval *vector;
int i, j, length;
JSObject *argsObj;
char *filename = NULL;
JSBool isInteractive = JS_TRUE;
for (i=0; i < argc; i++) {
if (argv[i][0] == '-') {
switch (argv[i][1]) {
case 'v':
if (i+1 == argc) {
return usage();
}
JS_SetVersion(cx, (JSVersion) atoi(argv[i+1]));
i++;
break;
case 'w':
reportWarnings = JS_TRUE;
break;
case 'W':
reportWarnings = JS_FALSE;
break;
case 's':
JS_ToggleOptions(cx, JSOPTION_STRICT);
break;
case 'b':
gBranchLimit = atoi(argv[++i]);
JS_SetBranchCallback(cx, my_BranchCallback);
break;
case 'c':
/* set stack chunk size */
gStackChunkSize = atoi(argv[++i]);
break;
case 'f':
if (i+1 == argc) {
return usage();
}
filename = argv[i+1];
/* "-f -" means read from stdin */
if (filename[0] == '-' && filename[1] == '\0')
filename = NULL;
Process(cx, obj, filename);
filename = NULL;
/* 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.
*/
isInteractive = JS_FALSE;
i++;
break;
default:
return usage();
}
} else {
filename = argv[i++];
isInteractive = JS_FALSE;
/*
* 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':
++i;
break;
}
}
length = argc - i;
if (length == 0) {
vector = NULL;
} else {
vector = (jsval *) JS_malloc(cx, length * sizeof(jsval));
if (vector == NULL)
return 1;
for (j = 0; j < length; j++) {
JSString *str = JS_NewStringCopyZ(cx, argv[i++]);
if (str == NULL)
return 1;
vector[j] = STRING_TO_JSVAL(str);
}
}
argsObj = JS_NewArrayObject(cx, length, vector);
if (vector)
JS_free(cx, vector);
if (argsObj == NULL)
/*
* 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;
}
length = argc - i;
for (j = 0; j < length; j++) {
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++];
isInteractive = JS_FALSE;
break;
}
switch (argv[i][1]) {
case 'v':
if (++i == argc) {
return usage();
}
JS_SetVersion(cx, (JSVersion) atoi(argv[i]));
break;
case 'w':
reportWarnings = JS_TRUE;
break;
case 'W':
reportWarnings = JS_FALSE;
break;
case 's':
JS_ToggleOptions(cx, JSOPTION_STRICT);
break;
case 'b':
gBranchLimit = atoi(argv[++i]);
JS_SetBranchCallback(cx, my_BranchCallback);
break;
case 'c':
/* set stack chunk size */
gStackChunkSize = atoi(argv[++i]);
break;
case 'f':
if (++i == argc) {
return usage();
}
Process(cx, obj, argv[i]);
/*
* 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.
*/
isInteractive = JS_FALSE;
break;
default:
return usage();
}
}
if (filename || isInteractive)
Process(cx, obj, filename);
return gExitCode;
@ -984,7 +991,7 @@ Disassemble(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
SHOW_FLAG(GETTER);
SHOW_FLAG(BOUND_METHOD);
SHOW_FLAG(HEAVYWEIGHT);
#undef SHOW_FLAG
putchar('\n');
}
@ -1990,13 +1997,115 @@ static JSClass global_class = {
JS_ConvertStub, JS_FinalizeStub
};
static JSBool
env_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
{
JSString *idstr, *valstr;
const char *name, *value;
int rv;
idstr = JS_ValueToString(cx, id);
valstr = JS_ValueToString(cx, *vp);
if (!idstr || !valstr)
return JS_FALSE;
name = JS_GetStringBytes(idstr);
value = JS_GetStringBytes(valstr);
#ifdef XP_WIN
{
char *waste = JS_smprintf("%s=%s", name, value);
if (!waste) {
JS_ReportOutOfMemory(cx);
return JS_FALSE;
}
rv = putenv(waste);
free(waste);
}
#else
rv = setenv(name, value, 1);
#endif
if (rv < 0) {
JS_ReportError(cx, "can't set envariable %s to %s", name, value);
return JS_FALSE;
}
*vp = STRING_TO_JSVAL(valstr);
return JS_TRUE;
}
static JSBool
env_enumerate(JSContext *cx, JSObject *obj)
{
static JSBool reflected;
char **evp, *name, *value;
JSString *valstr;
JSBool ok;
if (reflected)
return JS_TRUE;
for (evp = (char **)JS_GetPrivate(cx, obj); (name = *evp) != NULL; evp++) {
value = strchr(name, '=');
if (!value)
continue;
*value++ = '\0';
valstr = JS_NewStringCopyZ(cx, value);
if (!valstr) {
ok = JS_FALSE;
} else {
ok = JS_DefineProperty(cx, obj, name, STRING_TO_JSVAL(valstr),
NULL, NULL, JSPROP_ENUMERATE);
}
value[-1] = '=';
if (!ok)
return JS_FALSE;
}
reflected = JS_TRUE;
return JS_TRUE;
}
static JSBool
env_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
JSObject **objp)
{
JSString *idstr, *valstr;
const char *name, *value;
if (flags & JSRESOLVE_ASSIGNING)
return JS_TRUE;
idstr = JS_ValueToString(cx, id);
if (!idstr)
return JS_FALSE;
name = JS_GetStringBytes(idstr);
value = getenv(name);
if (value) {
valstr = JS_NewStringCopyZ(cx, value);
if (!valstr)
return JS_FALSE;
if (!JS_DefineProperty(cx, obj, name, STRING_TO_JSVAL(valstr),
NULL, NULL, JSPROP_ENUMERATE)) {
return JS_FALSE;
}
*objp = obj;
}
return JS_TRUE;
}
static JSClass env_class = {
"environment", JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE,
JS_PropertyStub, JS_PropertyStub,
JS_PropertyStub, env_setProperty,
env_enumerate, (JSResolveOp) env_resolve,
JS_ConvertStub, JS_FinalizeStub
};
int
main(int argc, char **argv)
main(int argc, char **argv, char **envp)
{
JSVersion version;
JSRuntime *rt;
JSContext *cx;
JSObject *glob, *it;
JSObject *glob, *it, *envobj;
int result;
#ifdef LIVECONNECT
JavaVM *java_vm = NULL;
@ -2017,41 +2126,41 @@ main(int argc, char **argv)
#ifdef XP_MAC
#ifndef XP_MAC_MPW
initConsole("\pJavaScript Shell", "Welcome to js shell.", &argc, &argv);
initConsole("\pJavaScript Shell", "Welcome to js shell.", &argc, &argv);
#endif
#endif
#ifdef MAC_TEST_HACK
/*
Open a file "testArgs.txt" and read each line into argc/argv.
Re-direct all output to "results.txt"
Open a file "testArgs.txt" and read each line into argc/argv.
Re-direct all output to "results.txt"
*/
{
char argText[256];
FILE *f = fopen("testargs.txt", "r");
if (f != NULL) {
int maxArgs = 32; /* arbitrary max !!! */
int argText_strlen;
argc = 1;
argv = malloc(sizeof(char *) * maxArgs);
argv[0] = NULL;
while (fgets(argText, 255, f) != NULL) {
/* argText includes '\n' */
argText_strlen = strlen(argText);
argv[argc] = malloc(argText_strlen);
strncpy(argv[argc], argText,
argText_strlen - 1);
argv[argc][argText_strlen - 1] = '\0';
argc++;
if (argc >= maxArgs) break;
}
fclose(f);
}
gTestResultFile = fopen("results.txt", "w");
{
char argText[256];
FILE *f = fopen("testargs.txt", "r");
if (f) {
int maxArgs = 32; /* arbitrary max !!! */
int argText_strlen;
argc = 1;
argv = malloc(sizeof(char *) * maxArgs);
argv[0] = NULL;
while (fgets(argText, 255, f)) {
/* argText includes '\n' */
argText_strlen = strlen(argText);
argv[argc] = malloc(argText_strlen);
strncpy(argv[argc], argText, argText_strlen - 1);
argv[argc][argText_strlen - 1] = '\0';
argc++;
if (argc >= maxArgs)
break;
}
fclose(f);
}
gTestResultFile = fopen("results.txt", "w");
}
gErrFile = gTestResultFile;
gOutFile = gTestResultFile;
gErrFile = gTestResultFile;
gOutFile = gTestResultFile;
#endif
version = JSVERSION_DEFAULT;
@ -2130,10 +2239,14 @@ main(int argc, char **argv)
#endif /* JSDEBUGGER */
#ifdef LIVECONNECT
if (!JSJ_SimpleInit(cx, glob, java_vm, getenv("CLASSPATH")))
return 1;
if (!JSJ_SimpleInit(cx, glob, java_vm, getenv("CLASSPATH")))
return 1;
#endif
envobj = JS_DefineObject(cx, glob, "environment", &env_class, NULL, 0);
if (!envobj || !JS_SetPrivate(cx, envobj, envp))
return 1;
result = ProcessArgs(cx, glob, argv, argc);
#ifdef JSDEBUGGER

View File

@ -359,6 +359,108 @@ static JSClass global_class = {
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
};
static JSBool
env_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
{
JSString *idstr, *valstr;
const char *name, *value;
int rv;
idstr = JS_ValueToString(cx, id);
valstr = JS_ValueToString(cx, *vp);
if (!idstr || !valstr)
return JS_FALSE;
name = JS_GetStringBytes(idstr);
value = JS_GetStringBytes(valstr);
#ifdef XP_WIN
{
char *waste = JS_smprintf("%s=%s", name, value);
if (!waste) {
JS_ReportOutOfMemory(cx);
return JS_FALSE;
}
rv = putenv(waste);
free(waste);
}
#else
rv = setenv(name, value, 1);
#endif
if (rv < 0) {
JS_ReportError(cx, "can't set envariable %s to %s", name, value);
return JS_FALSE;
}
*vp = STRING_TO_JSVAL(valstr);
return JS_TRUE;
}
static JSBool
env_enumerate(JSContext *cx, JSObject *obj)
{
static JSBool reflected;
char **evp, *name, *value;
JSString *valstr;
JSBool ok;
if (reflected)
return JS_TRUE;
for (evp = (char **)JS_GetPrivate(cx, obj); (name = *evp) != NULL; evp++) {
value = strchr(name, '=');
if (!value)
continue;
*value++ = '\0';
valstr = JS_NewStringCopyZ(cx, value);
if (!valstr) {
ok = JS_FALSE;
} else {
ok = JS_DefineProperty(cx, obj, name, STRING_TO_JSVAL(valstr),
NULL, NULL, JSPROP_ENUMERATE);
}
value[-1] = '=';
if (!ok)
return JS_FALSE;
}
reflected = JS_TRUE;
return JS_TRUE;
}
static JSBool
env_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
JSObject **objp)
{
JSString *idstr, *valstr;
const char *name, *value;
if (flags & JSRESOLVE_ASSIGNING)
return JS_TRUE;
idstr = JS_ValueToString(cx, id);
if (!idstr)
return JS_FALSE;
name = JS_GetStringBytes(idstr);
value = getenv(name);
if (value) {
valstr = JS_NewStringCopyZ(cx, value);
if (!valstr)
return JS_FALSE;
if (!JS_DefineProperty(cx, obj, name, STRING_TO_JSVAL(valstr),
NULL, NULL, JSPROP_ENUMERATE)) {
return JS_FALSE;
}
*objp = obj;
}
return JS_TRUE;
}
static JSClass env_class = {
"environment", JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE,
JS_PropertyStub, JS_PropertyStub,
JS_PropertyStub, env_setProperty,
env_enumerate, (JSResolveOp) env_resolve,
JS_ConvertStub, JS_FinalizeStub
};
/***************************************************************************/
typedef enum JSShellErrNum {
@ -399,15 +501,15 @@ extern void add_history(char *line);
#endif
static JSBool
GetLine(JSContext *cx, char *bufp, FILE *fh, const char *prompt) {
GetLine(JSContext *cx, char *bufp, FILE *file, const char *prompt) {
#ifdef EDITLINE
/*
* Use readline only if fh is stdin, because there's no way to specify
* Use readline only if file is stdin, because there's no way to specify
* another handle. Are other filehandles interactive?
*/
if (fh == stdin) {
char *linep;
if ((linep = readline(prompt)) == NULL)
if (file == stdin) {
char *linep = readline(prompt);
if (!linep)
return JS_FALSE;
if (*linep)
add_history(linep);
@ -422,7 +524,7 @@ GetLine(JSContext *cx, char *bufp, FILE *fh, const char *prompt) {
char line[256];
fprintf(gOutFile, prompt);
fflush(gOutFile);
if (fgets(line, 256, fh) == NULL)
if (!fgets(line, sizeof line, file))
return JS_FALSE;
strcpy(bufp, line);
}
@ -430,32 +532,16 @@ GetLine(JSContext *cx, char *bufp, FILE *fh, const char *prompt) {
}
static void
Process(JSContext *cx, JSObject *obj, char *filename, FILE *filehandle)
ProcessFile(JSContext *cx, JSObject *obj, const char *filename, FILE *file)
{
JSBool ok, hitEOF;
JSScript *script;
jsval result;
int lineno, startline;
JSBool ok, hitEOF;
char *bufp, buffer[4096];
JSString *str;
char buffer[4098];
char *bufp;
int lineno;
int startline;
FILE *fh;
if (filename != NULL && strcmp(filename, "-") != 0) {
fh = fopen(filename, "r");
if (!fh) {
JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL,
JSSMSG_CANT_OPEN,
filename, strerror(errno));
gExitCode = EXITCODE_FILE_NOT_FOUND;
return;
}
} else {
fh = filehandle;
}
if (!isatty(fileno(fh))) {
if (!isatty(fileno(file))) {
/*
* It's not interactive - just execute it.
*
@ -464,16 +550,16 @@ Process(JSContext *cx, JSObject *obj, char *filename, FILE *filehandle)
* as a legal js program (using sharp variables) might start with '#'.
* But that would require multi-character lookahead.
*/
int ch = fgetc(fh);
int ch = fgetc(file);
if (ch == '#') {
while((ch = fgetc(fh)) != EOF) {
while((ch = fgetc(file)) != EOF) {
if(ch == '\n' || ch == '\r')
break;
}
}
ungetc(ch, fh);
ungetc(ch, file);
DoBeginRequest(cx);
script = JS_CompileFileHandle(cx, obj, filename, fh);
script = JS_CompileFileHandle(cx, obj, filename, file);
if (script) {
(void)JS_ExecuteScript(cx, obj, script, &result);
JS_DestroyScript(cx, script);
@ -497,7 +583,7 @@ Process(JSContext *cx, JSObject *obj, char *filename, FILE *filehandle)
*/
startline = lineno;
do {
if (!GetLine(cx, bufp, fh, startline == lineno ? "js> " : "")) {
if (!GetLine(cx, bufp, file, startline == lineno ? "js> " : "")) {
hitEOF = JS_TRUE;
break;
}
@ -548,6 +634,27 @@ Process(JSContext *cx, JSObject *obj, char *filename, FILE *filehandle)
return;
}
static void
Process(JSContext *cx, JSObject *obj, const char *filename)
{
FILE *file;
if (!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);
}
static int
usage(void)
{
@ -559,99 +666,102 @@ usage(void)
static int
ProcessArgs(JSContext *cx, JSObject *obj, char **argv, int argc)
{
int i;
char *filename = NULL;
FILE *filehandle = NULL;
jsint length;
jsval *vector;
jsval *p;
const char rcfilename[] = "xpcshell.js";
FILE *rcfile;
int i, j, length;
JSObject *argsObj;
char *filename = NULL;
JSBool isInteractive = JS_TRUE;
filehandle = fopen("xpcshell.js", "r");
if (filehandle != NULL) {
printf("[loading 'xpcshell.js'...]\n");
Process(cx, obj, NULL, filehandle);
// evidently JS closes this for us.
// fclose(filehandle);
rcfile = fopen(rcfilename, "r");
if (rcfile) {
printf("[loading '%s'...]\n", rcfilename);
ProcessFile(cx, obj, rcfilename, rcfile);
}
for (i=0; i < argc; i++) {
if (argv[i][0] == '-') {
switch (argv[i][1]) {
case 'v':
if (i+1 == argc) {
return usage();
}
JS_SetVersion(cx, JSVersion(atoi(argv[i+1])));
i++;
break;
case 'W':
reportWarnings = JS_FALSE;
break;
case 'w':
reportWarnings = JS_TRUE;
break;
case 's':
JS_ToggleOptions(cx, JSOPTION_STRICT);
break;
case 'f':
if (i+1 == argc) {
return usage();
}
filename = argv[i+1];
/* "-f -" means read from stdin */
if (filename[0] == '-' && filename[1] == '\0')
filename = NULL;
Process(cx, obj, filename, NULL);
filename = NULL;
/* 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.
*/
isInteractive = JS_FALSE;
i++;
break;
default:
return usage();
}
} else {
filename = argv[i++];
isInteractive = JS_FALSE;
/*
* 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':
++i;
break;
}
}
/*
* 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;
}
length = argc - i;
if (length == 0) {
vector = NULL;
} else {
vector = (jsval*) JS_malloc(cx, length * sizeof(jsval));
if (vector == NULL)
for (j = 0; j < length; j++) {
JSString *str = JS_NewStringCopyZ(cx, argv[i++]);
if (!str)
return 1;
}
p = vector;
while (i < argc) {
JSString *str = JS_NewStringCopyZ(cx, argv[i]);
if (str == NULL)
if (!JS_DefineElement(cx, argsObj, j, STRING_TO_JSVAL(str),
NULL, NULL, JSPROP_ENUMERATE)) {
return 1;
*p++ = STRING_TO_JSVAL(str);
i++;
}
}
argsObj = JS_NewArrayObject(cx, length, vector);
if (vector) {
JS_free(cx, vector);
}
if (argsObj == NULL)
return 1;
if (!JS_DefineProperty(cx, obj, "arguments",
OBJECT_TO_JSVAL(argsObj), NULL, NULL, 0))
return 1;
for (i = 0; i < argc; i++) {
if (argv[i][0] != '-' || argv[i][1] == '\0') {
filename = argv[i++];
isInteractive = JS_FALSE;
break;
}
switch (argv[i][1]) {
case 'v':
if (++i == argc) {
return usage();
}
JS_SetVersion(cx, JSVersion(atoi(argv[i])));
break;
case 'W':
reportWarnings = JS_FALSE;
break;
case 'w':
reportWarnings = JS_TRUE;
break;
case 's':
JS_ToggleOptions(cx, JSOPTION_STRICT);
break;
case 'f':
if (++i == argc) {
return usage();
}
Process(cx, obj, argv[i]);
/*
* 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.
*/
isInteractive = JS_FALSE;
break;
default:
return usage();
}
}
if (filename || isInteractive)
Process(cx, obj, filename, filename ? NULL : stdin);
Process(cx, obj, filename);
return gExitCode;
}
@ -740,7 +850,6 @@ public:
NS_DECL_NSIXPCSCRIPTABLE
TestGlobal(){}
};
NS_IMPL_ISUPPORTS2(TestGlobal, nsIXPCTestNoisy, nsIXPCScriptable)
@ -810,11 +919,11 @@ nsXPCFunctionThisTranslator::TranslateThis(nsISupports *aInitialThis,
#endif
int
main(int argc, char **argv)
main(int argc, char **argv, char **envp)
{
JSRuntime *rt;
JSContext *jscontext;
JSObject *glob;
JSContext *cx;
JSObject *glob, *envobj;
int result;
nsresult rv;
@ -850,13 +959,13 @@ main(int argc, char **argv)
return 1;
}
jscontext = JS_NewContext(rt, 8192);
if (!jscontext) {
cx = JS_NewContext(rt, 8192);
if (!cx) {
printf("JS_NewContext failed!\n");
return 1;
}
JS_SetErrorReporter(jscontext, my_ErrorReporter);
JS_SetErrorReporter(cx, my_ErrorReporter);
nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID());
if (!xpc) {
@ -871,7 +980,7 @@ main(int argc, char **argv)
// anything, we set the flags to '0' so it ought never get called anyway.
nsCOMPtr<nsIXPCSecurityManager> secman =
NS_STATIC_CAST(nsIXPCSecurityManager*, new FullTrustSecMan());
xpc->SetSecurityManagerForJSContext(jscontext, secman, 0);
xpc->SetSecurityManagerForJSContext(cx, secman, 0);
// xpc->SetCollectGarbageOnMainThreadOnly(PR_TRUE);
// xpc->SetDeferReleasesUntilAfterGarbageCollection(PR_TRUE);
@ -888,25 +997,29 @@ main(int argc, char **argv)
return 1;
}
if(NS_FAILED(cxstack->Push(jscontext))) {
if(NS_FAILED(cxstack->Push(cx))) {
printf("failed to push the current JSContext on the nsThreadJSContextStack!\n");
return 1;
}
glob = JS_NewObject(jscontext, &global_class, NULL, NULL);
glob = JS_NewObject(cx, &global_class, NULL, NULL);
if (!glob)
return 1;
if (!JS_InitStandardClasses(jscontext, glob))
if (!JS_InitStandardClasses(cx, glob))
return 1;
if (!JS_DefineFunctions(jscontext, glob, glob_functions))
if (!JS_DefineFunctions(cx, glob, glob_functions))
return 1;
if (NS_FAILED(xpc->InitClasses(jscontext, glob)))
if (NS_FAILED(xpc->InitClasses(cx, glob)))
return 1;
envobj = JS_DefineObject(cx, glob, "environment", &env_class, NULL, 0);
if (!envobj || !JS_SetPrivate(cx, envobj, envp))
return 1;
argc--;
argv++;
result = ProcessArgs(jscontext, glob, argv, argc);
result = ProcessArgs(cx, glob, argv, argc);
#ifdef TEST_InitClassesWithNewWrappedGlobal
@ -928,18 +1041,18 @@ main(int argc, char **argv)
#ifdef TEST_CALL_ON_WRAPPED_JS_AFTER_SHUTDOWN
// test of late call and release (see below)
nsCOMPtr<nsIJSContextStack> bogus;
xpc->WrapJS(jscontext, glob, NS_GET_IID(nsIJSContextStack),
xpc->WrapJS(cx, glob, NS_GET_IID(nsIJSContextStack),
(void**) getter_AddRefs(bogus));
#endif
JS_ClearScope(jscontext, glob);
JS_GC(jscontext);
JS_ClearScope(cx, glob);
JS_GC(cx);
JSContext *oldcx;
cxstack->Pop(&oldcx);
NS_ASSERTION(oldcx == jscontext, "JS thread context push/pop mismatch");
NS_ASSERTION(oldcx == cx, "JS thread context push/pop mismatch");
cxstack = nsnull;
JS_GC(jscontext);
JS_DestroyContext(jscontext);
JS_GC(cx);
JS_DestroyContext(cx);
xpc->SyncJSContexts();
} // this scopes the nsCOMPtrs
// no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM