Add UseCounter for decimal with leading zero.
Re-landing https://codereview.chromium.org/1948403002/ New changes: move variable initialization to make compiler happy BUG=v8:4973 LOG=y Review-Url: https://codereview.chromium.org/1969203004 Cr-Commit-Position: refs/heads/master@{#36262}
This commit is contained in:
parent
0d43421a22
commit
5582e158e5
@ -5635,9 +5635,10 @@ class V8_EXPORT Isolate {
|
|||||||
kLegacyFunctionDeclaration = 29,
|
kLegacyFunctionDeclaration = 29,
|
||||||
kRegExpPrototypeSourceGetter = 30,
|
kRegExpPrototypeSourceGetter = 30,
|
||||||
kRegExpPrototypeOldFlagGetter = 31,
|
kRegExpPrototypeOldFlagGetter = 31,
|
||||||
|
kDecimalWithLeadingZeroInStrictMode = 32,
|
||||||
|
|
||||||
// If you add new values here, you'll also need to update V8Initializer.cpp
|
// If you add new values here, you'll also need to update Chromium's:
|
||||||
// in Chromium.
|
// UseCounter.h, V8PerIsolateData.cpp, histograms.xml
|
||||||
kUseCounterFeatureCount // This enum value must be last.
|
kUseCounterFeatureCount // This enum value must be last.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -718,6 +718,18 @@ class ParserBase : public Traits {
|
|||||||
*ok = false;
|
*ok = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// for now, this check just collects statistics.
|
||||||
|
void CheckDecimalLiteralWithLeadingZero(int* use_counts, int beg_pos,
|
||||||
|
int end_pos) {
|
||||||
|
Scanner::Location token_location =
|
||||||
|
scanner()->decimal_with_leading_zero_position();
|
||||||
|
if (token_location.IsValid() && beg_pos <= token_location.beg_pos &&
|
||||||
|
token_location.end_pos <= end_pos) {
|
||||||
|
scanner()->clear_decimal_with_leading_zero_position();
|
||||||
|
if (use_counts != nullptr)
|
||||||
|
++use_counts[v8::Isolate::kDecimalWithLeadingZeroInStrictMode];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
inline void CheckStrictOctalLiteral(int beg_pos, int end_pos, bool* ok) {
|
inline void CheckStrictOctalLiteral(int beg_pos, int end_pos, bool* ok) {
|
||||||
CheckOctalLiteral(beg_pos, end_pos, MessageTemplate::kStrictOctalLiteral,
|
CheckOctalLiteral(beg_pos, end_pos, MessageTemplate::kStrictOctalLiteral,
|
||||||
|
@ -949,6 +949,8 @@ FunctionLiteral* Parser::DoParseProgram(ParseInfo* info) {
|
|||||||
|
|
||||||
if (ok && is_strict(language_mode())) {
|
if (ok && is_strict(language_mode())) {
|
||||||
CheckStrictOctalLiteral(beg_pos, scanner()->location().end_pos, &ok);
|
CheckStrictOctalLiteral(beg_pos, scanner()->location().end_pos, &ok);
|
||||||
|
CheckDecimalLiteralWithLeadingZero(use_counts_, beg_pos,
|
||||||
|
scanner()->location().end_pos);
|
||||||
}
|
}
|
||||||
if (ok && is_sloppy(language_mode())) {
|
if (ok && is_sloppy(language_mode())) {
|
||||||
// TODO(littledan): Function bindings on the global object that modify
|
// TODO(littledan): Function bindings on the global object that modify
|
||||||
@ -4261,6 +4263,8 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
|
|||||||
if (is_strict(language_mode)) {
|
if (is_strict(language_mode)) {
|
||||||
CheckStrictOctalLiteral(scope->start_position(), scope->end_position(),
|
CheckStrictOctalLiteral(scope->start_position(), scope->end_position(),
|
||||||
CHECK_OK);
|
CHECK_OK);
|
||||||
|
CheckDecimalLiteralWithLeadingZero(use_counts_, scope->start_position(),
|
||||||
|
scope->end_position());
|
||||||
}
|
}
|
||||||
if (is_sloppy(language_mode)) {
|
if (is_sloppy(language_mode)) {
|
||||||
InsertSloppyBlockFunctionVarBindings(scope, CHECK_OK);
|
InsertSloppyBlockFunctionVarBindings(scope, CHECK_OK);
|
||||||
|
@ -136,6 +136,7 @@ PreParser::PreParseResult PreParser::PreParseLazyFunction(
|
|||||||
if (is_strict(scope_->language_mode())) {
|
if (is_strict(scope_->language_mode())) {
|
||||||
int end_pos = scanner()->location().end_pos;
|
int end_pos = scanner()->location().end_pos;
|
||||||
CheckStrictOctalLiteral(start_position, end_pos, &ok);
|
CheckStrictOctalLiteral(start_position, end_pos, &ok);
|
||||||
|
CheckDecimalLiteralWithLeadingZero(use_counts, start_position, end_pos);
|
||||||
if (!ok) return kPreParseSuccess;
|
if (!ok) return kPreParseSuccess;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1143,6 +1144,8 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
|
|||||||
if (is_strict(language_mode)) {
|
if (is_strict(language_mode)) {
|
||||||
int end_position = scanner()->location().end_pos;
|
int end_position = scanner()->location().end_pos;
|
||||||
CheckStrictOctalLiteral(start_position, end_position, CHECK_OK);
|
CheckStrictOctalLiteral(start_position, end_position, CHECK_OK);
|
||||||
|
CheckDecimalLiteralWithLeadingZero(use_counts_, start_position,
|
||||||
|
end_position);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Expression::Default();
|
return Expression::Default();
|
||||||
|
@ -1054,6 +1054,8 @@ class PreParser : public ParserBase<PreParserTraits> {
|
|||||||
} else if (is_strict(scope_->language_mode())) {
|
} else if (is_strict(scope_->language_mode())) {
|
||||||
CheckStrictOctalLiteral(start_position, scanner()->location().end_pos,
|
CheckStrictOctalLiteral(start_position, scanner()->location().end_pos,
|
||||||
&ok);
|
&ok);
|
||||||
|
CheckDecimalLiteralWithLeadingZero(use_counts_, start_position,
|
||||||
|
scanner()->location().end_pos);
|
||||||
}
|
}
|
||||||
if (materialized_literals) {
|
if (materialized_literals) {
|
||||||
*materialized_literals = function_state_->materialized_literal_count();
|
*materialized_literals = function_state_->materialized_literal_count();
|
||||||
|
@ -40,6 +40,7 @@ Scanner::Scanner(UnicodeCache* unicode_cache)
|
|||||||
: unicode_cache_(unicode_cache),
|
: unicode_cache_(unicode_cache),
|
||||||
bookmark_c0_(kNoBookmark),
|
bookmark_c0_(kNoBookmark),
|
||||||
octal_pos_(Location::invalid()),
|
octal_pos_(Location::invalid()),
|
||||||
|
decimal_with_leading_zero_pos_(Location::invalid()),
|
||||||
found_html_comment_(false),
|
found_html_comment_(false),
|
||||||
allow_harmony_exponentiation_operator_(false) {
|
allow_harmony_exponentiation_operator_(false) {
|
||||||
bookmark_current_.literal_chars = &bookmark_current_literal_;
|
bookmark_current_.literal_chars = &bookmark_current_literal_;
|
||||||
@ -981,10 +982,18 @@ void Scanner::ScanDecimalDigits() {
|
|||||||
Token::Value Scanner::ScanNumber(bool seen_period) {
|
Token::Value Scanner::ScanNumber(bool seen_period) {
|
||||||
DCHECK(IsDecimalDigit(c0_)); // the first digit of the number or the fraction
|
DCHECK(IsDecimalDigit(c0_)); // the first digit of the number or the fraction
|
||||||
|
|
||||||
enum { DECIMAL, HEX, OCTAL, IMPLICIT_OCTAL, BINARY } kind = DECIMAL;
|
enum {
|
||||||
|
DECIMAL,
|
||||||
|
DECIMAL_WITH_LEADING_ZERO,
|
||||||
|
HEX,
|
||||||
|
OCTAL,
|
||||||
|
IMPLICIT_OCTAL,
|
||||||
|
BINARY
|
||||||
|
} kind = DECIMAL;
|
||||||
|
|
||||||
LiteralScope literal(this);
|
LiteralScope literal(this);
|
||||||
bool at_start = !seen_period;
|
bool at_start = !seen_period;
|
||||||
|
int start_pos = source_pos(); // For reporting octal positions.
|
||||||
if (seen_period) {
|
if (seen_period) {
|
||||||
// we have already seen a decimal point of the float
|
// we have already seen a decimal point of the float
|
||||||
AddLiteralChar('.');
|
AddLiteralChar('.');
|
||||||
@ -993,7 +1002,6 @@ Token::Value Scanner::ScanNumber(bool seen_period) {
|
|||||||
} else {
|
} else {
|
||||||
// if the first character is '0' we must check for octals and hex
|
// if the first character is '0' we must check for octals and hex
|
||||||
if (c0_ == '0') {
|
if (c0_ == '0') {
|
||||||
int start_pos = source_pos(); // For reporting octal positions.
|
|
||||||
AddLiteralCharAdvance();
|
AddLiteralCharAdvance();
|
||||||
|
|
||||||
// either 0, 0exxx, 0Exxx, 0.xxx, a hex number, a binary number or
|
// either 0, 0exxx, 0Exxx, 0.xxx, a hex number, a binary number or
|
||||||
@ -1035,7 +1043,7 @@ Token::Value Scanner::ScanNumber(bool seen_period) {
|
|||||||
while (true) {
|
while (true) {
|
||||||
if (c0_ == '8' || c0_ == '9') {
|
if (c0_ == '8' || c0_ == '9') {
|
||||||
at_start = false;
|
at_start = false;
|
||||||
kind = DECIMAL;
|
kind = DECIMAL_WITH_LEADING_ZERO;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (c0_ < '0' || '7' < c0_) {
|
if (c0_ < '0' || '7' < c0_) {
|
||||||
@ -1045,11 +1053,13 @@ Token::Value Scanner::ScanNumber(bool seen_period) {
|
|||||||
}
|
}
|
||||||
AddLiteralCharAdvance();
|
AddLiteralCharAdvance();
|
||||||
}
|
}
|
||||||
|
} else if (c0_ == '8' || c0_ == '9') {
|
||||||
|
kind = DECIMAL_WITH_LEADING_ZERO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse decimal digits and allow trailing fractional part.
|
// Parse decimal digits and allow trailing fractional part.
|
||||||
if (kind == DECIMAL) {
|
if (kind == DECIMAL || kind == DECIMAL_WITH_LEADING_ZERO) {
|
||||||
if (at_start) {
|
if (at_start) {
|
||||||
uint64_t value = 0;
|
uint64_t value = 0;
|
||||||
while (IsDecimalDigit(c0_)) {
|
while (IsDecimalDigit(c0_)) {
|
||||||
@ -1066,6 +1076,8 @@ Token::Value Scanner::ScanNumber(bool seen_period) {
|
|||||||
literal.Complete();
|
literal.Complete();
|
||||||
HandleLeadSurrogate();
|
HandleLeadSurrogate();
|
||||||
|
|
||||||
|
if (kind == DECIMAL_WITH_LEADING_ZERO)
|
||||||
|
decimal_with_leading_zero_pos_ = Location(start_pos, source_pos());
|
||||||
return Token::SMI;
|
return Token::SMI;
|
||||||
}
|
}
|
||||||
HandleLeadSurrogate();
|
HandleLeadSurrogate();
|
||||||
@ -1082,7 +1094,8 @@ Token::Value Scanner::ScanNumber(bool seen_period) {
|
|||||||
// scan exponent, if any
|
// scan exponent, if any
|
||||||
if (c0_ == 'e' || c0_ == 'E') {
|
if (c0_ == 'e' || c0_ == 'E') {
|
||||||
DCHECK(kind != HEX); // 'e'/'E' must be scanned as part of the hex number
|
DCHECK(kind != HEX); // 'e'/'E' must be scanned as part of the hex number
|
||||||
if (kind != DECIMAL) return Token::ILLEGAL;
|
if (!(kind == DECIMAL || kind == DECIMAL_WITH_LEADING_ZERO))
|
||||||
|
return Token::ILLEGAL;
|
||||||
// scan exponent
|
// scan exponent
|
||||||
AddLiteralCharAdvance();
|
AddLiteralCharAdvance();
|
||||||
if (c0_ == '+' || c0_ == '-')
|
if (c0_ == '+' || c0_ == '-')
|
||||||
@ -1104,6 +1117,8 @@ Token::Value Scanner::ScanNumber(bool seen_period) {
|
|||||||
|
|
||||||
literal.Complete();
|
literal.Complete();
|
||||||
|
|
||||||
|
if (kind == DECIMAL_WITH_LEADING_ZERO)
|
||||||
|
decimal_with_leading_zero_pos_ = Location(start_pos, source_pos());
|
||||||
return Token::NUMBER;
|
return Token::NUMBER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -425,6 +425,13 @@ class Scanner {
|
|||||||
// Returns the location of the last seen octal literal.
|
// Returns the location of the last seen octal literal.
|
||||||
Location octal_position() const { return octal_pos_; }
|
Location octal_position() const { return octal_pos_; }
|
||||||
void clear_octal_position() { octal_pos_ = Location::invalid(); }
|
void clear_octal_position() { octal_pos_ = Location::invalid(); }
|
||||||
|
// Returns the location of the last seen decimal literal with a leading zero.
|
||||||
|
Location decimal_with_leading_zero_position() const {
|
||||||
|
return decimal_with_leading_zero_pos_;
|
||||||
|
}
|
||||||
|
void clear_decimal_with_leading_zero_position() {
|
||||||
|
decimal_with_leading_zero_pos_ = Location::invalid();
|
||||||
|
}
|
||||||
|
|
||||||
// Returns the value of the last smi that was scanned.
|
// Returns the value of the last smi that was scanned.
|
||||||
int smi_value() const { return current_.smi_value_; }
|
int smi_value() const { return current_.smi_value_; }
|
||||||
@ -778,9 +785,9 @@ class Scanner {
|
|||||||
// Input stream. Must be initialized to an Utf16CharacterStream.
|
// Input stream. Must be initialized to an Utf16CharacterStream.
|
||||||
Utf16CharacterStream* source_;
|
Utf16CharacterStream* source_;
|
||||||
|
|
||||||
|
// Last-seen positions of potentially problematic tokens.
|
||||||
// Start position of the octal literal last scanned.
|
|
||||||
Location octal_pos_;
|
Location octal_pos_;
|
||||||
|
Location decimal_with_leading_zero_pos_;
|
||||||
|
|
||||||
// One Unicode character look-ahead; c0_ < 0 at the end of the input.
|
// One Unicode character look-ahead; c0_ < 0 at the end of the input.
|
||||||
uc32 c0_;
|
uc32 c0_;
|
||||||
|
Loading…
Reference in New Issue
Block a user