linestr = js_NewStringCopyZ(cx, ts->linebuf.base, 0);
linestr = js_NewStringCopyN(cx, ts->linebuf.base, limit - ts->linebuf.base, 0);
js_ReportCompileErrorNumber(JSContext *cx, JSTokenStream *ts, uintN flags,			    const uintN errorNumber, ...){    va_list ap;    jschar *limit, lastc;    JSErrorReporter onError;    JSErrorReport report;    jschar *tokenptr;    JSString *linestr;    char *message;    report.errorNumber = errorNumber;    report.messageArgs = NULL;    report.ucmessage = NULL;    message = NULL;    va_start(ap, errorNumber);    if (!js_ExpandErrorArguments(cx, js_GetErrorMessage, NULL,				errorNumber, &message, &report,                                JS_TRUE, ap))	return;    va_end(ap);    JS_ASSERT(ts->linebuf.limit < ts->linebuf.base + JS_LINE_LIMIT);    limit = ts->linebuf.limit;    lastc = limit[-1];    if (lastc == '\n')	limit[-1] = 0;    onError = cx->errorReporter;    if (onError) {	report.filename = ts->filename;	report.lineno = ts->lineno;	linestr = js_NewStringCopyZ(cx, ts->linebuf.base, 0);	report.linebuf  = linestr			  ? JS_GetStringBytes(linestr)			  : NULL;        /* XXXbe this whole fn duplicates a lot of JS_ReportCompileError... */        tokenptr = CURRENT_TOKEN(ts).ptr;	report.tokenptr = linestr			  ? report.linebuf + (tokenptr - ts->linebuf.base)			  : NULL;	report.uclinebuf = ts->linebuf.base;	report.uctokenptr = tokenptr;	report.flags = flags;#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->flags & TSF_BADCOMPILE)) {            if (js_ErrorToException(cx, message, &report))                ts->flags |= TSF_BADCOMPILE;        }        /*         * 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 0#if !defined XP_PC || !defined _MSC_VER || _MSC_VER > 800    } else {	if (ts->filename)	    fprintf(stderr, "%s, ", ts->filename);	if (ts->lineno)	    fprintf(stderr, "line %u: ", ts->lineno);	fprintf(stderr, "%s:\n%s\n",message,		js_DeflateString(cx, ts->linebuf.base,				 ts->linebuf.limit - ts->linebuf.base));#endif#endif    }    if (lastc == '\n')	limit[-1] = lastc;    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);}