Speed-up reading words, strings and templates.
Now identifiers and strings even with escaped chars are read in optimized way by reading entire chunks delimited by escape chars (and not bailing to deopt mode on first one).
This commit is contained in:
parent
65d09eac6e
commit
cdd444eff1
49
acorn.js
49
acorn.js
@ -1119,36 +1119,33 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function readString(quote) {
|
function readString(quote) {
|
||||||
++tokPos;
|
var out = "", chunkStart = ++tokPos;
|
||||||
var out = "";
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (tokPos >= inputLen) raise(tokStart, "Unterminated string constant");
|
if (tokPos >= inputLen) raise(tokStart, "Unterminated string constant");
|
||||||
var ch = input.charCodeAt(tokPos);
|
var ch = input.charCodeAt(tokPos);
|
||||||
if (ch === quote) {
|
if (ch === quote) break;
|
||||||
++tokPos;
|
|
||||||
return finishToken(_string, out);
|
|
||||||
}
|
|
||||||
if (ch === 92) { // '\'
|
if (ch === 92) { // '\'
|
||||||
|
out += input.slice(chunkStart, tokPos);
|
||||||
out += readEscapedChar();
|
out += readEscapedChar();
|
||||||
|
chunkStart = tokPos;
|
||||||
} else {
|
} else {
|
||||||
|
if (isNewLine(ch)) raise(tokStart, "Unterminated string constant");
|
||||||
++tokPos;
|
++tokPos;
|
||||||
if (isNewLine(ch)) {
|
|
||||||
raise(tokStart, "Unterminated string constant");
|
|
||||||
}
|
|
||||||
out += String.fromCharCode(ch); // '\'
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
out += input.slice(chunkStart, tokPos++);
|
||||||
|
return finishToken(_string, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reads template string tokens.
|
// Reads template string tokens.
|
||||||
|
|
||||||
function readTmplToken() {
|
function readTmplToken() {
|
||||||
var out = "", start = tokPos;
|
var out = "", chunkStart = tokPos;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (tokPos >= inputLen) raise(tokStart, "Unterminated template");
|
if (tokPos >= inputLen) raise(tokStart, "Unterminated template");
|
||||||
var ch = input.charCodeAt(tokPos);
|
var ch = input.charCodeAt(tokPos);
|
||||||
if (ch === 96 || ch === 36 && input.charCodeAt(tokPos + 1) === 123) { // '`', '${'
|
if (ch === 96 || ch === 36 && input.charCodeAt(tokPos + 1) === 123) { // '`', '${'
|
||||||
if (tokPos === start && tokType === _template) {
|
if (tokPos === tokStart && tokType === _template) {
|
||||||
if (ch === 36) {
|
if (ch === 36) {
|
||||||
tokPos += 2;
|
tokPos += 2;
|
||||||
return finishToken(_dollarBraceL);
|
return finishToken(_dollarBraceL);
|
||||||
@ -1157,23 +1154,29 @@
|
|||||||
return finishToken(_backQuote);
|
return finishToken(_backQuote);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
out += input.slice(chunkStart, tokPos);
|
||||||
return finishToken(_template, out);
|
return finishToken(_template, out);
|
||||||
}
|
}
|
||||||
if (ch === 92) { // '\'
|
if (ch === 92) { // '\'
|
||||||
|
out += input.slice(chunkStart, tokPos);
|
||||||
out += readEscapedChar();
|
out += readEscapedChar();
|
||||||
} else {
|
chunkStart = tokPos;
|
||||||
|
} else if (isNewLine(ch)) {
|
||||||
|
out += input.slice(chunkStart, tokPos);
|
||||||
++tokPos;
|
++tokPos;
|
||||||
if (isNewLine(ch)) {
|
|
||||||
if (ch === 13 && input.charCodeAt(tokPos) === 10) {
|
if (ch === 13 && input.charCodeAt(tokPos) === 10) {
|
||||||
++tokPos;
|
++tokPos;
|
||||||
ch = 10;
|
out += "\n";
|
||||||
|
} else {
|
||||||
|
out += String.fromCharCode(ch);
|
||||||
}
|
}
|
||||||
if (options.locations) {
|
if (options.locations) {
|
||||||
++tokCurLine;
|
++tokCurLine;
|
||||||
tokLineStart = tokPos;
|
tokLineStart = tokPos;
|
||||||
}
|
}
|
||||||
}
|
chunkStart = tokPos;
|
||||||
out += String.fromCharCode(ch);
|
} else {
|
||||||
|
++tokPos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1228,20 +1231,19 @@
|
|||||||
// Read an identifier, and return it as a string. Sets `containsEsc`
|
// Read an identifier, and return it as a string. Sets `containsEsc`
|
||||||
// to whether the word contained a '\u' escape.
|
// to whether the word contained a '\u' escape.
|
||||||
//
|
//
|
||||||
// Only builds up the word character-by-character when it actually
|
// Incrementally adds only escaped chars, adding other chunks as-is
|
||||||
// containeds an escape, as a micro-optimization.
|
// as a micro-optimization.
|
||||||
|
|
||||||
function readWord1() {
|
function readWord1() {
|
||||||
containsEsc = false;
|
containsEsc = false;
|
||||||
var word, first = true, start = tokPos;
|
var word = "", first = true, chunkStart = tokPos;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
var ch = input.charCodeAt(tokPos);
|
var ch = input.charCodeAt(tokPos);
|
||||||
if (isIdentifierChar(ch)) {
|
if (isIdentifierChar(ch)) {
|
||||||
if (containsEsc) word += input.charAt(tokPos);
|
|
||||||
++tokPos;
|
++tokPos;
|
||||||
} else if (ch === 92) { // "\"
|
} else if (ch === 92) { // "\"
|
||||||
if (!containsEsc) word = input.slice(start, tokPos);
|
|
||||||
containsEsc = true;
|
containsEsc = true;
|
||||||
|
word += input.slice(chunkStart, tokPos);
|
||||||
if (input.charCodeAt(++tokPos) != 117) // "u"
|
if (input.charCodeAt(++tokPos) != 117) // "u"
|
||||||
raise(tokPos, "Expecting Unicode escape sequence \\uXXXX");
|
raise(tokPos, "Expecting Unicode escape sequence \\uXXXX");
|
||||||
++tokPos;
|
++tokPos;
|
||||||
@ -1251,12 +1253,13 @@
|
|||||||
if (!(first ? isIdentifierStart(esc) : isIdentifierChar(esc)))
|
if (!(first ? isIdentifierStart(esc) : isIdentifierChar(esc)))
|
||||||
raise(tokPos - 4, "Invalid Unicode escape");
|
raise(tokPos - 4, "Invalid Unicode escape");
|
||||||
word += escStr;
|
word += escStr;
|
||||||
|
chunkStart = tokPos;
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
first = false;
|
first = false;
|
||||||
}
|
}
|
||||||
return containsEsc ? word : input.slice(start, tokPos);
|
return word + input.slice(chunkStart, tokPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read an identifier or keyword token. Will check for reserved
|
// Read an identifier or keyword token. Will check for reserved
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user