📄 jsscan.c
字号:
if (PeekChars(ts, 6, cp) && cp[0] == 'C' && cp[1] == 'D' && cp[2] == 'A' && cp[3] == 'T' && cp[4] == 'A' && cp[5] == '[') { SkipChars(ts, 6); while ((c = GetChar(ts)) != ']' || !PeekChars(ts, 2, cp) || cp[0] != ']' || cp[1] != '>') { if (c == EOF) goto bad_xml_markup; ADD_TO_TOKENBUF(c); } GetChar(ts); /* discard ] but not > */ tt = TOK_XMLCDATA; tp->t_op = JSOP_XMLCDATA; goto finish_xml_markup; } goto bad_xml_markup; } } /* Check for processing instruction. */ if (MatchChar(ts, '?')) { JSBool inTarget = JS_TRUE; size_t targetLength = 0; ptrdiff_t contentIndex = -1; INIT_TOKENBUF(); while ((c = GetChar(ts)) != '?' || PeekChar(ts) != '>') { if (c == EOF) goto bad_xml_markup; if (inTarget) { if (JS_ISXMLSPACE(c)) { if (TOKENBUF_LENGTH() == 0) goto bad_xml_markup; inTarget = JS_FALSE; } else { if (!((TOKENBUF_LENGTH() == 0) ? JS_ISXMLNSSTART(c) : JS_ISXMLNS(c))) { goto bad_xml_markup; } ++targetLength; } } else { if (contentIndex < 0 && !JS_ISXMLSPACE(c)) contentIndex = TOKENBUF_LENGTH(); } ADD_TO_TOKENBUF(c); } if (targetLength == 0) goto bad_xml_markup; if (!TOKENBUF_OK()) goto error; if (contentIndex < 0) { atom = cx->runtime->atomState.emptyAtom; } else { atom = js_AtomizeChars(cx, &TOKENBUF_CHAR(contentIndex), TOKENBUF_LENGTH() - contentIndex, 0); if (!atom) goto error; } TRIM_TOKENBUF(targetLength); tp->t_atom2 = atom; tt = TOK_XMLPI; finish_xml_markup: if (!MatchChar(ts, '>')) goto bad_xml_markup; atom = TOKENBUF_TO_ATOM(); if (!atom) goto error; tp->t_atom = atom; tp->pos.end.lineno = (uint16)ts->lineno; goto out; } /* An XML start-of-tag character. */ tt = MatchChar(ts, '/') ? TOK_XMLETAGO : TOK_XMLSTAGO; goto out; bad_xml_markup: js_ReportCompileErrorNumber(cx, ts, JSREPORT_TS | JSREPORT_ERROR, JSMSG_BAD_XML_MARKUP); goto error; }#endif /* JS_HAS_XML_SUPPORT */ /* NB: treat HTML begin-comment as comment-till-end-of-line */ if (MatchChar(ts, '!')) { if (MatchChar(ts, '-')) { if (MatchChar(ts, '-')) { ts->flags |= TSF_IN_HTML_COMMENT; goto skipline; } UngetChar(ts, '-'); } UngetChar(ts, '!'); } if (MatchChar(ts, c)) { tp->t_op = JSOP_LSH; tt = MatchChar(ts, '=') ? TOK_ASSIGN : TOK_SHOP; } else { tp->t_op = MatchChar(ts, '=') ? JSOP_LE : JSOP_LT; tt = TOK_RELOP; } break; case '>': if (MatchChar(ts, c)) { tp->t_op = MatchChar(ts, c) ? JSOP_URSH : JSOP_RSH; tt = MatchChar(ts, '=') ? TOK_ASSIGN : TOK_SHOP; } else { tp->t_op = MatchChar(ts, '=') ? JSOP_GE : JSOP_GT; tt = TOK_RELOP; } break; case '*': tp->t_op = JSOP_MUL; tt = MatchChar(ts, '=') ? TOK_ASSIGN : TOK_STAR; break; case '/': if (MatchChar(ts, '/')) { /* * Hack for source filters such as the Mozilla XUL preprocessor: * "//@line 123\n" sets the number of the *next* line after the * comment to 123. */ if (JS_HAS_ATLINE_OPTION(cx)) { jschar cp[5]; uintN i, line, temp; char filename[1024]; if (PeekChars(ts, 5, cp) && cp[0] == '@' && cp[1] == 'l' && cp[2] == 'i' && cp[3] == 'n' && cp[4] == 'e') { SkipChars(ts, 5); while ((c = GetChar(ts)) != '\n' && JS_ISSPACE(c)) continue; if (JS7_ISDEC(c)) { line = JS7_UNDEC(c); while ((c = GetChar(ts)) != EOF && JS7_ISDEC(c)) { temp = 10 * line + JS7_UNDEC(c); if (temp < line) { /* Ignore overlarge line numbers. */ goto skipline; } line = temp; } while (c != '\n' && JS_ISSPACE(c)) c = GetChar(ts); i = 0; if (c == '"') { while ((c = GetChar(ts)) != EOF && c != '"') { if (c == '\n') { UngetChar(ts, c); goto skipline; } if ((c >> 8) != 0 || i >= sizeof filename - 1) goto skipline; filename[i++] = (char) c; } if (c == '"') { while ((c = GetChar(ts)) != '\n' && JS_ISSPACE(c)) { continue; } } } filename[i] = '\0'; if (c == '\n') { if (i > 0) { if (ts->flags & TSF_OWNFILENAME) JS_free(cx, (void *) ts->filename); ts->filename = JS_strdup(cx, filename); if (!ts->filename) goto error; ts->flags |= TSF_OWNFILENAME; } ts->lineno = line; } } UngetChar(ts, c); } }skipline: /* Optimize line skipping if we are not in an HTML comment. */ if (ts->flags & TSF_IN_HTML_COMMENT) { while ((c = GetChar(ts)) != EOF && c != '\n') { if (c == '-' && MatchChar(ts, '-') && MatchChar(ts, '>')) ts->flags &= ~TSF_IN_HTML_COMMENT; } } else { while ((c = GetChar(ts)) != EOF && c != '\n') continue; } UngetChar(ts, c); ts->cursor = (ts->cursor - 1) & NTOKENS_MASK; goto retry; } if (MatchChar(ts, '*')) { while ((c = GetChar(ts)) != EOF && !(c == '*' && MatchChar(ts, '/'))) { /* Ignore all characters until comment close. */ } if (c == EOF) { js_ReportCompileErrorNumber(cx, ts, JSREPORT_TS | JSREPORT_ERROR, JSMSG_UNTERMINATED_COMMENT); goto error; } ts->cursor = (ts->cursor - 1) & NTOKENS_MASK; goto retry; } if (ts->flags & TSF_OPERAND) { JSObject *obj; uintN flags; JSBool inCharClass = JS_FALSE; INIT_TOKENBUF(); for (;;) { c = GetChar(ts); if (c == '\n' || c == EOF) { UngetChar(ts, c); js_ReportCompileErrorNumber(cx, ts, JSREPORT_TS | JSREPORT_ERROR, JSMSG_UNTERMINATED_REGEXP); goto error; } if (c == '\\') { ADD_TO_TOKENBUF(c); c = GetChar(ts); } else if (c == '[') { inCharClass = JS_TRUE; } else if (c == ']') { inCharClass = JS_FALSE; } else if (c == '/' && !inCharClass) { /* For compat with IE, allow unescaped / in char classes. */ break; } ADD_TO_TOKENBUF(c); } for (flags = 0; ; ) { if (MatchChar(ts, 'g')) flags |= JSREG_GLOB; else if (MatchChar(ts, 'i')) flags |= JSREG_FOLD; else if (MatchChar(ts, 'm')) flags |= JSREG_MULTILINE; else break; } c = PeekChar(ts); if (JS7_ISLET(c)) { tp->ptr = ts->linebuf.ptr - 1; js_ReportCompileErrorNumber(cx, ts, JSREPORT_TS | JSREPORT_ERROR, JSMSG_BAD_REGEXP_FLAG); (void) GetChar(ts); goto error; } /* XXXbe fix jsregexp.c so it doesn't depend on NUL termination */ if (!TOKENBUF_OK()) goto error; NUL_TERM_TOKENBUF(); obj = js_NewRegExpObject(cx, ts, TOKENBUF_BASE(), TOKENBUF_LENGTH(), flags); if (!obj) goto error; atom = js_AtomizeObject(cx, obj, 0); if (!atom) goto error; /* * If the regexp's script is one-shot, we can avoid the extra * fork-on-exec costs of JSOP_REGEXP by selecting JSOP_OBJECT. * Otherwise, to avoid incorrect proto, parent, and lastIndex * sharing among threads and sequentially across re-execution, * select JSOP_REGEXP. */ tp->t_op = (cx->fp->flags & (JSFRAME_EVAL | JSFRAME_COMPILE_N_GO)) ? JSOP_OBJECT : JSOP_REGEXP; tp->t_atom = atom; tt = TOK_OBJECT; break; } tp->t_op = JSOP_DIV; tt = MatchChar(ts, '=') ? TOK_ASSIGN : TOK_DIVOP; break; case '%': tp->t_op = JSOP_MOD; tt = MatchChar(ts, '=') ? TOK_ASSIGN : TOK_DIVOP; break; case '~': tp->t_op = JSOP_BITNOT; tt = TOK_UNARYOP; break; case '+': if (MatchChar(ts, '=')) { tp->t_op = JSOP_ADD; tt = TOK_ASSIGN; } else if (MatchChar(ts, c)) { tt = TOK_INC; } else { tp->t_op = JSOP_POS; tt = TOK_PLUS; } break; case '-': if (MatchChar(ts, '=')) { tp->t_op = JSOP_SUB; tt = TOK_ASSIGN; } else if (MatchChar(ts, c)) { if (PeekChar(ts) == '>' && !(ts->flags & TSF_DIRTYLINE)) { ts->flags &= ~TSF_IN_HTML_COMMENT; goto skipline; } tt = TOK_DEC; } else { tp->t_op = JSOP_NEG; tt = TOK_MINUS; } break;#if JS_HAS_SHARP_VARS case '#': { uint32 n; c = GetChar(ts); if (!JS7_ISDEC(c)) { UngetChar(ts, c); goto badchar; } n = (uint32)JS7_UNDEC(c); for (;;) { c = GetChar(ts); if (!JS7_ISDEC(c)) break; n = 10 * n + JS7_UNDEC(c); if (n >= UINT16_LIMIT) { js_ReportCompileErrorNumber(cx, ts, JSREPORT_TS | JSREPORT_ERROR, JSMSG_SHARPVAR_TOO_BIG); goto error; } } tp->t_dval = (jsdouble) n; if (JS_HAS_STRICT_OPTION(cx) && (c == '=' || c == '#')) { char buf[20]; JS_snprintf(buf, sizeof buf, "#%u%c", n, c); if (!js_ReportCompileErrorNumber(cx, ts, JSREPORT_TS | JSREPORT_WARNING | JSREPORT_STRICT, JSMSG_DEPRECATED_USAGE, buf)) { goto error; } } if (c == '=') tt = TOK_DEFSHARP; else if (c == '#') tt = TOK_USESHARP; else goto badchar; break; }#endif /* JS_HAS_SHARP_VARS */#if JS_HAS_SHARP_VARS || JS_HAS_XML_SUPPORT badchar:#endif default: js_ReportCompileErrorNumber(cx, ts, JSREPORT_TS | JSREPORT_ERROR, JSMSG_ILLEGAL_CHARACTER); goto error; }out: JS_ASSERT(tt != TOK_EOL); ts->flags |= TSF_DIRTYLINE;eol_out: if (!STRI
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -