mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 19:04:45 +00:00
Bug 1283712 - Part 1: Add JSErrorBase, JSErrorNotes, JSErrorNotes::Note, and JSErrorReport.{notes,freeNotes}. r=jwalden
This commit is contained in:
parent
6e3978d74d
commit
5b355e2da8
131
js/src/jsapi.cpp
131
js/src/jsapi.cpp
@ -69,7 +69,6 @@
|
||||
#include "js/Proxy.h"
|
||||
#include "js/SliceBudget.h"
|
||||
#include "js/StructuredClone.h"
|
||||
#include "js/UniquePtr.h"
|
||||
#include "js/Utility.h"
|
||||
#include "vm/AsyncFunction.h"
|
||||
#include "vm/DateObject.h"
|
||||
@ -6262,7 +6261,7 @@ JSErrorReport::freeLinebuf()
|
||||
}
|
||||
|
||||
JSString*
|
||||
JSErrorReport::newMessageString(JSContext* cx)
|
||||
JSErrorBase::newMessageString(JSContext* cx)
|
||||
{
|
||||
if (!message_)
|
||||
return cx->runtime()->emptyString;
|
||||
@ -6271,7 +6270,7 @@ JSErrorReport::newMessageString(JSContext* cx)
|
||||
}
|
||||
|
||||
void
|
||||
JSErrorReport::freeMessage()
|
||||
JSErrorBase::freeMessage()
|
||||
{
|
||||
if (ownsMessage_) {
|
||||
js_free((void*)message_.get());
|
||||
@ -6280,6 +6279,132 @@ JSErrorReport::freeMessage()
|
||||
message_ = JS::ConstUTF8CharsZ();
|
||||
}
|
||||
|
||||
JSErrorNotes::JSErrorNotes()
|
||||
: notes_()
|
||||
{}
|
||||
|
||||
JSErrorNotes::~JSErrorNotes()
|
||||
{
|
||||
}
|
||||
|
||||
static UniquePtr<JSErrorNotes::Note>
|
||||
CreateErrorNoteVA(JSContext* cx,
|
||||
const char* filename, unsigned lineno, unsigned column,
|
||||
JSErrorCallback errorCallback, void* userRef,
|
||||
const unsigned errorNumber,
|
||||
ErrorArgumentsType argumentsType, va_list ap)
|
||||
{
|
||||
auto note = MakeUnique<JSErrorNotes::Note>();
|
||||
if (!note)
|
||||
return nullptr;
|
||||
|
||||
note->errorNumber = errorNumber;
|
||||
note->filename = filename;
|
||||
note->lineno = lineno;
|
||||
note->column = column;
|
||||
|
||||
if (!ExpandErrorArgumentsVA(cx, errorCallback, userRef, errorNumber,
|
||||
nullptr, argumentsType, note.get(), ap)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return note;
|
||||
}
|
||||
|
||||
bool
|
||||
JSErrorNotes::addNoteASCII(JSContext* cx,
|
||||
const char* filename, 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, userRef,
|
||||
errorNumber, ArgumentsAreASCII, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (!note)
|
||||
return false;
|
||||
if (!notes_.append(Move(note)))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
JSErrorNotes::addNoteLatin1(JSContext* cx,
|
||||
const char* filename, 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, userRef,
|
||||
errorNumber, ArgumentsAreLatin1, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (!note)
|
||||
return false;
|
||||
if (!notes_.append(Move(note)))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
JSErrorNotes::addNoteUTF8(JSContext* cx,
|
||||
const char* filename, 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, userRef,
|
||||
errorNumber, ArgumentsAreUTF8, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (!note)
|
||||
return false;
|
||||
if (!notes_.append(Move(note)))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t
|
||||
JSErrorNotes::length()
|
||||
{
|
||||
return notes_.length();
|
||||
}
|
||||
|
||||
UniquePtr<JSErrorNotes>
|
||||
JSErrorNotes::copy(JSContext* cx)
|
||||
{
|
||||
auto copiedNotes = MakeUnique<JSErrorNotes>();
|
||||
if (!copiedNotes)
|
||||
return nullptr;
|
||||
|
||||
for (auto&& note : *this) {
|
||||
js::UniquePtr<JSErrorNotes::Note> copied(CopyErrorNote(cx, note.get()));
|
||||
if (!copied)
|
||||
return nullptr;
|
||||
|
||||
if (!copiedNotes->notes_.append(Move(copied)))
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return copiedNotes;
|
||||
}
|
||||
|
||||
JSErrorNotes::iterator
|
||||
JSErrorNotes::begin()
|
||||
{
|
||||
return iterator(notes_.begin());
|
||||
}
|
||||
|
||||
JSErrorNotes::iterator
|
||||
JSErrorNotes::end()
|
||||
{
|
||||
return iterator(notes_.end());
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_ThrowStopIteration(JSContext* cx)
|
||||
{
|
||||
|
192
js/src/jsapi.h
192
js/src/jsapi.h
@ -17,6 +17,7 @@
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/Variant.h"
|
||||
|
||||
#include <iterator>
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
@ -36,6 +37,7 @@
|
||||
#include "js/RefCounted.h"
|
||||
#include "js/RootingAPI.h"
|
||||
#include "js/TracingAPI.h"
|
||||
#include "js/UniquePtr.h"
|
||||
#include "js/Utility.h"
|
||||
#include "js/Value.h"
|
||||
#include "js/Vector.h"
|
||||
@ -5389,65 +5391,43 @@ JS_ReportOutOfMemory(JSContext* cx);
|
||||
extern JS_PUBLIC_API(void)
|
||||
JS_ReportAllocationOverflow(JSContext* cx);
|
||||
|
||||
class JSErrorReport
|
||||
/**
|
||||
* Base class that implements parts shared by JSErrorReport and
|
||||
* JSErrorNotes::Note.
|
||||
*/
|
||||
class JSErrorBase
|
||||
{
|
||||
// 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'.
|
||||
size_t linebufLength_;
|
||||
|
||||
// The 0-based offset of error token in linebuf_.
|
||||
size_t tokenOffset_;
|
||||
|
||||
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)
|
||||
JSErrorBase()
|
||||
: filename(nullptr), lineno(0), column(0),
|
||||
errorNumber(0),
|
||||
ownsMessage_(false)
|
||||
{}
|
||||
|
||||
~JSErrorReport() {
|
||||
freeLinebuf();
|
||||
~JSErrorBase() {
|
||||
freeMessage();
|
||||
}
|
||||
|
||||
const char* filename; /* source file name, URL, etc., or null */
|
||||
unsigned lineno; /* source line number */
|
||||
unsigned column; /* zero-based column index in line */
|
||||
unsigned flags; /* error/warning, etc. */
|
||||
unsigned errorNumber; /* the error number, e.g. see js.msg */
|
||||
int16_t exnType; /* One of the JSExnType constants */
|
||||
bool isMuted : 1; /* See the comment in ReadOnlyCompileOptions. */
|
||||
// Source file name, URL, etc., or null.
|
||||
const char* filename;
|
||||
|
||||
// Source line number.
|
||||
unsigned lineno;
|
||||
|
||||
// Zero-based column index in line.
|
||||
unsigned column;
|
||||
|
||||
// the error number, e.g. see js.msg.
|
||||
unsigned errorNumber;
|
||||
|
||||
private:
|
||||
bool ownsLinebuf_ : 1;
|
||||
bool ownsMessage_ : 1;
|
||||
|
||||
public:
|
||||
const char16_t* linebuf() const {
|
||||
return linebuf_;
|
||||
}
|
||||
size_t linebufLength() const {
|
||||
return linebufLength_;
|
||||
}
|
||||
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_;
|
||||
}
|
||||
@ -5463,9 +5443,135 @@ class JSErrorReport
|
||||
|
||||
JSString* newMessageString(JSContext* cx);
|
||||
|
||||
private:
|
||||
void freeMessage();
|
||||
};
|
||||
|
||||
/**
|
||||
* Notes associated with JSErrorReport.
|
||||
*/
|
||||
class JSErrorNotes
|
||||
{
|
||||
public:
|
||||
class Note : public JSErrorBase
|
||||
{};
|
||||
|
||||
private:
|
||||
// Stores pointers to each note.
|
||||
js::Vector<js::UniquePtr<Note>, 1, js::SystemAllocPolicy> notes_;
|
||||
|
||||
public:
|
||||
JSErrorNotes();
|
||||
~JSErrorNotes();
|
||||
|
||||
// Add an note to the given position.
|
||||
bool addNoteASCII(JSContext* cx,
|
||||
const char* filename, unsigned lineno, unsigned column,
|
||||
JSErrorCallback errorCallback, void* userRef,
|
||||
const unsigned errorNumber, ...);
|
||||
bool addNoteLatin1(JSContext* cx,
|
||||
const char* filename, unsigned lineno, unsigned column,
|
||||
JSErrorCallback errorCallback, void* userRef,
|
||||
const unsigned errorNumber, ...);
|
||||
bool addNoteUTF8(JSContext* cx,
|
||||
const char* filename, unsigned lineno, unsigned column,
|
||||
JSErrorCallback errorCallback, void* userRef,
|
||||
const unsigned errorNumber, ...);
|
||||
|
||||
size_t length();
|
||||
|
||||
// Create a deep copy of notes.
|
||||
js::UniquePtr<JSErrorNotes> copy(JSContext* cx);
|
||||
|
||||
class iterator : public std::iterator<std::input_iterator_tag, js::UniquePtr<Note>>
|
||||
{
|
||||
js::UniquePtr<Note>* note_;
|
||||
public:
|
||||
explicit iterator(js::UniquePtr<Note>* note = nullptr) : note_(note)
|
||||
{}
|
||||
|
||||
bool operator==(iterator other) const {
|
||||
return note_ == other.note_;
|
||||
}
|
||||
bool operator!=(iterator other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
iterator& operator++() {
|
||||
note_++;
|
||||
return *this;
|
||||
}
|
||||
reference operator*() {
|
||||
return *note_;
|
||||
}
|
||||
};
|
||||
iterator begin();
|
||||
iterator end();
|
||||
};
|
||||
|
||||
/**
|
||||
* Describes a single error or warning that occurs in the execution of script.
|
||||
*/
|
||||
class JSErrorReport : public JSErrorBase
|
||||
{
|
||||
// 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'.
|
||||
size_t linebufLength_;
|
||||
|
||||
// The 0-based offset of error token in linebuf_.
|
||||
size_t tokenOffset_;
|
||||
|
||||
public:
|
||||
JSErrorReport()
|
||||
: linebuf_(nullptr), linebufLength_(0), tokenOffset_(0),
|
||||
notes(nullptr),
|
||||
flags(0), exnType(0), isMuted(false),
|
||||
ownsLinebuf_(false)
|
||||
{}
|
||||
|
||||
~JSErrorReport() {
|
||||
freeLinebuf();
|
||||
}
|
||||
|
||||
// Associated notes, or nullptr if there's no note.
|
||||
js::UniquePtr<JSErrorNotes> notes;
|
||||
|
||||
// error/warning, etc.
|
||||
unsigned flags;
|
||||
|
||||
// One of the JSExnType constants.
|
||||
int16_t exnType;
|
||||
|
||||
// See the comment in ReadOnlyCompileOptions.
|
||||
bool isMuted : 1;
|
||||
|
||||
private:
|
||||
bool ownsLinebuf_ : 1;
|
||||
|
||||
public:
|
||||
const char16_t* linebuf() const {
|
||||
return linebuf_;
|
||||
}
|
||||
size_t linebufLength() const {
|
||||
return linebufLength_;
|
||||
}
|
||||
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);
|
||||
|
||||
private:
|
||||
void freeLinebuf();
|
||||
};
|
||||
|
||||
/*
|
||||
* JSErrorReport flag values. These may be freely composed.
|
||||
*/
|
||||
|
@ -622,6 +622,18 @@ class MOZ_RAII AutoMessageArgs
|
||||
}
|
||||
};
|
||||
|
||||
static void
|
||||
SetExnType(JSErrorReport* reportp, int16_t exnType)
|
||||
{
|
||||
reportp->exnType = exnType;
|
||||
}
|
||||
|
||||
static void
|
||||
SetExnType(JSErrorNotes::Note* notep, int16_t exnType)
|
||||
{
|
||||
// Do nothing for JSErrorNotes::Note.
|
||||
}
|
||||
|
||||
/*
|
||||
* The arguments from ap need to be packaged up into an array and stored
|
||||
* into the report struct.
|
||||
@ -633,12 +645,13 @@ class MOZ_RAII AutoMessageArgs
|
||||
*
|
||||
* Returns true if the expansion succeeds (can fail if out of memory).
|
||||
*/
|
||||
template <typename T>
|
||||
bool
|
||||
js::ExpandErrorArgumentsVA(JSContext* cx, JSErrorCallback callback,
|
||||
ExpandErrorArgumentsHelper(JSContext* cx, JSErrorCallback callback,
|
||||
void* userRef, const unsigned errorNumber,
|
||||
const char16_t** messageArgs,
|
||||
ErrorArgumentsType argumentsType,
|
||||
JSErrorReport* reportp, va_list ap)
|
||||
T* reportp, va_list ap)
|
||||
{
|
||||
const JSErrorFormatString* efs;
|
||||
|
||||
@ -651,7 +664,7 @@ js::ExpandErrorArgumentsVA(JSContext* cx, JSErrorCallback callback,
|
||||
}
|
||||
|
||||
if (efs) {
|
||||
reportp->exnType = efs->exnType;
|
||||
SetExnType(reportp, efs->exnType);
|
||||
|
||||
MOZ_ASSERT_IF(argumentsType == ArgumentsAreASCII, JS::StringIsASCII(efs->format));
|
||||
|
||||
@ -734,6 +747,28 @@ js::ExpandErrorArgumentsVA(JSContext* cx, JSErrorCallback callback,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
js::ExpandErrorArgumentsVA(JSContext* cx, JSErrorCallback callback,
|
||||
void* userRef, const unsigned errorNumber,
|
||||
const char16_t** messageArgs,
|
||||
ErrorArgumentsType argumentsType,
|
||||
JSErrorReport* reportp, va_list ap)
|
||||
{
|
||||
return ExpandErrorArgumentsHelper(cx, callback, userRef, errorNumber,
|
||||
messageArgs, argumentsType, reportp, ap);
|
||||
}
|
||||
|
||||
bool
|
||||
js::ExpandErrorArgumentsVA(JSContext* cx, JSErrorCallback callback,
|
||||
void* userRef, const unsigned errorNumber,
|
||||
const char16_t** messageArgs,
|
||||
ErrorArgumentsType argumentsType,
|
||||
JSErrorNotes::Note* notep, va_list ap)
|
||||
{
|
||||
return ExpandErrorArgumentsHelper(cx, callback, userRef, errorNumber,
|
||||
messageArgs, argumentsType, notep, ap);
|
||||
}
|
||||
|
||||
bool
|
||||
js::ReportErrorNumberVA(JSContext* cx, unsigned flags, JSErrorCallback callback,
|
||||
void* userRef, const unsigned errorNumber,
|
||||
|
@ -993,6 +993,13 @@ ExpandErrorArgumentsVA(JSContext* cx, JSErrorCallback callback,
|
||||
ErrorArgumentsType argumentsType,
|
||||
JSErrorReport* reportp, va_list ap);
|
||||
|
||||
extern bool
|
||||
ExpandErrorArgumentsVA(JSContext* cx, JSErrorCallback callback,
|
||||
void* userRef, const unsigned errorNumber,
|
||||
const char16_t** messageArgs,
|
||||
ErrorArgumentsType argumentsType,
|
||||
JSErrorNotes::Note* notep, va_list ap);
|
||||
|
||||
/* |callee| requires a usage string provided by JS_DefineFunctionsWithHelp. */
|
||||
extern void
|
||||
ReportUsageErrorASCII(JSContext* cx, HandleObject callee, const char* msg);
|
||||
|
114
js/src/jsexn.cpp
114
js/src/jsexn.cpp
@ -205,28 +205,77 @@ ErrorObject::classes[JSEXN_ERROR_LIMIT] = {
|
||||
IMPLEMENT_ERROR_CLASS(RuntimeError)
|
||||
};
|
||||
|
||||
JSErrorReport*
|
||||
js::CopyErrorReport(JSContext* cx, JSErrorReport* report)
|
||||
size_t
|
||||
ExtraMallocSize(JSErrorReport* report)
|
||||
{
|
||||
if (report->linebuf())
|
||||
return (report->linebufLength() + 1) * sizeof(char16_t);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t
|
||||
ExtraMallocSize(JSErrorNotes::Note* note)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool
|
||||
CopyExtraData(JSContext* cx, uint8_t** cursor, JSErrorReport* copy, JSErrorReport* report)
|
||||
{
|
||||
if (report->linebuf()) {
|
||||
size_t linebufSize = (report->linebufLength() + 1) * sizeof(char16_t);
|
||||
const char16_t* linebufCopy = (const char16_t*)(*cursor);
|
||||
js_memcpy(*cursor, report->linebuf(), linebufSize);
|
||||
*cursor += linebufSize;
|
||||
copy->initBorrowedLinebuf(linebufCopy, report->linebufLength(), report->tokenOffset());
|
||||
}
|
||||
|
||||
/* Copy non-pointer members. */
|
||||
copy->isMuted = report->isMuted;
|
||||
copy->exnType = report->exnType;
|
||||
|
||||
/* Note that this is before it gets flagged with JSREPORT_EXCEPTION */
|
||||
copy->flags = report->flags;
|
||||
|
||||
/* Deep copy notes. */
|
||||
if (report->notes) {
|
||||
auto copiedNotes = report->notes->copy(cx);
|
||||
if (!copiedNotes)
|
||||
return false;
|
||||
copy->notes = Move(copiedNotes);
|
||||
} else {
|
||||
copy->notes.reset(nullptr);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CopyExtraData(JSContext* cx, uint8_t** cursor, JSErrorNotes::Note* copy, JSErrorNotes::Note* report)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static T*
|
||||
CopyErrorHelper(JSContext* cx, T* report)
|
||||
{
|
||||
/*
|
||||
* We use a single malloc block to make a deep copy of JSErrorReport with
|
||||
* We use a single malloc block to make a deep copy of JSErrorReport or
|
||||
* JSErrorNotes::Note, except JSErrorNotes linked from JSErrorReport with
|
||||
* the following layout:
|
||||
* JSErrorReport
|
||||
* JSErrorReport or JSErrorNotes::Note
|
||||
* char array with characters for message_
|
||||
* char16_t array with characters for linebuf
|
||||
* char array with characters for filename
|
||||
* char16_t array with characters for linebuf (only for JSErrorReport)
|
||||
* Such layout together with the properties enforced by the following
|
||||
* asserts does not need any extra alignment padding.
|
||||
*/
|
||||
JS_STATIC_ASSERT(sizeof(JSErrorReport) % sizeof(const char*) == 0);
|
||||
JS_STATIC_ASSERT(sizeof(T) % sizeof(const char*) == 0);
|
||||
JS_STATIC_ASSERT(sizeof(const char*) % sizeof(char16_t) == 0);
|
||||
|
||||
#define JS_CHARS_SIZE(chars) ((js_strlen(chars) + 1) * sizeof(char16_t))
|
||||
|
||||
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 messageSize = 0;
|
||||
if (report->message())
|
||||
messageSize = strlen(report->message().c_str()) + 1;
|
||||
@ -235,13 +284,13 @@ js::CopyErrorReport(JSContext* cx, JSErrorReport* report)
|
||||
* 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(T) + messageSize + filenameSize + ExtraMallocSize(report);
|
||||
uint8_t* cursor = cx->pod_calloc<uint8_t>(mallocSize);
|
||||
if (!cursor)
|
||||
return nullptr;
|
||||
|
||||
JSErrorReport* copy = (JSErrorReport*)cursor;
|
||||
cursor += sizeof(JSErrorReport);
|
||||
T* copy = new (cursor) T();
|
||||
cursor += sizeof(T);
|
||||
|
||||
if (report->message()) {
|
||||
copy->initBorrowedMessage((const char*)cursor);
|
||||
@ -249,33 +298,40 @@ js::CopyErrorReport(JSContext* cx, JSErrorReport* report)
|
||||
cursor += messageSize;
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
if (report->filename) {
|
||||
copy->filename = (const char*)cursor;
|
||||
js_memcpy(cursor, report->filename, filenameSize);
|
||||
cursor += filenameSize;
|
||||
}
|
||||
MOZ_ASSERT(cursor + filenameSize == (uint8_t*)copy + mallocSize);
|
||||
|
||||
if (!CopyExtraData(cx, &cursor, copy, report)) {
|
||||
/* js_delete calls destructor for T and js_free for pod_calloc. */
|
||||
js_delete(copy);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(cursor == (uint8_t*)copy + mallocSize);
|
||||
|
||||
/* Copy non-pointer members. */
|
||||
copy->isMuted = report->isMuted;
|
||||
copy->lineno = report->lineno;
|
||||
copy->column = report->column;
|
||||
copy->errorNumber = report->errorNumber;
|
||||
copy->exnType = report->exnType;
|
||||
|
||||
/* Note that this is before it gets flagged with JSREPORT_EXCEPTION */
|
||||
copy->flags = report->flags;
|
||||
|
||||
#undef JS_CHARS_SIZE
|
||||
return copy;
|
||||
}
|
||||
|
||||
JSErrorNotes::Note*
|
||||
js::CopyErrorNote(JSContext* cx, JSErrorNotes::Note* note)
|
||||
{
|
||||
return CopyErrorHelper(cx, note);
|
||||
}
|
||||
|
||||
JSErrorReport*
|
||||
js::CopyErrorReport(JSContext* cx, JSErrorReport* report)
|
||||
{
|
||||
return CopyErrorHelper(cx, report);
|
||||
}
|
||||
|
||||
struct SuppressErrorsGuard
|
||||
{
|
||||
JSContext* cx;
|
||||
@ -326,7 +382,7 @@ exn_finalize(FreeOp* fop, JSObject* obj)
|
||||
{
|
||||
MOZ_ASSERT(fop->maybeOnHelperThread());
|
||||
if (JSErrorReport* report = obj->as<ErrorObject>().getErrorReport())
|
||||
fop->free_(report);
|
||||
fop->delete_(report);
|
||||
}
|
||||
|
||||
JSErrorReport*
|
||||
|
@ -18,6 +18,9 @@
|
||||
namespace js {
|
||||
class ErrorObject;
|
||||
|
||||
JSErrorNotes::Note*
|
||||
CopyErrorNote(JSContext* cx, JSErrorNotes::Note* note);
|
||||
|
||||
JSErrorReport*
|
||||
CopyErrorReport(JSContext* cx, JSErrorReport* report);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user