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:
jwolfe 2016-05-16 16:20:29 -07:00 committed by Commit bot
parent 0d43421a22
commit 5582e158e5
7 changed files with 53 additions and 9 deletions

View File

@ -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.
}; };

View File

@ -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,

View File

@ -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);

View File

@ -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();

View File

@ -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();

View File

@ -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;
} }

View File

@ -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_;