mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Backed out 10 changesets (bug 889911, bug 889714) due to merge conflicts on a CLOSED TREE.
Backed out changeset 1a1a536121da (bug 889714) Backed out changeset 2cd88ef9eea5 (bug 889714) Backed out changeset 489723887eca (bug 889714) Backed out changeset 2b38ce22cf97 (bug 889714) Backed out changeset 87b0a59a5d51 (bug 889714) Backed out changeset 13229bab2ba4 (bug 889714) Backed out changeset 234bd6d1fbed (bug 889714) Backed out changeset 4f5f62284917 (bug 889714) Backed out changeset 18537c4436c7 (bug 889911) Backed out changeset ca7060ab1588 (bug 889911)
This commit is contained in:
parent
30246b6267
commit
ec49bf763f
@ -1,5 +1,4 @@
|
||||
/* vim: set ts=8 sts=4 et sw=4 tw=80:
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
@ -46,11 +45,12 @@
|
||||
#include "TestShellChild.h"
|
||||
#include "TestShellParent.h"
|
||||
|
||||
#define EXITCODE_RUNTIME_ERROR 3
|
||||
#define EXITCODE_FILE_NOT_FOUND 4
|
||||
|
||||
using mozilla::ipc::XPCShellEnvironment;
|
||||
using mozilla::ipc::TestShellChild;
|
||||
using mozilla::ipc::TestShellParent;
|
||||
using mozilla::AutoSafeJSContext;
|
||||
using namespace JS;
|
||||
|
||||
namespace {
|
||||
|
||||
@ -73,17 +73,123 @@ private:
|
||||
};
|
||||
|
||||
inline XPCShellEnvironment*
|
||||
Environment(JSObject* global)
|
||||
Environment(JSContext* cx)
|
||||
{
|
||||
AutoSafeJSContext cx;
|
||||
JSAutoCompartment ac(cx, global);
|
||||
Rooted<Value> v(cx);
|
||||
if (!JS_GetProperty(cx, global, "__XPCShellEnvironment", v.address()) ||
|
||||
!v.get().isDouble())
|
||||
{
|
||||
return nullptr;
|
||||
XPCShellEnvironment* env =
|
||||
static_cast<XPCShellEnvironment*>(JS_GetContextPrivate(cx));
|
||||
NS_ASSERTION(env, "Should never be null!");
|
||||
return env;
|
||||
}
|
||||
|
||||
static void
|
||||
ScriptErrorReporter(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;
|
||||
}
|
||||
return static_cast<XPCShellEnvironment*>(v.get().toPrivate());
|
||||
|
||||
// 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(stderr, "%s\n", message);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Conditionally ignore reported warnings. */
|
||||
if (JSREPORT_IS_WARNING(report->flags) &&
|
||||
!Environment(cx)->ShouldReportWarnings()) {
|
||||
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, stderr);
|
||||
fwrite(message, 1, ctmp - message, stderr);
|
||||
message = ctmp;
|
||||
}
|
||||
/* If there were no filename or lineno, the prefix might be empty */
|
||||
if (prefix)
|
||||
fputs(prefix, stderr);
|
||||
fputs(message, stderr);
|
||||
|
||||
if (!report->linebuf) {
|
||||
fputc('\n', stderr);
|
||||
goto out;
|
||||
}
|
||||
|
||||
fprintf(stderr, ":\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('.', stderr);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
fputc('.', stderr);
|
||||
j++;
|
||||
}
|
||||
fputs("^\n", stderr);
|
||||
out:
|
||||
if (!JSREPORT_IS_WARNING(report->flags)) {
|
||||
Environment(cx)->SetExitCode(EXITCODE_RUNTIME_ERROR);
|
||||
}
|
||||
JS_free(cx, prefix);
|
||||
}
|
||||
|
||||
JSContextCallback gOldContextCallback = NULL;
|
||||
|
||||
static JSBool
|
||||
ContextCallback(JSContext *cx,
|
||||
unsigned contextOp)
|
||||
{
|
||||
if (gOldContextCallback && !gOldContextCallback(cx, contextOp))
|
||||
return JS_FALSE;
|
||||
|
||||
if (contextOp == JSCONTEXT_NEW) {
|
||||
JS_SetErrorReporter(cx, ScriptErrorReporter);
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
@ -177,14 +283,15 @@ Load(JSContext *cx,
|
||||
JS::CompileOptions options(cx);
|
||||
options.setUTF8(true)
|
||||
.setFileAndLine(filename.ptr(), 1)
|
||||
.setPrincipals(Environment(JS_GetGlobalForScopeChain(cx))->GetPrincipal());
|
||||
.setPrincipals(Environment(cx)->GetPrincipal());
|
||||
JS::RootedObject rootedObj(cx, obj);
|
||||
JSScript *script = JS::Compile(cx, rootedObj, options, file);
|
||||
fclose(file);
|
||||
if (!script)
|
||||
return JS_FALSE;
|
||||
|
||||
if (!JS_ExecuteScript(cx, obj, script, result.address())) {
|
||||
if (!Environment(cx)->ShouldCompileOnly() &&
|
||||
!JS_ExecuteScript(cx, obj, script, result.address())) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
@ -217,7 +324,11 @@ Quit(JSContext *cx,
|
||||
unsigned argc,
|
||||
JS::Value *vp)
|
||||
{
|
||||
XPCShellEnvironment* env = Environment(JS_GetGlobalForScopeChain(cx));
|
||||
int exitCode = 0;
|
||||
JS_ConvertArguments(cx, argc, JS_ARGV(cx, vp), "/ i", &exitCode);
|
||||
|
||||
XPCShellEnvironment* env = Environment(cx);
|
||||
env->SetExitCode(exitCode);
|
||||
env->SetIsQuitting();
|
||||
|
||||
return JS_FALSE;
|
||||
@ -392,16 +503,16 @@ typedef enum JSShellErrNum
|
||||
#undef MSGDEF
|
||||
} JSShellErrNum;
|
||||
|
||||
} /* anonymous namespace */
|
||||
|
||||
void
|
||||
XPCShellEnvironment::ProcessFile(JSContext *cx,
|
||||
JS::Handle<JSObject*> obj,
|
||||
const char *filename,
|
||||
FILE *file,
|
||||
JSBool forceTTY)
|
||||
static void
|
||||
ProcessFile(JSContext *cx,
|
||||
JS::Handle<JSObject*> obj,
|
||||
const char *filename,
|
||||
FILE *file,
|
||||
JSBool forceTTY)
|
||||
{
|
||||
XPCShellEnvironment* env = this;
|
||||
XPCShellEnvironment* env = Environment(cx);
|
||||
nsCxPusher pusher;
|
||||
pusher.Push(env->GetContext());
|
||||
|
||||
JSScript *script;
|
||||
JS::Rooted<JS::Value> result(cx);
|
||||
@ -443,7 +554,7 @@ XPCShellEnvironment::ProcessFile(JSContext *cx,
|
||||
.setFileAndLine(filename, 1)
|
||||
.setPrincipals(env->GetPrincipal());
|
||||
JSScript* script = JS::Compile(cx, obj, options, file);
|
||||
if (script)
|
||||
if (script && !env->ShouldCompileOnly())
|
||||
(void)JS_ExecuteScript(cx, obj, script, result.address());
|
||||
|
||||
return;
|
||||
@ -483,20 +594,22 @@ XPCShellEnvironment::ProcessFile(JSContext *cx,
|
||||
if (script) {
|
||||
JSErrorReporter older;
|
||||
|
||||
ok = JS_ExecuteScript(cx, obj, script, result.address());
|
||||
if (ok && result != JSVAL_VOID) {
|
||||
/* Suppress error reports from JS_ValueToString(). */
|
||||
older = JS_SetErrorReporter(cx, NULL);
|
||||
str = JS_ValueToString(cx, result);
|
||||
JSAutoByteString bytes;
|
||||
if (str)
|
||||
bytes.encodeLatin1(cx, str);
|
||||
JS_SetErrorReporter(cx, older);
|
||||
if (!env->ShouldCompileOnly()) {
|
||||
ok = JS_ExecuteScript(cx, obj, script, result.address());
|
||||
if (ok && result != JSVAL_VOID) {
|
||||
/* Suppress error reports from JS_ValueToString(). */
|
||||
older = JS_SetErrorReporter(cx, NULL);
|
||||
str = JS_ValueToString(cx, result);
|
||||
JSAutoByteString bytes;
|
||||
if (str)
|
||||
bytes.encodeLatin1(cx, str);
|
||||
JS_SetErrorReporter(cx, older);
|
||||
|
||||
if (!!bytes)
|
||||
fprintf(stdout, "%s\n", bytes.ptr());
|
||||
else
|
||||
ok = JS_FALSE;
|
||||
if (!!bytes)
|
||||
fprintf(stdout, "%s\n", bytes.ptr());
|
||||
else
|
||||
ok = JS_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (!hitEOF && !env->IsQuitting());
|
||||
@ -504,6 +617,8 @@ XPCShellEnvironment::ProcessFile(JSContext *cx,
|
||||
fprintf(stdout, "\n");
|
||||
}
|
||||
|
||||
} /* anonymous namespace */
|
||||
|
||||
NS_IMETHODIMP_(nsrefcnt)
|
||||
XPCShellDirProvider::AddRef()
|
||||
{
|
||||
@ -552,24 +667,41 @@ XPCShellEnvironment::CreateEnvironment()
|
||||
}
|
||||
|
||||
XPCShellEnvironment::XPCShellEnvironment()
|
||||
: mQuitting(JS_FALSE)
|
||||
: mCx(NULL),
|
||||
mJSPrincipals(NULL),
|
||||
mExitCode(0),
|
||||
mQuitting(JS_FALSE),
|
||||
mReportWarnings(JS_TRUE),
|
||||
mCompileOnly(JS_FALSE)
|
||||
{
|
||||
}
|
||||
|
||||
XPCShellEnvironment::~XPCShellEnvironment()
|
||||
{
|
||||
if (mCx) {
|
||||
JS_BeginRequest(mCx);
|
||||
|
||||
AutoSafeJSContext cx;
|
||||
JSObject* global = GetGlobalObject();
|
||||
if (global) {
|
||||
{
|
||||
JSAutoCompartment ac(cx, global);
|
||||
JS_SetAllNonReservedSlotsToUndefined(cx, global);
|
||||
JSObject* global = GetGlobalObject();
|
||||
if (global) {
|
||||
JS_SetAllNonReservedSlotsToUndefined(mCx, global);
|
||||
}
|
||||
mGlobalHolder.Release();
|
||||
|
||||
JSRuntime *rt = JS_GetRuntime(cx);
|
||||
JSRuntime *rt = JS_GetRuntime(mCx);
|
||||
JS_GC(rt);
|
||||
|
||||
if (mJSPrincipals) {
|
||||
JS_DropPrincipals(rt, mJSPrincipals);
|
||||
}
|
||||
|
||||
JS_EndRequest(mCx);
|
||||
JS_DestroyContext(mCx);
|
||||
|
||||
if (gOldContextCallback) {
|
||||
NS_ASSERTION(rt, "Should never be null!");
|
||||
JS_SetContextCallback(rt, gOldContextCallback);
|
||||
gOldContextCallback = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -602,7 +734,18 @@ XPCShellEnvironment::Init()
|
||||
return false;
|
||||
}
|
||||
|
||||
AutoSafeJSContext cx;
|
||||
gOldContextCallback = JS_SetContextCallback(rt, ContextCallback);
|
||||
|
||||
JSContext *cx = JS_NewContext(rt, 8192);
|
||||
if (!cx) {
|
||||
NS_ERROR("JS_NewContext failed!");
|
||||
|
||||
JS_SetContextCallback(rt, gOldContextCallback);
|
||||
gOldContextCallback = NULL;
|
||||
|
||||
return false;
|
||||
}
|
||||
mCx = cx;
|
||||
|
||||
JS_SetContextPrivate(cx, this);
|
||||
|
||||
@ -620,11 +763,18 @@ XPCShellEnvironment::Init()
|
||||
rv = securityManager->GetSystemPrincipal(getter_AddRefs(principal));
|
||||
if (NS_FAILED(rv)) {
|
||||
fprintf(stderr, "+++ Failed to obtain SystemPrincipal from ScriptSecurityManager service.\n");
|
||||
} else {
|
||||
// fetch the JS principals and stick in a global
|
||||
mJSPrincipals = nsJSPrincipals::get(principal);
|
||||
JS_HoldPrincipals(mJSPrincipals);
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "+++ Failed to get ScriptSecurityManager service, running without principals");
|
||||
}
|
||||
|
||||
nsCxPusher pusher;
|
||||
pusher.Push(mCx);
|
||||
|
||||
nsRefPtr<BackstagePass> backstagePass;
|
||||
rv = NS_NewBackstagePass(getter_AddRefs(backstagePass));
|
||||
if (NS_FAILED(rv)) {
|
||||
@ -651,19 +801,18 @@ XPCShellEnvironment::Init()
|
||||
NS_ERROR("Failed to get global JSObject!");
|
||||
return false;
|
||||
}
|
||||
JSAutoCompartment ac(cx, globalObj);
|
||||
|
||||
backstagePass->SetGlobalObject(globalObj);
|
||||
|
||||
if (!JS_DefineProperty(cx, globalObj, "__XPCShellEnvironment",
|
||||
PRIVATE_TO_JSVAL(this), JS_PropertyStub,
|
||||
JS_StrictPropertyStub,
|
||||
JSPROP_READONLY | JSPROP_PERMANENT) ||
|
||||
!JS_DefineFunctions(cx, globalObj, gGlobalFunctions) ||
|
||||
!JS_DefineProfilingFunctions(cx, globalObj))
|
||||
{
|
||||
NS_ERROR("JS_DefineFunctions failed!");
|
||||
return false;
|
||||
JSAutoRequest ar(cx);
|
||||
JSAutoCompartment ac(cx, globalObj);
|
||||
|
||||
if (!JS_DefineFunctions(cx, globalObj, gGlobalFunctions) ||
|
||||
!JS_DefineProfilingFunctions(cx, globalObj)) {
|
||||
NS_ERROR("JS_DefineFunctions failed!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
mGlobalHolder = globalObj;
|
||||
@ -683,34 +832,43 @@ bool
|
||||
XPCShellEnvironment::EvaluateString(const nsString& aString,
|
||||
nsString* aResult)
|
||||
{
|
||||
AutoSafeJSContext cx;
|
||||
JS::Rooted<JSObject*> global(cx, GetGlobalObject());
|
||||
JSAutoCompartment ac(cx, global);
|
||||
XPCShellEnvironment* env = Environment(mCx);
|
||||
nsCxPusher pusher;
|
||||
pusher.Push(env->GetContext());
|
||||
|
||||
JSAutoRequest ar(mCx);
|
||||
|
||||
JS_ClearPendingException(mCx);
|
||||
|
||||
JS::Rooted<JSObject*> global(mCx, GetGlobalObject());
|
||||
JSAutoCompartment ac(mCx, global);
|
||||
|
||||
JSScript* script =
|
||||
JS_CompileUCScriptForPrincipals(cx, global, GetPrincipal(),
|
||||
JS_CompileUCScriptForPrincipals(mCx, global, GetPrincipal(),
|
||||
aString.get(), aString.Length(),
|
||||
"typein", 0);
|
||||
if (!script) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (aResult) {
|
||||
aResult->Truncate();
|
||||
}
|
||||
if (!ShouldCompileOnly()) {
|
||||
if (aResult) {
|
||||
aResult->Truncate();
|
||||
}
|
||||
|
||||
JS::Rooted<JS::Value> result(cx);
|
||||
JSBool ok = JS_ExecuteScript(cx, global, script, result.address());
|
||||
if (ok && result != JSVAL_VOID) {
|
||||
JSErrorReporter old = JS_SetErrorReporter(cx, NULL);
|
||||
JSString* str = JS_ValueToString(cx, result);
|
||||
nsDependentJSString depStr;
|
||||
if (str)
|
||||
depStr.init(cx, str);
|
||||
JS_SetErrorReporter(cx, old);
|
||||
JS::Rooted<JS::Value> result(mCx);
|
||||
JSBool ok = JS_ExecuteScript(mCx, global, script, result.address());
|
||||
if (ok && result != JSVAL_VOID) {
|
||||
JSErrorReporter old = JS_SetErrorReporter(mCx, NULL);
|
||||
JSString* str = JS_ValueToString(mCx, result);
|
||||
nsDependentJSString depStr;
|
||||
if (str)
|
||||
depStr.init(mCx, str);
|
||||
JS_SetErrorReporter(mCx, old);
|
||||
|
||||
if (!depStr.IsEmpty() && aResult) {
|
||||
aResult->Assign(depStr);
|
||||
if (!depStr.IsEmpty() && aResult) {
|
||||
aResult->Assign(depStr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,8 +14,6 @@
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsDebug.h"
|
||||
#include "nsStringGlue.h"
|
||||
#include "nsJSPrincipals.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
||||
struct JSContext;
|
||||
class JSObject;
|
||||
@ -30,19 +28,28 @@ public:
|
||||
static XPCShellEnvironment* CreateEnvironment();
|
||||
~XPCShellEnvironment();
|
||||
|
||||
void ProcessFile(JSContext *cx, JS::Handle<JSObject*> obj,
|
||||
const char *filename, FILE *file, JSBool forceTTY);
|
||||
bool EvaluateString(const nsString& aString,
|
||||
nsString* aResult = nullptr);
|
||||
|
||||
JSPrincipals* GetPrincipal() {
|
||||
return nsJSPrincipals::get(nsContentUtils::GetSystemPrincipal());
|
||||
return mJSPrincipals;
|
||||
}
|
||||
|
||||
JSObject* GetGlobalObject() {
|
||||
return mGlobalHolder.ToJSObject();
|
||||
}
|
||||
|
||||
JSContext* GetContext() {
|
||||
return mCx;
|
||||
}
|
||||
|
||||
void SetExitCode(int aExitCode) {
|
||||
mExitCode = aExitCode;
|
||||
}
|
||||
int ExitCode() {
|
||||
return mExitCode;
|
||||
}
|
||||
|
||||
void SetIsQuitting() {
|
||||
mQuitting = JS_TRUE;
|
||||
}
|
||||
@ -50,14 +57,33 @@ public:
|
||||
return mQuitting;
|
||||
}
|
||||
|
||||
void SetShouldReportWarnings(JSBool aReportWarnings) {
|
||||
mReportWarnings = aReportWarnings;
|
||||
}
|
||||
JSBool ShouldReportWarnings() {
|
||||
return mReportWarnings;
|
||||
}
|
||||
|
||||
void SetShouldCompoleOnly(JSBool aCompileOnly) {
|
||||
mCompileOnly = aCompileOnly;
|
||||
}
|
||||
JSBool ShouldCompileOnly() {
|
||||
return mCompileOnly;
|
||||
}
|
||||
|
||||
protected:
|
||||
XPCShellEnvironment();
|
||||
bool Init();
|
||||
|
||||
private:
|
||||
JSContext* mCx;
|
||||
nsAutoJSValHolder mGlobalHolder;
|
||||
JSPrincipals* mJSPrincipals;
|
||||
|
||||
int mExitCode;
|
||||
JSBool mQuitting;
|
||||
JSBool mReportWarnings;
|
||||
JSBool mCompileOnly;
|
||||
};
|
||||
|
||||
} /* namespace ipc */
|
||||
|
@ -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::SystemErrorReporterExternal(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;
|
||||
}
|
||||
|
@ -222,70 +222,8 @@ nsXPConnect::IsISupportsDescendant(nsIInterfaceInfo* info)
|
||||
return found;
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
}
|
||||
|
||||
NS_EXPORT_(void)
|
||||
xpc::SystemErrorReporterExternal(JSContext *cx, const char *message,
|
||||
JSErrorReport *rep)
|
||||
{
|
||||
return SystemErrorReporter(cx, message, rep);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
|
||||
nsresult
|
||||
nsXPConnect::GetInfoForIID(const nsIID * aIID, nsIInterfaceInfo** info)
|
||||
{
|
||||
|
@ -420,20 +420,6 @@ GetJunkScope();
|
||||
*/
|
||||
nsIGlobalObject *
|
||||
GetJunkScopeGlobal();
|
||||
|
||||
// Error reporter used when there is no associated DOM window on to which to
|
||||
// report errors and warnings.
|
||||
void
|
||||
SystemErrorReporter(JSContext *cx, const char *message, JSErrorReport *rep);
|
||||
|
||||
// We have a separate version that's exported with external linkage for use by
|
||||
// xpcshell, since external linkage on windows changes the signature to make it
|
||||
// incompatible with the JSErrorReporter type, causing JS_SetErrorReporter calls
|
||||
// to fail to compile.
|
||||
NS_EXPORT_(void)
|
||||
SystemErrorReporterExternal(JSContext *cx, const char *message,
|
||||
JSErrorReport *rep);
|
||||
|
||||
} // namespace xpc
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user