📄 jsscan.c
字号:
* This can happen when a segment ends in * \r\r. Start over. ptr == limit in this * case, so we'll fall into buffer-filling * code. */ return GetChar(ts); } } else { ts->linebuf.base[len-1] = '\n'; } } } else if (*nl == '\n') { if (nl > ts->userbuf.base && nl[-1] == '\r' && ts->linebuf.base[len-2] == '\r') { len--; JS_ASSERT(ts->linebuf.base[len] == '\n'); ts->linebuf.base[len-1] = '\n'; } } else if (*nl == LINE_SEPARATOR || *nl == PARA_SEPARATOR) { ts->linebuf.base[len-1] = '\n'; } } /* Reset linebuf based on adjusted segment length. */ ts->linebuf.limit = ts->linebuf.base + len; ts->linebuf.ptr = ts->linebuf.base; /* Update position of linebuf within physical userbuf line. */ if (!(ts->flags & TSF_NLFLAG)) ts->linepos += ts->linelen; else ts->linepos = 0; if (ts->linebuf.limit[-1] == '\n') ts->flags |= TSF_NLFLAG; else ts->flags &= ~TSF_NLFLAG; /* Update linelen from original segment length. */ ts->linelen = olen; } c = *ts->linebuf.ptr++; } while (JS_ISFORMAT(c)); } if (c == '\n') ts->lineno++; return c;}static voidUngetChar(JSTokenStream *ts, int32 c){ if (c == EOF) return; JS_ASSERT(ts->ungetpos < sizeof ts->ungetbuf / sizeof ts->ungetbuf[0]); if (c == '\n') ts->lineno--; ts->ungetbuf[ts->ungetpos++] = (jschar)c;}static int32PeekChar(JSTokenStream *ts){ int32 c; c = GetChar(ts); UngetChar(ts, c); return c;}/* * Peek n chars ahead into ts. Return true if n chars were read, false if * there weren't enough characters in the input stream. This function cannot * be used to peek into or past a newline. */static JSBoolPeekChars(JSTokenStream *ts, intN n, jschar *cp){ intN i, j; int32 c; for (i = 0; i < n; i++) { c = GetChar(ts); if (c == EOF) break; if (c == '\n') { UngetChar(ts, c); break; } cp[i] = (jschar)c; } for (j = i - 1; j >= 0; j--) UngetChar(ts, cp[j]); return i == n;}static voidSkipChars(JSTokenStream *ts, intN n){ while (--n >= 0) GetChar(ts);}static JSBoolMatchChar(JSTokenStream *ts, int32 expect){ int32 c; c = GetChar(ts); if (c == expect) return JS_TRUE; UngetChar(ts, c); return JS_FALSE;}static JSBoolReportCompileErrorNumber(JSContext *cx, void *handle, uintN flags, uintN errorNumber, JSErrorReport *report, JSBool charArgs, va_list ap){ JSTempValueRooter linetvr; JSString *linestr = NULL; JSTokenStream *ts = NULL; JSCodeGenerator *cg = NULL; JSParseNode *pn = NULL; JSErrorReporter onError; JSTokenPos *tp; JSStackFrame *fp; uintN index; char *message; JSBool warning; memset(report, 0, sizeof (struct JSErrorReport)); report->flags = flags; report->errorNumber = errorNumber; message = NULL; if (!js_ExpandErrorArguments(cx, js_GetErrorMessage, NULL, errorNumber, &message, report, &warning, charArgs, ap)) { return JS_FALSE; } JS_PUSH_TEMP_ROOT_STRING(cx, NULL, &linetvr); switch (flags & JSREPORT_HANDLE) { case JSREPORT_TS: ts = handle; break; case JSREPORT_CG: cg = handle; break; case JSREPORT_PN: pn = handle; ts = pn->pn_ts; break; } JS_ASSERT(!ts || ts->linebuf.limit < ts->linebuf.base + JS_LINE_LIMIT); /* * 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. */ do { if (ts) { report->filename = ts->filename; if (pn) { report->lineno = pn->pn_pos.begin.lineno; if (report->lineno != ts->lineno) break; } report->lineno = ts->lineno; linestr = js_NewStringCopyN(cx, ts->linebuf.base, PTRDIFF(ts->linebuf.limit, ts->linebuf.base, jschar), 0); linetvr.u.string = linestr; report->linebuf = linestr ? JS_GetStringBytes(linestr) : NULL; tp = &ts->tokens[(ts->cursor+ts->lookahead) & NTOKENS_MASK].pos; if (pn) tp = &pn->pn_pos; /* * FIXME: What should instead happen here is that we should * find error-tokens in userbuf, if !ts->file. That will * allow us to deliver a more helpful error message, which * includes all or part of the bad string or bad token. The * code here yields something that looks truncated. * See https://bugzilla.mozilla.org/show_bug.cgi?id=352970 */ index = 0; if (tp->begin.lineno == tp->end.lineno) { if (tp->begin.index < ts->linepos) break; index = tp->begin.index - ts->linepos; } report->tokenptr = linestr ? report->linebuf + index : NULL; report->uclinebuf = linestr ? JS_GetStringChars(linestr) : NULL; report->uctokenptr = linestr ? report->uclinebuf + index : NULL; break; } if (cg) { report->filename = cg->filename; report->lineno = CG_CURRENT_LINE(cg); break; } /* * If we can't find out where the error was based on the current * frame, see if the next frame has a script/pc combo we can use. */ for (fp = cx->fp; fp; fp = fp->down) { if (fp->script && fp->pc) { report->filename = fp->script->filename; report->lineno = js_PCToLineNumber(cx, fp->script, fp->pc); break; } } } while (0); /* * 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. * * 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. */ onError = cx->errorReporter; /* * Try to raise an exception only if there isn't one already set -- * otherwise the exception will describe the last compile-time error, * which is likely spurious. */ if (!ts || !(ts->flags & TSF_ERROR)) { if (js_ErrorToException(cx, message, report)) onError = NULL; } /* * Suppress any compile-time 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 && !JSREPORT_IS_WARNING(flags)) onError = NULL; if (onError) { JSDebugErrorHook hook = cx->runtime->debugErrorHook; /* * If debugErrorHook is present then we give it a chance to veto * sending the error on to the regular error reporter. */ 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->ucmessage) JS_free(cx, (void *)report->ucmessage); JS_POP_TEMP_ROOT(cx, &linetvr); if (ts && !JSREPORT_IS_WARNING(flags)) { /* Set the error flag to suppress spurious reports. */ ts->flags |= TSF_ERROR; } return warning;}JSBooljs_ReportCompileErrorNumber(JSContext *cx, void *handle, uintN flags, uintN errorNumber, ...){ va_list ap; JSErrorReport report; JSBool warning; if ((flags & JSREPORT_STRICT) && !JS_HAS_STRICT_OPTION(cx)) return JS_TRUE; va_start(ap, errorNumber); warning = ReportCompileErrorNumber(cx, handle, flags, errorNumber, &report, JS_TRUE, ap); va_end(ap); /* * We have to do this here because js_ReportCompileErrorNumberUC doesn't * need to do this. */ if (report.messageArgs) { int i = 0; while (report.messageArgs[i]) JS_free(cx, (void *)report.messageArgs[i++]); JS_free(cx, (void *)report.messageArgs); } return warning;}JSBooljs_ReportCompileErrorNumberUC(JSContext *cx, void *handle, uintN flags, uintN errorNumber, ...){ va_list ap; JSErrorReport report; JSBool warning; if ((flags & JSREPORT_STRICT) && !JS_HAS_STRICT_OPTION(cx)) return JS_TRUE; va_start(ap, errorNumber); warning = ReportCompileErrorNumber(cx, handle, flags, errorNumber, &report, JS_FALSE, ap); va_end(ap); if (report.messageArgs) JS_free(cx, (void *)report.messageArgs); return warning;}static JSBoolGrowStringBuffer(JSStringBuffer *sb, size_t newlength){ ptrdiff_t offset; jschar *bp; offset = PTRDIFF(sb->ptr, sb->base, jschar); JS_ASSERT(offset >= 0); newlength += offset + 1; if ((size_t)offset < newlength && newlength < ~(size_t)0 / sizeof(jschar)) bp = realloc(sb->base, newlength * sizeof(jschar)); else bp = NULL; if (!bp) { free(sb->base); sb->base = STRING_BUFFER_ERROR_BASE; return JS_FALSE; } sb->base = bp; sb->ptr = bp + offset; sb->limit = bp + newlength - 1; return JS_TRUE;}static voidFreeStringBuffer(JSStringBuffer *sb){ JS_ASSERT(STRING_BUFFER_OK(sb)); if (sb->base) free(sb->base);}voidjs_InitStringBuffer(JSStringBuffer *sb){ sb->base = sb->limit = sb->ptr = NULL; sb->data = NULL; sb->grow = GrowStringBuffer; sb->free = FreeStringBuffer;}voidjs_FinishStringBuffer(JSStringBuffer *sb){ sb->free(sb);}#define ENSURE_STRING_BUFFER(sb,n) \ ((sb)->ptr + (n) <= (sb)->limit || sb->grow(sb, n))static voidFastAppendChar(JSStringBuffer *sb, jschar c){ if (!STRING_BUFFER_OK(sb)) return; if (!ENSURE_STRING_BUFFER(sb, 1)) return; *sb->ptr++ = c;}voidjs_AppendChar(JSStringBuffer *sb, jschar c){ jschar *bp; if (!STRING_BUFFER_OK(sb)) return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -