Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(216)

Unified Diff: src/parser.cc

Issue 6246064: Issue 117 - strict mode and future reserved words (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Address code review comments Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/parser.h ('k') | src/preparser.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/parser.cc
diff --git a/src/parser.cc b/src/parser.cc
index fb65b61cefaa2265dd961de77869196172937f19..e495017b5b3204811d6b4fcf714b9781ca4b3867 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -759,7 +759,9 @@ FunctionLiteral* Parser::ParseLazy(Handle<SharedFunctionInfo> info,
FunctionLiteralType type =
info->is_expression() ? EXPRESSION : DECLARATION;
bool ok = true;
- result = ParseFunctionLiteral(name, RelocInfo::kNoPosition, type, &ok);
+ result = ParseFunctionLiteral(name,
+ false, // Strict mode name already checked.
+ RelocInfo::kNoPosition, type, &ok);
// Make sure the results agree.
ASSERT(ok == (result != NULL));
// The only errors should be stack overflows.
@@ -1448,8 +1450,10 @@ Statement* Parser::ParseFunctionDeclaration(bool* ok) {
// 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
Expect(Token::FUNCTION, CHECK_OK);
int function_token_position = scanner().location().beg_pos;
- Handle<String> name = ParseIdentifier(CHECK_OK);
+ bool is_reserved = false;
+ Handle<String> name = ParseIdentifierOrReservedWord(&is_reserved, CHECK_OK);
FunctionLiteral* fun = ParseFunctionLiteral(name,
+ is_reserved,
function_token_position,
DECLARATION,
CHECK_OK);
@@ -1708,7 +1712,7 @@ Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels,
// ExpressionStatement | LabelledStatement ::
// Expression ';'
// Identifier ':' Statement
- bool starts_with_idenfifier = (peek() == Token::IDENTIFIER);
+ bool starts_with_idenfifier = peek_any_identifier();
Expression* expr = ParseExpression(true, CHECK_OK);
if (peek() == Token::COLON && starts_with_idenfifier && expr &&
expr->AsVariableProxy() != NULL &&
@@ -2697,9 +2701,12 @@ Expression* Parser::ParseMemberWithNewPrefixesExpression(PositionStack* stack,
Expect(Token::FUNCTION, CHECK_OK);
int function_token_position = scanner().location().beg_pos;
Handle<String> name;
- if (peek() == Token::IDENTIFIER) name = ParseIdentifier(CHECK_OK);
- result = ParseFunctionLiteral(name, function_token_position,
- NESTED, CHECK_OK);
+ bool is_reserved_name = false;
+ if (peek_any_identifier()) {
+ name = ParseIdentifierOrReservedWord(&is_reserved_name, CHECK_OK);
+ }
+ result = ParseFunctionLiteral(name, is_reserved_name,
+ function_token_position, NESTED, CHECK_OK);
} else {
result = ParsePrimaryExpression(CHECK_OK);
}
@@ -2768,6 +2775,11 @@ void Parser::ReportUnexpectedToken(Token::Value token) {
case Token::IDENTIFIER:
return ReportMessage("unexpected_token_identifier",
Vector<const char*>::empty());
+ case Token::FUTURE_RESERVED_WORD:
+ return ReportMessage(temp_scope_->StrictMode() ?
+ "unexpected_strict_reserved" :
+ "unexpected_token_identifier",
+ Vector<const char*>::empty());
default:
const char* name = Token::String(token);
ASSERT(name != NULL);
@@ -2823,7 +2835,8 @@ Expression* Parser::ParsePrimaryExpression(bool* ok) {
result = new Literal(Factory::false_value());
break;
- case Token::IDENTIFIER: {
+ case Token::IDENTIFIER:
+ case Token::FUTURE_RESERVED_WORD: {
Handle<String> name = ParseIdentifier(CHECK_OK);
if (fni_ != NULL) fni_->PushVariableName(name);
result = top_scope_->NewUnresolved(name, inside_with());
@@ -3230,6 +3243,7 @@ ObjectLiteral::Property* Parser::ParseObjectLiteralGetSet(bool is_getter,
Token::Value next = Next();
bool is_keyword = Token::IsKeyword(next);
if (next == Token::IDENTIFIER || next == Token::NUMBER ||
+ next == Token::FUTURE_RESERVED_WORD ||
next == Token::STRING || is_keyword) {
Handle<String> name;
if (is_keyword) {
@@ -3239,6 +3253,7 @@ ObjectLiteral::Property* Parser::ParseObjectLiteralGetSet(bool is_getter,
}
FunctionLiteral* value =
ParseFunctionLiteral(name,
+ false, // reserved words are allowed here
RelocInfo::kNoPosition,
DECLARATION,
CHECK_OK);
@@ -3281,6 +3296,7 @@ Expression* Parser::ParseObjectLiteral(bool* ok) {
Scanner::Location loc = scanner().peek_location();
switch (next) {
+ case Token::FUTURE_RESERVED_WORD:
case Token::IDENTIFIER: {
bool is_getter = false;
bool is_setter = false;
@@ -3429,6 +3445,7 @@ ZoneList<Expression*>* Parser::ParseArguments(bool* ok) {
FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
+ bool name_is_reserved,
int function_token_position,
FunctionLiteralType type,
bool* ok) {
@@ -3462,10 +3479,13 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
int start_pos = scanner().location().beg_pos;
Scanner::Location name_loc = Scanner::NoLocation();
Scanner::Location dupe_loc = Scanner::NoLocation();
+ Scanner::Location reserved_loc = Scanner::NoLocation();
bool done = (peek() == Token::RPAREN);
while (!done) {
- Handle<String> param_name = ParseIdentifier(CHECK_OK);
+ bool is_reserved = false;
+ Handle<String> param_name =
+ ParseIdentifierOrReservedWord(&is_reserved, CHECK_OK);
// Store locations for possible future error reports.
if (!name_loc.IsValid() && IsEvalOrArguments(param_name)) {
@@ -3474,6 +3494,9 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
if (!dupe_loc.IsValid() && top_scope_->IsDeclared(param_name)) {
dupe_loc = scanner().location();
}
+ if (!reserved_loc.IsValid() && is_reserved) {
+ reserved_loc = scanner().location();
+ }
Variable* parameter = top_scope_->DeclareLocal(param_name, Variable::VAR);
top_scope_->AddParameter(parameter);
@@ -3554,7 +3577,8 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
int position = function_token_position != RelocInfo::kNoPosition
? function_token_position
: (start_pos > 0 ? start_pos - 1 : start_pos);
- ReportMessageAt(Scanner::Location(position, start_pos),
+ Scanner::Location location = Scanner::Location(position, start_pos);
+ ReportMessageAt(location,
"strict_function_name", Vector<const char*>::empty());
*ok = false;
return NULL;
@@ -3571,6 +3595,22 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
*ok = false;
return NULL;
}
+ if (name_is_reserved) {
+ int position = function_token_position != RelocInfo::kNoPosition
+ ? function_token_position
+ : (start_pos > 0 ? start_pos - 1 : start_pos);
+ Scanner::Location location = Scanner::Location(position, start_pos);
+ ReportMessageAt(location, "strict_reserved_word",
+ Vector<const char*>::empty());
+ *ok = false;
+ return NULL;
+ }
+ if (reserved_loc.IsValid()) {
+ ReportMessageAt(reserved_loc, "strict_reserved_word",
+ Vector<const char*>::empty());
+ *ok = false;
+ return NULL;
+ }
CheckOctalLiteral(start_pos, end_pos, CHECK_OK);
}
@@ -3642,6 +3682,13 @@ Expression* Parser::ParseV8Intrinsic(bool* ok) {
}
+bool Parser::peek_any_identifier() {
+ Token::Value next = peek();
+ return next == Token::IDENTIFIER ||
+ next == Token::FUTURE_RESERVED_WORD;
+}
+
+
void Parser::Consume(Token::Value token) {
Token::Value next = Next();
USE(next);
@@ -3701,7 +3748,22 @@ Literal* Parser::GetLiteralNumber(double value) {
Handle<String> Parser::ParseIdentifier(bool* ok) {
- Expect(Token::IDENTIFIER, ok);
+ bool is_reserved;
+ return ParseIdentifierOrReservedWord(&is_reserved, ok);
+}
+
+
+Handle<String> Parser::ParseIdentifierOrReservedWord(bool* is_reserved,
+ bool* ok) {
+ *is_reserved = false;
+ if (temp_scope_->StrictMode()) {
+ Expect(Token::IDENTIFIER, ok);
+ } else {
+ if (!Check(Token::IDENTIFIER)) {
+ Expect(Token::FUTURE_RESERVED_WORD, ok);
+ *is_reserved = true;
+ }
+ }
if (!*ok) return Handle<String>();
return GetSymbol(ok);
}
@@ -3709,7 +3771,9 @@ Handle<String> Parser::ParseIdentifier(bool* ok) {
Handle<String> Parser::ParseIdentifierName(bool* ok) {
Token::Value next = Next();
- if (next != Token::IDENTIFIER && !Token::IsKeyword(next)) {
+ if (next != Token::IDENTIFIER &&
+ next != Token::FUTURE_RESERVED_WORD &&
+ !Token::IsKeyword(next)) {
ReportUnexpectedToken(next);
*ok = false;
return Handle<String>();
@@ -3749,20 +3813,18 @@ void Parser::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) {
// This function reads an identifier and determines whether or not it
-// is 'get' or 'set'. The reason for not using ParseIdentifier and
-// checking on the output is that this involves heap allocation which
-// we can't do during preparsing.
+// is 'get' or 'set'.
Handle<String> Parser::ParseIdentifierOrGetOrSet(bool* is_get,
bool* is_set,
bool* ok) {
- Expect(Token::IDENTIFIER, ok);
+ Handle<String> result = ParseIdentifier(ok);
if (!*ok) return Handle<String>();
if (scanner().is_literal_ascii() && scanner().literal_length() == 3) {
const char* token = scanner().literal_ascii_string().start();
*is_get = strncmp(token, "get", 3) == 0;
*is_set = !*is_get && strncmp(token, "set", 3) == 0;
}
- return GetSymbol(ok);
+ return result;
}
@@ -3904,6 +3966,7 @@ Handle<Object> JsonParser::ParseJson(Handle<String> script,
message = "unexpected_token_string";
break;
case Token::IDENTIFIER:
+ case Token::FUTURE_RESERVED_WORD:
message = "unexpected_token_identifier";
break;
default:
« no previous file with comments | « src/parser.h ('k') | src/preparser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698