Strict mode octal literals.

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6446 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
mmaly@chromium.org 2011-01-24 18:13:18 +00:00
parent e01336c3dc
commit 8d79f3a788
6 changed files with 52 additions and 3 deletions

View File

@ -216,6 +216,7 @@ function FormatMessage(message) {
strict_param_dupe: "Strict mode function may not have duplicate parameter names",
strict_var_name: "Variable name may not be eval or arguments in strict mode",
strict_function_name: "Function name may not be eval or arguments in strict mode",
strict_octal_literal: "Octal literals are not allowed in strict mode.",
};
}
var format = kMessages[message.type];

View File

@ -664,7 +664,11 @@ FunctionLiteral* Parser::DoParseProgram(Handle<String> source,
TemporaryScope temp_scope(&this->temp_scope_);
ZoneList<Statement*>* body = new ZoneList<Statement*>(16);
bool ok = true;
int beg_loc = scanner().location().beg_pos;
ParseSourceElements(body, Token::EOS, &ok);
if (ok && temp_scope_->StrictMode()) {
CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok);
}
if (ok) {
result = new FunctionLiteral(
no_name,
@ -3384,7 +3388,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
*ok = false;
return NULL;
}
// TODO(mmaly): Check for octal escape sequence here.
CheckOctalLiteral(start_pos, end_pos, CHECK_OK);
}
FunctionLiteral* function_literal =
@ -3530,6 +3534,18 @@ Handle<String> Parser::ParseIdentifierName(bool* ok) {
return GetSymbol(ok);
}
// Checks whether octal literal last seen is between beg_pos and end_pos.
// If so, reports an error.
void Parser::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) {
int octal = scanner().octal_position();
if (beg_pos <= octal && octal <= end_pos) {
ReportMessageAt(Scanner::Location(octal, octal + 1), "strict_octal_literal",
Vector<const char*>::empty());
scanner().clear_octal_position();
*ok = false;
}
}
// This function reads an identifier and determines whether or not it
// is 'get' or 'set'. The reason for not using ParseIdentifier and

View File

@ -613,6 +613,9 @@ class Parser {
bool* is_set,
bool* ok);
// Strict mode octal literal validation.
void CheckOctalLiteral(int beg_pos, int end_pos, bool* ok);
// Parser support
VariableProxy* Declare(Handle<String> name, Variable::Mode mode,
FunctionLiteral* fun,

View File

@ -64,7 +64,8 @@ bool ScannerConstants::IsIdentifier(unibrow::CharacterStream* buffer) {
// ----------------------------------------------------------------------------
// Scanner
Scanner::Scanner() { }
Scanner::Scanner()
: octal_pos_(kNoOctalLocation) { }
uc32 Scanner::ScanHexEscape(uc32 c, int length) {
@ -98,6 +99,7 @@ uc32 Scanner::ScanHexEscape(uc32 c, int length) {
// Octal escapes of the forms '\0xx' and '\xxx' are not a part of
// ECMA-262. Other JS VMs support them.
uc32 Scanner::ScanOctalEscape(uc32 c, int length) {
octal_pos_ = source_pos() - 1; // Already advanced
uc32 x = c - '0';
for (int i = 0; i < length; i++) {
int d = c0_ - '0';
@ -601,7 +603,11 @@ Token::Value JavaScriptScanner::ScanNumber(bool seen_period) {
kind = DECIMAL;
break;
}
if (c0_ < '0' || '7' < c0_) break;
if (c0_ < '0' || '7' < c0_) {
// Octal literal finished.
octal_pos_ = next_.location.beg_pos;
break;
}
AddLiteralCharAdvance();
}
}

View File

@ -247,6 +247,9 @@ class LiteralBuffer {
// Generic functionality used by both JSON and JavaScript scanners.
class Scanner {
public:
// -1 is outside of the range of any real source code.
static const int kNoOctalLocation = -1;
typedef unibrow::Utf8InputBuffer<1024> Utf8Decoder;
class LiteralScope {
@ -280,6 +283,10 @@ class Scanner {
Location location() const { return current_.location; }
Location peek_location() const { return next_.location; }
// Returns the location of the last seen octal literal
int octal_position() const { return octal_pos_; }
void clear_octal_position() { octal_pos_ = -1; }
// Returns the literal string, if any, for the current token (the
// token returned by Next()). The string is 0-terminated and in
// UTF-8 format; they may contain 0-characters. Literal strings are
@ -410,6 +417,8 @@ class Scanner {
// Input stream. Must be initialized to an UC16CharacterStream.
UC16CharacterStream* source_;
// Start position of the octal literal last scanned.
int octal_pos_;
// One Unicode character look-ahead; c0_ < 0 at the end of the input.
uc32 c0_;

View File

@ -115,3 +115,17 @@ function NotStrict(eval) {
}
with ({}) {};
}
// Octal literal
CheckStrictMode("var x = 012");
CheckStrictMode("012");
CheckStrictMode("'Hello octal\\032'");
CheckStrictMode("function octal() { return 012; }");
CheckStrictMode("function octal() { return '\\032'; }");
// Octal before "use strict"
assertThrows('\
function strict() {\
"octal\\032directive";\
"use strict";\
}', SyntaxError);