Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / v8 / src / scanner.cc
1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Features shared by parsing and pre-parsing scanners.
6
7 #include <stdint.h>
8
9 #include <cmath>
10
11 #include "src/v8.h"
12
13 #include "src/ast-value-factory.h"
14 #include "src/char-predicates-inl.h"
15 #include "src/conversions-inl.h"
16 #include "src/list-inl.h"
17 #include "src/parser.h"
18 #include "src/scanner.h"
19
20 namespace v8 {
21 namespace internal {
22
23
24 Handle<String> LiteralBuffer::Internalize(Isolate* isolate) const {
25   if (is_one_byte()) {
26     return isolate->factory()->InternalizeOneByteString(one_byte_literal());
27   }
28   return isolate->factory()->InternalizeTwoByteString(two_byte_literal());
29 }
30
31
32 // ----------------------------------------------------------------------------
33 // Scanner
34
35 Scanner::Scanner(UnicodeCache* unicode_cache)
36     : unicode_cache_(unicode_cache),
37       octal_pos_(Location::invalid()),
38       harmony_scoping_(false),
39       harmony_modules_(false),
40       harmony_numeric_literals_(false),
41       harmony_classes_(false) { }
42
43
44 void Scanner::Initialize(Utf16CharacterStream* source) {
45   source_ = source;
46   // Need to capture identifiers in order to recognize "get" and "set"
47   // in object literals.
48   Init();
49   // Skip initial whitespace allowing HTML comment ends just like
50   // after a newline and scan first token.
51   has_line_terminator_before_next_ = true;
52   SkipWhiteSpace();
53   Scan();
54 }
55
56
57 uc32 Scanner::ScanHexNumber(int expected_length) {
58   DCHECK(expected_length <= 4);  // prevent overflow
59
60   uc32 x = 0;
61   for (int i = 0; i < expected_length; i++) {
62     int d = HexValue(c0_);
63     if (d < 0) {
64       return -1;
65     }
66     x = x * 16 + d;
67     Advance();
68   }
69
70   return x;
71 }
72
73
74 // Ensure that tokens can be stored in a byte.
75 STATIC_ASSERT(Token::NUM_TOKENS <= 0x100);
76
77 // Table of one-character tokens, by character (0x00..0x7f only).
78 static const byte one_char_tokens[] = {
79   Token::ILLEGAL,
80   Token::ILLEGAL,
81   Token::ILLEGAL,
82   Token::ILLEGAL,
83   Token::ILLEGAL,
84   Token::ILLEGAL,
85   Token::ILLEGAL,
86   Token::ILLEGAL,
87   Token::ILLEGAL,
88   Token::ILLEGAL,
89   Token::ILLEGAL,
90   Token::ILLEGAL,
91   Token::ILLEGAL,
92   Token::ILLEGAL,
93   Token::ILLEGAL,
94   Token::ILLEGAL,
95   Token::ILLEGAL,
96   Token::ILLEGAL,
97   Token::ILLEGAL,
98   Token::ILLEGAL,
99   Token::ILLEGAL,
100   Token::ILLEGAL,
101   Token::ILLEGAL,
102   Token::ILLEGAL,
103   Token::ILLEGAL,
104   Token::ILLEGAL,
105   Token::ILLEGAL,
106   Token::ILLEGAL,
107   Token::ILLEGAL,
108   Token::ILLEGAL,
109   Token::ILLEGAL,
110   Token::ILLEGAL,
111   Token::ILLEGAL,
112   Token::ILLEGAL,
113   Token::ILLEGAL,
114   Token::ILLEGAL,
115   Token::ILLEGAL,
116   Token::ILLEGAL,
117   Token::ILLEGAL,
118   Token::ILLEGAL,
119   Token::LPAREN,       // 0x28
120   Token::RPAREN,       // 0x29
121   Token::ILLEGAL,
122   Token::ILLEGAL,
123   Token::COMMA,        // 0x2c
124   Token::ILLEGAL,
125   Token::ILLEGAL,
126   Token::ILLEGAL,
127   Token::ILLEGAL,
128   Token::ILLEGAL,
129   Token::ILLEGAL,
130   Token::ILLEGAL,
131   Token::ILLEGAL,
132   Token::ILLEGAL,
133   Token::ILLEGAL,
134   Token::ILLEGAL,
135   Token::ILLEGAL,
136   Token::ILLEGAL,
137   Token::COLON,        // 0x3a
138   Token::SEMICOLON,    // 0x3b
139   Token::ILLEGAL,
140   Token::ILLEGAL,
141   Token::ILLEGAL,
142   Token::CONDITIONAL,  // 0x3f
143   Token::ILLEGAL,
144   Token::ILLEGAL,
145   Token::ILLEGAL,
146   Token::ILLEGAL,
147   Token::ILLEGAL,
148   Token::ILLEGAL,
149   Token::ILLEGAL,
150   Token::ILLEGAL,
151   Token::ILLEGAL,
152   Token::ILLEGAL,
153   Token::ILLEGAL,
154   Token::ILLEGAL,
155   Token::ILLEGAL,
156   Token::ILLEGAL,
157   Token::ILLEGAL,
158   Token::ILLEGAL,
159   Token::ILLEGAL,
160   Token::ILLEGAL,
161   Token::ILLEGAL,
162   Token::ILLEGAL,
163   Token::ILLEGAL,
164   Token::ILLEGAL,
165   Token::ILLEGAL,
166   Token::ILLEGAL,
167   Token::ILLEGAL,
168   Token::ILLEGAL,
169   Token::ILLEGAL,
170   Token::LBRACK,     // 0x5b
171   Token::ILLEGAL,
172   Token::RBRACK,     // 0x5d
173   Token::ILLEGAL,
174   Token::ILLEGAL,
175   Token::ILLEGAL,
176   Token::ILLEGAL,
177   Token::ILLEGAL,
178   Token::ILLEGAL,
179   Token::ILLEGAL,
180   Token::ILLEGAL,
181   Token::ILLEGAL,
182   Token::ILLEGAL,
183   Token::ILLEGAL,
184   Token::ILLEGAL,
185   Token::ILLEGAL,
186   Token::ILLEGAL,
187   Token::ILLEGAL,
188   Token::ILLEGAL,
189   Token::ILLEGAL,
190   Token::ILLEGAL,
191   Token::ILLEGAL,
192   Token::ILLEGAL,
193   Token::ILLEGAL,
194   Token::ILLEGAL,
195   Token::ILLEGAL,
196   Token::ILLEGAL,
197   Token::ILLEGAL,
198   Token::ILLEGAL,
199   Token::ILLEGAL,
200   Token::ILLEGAL,
201   Token::ILLEGAL,
202   Token::LBRACE,       // 0x7b
203   Token::ILLEGAL,
204   Token::RBRACE,       // 0x7d
205   Token::BIT_NOT,      // 0x7e
206   Token::ILLEGAL
207 };
208
209
210 Token::Value Scanner::Next() {
211   current_ = next_;
212   has_line_terminator_before_next_ = false;
213   has_multiline_comment_before_next_ = false;
214   if (static_cast<unsigned>(c0_) <= 0x7f) {
215     Token::Value token = static_cast<Token::Value>(one_char_tokens[c0_]);
216     if (token != Token::ILLEGAL) {
217       int pos = source_pos();
218       next_.token = token;
219       next_.location.beg_pos = pos;
220       next_.location.end_pos = pos + 1;
221       Advance();
222       return current_.token;
223     }
224   }
225   Scan();
226   return current_.token;
227 }
228
229
230 // TODO(yangguo): check whether this is actually necessary.
231 static inline bool IsLittleEndianByteOrderMark(uc32 c) {
232   // The Unicode value U+FFFE is guaranteed never to be assigned as a
233   // Unicode character; this implies that in a Unicode context the
234   // 0xFF, 0xFE byte pattern can only be interpreted as the U+FEFF
235   // character expressed in little-endian byte order (since it could
236   // not be a U+FFFE character expressed in big-endian byte
237   // order). Nevertheless, we check for it to be compatible with
238   // Spidermonkey.
239   return c == 0xFFFE;
240 }
241
242
243 bool Scanner::SkipWhiteSpace() {
244   int start_position = source_pos();
245
246   while (true) {
247     while (true) {
248       // Advance as long as character is a WhiteSpace or LineTerminator.
249       // Remember if the latter is the case.
250       if (unicode_cache_->IsLineTerminator(c0_)) {
251         has_line_terminator_before_next_ = true;
252       } else if (!unicode_cache_->IsWhiteSpace(c0_) &&
253                  !IsLittleEndianByteOrderMark(c0_)) {
254         break;
255       }
256       Advance();
257     }
258
259     // If there is an HTML comment end '-->' at the beginning of a
260     // line (with only whitespace in front of it), we treat the rest
261     // of the line as a comment. This is in line with the way
262     // SpiderMonkey handles it.
263     if (c0_ == '-' && has_line_terminator_before_next_) {
264       Advance();
265       if (c0_ == '-') {
266         Advance();
267         if (c0_ == '>') {
268           // Treat the rest of the line as a comment.
269           SkipSingleLineComment();
270           // Continue skipping white space after the comment.
271           continue;
272         }
273         PushBack('-');  // undo Advance()
274       }
275       PushBack('-');  // undo Advance()
276     }
277     // Return whether or not we skipped any characters.
278     return source_pos() != start_position;
279   }
280 }
281
282
283 Token::Value Scanner::SkipSingleLineComment() {
284   Advance();
285
286   // The line terminator at the end of the line is not considered
287   // to be part of the single-line comment; it is recognized
288   // separately by the lexical grammar and becomes part of the
289   // stream of input elements for the syntactic grammar (see
290   // ECMA-262, section 7.4).
291   while (c0_ >= 0 && !unicode_cache_->IsLineTerminator(c0_)) {
292     Advance();
293   }
294
295   return Token::WHITESPACE;
296 }
297
298
299 Token::Value Scanner::SkipSourceURLComment() {
300   TryToParseSourceURLComment();
301   while (c0_ >= 0 && !unicode_cache_->IsLineTerminator(c0_)) {
302     Advance();
303   }
304
305   return Token::WHITESPACE;
306 }
307
308
309 void Scanner::TryToParseSourceURLComment() {
310   // Magic comments are of the form: //[#@]\s<name>=\s*<value>\s*.* and this
311   // function will just return if it cannot parse a magic comment.
312   if (!unicode_cache_->IsWhiteSpace(c0_))
313     return;
314   Advance();
315   LiteralBuffer name;
316   while (c0_ >= 0 && !unicode_cache_->IsWhiteSpaceOrLineTerminator(c0_) &&
317          c0_ != '=') {
318     name.AddChar(c0_);
319     Advance();
320   }
321   if (!name.is_one_byte()) return;
322   Vector<const uint8_t> name_literal = name.one_byte_literal();
323   LiteralBuffer* value;
324   if (name_literal == STATIC_CHAR_VECTOR("sourceURL")) {
325     value = &source_url_;
326   } else if (name_literal == STATIC_CHAR_VECTOR("sourceMappingURL")) {
327     value = &source_mapping_url_;
328   } else {
329     return;
330   }
331   if (c0_ != '=')
332     return;
333   Advance();
334   value->Reset();
335   while (c0_ >= 0 && unicode_cache_->IsWhiteSpace(c0_)) {
336     Advance();
337   }
338   while (c0_ >= 0 && !unicode_cache_->IsLineTerminator(c0_)) {
339     // Disallowed characters.
340     if (c0_ == '"' || c0_ == '\'') {
341       value->Reset();
342       return;
343     }
344     if (unicode_cache_->IsWhiteSpace(c0_)) {
345       break;
346     }
347     value->AddChar(c0_);
348     Advance();
349   }
350   // Allow whitespace at the end.
351   while (c0_ >= 0 && !unicode_cache_->IsLineTerminator(c0_)) {
352     if (!unicode_cache_->IsWhiteSpace(c0_)) {
353       value->Reset();
354       break;
355     }
356     Advance();
357   }
358 }
359
360
361 Token::Value Scanner::SkipMultiLineComment() {
362   DCHECK(c0_ == '*');
363   Advance();
364
365   while (c0_ >= 0) {
366     uc32 ch = c0_;
367     Advance();
368     if (unicode_cache_->IsLineTerminator(ch)) {
369       // Following ECMA-262, section 7.4, a comment containing
370       // a newline will make the comment count as a line-terminator.
371       has_multiline_comment_before_next_ = true;
372     }
373     // If we have reached the end of the multi-line comment, we
374     // consume the '/' and insert a whitespace. This way all
375     // multi-line comments are treated as whitespace.
376     if (ch == '*' && c0_ == '/') {
377       c0_ = ' ';
378       return Token::WHITESPACE;
379     }
380   }
381
382   // Unterminated multi-line comment.
383   return Token::ILLEGAL;
384 }
385
386
387 Token::Value Scanner::ScanHtmlComment() {
388   // Check for <!-- comments.
389   DCHECK(c0_ == '!');
390   Advance();
391   if (c0_ == '-') {
392     Advance();
393     if (c0_ == '-') return SkipSingleLineComment();
394     PushBack('-');  // undo Advance()
395   }
396   PushBack('!');  // undo Advance()
397   DCHECK(c0_ == '!');
398   return Token::LT;
399 }
400
401
402 void Scanner::Scan() {
403   next_.literal_chars = NULL;
404   Token::Value token;
405   do {
406     // Remember the position of the next token
407     next_.location.beg_pos = source_pos();
408
409     switch (c0_) {
410       case ' ':
411       case '\t':
412         Advance();
413         token = Token::WHITESPACE;
414         break;
415
416       case '\n':
417         Advance();
418         has_line_terminator_before_next_ = true;
419         token = Token::WHITESPACE;
420         break;
421
422       case '"': case '\'':
423         token = ScanString();
424         break;
425
426       case '<':
427         // < <= << <<= <!--
428         Advance();
429         if (c0_ == '=') {
430           token = Select(Token::LTE);
431         } else if (c0_ == '<') {
432           token = Select('=', Token::ASSIGN_SHL, Token::SHL);
433         } else if (c0_ == '!') {
434           token = ScanHtmlComment();
435         } else {
436           token = Token::LT;
437         }
438         break;
439
440       case '>':
441         // > >= >> >>= >>> >>>=
442         Advance();
443         if (c0_ == '=') {
444           token = Select(Token::GTE);
445         } else if (c0_ == '>') {
446           // >> >>= >>> >>>=
447           Advance();
448           if (c0_ == '=') {
449             token = Select(Token::ASSIGN_SAR);
450           } else if (c0_ == '>') {
451             token = Select('=', Token::ASSIGN_SHR, Token::SHR);
452           } else {
453             token = Token::SAR;
454           }
455         } else {
456           token = Token::GT;
457         }
458         break;
459
460       case '=':
461         // = == === =>
462         Advance();
463         if (c0_ == '=') {
464           token = Select('=', Token::EQ_STRICT, Token::EQ);
465         } else if (c0_ == '>') {
466           token = Select(Token::ARROW);
467         } else {
468           token = Token::ASSIGN;
469         }
470         break;
471
472       case '!':
473         // ! != !==
474         Advance();
475         if (c0_ == '=') {
476           token = Select('=', Token::NE_STRICT, Token::NE);
477         } else {
478           token = Token::NOT;
479         }
480         break;
481
482       case '+':
483         // + ++ +=
484         Advance();
485         if (c0_ == '+') {
486           token = Select(Token::INC);
487         } else if (c0_ == '=') {
488           token = Select(Token::ASSIGN_ADD);
489         } else {
490           token = Token::ADD;
491         }
492         break;
493
494       case '-':
495         // - -- --> -=
496         Advance();
497         if (c0_ == '-') {
498           Advance();
499           if (c0_ == '>' && has_line_terminator_before_next_) {
500             // For compatibility with SpiderMonkey, we skip lines that
501             // start with an HTML comment end '-->'.
502             token = SkipSingleLineComment();
503           } else {
504             token = Token::DEC;
505           }
506         } else if (c0_ == '=') {
507           token = Select(Token::ASSIGN_SUB);
508         } else {
509           token = Token::SUB;
510         }
511         break;
512
513       case '*':
514         // * *=
515         token = Select('=', Token::ASSIGN_MUL, Token::MUL);
516         break;
517
518       case '%':
519         // % %=
520         token = Select('=', Token::ASSIGN_MOD, Token::MOD);
521         break;
522
523       case '/':
524         // /  // /* /=
525         Advance();
526         if (c0_ == '/') {
527           Advance();
528           if (c0_ == '@' || c0_ == '#') {
529             Advance();
530             token = SkipSourceURLComment();
531           } else {
532             PushBack(c0_);
533             token = SkipSingleLineComment();
534           }
535         } else if (c0_ == '*') {
536           token = SkipMultiLineComment();
537         } else if (c0_ == '=') {
538           token = Select(Token::ASSIGN_DIV);
539         } else {
540           token = Token::DIV;
541         }
542         break;
543
544       case '&':
545         // & && &=
546         Advance();
547         if (c0_ == '&') {
548           token = Select(Token::AND);
549         } else if (c0_ == '=') {
550           token = Select(Token::ASSIGN_BIT_AND);
551         } else {
552           token = Token::BIT_AND;
553         }
554         break;
555
556       case '|':
557         // | || |=
558         Advance();
559         if (c0_ == '|') {
560           token = Select(Token::OR);
561         } else if (c0_ == '=') {
562           token = Select(Token::ASSIGN_BIT_OR);
563         } else {
564           token = Token::BIT_OR;
565         }
566         break;
567
568       case '^':
569         // ^ ^=
570         token = Select('=', Token::ASSIGN_BIT_XOR, Token::BIT_XOR);
571         break;
572
573       case '.':
574         // . Number
575         Advance();
576         if (IsDecimalDigit(c0_)) {
577           token = ScanNumber(true);
578         } else {
579           token = Token::PERIOD;
580         }
581         break;
582
583       case ':':
584         token = Select(Token::COLON);
585         break;
586
587       case ';':
588         token = Select(Token::SEMICOLON);
589         break;
590
591       case ',':
592         token = Select(Token::COMMA);
593         break;
594
595       case '(':
596         token = Select(Token::LPAREN);
597         break;
598
599       case ')':
600         token = Select(Token::RPAREN);
601         break;
602
603       case '[':
604         token = Select(Token::LBRACK);
605         break;
606
607       case ']':
608         token = Select(Token::RBRACK);
609         break;
610
611       case '{':
612         token = Select(Token::LBRACE);
613         break;
614
615       case '}':
616         token = Select(Token::RBRACE);
617         break;
618
619       case '?':
620         token = Select(Token::CONDITIONAL);
621         break;
622
623       case '~':
624         token = Select(Token::BIT_NOT);
625         break;
626
627       default:
628         if (unicode_cache_->IsIdentifierStart(c0_)) {
629           token = ScanIdentifierOrKeyword();
630         } else if (IsDecimalDigit(c0_)) {
631           token = ScanNumber(false);
632         } else if (SkipWhiteSpace()) {
633           token = Token::WHITESPACE;
634         } else if (c0_ < 0) {
635           token = Token::EOS;
636         } else {
637           token = Select(Token::ILLEGAL);
638         }
639         break;
640     }
641
642     // Continue scanning for tokens as long as we're just skipping
643     // whitespace.
644   } while (token == Token::WHITESPACE);
645
646   next_.location.end_pos = source_pos();
647   next_.token = token;
648 }
649
650
651 void Scanner::SeekForward(int pos) {
652   // After this call, we will have the token at the given position as
653   // the "next" token. The "current" token will be invalid.
654   if (pos == next_.location.beg_pos) return;
655   int current_pos = source_pos();
656   DCHECK_EQ(next_.location.end_pos, current_pos);
657   // Positions inside the lookahead token aren't supported.
658   DCHECK(pos >= current_pos);
659   if (pos != current_pos) {
660     source_->SeekForward(pos - source_->pos());
661     Advance();
662     // This function is only called to seek to the location
663     // of the end of a function (at the "}" token). It doesn't matter
664     // whether there was a line terminator in the part we skip.
665     has_line_terminator_before_next_ = false;
666     has_multiline_comment_before_next_ = false;
667   }
668   Scan();
669 }
670
671
672 bool Scanner::ScanEscape() {
673   uc32 c = c0_;
674   Advance();
675
676   // Skip escaped newlines.
677   if (unicode_cache_->IsLineTerminator(c)) {
678     // Allow CR+LF newlines in multiline string literals.
679     if (IsCarriageReturn(c) && IsLineFeed(c0_)) Advance();
680     // Allow LF+CR newlines in multiline string literals.
681     if (IsLineFeed(c) && IsCarriageReturn(c0_)) Advance();
682     return true;
683   }
684
685   switch (c) {
686     case '\'':  // fall through
687     case '"' :  // fall through
688     case '\\': break;
689     case 'b' : c = '\b'; break;
690     case 'f' : c = '\f'; break;
691     case 'n' : c = '\n'; break;
692     case 'r' : c = '\r'; break;
693     case 't' : c = '\t'; break;
694     case 'u' : {
695       c = ScanHexNumber(4);
696       if (c < 0) return false;
697       break;
698     }
699     case 'v' : c = '\v'; break;
700     case 'x' : {
701       c = ScanHexNumber(2);
702       if (c < 0) return false;
703       break;
704     }
705     case '0' :  // fall through
706     case '1' :  // fall through
707     case '2' :  // fall through
708     case '3' :  // fall through
709     case '4' :  // fall through
710     case '5' :  // fall through
711     case '6' :  // fall through
712     case '7' : c = ScanOctalEscape(c, 2); break;
713   }
714
715   // According to ECMA-262, section 7.8.4, characters not covered by the
716   // above cases should be illegal, but they are commonly handled as
717   // non-escaped characters by JS VMs.
718   AddLiteralChar(c);
719   return true;
720 }
721
722
723 // Octal escapes of the forms '\0xx' and '\xxx' are not a part of
724 // ECMA-262. Other JS VMs support them.
725 uc32 Scanner::ScanOctalEscape(uc32 c, int length) {
726   uc32 x = c - '0';
727   int i = 0;
728   for (; i < length; i++) {
729     int d = c0_ - '0';
730     if (d < 0 || d > 7) break;
731     int nx = x * 8 + d;
732     if (nx >= 256) break;
733     x = nx;
734     Advance();
735   }
736   // Anything except '\0' is an octal escape sequence, illegal in strict mode.
737   // Remember the position of octal escape sequences so that an error
738   // can be reported later (in strict mode).
739   // We don't report the error immediately, because the octal escape can
740   // occur before the "use strict" directive.
741   if (c != '0' || i > 0) {
742     octal_pos_ = Location(source_pos() - i - 1, source_pos() - 1);
743   }
744   return x;
745 }
746
747
748 Token::Value Scanner::ScanString() {
749   uc32 quote = c0_;
750   Advance();  // consume quote
751
752   LiteralScope literal(this);
753   while (c0_ != quote && c0_ >= 0
754          && !unicode_cache_->IsLineTerminator(c0_)) {
755     uc32 c = c0_;
756     Advance();
757     if (c == '\\') {
758       if (c0_ < 0 || !ScanEscape()) return Token::ILLEGAL;
759     } else {
760       AddLiteralChar(c);
761     }
762   }
763   if (c0_ != quote) return Token::ILLEGAL;
764   literal.Complete();
765
766   Advance();  // consume quote
767   return Token::STRING;
768 }
769
770
771 void Scanner::ScanDecimalDigits() {
772   while (IsDecimalDigit(c0_))
773     AddLiteralCharAdvance();
774 }
775
776
777 Token::Value Scanner::ScanNumber(bool seen_period) {
778   DCHECK(IsDecimalDigit(c0_));  // the first digit of the number or the fraction
779
780   enum { DECIMAL, HEX, OCTAL, IMPLICIT_OCTAL, BINARY } kind = DECIMAL;
781
782   LiteralScope literal(this);
783   if (seen_period) {
784     // we have already seen a decimal point of the float
785     AddLiteralChar('.');
786     ScanDecimalDigits();  // we know we have at least one digit
787
788   } else {
789     // if the first character is '0' we must check for octals and hex
790     if (c0_ == '0') {
791       int start_pos = source_pos();  // For reporting octal positions.
792       AddLiteralCharAdvance();
793
794       // either 0, 0exxx, 0Exxx, 0.xxx, a hex number, a binary number or
795       // an octal number.
796       if (c0_ == 'x' || c0_ == 'X') {
797         // hex number
798         kind = HEX;
799         AddLiteralCharAdvance();
800         if (!IsHexDigit(c0_)) {
801           // we must have at least one hex digit after 'x'/'X'
802           return Token::ILLEGAL;
803         }
804         while (IsHexDigit(c0_)) {
805           AddLiteralCharAdvance();
806         }
807       } else if (harmony_numeric_literals_ && (c0_ == 'o' || c0_ == 'O')) {
808         kind = OCTAL;
809         AddLiteralCharAdvance();
810         if (!IsOctalDigit(c0_)) {
811           // we must have at least one octal digit after 'o'/'O'
812           return Token::ILLEGAL;
813         }
814         while (IsOctalDigit(c0_)) {
815           AddLiteralCharAdvance();
816         }
817       } else if (harmony_numeric_literals_ && (c0_ == 'b' || c0_ == 'B')) {
818         kind = BINARY;
819         AddLiteralCharAdvance();
820         if (!IsBinaryDigit(c0_)) {
821           // we must have at least one binary digit after 'b'/'B'
822           return Token::ILLEGAL;
823         }
824         while (IsBinaryDigit(c0_)) {
825           AddLiteralCharAdvance();
826         }
827       } else if ('0' <= c0_ && c0_ <= '7') {
828         // (possible) octal number
829         kind = IMPLICIT_OCTAL;
830         while (true) {
831           if (c0_ == '8' || c0_ == '9') {
832             kind = DECIMAL;
833             break;
834           }
835           if (c0_  < '0' || '7'  < c0_) {
836             // Octal literal finished.
837             octal_pos_ = Location(start_pos, source_pos());
838             break;
839           }
840           AddLiteralCharAdvance();
841         }
842       }
843     }
844
845     // Parse decimal digits and allow trailing fractional part.
846     if (kind == DECIMAL) {
847       ScanDecimalDigits();  // optional
848       if (c0_ == '.') {
849         AddLiteralCharAdvance();
850         ScanDecimalDigits();  // optional
851       }
852     }
853   }
854
855   // scan exponent, if any
856   if (c0_ == 'e' || c0_ == 'E') {
857     DCHECK(kind != HEX);  // 'e'/'E' must be scanned as part of the hex number
858     if (kind != DECIMAL) return Token::ILLEGAL;
859     // scan exponent
860     AddLiteralCharAdvance();
861     if (c0_ == '+' || c0_ == '-')
862       AddLiteralCharAdvance();
863     if (!IsDecimalDigit(c0_)) {
864       // we must have at least one decimal digit after 'e'/'E'
865       return Token::ILLEGAL;
866     }
867     ScanDecimalDigits();
868   }
869
870   // The source character immediately following a numeric literal must
871   // not be an identifier start or a decimal digit; see ECMA-262
872   // section 7.8.3, page 17 (note that we read only one decimal digit
873   // if the value is 0).
874   if (IsDecimalDigit(c0_) || unicode_cache_->IsIdentifierStart(c0_))
875     return Token::ILLEGAL;
876
877   literal.Complete();
878
879   return Token::NUMBER;
880 }
881
882
883 uc32 Scanner::ScanIdentifierUnicodeEscape() {
884   Advance();
885   if (c0_ != 'u') return -1;
886   Advance();
887   return ScanHexNumber(4);
888 }
889
890
891 // ----------------------------------------------------------------------------
892 // Keyword Matcher
893
894 #define KEYWORDS(KEYWORD_GROUP, KEYWORD)                                     \
895   KEYWORD_GROUP('b')                                                         \
896   KEYWORD("break", Token::BREAK)                                             \
897   KEYWORD_GROUP('c')                                                         \
898   KEYWORD("case", Token::CASE)                                               \
899   KEYWORD("catch", Token::CATCH)                                             \
900   KEYWORD("class",                                                           \
901           harmony_classes ? Token::CLASS : Token::FUTURE_RESERVED_WORD)      \
902   KEYWORD("const", Token::CONST)                                             \
903   KEYWORD("continue", Token::CONTINUE)                                       \
904   KEYWORD_GROUP('d')                                                         \
905   KEYWORD("debugger", Token::DEBUGGER)                                       \
906   KEYWORD("default", Token::DEFAULT)                                         \
907   KEYWORD("delete", Token::DELETE)                                           \
908   KEYWORD("do", Token::DO)                                                   \
909   KEYWORD_GROUP('e')                                                         \
910   KEYWORD("else", Token::ELSE)                                               \
911   KEYWORD("enum", Token::FUTURE_RESERVED_WORD)                               \
912   KEYWORD("export",                                                          \
913           harmony_modules ? Token::EXPORT : Token::FUTURE_RESERVED_WORD)     \
914   KEYWORD("extends",                                                         \
915           harmony_classes ? Token::EXTENDS : Token::FUTURE_RESERVED_WORD)    \
916   KEYWORD_GROUP('f')                                                         \
917   KEYWORD("false", Token::FALSE_LITERAL)                                     \
918   KEYWORD("finally", Token::FINALLY)                                         \
919   KEYWORD("for", Token::FOR)                                                 \
920   KEYWORD("function", Token::FUNCTION)                                       \
921   KEYWORD_GROUP('i')                                                         \
922   KEYWORD("if", Token::IF)                                                   \
923   KEYWORD("implements", Token::FUTURE_STRICT_RESERVED_WORD)                  \
924   KEYWORD("import",                                                          \
925           harmony_modules ? Token::IMPORT : Token::FUTURE_RESERVED_WORD)     \
926   KEYWORD("in", Token::IN)                                                   \
927   KEYWORD("instanceof", Token::INSTANCEOF)                                   \
928   KEYWORD("interface", Token::FUTURE_STRICT_RESERVED_WORD)                   \
929   KEYWORD_GROUP('l')                                                         \
930   KEYWORD("let",                                                             \
931           harmony_scoping ? Token::LET : Token::FUTURE_STRICT_RESERVED_WORD) \
932   KEYWORD_GROUP('n')                                                         \
933   KEYWORD("new", Token::NEW)                                                 \
934   KEYWORD("null", Token::NULL_LITERAL)                                       \
935   KEYWORD_GROUP('p')                                                         \
936   KEYWORD("package", Token::FUTURE_STRICT_RESERVED_WORD)                     \
937   KEYWORD("private", Token::FUTURE_STRICT_RESERVED_WORD)                     \
938   KEYWORD("protected", Token::FUTURE_STRICT_RESERVED_WORD)                   \
939   KEYWORD("public", Token::FUTURE_STRICT_RESERVED_WORD)                      \
940   KEYWORD_GROUP('r')                                                         \
941   KEYWORD("return", Token::RETURN)                                           \
942   KEYWORD_GROUP('s')                                                         \
943   KEYWORD("static", harmony_classes ? Token::STATIC                          \
944                                     : Token::FUTURE_STRICT_RESERVED_WORD)    \
945   KEYWORD("super",                                                           \
946           harmony_classes ? Token::SUPER : Token::FUTURE_RESERVED_WORD)      \
947   KEYWORD("switch", Token::SWITCH)                                           \
948   KEYWORD_GROUP('t')                                                         \
949   KEYWORD("this", Token::THIS)                                               \
950   KEYWORD("throw", Token::THROW)                                             \
951   KEYWORD("true", Token::TRUE_LITERAL)                                       \
952   KEYWORD("try", Token::TRY)                                                 \
953   KEYWORD("typeof", Token::TYPEOF)                                           \
954   KEYWORD_GROUP('v')                                                         \
955   KEYWORD("var", Token::VAR)                                                 \
956   KEYWORD("void", Token::VOID)                                               \
957   KEYWORD_GROUP('w')                                                         \
958   KEYWORD("while", Token::WHILE)                                             \
959   KEYWORD("with", Token::WITH)                                               \
960   KEYWORD_GROUP('y')                                                         \
961   KEYWORD("yield", Token::YIELD)
962
963
964 static Token::Value KeywordOrIdentifierToken(const uint8_t* input,
965                                              int input_length,
966                                              bool harmony_scoping,
967                                              bool harmony_modules,
968                                              bool harmony_classes) {
969   DCHECK(input_length >= 1);
970   const int kMinLength = 2;
971   const int kMaxLength = 10;
972   if (input_length < kMinLength || input_length > kMaxLength) {
973     return Token::IDENTIFIER;
974   }
975   switch (input[0]) {
976     default:
977 #define KEYWORD_GROUP_CASE(ch)                                \
978       break;                                                  \
979     case ch:
980 #define KEYWORD(keyword, token)                               \
981     {                                                         \
982       /* 'keyword' is a char array, so sizeof(keyword) is */  \
983       /* strlen(keyword) plus 1 for the NUL char. */          \
984       const int keyword_length = sizeof(keyword) - 1;         \
985       STATIC_ASSERT(keyword_length >= kMinLength);            \
986       STATIC_ASSERT(keyword_length <= kMaxLength);            \
987       if (input_length == keyword_length &&                   \
988           input[1] == keyword[1] &&                           \
989           (keyword_length <= 2 || input[2] == keyword[2]) &&  \
990           (keyword_length <= 3 || input[3] == keyword[3]) &&  \
991           (keyword_length <= 4 || input[4] == keyword[4]) &&  \
992           (keyword_length <= 5 || input[5] == keyword[5]) &&  \
993           (keyword_length <= 6 || input[6] == keyword[6]) &&  \
994           (keyword_length <= 7 || input[7] == keyword[7]) &&  \
995           (keyword_length <= 8 || input[8] == keyword[8]) &&  \
996           (keyword_length <= 9 || input[9] == keyword[9])) {  \
997         return token;                                         \
998       }                                                       \
999     }
1000     KEYWORDS(KEYWORD_GROUP_CASE, KEYWORD)
1001   }
1002   return Token::IDENTIFIER;
1003 }
1004
1005
1006 bool Scanner::IdentifierIsFutureStrictReserved(
1007     const AstRawString* string) const {
1008   // Keywords are always 1-byte strings.
1009   if (!string->is_one_byte()) return false;
1010   if (string->IsOneByteEqualTo("let") || string->IsOneByteEqualTo("static") ||
1011       string->IsOneByteEqualTo("yield")) {
1012     return true;
1013   }
1014   return Token::FUTURE_STRICT_RESERVED_WORD ==
1015          KeywordOrIdentifierToken(string->raw_data(), string->length(),
1016                                   harmony_scoping_, harmony_modules_,
1017                                   harmony_classes_);
1018 }
1019
1020
1021 Token::Value Scanner::ScanIdentifierOrKeyword() {
1022   DCHECK(unicode_cache_->IsIdentifierStart(c0_));
1023   LiteralScope literal(this);
1024   // Scan identifier start character.
1025   if (c0_ == '\\') {
1026     uc32 c = ScanIdentifierUnicodeEscape();
1027     // Only allow legal identifier start characters.
1028     if (c < 0 ||
1029         c == '\\' ||  // No recursive escapes.
1030         !unicode_cache_->IsIdentifierStart(c)) {
1031       return Token::ILLEGAL;
1032     }
1033     AddLiteralChar(c);
1034     return ScanIdentifierSuffix(&literal);
1035   }
1036
1037   uc32 first_char = c0_;
1038   Advance();
1039   AddLiteralChar(first_char);
1040
1041   // Scan the rest of the identifier characters.
1042   while (unicode_cache_->IsIdentifierPart(c0_)) {
1043     if (c0_ != '\\') {
1044       uc32 next_char = c0_;
1045       Advance();
1046       AddLiteralChar(next_char);
1047       continue;
1048     }
1049     // Fallthrough if no longer able to complete keyword.
1050     return ScanIdentifierSuffix(&literal);
1051   }
1052
1053   literal.Complete();
1054
1055   if (next_.literal_chars->is_one_byte()) {
1056     Vector<const uint8_t> chars = next_.literal_chars->one_byte_literal();
1057     return KeywordOrIdentifierToken(chars.start(),
1058                                     chars.length(),
1059                                     harmony_scoping_,
1060                                     harmony_modules_,
1061                                     harmony_classes_);
1062   }
1063
1064   return Token::IDENTIFIER;
1065 }
1066
1067
1068 Token::Value Scanner::ScanIdentifierSuffix(LiteralScope* literal) {
1069   // Scan the rest of the identifier characters.
1070   while (unicode_cache_->IsIdentifierPart(c0_)) {
1071     if (c0_ == '\\') {
1072       uc32 c = ScanIdentifierUnicodeEscape();
1073       // Only allow legal identifier part characters.
1074       if (c < 0 ||
1075           c == '\\' ||
1076           !unicode_cache_->IsIdentifierPart(c)) {
1077         return Token::ILLEGAL;
1078       }
1079       AddLiteralChar(c);
1080     } else {
1081       AddLiteralChar(c0_);
1082       Advance();
1083     }
1084   }
1085   literal->Complete();
1086
1087   return Token::IDENTIFIER;
1088 }
1089
1090
1091 bool Scanner::ScanRegExpPattern(bool seen_equal) {
1092   // Scan: ('/' | '/=') RegularExpressionBody '/' RegularExpressionFlags
1093   bool in_character_class = false;
1094
1095   // Previous token is either '/' or '/=', in the second case, the
1096   // pattern starts at =.
1097   next_.location.beg_pos = source_pos() - (seen_equal ? 2 : 1);
1098   next_.location.end_pos = source_pos() - (seen_equal ? 1 : 0);
1099
1100   // Scan regular expression body: According to ECMA-262, 3rd, 7.8.5,
1101   // the scanner should pass uninterpreted bodies to the RegExp
1102   // constructor.
1103   LiteralScope literal(this);
1104   if (seen_equal) {
1105     AddLiteralChar('=');
1106   }
1107
1108   while (c0_ != '/' || in_character_class) {
1109     if (unicode_cache_->IsLineTerminator(c0_) || c0_ < 0) return false;
1110     if (c0_ == '\\') {  // Escape sequence.
1111       AddLiteralCharAdvance();
1112       if (unicode_cache_->IsLineTerminator(c0_) || c0_ < 0) return false;
1113       AddLiteralCharAdvance();
1114       // If the escape allows more characters, i.e., \x??, \u????, or \c?,
1115       // only "safe" characters are allowed (letters, digits, underscore),
1116       // otherwise the escape isn't valid and the invalid character has
1117       // its normal meaning. I.e., we can just continue scanning without
1118       // worrying whether the following characters are part of the escape
1119       // or not, since any '/', '\\' or '[' is guaranteed to not be part
1120       // of the escape sequence.
1121
1122       // TODO(896): At some point, parse RegExps more throughly to capture
1123       // octal esacpes in strict mode.
1124     } else {  // Unescaped character.
1125       if (c0_ == '[') in_character_class = true;
1126       if (c0_ == ']') in_character_class = false;
1127       AddLiteralCharAdvance();
1128     }
1129   }
1130   Advance();  // consume '/'
1131
1132   literal.Complete();
1133
1134   return true;
1135 }
1136
1137
1138 bool Scanner::ScanLiteralUnicodeEscape() {
1139   DCHECK(c0_ == '\\');
1140   AddLiteralChar(c0_);
1141   Advance();
1142   int hex_digits_read = 0;
1143   if (c0_ == 'u') {
1144     AddLiteralChar(c0_);
1145     while (hex_digits_read < 4) {
1146       Advance();
1147       if (!IsHexDigit(c0_)) break;
1148       AddLiteralChar(c0_);
1149       ++hex_digits_read;
1150     }
1151   }
1152   return hex_digits_read == 4;
1153 }
1154
1155
1156 bool Scanner::ScanRegExpFlags() {
1157   // Scan regular expression flags.
1158   LiteralScope literal(this);
1159   while (unicode_cache_->IsIdentifierPart(c0_)) {
1160     if (c0_ != '\\') {
1161       AddLiteralCharAdvance();
1162     } else {
1163       if (!ScanLiteralUnicodeEscape()) {
1164         return false;
1165       }
1166       Advance();
1167     }
1168   }
1169   literal.Complete();
1170
1171   next_.location.end_pos = source_pos() - 1;
1172   return true;
1173 }
1174
1175
1176 const AstRawString* Scanner::CurrentSymbol(AstValueFactory* ast_value_factory) {
1177   if (is_literal_one_byte()) {
1178     return ast_value_factory->GetOneByteString(literal_one_byte_string());
1179   }
1180   return ast_value_factory->GetTwoByteString(literal_two_byte_string());
1181 }
1182
1183
1184 const AstRawString* Scanner::NextSymbol(AstValueFactory* ast_value_factory) {
1185   if (is_next_literal_one_byte()) {
1186     return ast_value_factory->GetOneByteString(next_literal_one_byte_string());
1187   }
1188   return ast_value_factory->GetTwoByteString(next_literal_two_byte_string());
1189 }
1190
1191
1192 double Scanner::DoubleValue() {
1193   DCHECK(is_literal_one_byte());
1194   return StringToDouble(
1195       unicode_cache_,
1196       literal_one_byte_string(),
1197       ALLOW_HEX | ALLOW_OCTAL | ALLOW_IMPLICIT_OCTAL | ALLOW_BINARY);
1198 }
1199
1200
1201 int Scanner::FindNumber(DuplicateFinder* finder, int value) {
1202   return finder->AddNumber(literal_one_byte_string(), value);
1203 }
1204
1205
1206 int Scanner::FindSymbol(DuplicateFinder* finder, int value) {
1207   if (is_literal_one_byte()) {
1208     return finder->AddOneByteSymbol(literal_one_byte_string(), value);
1209   }
1210   return finder->AddTwoByteSymbol(literal_two_byte_string(), value);
1211 }
1212
1213
1214 int DuplicateFinder::AddOneByteSymbol(Vector<const uint8_t> key, int value) {
1215   return AddSymbol(key, true, value);
1216 }
1217
1218
1219 int DuplicateFinder::AddTwoByteSymbol(Vector<const uint16_t> key, int value) {
1220   return AddSymbol(Vector<const uint8_t>::cast(key), false, value);
1221 }
1222
1223
1224 int DuplicateFinder::AddSymbol(Vector<const uint8_t> key,
1225                                bool is_one_byte,
1226                                int value) {
1227   uint32_t hash = Hash(key, is_one_byte);
1228   byte* encoding = BackupKey(key, is_one_byte);
1229   HashMap::Entry* entry = map_.Lookup(encoding, hash, true);
1230   int old_value = static_cast<int>(reinterpret_cast<intptr_t>(entry->value));
1231   entry->value =
1232     reinterpret_cast<void*>(static_cast<intptr_t>(value | old_value));
1233   return old_value;
1234 }
1235
1236
1237 int DuplicateFinder::AddNumber(Vector<const uint8_t> key, int value) {
1238   DCHECK(key.length() > 0);
1239   // Quick check for already being in canonical form.
1240   if (IsNumberCanonical(key)) {
1241     return AddOneByteSymbol(key, value);
1242   }
1243
1244   int flags = ALLOW_HEX | ALLOW_OCTAL | ALLOW_IMPLICIT_OCTAL | ALLOW_BINARY;
1245   double double_value = StringToDouble(
1246       unicode_constants_, key, flags, 0.0);
1247   int length;
1248   const char* string;
1249   if (!std::isfinite(double_value)) {
1250     string = "Infinity";
1251     length = 8;  // strlen("Infinity");
1252   } else {
1253     string = DoubleToCString(double_value,
1254                              Vector<char>(number_buffer_, kBufferSize));
1255     length = StrLength(string);
1256   }
1257   return AddSymbol(Vector<const byte>(reinterpret_cast<const byte*>(string),
1258                                       length), true, value);
1259 }
1260
1261
1262 bool DuplicateFinder::IsNumberCanonical(Vector<const uint8_t> number) {
1263   // Test for a safe approximation of number literals that are already
1264   // in canonical form: max 15 digits, no leading zeroes, except an
1265   // integer part that is a single zero, and no trailing zeros below
1266   // the decimal point.
1267   int pos = 0;
1268   int length = number.length();
1269   if (number.length() > 15) return false;
1270   if (number[pos] == '0') {
1271     pos++;
1272   } else {
1273     while (pos < length &&
1274            static_cast<unsigned>(number[pos] - '0') <= ('9' - '0')) pos++;
1275   }
1276   if (length == pos) return true;
1277   if (number[pos] != '.') return false;
1278   pos++;
1279   bool invalid_last_digit = true;
1280   while (pos < length) {
1281     uint8_t digit = number[pos] - '0';
1282     if (digit > '9' - '0') return false;
1283     invalid_last_digit = (digit == 0);
1284     pos++;
1285   }
1286   return !invalid_last_digit;
1287 }
1288
1289
1290 uint32_t DuplicateFinder::Hash(Vector<const uint8_t> key, bool is_one_byte) {
1291   // Primitive hash function, almost identical to the one used
1292   // for strings (except that it's seeded by the length and representation).
1293   int length = key.length();
1294   uint32_t hash = (length << 1) | (is_one_byte ? 1 : 0) ;
1295   for (int i = 0; i < length; i++) {
1296     uint32_t c = key[i];
1297     hash = (hash + c) * 1025;
1298     hash ^= (hash >> 6);
1299   }
1300   return hash;
1301 }
1302
1303
1304 bool DuplicateFinder::Match(void* first, void* second) {
1305   // Decode lengths.
1306   // Length + representation is encoded as base 128, most significant heptet
1307   // first, with a 8th bit being non-zero while there are more heptets.
1308   // The value encodes the number of bytes following, and whether the original
1309   // was Latin1.
1310   byte* s1 = reinterpret_cast<byte*>(first);
1311   byte* s2 = reinterpret_cast<byte*>(second);
1312   uint32_t length_one_byte_field = 0;
1313   byte c1;
1314   do {
1315     c1 = *s1;
1316     if (c1 != *s2) return false;
1317     length_one_byte_field = (length_one_byte_field << 7) | (c1 & 0x7f);
1318     s1++;
1319     s2++;
1320   } while ((c1 & 0x80) != 0);
1321   int length = static_cast<int>(length_one_byte_field >> 1);
1322   return memcmp(s1, s2, length) == 0;
1323 }
1324
1325
1326 byte* DuplicateFinder::BackupKey(Vector<const uint8_t> bytes,
1327                                  bool is_one_byte) {
1328   uint32_t one_byte_length = (bytes.length() << 1) | (is_one_byte ? 1 : 0);
1329   backing_store_.StartSequence();
1330   // Emit one_byte_length as base-128 encoded number, with the 7th bit set
1331   // on the byte of every heptet except the last, least significant, one.
1332   if (one_byte_length >= (1 << 7)) {
1333     if (one_byte_length >= (1 << 14)) {
1334       if (one_byte_length >= (1 << 21)) {
1335         if (one_byte_length >= (1 << 28)) {
1336           backing_store_.Add(
1337               static_cast<uint8_t>((one_byte_length >> 28) | 0x80));
1338         }
1339         backing_store_.Add(
1340             static_cast<uint8_t>((one_byte_length >> 21) | 0x80u));
1341       }
1342       backing_store_.Add(
1343           static_cast<uint8_t>((one_byte_length >> 14) | 0x80u));
1344     }
1345     backing_store_.Add(static_cast<uint8_t>((one_byte_length >> 7) | 0x80u));
1346   }
1347   backing_store_.Add(static_cast<uint8_t>(one_byte_length & 0x7f));
1348
1349   backing_store_.AddBlock(bytes);
1350   return backing_store_.EndSequence().start();
1351 }
1352
1353 } }  // namespace v8::internal