mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-26 23:23:33 +00:00
Backed out 10 changesets (bug 1283710) for osx xpcshell failures a=backout
Backed out changeset eb95a12e5d86 (bug 1283710) Backed out changeset f727edc4be48 (bug 1283710) Backed out changeset fed60fbf645d (bug 1283710) Backed out changeset 98339fa564f1 (bug 1283710) Backed out changeset 51b8d69edca0 (bug 1283710) Backed out changeset d72527b7d3c0 (bug 1283710) Backed out changeset ee5215f1a38e (bug 1283710) Backed out changeset dcedbaefe399 (bug 1283710) Backed out changeset 61f8250cbe0b (bug 1283710) Backed out changeset 239382846137 (bug 1283710)
This commit is contained in:
parent
9fd5d0bea3
commit
71f24926ed
@ -332,7 +332,8 @@ AutoJSAPI::~AutoJSAPI()
|
||||
}
|
||||
|
||||
void
|
||||
WarningOnlyErrorReporter(JSContext* aCx, JSErrorReport* aRep);
|
||||
WarningOnlyErrorReporter(JSContext* aCx, const char* aMessage,
|
||||
JSErrorReport* aRep);
|
||||
|
||||
void
|
||||
AutoJSAPI::InitInternal(nsIGlobalObject* aGlobalObject, JSObject* aGlobal,
|
||||
@ -519,7 +520,7 @@ AutoJSAPI::Init(nsGlobalWindow* aWindow)
|
||||
// Eventually, SpiderMonkey will have a special-purpose callback for warnings
|
||||
// only.
|
||||
void
|
||||
WarningOnlyErrorReporter(JSContext* aCx, JSErrorReport* aRep)
|
||||
WarningOnlyErrorReporter(JSContext* aCx, const char* aMessage, JSErrorReport* aRep)
|
||||
{
|
||||
MOZ_ASSERT(JSREPORT_IS_WARNING(aRep->flags));
|
||||
if (!NS_IsMainThread()) {
|
||||
@ -533,7 +534,7 @@ WarningOnlyErrorReporter(JSContext* aCx, JSErrorReport* aRep)
|
||||
workers::WorkerPrivate* worker = workers::GetWorkerPrivateFromContext(aCx);
|
||||
MOZ_ASSERT(worker);
|
||||
|
||||
worker->ReportError(aCx, JS::ConstUTF8CharsZ(), aRep);
|
||||
worker->ReportError(aCx, aMessage, aRep);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -545,7 +546,7 @@ WarningOnlyErrorReporter(JSContext* aCx, JSErrorReport* aRep)
|
||||
// DOM Window.
|
||||
win = xpc::AddonWindowOrNull(JS::CurrentGlobalOrNull(aCx));
|
||||
}
|
||||
xpcReport->Init(aRep, nullptr, nsContentUtils::IsCallerChrome(),
|
||||
xpcReport->Init(aRep, aMessage, nsContentUtils::IsCallerChrome(),
|
||||
win ? win->AsInner()->WindowID() : 0);
|
||||
xpcReport->LogToConsole();
|
||||
}
|
||||
@ -585,7 +586,7 @@ AutoJSAPI::ReportException()
|
||||
win = xpc::AddonWindowOrNull(errorGlobal);
|
||||
}
|
||||
nsPIDOMWindowInner* inner = win ? win->AsInner() : nullptr;
|
||||
xpcReport->Init(jsReport.report(), jsReport.toStringResult().c_str(),
|
||||
xpcReport->Init(jsReport.report(), jsReport.message(),
|
||||
nsContentUtils::IsCallerChrome(),
|
||||
inner ? inner->WindowID() : 0);
|
||||
if (inner && jsReport.report()->errorNumber != JSMSG_OUT_OF_MEMORY) {
|
||||
@ -609,7 +610,7 @@ AutoJSAPI::ReportException()
|
||||
// to get hold of it. After we invoke ReportError, clear the exception on
|
||||
// cx(), just in case ReportError didn't.
|
||||
JS_SetPendingException(cx(), exn);
|
||||
worker->ReportError(cx(), jsReport.toStringResult(), jsReport.report());
|
||||
worker->ReportError(cx(), jsReport.message(), jsReport.report());
|
||||
ClearException();
|
||||
}
|
||||
} else {
|
||||
|
@ -1022,8 +1022,7 @@ Promise::ReportRejectedPromise(JSContext* aCx, JS::HandleObject aPromise)
|
||||
bool isChrome = isMainThread ? nsContentUtils::IsSystemPrincipal(nsContentUtils::ObjectPrincipal(aPromise))
|
||||
: GetCurrentThreadWorkerPrivate()->IsChromeWorker();
|
||||
nsGlobalWindow* win = isMainThread ? xpc::WindowGlobalOrNull(aPromise) : nullptr;
|
||||
xpcReport->Init(report.report(), report.toStringResult().c_str(), isChrome,
|
||||
win ? win->AsInner()->WindowID() : 0);
|
||||
xpcReport->Init(report.report(), report.message(), isChrome, win ? win->AsInner()->WindowID() : 0);
|
||||
|
||||
// Now post an event to do the real reporting async
|
||||
NS_DispatchToMainThread(new AsyncErrorReporter(xpcReport));
|
||||
@ -2645,8 +2644,7 @@ Promise::MaybeReportRejected()
|
||||
if (exp) {
|
||||
xpcReport->Init(cx, exp, isChrome, windowID);
|
||||
} else {
|
||||
xpcReport->Init(report.report(), report.toStringResult(),
|
||||
isChrome, windowID);
|
||||
xpcReport->Init(report.report(), report.message(), isChrome, windowID);
|
||||
}
|
||||
|
||||
// Now post an event to do the real reporting async
|
||||
|
@ -2094,7 +2094,7 @@ ScriptExecutorRunnable::LogExceptionToConsole(JSContext* aCx,
|
||||
}
|
||||
|
||||
RefPtr<xpc::ErrorReport> xpcReport = new xpc::ErrorReport();
|
||||
xpcReport->Init(report.report(), report.toStringResult().c_str(),
|
||||
xpcReport->Init(report.report(), report.message(),
|
||||
aWorkerPrivate->IsChromeWorker(), aWorkerPrivate->WindowID());
|
||||
|
||||
RefPtr<AsyncErrorReporter> r = new AsyncErrorReporter(xpcReport);
|
||||
|
@ -426,7 +426,7 @@ ExtractErrorValues(JSContext* aCx, JS::Handle<JS::Value> aValue,
|
||||
// this report anywhere.
|
||||
RefPtr<xpc::ErrorReport> report = new xpc::ErrorReport();
|
||||
report->Init(err,
|
||||
"<unknown>", // toString result
|
||||
"<unknown>", // fallback message
|
||||
false, // chrome
|
||||
0); // window ID
|
||||
|
||||
|
@ -86,7 +86,6 @@
|
||||
#include "nsProxyRelease.h"
|
||||
#include "nsQueryObject.h"
|
||||
#include "nsSandboxFlags.h"
|
||||
#include "nsUTF8Utils.h"
|
||||
#include "prthread.h"
|
||||
#include "xpcpublic.h"
|
||||
|
||||
@ -5812,7 +5811,7 @@ WorkerPrivate::NotifyInternal(JSContext* aCx, Status aStatus)
|
||||
}
|
||||
|
||||
void
|
||||
WorkerPrivate::ReportError(JSContext* aCx, JS::ConstUTF8CharsZ aToStringResult,
|
||||
WorkerPrivate::ReportError(JSContext* aCx, const char* aFallbackMessage,
|
||||
JSErrorReport* aReport)
|
||||
{
|
||||
AssertIsOnWorkerThread();
|
||||
@ -5856,19 +5855,13 @@ WorkerPrivate::ReportError(JSContext* aCx, JS::ConstUTF8CharsZ aToStringResult,
|
||||
flags = nsIScriptError::errorFlag | nsIScriptError::exceptionFlag;
|
||||
}
|
||||
|
||||
if (message.IsEmpty() && aToStringResult) {
|
||||
nsDependentCString toStringResult(aToStringResult.c_str());
|
||||
if (!AppendUTF8toUTF16(toStringResult, message, mozilla::fallible)) {
|
||||
if (message.IsEmpty()) {
|
||||
nsDependentCString fallbackMessage(aFallbackMessage);
|
||||
if (!AppendUTF8toUTF16(fallbackMessage, message, mozilla::fallible)) {
|
||||
// Try again, with only a 1 KB string. Do this infallibly this time.
|
||||
// If the user doesn't have 1 KB to spare we're done anyways.
|
||||
uint32_t index = std::min(uint32_t(1024), toStringResult.Length());
|
||||
|
||||
// Drop the last code point that may be cropped.
|
||||
index = RewindToPriorUTF8Codepoint(toStringResult.BeginReading(), index);
|
||||
|
||||
nsDependentCString truncatedToStringResult(aToStringResult.c_str(),
|
||||
index);
|
||||
AppendUTF8toUTF16(truncatedToStringResult, message);
|
||||
nsDependentCString truncatedFallbackMessage(aFallbackMessage, 1024);
|
||||
AppendUTF8toUTF16(truncatedFallbackMessage, message);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,6 @@
|
||||
|
||||
#include "Workers.h"
|
||||
|
||||
#include "js/CharacterEncoding.h"
|
||||
#include "nsIContentPolicy.h"
|
||||
#include "nsIContentSecurityPolicy.h"
|
||||
#include "nsILoadGroup.h"
|
||||
@ -1165,8 +1164,7 @@ public:
|
||||
NotifyInternal(JSContext* aCx, Status aStatus);
|
||||
|
||||
void
|
||||
ReportError(JSContext* aCx, JS::ConstUTF8CharsZ aToStringResult,
|
||||
JSErrorReport* aReport);
|
||||
ReportError(JSContext* aCx, const char* aMessage, JSErrorReport* aReport);
|
||||
|
||||
static void
|
||||
ReportErrorToConsole(const char* aMessage);
|
||||
|
@ -567,8 +567,8 @@ TokenStream::reportStrictModeErrorNumberVA(uint32_t offset, bool strictMode, uns
|
||||
void
|
||||
CompileError::throwError(JSContext* cx)
|
||||
{
|
||||
if (JSREPORT_IS_WARNING(flags)) {
|
||||
CallWarningReporter(cx, this);
|
||||
if (JSREPORT_IS_WARNING(report.flags)) {
|
||||
CallWarningReporter(cx, message, &report);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -583,7 +583,17 @@ CompileError::throwError(JSContext* cx)
|
||||
// as the non-top-level "load", "eval", or "compile" native function
|
||||
// returns false, the top-level reporter will eventually receive the
|
||||
// uncaught exception report.
|
||||
ErrorToException(cx, this, nullptr, nullptr);
|
||||
ErrorToException(cx, message, &report, nullptr, nullptr);
|
||||
}
|
||||
|
||||
CompileError::~CompileError()
|
||||
{
|
||||
js_free((void*)report.linebuf());
|
||||
js_free((void*)report.ucmessage);
|
||||
js_free(message);
|
||||
message = nullptr;
|
||||
|
||||
PodZero(&report);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -605,33 +615,33 @@ TokenStream::reportCompileErrorNumberVA(uint32_t offset, unsigned flags, unsigne
|
||||
return false;
|
||||
CompileError& err = *tempErrPtr;
|
||||
|
||||
err.flags = flags;
|
||||
err.errorNumber = errorNumber;
|
||||
err.filename = filename;
|
||||
err.isMuted = mutedErrors;
|
||||
err.report.flags = flags;
|
||||
err.report.errorNumber = errorNumber;
|
||||
err.report.filename = filename;
|
||||
err.report.isMuted = mutedErrors;
|
||||
if (offset == NoOffset) {
|
||||
err.lineno = 0;
|
||||
err.column = 0;
|
||||
err.report.lineno = 0;
|
||||
err.report.column = 0;
|
||||
} else {
|
||||
err.lineno = srcCoords.lineNum(offset);
|
||||
err.column = srcCoords.columnIndex(offset);
|
||||
err.report.lineno = srcCoords.lineNum(offset);
|
||||
err.report.column = srcCoords.columnIndex(offset);
|
||||
}
|
||||
|
||||
// If we have no location information, try to get one from the caller.
|
||||
bool callerFilename = false;
|
||||
if (offset != NoOffset && !err.filename && cx->isJSContext()) {
|
||||
if (offset != NoOffset && !err.report.filename && cx->isJSContext()) {
|
||||
NonBuiltinFrameIter iter(cx->asJSContext(),
|
||||
FrameIter::FOLLOW_DEBUGGER_EVAL_PREV_LINK,
|
||||
cx->compartment()->principals());
|
||||
if (!iter.done() && iter.filename()) {
|
||||
callerFilename = true;
|
||||
err.filename = iter.filename();
|
||||
err.lineno = iter.computeLine(&err.column);
|
||||
err.report.filename = iter.filename();
|
||||
err.report.lineno = iter.computeLine(&err.report.column);
|
||||
}
|
||||
}
|
||||
|
||||
if (!ExpandErrorArgumentsVA(cx, GetErrorMessage, nullptr, errorNumber,
|
||||
nullptr, ArgumentsAreLatin1, &err, args))
|
||||
if (!ExpandErrorArgumentsVA(cx, GetErrorMessage, nullptr, errorNumber, &err.message,
|
||||
nullptr, ArgumentsAreLatin1, &err.report, args))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -644,7 +654,7 @@ TokenStream::reportCompileErrorNumberVA(uint32_t offset, unsigned flags, unsigne
|
||||
// So we don't even try, leaving report.linebuf and friends zeroed. This
|
||||
// means that any error involving a multi-line token (e.g. an unterminated
|
||||
// multi-line string literal) won't have a context printed.
|
||||
if (offset != NoOffset && err.lineno == lineno && !callerFilename) {
|
||||
if (offset != NoOffset && err.report.lineno == lineno && !callerFilename) {
|
||||
// We show only a portion (a "window") of the line around the erroneous
|
||||
// token -- the first char in the token, plus |windowRadius| chars
|
||||
// before it and |windowRadius - 1| chars after it. This is because
|
||||
@ -682,7 +692,7 @@ TokenStream::reportCompileErrorNumberVA(uint32_t offset, unsigned flags, unsigne
|
||||
if (!linebuf)
|
||||
return false;
|
||||
|
||||
err.initOwnedLinebuf(linebuf.release(), windowLength, offset - windowStart);
|
||||
err.report.initLinebuf(linebuf.release(), windowLength, offset - windowStart);
|
||||
}
|
||||
|
||||
if (cx->isJSContext())
|
||||
|
@ -237,9 +237,18 @@ struct Token
|
||||
}
|
||||
};
|
||||
|
||||
class CompileError : public JSErrorReport {
|
||||
public:
|
||||
struct CompileError {
|
||||
JSErrorReport report;
|
||||
char* message;
|
||||
CompileError() : message(nullptr) {}
|
||||
~CompileError();
|
||||
void throwError(JSContext* cx);
|
||||
|
||||
private:
|
||||
// CompileError owns raw allocated memory, so disable assignment and copying
|
||||
// for safety.
|
||||
void operator=(const CompileError&) = delete;
|
||||
CompileError(const CompileError&) = delete;
|
||||
};
|
||||
|
||||
// Ideally, tokenizing would be entirely independent of context. But the
|
||||
|
@ -43,12 +43,12 @@ checkBool(bool success)
|
||||
}
|
||||
|
||||
/* The warning reporter callback. */
|
||||
void reportWarning(JSContext* cx, JSErrorReport* report)
|
||||
void reportWarning(JSContext* cx, const char* message, JSErrorReport* report)
|
||||
{
|
||||
fprintf(stderr, "%s:%u: %s\n",
|
||||
report->filename ? report->filename : "<no filename>",
|
||||
(unsigned int) report->lineno,
|
||||
report->message().c_str());
|
||||
message);
|
||||
}
|
||||
|
||||
// prologue.py sets a breakpoint on this function; test functions can call it
|
||||
|
@ -307,7 +307,7 @@ Error(JSContext* cx, const char (&input)[N], uint32_t expectedLine,
|
||||
CHECK(report.report()->errorNumber == JSMSG_JSON_BAD_PARSE);
|
||||
|
||||
const char* lineAndColumnASCII = JS_smprintf("line %d column %d", expectedLine, expectedColumn);
|
||||
CHECK(strstr(report.toStringResult().c_str(), lineAndColumnASCII) != nullptr);
|
||||
CHECK(strstr(report.message(), lineAndColumnASCII) != nullptr);
|
||||
js_free((void*)lineAndColumnASCII);
|
||||
|
||||
/* We do not execute JS, so there should be no exception thrown. */
|
||||
|
@ -41,11 +41,11 @@ GetSymbolExceptionType(JSContext* cx)
|
||||
js::ErrorReport report(cx);
|
||||
MOZ_RELEASE_ASSERT(report.init(cx, exn, js::ErrorReport::WithSideEffects));
|
||||
|
||||
if (strcmp(report.toStringResult().c_str(), "uncaught exception: Symbol(Symbol.iterator)") == 0)
|
||||
if (strcmp(report.message(), "uncaught exception: Symbol(Symbol.iterator)") == 0)
|
||||
return SYMBOL_ITERATOR;
|
||||
if (strcmp(report.toStringResult().c_str(), "uncaught exception: Symbol(foo)") == 0)
|
||||
if (strcmp(report.message(), "uncaught exception: Symbol(foo)") == 0)
|
||||
return SYMBOL_FOO;
|
||||
if (strcmp(report.toStringResult().c_str(), "uncaught exception: Symbol()") == 0)
|
||||
if (strcmp(report.message(), "uncaught exception: Symbol()") == 0)
|
||||
return SYMBOL_EMPTY;
|
||||
MOZ_CRASH("Unexpected symbol");
|
||||
}
|
||||
|
@ -298,14 +298,14 @@ class JSAPITest
|
||||
cx = nullptr;
|
||||
}
|
||||
|
||||
static void reportWarning(JSContext* cx, JSErrorReport* report) {
|
||||
static void reportWarning(JSContext* cx, const char* message, JSErrorReport* report) {
|
||||
MOZ_RELEASE_ASSERT(report);
|
||||
MOZ_RELEASE_ASSERT(JSREPORT_IS_WARNING(report->flags));
|
||||
|
||||
fprintf(stderr, "%s:%u:%s\n",
|
||||
report->filename ? report->filename : "<no filename>",
|
||||
(unsigned int) report->lineno,
|
||||
report->message().c_str());
|
||||
message);
|
||||
}
|
||||
|
||||
virtual const JSClass * getGlobalClass() {
|
||||
|
@ -70,7 +70,6 @@
|
||||
#include "js/SliceBudget.h"
|
||||
#include "js/StructuredClone.h"
|
||||
#include "js/UniquePtr.h"
|
||||
#include "js/Utility.h"
|
||||
#include "vm/DateObject.h"
|
||||
#include "vm/Debugger.h"
|
||||
#include "vm/EnvironmentObject.h"
|
||||
@ -6130,45 +6129,15 @@ JS_ErrorFromException(JSContext* cx, HandleObject obj)
|
||||
}
|
||||
|
||||
void
|
||||
JSErrorReport::initBorrowedLinebuf(const char16_t* linebufArg, size_t linebufLengthArg,
|
||||
size_t tokenOffsetArg)
|
||||
JSErrorReport::initLinebuf(const char16_t* linebuf, size_t linebufLength, size_t tokenOffset)
|
||||
{
|
||||
MOZ_ASSERT(linebufArg);
|
||||
MOZ_ASSERT(tokenOffsetArg <= linebufLengthArg);
|
||||
MOZ_ASSERT(linebufArg[linebufLengthArg] == '\0');
|
||||
MOZ_ASSERT(linebuf);
|
||||
MOZ_ASSERT(tokenOffset <= linebufLength);
|
||||
MOZ_ASSERT(linebuf[linebufLength] == '\0');
|
||||
|
||||
linebuf_ = linebufArg;
|
||||
linebufLength_ = linebufLengthArg;
|
||||
tokenOffset_ = tokenOffsetArg;
|
||||
}
|
||||
|
||||
void
|
||||
JSErrorReport::freeLinebuf()
|
||||
{
|
||||
if (ownsLinebuf_ && linebuf_) {
|
||||
js_free((void*)linebuf_);
|
||||
ownsLinebuf_ = false;
|
||||
}
|
||||
linebuf_ = nullptr;
|
||||
}
|
||||
|
||||
JSString*
|
||||
JSErrorReport::newMessageString(JSContext* cx)
|
||||
{
|
||||
if (!message_)
|
||||
return cx->runtime()->emptyString;
|
||||
|
||||
return JS_NewStringCopyUTF8Z(cx, message_);
|
||||
}
|
||||
|
||||
void
|
||||
JSErrorReport::freeMessage()
|
||||
{
|
||||
if (ownsMessage_) {
|
||||
js_free((void*)message_.get());
|
||||
ownsMessage_ = false;
|
||||
}
|
||||
message_ = JS::ConstUTF8CharsZ();
|
||||
linebuf_ = linebuf;
|
||||
linebufLength_ = linebufLength;
|
||||
tokenOffset_ = tokenOffset;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
|
@ -5299,12 +5299,7 @@ JS_ReportAllocationOverflow(JSContext* cx);
|
||||
|
||||
class JSErrorReport
|
||||
{
|
||||
// The (default) error message.
|
||||
// If ownsMessage_ is true, the it is freed in destructor.
|
||||
JS::ConstUTF8CharsZ message_;
|
||||
|
||||
// Offending source line without final '\n'.
|
||||
// If ownsLinebuf__ is true, the buffer is freed in destructor.
|
||||
const char16_t* linebuf_;
|
||||
|
||||
// Number of chars in linebuf_. Does not include trailing '\0'.
|
||||
@ -5316,30 +5311,20 @@ class JSErrorReport
|
||||
public:
|
||||
JSErrorReport()
|
||||
: linebuf_(nullptr), linebufLength_(0), tokenOffset_(0),
|
||||
filename(nullptr), lineno(0), column(0),
|
||||
flags(0), errorNumber(0),
|
||||
exnType(0), isMuted(false),
|
||||
ownsLinebuf_(false), ownsMessage_(false)
|
||||
filename(nullptr), lineno(0), column(0), isMuted(false),
|
||||
flags(0), errorNumber(0), ucmessage(nullptr),
|
||||
exnType(0)
|
||||
{}
|
||||
|
||||
~JSErrorReport() {
|
||||
freeLinebuf();
|
||||
freeMessage();
|
||||
}
|
||||
|
||||
const char* filename; /* source file name, URL, etc., or null */
|
||||
unsigned lineno; /* source line number */
|
||||
unsigned column; /* zero-based column index in line */
|
||||
bool isMuted; /* See the comment in ReadOnlyCompileOptions. */
|
||||
unsigned flags; /* error/warning, etc. */
|
||||
unsigned errorNumber; /* the error number, e.g. see js.msg */
|
||||
const char16_t* ucmessage; /* the (default) error message */
|
||||
int16_t exnType; /* One of the JSExnType constants */
|
||||
bool isMuted : 1; /* See the comment in ReadOnlyCompileOptions. */
|
||||
|
||||
private:
|
||||
bool ownsLinebuf_ : 1;
|
||||
bool ownsMessage_ : 1;
|
||||
|
||||
public:
|
||||
const char16_t* linebuf() const {
|
||||
return linebuf_;
|
||||
}
|
||||
@ -5349,29 +5334,7 @@ class JSErrorReport
|
||||
size_t tokenOffset() const {
|
||||
return tokenOffset_;
|
||||
}
|
||||
void initOwnedLinebuf(const char16_t* linebufArg, size_t linebufLengthArg, size_t tokenOffsetArg) {
|
||||
initBorrowedLinebuf(linebufArg, linebufLengthArg, tokenOffsetArg);
|
||||
ownsLinebuf_ = true;
|
||||
}
|
||||
void initBorrowedLinebuf(const char16_t* linebufArg, size_t linebufLengthArg, size_t tokenOffsetArg);
|
||||
void freeLinebuf();
|
||||
|
||||
const JS::ConstUTF8CharsZ message() const {
|
||||
return message_;
|
||||
}
|
||||
|
||||
void initOwnedMessage(const char* messageArg) {
|
||||
initBorrowedMessage(messageArg);
|
||||
ownsMessage_ = true;
|
||||
}
|
||||
void initBorrowedMessage(const char* messageArg) {
|
||||
MOZ_ASSERT(!message_);
|
||||
message_ = JS::ConstUTF8CharsZ(messageArg, strlen(messageArg));
|
||||
}
|
||||
|
||||
JSString* newMessageString(JSContext* cx);
|
||||
|
||||
void freeMessage();
|
||||
void initLinebuf(const char16_t* linebuf, size_t linebufLength, size_t tokenOffset);
|
||||
};
|
||||
|
||||
/*
|
||||
@ -5397,7 +5360,8 @@ class JSErrorReport
|
||||
|
||||
namespace JS {
|
||||
|
||||
using WarningReporter = void (*)(JSContext* cx, JSErrorReport* report);
|
||||
typedef void
|
||||
(* WarningReporter)(JSContext* cx, const char* message, JSErrorReport* report);
|
||||
|
||||
extern JS_PUBLIC_API(WarningReporter)
|
||||
SetWarningReporter(JSContext* cx, WarningReporter reporter);
|
||||
|
@ -159,8 +159,8 @@ AutoResolving::alreadyStartedSlow() const
|
||||
}
|
||||
|
||||
static void
|
||||
ReportError(JSContext* cx, JSErrorReport* reportp, JSErrorCallback callback,
|
||||
void* userRef)
|
||||
ReportError(JSContext* cx, const char* message, JSErrorReport* reportp,
|
||||
JSErrorCallback callback, void* userRef)
|
||||
{
|
||||
/*
|
||||
* Check the error report, and set a JavaScript-catchable exception
|
||||
@ -176,11 +176,11 @@ ReportError(JSContext* cx, JSErrorReport* reportp, JSErrorCallback callback,
|
||||
}
|
||||
|
||||
if (JSREPORT_IS_WARNING(reportp->flags)) {
|
||||
CallWarningReporter(cx, reportp);
|
||||
CallWarningReporter(cx, message, reportp);
|
||||
return;
|
||||
}
|
||||
|
||||
ErrorToException(cx, reportp, callback, userRef);
|
||||
ErrorToException(cx, message, reportp, callback, userRef);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -321,36 +321,45 @@ bool
|
||||
js::ReportErrorVA(JSContext* cx, unsigned flags, const char* format,
|
||||
ErrorArgumentsType argumentsType, va_list ap)
|
||||
{
|
||||
char* message;
|
||||
char16_t* ucmessage;
|
||||
size_t messagelen;
|
||||
JSErrorReport report;
|
||||
bool warning;
|
||||
|
||||
if (checkReportFlags(cx, &flags))
|
||||
return true;
|
||||
|
||||
UniqueChars message(JS_vsmprintf(format, ap));
|
||||
message = JS_vsmprintf(format, ap);
|
||||
if (!message) {
|
||||
ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
messagelen = strlen(message);
|
||||
|
||||
MOZ_ASSERT_IF(argumentsType == ArgumentsAreASCII, JS::StringIsASCII(message.get()));
|
||||
MOZ_ASSERT_IF(argumentsType == ArgumentsAreASCII, JS::StringIsASCII(message));
|
||||
|
||||
report.flags = flags;
|
||||
report.errorNumber = JSMSG_USER_DEFINED_ERROR;
|
||||
if (argumentsType == ArgumentsAreASCII || argumentsType == ArgumentsAreUTF8) {
|
||||
report.initOwnedMessage(message.release());
|
||||
if (argumentsType == ArgumentsAreASCII || argumentsType == ArgumentsAreLatin1) {
|
||||
ucmessage = InflateString(cx, message, &messagelen);
|
||||
} else {
|
||||
MOZ_ASSERT(argumentsType == ArgumentsAreLatin1);
|
||||
Latin1Chars latin1(message.get(), strlen(message.get()));
|
||||
UTF8CharsZ utf8(JS::CharsToNewUTF8CharsZ(cx, latin1));
|
||||
if (!utf8)
|
||||
return false;
|
||||
report.initOwnedMessage(reinterpret_cast<const char*>(utf8.get()));
|
||||
JS::UTF8Chars utf8(message, messagelen);
|
||||
size_t unused;
|
||||
ucmessage = LossyUTF8CharsToNewTwoByteCharsZ(cx, utf8, &unused).get();
|
||||
}
|
||||
if (!ucmessage) {
|
||||
js_free(message);
|
||||
return false;
|
||||
}
|
||||
report.ucmessage = ucmessage;
|
||||
PopulateReportBlame(cx, &report);
|
||||
|
||||
bool warning = JSREPORT_IS_WARNING(report.flags);
|
||||
warning = JSREPORT_IS_WARNING(report.flags);
|
||||
|
||||
ReportError(cx, &report, nullptr, nullptr);
|
||||
ReportError(cx, message, &report, nullptr, nullptr);
|
||||
js_free(message);
|
||||
js_free(ucmessage);
|
||||
return warning;
|
||||
}
|
||||
|
||||
@ -382,10 +391,14 @@ js::ReportUsageErrorASCII(JSContext* cx, HandleObject callee, const char* msg)
|
||||
}
|
||||
|
||||
bool
|
||||
js::PrintError(JSContext* cx, FILE* file, JS::ConstUTF8CharsZ toStringResult,
|
||||
JSErrorReport* report, bool reportWarnings)
|
||||
js::PrintError(JSContext* cx, FILE* file, const char* message, JSErrorReport* report,
|
||||
bool reportWarnings)
|
||||
{
|
||||
MOZ_ASSERT(report);
|
||||
if (!report) {
|
||||
fprintf(file, "%s\n", message);
|
||||
fflush(file);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Conditionally ignore reported warnings. */
|
||||
if (JSREPORT_IS_WARNING(report->flags) && !reportWarnings)
|
||||
@ -407,8 +420,6 @@ js::PrintError(JSContext* cx, FILE* file, JS::ConstUTF8CharsZ toStringResult,
|
||||
JS_free(cx, tmp);
|
||||
}
|
||||
|
||||
const char* message = toStringResult ? toStringResult.c_str() : report->message().c_str();
|
||||
|
||||
/* embedded newlines -- argh! */
|
||||
const char* ctmp;
|
||||
while ((ctmp = strchr(message, '\n')) != 0) {
|
||||
@ -461,34 +472,38 @@ js::PrintError(JSContext* cx, FILE* file, JS::ConstUTF8CharsZ toStringResult,
|
||||
|
||||
class MOZ_RAII AutoMessageArgs
|
||||
{
|
||||
const char16_t** args_;
|
||||
size_t totalLength_;
|
||||
/* only {0} thru {9} supported */
|
||||
mozilla::Array<const char*, JS::MaxNumErrorArguments> args_;
|
||||
mozilla::Array<size_t, JS::MaxNumErrorArguments> lengths_;
|
||||
uint16_t count_;
|
||||
bool passed_ : 1;
|
||||
bool allocatedElements_ : 1;
|
||||
|
||||
public:
|
||||
AutoMessageArgs()
|
||||
: totalLength_(0), count_(0), allocatedElements_(false)
|
||||
{
|
||||
PodArrayZero(args_);
|
||||
}
|
||||
: args_(nullptr), totalLength_(0), count_(0),
|
||||
passed_(false), allocatedElements_(false)
|
||||
{}
|
||||
|
||||
~AutoMessageArgs()
|
||||
{
|
||||
if (passed_)
|
||||
return;
|
||||
|
||||
if (!args_)
|
||||
return;
|
||||
|
||||
/* free the arguments only if we allocated them */
|
||||
if (allocatedElements_) {
|
||||
uint16_t i = 0;
|
||||
while (i < count_) {
|
||||
if (args_[i])
|
||||
js_free((void*)args_[i]);
|
||||
i++;
|
||||
}
|
||||
while (args_[i])
|
||||
js_free((void*)args_[i++]);
|
||||
}
|
||||
js_free(args_);
|
||||
}
|
||||
|
||||
const char* args(size_t i) const {
|
||||
const char16_t* args(size_t i) const {
|
||||
MOZ_ASSERT(i < count_);
|
||||
return args_[i];
|
||||
}
|
||||
@ -506,50 +521,56 @@ class MOZ_RAII AutoMessageArgs
|
||||
return count_;
|
||||
}
|
||||
|
||||
/* Gather the arguments into an array, and accumulate their sizes. */
|
||||
bool passed() const {
|
||||
return passed_;
|
||||
}
|
||||
|
||||
/*
|
||||
* Gather the arguments into an array, and accumulate their sizes. We
|
||||
* allocate 1 more than necessary and null it out to act as the sentinel
|
||||
* value when we free the pointers later.
|
||||
*/
|
||||
bool init(ExclusiveContext* cx, const char16_t** argsArg, uint16_t countArg,
|
||||
ErrorArgumentsType typeArg, va_list ap) {
|
||||
MOZ_ASSERT(!args_);
|
||||
MOZ_ASSERT(countArg > 0);
|
||||
|
||||
args_ = argsArg;
|
||||
count_ = countArg;
|
||||
|
||||
passed_ = !!args_;
|
||||
if (passed_) {
|
||||
MOZ_ASSERT(!args_[count_]);
|
||||
} else {
|
||||
args_ = cx->pod_malloc<const char16_t*>(count_ + 1);
|
||||
if (!args_)
|
||||
return false;
|
||||
args_[count_] = nullptr;
|
||||
}
|
||||
for (uint16_t i = 0; i < count_; i++) {
|
||||
switch (typeArg) {
|
||||
case ArgumentsAreASCII:
|
||||
case ArgumentsAreUTF8: {
|
||||
MOZ_ASSERT(!argsArg);
|
||||
args_[i] = va_arg(ap, char*);
|
||||
MOZ_ASSERT_IF(typeArg == ArgumentsAreASCII, JS::StringIsASCII(args_[i]));
|
||||
lengths_[i] = strlen(args_[i]);
|
||||
break;
|
||||
}
|
||||
case ArgumentsAreLatin1: {
|
||||
MOZ_ASSERT(!argsArg);
|
||||
const Latin1Char* latin1 = va_arg(ap, Latin1Char*);
|
||||
size_t len = strlen(reinterpret_cast<const char*>(latin1));
|
||||
mozilla::Range<const Latin1Char> range(latin1, len);
|
||||
char* utf8 = JS::CharsToNewUTF8CharsZ(cx, range).c_str();
|
||||
if (!utf8)
|
||||
return false;
|
||||
if (passed_) {
|
||||
lengths_[i] = js_strlen(args_[i]);
|
||||
} else if (typeArg == ArgumentsAreASCII || typeArg == ArgumentsAreLatin1) {
|
||||
const char* charArg = va_arg(ap, char*);
|
||||
size_t charArgLength = strlen(charArg);
|
||||
|
||||
args_[i] = utf8;
|
||||
lengths_[i] = strlen(utf8);
|
||||
allocatedElements_ = true;
|
||||
break;
|
||||
}
|
||||
case ArgumentsAreUnicode: {
|
||||
const char16_t* uc = argsArg ? argsArg[i] : va_arg(ap, char16_t*);
|
||||
size_t len = js_strlen(uc);
|
||||
mozilla::Range<const char16_t> range(uc, len);
|
||||
char* utf8 = JS::CharsToNewUTF8CharsZ(cx, range).c_str();
|
||||
if (!utf8)
|
||||
return false;
|
||||
MOZ_ASSERT_IF(typeArg == ArgumentsAreASCII, JS::StringIsASCII(charArg));
|
||||
|
||||
args_[i] = utf8;
|
||||
lengths_[i] = strlen(utf8);
|
||||
args_[i] = InflateString(cx, charArg, &charArgLength);
|
||||
if (!args_[i])
|
||||
return false;
|
||||
allocatedElements_ = true;
|
||||
break;
|
||||
}
|
||||
MOZ_ASSERT(charArgLength == js_strlen(args_[i]));
|
||||
lengths_[i] = charArgLength;
|
||||
} else if (typeArg == ArgumentsAreUTF8) {
|
||||
const char* charArg = va_arg(ap, char*);
|
||||
JS::UTF8Chars utf8(charArg, strlen(charArg));
|
||||
args_[i] = LossyUTF8CharsToNewTwoByteCharsZ(cx, utf8, &lengths_[i]).get();
|
||||
if (!args_[i])
|
||||
return false;
|
||||
allocatedElements_ = true;
|
||||
} else {
|
||||
args_[i] = va_arg(ap, char16_t*);
|
||||
lengths_[i] = js_strlen(args_[i]);
|
||||
}
|
||||
totalLength_ += lengths_[i];
|
||||
}
|
||||
@ -564,19 +585,21 @@ class MOZ_RAII AutoMessageArgs
|
||||
* The format string addressed by the error number may contain operands
|
||||
* identified by the format {N}, where N is a decimal digit. Each of these
|
||||
* is to be replaced by the Nth argument from the va_list. The complete
|
||||
* message is placed into reportp->message_.
|
||||
* message is placed into reportp->ucmessage converted to a JSString.
|
||||
*
|
||||
* Returns true if the expansion succeeds (can fail if out of memory).
|
||||
*/
|
||||
bool
|
||||
js::ExpandErrorArgumentsVA(ExclusiveContext* cx, JSErrorCallback callback,
|
||||
void* userRef, const unsigned errorNumber,
|
||||
const char16_t** messageArgs,
|
||||
char** messagep, const char16_t** messageArgs,
|
||||
ErrorArgumentsType argumentsType,
|
||||
JSErrorReport* reportp, va_list ap)
|
||||
{
|
||||
const JSErrorFormatString* efs;
|
||||
|
||||
*messagep = nullptr;
|
||||
|
||||
if (!callback)
|
||||
callback = GetErrorMessage;
|
||||
|
||||
@ -598,8 +621,9 @@ js::ExpandErrorArgumentsVA(ExclusiveContext* cx, JSErrorCallback callback,
|
||||
* for {X} in the format.
|
||||
*/
|
||||
if (efs->format) {
|
||||
const char* fmt;
|
||||
char* out;
|
||||
char16_t* buffer;
|
||||
char16_t* fmt;
|
||||
char16_t* out;
|
||||
#ifdef DEBUG
|
||||
int expandedArgs = 0;
|
||||
#endif
|
||||
@ -610,6 +634,9 @@ js::ExpandErrorArgumentsVA(ExclusiveContext* cx, JSErrorCallback callback,
|
||||
if (!args.init(cx, messageArgs, argCount, argumentsType, ap))
|
||||
return false;
|
||||
|
||||
buffer = fmt = InflateString(cx, efs->format, &len);
|
||||
if (!buffer)
|
||||
goto error;
|
||||
expandedLength = len
|
||||
- (3 * args.count()) /* exclude the {n} */
|
||||
+ args.totalLength();
|
||||
@ -618,17 +645,17 @@ js::ExpandErrorArgumentsVA(ExclusiveContext* cx, JSErrorCallback callback,
|
||||
* Note - the above calculation assumes that each argument
|
||||
* is used once and only once in the expansion !!!
|
||||
*/
|
||||
char* utf8 = out = cx->pod_malloc<char>(expandedLength + 1);
|
||||
if (!out)
|
||||
return false;
|
||||
|
||||
fmt = efs->format;
|
||||
reportp->ucmessage = out = cx->pod_malloc<char16_t>(expandedLength + 1);
|
||||
if (!out) {
|
||||
js_free(buffer);
|
||||
goto error;
|
||||
}
|
||||
while (*fmt) {
|
||||
if (*fmt == '{') {
|
||||
if (isdigit(fmt[1])) {
|
||||
int d = JS7_UNDEC(fmt[1]);
|
||||
MOZ_RELEASE_ASSERT(d < args.count());
|
||||
strncpy(out, args.args(d), args.lengths(d));
|
||||
js_strncpy(out, args.args(d), args.lengths(d));
|
||||
out += args.lengths(d);
|
||||
fmt += 3;
|
||||
#ifdef DEBUG
|
||||
@ -641,8 +668,13 @@ js::ExpandErrorArgumentsVA(ExclusiveContext* cx, JSErrorCallback callback,
|
||||
}
|
||||
MOZ_ASSERT(expandedArgs == args.count());
|
||||
*out = 0;
|
||||
|
||||
reportp->initOwnedMessage(utf8);
|
||||
js_free(buffer);
|
||||
size_t msgLen = PointerRangeSize(static_cast<const char16_t*>(reportp->ucmessage),
|
||||
static_cast<const char16_t*>(out));
|
||||
mozilla::Range<const char16_t> ucmsg(reportp->ucmessage, msgLen);
|
||||
*messagep = JS::LossyTwoByteCharsToNewLatin1CharsZ(cx, ucmsg).c_str();
|
||||
if (!*messagep)
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
/* Non-null messageArgs should have at least one non-null arg. */
|
||||
@ -651,22 +683,40 @@ js::ExpandErrorArgumentsVA(ExclusiveContext* cx, JSErrorCallback callback,
|
||||
* Zero arguments: the format string (if it exists) is the
|
||||
* entire message.
|
||||
*/
|
||||
if (efs->format)
|
||||
reportp->initBorrowedMessage(efs->format);
|
||||
if (efs->format) {
|
||||
size_t len;
|
||||
*messagep = DuplicateString(cx, efs->format).release();
|
||||
if (!*messagep)
|
||||
goto error;
|
||||
len = strlen(*messagep);
|
||||
reportp->ucmessage = InflateString(cx, *messagep, &len);
|
||||
if (!reportp->ucmessage)
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!reportp->message()) {
|
||||
if (*messagep == nullptr) {
|
||||
/* where's the right place for this ??? */
|
||||
const char* defaultErrorMessage
|
||||
= "No error message available for error number %d";
|
||||
size_t nbytes = strlen(defaultErrorMessage) + 16;
|
||||
char* message = cx->pod_malloc<char>(nbytes);
|
||||
if (!message)
|
||||
return false;
|
||||
snprintf(message, nbytes, defaultErrorMessage, errorNumber);
|
||||
reportp->initOwnedMessage(message);
|
||||
*messagep = cx->pod_malloc<char>(nbytes);
|
||||
if (!*messagep)
|
||||
goto error;
|
||||
snprintf(*messagep, nbytes, defaultErrorMessage, errorNumber);
|
||||
}
|
||||
return true;
|
||||
|
||||
error:
|
||||
if (reportp->ucmessage) {
|
||||
js_free((void*)reportp->ucmessage);
|
||||
reportp->ucmessage = nullptr;
|
||||
}
|
||||
if (*messagep) {
|
||||
js_free((void*)*messagep);
|
||||
*messagep = nullptr;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -675,6 +725,7 @@ js::ReportErrorNumberVA(JSContext* cx, unsigned flags, JSErrorCallback callback,
|
||||
ErrorArgumentsType argumentsType, va_list ap)
|
||||
{
|
||||
JSErrorReport report;
|
||||
char* message;
|
||||
bool warning;
|
||||
|
||||
if (checkReportFlags(cx, &flags))
|
||||
@ -686,11 +737,14 @@ js::ReportErrorNumberVA(JSContext* cx, unsigned flags, JSErrorCallback callback,
|
||||
PopulateReportBlame(cx, &report);
|
||||
|
||||
if (!ExpandErrorArgumentsVA(cx, callback, userRef, errorNumber,
|
||||
nullptr, argumentsType, &report, ap)) {
|
||||
&message, nullptr, argumentsType, &report, ap)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ReportError(cx, &report, callback, userRef);
|
||||
ReportError(cx, message, &report, callback, userRef);
|
||||
|
||||
js_free(message);
|
||||
js_free((void*)report.ucmessage);
|
||||
|
||||
return warning;
|
||||
}
|
||||
@ -698,14 +752,14 @@ js::ReportErrorNumberVA(JSContext* cx, unsigned flags, JSErrorCallback callback,
|
||||
static bool
|
||||
ExpandErrorArguments(ExclusiveContext* cx, JSErrorCallback callback,
|
||||
void* userRef, const unsigned errorNumber,
|
||||
const char16_t** messageArgs,
|
||||
char** messagep, const char16_t** messageArgs,
|
||||
ErrorArgumentsType argumentsType,
|
||||
JSErrorReport* reportp, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, reportp);
|
||||
bool expanded = js::ExpandErrorArgumentsVA(cx, callback, userRef, errorNumber,
|
||||
messageArgs, argumentsType, reportp, ap);
|
||||
messagep, messageArgs, argumentsType, reportp, ap);
|
||||
va_end(ap);
|
||||
return expanded;
|
||||
}
|
||||
@ -724,25 +778,30 @@ js::ReportErrorNumberUCArray(JSContext* cx, unsigned flags, JSErrorCallback call
|
||||
report.errorNumber = errorNumber;
|
||||
PopulateReportBlame(cx, &report);
|
||||
|
||||
char* message;
|
||||
if (!ExpandErrorArguments(cx, callback, userRef, errorNumber,
|
||||
args, ArgumentsAreUnicode, &report))
|
||||
&message, args, ArgumentsAreUnicode, &report))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ReportError(cx, &report, callback, userRef);
|
||||
ReportError(cx, message, &report, callback, userRef);
|
||||
|
||||
js_free(message);
|
||||
js_free((void*)report.ucmessage);
|
||||
|
||||
return warning;
|
||||
}
|
||||
|
||||
void
|
||||
js::CallWarningReporter(JSContext* cx, JSErrorReport* reportp)
|
||||
js::CallWarningReporter(JSContext* cx, const char* message, JSErrorReport* reportp)
|
||||
{
|
||||
MOZ_ASSERT(message);
|
||||
MOZ_ASSERT(reportp);
|
||||
MOZ_ASSERT(JSREPORT_IS_WARNING(reportp->flags));
|
||||
|
||||
if (JS::WarningReporter warningReporter = cx->runtime()->warningReporter)
|
||||
warningReporter(cx, reportp);
|
||||
warningReporter(cx, message, reportp);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -67,7 +67,7 @@ TraceCycleDetectionSet(JSTracer* trc, AutoCycleDetector::Set& set);
|
||||
|
||||
struct AutoResolving;
|
||||
|
||||
namespace frontend { class CompileError; }
|
||||
namespace frontend { struct CompileError; }
|
||||
|
||||
/*
|
||||
* Execution Context Overview:
|
||||
@ -616,7 +616,7 @@ ReportErrorNumberUCArray(JSContext* cx, unsigned flags, JSErrorCallback callback
|
||||
extern bool
|
||||
ExpandErrorArgumentsVA(ExclusiveContext* cx, JSErrorCallback callback,
|
||||
void* userRef, const unsigned errorNumber,
|
||||
const char16_t** messageArgs,
|
||||
char** message, const char16_t** messageArgs,
|
||||
ErrorArgumentsType argumentsType,
|
||||
JSErrorReport* reportp, va_list ap);
|
||||
|
||||
@ -628,17 +628,17 @@ ReportUsageErrorASCII(JSContext* cx, HandleObject callee, const char* msg);
|
||||
* Prints a full report and returns true if the given report is non-nullptr
|
||||
* and the report doesn't have the JSREPORT_WARNING flag set or reportWarnings
|
||||
* is true.
|
||||
* Returns false otherwise.
|
||||
* Returns false otherwise, printing just the message if the report is nullptr.
|
||||
*/
|
||||
extern bool
|
||||
PrintError(JSContext* cx, FILE* file, JS::ConstUTF8CharsZ toStringResult,
|
||||
JSErrorReport* report, bool reportWarnings);
|
||||
PrintError(JSContext* cx, FILE* file, const char* message, JSErrorReport* report,
|
||||
bool reportWarnings);
|
||||
|
||||
/*
|
||||
* Send a JSErrorReport to the warningReporter callback.
|
||||
*/
|
||||
void
|
||||
CallWarningReporter(JSContext* cx, JSErrorReport* report);
|
||||
CallWarningReporter(JSContext* cx, const char* message, JSErrorReport* report);
|
||||
|
||||
extern bool
|
||||
ReportIsNotDefined(JSContext* cx, HandlePropertyName name);
|
||||
|
@ -28,7 +28,6 @@
|
||||
#include "jswrapper.h"
|
||||
|
||||
#include "gc/Marking.h"
|
||||
#include "js/CharacterEncoding.h"
|
||||
#include "vm/ErrorObject.h"
|
||||
#include "vm/GlobalObject.h"
|
||||
#include "vm/SavedStacks.h"
|
||||
@ -152,7 +151,7 @@ js::CopyErrorReport(JSContext* cx, JSErrorReport* report)
|
||||
* We use a single malloc block to make a deep copy of JSErrorReport with
|
||||
* the following layout:
|
||||
* JSErrorReport
|
||||
* char array with characters for message_
|
||||
* char16_t array with characters for ucmessage
|
||||
* char16_t array with characters for linebuf
|
||||
* char array with characters for filename
|
||||
* Such layout together with the properties enforced by the following
|
||||
@ -167,15 +166,15 @@ js::CopyErrorReport(JSContext* cx, JSErrorReport* report)
|
||||
size_t linebufSize = 0;
|
||||
if (report->linebuf())
|
||||
linebufSize = (report->linebufLength() + 1) * sizeof(char16_t);
|
||||
size_t messageSize = 0;
|
||||
if (report->message())
|
||||
messageSize = strlen(report->message().c_str()) + 1;
|
||||
size_t ucmessageSize = 0;
|
||||
if (report->ucmessage)
|
||||
ucmessageSize = JS_CHARS_SIZE(report->ucmessage);
|
||||
|
||||
/*
|
||||
* The mallocSize can not overflow since it represents the sum of the
|
||||
* sizes of already allocated objects.
|
||||
*/
|
||||
size_t mallocSize = sizeof(JSErrorReport) + messageSize + linebufSize + filenameSize;
|
||||
size_t mallocSize = sizeof(JSErrorReport) + ucmessageSize + linebufSize + filenameSize;
|
||||
uint8_t* cursor = cx->pod_calloc<uint8_t>(mallocSize);
|
||||
if (!cursor)
|
||||
return nullptr;
|
||||
@ -183,17 +182,17 @@ js::CopyErrorReport(JSContext* cx, JSErrorReport* report)
|
||||
JSErrorReport* copy = (JSErrorReport*)cursor;
|
||||
cursor += sizeof(JSErrorReport);
|
||||
|
||||
if (report->message()) {
|
||||
copy->initBorrowedMessage((const char*)cursor);
|
||||
js_memcpy(cursor, report->message().c_str(), messageSize);
|
||||
cursor += messageSize;
|
||||
if (report->ucmessage) {
|
||||
copy->ucmessage = (const char16_t*)cursor;
|
||||
js_memcpy(cursor, report->ucmessage, ucmessageSize);
|
||||
cursor += ucmessageSize;
|
||||
}
|
||||
|
||||
if (report->linebuf()) {
|
||||
const char16_t* linebufCopy = (const char16_t*)cursor;
|
||||
js_memcpy(cursor, report->linebuf(), linebufSize);
|
||||
cursor += linebufSize;
|
||||
copy->initBorrowedLinebuf(linebufCopy, report->linebufLength(), report->tokenOffset());
|
||||
copy->initLinebuf(linebufCopy, report->linebufLength(), report->tokenOffset());
|
||||
}
|
||||
|
||||
if (report->filename) {
|
||||
@ -503,7 +502,7 @@ js::GetErrorTypeName(JSContext* cx, int16_t exnType)
|
||||
}
|
||||
|
||||
void
|
||||
js::ErrorToException(JSContext* cx, JSErrorReport* reportp,
|
||||
js::ErrorToException(JSContext* cx, const char* message, JSErrorReport* reportp,
|
||||
JSErrorCallback callback, void* userRef)
|
||||
{
|
||||
MOZ_ASSERT(reportp);
|
||||
@ -513,7 +512,7 @@ js::ErrorToException(JSContext* cx, JSErrorReport* reportp,
|
||||
// we cannot construct the Error constructor without self-hosted code. Just
|
||||
// print the error to stderr to help debugging.
|
||||
if (cx->runtime()->isSelfHostingCompartment(cx->compartment())) {
|
||||
PrintError(cx, stderr, JS::ConstUTF8CharsZ(), reportp, true);
|
||||
PrintError(cx, stderr, message, reportp, true);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -537,7 +536,8 @@ js::ErrorToException(JSContext* cx, JSErrorReport* reportp,
|
||||
AutoScopedAssign<bool> asa(&cx->generatingError, true);
|
||||
|
||||
// Create an exception object.
|
||||
RootedString messageStr(cx, reportp->newMessageString(cx));
|
||||
RootedString messageStr(cx, reportp->ucmessage ? JS_NewUCStringCopyZ(cx, reportp->ucmessage)
|
||||
: JS_NewStringCopyZ(cx, message));
|
||||
if (!messageStr)
|
||||
return;
|
||||
|
||||
@ -612,7 +612,7 @@ ErrorReportToString(JSContext* cx, JSErrorReport* reportp)
|
||||
|
||||
/*
|
||||
* If "str" is null at this point, that means we just want to use
|
||||
* message without prefixing it with anything.
|
||||
* reportp->ucmessage without prefixing it with anything.
|
||||
*/
|
||||
if (str) {
|
||||
RootedString separator(cx, JS_NewUCStringCopyN(cx, u": ", 2));
|
||||
@ -623,7 +623,7 @@ ErrorReportToString(JSContext* cx, JSErrorReport* reportp)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RootedString message(cx, reportp->newMessageString(cx));
|
||||
RootedString message(cx, JS_NewUCStringCopyZ(cx, reportp->ucmessage));
|
||||
if (!message)
|
||||
return nullptr;
|
||||
|
||||
@ -635,6 +635,8 @@ ErrorReportToString(JSContext* cx, JSErrorReport* reportp)
|
||||
|
||||
ErrorReport::ErrorReport(JSContext* cx)
|
||||
: reportp(nullptr),
|
||||
message_(nullptr),
|
||||
ownedMessage(nullptr),
|
||||
str(cx),
|
||||
strChars(cx),
|
||||
exnObject(cx)
|
||||
@ -643,6 +645,11 @@ ErrorReport::ErrorReport(JSContext* cx)
|
||||
|
||||
ErrorReport::~ErrorReport()
|
||||
{
|
||||
if (!ownedMessage)
|
||||
return;
|
||||
|
||||
js_free(ownedMessage);
|
||||
js_free(const_cast<char16_t*>(ownedReport.ucmessage));
|
||||
}
|
||||
|
||||
void
|
||||
@ -831,47 +838,37 @@ ErrorReport::init(JSContext* cx, HandleValue exn,
|
||||
ownedReport.exnType = JSEXN_INTERNALERR;
|
||||
ownedReport.column = column;
|
||||
if (str) {
|
||||
// Note that using |str| for |message_| here is kind of wrong,
|
||||
// Note that using |str| for |ucmessage| here is kind of wrong,
|
||||
// because |str| is supposed to be of the format
|
||||
// |ErrorName: ErrorMessage|, and |message_| is supposed to
|
||||
// correspond to |ErrorMessage|. But this is what we've
|
||||
// historically done for duck-typed error objects.
|
||||
// |ErrorName: ErrorMessage|, and |ucmessage| is supposed to
|
||||
// correspond to |ErrorMessage|. But this is what we've historically
|
||||
// done for duck-typed error objects.
|
||||
//
|
||||
// If only this stuff could get specced one day...
|
||||
char* utf8;
|
||||
if (str->ensureFlat(cx) &&
|
||||
strChars.initTwoByte(cx, str) &&
|
||||
(utf8 = JS::CharsToNewUTF8CharsZ(cx, strChars.twoByteRange()).c_str()))
|
||||
{
|
||||
ownedReport.initOwnedMessage(utf8);
|
||||
} else {
|
||||
cx->clearPendingException();
|
||||
str = nullptr;
|
||||
}
|
||||
if (str->ensureFlat(cx) && strChars.initTwoByte(cx, str))
|
||||
ownedReport.ucmessage = strChars.twoByteChars();
|
||||
}
|
||||
}
|
||||
|
||||
const char* utf8Message = nullptr;
|
||||
if (str)
|
||||
utf8Message = toStringResultBytesStorage.encodeUtf8(cx, str);
|
||||
if (!utf8Message)
|
||||
utf8Message = "unknown (can't convert to string)";
|
||||
message_ = bytesStorage.encodeUtf8(cx, str);
|
||||
if (!message_)
|
||||
message_ = "unknown (can't convert to string)";
|
||||
|
||||
if (!reportp) {
|
||||
// This is basically an inlined version of
|
||||
//
|
||||
// JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
|
||||
// JSMSG_UNCAUGHT_EXCEPTION, utf8Message);
|
||||
// JSMSG_UNCAUGHT_EXCEPTION, message_);
|
||||
//
|
||||
// but without the reporting bits. Instead it just puts all
|
||||
// the stuff we care about in our ownedReport and message_.
|
||||
if (!populateUncaughtExceptionReportUTF8(cx, utf8Message)) {
|
||||
if (!populateUncaughtExceptionReportUTF8(cx, message_)) {
|
||||
// Just give up. We're out of memory or something; not much we can
|
||||
// do here.
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
toStringResult_ = JS::ConstUTF8CharsZ(utf8Message, strlen(utf8Message));
|
||||
/* Flag the error as an exception. */
|
||||
reportp->flags |= JSREPORT_EXCEPTION;
|
||||
}
|
||||
@ -910,13 +907,14 @@ ErrorReport::populateUncaughtExceptionReportUTF8VA(JSContext* cx, va_list ap)
|
||||
}
|
||||
|
||||
if (!ExpandErrorArgumentsVA(cx, GetErrorMessage, nullptr,
|
||||
JSMSG_UNCAUGHT_EXCEPTION,
|
||||
JSMSG_UNCAUGHT_EXCEPTION, &ownedMessage,
|
||||
nullptr, ArgumentsAreUTF8, &ownedReport, ap)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
toStringResult_ = ownedReport.message();
|
||||
reportp = &ownedReport;
|
||||
message_ = ownedMessage;
|
||||
ownsMessageAndReport = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,7 @@ ComputeStackString(JSContext* cx);
|
||||
* the rug.
|
||||
*/
|
||||
extern void
|
||||
ErrorToException(JSContext* cx, JSErrorReport* reportp,
|
||||
ErrorToException(JSContext* cx, const char* message, JSErrorReport* reportp,
|
||||
JSErrorCallback callback, void* userRef);
|
||||
|
||||
extern JSErrorReport*
|
||||
|
@ -1452,9 +1452,9 @@ struct MOZ_STACK_CLASS JS_FRIEND_API(ErrorReport)
|
||||
return reportp;
|
||||
}
|
||||
|
||||
const JS::ConstUTF8CharsZ toStringResult()
|
||||
const char* message()
|
||||
{
|
||||
return toStringResult_;
|
||||
return message_;
|
||||
}
|
||||
|
||||
private:
|
||||
@ -1473,9 +1473,16 @@ struct MOZ_STACK_CLASS JS_FRIEND_API(ErrorReport)
|
||||
// We may have a provided JSErrorReport, so need a way to represent that.
|
||||
JSErrorReport* reportp;
|
||||
|
||||
// And we may have a message.
|
||||
const char* message_;
|
||||
|
||||
// Or we may need to synthesize a JSErrorReport one of our own.
|
||||
JSErrorReport ownedReport;
|
||||
|
||||
// Or a message of our own. If this is non-null, we need to clean up both
|
||||
// it and ownedReport.
|
||||
char* ownedMessage;
|
||||
|
||||
// And we have a string to maybe keep alive that has pointers into
|
||||
// it from ownedReport.
|
||||
JS::RootedString str;
|
||||
@ -1486,14 +1493,14 @@ struct MOZ_STACK_CLASS JS_FRIEND_API(ErrorReport)
|
||||
// And we need to root our exception value.
|
||||
JS::RootedObject exnObject;
|
||||
|
||||
// And possibly some byte storage for our message_.
|
||||
JSAutoByteString bytesStorage;
|
||||
|
||||
// And for our filename.
|
||||
JSAutoByteString filename;
|
||||
|
||||
// We may have a result of error.toString().
|
||||
// FIXME: We should not call error.toString(), since it could have side
|
||||
// effect (see bug 633623).
|
||||
JS::ConstUTF8CharsZ toStringResult_;
|
||||
JSAutoByteString toStringResultBytesStorage;
|
||||
// True if we need to free message_ and the stuff in ownedReport
|
||||
bool ownsMessageAndReport;
|
||||
};
|
||||
|
||||
/* Implemented in vm/StructuredClone.cpp. */
|
||||
|
@ -6314,7 +6314,7 @@ CreateLastWarningObject(JSContext* cx, JSErrorReport* report)
|
||||
if (!DefineProperty(cx, warningObj, cx->names().name, nameVal))
|
||||
return false;
|
||||
|
||||
RootedString messageStr(cx, report->newMessageString(cx));
|
||||
RootedString messageStr(cx, JS_NewUCStringCopyZ(cx, report->ucmessage));
|
||||
if (!messageStr)
|
||||
return false;
|
||||
RootedValue messageVal(cx, StringValue(messageStr));
|
||||
@ -6394,8 +6394,7 @@ js::shell::AutoReportException::~AutoReportException()
|
||||
ShellContext* sc = GetShellContext(cx);
|
||||
js::ErrorReport report(cx);
|
||||
if (!report.init(cx, exn, js::ErrorReport::WithSideEffects)) {
|
||||
fprintf(stderr, "out of memory initializing ErrorReport\n");
|
||||
fflush(stderr);
|
||||
PrintError(cx, stderr, "out of memory initializing ErrorReport", nullptr, reportWarnings);
|
||||
JS_ClearPendingException(cx);
|
||||
return;
|
||||
}
|
||||
@ -6403,7 +6402,7 @@ js::shell::AutoReportException::~AutoReportException()
|
||||
MOZ_ASSERT(!JSREPORT_IS_WARNING(report.report()->flags));
|
||||
|
||||
FILE* fp = ErrorFilePointer();
|
||||
PrintError(cx, fp, report.toStringResult(), report.report(), reportWarnings);
|
||||
PrintError(cx, fp, report.message(), report.report(), reportWarnings);
|
||||
|
||||
{
|
||||
JS::AutoSaveExceptionState savedExc(cx);
|
||||
@ -6421,7 +6420,7 @@ js::shell::AutoReportException::~AutoReportException()
|
||||
}
|
||||
|
||||
void
|
||||
js::shell::WarningReporter(JSContext* cx, JSErrorReport* report)
|
||||
js::shell::WarningReporter(JSContext* cx, const char* message, JSErrorReport* report)
|
||||
{
|
||||
ShellContext* sc = GetShellContext(cx);
|
||||
FILE* fp = ErrorFilePointer();
|
||||
@ -6439,7 +6438,7 @@ js::shell::WarningReporter(JSContext* cx, JSErrorReport* report)
|
||||
}
|
||||
|
||||
// Print the warning.
|
||||
PrintError(cx, fp, JS::ConstUTF8CharsZ(), report, reportWarnings);
|
||||
PrintError(cx, fp, message, report, reportWarnings);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
@ -24,7 +24,7 @@ const JSErrorFormatString*
|
||||
my_GetErrorMessage(void* userRef, const unsigned errorNumber);
|
||||
|
||||
void
|
||||
WarningReporter(JSContext* cx, JSErrorReport* report);
|
||||
WarningReporter(JSContext* cx, const char* message, JSErrorReport* report);
|
||||
|
||||
class MOZ_STACK_CLASS AutoReportException
|
||||
{
|
||||
|
@ -7,14 +7,10 @@
|
||||
|
||||
#include "vm/ErrorObject-inl.h"
|
||||
|
||||
#include "mozilla/Range.h"
|
||||
|
||||
#include "jsexn.h"
|
||||
|
||||
#include "js/CallArgs.h"
|
||||
#include "js/CharacterEncoding.h"
|
||||
#include "vm/GlobalObject.h"
|
||||
#include "vm/String.h"
|
||||
|
||||
#include "jsobjinlines.h"
|
||||
|
||||
@ -149,11 +145,10 @@ js::ErrorObject::getOrCreateErrorReport(JSContext* cx)
|
||||
message = cx->runtime()->emptyString;
|
||||
if (!message->ensureFlat(cx))
|
||||
return nullptr;
|
||||
|
||||
UniquePtr<char[], JS::FreePolicy> utf8 = StringToNewUTF8CharsZ(cx, *message);
|
||||
if (!utf8)
|
||||
AutoStableStringChars chars(cx);
|
||||
if (!chars.initTwoByte(cx, message))
|
||||
return nullptr;
|
||||
report.initOwnedMessage(utf8.release());
|
||||
report.ucmessage = chars.twoByteRange().start().get();
|
||||
|
||||
// Cache and return.
|
||||
JSErrorReport* copy = CopyErrorReport(cx, &report);
|
||||
|
@ -37,7 +37,6 @@
|
||||
#include "gc/Policy.h"
|
||||
#include "jit/AtomicOperations.h"
|
||||
#include "jit/InlinableNatives.h"
|
||||
#include "js/CharacterEncoding.h"
|
||||
#include "js/Date.h"
|
||||
#include "vm/Compression.h"
|
||||
#include "vm/GeneratorObject.h"
|
||||
@ -67,12 +66,12 @@ using mozilla::PodMove;
|
||||
using mozilla::Maybe;
|
||||
|
||||
static void
|
||||
selfHosting_WarningReporter(JSContext* cx, JSErrorReport* report)
|
||||
selfHosting_WarningReporter(JSContext* cx, const char* message, JSErrorReport* report)
|
||||
{
|
||||
MOZ_ASSERT(report);
|
||||
MOZ_ASSERT(JSREPORT_IS_WARNING(report->flags));
|
||||
|
||||
PrintError(cx, stderr, JS::ConstUTF8CharsZ(), report, true);
|
||||
PrintError(cx, stderr, message, report, true);
|
||||
}
|
||||
|
||||
static bool
|
||||
@ -2683,7 +2682,7 @@ MaybePrintAndClearPendingException(JSContext* cx, FILE* file)
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!JSREPORT_IS_WARNING(report.report()->flags));
|
||||
PrintError(cx, file, report.toStringResult(), report.report(), true);
|
||||
PrintError(cx, file, report.message(), report.report(), true);
|
||||
}
|
||||
|
||||
class MOZ_STACK_CLASS AutoSelfHostingErrorReporter
|
||||
|
@ -2343,11 +2343,11 @@ nsXPCComponents_Utils::ReportError(HandleValue error, JSContext* cx)
|
||||
|
||||
uint32_t column = err->tokenOffset();
|
||||
|
||||
const char16_t* ucmessage = err->ucmessage;
|
||||
const char16_t* linebuf = err->linebuf();
|
||||
|
||||
nsresult rv = scripterr->InitWithWindowID(
|
||||
err->message() ? NS_ConvertUTF8toUTF16(err->message().c_str())
|
||||
: EmptyString(),
|
||||
ucmessage ? nsDependentString(ucmessage) : EmptyString(),
|
||||
fileUni,
|
||||
linebuf ? nsDependentString(linebuf, err->linebufLength()) : EmptyString(),
|
||||
err->lineno,
|
||||
|
@ -1047,56 +1047,6 @@ private:
|
||||
RootedValue tvr;
|
||||
};
|
||||
|
||||
static nsresult
|
||||
JSErrorToXPCException(const char* toStringResult,
|
||||
const char* ifaceName,
|
||||
const char* methodName,
|
||||
const JSErrorReport* report,
|
||||
nsIException** exceptn)
|
||||
{
|
||||
AutoJSContext cx;
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
RefPtr<nsScriptError> data;
|
||||
if (report) {
|
||||
nsAutoString bestMessage;
|
||||
if (report && report->message()) {
|
||||
CopyUTF8toUTF16(report->message().c_str(), bestMessage);
|
||||
} else if (toStringResult) {
|
||||
CopyUTF8toUTF16(toStringResult, bestMessage);
|
||||
} else {
|
||||
bestMessage.AssignLiteral("JavaScript Error");
|
||||
}
|
||||
|
||||
const char16_t* linebuf = report->linebuf();
|
||||
|
||||
data = new nsScriptError();
|
||||
data->InitWithWindowID(
|
||||
bestMessage,
|
||||
NS_ConvertASCIItoUTF16(report->filename),
|
||||
linebuf ? nsDependentString(linebuf, report->linebufLength()) : EmptyString(),
|
||||
report->lineno,
|
||||
report->tokenOffset(), report->flags,
|
||||
NS_LITERAL_CSTRING("XPConnect JavaScript"),
|
||||
nsJSUtils::GetCurrentlyRunningCodeInnerWindowID(cx));
|
||||
}
|
||||
|
||||
if (data) {
|
||||
nsAutoCString formattedMsg;
|
||||
data->ToString(formattedMsg);
|
||||
|
||||
rv = XPCConvert::ConstructException(NS_ERROR_XPC_JAVASCRIPT_ERROR_WITH_DETAILS,
|
||||
formattedMsg.get(), ifaceName,
|
||||
methodName,
|
||||
static_cast<nsIScriptError*>(data.get()),
|
||||
exceptn, nullptr, nullptr);
|
||||
} else {
|
||||
rv = XPCConvert::ConstructException(NS_ERROR_XPC_JAVASCRIPT_ERROR,
|
||||
nullptr, ifaceName, methodName,
|
||||
nullptr, exceptn, nullptr, nullptr);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
XPCConvert::JSValToXPCException(MutableHandleValue s,
|
||||
@ -1140,11 +1090,11 @@ XPCConvert::JSValToXPCException(MutableHandleValue s,
|
||||
// extract the report and build an xpcexception from that
|
||||
const JSErrorReport* report;
|
||||
if (nullptr != (report = JS_ErrorFromException(cx, obj))) {
|
||||
JSAutoByteString toStringResult;
|
||||
RootedString str(cx, ToString(cx, s));
|
||||
if (str)
|
||||
toStringResult.encodeUtf8(cx, str);
|
||||
return JSErrorToXPCException(toStringResult.ptr(), ifaceName,
|
||||
JSAutoByteString message;
|
||||
JSString* str;
|
||||
if (nullptr != (str = ToString(cx, s)))
|
||||
message.encodeLatin1(cx, str);
|
||||
return JSErrorToXPCException(message.ptr(), ifaceName,
|
||||
methodName, report, exceptn);
|
||||
}
|
||||
|
||||
@ -1237,6 +1187,58 @@ XPCConvert::JSValToXPCException(MutableHandleValue s,
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
/********************************/
|
||||
|
||||
// static
|
||||
nsresult
|
||||
XPCConvert::JSErrorToXPCException(const char* message,
|
||||
const char* ifaceName,
|
||||
const char* methodName,
|
||||
const JSErrorReport* report,
|
||||
nsIException** exceptn)
|
||||
{
|
||||
AutoJSContext cx;
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
RefPtr<nsScriptError> data;
|
||||
if (report) {
|
||||
nsAutoString bestMessage;
|
||||
if (report && report->ucmessage) {
|
||||
bestMessage = static_cast<const char16_t*>(report->ucmessage);
|
||||
} else if (message) {
|
||||
CopyASCIItoUTF16(message, bestMessage);
|
||||
} else {
|
||||
bestMessage.AssignLiteral("JavaScript Error");
|
||||
}
|
||||
|
||||
const char16_t* linebuf = report->linebuf();
|
||||
|
||||
data = new nsScriptError();
|
||||
data->InitWithWindowID(
|
||||
bestMessage,
|
||||
NS_ConvertASCIItoUTF16(report->filename),
|
||||
linebuf ? nsDependentString(linebuf, report->linebufLength()) : EmptyString(),
|
||||
report->lineno,
|
||||
report->tokenOffset(), report->flags,
|
||||
NS_LITERAL_CSTRING("XPConnect JavaScript"),
|
||||
nsJSUtils::GetCurrentlyRunningCodeInnerWindowID(cx));
|
||||
}
|
||||
|
||||
if (data) {
|
||||
nsAutoCString formattedMsg;
|
||||
data->ToString(formattedMsg);
|
||||
|
||||
rv = ConstructException(NS_ERROR_XPC_JAVASCRIPT_ERROR_WITH_DETAILS,
|
||||
formattedMsg.get(), ifaceName, methodName,
|
||||
static_cast<nsIScriptError*>(data.get()),
|
||||
exceptn, nullptr, nullptr);
|
||||
} else {
|
||||
rv = ConstructException(NS_ERROR_XPC_JAVASCRIPT_ERROR,
|
||||
nullptr, ifaceName, methodName, nullptr,
|
||||
exceptn, nullptr, nullptr);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
// array fun...
|
||||
|
@ -169,7 +169,7 @@ nsXPConnect::IsISupportsDescendant(nsIInterfaceInfo* info)
|
||||
}
|
||||
|
||||
void
|
||||
xpc::ErrorReport::Init(JSErrorReport* aReport, const char* aToStringResult,
|
||||
xpc::ErrorReport::Init(JSErrorReport* aReport, const char* aFallbackMessage,
|
||||
bool aIsChrome, uint64_t aWindowID)
|
||||
{
|
||||
mCategory = aIsChrome ? NS_LITERAL_CSTRING("chrome javascript")
|
||||
@ -177,8 +177,8 @@ xpc::ErrorReport::Init(JSErrorReport* aReport, const char* aToStringResult,
|
||||
mWindowID = aWindowID;
|
||||
|
||||
ErrorReportToMessageString(aReport, mErrorMsg);
|
||||
if (mErrorMsg.IsEmpty() && aToStringResult) {
|
||||
AppendUTF8toUTF16(aToStringResult, mErrorMsg);
|
||||
if (mErrorMsg.IsEmpty() && aFallbackMessage) {
|
||||
mErrorMsg.AssignWithConversion(aFallbackMessage);
|
||||
}
|
||||
|
||||
if (!aReport->filename) {
|
||||
@ -290,13 +290,14 @@ xpc::ErrorReport::ErrorReportToMessageString(JSErrorReport* aReport,
|
||||
nsAString& aString)
|
||||
{
|
||||
aString.Truncate();
|
||||
if (aReport->message()) {
|
||||
const char16_t* m = aReport->ucmessage;
|
||||
if (m) {
|
||||
JSFlatString* name = js::GetErrorTypeName(CycleCollectedJSContext::Get()->Context(), aReport->exnType);
|
||||
if (name) {
|
||||
AssignJSFlatString(aString, name);
|
||||
aString.AppendLiteral(": ");
|
||||
}
|
||||
aString.Append(NS_ConvertUTF8toUTF16(aReport->message().c_str()));
|
||||
aString.Append(m);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2376,6 +2376,12 @@ public:
|
||||
const char* methodName,
|
||||
nsIException** exception);
|
||||
|
||||
static nsresult JSErrorToXPCException(const char* message,
|
||||
const char* ifaceName,
|
||||
const char* methodName,
|
||||
const JSErrorReport* report,
|
||||
nsIException** exception);
|
||||
|
||||
static nsresult ConstructException(nsresult rv, const char* message,
|
||||
const char* ifaceName,
|
||||
const char* methodName,
|
||||
|
@ -516,7 +516,7 @@ class ErrorReport {
|
||||
, mIsMuted(false)
|
||||
{}
|
||||
|
||||
void Init(JSErrorReport* aReport, const char* aToStringResult,
|
||||
void Init(JSErrorReport* aReport, const char* aFallbackMessage,
|
||||
bool aIsChrome, uint64_t aWindowID);
|
||||
void Init(JSContext* aCx, mozilla::dom::Exception* aException,
|
||||
bool aIsChrome, uint64_t aWindowID);
|
||||
|
@ -327,8 +327,7 @@ PACLogErrorOrWarning(const nsAString& aKind, JSErrorReport* aReport)
|
||||
nsString formattedMessage(NS_LITERAL_STRING("PAC Execution "));
|
||||
formattedMessage += aKind;
|
||||
formattedMessage += NS_LITERAL_STRING(": ");
|
||||
if (aReport->message())
|
||||
formattedMessage.Append(NS_ConvertUTF8toUTF16(aReport->message().c_str()));
|
||||
formattedMessage += aReport->ucmessage;
|
||||
formattedMessage += NS_LITERAL_STRING(" [");
|
||||
formattedMessage.Append(aReport->linebuf(), aReport->linebufLength());
|
||||
formattedMessage += NS_LITERAL_STRING("]");
|
||||
@ -336,7 +335,7 @@ PACLogErrorOrWarning(const nsAString& aKind, JSErrorReport* aReport)
|
||||
}
|
||||
|
||||
static void
|
||||
PACWarningReporter(JSContext* aCx, JSErrorReport* aReport)
|
||||
PACWarningReporter(JSContext* aCx, const char* aMessage, JSErrorReport* aReport)
|
||||
{
|
||||
MOZ_ASSERT(aReport);
|
||||
MOZ_ASSERT(JSREPORT_IS_WARNING(aReport->flags));
|
||||
|
@ -486,7 +486,7 @@ CycleCollectedJSContext::~CycleCollectedJSContext()
|
||||
}
|
||||
|
||||
static void
|
||||
MozCrashWarningReporter(JSContext*, JSErrorReport*)
|
||||
MozCrashWarningReporter(JSContext*, const char*, JSErrorReport*)
|
||||
{
|
||||
MOZ_CRASH("Why is someone touching JSAPI without an AutoJSAPI?");
|
||||
}
|
||||
|
@ -13,7 +13,6 @@
|
||||
#include "nscore.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/SSE.h"
|
||||
#include "mozilla/TypeTraits.h"
|
||||
|
||||
#include "nsCharTraits.h"
|
||||
|
||||
@ -723,20 +722,4 @@ private:
|
||||
};
|
||||
#endif // MOZILLA_INTERNAL_API
|
||||
|
||||
|
||||
template<typename Char, typename UnsignedT>
|
||||
inline UnsignedT
|
||||
RewindToPriorUTF8Codepoint(const Char* utf8Chars, UnsignedT index)
|
||||
{
|
||||
static_assert(mozilla::IsSame<Char, char>::value ||
|
||||
mozilla::IsSame<Char, unsigned char>::value ||
|
||||
mozilla::IsSame<Char, signed char>::value,
|
||||
"UTF-8 data must be in 8-bit units");
|
||||
static_assert(mozilla::IsUnsigned<UnsignedT>::value, "index type must be unsigned");
|
||||
while (index > 0 && (utf8Chars[index] & 0xC0) == 0x80)
|
||||
--index;
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
#endif /* !defined(nsUTF8Utils_h_) */
|
||||
|
Loading…
x
Reference in New Issue
Block a user