diff --git a/js/src/jsapi.c b/js/src/jsapi.c index 1b6dd4172af0..84ffa0359ece 100644 --- a/js/src/jsapi.c +++ b/js/src/jsapi.c @@ -858,11 +858,6 @@ JS_SetVersion(JSContext *cx, JSVersion version) } #endif /* !JS_BUG_FALLIBLE_EQOPS */ -#if JS_HAS_EXPORT_IMPORT - /* XXX this might fail due to low memory */ - js_InitScanner(cx); -#endif /* JS_HAS_EXPORT_IMPORT */ - return oldVersion; } diff --git a/js/src/jscntxt.h b/js/src/jscntxt.h index b12e131ffc40..07939877077b 100644 --- a/js/src/jscntxt.h +++ b/js/src/jscntxt.h @@ -233,6 +233,9 @@ struct JSContext { jsval exception; /* most-recently-thrown exceptin */ uint32 options; /* see jsapi.h for JSOPTION_* */ + + /* Delay JS_SetVersion scanner effects until they're needed. */ + JSVersion scannerVersion; }; /* Slightly more readable macros, also to hide bitset implementation detail. */ diff --git a/js/src/jsscan.c b/js/src/jsscan.c index 1f85566f2ab6..cd98bb6dc40e 100644 --- a/js/src/jsscan.c +++ b/js/src/jsscan.c @@ -216,6 +216,12 @@ js_NewBufferTokenStream(JSContext *cx, const jschar *base, size_t length) size_t nb; JSTokenStream *ts; + if (cx->scannerVersion != cx->version) { + if (!js_InitScanner(cx)) + return NULL; + cx->scannerVersion = cx->version; + } + nb = sizeof(JSTokenStream) + JS_LINE_LIMIT * sizeof(jschar); JS_ARENA_ALLOCATE(ts, &cx->tempPool, nb); if (!ts) { @@ -666,7 +672,7 @@ AddToTokenBuf(JSContext *cx, JSTokenBuf *tb, jschar c) * Otherwise, non-destructively return the original '\'. */ static int32 -getUnicodeEscape(JSTokenStream *ts) +GetUnicodeEscape(JSTokenStream *ts) { jschar cp[5]; int32 c; @@ -733,23 +739,23 @@ retry: hadUnicodeEscape = JS_FALSE; if (JS_ISIDENT_START(c) || - ((c == '\\') && - (c = getUnicodeEscape(ts), - hadUnicodeEscape = JS_ISIDENT_START(c)))) { + (c == '\\' && + (c = GetUnicodeEscape(ts), + hadUnicodeEscape = JS_ISIDENT_START(c)))) { INIT_TOKENBUF(&ts->tokenbuf); for (;;) { if (!AddToTokenBuf(cx, &ts->tokenbuf, (jschar)c)) RETURN(TOK_ERROR); c = GetChar(ts); if (c == '\\') { - c = getUnicodeEscape(ts); - if (JS_ISIDENT(c)) - hadUnicodeEscape = JS_TRUE; - else + c = GetUnicodeEscape(ts); + if (!JS_ISIDENT(c)) + break; + hadUnicodeEscape = JS_TRUE; + } else { + if (!JS_ISIDENT(c)) break; } - else - if (!JS_ISIDENT(c)) break; } UngetChar(ts, c); FINISH_TOKENBUF(&ts->tokenbuf); @@ -760,16 +766,13 @@ retry: 0); if (!atom) RETURN(TOK_ERROR); - if (hadUnicodeEscape) /* Can never be a keyword, then. */ - atom->kwindex = -1; - else - if (atom->kwindex >= 0) { - struct keyword *kw; + if (!hadUnicodeEscape && atom->kwindex >= 0) { + struct keyword *kw; - kw = &keywords[atom->kwindex]; - tp->t_op = (JSOp) kw->op; - RETURN(kw->tokentype); - } + kw = &keywords[atom->kwindex]; + tp->t_op = (JSOp) kw->op; + RETURN(kw->tokentype); + } tp->t_op = JSOP_NAME; tp->t_atom = atom; RETURN(TOK_NAME);