Bug 1212328 - Clean up some JSErrorReport-related code. r=Waldo,bz

This commit is contained in:
Jan de Mooij 2016-03-11 15:19:06 +01:00
parent 46689fcaca
commit 40172eddb0
10 changed files with 99 additions and 92 deletions

View File

@ -5781,9 +5781,9 @@ WorkerPrivate::ReportError(JSContext* aCx, const char* aFallbackMessage,
xpc::ErrorReport::ErrorReportToMessageString(aReport, message);
filename = NS_ConvertUTF8toUTF16(aReport->filename);
line = aReport->uclinebuf;
line.Assign(aReport->linebuf(), aReport->linebufLength());
lineNumber = aReport->lineno;
columnNumber = aReport->uctokenptr - aReport->uclinebuf;
columnNumber = aReport->tokenOffset();
flags = aReport->flags;
errorNumber = aReport->errorNumber;
MOZ_ASSERT(aReport->exnType >= JSEXN_NONE && aReport->exnType < JSEXN_LIMIT);

View File

@ -584,8 +584,7 @@ CompileError::throwError(JSContext* cx)
CompileError::~CompileError()
{
js_free((void*)report.uclinebuf);
js_free((void*)report.linebuf);
js_free((void*)report.linebuf());
js_free((void*)report.ucmessage);
js_free(message);
message = nullptr;
@ -691,22 +690,17 @@ TokenStream::reportCompileErrorNumberVA(uint32_t offset, unsigned flags, unsigne
// Create the windowed strings.
StringBuffer windowBuf(cx);
if (!windowBuf.append(userbuf.rawCharPtrAt(windowStart), windowLength) ||
!windowBuf.append((char16_t)0))
!windowBuf.append('\0'))
{
return false;
}
// The window into the offending source line, without final \n.
UniqueTwoByteChars linebuf(windowBuf.stealChars());
if (!linebuf)
return false;
// Unicode and char versions of the window into the offending source
// line, without final \n.
err.report.uclinebuf = windowBuf.stealChars();
if (!err.report.uclinebuf)
return false;
mozilla::Range<const char16_t> tbchars(err.report.uclinebuf, windowLength);
err.report.linebuf = JS::LossyTwoByteCharsToNewLatin1CharsZ(cx, tbchars).c_str();
if (!err.report.linebuf)
return false;
err.report.tokenptr = err.report.linebuf + (offset - windowStart);
err.report.uctokenptr = err.report.uclinebuf + (offset - windowStart);
err.report.initLinebuf(linebuf.release(), windowLength, offset - windowStart);
}
if (cx->isJSContext())

View File

@ -5785,6 +5785,18 @@ JS_ErrorFromException(JSContext* cx, HandleObject obj)
return ErrorFromException(cx, obj);
}
void
JSErrorReport::initLinebuf(const char16_t* linebuf, size_t linebufLength, size_t tokenOffset)
{
MOZ_ASSERT(linebuf);
MOZ_ASSERT(tokenOffset <= linebufLength);
MOZ_ASSERT(linebuf[linebufLength] == '\0');
linebuf_ = linebuf;
linebufLength_ = linebufLength;
tokenOffset_ = tokenOffset;
}
JS_PUBLIC_API(bool)
JS_ThrowStopIteration(JSContext* cx)
{

View File

@ -4943,26 +4943,43 @@ JS_ReportAllocationOverflow(JSContext* cx);
class JSErrorReport
{
// Offending source line without final '\n'.
const char16_t* linebuf_;
// Number of chars in linebuf_. Does not include trailing '\0'.
size_t linebufLength_;
// The 0-based offset of error token in linebuf_.
size_t tokenOffset_;
public:
JSErrorReport()
: filename(nullptr), lineno(0), column(0), isMuted(false), linebuf(nullptr),
tokenptr(nullptr), uclinebuf(nullptr), uctokenptr(nullptr), flags(0), errorNumber(0),
ucmessage(nullptr), messageArgs(nullptr), exnType(0)
: linebuf_(nullptr), linebufLength_(0), tokenOffset_(0),
filename(nullptr), lineno(0), column(0), isMuted(false),
flags(0), errorNumber(0), ucmessage(nullptr),
messageArgs(nullptr), exnType(0)
{}
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. */
const char* linebuf; /* offending source line without final \n */
const char* tokenptr; /* pointer to error token in linebuf */
const char16_t* uclinebuf; /* unicode (original) line buffer */
const char16_t* uctokenptr; /* unicode (original) token pointer */
unsigned flags; /* error/warning, etc. */
unsigned errorNumber; /* the error number, e.g. see js.msg */
const char16_t* ucmessage; /* the (default) error message */
const char16_t** messageArgs; /* arguments for the error message */
int16_t exnType; /* One of the JSExnType constants */
const char16_t* linebuf() const {
return linebuf_;
}
size_t linebufLength() const {
return linebufLength_;
}
size_t tokenOffset() const {
return tokenOffset_;
}
void initLinebuf(const char16_t* linebuf, size_t linebufLength, size_t tokenOffset);
};
/*

View File

@ -519,20 +519,28 @@ js::PrintError(JSContext* cx, FILE* file, const char* message, JSErrorReport* re
fputs(prefix, file);
fputs(message, file);
if (report->linebuf) {
/* report->linebuf usually ends with a newline. */
int n = strlen(report->linebuf);
fprintf(file, ":\n%s%s%s%s",
prefix,
report->linebuf,
(n > 0 && report->linebuf[n-1] == '\n') ? "" : "\n",
prefix);
n = report->tokenptr - report->linebuf;
for (int i = 0, j = 0; i < n; i++) {
if (report->linebuf[i] == '\t') {
for (int k = (j + 8) & ~7; j < k; j++) {
if (const char16_t* linebuf = report->linebuf()) {
size_t n = report->linebufLength();
fputs(":\n", file);
if (prefix)
fputs(prefix, file);
for (size_t i = 0; i < n; i++)
fputc(static_cast<char>(linebuf[i]), file);
// linebuf usually ends with a newline. If not, add one here.
if (n == 0 || linebuf[n-1] != '\n')
fputc('\n', file);
if (prefix)
fputs(prefix, file);
n = report->tokenOffset();
for (size_t i = 0, j = 0; i < n; i++) {
if (linebuf[i] == '\t') {
for (size_t k = (j + 8) & ~7; j < k; j++)
fputc('.', file);
}
continue;
}
fputc('.', file);

View File

@ -148,8 +148,7 @@ js::CopyErrorReport(JSContext* cx, JSErrorReport* report)
* array of copies of report->messageArgs
* char16_t array with characters for all messageArgs
* char16_t array with characters for ucmessage
* char16_t array with characters for uclinebuf and uctokenptr
* char array with characters for linebuf and tokenptr
* char16_t array with characters for linebuf
* char array with characters for filename
* Such layout together with the properties enforced by the following
* asserts does not need any extra alignment padding.
@ -157,27 +156,20 @@ js::CopyErrorReport(JSContext* cx, JSErrorReport* report)
JS_STATIC_ASSERT(sizeof(JSErrorReport) % sizeof(const char*) == 0);
JS_STATIC_ASSERT(sizeof(const char*) % sizeof(char16_t) == 0);
size_t filenameSize;
size_t linebufSize;
size_t uclinebufSize;
size_t ucmessageSize;
size_t i, argsArraySize, argsCopySize, argSize;
size_t mallocSize;
JSErrorReport* copy;
uint8_t* cursor;
#define JS_CHARS_SIZE(chars) ((js_strlen(chars) + 1) * sizeof(char16_t))
filenameSize = report->filename ? strlen(report->filename) + 1 : 0;
linebufSize = report->linebuf ? strlen(report->linebuf) + 1 : 0;
uclinebufSize = report->uclinebuf ? JS_CHARS_SIZE(report->uclinebuf) : 0;
ucmessageSize = 0;
argsArraySize = 0;
argsCopySize = 0;
size_t filenameSize = report->filename ? strlen(report->filename) + 1 : 0;
size_t linebufSize = 0;
if (report->linebuf())
linebufSize = (report->linebufLength() + 1) * sizeof(char16_t);
size_t ucmessageSize = 0;
size_t argsArraySize = 0;
size_t argsCopySize = 0;
if (report->ucmessage) {
ucmessageSize = JS_CHARS_SIZE(report->ucmessage);
if (report->messageArgs) {
for (i = 0; report->messageArgs[i]; ++i)
size_t i = 0;
for (; report->messageArgs[i]; ++i)
argsCopySize += JS_CHARS_SIZE(report->messageArgs[i]);
/* Non-null messageArgs should have at least one non-null arg. */
@ -190,22 +182,22 @@ js::CopyErrorReport(JSContext* cx, JSErrorReport* report)
* The mallocSize can not overflow since it represents the sum of the
* sizes of already allocated objects.
*/
mallocSize = sizeof(JSErrorReport) + argsArraySize + argsCopySize +
ucmessageSize + uclinebufSize + linebufSize + filenameSize;
cursor = cx->pod_malloc<uint8_t>(mallocSize);
size_t mallocSize = sizeof(JSErrorReport) + argsArraySize + argsCopySize +
ucmessageSize + linebufSize + filenameSize;
uint8_t* cursor = cx->pod_calloc<uint8_t>(mallocSize);
if (!cursor)
return nullptr;
copy = (JSErrorReport*)cursor;
memset(cursor, 0, sizeof(JSErrorReport));
JSErrorReport* copy = (JSErrorReport*)cursor;
cursor += sizeof(JSErrorReport);
if (argsArraySize != 0) {
copy->messageArgs = (const char16_t**)cursor;
cursor += argsArraySize;
for (i = 0; report->messageArgs[i]; ++i) {
size_t i = 0;
for (; report->messageArgs[i]; ++i) {
copy->messageArgs[i] = (const char16_t*)cursor;
argSize = JS_CHARS_SIZE(report->messageArgs[i]);
size_t argSize = JS_CHARS_SIZE(report->messageArgs[i]);
js_memcpy(cursor, report->messageArgs[i], argSize);
cursor += argSize;
}
@ -219,24 +211,11 @@ js::CopyErrorReport(JSContext* cx, JSErrorReport* report)
cursor += ucmessageSize;
}
if (report->uclinebuf) {
copy->uclinebuf = (const char16_t*)cursor;
js_memcpy(cursor, report->uclinebuf, uclinebufSize);
cursor += uclinebufSize;
if (report->uctokenptr) {
copy->uctokenptr = copy->uclinebuf + (report->uctokenptr -
report->uclinebuf);
}
}
if (report->linebuf) {
copy->linebuf = (const char*)cursor;
js_memcpy(cursor, report->linebuf, linebufSize);
if (report->linebuf()) {
const char16_t* linebufCopy = (const char16_t*)cursor;
js_memcpy(cursor, report->linebuf(), linebufSize);
cursor += linebufSize;
if (report->tokenptr) {
copy->tokenptr = copy->linebuf + (report->tokenptr -
report->linebuf);
}
copy->initLinebuf(linebufCopy, report->linebufLength(), report->tokenOffset());
}
if (report->filename) {

View File

@ -2337,17 +2337,15 @@ nsXPCComponents_Utils::ReportError(HandleValue error, JSContext* cx)
nsAutoString fileUni;
CopyUTF8toUTF16(err->filename, fileUni);
uint32_t column = err->uctokenptr - err->uclinebuf;
uint32_t column = err->tokenOffset();
const char16_t* ucmessage =
static_cast<const char16_t*>(err->ucmessage);
const char16_t* uclinebuf =
static_cast<const char16_t*>(err->uclinebuf);
const char16_t* ucmessage = err->ucmessage;
const char16_t* linebuf = err->linebuf();
nsresult rv = scripterr->InitWithWindowID(
ucmessage ? nsDependentString(ucmessage) : EmptyString(),
fileUni,
uclinebuf ? nsDependentString(uclinebuf) : EmptyString(),
linebuf ? nsDependentString(linebuf, err->linebufLength()) : EmptyString(),
err->lineno,
column, err->flags, "XPConnect JavaScript", innerWindowID);
NS_ENSURE_SUCCESS(rv, NS_OK);

View File

@ -1249,16 +1249,15 @@ XPCConvert::JSErrorToXPCException(const char* message,
bestMessage.AssignLiteral("JavaScript Error");
}
const char16_t* uclinebuf =
static_cast<const char16_t*>(report->uclinebuf);
const char16_t* linebuf = report->linebuf();
data = new nsScriptError();
data->InitWithWindowID(
bestMessage,
NS_ConvertASCIItoUTF16(report->filename),
uclinebuf ? nsDependentString(uclinebuf) : EmptyString(),
linebuf ? nsDependentString(linebuf, report->linebufLength()) : EmptyString(),
report->lineno,
report->uctokenptr - report->uclinebuf, report->flags,
report->tokenOffset(), report->flags,
NS_LITERAL_CSTRING("XPConnect JavaScript"),
nsJSUtils::GetCurrentlyRunningCodeInnerWindowID(cx));
}

View File

@ -189,7 +189,7 @@ xpc::ErrorReport::Init(JSErrorReport* aReport, const char* aFallbackMessage,
mFileName.AssignWithConversion(aReport->filename);
}
mSourceLine = static_cast<const char16_t*>(aReport->uclinebuf);
mSourceLine.Assign(aReport->linebuf(), aReport->linebufLength());
mLineNumber = aReport->lineno;
mColumn = aReport->column;

View File

@ -322,7 +322,7 @@ PACErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)
nsString formattedMessage(NS_LITERAL_STRING("PAC Execution Error: "));
formattedMessage += report->ucmessage;
formattedMessage += NS_LITERAL_STRING(" [");
formattedMessage += report->uclinebuf;
formattedMessage.Append(report->linebuf(), report->linebufLength());
formattedMessage += NS_LITERAL_STRING("]");
PACLogToConsole(formattedMessage);
}