In parallel to the strict octal check that would reject 012 in strict mode, this patch collects UseCounters for 089 in strict mode. The spec says this should be an error, but this patch does not report it as such.

BUG=v8:4973
LOG=y

Review-Url: https://codereview.chromium.org/1948403002
Cr-Commit-Position: refs/heads/master@{#36221}
This commit is contained in:
jwolfe 2016-05-12 13:51:48 -07:00 committed by Commit bot
parent 02b7373ab1
commit d0b6686c14
7 changed files with 54 additions and 9 deletions

View File

@ -5625,9 +5625,10 @@ class V8_EXPORT Isolate {
kLegacyFunctionDeclaration = 29,
kRegExpPrototypeSourceGetter = 30,
kRegExpPrototypeOldFlagGetter = 31,
kDecimalWithLeadingZeroInStrictMode = 32,
// If you add new values here, you'll also need to update V8Initializer.cpp
// in Chromium.
// If you add new values here, you'll also need to update Chromium's:
// UseCounter.h, V8PerIsolateData.cpp, histograms.xml
kUseCounterFeatureCount // This enum value must be last.
};

View File

@ -633,6 +633,18 @@ class ParserBase : public Traits {
*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) {
CheckOctalLiteral(beg_pos, end_pos, MessageTemplate::kStrictOctalLiteral,

View File

@ -943,6 +943,8 @@ FunctionLiteral* Parser::DoParseProgram(ParseInfo* info) {
if (ok && is_strict(language_mode())) {
CheckStrictOctalLiteral(beg_pos, scanner()->location().end_pos, &ok);
CheckDecimalLiteralWithLeadingZero(use_counts_, beg_pos,
scanner()->location().end_pos);
}
if (ok && is_sloppy(language_mode())) {
// TODO(littledan): Function bindings on the global object that modify
@ -4175,6 +4177,8 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
if (is_strict(language_mode)) {
CheckStrictOctalLiteral(scope->start_position(), scope->end_position(),
CHECK_OK);
CheckDecimalLiteralWithLeadingZero(use_counts_, scope->start_position(),
scope->end_position());
}
if (is_sloppy(language_mode)) {
InsertSloppyBlockFunctionVarBindings(scope, CHECK_OK);

View File

@ -134,6 +134,7 @@ PreParser::PreParseResult PreParser::PreParseLazyFunction(
if (is_strict(scope_->language_mode())) {
int end_pos = scanner()->location().end_pos;
CheckStrictOctalLiteral(start_position, end_pos, &ok);
CheckDecimalLiteralWithLeadingZero(use_counts, start_position, end_pos);
if (!ok) return kPreParseSuccess;
}
}
@ -1106,6 +1107,8 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
if (is_strict(language_mode)) {
int end_position = scanner()->location().end_pos;
CheckStrictOctalLiteral(start_position, end_position, CHECK_OK);
CheckDecimalLiteralWithLeadingZero(use_counts_, start_position,
end_position);
}
return Expression::Default();

View File

@ -1031,6 +1031,8 @@ class PreParser : public ParserBase<PreParserTraits> {
} else if (is_strict(scope_->language_mode())) {
CheckStrictOctalLiteral(start_position, scanner()->location().end_pos,
&ok);
CheckDecimalLiteralWithLeadingZero(use_counts_, start_position,
scanner()->location().end_pos);
}
if (materialized_literals) {
*materialized_literals = function_state_->materialized_literal_count();

View File

@ -40,6 +40,7 @@ Scanner::Scanner(UnicodeCache* unicode_cache)
: unicode_cache_(unicode_cache),
bookmark_c0_(kNoBookmark),
octal_pos_(Location::invalid()),
decimal_with_leading_zero_pos_(Location::invalid()),
found_html_comment_(false),
allow_harmony_exponentiation_operator_(false) {
bookmark_current_.literal_chars = &bookmark_current_literal_;
@ -975,10 +976,18 @@ void Scanner::ScanDecimalDigits() {
Token::Value Scanner::ScanNumber(bool seen_period) {
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);
bool at_start = !seen_period;
int start_pos; // For reporting octal positions.
if (seen_period) {
// we have already seen a decimal point of the float
AddLiteralChar('.');
@ -987,7 +996,7 @@ Token::Value Scanner::ScanNumber(bool seen_period) {
} else {
// if the first character is '0' we must check for octals and hex
if (c0_ == '0') {
int start_pos = source_pos(); // For reporting octal positions.
start_pos = source_pos();
AddLiteralCharAdvance();
// either 0, 0exxx, 0Exxx, 0.xxx, a hex number, a binary number or
@ -1029,7 +1038,7 @@ Token::Value Scanner::ScanNumber(bool seen_period) {
while (true) {
if (c0_ == '8' || c0_ == '9') {
at_start = false;
kind = DECIMAL;
kind = DECIMAL_WITH_LEADING_ZERO;
break;
}
if (c0_ < '0' || '7' < c0_) {
@ -1039,11 +1048,13 @@ Token::Value Scanner::ScanNumber(bool seen_period) {
}
AddLiteralCharAdvance();
}
} else if (c0_ == '8' || c0_ == '9') {
kind = DECIMAL_WITH_LEADING_ZERO;
}
}
// Parse decimal digits and allow trailing fractional part.
if (kind == DECIMAL) {
if (kind == DECIMAL || kind == DECIMAL_WITH_LEADING_ZERO) {
if (at_start) {
uint64_t value = 0;
while (IsDecimalDigit(c0_)) {
@ -1060,6 +1071,8 @@ Token::Value Scanner::ScanNumber(bool seen_period) {
literal.Complete();
HandleLeadSurrogate();
if (kind == DECIMAL_WITH_LEADING_ZERO)
decimal_with_leading_zero_pos_ = Location(start_pos, source_pos());
return Token::SMI;
}
HandleLeadSurrogate();
@ -1076,7 +1089,8 @@ Token::Value Scanner::ScanNumber(bool seen_period) {
// scan exponent, if any
if (c0_ == 'e' || c0_ == 'E') {
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
AddLiteralCharAdvance();
if (c0_ == '+' || c0_ == '-')
@ -1098,6 +1112,8 @@ Token::Value Scanner::ScanNumber(bool seen_period) {
literal.Complete();
if (kind == DECIMAL_WITH_LEADING_ZERO)
decimal_with_leading_zero_pos_ = Location(start_pos, source_pos());
return Token::NUMBER;
}

View File

@ -425,6 +425,13 @@ class Scanner {
// Returns the location of the last seen octal literal.
Location octal_position() const { return octal_pos_; }
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.
int smi_value() const { return current_.smi_value_; }
@ -772,9 +779,9 @@ class Scanner {
// Input stream. Must be initialized to an Utf16CharacterStream.
Utf16CharacterStream* source_;
// Start position of the octal literal last scanned.
// Last-seen positions of potentially problematic tokens.
Location octal_pos_;
Location decimal_with_leading_zero_pos_;
// One Unicode character look-ahead; c0_ < 0 at the end of the input.
uc32 c0_;