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);
|
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
|
bool
|
||||||
TokenStream::reportCompileErrorNumberVA(ParseNode *pn, unsigned flags, unsigned errorNumber,
|
TokenStream::reportCompileErrorNumberVA(ParseNode *pn, unsigned flags, unsigned errorNumber,
|
||||||
va_list args)
|
va_list args)
|
||||||
{
|
{
|
||||||
class ReportManager
|
bool strict = JSREPORT_IS_STRICT(flags);
|
||||||
{
|
bool warning = JSREPORT_IS_WARNING(flags);
|
||||||
JSContext *cx;
|
|
||||||
JSErrorReport *report;
|
|
||||||
bool hasCharArgs;
|
|
||||||
|
|
||||||
public:
|
if (strict && !cx->hasStrictOption())
|
||||||
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())
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
bool warning = JSREPORT_IS_WARNING(flags);
|
|
||||||
if (warning && cx->hasWErrorOption()) {
|
if (warning && cx->hasWErrorOption()) {
|
||||||
flags &= ~JSREPORT_WARNING;
|
flags &= ~JSREPORT_WARNING;
|
||||||
warning = false;
|
warning = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CompileError normalError(cx);
|
||||||
|
CompileError *err = &normalError;
|
||||||
const TokenPos *const tp = pn ? &pn->pn_pos : ¤tToken().pos;
|
const TokenPos *const tp = pn ? &pn->pn_pos : ¤tToken().pos;
|
||||||
|
|
||||||
JSErrorReport report;
|
err->report.flags = flags;
|
||||||
PodZero(&report);
|
err->report.errorNumber = errorNumber;
|
||||||
report.flags = flags;
|
err->report.filename = filename;
|
||||||
report.errorNumber = errorNumber;
|
err->report.originPrincipals = originPrincipals;
|
||||||
report.filename = filename;
|
err->report.lineno = tp->begin.lineno;
|
||||||
report.originPrincipals = originPrincipals;
|
|
||||||
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, &err->message, &err->report,
|
||||||
|
err->hasCharArgs, args)) {
|
||||||
if (!js_ExpandErrorArguments(cx, js_GetErrorMessage, NULL, errorNumber, &mgr.message, &report,
|
|
||||||
hasCharArgs, args)) {
|
|
||||||
return false;
|
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
|
* means that any error involving a multi-line token (eg. an unterminated
|
||||||
* multi-line string literal) won't have a context printed.
|
* 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;
|
const jschar *tokptr = linebase + tp->begin.index;
|
||||||
|
|
||||||
// We show only a portion (a "window") of the line around the erroneous
|
// 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
|
// Unicode and char versions of the window into the offending source
|
||||||
// line, without final \n.
|
// line, without final \n.
|
||||||
report.uclinebuf = windowBuf.extractWellSized();
|
err->report.uclinebuf = windowBuf.extractWellSized();
|
||||||
if (!report.uclinebuf)
|
if (!err->report.uclinebuf)
|
||||||
return false;
|
return false;
|
||||||
report.linebuf = DeflateString(cx, report.uclinebuf, windowLength);
|
err->report.linebuf = DeflateString(cx, err->report.uclinebuf, windowLength);
|
||||||
if (!report.linebuf)
|
if (!err->report.linebuf)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// The lineno check above means we should only see single-line tokens here.
|
// The lineno check above means we should only see single-line tokens here.
|
||||||
JS_ASSERT(tp->begin.lineno == tp->end.lineno);
|
JS_ASSERT(tp->begin.lineno == tp->end.lineno);
|
||||||
report.tokenptr = report.linebuf + windowIndex;
|
err->report.tokenptr = err->report.linebuf + windowIndex;
|
||||||
report.uctokenptr = report.uclinebuf + windowIndex;
|
err->report.uctokenptr = err->report.uclinebuf + windowIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
err->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, 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
return warning;
|
return warning;
|
||||||
}
|
}
|
||||||
|
@ -413,6 +413,20 @@ enum TokenStreamFlags
|
|||||||
|
|
||||||
struct Parser;
|
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
|
// Ideally, tokenizing would be entirely independent of context. But the
|
||||||
// strict mode flag, which is in SharedContext, affects tokenizing, and
|
// strict mode flag, which is in SharedContext, affects tokenizing, and
|
||||||
// TokenStream needs to see it.
|
// TokenStream needs to see it.
|
||||||
|
Loading…
Reference in New Issue
Block a user