} else if (cg) { report.filename = cg->filename; report.lineno = cg->currentLine;
js_ReportCompileErrorNumber(JSContext *cx, JSTokenStream *ts,                            JSCodeGenerator *cg, uintN flags,                            const uintN errorNumber, ...){    va_list ap;    JSErrorReporter onError;    JSErrorReport report;    jschar *tokenptr;    JSString *linestr = NULL;    char *message;    JSBool warning;    memset(&report, 0, sizeof (struct JSErrorReport));    report.flags = flags;    report.errorNumber = errorNumber;    message = NULL;    va_start(ap, errorNumber);    if (!js_ExpandErrorArguments(cx, js_GetErrorMessage, NULL,				 errorNumber, &message, &report, &warning,                                 JS_TRUE, ap)) {	return JS_FALSE;    }    va_end(ap);    js_AddRoot(cx, &linestr, "error line buffer");    JS_ASSERT(ts->linebuf.limit < ts->linebuf.base + JS_LINE_LIMIT);    onError = cx->errorReporter;    if (onError) {        /*          * We are typically called with non-null ts and null cg from jsparse.c.         * We can be called with null ts from the regexp compilation functions.         * The code generator (jsemit.c) may pass null ts and non-null cg.         */        if (ts) {            report.filename = ts->filename;            report.lineno = ts->lineno;            linestr = js_NewStringCopyN(cx, ts->linebuf.base,                                        ts->linebuf.limit - ts->linebuf.base,                                        0);            report.linebuf = linestr                ? JS_GetStringBytes(linestr)                : NULL;            tokenptr =                ts->tokens[(ts->cursor + ts->lookahead) & NTOKENS_MASK].ptr;            report.tokenptr = linestr                ? report.linebuf + (tokenptr - ts->linebuf.base)                : NULL;            report.uclinebuf = linestr                ? JS_GetStringChars(linestr)                : NULL;            report.uctokenptr = linestr                ? report.uclinebuf + (tokenptr - ts->linebuf.base)                : NULL;        } else if (cg) {            report.filename = cg->filename;            report.lineno = cg->currentLine;        }#if JS_HAS_ERROR_EXCEPTIONS	/*	 * 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, then the JSREPORT_EXCEPTION flag will be set in	 * report.flags.  Proper behavior for error reporters is probably to	 * ignore this for all but toplevel compilation errors.         *	 * XXX it'd probably be best if there was only one call to this	 * function, but there seem to be two error reporter call points.	 */        /*         * Only try to raise an exception if there isn't one already set -         * otherwise the exception will describe only the last compile error,         * which is likely spurious.         */        if (!(ts && (ts->flags & TSF_ERROR)))            (void) js_ErrorToException(cx, message, &report);        /*         * Suppress any compiletime errors that don't occur at the top level.         * This may still fail, as interplevel may be zero in contexts where we         * don't really want to call the error reporter, as when js is called         * by other code which could catch the error.         */        if (cx->interpLevel != 0)            onError = NULL;#endif        if (cx->runtime->debugErrorHook && onError) {            JSDebugErrorHook hook = cx->runtime->debugErrorHook;            /* test local in case debugErrorHook changed on another thread */            if (hook && !hook(cx, message, &report,                              cx->runtime->debugErrorHookData)) {                onError = NULL;            }        }        if (onError)            (*onError)(cx, message, &report);    }    if (message)        JS_free(cx, message);    if (report.messageArgs) {        int i = 0;        while (report.messageArgs[i])            JS_free(cx, (void *)report.messageArgs[i++]);        JS_free(cx, (void *)report.messageArgs);    }    if (report.ucmessage)        JS_free(cx, (void *)report.ucmessage);    js_RemoveRoot(cx->runtime, &linestr);    if (ts && !JSREPORT_IS_WARNING(flags)) {        /* Set the error flag to suppress spurious reports. */        ts->flags |= TSF_ERROR;    }    return warning;}