return (ScriptStatus)ret;
}
protected ScriptStatus runScript(Context cx)
{
ScriptStatus status;
if (scriptObject.getDisplayName() != null) {
try {
Thread.currentThread().setName("Trireme: " + scriptObject.getDisplayName());
} catch (SecurityException ignore) {
}
}
cx.putThreadLocal(RUNNER, this);
now = System.currentTimeMillis();
try {
// All scripts get their own global scope. This is a lot safer than sharing them in case a script wants
// to add to the prototype of String or Date or whatever (as they often do)
// This uses a bit more memory and in theory slows down script startup but in practice it is
// a drop in the bucket.
scope = cx.initStandardObjects();
// Lazy first-time init of the node version.
registry.load(cx);
try {
initGlobals(cx);
} catch (NodeException ne) {
return new ScriptStatus(ne);
} finally {
initialized.countDown();
}
if ((scriptFile == null) && (script == null)) {
// Just have trireme.js process "process.argv"
process.setForceRepl(forceRepl);
setArgv(null);
} else if (scriptFile == null) {
// If the script was passed as a string, pretend that "-e" was used to "eval" it.
// We also get here if we were called by "executeModule".
process.setEval(script);
process.setPrintEval(scriptObject.isPrintEval());
setArgv(scriptFileName);
} else {
// Otherwise, assume that the script was the second argument to "argv".
setArgv(scriptFileName);
}
// Run "trireme.js," which is our equivalent of "node.js". It returns a function that takes
// "process". When done, we may have ticks to execute.
Script mainScript = registry.getMainScript();
Function main = (Function)mainScript.exec(cx, scope);
boolean timing = startTiming(cx);
try {
main.call(cx, scope, scope, new Object[] { process });
} catch (RhinoException re) {
boolean handled = handleScriptException(cx, re);
if (!handled) {
throw re;
}
} finally {
if (timing) {
endTiming(cx);
}
}
status = mainLoop(cx);
} catch (NodeExitException ne) {
// This exception is thrown by process.exit()
status = ne.getStatus();
} catch (IOException ioe) {
log.debug("I/O exception processing script: {}", ioe);
status = new ScriptStatus(ioe);
} catch (Throwable t) {
log.debug("Unexpected script error: {}", t);
status = new ScriptStatus(t);
}
log.debug("Script exiting with exit code {}", status.getExitCode());
if (!status.hasCause() && !process.isExiting()) {
// Fire the exit callback, but only if we aren't exiting due to an unhandled exception, and "exit"
// wasn't already fired because we called "exit"
try {
process.setExiting(true);
process.fireExit(cx, status.getExitCode());
} catch (NodeExitException ee) {
// Exit called exit -- allow it to replace the exit code
log.debug("Script replacing exit code with {}", ee.getCode());
status = ee.getStatus();
} catch (RhinoException re) {
// Many of the unit tests fire exceptions inside exit.
status = new ScriptStatus(re);
}
}
closeCloseables(cx);
try {