Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Features shared by parsing and pre-parsing scanners. | 5 // Features shared by parsing and pre-parsing scanners. |
| 6 | 6 |
| 7 #include "src/parsing/scanner.h" | 7 #include "src/parsing/scanner.h" |
| 8 | 8 |
| 9 #include <stdint.h> | 9 #include <stdint.h> |
| 10 | 10 |
| (...skipping 958 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 969 void Scanner::ScanDecimalDigits() { | 969 void Scanner::ScanDecimalDigits() { |
| 970 while (IsDecimalDigit(c0_)) | 970 while (IsDecimalDigit(c0_)) |
| 971 AddLiteralCharAdvance(); | 971 AddLiteralCharAdvance(); |
| 972 } | 972 } |
| 973 | 973 |
| 974 | 974 |
| 975 Token::Value Scanner::ScanNumber(bool seen_period) { | 975 Token::Value Scanner::ScanNumber(bool seen_period) { |
| 976 DCHECK(IsDecimalDigit(c0_)); // the first digit of the number or the fraction | 976 DCHECK(IsDecimalDigit(c0_)); // the first digit of the number or the fraction |
| 977 | 977 |
| 978 enum { DECIMAL, HEX, OCTAL, IMPLICIT_OCTAL, BINARY } kind = DECIMAL; | 978 enum { DECIMAL, HEX, OCTAL, IMPLICIT_OCTAL, BINARY } kind = DECIMAL; |
| 979 bool decimal_that_looks_like_octal = false; | |
| 979 | 980 |
| 980 LiteralScope literal(this); | 981 LiteralScope literal(this); |
| 981 bool at_start = !seen_period; | 982 bool at_start = !seen_period; |
| 983 int start_pos = source_pos(); // For reporting octal positions. | |
| 982 if (seen_period) { | 984 if (seen_period) { |
| 983 // we have already seen a decimal point of the float | 985 // we have already seen a decimal point of the float |
| 984 AddLiteralChar('.'); | 986 AddLiteralChar('.'); |
| 985 ScanDecimalDigits(); // we know we have at least one digit | 987 ScanDecimalDigits(); // we know we have at least one digit |
| 986 | 988 |
| 987 } else { | 989 } else { |
| 988 // if the first character is '0' we must check for octals and hex | 990 // if the first character is '0' we must check for octals and hex |
| 989 if (c0_ == '0') { | 991 if (c0_ == '0') { |
| 990 int start_pos = source_pos(); // For reporting octal positions. | |
|
caitp (gmail)
2016/05/05 18:25:02
This change seems not to be needed, since it's irr
jwolfe
2016/05/05 18:42:02
I can leave the local variable uninitialized until
| |
| 991 AddLiteralCharAdvance(); | 992 AddLiteralCharAdvance(); |
| 992 | 993 |
| 993 // either 0, 0exxx, 0Exxx, 0.xxx, a hex number, a binary number or | 994 // either 0, 0exxx, 0Exxx, 0.xxx, a hex number, a binary number or |
| 994 // an octal number. | 995 // an octal number. |
| 995 if (c0_ == 'x' || c0_ == 'X') { | 996 if (c0_ == 'x' || c0_ == 'X') { |
| 996 // hex number | 997 // hex number |
| 997 kind = HEX; | 998 kind = HEX; |
| 998 AddLiteralCharAdvance(); | 999 AddLiteralCharAdvance(); |
| 999 if (!IsHexDigit(c0_)) { | 1000 if (!IsHexDigit(c0_)) { |
| 1000 // we must have at least one hex digit after 'x'/'X' | 1001 // we must have at least one hex digit after 'x'/'X' |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 1023 while (IsBinaryDigit(c0_)) { | 1024 while (IsBinaryDigit(c0_)) { |
| 1024 AddLiteralCharAdvance(); | 1025 AddLiteralCharAdvance(); |
| 1025 } | 1026 } |
| 1026 } else if ('0' <= c0_ && c0_ <= '7') { | 1027 } else if ('0' <= c0_ && c0_ <= '7') { |
| 1027 // (possible) octal number | 1028 // (possible) octal number |
| 1028 kind = IMPLICIT_OCTAL; | 1029 kind = IMPLICIT_OCTAL; |
| 1029 while (true) { | 1030 while (true) { |
| 1030 if (c0_ == '8' || c0_ == '9') { | 1031 if (c0_ == '8' || c0_ == '9') { |
| 1031 at_start = false; | 1032 at_start = false; |
| 1032 kind = DECIMAL; | 1033 kind = DECIMAL; |
| 1034 decimal_that_looks_like_octal = true; | |
|
caitp (gmail)
2016/05/05 18:21:08
'8' and '9' are decidedly not octal digits --- why
| |
| 1033 break; | 1035 break; |
| 1034 } | 1036 } |
| 1035 if (c0_ < '0' || '7' < c0_) { | 1037 if (c0_ < '0' || '7' < c0_) { |
| 1036 // Octal literal finished. | 1038 // Octal literal finished. |
| 1037 octal_pos_ = Location(start_pos, source_pos()); | 1039 octal_pos_ = Location(start_pos, source_pos()); |
| 1038 break; | 1040 break; |
| 1039 } | 1041 } |
| 1040 AddLiteralCharAdvance(); | 1042 AddLiteralCharAdvance(); |
| 1041 } | 1043 } |
| 1044 } else if (c0_ == '8' || c0_ == '9') { | |
| 1045 decimal_that_looks_like_octal = true; | |
| 1042 } | 1046 } |
| 1043 } | 1047 } |
| 1044 | 1048 |
| 1045 // Parse decimal digits and allow trailing fractional part. | 1049 // Parse decimal digits and allow trailing fractional part. |
| 1046 if (kind == DECIMAL) { | 1050 if (kind == DECIMAL) { |
| 1047 if (at_start) { | 1051 if (at_start) { |
| 1048 uint64_t value = 0; | 1052 uint64_t value = 0; |
| 1049 while (IsDecimalDigit(c0_)) { | 1053 while (IsDecimalDigit(c0_)) { |
| 1050 value = 10 * value + (c0_ - '0'); | 1054 value = 10 * value + (c0_ - '0'); |
| 1051 | 1055 |
| 1052 uc32 first_char = c0_; | 1056 uc32 first_char = c0_; |
| 1053 Advance<false, false>(); | 1057 Advance<false, false>(); |
| 1054 AddLiteralChar(first_char); | 1058 AddLiteralChar(first_char); |
| 1055 } | 1059 } |
| 1056 | 1060 |
| 1057 if (next_.literal_chars->one_byte_literal().length() <= 10 && | 1061 if (next_.literal_chars->one_byte_literal().length() <= 10 && |
| 1058 value <= Smi::kMaxValue && c0_ != '.' && c0_ != 'e' && c0_ != 'E') { | 1062 value <= Smi::kMaxValue && c0_ != '.' && c0_ != 'e' && c0_ != 'E') { |
| 1059 next_.smi_value_ = static_cast<int>(value); | 1063 next_.smi_value_ = static_cast<int>(value); |
| 1060 literal.Complete(); | 1064 literal.Complete(); |
| 1061 HandleLeadSurrogate(); | 1065 HandleLeadSurrogate(); |
| 1062 | 1066 |
| 1067 if (decimal_that_looks_like_octal) | |
|
caitp (gmail)
2016/05/05 18:25:02
`decimal_that_looks_like_octal` is always false un
jwolfe
2016/05/05 18:42:01
I was surprised by needing two different checks in
| |
| 1068 octal_pos_ = Location(start_pos, source_pos()); | |
| 1063 return Token::SMI; | 1069 return Token::SMI; |
| 1064 } | 1070 } |
| 1065 HandleLeadSurrogate(); | 1071 HandleLeadSurrogate(); |
| 1066 } | 1072 } |
| 1067 | 1073 |
| 1068 ScanDecimalDigits(); // optional | 1074 ScanDecimalDigits(); // optional |
| 1069 if (c0_ == '.') { | 1075 if (c0_ == '.') { |
| 1070 AddLiteralCharAdvance(); | 1076 AddLiteralCharAdvance(); |
| 1071 ScanDecimalDigits(); // optional | 1077 ScanDecimalDigits(); // optional |
| 1072 } | 1078 } |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 1091 // The source character immediately following a numeric literal must | 1097 // The source character immediately following a numeric literal must |
| 1092 // not be an identifier start or a decimal digit; see ECMA-262 | 1098 // not be an identifier start or a decimal digit; see ECMA-262 |
| 1093 // section 7.8.3, page 17 (note that we read only one decimal digit | 1099 // section 7.8.3, page 17 (note that we read only one decimal digit |
| 1094 // if the value is 0). | 1100 // if the value is 0). |
| 1095 if (IsDecimalDigit(c0_) || | 1101 if (IsDecimalDigit(c0_) || |
| 1096 (c0_ >= 0 && unicode_cache_->IsIdentifierStart(c0_))) | 1102 (c0_ >= 0 && unicode_cache_->IsIdentifierStart(c0_))) |
| 1097 return Token::ILLEGAL; | 1103 return Token::ILLEGAL; |
| 1098 | 1104 |
| 1099 literal.Complete(); | 1105 literal.Complete(); |
| 1100 | 1106 |
| 1107 if (decimal_that_looks_like_octal) | |
| 1108 octal_pos_ = Location(start_pos, source_pos()); | |
|
caitp (gmail)
2016/05/06 21:08:03
So, if we want to have a different error message f
| |
| 1101 return Token::NUMBER; | 1109 return Token::NUMBER; |
| 1102 } | 1110 } |
| 1103 | 1111 |
| 1104 | 1112 |
| 1105 uc32 Scanner::ScanIdentifierUnicodeEscape() { | 1113 uc32 Scanner::ScanIdentifierUnicodeEscape() { |
| 1106 Advance(); | 1114 Advance(); |
| 1107 if (c0_ != 'u') return -1; | 1115 if (c0_ != 'u') return -1; |
| 1108 Advance(); | 1116 Advance(); |
| 1109 return ScanUnicodeEscape<false>(); | 1117 return ScanUnicodeEscape<false>(); |
| 1110 } | 1118 } |
| (...skipping 576 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1687 backing_store_.Add(static_cast<uint8_t>((one_byte_length >> 7) | 0x80u)); | 1695 backing_store_.Add(static_cast<uint8_t>((one_byte_length >> 7) | 0x80u)); |
| 1688 } | 1696 } |
| 1689 backing_store_.Add(static_cast<uint8_t>(one_byte_length & 0x7f)); | 1697 backing_store_.Add(static_cast<uint8_t>(one_byte_length & 0x7f)); |
| 1690 | 1698 |
| 1691 backing_store_.AddBlock(bytes); | 1699 backing_store_.AddBlock(bytes); |
| 1692 return backing_store_.EndSequence().start(); | 1700 return backing_store_.EndSequence().start(); |
| 1693 } | 1701 } |
| 1694 | 1702 |
| 1695 } // namespace internal | 1703 } // namespace internal |
| 1696 } // namespace v8 | 1704 } // namespace v8 |
| OLD | NEW |