Index: src/scanner.cc |
diff --git a/src/scanner.cc b/src/scanner.cc |
index 561c30b58a12e0cb2c5e54d16bfc2e1572c9cd3e..96459f3c6699ec07f5b3a73db6defd5665dc791e 100644 |
--- a/src/scanner.cc |
+++ b/src/scanner.cc |
@@ -34,7 +34,6 @@ Handle<String> LiteralBuffer::Internalize(Isolate* isolate) const { |
Scanner::Scanner(UnicodeCache* unicode_cache) |
: unicode_cache_(unicode_cache), |
- capturing_raw_literal_(false), |
octal_pos_(Location::invalid()), |
harmony_scoping_(false), |
harmony_modules_(false), |
@@ -57,6 +56,7 @@ void Scanner::Initialize(Utf16CharacterStream* source) { |
} |
+template <bool capture_raw> |
uc32 Scanner::ScanHexNumber(int expected_length) { |
DCHECK(expected_length <= 4); // prevent overflow |
@@ -67,13 +67,14 @@ uc32 Scanner::ScanHexNumber(int expected_length) { |
return -1; |
} |
x = x * 16 + d; |
- Advance(); |
+ Advance<capture_raw>(); |
} |
return x; |
} |
+template <bool capture_raw> |
uc32 Scanner::ScanUnlimitedLengthHexNumber(int max_value) { |
uc32 x = 0; |
int d = HexValue(c0_); |
@@ -83,7 +84,7 @@ uc32 Scanner::ScanUnlimitedLengthHexNumber(int max_value) { |
while (d >= 0) { |
x = x * 16 + d; |
if (x > max_value) return -1; |
- Advance(); |
+ Advance<capture_raw>(); |
d = HexValue(c0_); |
} |
return x; |
@@ -696,16 +697,17 @@ void Scanner::SeekForward(int pos) { |
} |
+template <bool capture_raw> |
bool Scanner::ScanEscape() { |
uc32 c = c0_; |
- Advance(); |
+ Advance<capture_raw>(); |
// Skip escaped newlines. |
if (c0_ >= 0 && unicode_cache_->IsLineTerminator(c)) { |
// Allow CR+LF newlines in multiline string literals. |
- if (IsCarriageReturn(c) && IsLineFeed(c0_)) Advance(); |
+ if (IsCarriageReturn(c) && IsLineFeed(c0_)) Advance<capture_raw>(); |
// Allow LF+CR newlines in multiline string literals. |
- if (IsLineFeed(c) && IsCarriageReturn(c0_)) Advance(); |
+ if (IsLineFeed(c) && IsCarriageReturn(c0_)) Advance<capture_raw>(); |
return true; |
} |
@@ -719,13 +721,13 @@ bool Scanner::ScanEscape() { |
case 'r' : c = '\r'; break; |
case 't' : c = '\t'; break; |
case 'u' : { |
- c = ScanUnicodeEscape(); |
+ c = ScanUnicodeEscape<capture_raw>(); |
if (c < 0) return false; |
break; |
} |
case 'v' : c = '\v'; break; |
case 'x' : { |
- c = ScanHexNumber(2); |
+ c = ScanHexNumber<capture_raw>(2); |
if (c < 0) return false; |
break; |
} |
@@ -736,7 +738,9 @@ bool Scanner::ScanEscape() { |
case '4' : // fall through |
case '5' : // fall through |
case '6' : // fall through |
- case '7' : c = ScanOctalEscape(c, 2); break; |
+ case '7': |
+ c = ScanOctalEscape<capture_raw>(c, 2); |
+ break; |
} |
// According to ECMA-262, section 7.8.4, characters not covered by the |
@@ -749,6 +753,7 @@ bool Scanner::ScanEscape() { |
// Octal escapes of the forms '\0xx' and '\xxx' are not a part of |
// ECMA-262. Other JS VMs support them. |
+template <bool capture_raw> |
uc32 Scanner::ScanOctalEscape(uc32 c, int length) { |
uc32 x = c - '0'; |
int i = 0; |
@@ -758,7 +763,7 @@ uc32 Scanner::ScanOctalEscape(uc32 c, int length) { |
int nx = x * 8 + d; |
if (nx >= 256) break; |
x = nx; |
- Advance(); |
+ Advance<capture_raw>(); |
} |
// Anything except '\0' is an octal escape sequence, illegal in strict mode. |
// Remember the position of octal escape sequences so that an error |
@@ -782,7 +787,7 @@ Token::Value Scanner::ScanString() { |
uc32 c = c0_; |
Advance(); |
if (c == '\\') { |
- if (c0_ < 0 || !ScanEscape()) return Token::ILLEGAL; |
+ if (c0_ < 0 || !ScanEscape<false>()) return Token::ILLEGAL; |
} else { |
AddLiteralChar(c); |
} |
@@ -810,17 +815,19 @@ Token::Value Scanner::ScanTemplateSpan() { |
// followed by an Expression. |
Token::Value result = Token::TEMPLATE_SPAN; |
- LiteralScope literal(this, true); |
+ LiteralScope literal(this); |
+ StartRawLiteral(); |
+ const bool capture_raw = true; |
while (true) { |
uc32 c = c0_; |
- Advance(); |
+ Advance<capture_raw>(); |
if (c == '`') { |
result = Token::TEMPLATE_TAIL; |
ReduceRawLiteralLength(1); |
break; |
} else if (c == '$' && c0_ == '{') { |
- Advance(); // Consume '{' |
+ Advance<capture_raw>(); // Consume '{' |
ReduceRawLiteralLength(2); |
break; |
} else if (c == '\\') { |
@@ -828,20 +835,20 @@ Token::Value Scanner::ScanTemplateSpan() { |
// The TV of LineContinuation :: \ LineTerminatorSequence is the empty |
// code unit sequence. |
uc32 lastChar = c0_; |
- Advance(); |
+ Advance<capture_raw>(); |
if (lastChar == '\r') { |
ReduceRawLiteralLength(1); // Remove \r |
if (c0_ == '\n') { |
- Advance(); // Adds \n |
+ Advance<capture_raw>(); // Adds \n |
} else { |
AddRawLiteralChar('\n'); |
} |
} |
} else if (c0_ == '0') { |
- Advance(); |
+ Advance<capture_raw>(); |
AddLiteralChar('0'); |
} else { |
- ScanEscape(); |
+ ScanEscape<true>(); |
} |
} else if (c < 0) { |
// Unterminated template literal |
@@ -854,7 +861,7 @@ Token::Value Scanner::ScanTemplateSpan() { |
if (c == '\r') { |
ReduceRawLiteralLength(1); // Remove \r |
if (c0_ == '\n') { |
- Advance(); // Adds \n |
+ Advance<capture_raw>(); // Adds \n |
} else { |
AddRawLiteralChar('\n'); |
} |
@@ -1002,27 +1009,28 @@ uc32 Scanner::ScanIdentifierUnicodeEscape() { |
Advance(); |
if (c0_ != 'u') return -1; |
Advance(); |
- return ScanUnicodeEscape(); |
+ return ScanUnicodeEscape<false>(); |
} |
+template <bool capture_raw> |
uc32 Scanner::ScanUnicodeEscape() { |
// Accept both \uxxxx and \u{xxxxxx} (if harmony unicode escapes are |
// allowed). In the latter case, the number of hex digits between { } is |
// arbitrary. \ and u have already been read. |
if (c0_ == '{' && HarmonyUnicode()) { |
- Advance(); |
- uc32 cp = ScanUnlimitedLengthHexNumber(0x10ffff); |
+ Advance<capture_raw>(); |
+ uc32 cp = ScanUnlimitedLengthHexNumber<capture_raw>(0x10ffff); |
if (cp < 0) { |
return -1; |
} |
if (c0_ != '}') { |
return -1; |
} |
- Advance(); |
+ Advance<capture_raw>(); |
return cp; |
} |
- return ScanHexNumber(4); |
+ return ScanHexNumber<capture_raw>(4); |
} |