Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(223)

Side by Side Diff: src/scanner-base.cc

Issue 6927075: Strict mode detection in preparser. (Closed)
Patch Set: Added TODO with bugnumber for R Created 9 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/scanner-base.h ('k') | test/preparser/non-use-strict-hex-escape.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 20 matching lines...) Expand all
31 #include "scanner-base.h" 31 #include "scanner-base.h"
32 #include "char-predicates-inl.h" 32 #include "char-predicates-inl.h"
33 33
34 namespace v8 { 34 namespace v8 {
35 namespace internal { 35 namespace internal {
36 36
37 // ---------------------------------------------------------------------------- 37 // ----------------------------------------------------------------------------
38 // Scanner 38 // Scanner
39 39
40 Scanner::Scanner(UnicodeCache* unicode_cache) 40 Scanner::Scanner(UnicodeCache* unicode_cache)
41 : unicode_cache_(unicode_cache), 41 : unicode_cache_(unicode_cache) { }
42 octal_pos_(kNoOctalLocation) { }
43 42
44 43
45 uc32 Scanner::ScanHexEscape(uc32 c, int length) { 44 uc32 Scanner::ScanHexEscape(uc32 c, int length) {
46 ASSERT(length <= 4); // prevent overflow 45 ASSERT(length <= 4); // prevent overflow
47 46
48 uc32 digits[4]; 47 uc32 digits[4];
49 uc32 x = 0; 48 uc32 x = 0;
50 for (int i = 0; i < length; i++) { 49 for (int i = 0; i < length; i++) {
51 digits[i] = c0_; 50 digits[i] = c0_;
52 int d = HexValue(c0_); 51 int d = HexValue(c0_);
(...skipping 10 matching lines...) Expand all
63 return c; 62 return c;
64 } 63 }
65 x = x * 16 + d; 64 x = x * 16 + d;
66 Advance(); 65 Advance();
67 } 66 }
68 67
69 return x; 68 return x;
70 } 69 }
71 70
72 71
73 // Octal escapes of the forms '\0xx' and '\xxx' are not a part of
74 // ECMA-262. Other JS VMs support them.
75 uc32 Scanner::ScanOctalEscape(uc32 c, int length) {
76 uc32 x = c - '0';
77 int i = 0;
78 for (; i < length; i++) {
79 int d = c0_ - '0';
80 if (d < 0 || d > 7) break;
81 int nx = x * 8 + d;
82 if (nx >= 256) break;
83 x = nx;
84 Advance();
85 }
86 // Anything excelt '\0' is an octal escape sequence, illegal in strict mode.
87 // Remember the position of octal escape sequences so that better error
88 // can be reported later (in strict mode).
89 if (c != '0' || i > 0) {
90 octal_pos_ = source_pos() - i - 1; // Already advanced
91 }
92 return x;
93 }
94
95 72
96 // ---------------------------------------------------------------------------- 73 // ----------------------------------------------------------------------------
97 // JavaScriptScanner 74 // JavaScriptScanner
98 75
99 JavaScriptScanner::JavaScriptScanner(UnicodeCache* scanner_contants) 76 JavaScriptScanner::JavaScriptScanner(UnicodeCache* scanner_contants)
100 : Scanner(scanner_contants) { } 77 : Scanner(scanner_contants), octal_pos_(Location::invalid()) { }
101 78
102 79
103 Token::Value JavaScriptScanner::Next() { 80 Token::Value JavaScriptScanner::Next() {
104 current_ = next_; 81 current_ = next_;
105 has_line_terminator_before_next_ = false; 82 has_line_terminator_before_next_ = false;
106 Scan(); 83 Scan();
107 return current_.token; 84 return current_.token;
108 } 85 }
109 86
110 87
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after
511 case '7' : c = ScanOctalEscape(c, 2); break; 488 case '7' : c = ScanOctalEscape(c, 2); break;
512 } 489 }
513 490
514 // According to ECMA-262, 3rd, 7.8.4 (p 18ff) these 491 // According to ECMA-262, 3rd, 7.8.4 (p 18ff) these
515 // should be illegal, but they are commonly handled 492 // should be illegal, but they are commonly handled
516 // as non-escaped characters by JS VMs. 493 // as non-escaped characters by JS VMs.
517 AddLiteralChar(c); 494 AddLiteralChar(c);
518 } 495 }
519 496
520 497
498 // Octal escapes of the forms '\0xx' and '\xxx' are not a part of
499 // ECMA-262. Other JS VMs support them.
500 uc32 JavaScriptScanner::ScanOctalEscape(uc32 c, int length) {
501 uc32 x = c - '0';
502 int i = 0;
503 for (; i < length; i++) {
504 int d = c0_ - '0';
505 if (d < 0 || d > 7) break;
506 int nx = x * 8 + d;
507 if (nx >= 256) break;
508 x = nx;
509 Advance();
510 }
511 // Anything except '\0' is an octal escape sequence, illegal in strict mode.
512 // Remember the position of octal escape sequences so that an error
513 // can be reported later (in strict mode).
514 // We don't report the error immediately, because the octal escape can
515 // occur before the "use strict" directive.
516 if (c != '0' || i > 0) {
517 octal_pos_ = Location(source_pos() - i - 1, source_pos() - 1);
518 }
519 return x;
520 }
521
522
521 Token::Value JavaScriptScanner::ScanString() { 523 Token::Value JavaScriptScanner::ScanString() {
522 uc32 quote = c0_; 524 uc32 quote = c0_;
523 Advance(); // consume quote 525 Advance(); // consume quote
524 526
525 LiteralScope literal(this); 527 LiteralScope literal(this);
526 while (c0_ != quote && c0_ >= 0 528 while (c0_ != quote && c0_ >= 0
527 && !unicode_cache_->IsLineTerminator(c0_)) { 529 && !unicode_cache_->IsLineTerminator(c0_)) {
528 uc32 c = c0_; 530 uc32 c = c0_;
529 Advance(); 531 Advance();
530 if (c == '\\') { 532 if (c == '\\') {
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
579 } else if ('0' <= c0_ && c0_ <= '7') { 581 } else if ('0' <= c0_ && c0_ <= '7') {
580 // (possible) octal number 582 // (possible) octal number
581 kind = OCTAL; 583 kind = OCTAL;
582 while (true) { 584 while (true) {
583 if (c0_ == '8' || c0_ == '9') { 585 if (c0_ == '8' || c0_ == '9') {
584 kind = DECIMAL; 586 kind = DECIMAL;
585 break; 587 break;
586 } 588 }
587 if (c0_ < '0' || '7' < c0_) { 589 if (c0_ < '0' || '7' < c0_) {
588 // Octal literal finished. 590 // Octal literal finished.
589 octal_pos_ = next_.location.beg_pos; 591 octal_pos_ = next_.location;
590 break; 592 break;
591 } 593 }
592 AddLiteralCharAdvance(); 594 AddLiteralCharAdvance();
593 } 595 }
594 } 596 }
595 } 597 }
596 598
597 // Parse decimal digits and allow trailing fractional part. 599 // Parse decimal digits and allow trailing fractional part.
598 if (kind == DECIMAL) { 600 if (kind == DECIMAL) {
599 ScanDecimalDigits(); // optional 601 ScanDecimalDigits(); // optional
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
722 AddLiteralCharAdvance(); 724 AddLiteralCharAdvance();
723 if (unicode_cache_->IsLineTerminator(c0_) || c0_ < 0) return false; 725 if (unicode_cache_->IsLineTerminator(c0_) || c0_ < 0) return false;
724 AddLiteralCharAdvance(); 726 AddLiteralCharAdvance();
725 // If the escape allows more characters, i.e., \x??, \u????, or \c?, 727 // If the escape allows more characters, i.e., \x??, \u????, or \c?,
726 // only "safe" characters are allowed (letters, digits, underscore), 728 // only "safe" characters are allowed (letters, digits, underscore),
727 // otherwise the escape isn't valid and the invalid character has 729 // otherwise the escape isn't valid and the invalid character has
728 // its normal meaning. I.e., we can just continue scanning without 730 // its normal meaning. I.e., we can just continue scanning without
729 // worrying whether the following characters are part of the escape 731 // worrying whether the following characters are part of the escape
730 // or not, since any '/', '\\' or '[' is guaranteed to not be part 732 // or not, since any '/', '\\' or '[' is guaranteed to not be part
731 // of the escape sequence. 733 // of the escape sequence.
734
735 // TODO(896): At some point, parse RegExps more throughly to capture
736 // octal esacpes in strict mode.
732 } else { // Unescaped character. 737 } else { // Unescaped character.
733 if (c0_ == '[') in_character_class = true; 738 if (c0_ == '[') in_character_class = true;
734 if (c0_ == ']') in_character_class = false; 739 if (c0_ == ']') in_character_class = false;
735 AddLiteralCharAdvance(); 740 AddLiteralCharAdvance();
736 } 741 }
737 } 742 }
738 Advance(); // consume '/' 743 Advance(); // consume '/'
739 744
740 literal.Complete(); 745 literal.Complete();
741 746
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
937 if (MatchKeywordStart(input, "with", 1, Token::WITH)) return; 942 if (MatchKeywordStart(input, "with", 1, Token::WITH)) return;
938 break; 943 break;
939 case UNMATCHABLE: 944 case UNMATCHABLE:
940 break; 945 break;
941 } 946 }
942 // On fallthrough, it's a failure. 947 // On fallthrough, it's a failure.
943 state_ = UNMATCHABLE; 948 state_ = UNMATCHABLE;
944 } 949 }
945 950
946 } } // namespace v8::internal 951 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/scanner-base.h ('k') | test/preparser/non-use-strict-hex-escape.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698