| Index: src/scanner.cc
|
| diff --git a/src/scanner.cc b/src/scanner.cc
|
| index 3214c6f1c765ac9005d77179b2014224e3190641..6ce222c871c8c72567ddefd44466105d9fe90d2b 100644
|
| --- a/src/scanner.cc
|
| +++ b/src/scanner.cc
|
| @@ -39,7 +39,8 @@ Scanner::Scanner(UnicodeCache* unicode_cache)
|
| harmony_modules_(false),
|
| harmony_numeric_literals_(false),
|
| harmony_classes_(false),
|
| - harmony_templates_(false) {}
|
| + harmony_templates_(false),
|
| + harmony_unicode_(false) {}
|
|
|
|
|
| void Scanner::Initialize(Utf16CharacterStream* source) {
|
| @@ -72,6 +73,22 @@ uc32 Scanner::ScanHexNumber(int expected_length) {
|
| }
|
|
|
|
|
| +uc32 Scanner::ScanUnlimitedLengthHexNumber(int max_value) {
|
| + uc32 x = 0;
|
| + int d = HexValue(c0_);
|
| + if (d < 0) {
|
| + return -1;
|
| + }
|
| + while (d >= 0) {
|
| + x = x * 16 + d;
|
| + if (x > max_value) return -1;
|
| + Advance();
|
| + d = HexValue(c0_);
|
| + }
|
| + return x;
|
| +}
|
| +
|
| +
|
| // Ensure that tokens can be stored in a byte.
|
| STATIC_ASSERT(Token::NUM_TOKENS <= 0x100);
|
|
|
| @@ -700,7 +717,7 @@ bool Scanner::ScanEscape() {
|
| case 'r' : c = '\r'; break;
|
| case 't' : c = '\t'; break;
|
| case 'u' : {
|
| - c = ScanHexNumber(4);
|
| + c = ScanUnicodeEscape();
|
| if (c < 0) return false;
|
| break;
|
| }
|
| @@ -964,6 +981,26 @@ uc32 Scanner::ScanIdentifierUnicodeEscape() {
|
| Advance();
|
| if (c0_ != 'u') return -1;
|
| Advance();
|
| + return ScanUnicodeEscape();
|
| +}
|
| +
|
| +
|
| +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);
|
| + if (cp < 0) {
|
| + return -1;
|
| + }
|
| + if (c0_ != '}') {
|
| + return -1;
|
| + }
|
| + Advance();
|
| + return cp;
|
| + }
|
| return ScanHexNumber(4);
|
| }
|
|
|
|
|