Commit 5788b34a authored by marja@chromium.org's avatar marja@chromium.org

Unify function name validation in Parser and PreParser.

BUG=3126
LOG=N
R=ulan@chromium.org

Review URL: https://codereview.chromium.org/140183005

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@19193 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 7a53841c
......@@ -3388,7 +3388,7 @@ Expression* Parser::ParseMemberWithNewPrefixesExpression(PositionStack* stack,
// Parse the initial primary or function expression.
Expression* result = NULL;
if (peek() == Token::FUNCTION) {
Expect(Token::FUNCTION, CHECK_OK);
Consume(Token::FUNCTION);
int function_token_position = position();
bool is_generator = allow_generators() && Check(Token::MUL);
Handle<String> name;
......@@ -4265,20 +4265,20 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
*ok = false;
return NULL;
}
if (name_loc.IsValid()) {
ReportMessageAt(name_loc, "strict_eval_arguments",
if (name_is_strict_reserved) {
ReportMessageAt(function_name_location, "unexpected_strict_reserved",
Vector<const char*>::empty());
*ok = false;
return NULL;
}
if (dupe_loc.IsValid()) {
ReportMessageAt(dupe_loc, "strict_param_dupe",
if (name_loc.IsValid()) {
ReportMessageAt(name_loc, "strict_eval_arguments",
Vector<const char*>::empty());
*ok = false;
return NULL;
}
if (name_is_strict_reserved) {
ReportMessageAt(function_name_location, "unexpected_strict_reserved",
if (dupe_loc.IsValid()) {
ReportMessageAt(dupe_loc, "strict_param_dupe",
Vector<const char*>::empty());
*ok = false;
return NULL;
......
......@@ -649,9 +649,9 @@ class Parser : public ParserBase {
ZoneList<Expression*>* ParseArguments(bool* ok);
FunctionLiteral* ParseFunctionLiteral(
Handle<String> var_name,
Handle<String> name,
Scanner::Location function_name_location,
bool name_is_reserved,
bool name_is_strict_reserved,
bool is_generator,
int function_token_position,
FunctionLiteral::FunctionType type,
......
......@@ -265,25 +265,14 @@ PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) {
Expect(Token::FUNCTION, CHECK_OK);
bool is_generator = allow_generators() && Check(Token::MUL);
Identifier identifier = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
Scanner::Location location = scanner()->location();
Expression function_value = ParseFunctionLiteral(is_generator, CHECK_OK);
// If we're in strict mode, ParseIdentifier will catch using eval, arguments
// or a strict reserved word as function name. However, if only the function
// is strict, we need to do an extra check.
if (function_value.IsStrictFunction() &&
!identifier.IsValidStrictVariable()) {
// Strict mode violation, using either reserved word or eval/arguments
// as name of strict function.
const char* type = "strict_eval_arguments";
if (identifier.IsFutureStrictReserved() || identifier.IsYield()) {
type = "unexpected_strict_reserved";
}
ReportMessageAt(location, type, NULL);
*ok = false;
}
bool is_strict_reserved = false;
Identifier name = ParseIdentifierOrStrictReservedWord(
&is_strict_reserved, CHECK_OK);
ParseFunctionLiteral(name,
scanner()->location(),
is_strict_reserved,
is_generator,
CHECK_OK);
return Statement::FunctionDeclaration();
}
......@@ -1021,20 +1010,19 @@ PreParser::Expression PreParser::ParseMemberWithNewPrefixesExpression(
Consume(Token::FUNCTION);
bool is_generator = allow_generators() && Check(Token::MUL);
Identifier identifier = Identifier::Default();
Identifier name = Identifier::Default();
bool is_strict_reserved_name = false;
Scanner::Location function_name_location = Scanner::Location::invalid();
if (peek_any_identifier()) {
identifier = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
}
result = ParseFunctionLiteral(is_generator, CHECK_OK);
// If we're in strict mode, ParseIdentifier will catch using eval, arguments
// or a strict reserved word as function name. However, if only the function
// is strict, we need to do an extra check.
if (result.IsStrictFunction() && !identifier.IsValidStrictVariable()) {
StrictModeIdentifierViolation(scanner()->location(),
identifier,
ok);
return Expression::Default();
name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name,
CHECK_OK);
function_name_location = scanner()->location();
}
result = ParseFunctionLiteral(name,
function_name_location,
is_strict_reserved_name,
is_generator,
CHECK_OK);
} else {
result = ParsePrimaryExpression(CHECK_OK);
}
......@@ -1216,7 +1204,11 @@ PreParser::Expression PreParser::ParseObjectLiteral(bool* ok) {
}
PropertyKind type = is_getter ? kGetterProperty : kSetterProperty;
checker.CheckProperty(name, type, CHECK_OK);
ParseFunctionLiteral(false, CHECK_OK);
ParseFunctionLiteral(Identifier::Default(),
scanner()->location(),
false, // reserved words are allowed here
false, // not a generator
CHECK_OK);
if (peek() != Token::RBRACE) {
Expect(Token::COMMA, CHECK_OK);
}
......@@ -1302,9 +1294,12 @@ PreParser::Arguments PreParser::ParseArguments(bool* ok) {
return argc;
}
PreParser::Expression PreParser::ParseFunctionLiteral(bool is_generator,
bool* ok) {
PreParser::Expression PreParser::ParseFunctionLiteral(
Identifier name,
Scanner::Location function_name_location,
bool name_is_strict_reserved,
bool is_generator,
bool* ok) {
// Function ::
// '(' FormalParameterList? ')' '{' FunctionBody '}'
......@@ -1358,7 +1353,20 @@ PreParser::Expression PreParser::ParseFunctionLiteral(bool is_generator,
}
Expect(Token::RBRACE, CHECK_OK);
// Validate strict mode.
if (!scope_->is_classic_mode()) {
if (name.IsEvalOrArguments()) {
ReportMessageAt(function_name_location, "strict_eval_arguments", NULL);
*ok = false;
return Expression::Default();
}
if (name_is_strict_reserved) {
ReportMessageAt(
function_name_location, "unexpected_strict_reserved", NULL);
*ok = false;
return Expression::Default();
}
int end_position = scanner()->location().end_pos;
CheckOctalLiteral(start_position, end_position, CHECK_OK);
CheckDelayedStrictModeViolation(start_position, end_position, CHECK_OK);
......@@ -1534,6 +1542,25 @@ void PreParser::StrictModeIdentifierViolation(Scanner::Location location,
}
// Parses and identifier or a strict mode future reserved word, and indicate
// whether it is strict mode future reserved.
PreParser::Identifier PreParser::ParseIdentifierOrStrictReservedWord(
bool* is_strict_reserved, bool* ok) {
Token::Value next = Next();
if (next == Token::IDENTIFIER) {
*is_strict_reserved = false;
} else if (next == Token::FUTURE_STRICT_RESERVED_WORD ||
(next == Token::YIELD && !scope_->is_generator())) {
*is_strict_reserved = true;
} else {
ReportUnexpectedToken(next);
*ok = false;
return Identifier::Default();
}
return GetIdentifierSymbol();
}
PreParser::Identifier PreParser::ParseIdentifierName(bool* ok) {
Token::Value next = Next();
if (next != Token::IDENTIFIER &&
......
......@@ -616,10 +616,17 @@ class PreParser : public ParserBase {
Expression ParseV8Intrinsic(bool* ok);
Arguments ParseArguments(bool* ok);
Expression ParseFunctionLiteral(bool is_generator, bool* ok);
Expression ParseFunctionLiteral(
Identifier name,
Scanner::Location function_name_location,
bool name_is_strict_reserved,
bool is_generator,
bool* ok);
void ParseLazyFunctionLiteralBody(bool* ok);
Identifier ParseIdentifier(AllowEvalOrArgumentsAsIdentifier, bool* ok);
Identifier ParseIdentifierOrStrictReservedWord(bool* is_strict_reserved,
bool* ok);
Identifier ParseIdentifierName(bool* ok);
Identifier ParseIdentifierNameOrGetOrSet(bool* is_get,
bool* is_set,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment