mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 772012: create a CompileError class. r=njn
This commit is contained in:
parent
5931a642f4
commit
8a473230cb
@ -407,65 +407,87 @@ TokenStream::reportStrictModeErrorNumberVA(ParseNode *pn, unsigned errorNumber,
|
||||
return reportCompileErrorNumberVA(pn, flags, errorNumber, args);
|
||||
}
|
||||
|
||||
void
|
||||
CompileError::throwError()
|
||||
{
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
if (!js_ErrorToException(cx, message, &report, NULL, NULL)) {
|
||||
/*
|
||||
* If debugErrorHook is present then we give it a chance to veto
|
||||
* sending the error on to the regular error reporter.
|
||||
*/
|
||||
bool reportError = true;
|
||||
if (JSDebugErrorHook hook = cx->runtime->debugHooks.debugErrorHook) {
|
||||
reportError = hook(cx, message, &report, cx->runtime->debugHooks.debugErrorHookData);
|
||||
}
|
||||
|
||||
/* Report the error */
|
||||
if (reportError && cx->errorReporter)
|
||||
cx->errorReporter(cx, message, &report);
|
||||
}
|
||||
}
|
||||
|
||||
CompileError::~CompileError()
|
||||
{
|
||||
cx->free_((void*)report.uclinebuf);
|
||||
cx->free_((void*)report.linebuf);
|
||||
cx->free_((void*)report.ucmessage);
|
||||
cx->free_(message);
|
||||
message = NULL;
|
||||
|
||||
if (report.messageArgs) {
|
||||
if (hasCharArgs) {
|
||||
unsigned i = 0;
|
||||
while (report.messageArgs[i])
|
||||
cx->free_((void*)report.messageArgs[i++]);
|
||||
}
|
||||
cx->free_(report.messageArgs);
|
||||
}
|
||||
|
||||
PodZero(&report);
|
||||
}
|
||||
|
||||
bool
|
||||
TokenStream::reportCompileErrorNumberVA(ParseNode *pn, unsigned flags, unsigned errorNumber,
|
||||
va_list args)
|
||||
{
|
||||
class ReportManager
|
||||
{
|
||||
JSContext *cx;
|
||||
JSErrorReport *report;
|
||||
bool hasCharArgs;
|
||||
bool strict = JSREPORT_IS_STRICT(flags);
|
||||
bool warning = JSREPORT_IS_WARNING(flags);
|
||||
|
||||
public:
|
||||
char *message;
|
||||
|
||||
ReportManager(JSContext *cx, JSErrorReport *report, bool hasCharArgs)
|
||||
: cx(cx), report(report), hasCharArgs(hasCharArgs), message(NULL)
|
||||
{}
|
||||
|
||||
~ReportManager() {
|
||||
cx->free_((void*)report->uclinebuf);
|
||||
cx->free_((void*)report->linebuf);
|
||||
cx->free_(message);
|
||||
cx->free_((void*)report->ucmessage);
|
||||
|
||||
if (report->messageArgs) {
|
||||
if (hasCharArgs) {
|
||||
unsigned i = 0;
|
||||
while (report->messageArgs[i])
|
||||
cx->free_((void *)report->messageArgs[i++]);
|
||||
}
|
||||
cx->free_((void *)report->messageArgs);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (JSREPORT_IS_STRICT(flags) && !cx->hasStrictOption())
|
||||
if (strict && !cx->hasStrictOption())
|
||||
return true;
|
||||
|
||||
bool warning = JSREPORT_IS_WARNING(flags);
|
||||
if (warning && cx->hasWErrorOption()) {
|
||||
flags &= ~JSREPORT_WARNING;
|
||||
warning = false;
|
||||
}
|
||||
|
||||
CompileError normalError(cx);
|
||||
CompileError *err = &normalError;
|
||||
const TokenPos *const tp = pn ? &pn->pn_pos : ¤tToken().pos;
|
||||
|
||||
JSErrorReport report;
|
||||
PodZero(&report);
|
||||
report.flags = flags;
|
||||
report.errorNumber = errorNumber;
|
||||
report.filename = filename;
|
||||
report.originPrincipals = originPrincipals;
|
||||
report.lineno = tp->begin.lineno;
|
||||
err->report.flags = flags;
|
||||
err->report.errorNumber = errorNumber;
|
||||
err->report.filename = filename;
|
||||
err->report.originPrincipals = originPrincipals;
|
||||
err->report.lineno = tp->begin.lineno;
|
||||
|
||||
bool hasCharArgs = !(flags & JSREPORT_UC);
|
||||
err->hasCharArgs = !(flags & JSREPORT_UC);
|
||||
|
||||
ReportManager mgr(cx, &report, hasCharArgs);
|
||||
|
||||
if (!js_ExpandErrorArguments(cx, js_GetErrorMessage, NULL, errorNumber, &mgr.message, &report,
|
||||
hasCharArgs, args)) {
|
||||
if (!js_ExpandErrorArguments(cx, js_GetErrorMessage, NULL, errorNumber, &err->message, &err->report,
|
||||
err->hasCharArgs, args)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -479,7 +501,7 @@ TokenStream::reportCompileErrorNumberVA(ParseNode *pn, unsigned flags, unsigned
|
||||
* means that any error involving a multi-line token (eg. an unterminated
|
||||
* multi-line string literal) won't have a context printed.
|
||||
*/
|
||||
if (report.lineno == lineno) {
|
||||
if (err->report.lineno == lineno) {
|
||||
const jschar *tokptr = linebase + tp->begin.index;
|
||||
|
||||
// We show only a portion (a "window") of the line around the erroneous
|
||||
@ -508,47 +530,20 @@ TokenStream::reportCompileErrorNumberVA(ParseNode *pn, unsigned flags, unsigned
|
||||
|
||||
// Unicode and char versions of the window into the offending source
|
||||
// line, without final \n.
|
||||
report.uclinebuf = windowBuf.extractWellSized();
|
||||
if (!report.uclinebuf)
|
||||
err->report.uclinebuf = windowBuf.extractWellSized();
|
||||
if (!err->report.uclinebuf)
|
||||
return false;
|
||||
report.linebuf = DeflateString(cx, report.uclinebuf, windowLength);
|
||||
if (!report.linebuf)
|
||||
err->report.linebuf = DeflateString(cx, err->report.uclinebuf, windowLength);
|
||||
if (!err->report.linebuf)
|
||||
return false;
|
||||
|
||||
// The lineno check above means we should only see single-line tokens here.
|
||||
JS_ASSERT(tp->begin.lineno == tp->end.lineno);
|
||||
report.tokenptr = report.linebuf + windowIndex;
|
||||
report.uctokenptr = report.uclinebuf + windowIndex;
|
||||
err->report.tokenptr = err->report.linebuf + windowIndex;
|
||||
err->report.uctokenptr = err->report.uclinebuf + windowIndex;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
if (!js_ErrorToException(cx, mgr.message, &report, NULL, NULL)) {
|
||||
/*
|
||||
* If debugErrorHook is present then we give it a chance to veto
|
||||
* sending the error on to the regular error reporter.
|
||||
*/
|
||||
bool reportError = true;
|
||||
if (JSDebugErrorHook hook = cx->runtime->debugHooks.debugErrorHook) {
|
||||
reportError = hook(cx, mgr.message, &report,
|
||||
cx->runtime->debugHooks.debugErrorHookData);
|
||||
}
|
||||
|
||||
/* Report the error */
|
||||
if (reportError && cx->errorReporter)
|
||||
cx->errorReporter(cx, mgr.message, &report);
|
||||
}
|
||||
err->throwError();
|
||||
|
||||
return warning;
|
||||
}
|
||||
|
@ -413,6 +413,20 @@ enum TokenStreamFlags
|
||||
|
||||
struct Parser;
|
||||
|
||||
struct CompileError {
|
||||
JSContext *cx;
|
||||
JSErrorReport report;
|
||||
char *message;
|
||||
bool hasCharArgs;
|
||||
CompileError(JSContext *cx)
|
||||
: cx(cx), message(NULL), hasCharArgs(false)
|
||||
{
|
||||
PodZero(&report);
|
||||
}
|
||||
~CompileError();
|
||||
void throwError();
|
||||
};
|
||||
|
||||
// Ideally, tokenizing would be entirely independent of context. But the
|
||||
// strict mode flag, which is in SharedContext, affects tokenizing, and
|
||||
// TokenStream needs to see it.
|
||||
|
Loading…
Reference in New Issue
Block a user