Backed out 4 changesets (bug 889911) for Windows bustage.

Backed out changeset 5e55ddfc9dc3 (bug 889911)
Backed out changeset 5e296989dd3d (bug 889911)
Backed out changeset 6e48a408d1de (bug 889911)
Backed out changeset e4ec71ab768f (bug 889911)
This commit is contained in:
Ryan VanderMeulen 2013-07-15 15:28:29 -04:00
parent 46991511ae
commit b8afdbdee5
12 changed files with 163 additions and 133 deletions

View File

@ -45,7 +45,7 @@ interface nsIScriptError : nsIConsoleMessage
* Categories I know about -
* XUL javascript
* content javascript (both of these from nsDocShell, currently)
* system javascript (errors in JS components and other system JS)
* component javascript (errors in JS components)
*/
readonly attribute string category;

View File

@ -123,6 +123,61 @@ static PRLogModuleInfo *gJSCLLog;
#define ERROR_GETTING_SYMBOL "%s - Could not get symbol '%s'."
#define ERROR_SETTING_SYMBOL "%s - Could not set symbol '%s' on target object."
void
mozJSLoaderErrorReporter(JSContext *cx, const char *message, JSErrorReport *rep)
{
nsresult rv;
/* Use the console service to register the error. */
nsCOMPtr<nsIConsoleService> consoleService =
do_GetService(NS_CONSOLESERVICE_CONTRACTID);
/*
* Make an nsIScriptError, populate it with information from this
* error, then log it with the console service. The UI can then
* poll the service to update the Error console.
*/
nsCOMPtr<nsIScriptError> errorObject =
do_CreateInstance(NS_SCRIPTERROR_CONTRACTID);
if (consoleService && errorObject) {
uint32_t column = rep->uctokenptr - rep->uclinebuf;
const PRUnichar* ucmessage =
static_cast<const PRUnichar*>(rep->ucmessage);
const PRUnichar* uclinebuf =
static_cast<const PRUnichar*>(rep->uclinebuf);
rv = errorObject->Init(
ucmessage ? nsDependentString(ucmessage) : EmptyString(),
NS_ConvertASCIItoUTF16(rep->filename),
uclinebuf ? nsDependentString(uclinebuf) : EmptyString(),
rep->lineno, column, rep->flags,
"component javascript");
if (NS_SUCCEEDED(rv)) {
rv = consoleService->LogMessage(errorObject);
if (NS_SUCCEEDED(rv)) {
// We're done! Skip return to fall thru to stderr
// printout, for the benefit of those invoking the
// browser with -console
// return;
}
}
}
/*
* If any of the above fails for some reason, fall back to
* printing to stderr.
*/
#ifdef DEBUG
fprintf(stderr, "JS Component Loader: %s %s:%d\n"
" %s\n",
JSREPORT_IS_WARNING(rep->flags) ? "WARNING" : "ERROR",
rep->filename, rep->lineno,
message ? message : "<no message>");
#endif
}
static JSBool
Dump(JSContext *cx, unsigned argc, jsval *vp)
{
@ -515,7 +570,7 @@ mozJSComponentLoader::LoadModule(FileLocation &aFile)
return NULL;
}
JSCLAutoErrorReporterSetter aers(cx, xpc::SystemErrorReporter);
JSCLAutoErrorReporterSetter aers(cx, mozJSLoaderErrorReporter);
RootedValue NSGetFactory_val(cx);
if (!JS_GetProperty(cx, entry->obj, "NSGetFactory", NSGetFactory_val.address()) ||
@ -766,7 +821,7 @@ mozJSComponentLoader::ObjectForLocation(nsIFile *aComponentFile,
JS_AbortIfWrongThread(JS_GetRuntime(cx));
JSCLAutoErrorReporterSetter aers(cx, xpc::SystemErrorReporter);
JSCLAutoErrorReporterSetter aers(cx, mozJSLoaderErrorReporter);
bool realFile = false;
RootedObject obj(cx, PrepareObjectForLocation(cx, aComponentFile, aURI,

View File

@ -50,6 +50,10 @@ using namespace JS;
#define LOAD_ERROR_NOSPEC "Failed to get URI spec. This is bad."
#define LOAD_ERROR_CONTENTTOOBIG "ContentLength is too large"
// We just use the same reporter as the component loader
extern void
mozJSLoaderErrorReporter(JSContext *cx, const char *message, JSErrorReport *rep);
mozJSSubScriptLoader::mozJSSubScriptLoader() : mSystemPrincipal(nullptr)
{
// Force construction of the JS component loader. We may need it later.
@ -119,7 +123,7 @@ mozJSSubScriptLoader::ReadScript(nsIURI *uri, JSContext *cx, JSObject *targetObj
/* set our own error reporter so we can report any bad things as catchable
* exceptions, including the source/line number */
er = JS_SetErrorReporter(cx, xpc::SystemErrorReporter);
er = JS_SetErrorReporter(cx, mozJSLoaderErrorReporter);
JS::CompileOptions options(cx);
options.setPrincipals(nsJSPrincipals::get(principal))

View File

@ -139,7 +139,6 @@ FILE *gErrFile = NULL;
FILE *gInFile = NULL;
int gExitCode = 0;
bool gIgnoreReportedErrors = false;
JSBool gQuitting = false;
static JSBool reportWarnings = true;
static JSBool compileOnly = false;
@ -267,6 +266,97 @@ GetLine(JSContext *cx, char *bufp, FILE *file, const char *prompt) {
return true;
}
static void
my_ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)
{
int i, j, k, n;
char *prefix = NULL, *tmp;
const char *ctmp;
nsCOMPtr<nsIXPConnect> xpc;
// Don't report an exception from inner JS frames as the callers may intend
// to handle it.
if (JS_DescribeScriptedCaller(cx, nullptr, nullptr)) {
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 = nullptr;
xpc->GetCurrentNativeCallContext(&cc);
if (cc) {
nsAXPCNativeCallContext *prev = cc;
while (NS_SUCCEEDED(prev->GetPreviousCallContext(&prev)) && prev) {
uint16_t lang;
if (NS_SUCCEEDED(prev->GetLanguage(&lang)) &&
lang == nsAXPCNativeCallContext::LANG_JS) {
return;
}
}
}
}
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);
}
static JSBool
ReadLine(JSContext *cx, unsigned argc, jsval *vp)
{
@ -428,21 +518,6 @@ Quit(JSContext *cx, unsigned argc, jsval *vp)
return false;
}
// Provide script a way to disable the xpcshell error reporter, preventing
// reported errors from being logged to the console and also from affecting the
// exit code returned by the xpcshell binary.
static JSBool
IgnoreReportedErrors(JSContext *cx, unsigned argc, jsval *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
if (argc != 1 || !args[0].isBoolean()) {
JS_ReportError(cx, "Bad arguments");
return false;
}
gIgnoreReportedErrors = args[0].toBoolean();
return true;
}
static JSBool
DumpXPC(JSContext *cx, unsigned argc, jsval *vp)
{
@ -817,7 +892,6 @@ static const JSFunctionSpec glob_functions[] = {
JS_FS("readline", ReadLine, 1,0),
JS_FS("load", Load, 1,0),
JS_FS("quit", Quit, 0,0),
JS_FS("ignoreReportedErrors", IgnoreReportedErrors, 1,0),
JS_FS("version", Version, 1,0),
JS_FS("build", BuildDate, 0,0),
JS_FS("dumpXPC", DumpXPC, 1,0),
@ -1304,7 +1378,6 @@ ProcessArgs(JSContext *cx, JS::Handle<JSObject*> obj, char **argv, int argc, XPC
if (filename || isInteractive)
Process(cx, obj, filename, forceTTY);
return gExitCode;
}
@ -1389,19 +1462,6 @@ nsXPCFunctionThisTranslator::TranslateThis(nsISupports *aInitialThis,
// ContextCallback calls are chained
static JSContextCallback gOldJSContextCallback;
void
XPCShellErrorReporter(JSContext *cx, const char *message, JSErrorReport *rep)
{
if (gIgnoreReportedErrors)
return;
if (!JSREPORT_IS_WARNING(rep->flags))
gExitCode = EXITCODE_RUNTIME_ERROR;
// Delegate to the system error reporter for heavy lifting.
xpc::SystemErrorReporter(cx, message, rep);
}
static JSBool
ContextCallback(JSContext *cx, unsigned contextOp)
{
@ -1409,7 +1469,7 @@ ContextCallback(JSContext *cx, unsigned contextOp)
return false;
if (contextOp == JSCONTEXT_NEW) {
JS_SetErrorReporter(cx, XPCShellErrorReporter);
JS_SetErrorReporter(cx, my_ErrorReporter);
}
return true;
}

View File

@ -129,6 +129,11 @@ static JSClass global_class = {
NULL, NULL, NULL, NULL, TraceXPCGlobal
};
// We just use the same reporter as the component loader
// XXX #include angels cry.
extern void
mozJSLoaderErrorReporter(JSContext *cx, const char *message, JSErrorReport *rep);
JSContext*
XPCJSContextStack::GetSafeJSContext()
{
@ -153,7 +158,7 @@ XPCJSContextStack::GetSafeJSContext()
JSAutoRequest req(mSafeJSContext);
JS::RootedObject glob(mSafeJSContext);
JS_SetErrorReporter(mSafeJSContext, xpc::SystemErrorReporter);
JS_SetErrorReporter(mSafeJSContext, mozJSLoaderErrorReporter);
JS::CompartmentOptions options;
options.setZone(JS::SystemZone);

View File

@ -222,62 +222,8 @@ nsXPConnect::IsISupportsDescendant(nsIInterfaceInfo* info)
return found;
}
NS_EXPORT_(void)
xpc::SystemErrorReporter(JSContext *cx, const char *message, JSErrorReport *rep)
{
// It would be nice to assert !JS_DescribeScriptedCaller here, to be sure
// that there isn't any script running that could catch the exception. But
// the JS engine invokes the error reporter directly if someone reports an
// ErrorReport that it doesn't know how to turn into an exception. Arguably
// it should just learn how to throw everything. But either way, if the
// exception is ending here, it's not going to get propagated to a caller,
// so it's up to us to make it known.
nsresult rv;
/* Use the console service to register the error. */
nsCOMPtr<nsIConsoleService> consoleService =
do_GetService(NS_CONSOLESERVICE_CONTRACTID);
/*
* Make an nsIScriptError, populate it with information from this
* error, then log it with the console service.
*/
nsCOMPtr<nsIScriptError> errorObject =
do_CreateInstance(NS_SCRIPTERROR_CONTRACTID);
if (consoleService && errorObject) {
uint32_t column = rep->uctokenptr - rep->uclinebuf;
const PRUnichar* ucmessage =
static_cast<const PRUnichar*>(rep->ucmessage);
const PRUnichar* uclinebuf =
static_cast<const PRUnichar*>(rep->uclinebuf);
rv = errorObject->Init(
ucmessage ? nsDependentString(ucmessage) : EmptyString(),
NS_ConvertASCIItoUTF16(rep->filename),
uclinebuf ? nsDependentString(uclinebuf) : EmptyString(),
rep->lineno, column, rep->flags,
"system javascript");
if (NS_SUCCEEDED(rv))
consoleService->LogMessage(errorObject);
}
/* Log to stderr in debug builds. */
#ifdef DEBUG
fprintf(stderr, "System JS : %s %s:%d\n"
" %s\n",
JSREPORT_IS_WARNING(rep->flags) ? "WARNING" : "ERROR",
rep->filename, rep->lineno,
message ? message : "<no message>");
#endif
}
/***************************************************************************/
nsresult
nsXPConnect::GetInfoForIID(const nsIID * aIID, nsIInterfaceInfo** info)
{

View File

@ -413,12 +413,6 @@ GetNativeForGlobal(JSObject *global);
*/
JSObject *
GetJunkScope();
// Error reporter used when there is no associated DOM window on to which to
// report errors and warnings.
NS_EXPORT_(void)
SystemErrorReporter(JSContext *cx, const char *message, JSErrorReport *rep);
} // namespace xpc
namespace mozilla {

View File

@ -63,10 +63,7 @@ AsyncRunner.prototype = {
},
observe: function AR_consoleServiceListener(msg) {
if (msg instanceof Ci.nsIScriptError &&
!(msg.flags & Ci.nsIScriptError.warningFlag))
{
if (msg instanceof Ci.nsIScriptError)
this._callbacks.consoleError(msg);
}
},
};

View File

@ -151,11 +151,8 @@ AsyncRunner.prototype = {
},
observe: function observe(msg) {
if (msg instanceof Ci.nsIScriptError &&
!(msg.flags & Ci.nsIScriptError.warningFlag))
{
if (msg instanceof Ci.nsIScriptError)
this._callbacks.consoleError(msg);
}
},
};

View File

@ -11,15 +11,6 @@ var gThreadClient;
Components.utils.import('resource:///modules/devtools/SourceMap.jsm');
// Deep in the complicated labyrinth of code that this test invokes, beneath
// debugger callbacks, sandboxes and nested event loops, lies an exception.
// This exception lay sleeping since the dawn of time, held captive in a
// delicate balance of custom xpcshell error reporters and garbage data about
// the XPCCallContext stack. But bholley dug too greedily, and too deep, and
// awoke shadow and flame in the darkness of nsExternalHelperAppService.cpp.
// We must now trust in deep magic to ensure that it does not awaken again.
ignoreReportedErrors(true);
function run_test()
{
initTestDebuggerServer();

View File

@ -11,15 +11,6 @@ var gThreadClient;
Components.utils.import('resource:///modules/devtools/SourceMap.jsm');
// Deep in the complicated labyrinth of code that this test invokes, beneath
// debugger callbacks, sandboxes and nested event loops, lies an exception.
// This exception lay sleeping since the dawn of time, held captive in a
// delicate balance of custom xpcshell error reporters and garbage data about
// the XPCCallContext stack. But bholley dug too greedily, and too deep, and
// awoke shadow and flame in the darkness of nsExternalHelperAppService.cpp.
// We must now trust in deep magic to ensure that it does not awaken again.
ignoreReportedErrors(true);
function run_test()
{
initTestDebuggerServer();

View File

@ -66,22 +66,12 @@ function get_modules_under(uri) {
function load_modules_under(spec, uri) {
var entries = get_modules_under(uri);
// The precompilation of JS here sometimes reports errors, which we don't
// really care about. But if the errors are ever reported to xpcshell's
// error reporter, it will cause it to return an error code, which will break
// automation. Currently they won't be, because the component loader spins up
// its JSContext before xpcshell has time to set its context callback (which
// overrides the error reporter on all newly-created JSContexts). But as we
// move towards a singled-cxed browser, we'll run into this. So let's be
// forward-thinking and deal with it now.
ignoreReportedErrors(true);
for each (let entry in entries) {
try {
dump(spec + entry + "\n");
Cu.import(spec + entry, null);
} catch(e) {}
}
ignoreReportedErrors(false);
}
function resolveResource(spec) {