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

Side by Side Diff: src/preparser.cc

Issue 140183005: Unify function name validation in Parser and PreParser. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: rebased Created 6 years, 10 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/preparser.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
258 258
259 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) { 259 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) {
260 // FunctionDeclaration :: 260 // FunctionDeclaration ::
261 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' 261 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
262 // GeneratorDeclaration :: 262 // GeneratorDeclaration ::
263 // 'function' '*' Identifier '(' FormalParameterListopt ')' 263 // 'function' '*' Identifier '(' FormalParameterListopt ')'
264 // '{' FunctionBody '}' 264 // '{' FunctionBody '}'
265 Expect(Token::FUNCTION, CHECK_OK); 265 Expect(Token::FUNCTION, CHECK_OK);
266 266
267 bool is_generator = allow_generators() && Check(Token::MUL); 267 bool is_generator = allow_generators() && Check(Token::MUL);
268 Identifier identifier = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); 268 bool is_strict_reserved = false;
269 Scanner::Location location = scanner()->location(); 269 Identifier name = ParseIdentifierOrStrictReservedWord(
270 270 &is_strict_reserved, CHECK_OK);
271 Expression function_value = ParseFunctionLiteral(is_generator, CHECK_OK); 271 ParseFunctionLiteral(name,
272 272 scanner()->location(),
273 // If we're in strict mode, ParseIdentifier will catch using eval, arguments 273 is_strict_reserved,
274 // or a strict reserved word as function name. However, if only the function 274 is_generator,
275 // is strict, we need to do an extra check. 275 CHECK_OK);
276 if (function_value.IsStrictFunction() &&
277 !identifier.IsValidStrictVariable()) {
278 // Strict mode violation, using either reserved word or eval/arguments
279 // as name of strict function.
280 const char* type = "strict_eval_arguments";
281 if (identifier.IsFutureStrictReserved() || identifier.IsYield()) {
282 type = "unexpected_strict_reserved";
283 }
284 ReportMessageAt(location, type, NULL);
285 *ok = false;
286 }
287 return Statement::FunctionDeclaration(); 276 return Statement::FunctionDeclaration();
288 } 277 }
289 278
290 279
291 PreParser::Statement PreParser::ParseBlock(bool* ok) { 280 PreParser::Statement PreParser::ParseBlock(bool* ok) {
292 // Block :: 281 // Block ::
293 // '{' Statement* '}' 282 // '{' Statement* '}'
294 283
295 // Note that a Block does not introduce a new execution scope! 284 // Note that a Block does not introduce a new execution scope!
296 // (ECMA-262, 3rd, 12.2) 285 // (ECMA-262, 3rd, 12.2)
(...skipping 717 matching lines...) Expand 10 before | Expand all | Expand 10 after
1014 // MemberExpression :: 1003 // MemberExpression ::
1015 // (PrimaryExpression | FunctionLiteral) 1004 // (PrimaryExpression | FunctionLiteral)
1016 // ('[' Expression ']' | '.' Identifier | Arguments)* 1005 // ('[' Expression ']' | '.' Identifier | Arguments)*
1017 1006
1018 // Parse the initial primary or function expression. 1007 // Parse the initial primary or function expression.
1019 Expression result = Expression::Default(); 1008 Expression result = Expression::Default();
1020 if (peek() == Token::FUNCTION) { 1009 if (peek() == Token::FUNCTION) {
1021 Consume(Token::FUNCTION); 1010 Consume(Token::FUNCTION);
1022 1011
1023 bool is_generator = allow_generators() && Check(Token::MUL); 1012 bool is_generator = allow_generators() && Check(Token::MUL);
1024 Identifier identifier = Identifier::Default(); 1013 Identifier name = Identifier::Default();
1014 bool is_strict_reserved_name = false;
1015 Scanner::Location function_name_location = Scanner::Location::invalid();
1025 if (peek_any_identifier()) { 1016 if (peek_any_identifier()) {
1026 identifier = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); 1017 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name,
1018 CHECK_OK);
1019 function_name_location = scanner()->location();
1027 } 1020 }
1028 result = ParseFunctionLiteral(is_generator, CHECK_OK); 1021 result = ParseFunctionLiteral(name,
1029 // If we're in strict mode, ParseIdentifier will catch using eval, arguments 1022 function_name_location,
1030 // or a strict reserved word as function name. However, if only the function 1023 is_strict_reserved_name,
1031 // is strict, we need to do an extra check. 1024 is_generator,
1032 if (result.IsStrictFunction() && !identifier.IsValidStrictVariable()) { 1025 CHECK_OK);
1033 StrictModeIdentifierViolation(scanner()->location(),
1034 identifier,
1035 ok);
1036 return Expression::Default();
1037 }
1038 } else { 1026 } else {
1039 result = ParsePrimaryExpression(CHECK_OK); 1027 result = ParsePrimaryExpression(CHECK_OK);
1040 } 1028 }
1041 1029
1042 while (true) { 1030 while (true) {
1043 switch (peek()) { 1031 switch (peek()) {
1044 case Token::LBRACK: { 1032 case Token::LBRACK: {
1045 Consume(Token::LBRACK); 1033 Consume(Token::LBRACK);
1046 ParseExpression(true, CHECK_OK); 1034 ParseExpression(true, CHECK_OK);
1047 Expect(Token::RBRACK, CHECK_OK); 1035 Expect(Token::RBRACK, CHECK_OK);
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
1209 name != Token::STRING && 1197 name != Token::STRING &&
1210 !is_keyword) { 1198 !is_keyword) {
1211 *ok = false; 1199 *ok = false;
1212 return Expression::Default(); 1200 return Expression::Default();
1213 } 1201 }
1214 if (!is_keyword) { 1202 if (!is_keyword) {
1215 LogSymbol(); 1203 LogSymbol();
1216 } 1204 }
1217 PropertyKind type = is_getter ? kGetterProperty : kSetterProperty; 1205 PropertyKind type = is_getter ? kGetterProperty : kSetterProperty;
1218 checker.CheckProperty(name, type, CHECK_OK); 1206 checker.CheckProperty(name, type, CHECK_OK);
1219 ParseFunctionLiteral(false, CHECK_OK); 1207 ParseFunctionLiteral(Identifier::Default(),
1208 scanner()->location(),
1209 false, // reserved words are allowed here
1210 false, // not a generator
1211 CHECK_OK);
1220 if (peek() != Token::RBRACE) { 1212 if (peek() != Token::RBRACE) {
1221 Expect(Token::COMMA, CHECK_OK); 1213 Expect(Token::COMMA, CHECK_OK);
1222 } 1214 }
1223 continue; // restart the while 1215 continue; // restart the while
1224 } 1216 }
1225 checker.CheckProperty(next, kValueProperty, CHECK_OK); 1217 checker.CheckProperty(next, kValueProperty, CHECK_OK);
1226 break; 1218 break;
1227 } 1219 }
1228 case Token::STRING: 1220 case Token::STRING:
1229 Consume(next); 1221 Consume(next);
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1295 done = (peek() == Token::RPAREN); 1287 done = (peek() == Token::RPAREN);
1296 if (!done) { 1288 if (!done) {
1297 Expect(Token::COMMA, ok); 1289 Expect(Token::COMMA, ok);
1298 if (!*ok) return -1; 1290 if (!*ok) return -1;
1299 } 1291 }
1300 } 1292 }
1301 Expect(Token::RPAREN, ok); 1293 Expect(Token::RPAREN, ok);
1302 return argc; 1294 return argc;
1303 } 1295 }
1304 1296
1305 1297 PreParser::Expression PreParser::ParseFunctionLiteral(
1306 PreParser::Expression PreParser::ParseFunctionLiteral(bool is_generator, 1298 Identifier name,
1307 bool* ok) { 1299 Scanner::Location function_name_location,
1300 bool name_is_strict_reserved,
1301 bool is_generator,
1302 bool* ok) {
1308 // Function :: 1303 // Function ::
1309 // '(' FormalParameterList? ')' '{' FunctionBody '}' 1304 // '(' FormalParameterList? ')' '{' FunctionBody '}'
1310 1305
1311 // Parse function body. 1306 // Parse function body.
1312 ScopeType outer_scope_type = scope_->type(); 1307 ScopeType outer_scope_type = scope_->type();
1313 bool inside_with = scope_->IsInsideWith(); 1308 bool inside_with = scope_->IsInsideWith();
1314 Scope function_scope(&scope_, kFunctionScope); 1309 Scope function_scope(&scope_, kFunctionScope);
1315 function_scope.set_is_generator(is_generator); 1310 function_scope.set_is_generator(is_generator);
1316 // FormalParameterList :: 1311 // FormalParameterList ::
1317 // '(' (Identifier)*[','] ')' 1312 // '(' (Identifier)*[','] ')'
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1351 parenthesized_function_ = false; 1346 parenthesized_function_ = false;
1352 1347
1353 Expect(Token::LBRACE, CHECK_OK); 1348 Expect(Token::LBRACE, CHECK_OK);
1354 if (is_lazily_compiled) { 1349 if (is_lazily_compiled) {
1355 ParseLazyFunctionLiteralBody(CHECK_OK); 1350 ParseLazyFunctionLiteralBody(CHECK_OK);
1356 } else { 1351 } else {
1357 ParseSourceElements(Token::RBRACE, ok); 1352 ParseSourceElements(Token::RBRACE, ok);
1358 } 1353 }
1359 Expect(Token::RBRACE, CHECK_OK); 1354 Expect(Token::RBRACE, CHECK_OK);
1360 1355
1356 // Validate strict mode.
1361 if (!scope_->is_classic_mode()) { 1357 if (!scope_->is_classic_mode()) {
1358 if (name.IsEvalOrArguments()) {
1359 ReportMessageAt(function_name_location, "strict_eval_arguments", NULL);
1360 *ok = false;
1361 return Expression::Default();
1362 }
1363 if (name_is_strict_reserved) {
1364 ReportMessageAt(
1365 function_name_location, "unexpected_strict_reserved", NULL);
1366 *ok = false;
1367 return Expression::Default();
1368 }
1369
1362 int end_position = scanner()->location().end_pos; 1370 int end_position = scanner()->location().end_pos;
1363 CheckOctalLiteral(start_position, end_position, CHECK_OK); 1371 CheckOctalLiteral(start_position, end_position, CHECK_OK);
1364 CheckDelayedStrictModeViolation(start_position, end_position, CHECK_OK); 1372 CheckDelayedStrictModeViolation(start_position, end_position, CHECK_OK);
1365 return Expression::StrictFunction(); 1373 return Expression::StrictFunction();
1366 } 1374 }
1367 1375
1368 return Expression::Default(); 1376 return Expression::Default();
1369 } 1377 }
1370 1378
1371 1379
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
1527 if (!scope_->is_classic_mode()) { 1535 if (!scope_->is_classic_mode()) {
1528 ReportMessageAt(location, type, NULL); 1536 ReportMessageAt(location, type, NULL);
1529 *ok = false; 1537 *ok = false;
1530 return; 1538 return;
1531 } 1539 }
1532 strict_mode_violation_location_ = location; 1540 strict_mode_violation_location_ = location;
1533 strict_mode_violation_type_ = type; 1541 strict_mode_violation_type_ = type;
1534 } 1542 }
1535 1543
1536 1544
1545 // Parses and identifier or a strict mode future reserved word, and indicate
1546 // whether it is strict mode future reserved.
1547 PreParser::Identifier PreParser::ParseIdentifierOrStrictReservedWord(
1548 bool* is_strict_reserved, bool* ok) {
1549 Token::Value next = Next();
1550 if (next == Token::IDENTIFIER) {
1551 *is_strict_reserved = false;
1552 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD ||
1553 (next == Token::YIELD && !scope_->is_generator())) {
1554 *is_strict_reserved = true;
1555 } else {
1556 ReportUnexpectedToken(next);
1557 *ok = false;
1558 return Identifier::Default();
1559 }
1560 return GetIdentifierSymbol();
1561 }
1562
1563
1537 PreParser::Identifier PreParser::ParseIdentifierName(bool* ok) { 1564 PreParser::Identifier PreParser::ParseIdentifierName(bool* ok) {
1538 Token::Value next = Next(); 1565 Token::Value next = Next();
1539 if (next != Token::IDENTIFIER && 1566 if (next != Token::IDENTIFIER &&
1540 next != Token::FUTURE_RESERVED_WORD && 1567 next != Token::FUTURE_RESERVED_WORD &&
1541 next != Token::FUTURE_STRICT_RESERVED_WORD && 1568 next != Token::FUTURE_STRICT_RESERVED_WORD &&
1542 !Token::IsKeyword(next)) { 1569 !Token::IsKeyword(next)) {
1543 ReportUnexpectedToken(next); 1570 ReportUnexpectedToken(next);
1544 *ok = false; 1571 *ok = false;
1545 return Identifier::Default(); 1572 return Identifier::Default();
1546 } 1573 }
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1593 ASSERT(IsAccessorAccessorConflict(old_type, type)); 1620 ASSERT(IsAccessorAccessorConflict(old_type, type));
1594 // Both accessors of the same type. 1621 // Both accessors of the same type.
1595 parser()->ReportMessageAt(scanner()->location(), 1622 parser()->ReportMessageAt(scanner()->location(),
1596 "accessor_get_set"); 1623 "accessor_get_set");
1597 } 1624 }
1598 *ok = false; 1625 *ok = false;
1599 } 1626 }
1600 } 1627 }
1601 1628
1602 } } // v8::internal 1629 } } // v8::internal
OLDNEW
« no previous file with comments | « src/preparser.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698