Bug 1447244 Part 3 - Track source ID in JSErrorReport and ErrorObject, r=jimb.

--HG--
extra : rebase_source : 474f8ebd0c15a00a5358edb3b189570d1bb68a69
This commit is contained in:
Brian Hackett 2019-01-16 11:59:34 -10:00
parent e2c9ceed8d
commit d9b3f4ab03
10 changed files with 67 additions and 25 deletions

View File

@ -93,6 +93,9 @@ class JSErrorBase {
// Source file name, URL, etc., or null.
const char* filename;
// Unique identifier for the script source.
unsigned sourceId;
// Source line number.
unsigned lineno;
@ -108,6 +111,7 @@ class JSErrorBase {
public:
JSErrorBase()
: filename(nullptr),
sourceId(0),
lineno(0),
column(0),
errorNumber(0),
@ -149,13 +153,16 @@ class JSErrorNotes {
~JSErrorNotes();
// Add an note to the given position.
bool addNoteASCII(JSContext* cx, const char* filename, unsigned lineno,
bool addNoteASCII(JSContext* cx, const char* filename,
unsigned sourceId, unsigned lineno,
unsigned column, JSErrorCallback errorCallback,
void* userRef, const unsigned errorNumber, ...);
bool addNoteLatin1(JSContext* cx, const char* filename, unsigned lineno,
bool addNoteLatin1(JSContext* cx, const char* filename,
unsigned sourceId, unsigned lineno,
unsigned column, JSErrorCallback errorCallback,
void* userRef, const unsigned errorNumber, ...);
bool addNoteUTF8(JSContext* cx, const char* filename, unsigned lineno,
bool addNoteUTF8(JSContext* cx, const char* filename,
unsigned sourceId, unsigned lineno,
unsigned column, JSErrorCallback errorCallback,
void* userRef, const unsigned errorNumber, ...);

View File

@ -464,7 +464,7 @@ void GeneralParser<ParseHandler, Unit>::reportMissingClosing(
char lineNumber[MaxWidth];
SprintfLiteral(lineNumber, "%" PRIu32, line);
if (!notes->addNoteASCII(pc_->sc()->cx_, getFilename(), line, column,
if (!notes->addNoteASCII(pc_->sc()->cx_, getFilename(), 0, line, column,
GetErrorMessage, nullptr, noteNumber, lineNumber,
columnNumber)) {
return;
@ -503,7 +503,7 @@ void GeneralParser<ParseHandler, Unit>::reportRedeclaration(
char lineNumber[MaxWidth];
SprintfLiteral(lineNumber, "%" PRIu32, line);
if (!notes->addNoteASCII(pc_->sc()->cx_, getFilename(), line, column,
if (!notes->addNoteASCII(pc_->sc()->cx_, getFilename(), 0, line, column,
GetErrorMessage, nullptr, JSMSG_REDECLARED_PREV,
lineNumber, columnNumber)) {
return;

View File

@ -759,7 +759,8 @@ MOZ_COLD void TokenStreamChars<Utf8Unit, AnyCharsAccess>::internalEncodingError(
uint32_t line, column;
computeLineAndColumn(offset, &line, &column);
if (!notes->addNoteASCII(anyChars.cx, anyChars.getFilename(), line, column,
if (!notes->addNoteASCII(anyChars.cx, anyChars.getFilename(),
0, line, column,
GetErrorMessage, nullptr, JSMSG_BAD_CODE_UNITS,
badUnitsStr)) {
break;

View File

@ -5300,7 +5300,8 @@ JSErrorNotes::JSErrorNotes() : notes_() {}
JSErrorNotes::~JSErrorNotes() {}
static UniquePtr<JSErrorNotes::Note> CreateErrorNoteVA(
JSContext* cx, const char* filename, unsigned lineno, unsigned column,
JSContext* cx, const char* filename, unsigned sourceId,
unsigned lineno, unsigned column,
JSErrorCallback errorCallback, void* userRef, const unsigned errorNumber,
ErrorArgumentsType argumentsType, va_list ap) {
auto note = MakeUnique<JSErrorNotes::Note>();
@ -5311,6 +5312,7 @@ static UniquePtr<JSErrorNotes::Note> CreateErrorNoteVA(
note->errorNumber = errorNumber;
note->filename = filename;
note->sourceId = sourceId;
note->lineno = lineno;
note->column = column;
@ -5323,12 +5325,14 @@ static UniquePtr<JSErrorNotes::Note> CreateErrorNoteVA(
}
bool JSErrorNotes::addNoteASCII(JSContext* cx, const char* filename,
unsigned sourceId,
unsigned lineno, unsigned column,
JSErrorCallback errorCallback, void* userRef,
const unsigned errorNumber, ...) {
va_list ap;
va_start(ap, errorNumber);
auto note = CreateErrorNoteVA(cx, filename, lineno, column, errorCallback,
auto note = CreateErrorNoteVA(cx, filename, sourceId, lineno, column,
errorCallback,
userRef, errorNumber, ArgumentsAreASCII, ap);
va_end(ap);
@ -5343,12 +5347,14 @@ bool JSErrorNotes::addNoteASCII(JSContext* cx, const char* filename,
}
bool JSErrorNotes::addNoteLatin1(JSContext* cx, const char* filename,
unsigned sourceId,
unsigned lineno, unsigned column,
JSErrorCallback errorCallback, void* userRef,
const unsigned errorNumber, ...) {
va_list ap;
va_start(ap, errorNumber);
auto note = CreateErrorNoteVA(cx, filename, lineno, column, errorCallback,
auto note = CreateErrorNoteVA(cx, filename, sourceId, lineno, column,
errorCallback,
userRef, errorNumber, ArgumentsAreLatin1, ap);
va_end(ap);
@ -5363,12 +5369,14 @@ bool JSErrorNotes::addNoteLatin1(JSContext* cx, const char* filename,
}
bool JSErrorNotes::addNoteUTF8(JSContext* cx, const char* filename,
unsigned sourceId,
unsigned lineno, unsigned column,
JSErrorCallback errorCallback, void* userRef,
const unsigned errorNumber, ...) {
va_list ap;
va_start(ap, errorNumber);
auto note = CreateErrorNoteVA(cx, filename, lineno, column, errorCallback,
auto note = CreateErrorNoteVA(cx, filename, sourceId, lineno, column,
errorCallback,
userRef, errorNumber, ArgumentsAreUTF8, ap);
va_end(ap);

View File

@ -280,6 +280,7 @@ static UniquePtr<T> CopyErrorHelper(JSContext* cx, T* report) {
MOZ_ASSERT(cursor == (uint8_t*)copy.get() + mallocSize);
/* Copy non-pointer members. */
copy->sourceId = report->sourceId;
copy->lineno = report->lineno;
copy->column = report->column;
copy->errorNumber = report->errorNumber;
@ -417,6 +418,7 @@ bool Error(JSContext* cx, unsigned argc, Value* vp) {
NonBuiltinFrameIter iter(cx, cx->realm()->principals());
RootedString fileName(cx);
uint32_t sourceId = 0;
if (args.length() > 1) {
fileName = ToString<CanGC>(cx, args[1]);
} else {
@ -425,6 +427,9 @@ bool Error(JSContext* cx, unsigned argc, Value* vp) {
if (const char* cfilename = iter.filename()) {
fileName = JS_NewStringCopyZ(cx, cfilename);
}
if (iter.hasScript()) {
sourceId = iter.script()->scriptSource()->id();
}
}
}
if (!fileName) {
@ -447,8 +452,9 @@ bool Error(JSContext* cx, unsigned argc, Value* vp) {
}
RootedObject obj(cx,
ErrorObject::create(cx, exnType, stack, fileName, lineNumber,
columnNumber, nullptr, message, proto));
ErrorObject::create(cx, exnType, stack, fileName, sourceId,
lineNumber, columnNumber, nullptr,
message, proto));
if (!obj) {
return false;
}
@ -649,6 +655,7 @@ void js::ErrorToException(JSContext* cx, JSErrorReport* reportp,
return;
}
uint32_t sourceId = reportp->sourceId;
uint32_t lineNumber = reportp->lineno;
uint32_t columnNumber = reportp->column;
@ -663,7 +670,7 @@ void js::ErrorToException(JSContext* cx, JSErrorReport* reportp,
}
ErrorObject* errObject =
ErrorObject::create(cx, exnType, stack, fileName, lineNumber,
ErrorObject::create(cx, exnType, stack, fileName, sourceId, lineNumber,
columnNumber, std::move(report), messageStr);
if (!errObject) {
return;
@ -879,6 +886,7 @@ bool ErrorReport::init(JSContext* cx, HandleValue exn,
ownedReport.lineno = lineno;
ownedReport.exnType = JSEXN_INTERNALERR;
ownedReport.column = column;
if (str) {
// Note that using |str| for |message_| here is kind of wrong,
// because |str| is supposed to be of the format
@ -950,6 +958,8 @@ bool ErrorReport::populateUncaughtExceptionReportUTF8VA(JSContext* cx,
if (!iter.done()) {
ownedReport.filename = iter.filename();
uint32_t column;
ownedReport.sourceId =
iter.script() ? iter.script()->scriptSource()->id() : 0;
ownedReport.lineno = iter.computeLine(&column);
ownedReport.column = FixupColumnForDisplay(column);
ownedReport.isMuted = iter.mutedErrors();
@ -987,13 +997,15 @@ JSObject* js::CopyErrorObject(JSContext* cx, Handle<ErrorObject*> err) {
if (!cx->compartment()->wrap(cx, &stack)) {
return nullptr;
}
uint32_t sourceId = err->sourceId();
uint32_t lineNumber = err->lineNumber();
uint32_t columnNumber = err->columnNumber();
JSExnType errorType = err->type();
// Create the Error object.
return ErrorObject::create(cx, errorType, stack, fileName, lineNumber,
columnNumber, std::move(copyReport), message);
return ErrorObject::create(cx, errorType, stack, fileName, sourceId,
lineNumber, columnNumber,
std::move(copyReport), message);
}
JS_PUBLIC_API bool JS::CreateError(JSContext* cx, JSExnType type,
@ -1013,7 +1025,7 @@ JS_PUBLIC_API bool JS::CreateError(JSContext* cx, JSExnType type,
}
JSObject* obj =
js::ErrorObject::create(cx, type, stack, fileName, lineNumber,
js::ErrorObject::create(cx, type, stack, fileName, 0, lineNumber,
columnNumber, std::move(rep), message);
if (!obj) {
return false;

View File

@ -16,6 +16,11 @@ inline JSString* js::ErrorObject::fileName(JSContext* cx) const {
return slot.isString() ? slot.toString() : cx->names().empty;
}
inline uint32_t js::ErrorObject::sourceId() const {
const HeapSlot& slot = getReservedSlotRef(SOURCEID_SLOT);
return slot.isInt32() ? slot.toInt32() : 0;
}
inline uint32_t js::ErrorObject::lineNumber() const {
const HeapSlot& slot = getReservedSlotRef(LINENUMBER_SLOT);
return slot.isInt32() ? slot.toInt32() : 0;

View File

@ -46,7 +46,8 @@ using namespace js;
JSExnType type,
UniquePtr<JSErrorReport> errorReport,
HandleString fileName,
HandleObject stack, uint32_t lineNumber,
HandleObject stack, uint32_t sourceId,
uint32_t lineNumber,
uint32_t columnNumber,
HandleString message) {
AssertObjectIsSavedFrameOrWrapper(cx, stack);
@ -95,6 +96,7 @@ using namespace js;
if (message) {
obj->setSlotWithType(cx, messageShape, StringValue(message));
}
obj->initReservedSlot(SOURCEID_SLOT, Int32Value(sourceId));
// When recording/replaying and running on the main thread, get a counter
// which the devtools can use to warp to this point in the future.
@ -114,7 +116,8 @@ using namespace js;
/* static */ ErrorObject* js::ErrorObject::create(
JSContext* cx, JSExnType errorType, HandleObject stack,
HandleString fileName, uint32_t lineNumber, uint32_t columnNumber,
HandleString fileName, uint32_t sourceId,
uint32_t lineNumber, uint32_t columnNumber,
UniquePtr<JSErrorReport> report, HandleString message,
HandleObject protoArg /* = nullptr */) {
AssertObjectIsSavedFrameOrWrapper(cx, stack);
@ -139,7 +142,7 @@ using namespace js;
}
if (!ErrorObject::init(cx, errObject, errorType, std::move(report), fileName,
stack, lineNumber, columnNumber, message)) {
stack, sourceId, lineNumber, columnNumber, message)) {
return nullptr;
}
@ -167,6 +170,7 @@ JSErrorReport* js::ErrorObject::getOrCreateErrorReport(JSContext* cx) {
report.filename = filenameStr.get();
// Coordinates.
report.sourceId = sourceId();
report.lineno = lineNumber();
report.column = columnNumber();

View File

@ -31,7 +31,7 @@ class ErrorObject : public NativeObject {
static bool init(JSContext* cx, Handle<ErrorObject*> obj, JSExnType type,
UniquePtr<JSErrorReport> errorReport, HandleString fileName,
HandleObject stack, uint32_t lineNumber,
HandleObject stack, uint32_t sourceId, uint32_t lineNumber,
uint32_t columnNumber, HandleString message);
static const ClassSpec classSpecs[JSEXN_ERROR_LIMIT];
@ -45,7 +45,8 @@ class ErrorObject : public NativeObject {
static const uint32_t LINENUMBER_SLOT = FILENAME_SLOT + 1;
static const uint32_t COLUMNNUMBER_SLOT = LINENUMBER_SLOT + 1;
static const uint32_t MESSAGE_SLOT = COLUMNNUMBER_SLOT + 1;
static const uint32_t TIME_WARP_SLOT = MESSAGE_SLOT + 1;
static const uint32_t SOURCEID_SLOT = MESSAGE_SLOT + 1;
static const uint32_t TIME_WARP_SLOT = SOURCEID_SLOT + 1;
static const uint32_t RESERVED_SLOTS = TIME_WARP_SLOT + 1;
@ -67,8 +68,8 @@ class ErrorObject : public NativeObject {
// property with that value; otherwise the error will have no .message
// property.
static ErrorObject* create(JSContext* cx, JSExnType type, HandleObject stack,
HandleString fileName, uint32_t lineNumber,
uint32_t columnNumber,
HandleString fileName, uint32_t sourceId,
uint32_t lineNumber, uint32_t columnNumber,
UniquePtr<JSErrorReport> report,
HandleString message,
HandleObject proto = nullptr);
@ -95,6 +96,7 @@ class ErrorObject : public NativeObject {
JSErrorReport* getOrCreateErrorReport(JSContext* cx);
inline JSString* fileName(JSContext* cx) const;
inline uint32_t sourceId() const;
inline uint32_t lineNumber() const;
inline uint32_t columnNumber() const;
inline JSObject* stack() const;

View File

@ -258,6 +258,9 @@ static void PopulateReportBlame(JSContext* cx, JSErrorReport* report) {
}
report->filename = iter.filename();
if (iter.hasScript()) {
report->sourceId = iter.script()->scriptSource()->id();
}
uint32_t column;
report->lineno = iter.computeLine(&column);
report->column = FixupColumnForDisplay(column);

View File

@ -2832,8 +2832,8 @@ static bool Reject(JSContext* cx, const CompileArgs& args,
}
RootedObject errorObj(
cx, ErrorObject::create(cx, JSEXN_WASMCOMPILEERROR, stack, filename, line,
0, nullptr, message));
cx, ErrorObject::create(cx, JSEXN_WASMCOMPILEERROR, stack, filename, 0,
line, 0, nullptr, message));
if (!errorObj) {
return false;
}