Mypal/js/src/vm/ErrorReporting.cpp

125 lines
3.9 KiB
C++

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "vm/ErrorReporting.h"
#include "mozilla/Move.h"
#include <stdarg.h>
#include "jscntxt.h"
#include "jsexn.h"
using mozilla::Move;
using JS::UniqueTwoByteChars;
void
CallWarningReporter(JSContext* cx, JSErrorReport* reportp)
{
MOZ_ASSERT(reportp);
MOZ_ASSERT(JSREPORT_IS_WARNING(reportp->flags));
if (JS::WarningReporter warningReporter = cx->runtime()->warningReporter)
warningReporter(cx, reportp);
}
void
CompileError::throwError(JSContext* cx)
{
if (JSREPORT_IS_WARNING(flags)) {
CallWarningReporter(cx, this);
return;
}
// If there's a runtime exception type associated with this error
// number, set that as the pending exception. For errors occuring at
// compile time, this is very likely to be a JSEXN_SYNTAXERR.
//
// If an exception is thrown but not caught, the JSREPORT_EXCEPTION
// flag will be set in report.flags. Proper behavior for an error
// reporter is to ignore a report with this flag for all but top-level
// compilation errors. The exception will remain pending, and so long
// 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);
}
bool
ReportCompileWarning(JSContext* cx, ErrorMetadata&& metadata, UniquePtr<JSErrorNotes> notes,
unsigned flags, unsigned errorNumber, va_list args)
{
// On the main thread, report the error immediately. When compiling off
// thread, save the error so that the thread finishing the parse can report
// it later.
CompileError tempErr;
CompileError* err = &tempErr;
if (!cx->isJSContext() && !cx->addPendingCompileError(&err)) {
return false;
}
err->notes = Move(notes);
err->flags = flags;
err->errorNumber = errorNumber;
err->filename = metadata.filename;
err->lineno = metadata.lineNumber;
err->column = metadata.columnNumber;
err->isMuted = metadata.isMuted;
if (UniqueTwoByteChars lineOfContext = Move(metadata.lineOfContext))
err->initOwnedLinebuf(lineOfContext.release(), metadata.lineLength, metadata.tokenOffset);
if (!ExpandErrorArgumentsVA(cx, GetErrorMessage, nullptr, errorNumber,
nullptr, ArgumentsAreLatin1, err, args))
{
return false;
}
if (cx->isJSContext()) {
err->throwError(cx->asJSContext());
}
return true;
}
void
ReportCompileError(JSContext* cx, ErrorMetadata&& metadata, UniquePtr<JSErrorNotes> notes,
unsigned flags, unsigned errorNumber, va_list args)
{
// On the main thread, report the error immediately. When compiling off
// thread, save the error so that the thread finishing the parse can report
// it later.
CompileError tempErr;
CompileError* err = &tempErr;
if (!cx->isJSContext() && !cx->addPendingCompileError(&err)) {
return;
}
err->notes = Move(notes);
err->flags = flags;
err->errorNumber = errorNumber;
err->filename = metadata.filename;
err->lineno = metadata.lineNumber;
err->column = metadata.columnNumber;
err->isMuted = metadata.isMuted;
if (UniqueTwoByteChars lineOfContext = Move(metadata.lineOfContext))
err->initOwnedLinebuf(lineOfContext.release(), metadata.lineLength, metadata.tokenOffset);
if (!ExpandErrorArgumentsVA(cx, GetErrorMessage, nullptr, errorNumber,
nullptr, ArgumentsAreLatin1, err, args))
{
return;
}
if (cx->isJSContext()) {
err->throwError(cx->asJSContext());
}
}