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

Side by Side Diff: src/preparser.cc

Issue 7207007: Proper handling of future reserved words in strict and normal mode. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: addressed comments Created 9 years, 6 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') | src/scanner-base.h » ('j') | 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 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 case i::Token::EOS: 70 case i::Token::EOS:
71 return ReportMessageAt(source_location.beg_pos, source_location.end_pos, 71 return ReportMessageAt(source_location.beg_pos, source_location.end_pos,
72 "unexpected_eos", NULL); 72 "unexpected_eos", NULL);
73 case i::Token::NUMBER: 73 case i::Token::NUMBER:
74 return ReportMessageAt(source_location.beg_pos, source_location.end_pos, 74 return ReportMessageAt(source_location.beg_pos, source_location.end_pos,
75 "unexpected_token_number", NULL); 75 "unexpected_token_number", NULL);
76 case i::Token::STRING: 76 case i::Token::STRING:
77 return ReportMessageAt(source_location.beg_pos, source_location.end_pos, 77 return ReportMessageAt(source_location.beg_pos, source_location.end_pos,
78 "unexpected_token_string", NULL); 78 "unexpected_token_string", NULL);
79 case i::Token::IDENTIFIER: 79 case i::Token::IDENTIFIER:
80 return ReportMessageAt(source_location.beg_pos, source_location.end_pos,
81 "unexpected_token_identifier", NULL);
80 case i::Token::FUTURE_RESERVED_WORD: 82 case i::Token::FUTURE_RESERVED_WORD:
81 return ReportMessageAt(source_location.beg_pos, source_location.end_pos, 83 return ReportMessageAt(source_location.beg_pos, source_location.end_pos,
82 "unexpected_token_identifier", NULL); 84 "unexpected_reserved", NULL);
85 case i::Token::FUTURE_STRICT_RESERVED_WORD:
86 return ReportMessageAt(source_location.beg_pos, source_location.end_pos,
87 "unexpected_strict_reserved", NULL);
83 default: 88 default:
84 const char* name = i::Token::String(token); 89 const char* name = i::Token::String(token);
85 ReportMessageAt(source_location.beg_pos, source_location.end_pos, 90 ReportMessageAt(source_location.beg_pos, source_location.end_pos,
86 "unexpected_token", name); 91 "unexpected_token", name);
87 } 92 }
88 } 93 }
89 94
90 95
91 // Checks whether octal literal last seen is between beg_pos and end_pos. 96 // Checks whether octal literal last seen is between beg_pos and end_pos.
92 // If so, reports an error. 97 // If so, reports an error.
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 Identifier identifier = ParseIdentifier(CHECK_OK); 231 Identifier identifier = ParseIdentifier(CHECK_OK);
227 i::Scanner::Location location = scanner_->location(); 232 i::Scanner::Location location = scanner_->location();
228 233
229 Expression function_value = ParseFunctionLiteral(CHECK_OK); 234 Expression function_value = ParseFunctionLiteral(CHECK_OK);
230 235
231 if (function_value.IsStrictFunction() && 236 if (function_value.IsStrictFunction() &&
232 !identifier.IsValidStrictVariable()) { 237 !identifier.IsValidStrictVariable()) {
233 // Strict mode violation, using either reserved word or eval/arguments 238 // Strict mode violation, using either reserved word or eval/arguments
234 // as name of strict function. 239 // as name of strict function.
235 const char* type = "strict_function_name"; 240 const char* type = "strict_function_name";
236 if (identifier.IsFutureReserved()) { 241 if (identifier.IsFutureStrictReserved()) {
237 type = "strict_reserved_word"; 242 type = "strict_reserved_word";
238 } 243 }
239 ReportMessageAt(location.beg_pos, location.end_pos, type, NULL); 244 ReportMessageAt(location.beg_pos, location.end_pos, type, NULL);
240 *ok = false; 245 *ok = false;
241 } 246 }
242 return Statement::FunctionDeclaration(); 247 return Statement::FunctionDeclaration();
243 } 248 }
244 249
245 250
246 PreParser::Statement PreParser::ParseBlock(bool* ok) { 251 PreParser::Statement PreParser::ParseBlock(bool* ok) {
(...skipping 725 matching lines...) Expand 10 before | Expand all | Expand 10 after
972 // '(' Expression ')' 977 // '(' Expression ')'
973 978
974 Expression result = Expression::Default(); 979 Expression result = Expression::Default();
975 switch (peek()) { 980 switch (peek()) {
976 case i::Token::THIS: { 981 case i::Token::THIS: {
977 Next(); 982 Next();
978 result = Expression::This(); 983 result = Expression::This();
979 break; 984 break;
980 } 985 }
981 986
982 case i::Token::FUTURE_RESERVED_WORD: 987 case i::Token::FUTURE_RESERVED_WORD: {
988 Next();
989 i::Scanner::Location location = scanner_->location();
990 ReportMessageAt(location.beg_pos, location.end_pos,
991 "reserved_word", NULL);
992 *ok = false;
993 return Expression::Default();
994 }
995
996 case i::Token::FUTURE_STRICT_RESERVED_WORD:
983 if (strict_mode()) { 997 if (strict_mode()) {
984 Next(); 998 Next();
985 i::Scanner::Location location = scanner_->location(); 999 i::Scanner::Location location = scanner_->location();
986 ReportMessageAt(location.beg_pos, location.end_pos, 1000 ReportMessageAt(location.beg_pos, location.end_pos,
987 "strict_reserved_word", NULL); 1001 "strict_reserved_word", NULL);
988 *ok = false; 1002 *ok = false;
989 return Expression::Default(); 1003 return Expression::Default();
990 } 1004 }
991 // FALLTHROUGH 1005 // FALLTHROUGH
992 case i::Token::IDENTIFIER: { 1006 case i::Token::IDENTIFIER: {
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1071 // '{' ( 1085 // '{' (
1072 // ((IdentifierName | String | Number) ':' AssignmentExpression) 1086 // ((IdentifierName | String | Number) ':' AssignmentExpression)
1073 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) 1087 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral)
1074 // )*[','] '}' 1088 // )*[','] '}'
1075 1089
1076 Expect(i::Token::LBRACE, CHECK_OK); 1090 Expect(i::Token::LBRACE, CHECK_OK);
1077 while (peek() != i::Token::RBRACE) { 1091 while (peek() != i::Token::RBRACE) {
1078 i::Token::Value next = peek(); 1092 i::Token::Value next = peek();
1079 switch (next) { 1093 switch (next) {
1080 case i::Token::IDENTIFIER: 1094 case i::Token::IDENTIFIER:
1081 case i::Token::FUTURE_RESERVED_WORD: { 1095 case i::Token::FUTURE_RESERVED_WORD:
1096 case i::Token::FUTURE_STRICT_RESERVED_WORD: {
1082 bool is_getter = false; 1097 bool is_getter = false;
1083 bool is_setter = false; 1098 bool is_setter = false;
1084 ParseIdentifierOrGetOrSet(&is_getter, &is_setter, CHECK_OK); 1099 ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK);
1085 if ((is_getter || is_setter) && peek() != i::Token::COLON) { 1100 if ((is_getter || is_setter) && peek() != i::Token::COLON) {
1086 i::Token::Value name = Next(); 1101 i::Token::Value name = Next();
1087 bool is_keyword = i::Token::IsKeyword(name); 1102 bool is_keyword = i::Token::IsKeyword(name);
1088 if (name != i::Token::IDENTIFIER && 1103 if (name != i::Token::IDENTIFIER &&
1089 name != i::Token::FUTURE_RESERVED_WORD && 1104 name != i::Token::FUTURE_RESERVED_WORD &&
1105 name != i::Token::FUTURE_STRICT_RESERVED_WORD &&
1090 name != i::Token::NUMBER && 1106 name != i::Token::NUMBER &&
1091 name != i::Token::STRING && 1107 name != i::Token::STRING &&
1092 !is_keyword) { 1108 !is_keyword) {
1093 *ok = false; 1109 *ok = false;
1094 return Expression::Default(); 1110 return Expression::Default();
1095 } 1111 }
1096 if (!is_keyword) { 1112 if (!is_keyword) {
1097 LogSymbol(); 1113 LogSymbol();
1098 } 1114 }
1099 ParseFunctionLiteral(CHECK_OK); 1115 ParseFunctionLiteral(CHECK_OK);
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
1305 return Expression::UseStrictStringLiteral(); 1321 return Expression::UseStrictStringLiteral();
1306 } 1322 }
1307 return Expression::StringLiteral(); 1323 return Expression::StringLiteral();
1308 } 1324 }
1309 1325
1310 1326
1311 PreParser::Identifier PreParser::GetIdentifierSymbol() { 1327 PreParser::Identifier PreParser::GetIdentifierSymbol() {
1312 LogSymbol(); 1328 LogSymbol();
1313 if (scanner_->current_token() == i::Token::FUTURE_RESERVED_WORD) { 1329 if (scanner_->current_token() == i::Token::FUTURE_RESERVED_WORD) {
1314 return Identifier::FutureReserved(); 1330 return Identifier::FutureReserved();
1331 } else if (scanner_->current_token() ==
1332 i::Token::FUTURE_STRICT_RESERVED_WORD) {
1333 return Identifier::FutureStrictReserved();
1315 } 1334 }
1316 if (scanner_->is_literal_ascii()) { 1335 if (scanner_->is_literal_ascii()) {
1317 // Detect strict-mode poison words. 1336 // Detect strict-mode poison words.
1318 if (scanner_->literal_length() == 4 && 1337 if (scanner_->literal_length() == 4 &&
1319 !strncmp(scanner_->literal_ascii_string().start(), "eval", 4)) { 1338 !strncmp(scanner_->literal_ascii_string().start(), "eval", 4)) {
1320 return Identifier::Eval(); 1339 return Identifier::Eval();
1321 } 1340 }
1322 if (scanner_->literal_length() == 9 && 1341 if (scanner_->literal_length() == 9 &&
1323 !strncmp(scanner_->literal_ascii_string().start(), "arguments", 9)) { 1342 !strncmp(scanner_->literal_ascii_string().start(), "arguments", 9)) {
1324 return Identifier::Arguments(); 1343 return Identifier::Arguments();
1325 } 1344 }
1326 } 1345 }
1327 return Identifier::Default(); 1346 return Identifier::Default();
1328 } 1347 }
1329 1348
1330 1349
1331 PreParser::Identifier PreParser::ParseIdentifier(bool* ok) { 1350 PreParser::Identifier PreParser::ParseIdentifier(bool* ok) {
1332 if (!Check(i::Token::FUTURE_RESERVED_WORD)) { 1351 i::Token::Value next = Next();
1333 Expect(i::Token::IDENTIFIER, ok); 1352 switch (next) {
1334 if (!*ok) return Identifier::Default(); 1353 case i::Token::FUTURE_RESERVED_WORD: {
1354 i::Scanner::Location location = scanner_->location();
1355 ReportMessageAt(location.beg_pos, location.end_pos, "reserved_word", NULL) ;
1356 *ok = false;
1357 }
1358 // FALLTHROUGH
1359 case i::Token::FUTURE_STRICT_RESERVED_WORD:
1360 case i::Token::IDENTIFIER:
1361 return GetIdentifierSymbol();
1362 default:
1363 *ok = false;
1364 return Identifier::Default();
1335 } 1365 }
1336 return GetIdentifierSymbol();
1337 } 1366 }
1338 1367
1339 1368
1340 void PreParser::SetStrictModeViolation(i::Scanner::Location location, 1369 void PreParser::SetStrictModeViolation(i::Scanner::Location location,
1341 const char* type, 1370 const char* type,
1342 bool* ok) { 1371 bool* ok) {
1343 if (strict_mode()) { 1372 if (strict_mode()) {
1344 ReportMessageAt(location.beg_pos, location.end_pos, type, NULL); 1373 ReportMessageAt(location.beg_pos, location.end_pos, type, NULL);
1345 *ok = false; 1374 *ok = false;
1346 return; 1375 return;
(...skipping 19 matching lines...) Expand all
1366 strict_mode_violation_location_ = i::Scanner::Location::invalid(); 1395 strict_mode_violation_location_ = i::Scanner::Location::invalid();
1367 } 1396 }
1368 1397
1369 1398
1370 void PreParser::StrictModeIdentifierViolation(i::Scanner::Location location, 1399 void PreParser::StrictModeIdentifierViolation(i::Scanner::Location location,
1371 const char* eval_args_type, 1400 const char* eval_args_type,
1372 Identifier identifier, 1401 Identifier identifier,
1373 bool* ok) { 1402 bool* ok) {
1374 const char* type = eval_args_type; 1403 const char* type = eval_args_type;
1375 if (identifier.IsFutureReserved()) { 1404 if (identifier.IsFutureReserved()) {
1405 type = "reserved_word";
1406 } else if (identifier.IsFutureStrictReserved()) {
1376 type = "strict_reserved_word"; 1407 type = "strict_reserved_word";
1377 } 1408 }
1378 if (strict_mode()) { 1409 if (strict_mode()) {
1379 ReportMessageAt(location.beg_pos, location.end_pos, type, NULL); 1410 ReportMessageAt(location.beg_pos, location.end_pos, type, NULL);
1380 *ok = false; 1411 *ok = false;
1381 return; 1412 return;
1382 } 1413 }
1383 strict_mode_violation_location_ = location; 1414 strict_mode_violation_location_ = location;
1384 strict_mode_violation_type_ = type; 1415 strict_mode_violation_type_ = type;
1385 } 1416 }
1386 1417
1387 1418
1388 PreParser::Identifier PreParser::ParseIdentifierName(bool* ok) { 1419 PreParser::Identifier PreParser::ParseIdentifierName(bool* ok) {
1389 i::Token::Value next = Next(); 1420 i::Token::Value next = Next();
1390 if (i::Token::IsKeyword(next)) { 1421 if (i::Token::IsKeyword(next)) {
1391 int pos = scanner_->location().beg_pos; 1422 int pos = scanner_->location().beg_pos;
1392 const char* keyword = i::Token::String(next); 1423 const char* keyword = i::Token::String(next);
1393 log_->LogAsciiSymbol(pos, i::Vector<const char>(keyword, 1424 log_->LogAsciiSymbol(pos, i::Vector<const char>(keyword,
1394 i::StrLength(keyword))); 1425 i::StrLength(keyword)));
1395 return Identifier::Default(); 1426 return Identifier::Default();
1396 } 1427 }
1397 if (next == i::Token::IDENTIFIER || 1428 if (next == i::Token::IDENTIFIER ||
1398 next == i::Token::FUTURE_RESERVED_WORD) { 1429 next == i::Token::FUTURE_RESERVED_WORD ||
1430 next == i::Token::FUTURE_STRICT_RESERVED_WORD) {
1399 return GetIdentifierSymbol(); 1431 return GetIdentifierSymbol();
1400 } 1432 }
1401 *ok = false; 1433 *ok = false;
1402 return Identifier::Default(); 1434 return Identifier::Default();
1403 } 1435 }
1404 1436
1405 #undef CHECK_OK 1437 #undef CHECK_OK
1406 1438
1407 1439
1408 // This function reads an identifier and determines whether or not it 1440 // This function reads an identifier and determines whether or not it
1409 // is 'get' or 'set'. 1441 // is 'get' or 'set'.
1410 PreParser::Identifier PreParser::ParseIdentifierOrGetOrSet(bool* is_get, 1442 PreParser::Identifier PreParser::ParseIdentifierNameOrGetOrSet(bool* is_get,
1411 bool* is_set, 1443 bool* is_set,
1412 bool* ok) { 1444 bool* ok) {
1413 Identifier result = ParseIdentifier(ok); 1445 Identifier result = ParseIdentifierName(ok);
1414 if (!*ok) return Identifier::Default(); 1446 if (!*ok) return Identifier::Default();
1415 if (scanner_->is_literal_ascii() && 1447 if (scanner_->is_literal_ascii() &&
1416 scanner_->literal_length() == 3) { 1448 scanner_->literal_length() == 3) {
1417 const char* token = scanner_->literal_ascii_string().start(); 1449 const char* token = scanner_->literal_ascii_string().start();
1418 *is_get = strncmp(token, "get", 3) == 0; 1450 *is_get = strncmp(token, "get", 3) == 0;
1419 *is_set = !*is_get && strncmp(token, "set", 3) == 0; 1451 *is_set = !*is_get && strncmp(token, "set", 3) == 0;
1420 } 1452 }
1421 return result; 1453 return result;
1422 } 1454 }
1423 1455
1424 bool PreParser::peek_any_identifier() { 1456 bool PreParser::peek_any_identifier() {
1425 i::Token::Value next = peek(); 1457 i::Token::Value next = peek();
1426 return next == i::Token::IDENTIFIER || 1458 return next == i::Token::IDENTIFIER ||
1427 next == i::Token::FUTURE_RESERVED_WORD; 1459 next == i::Token::FUTURE_RESERVED_WORD ||
1460 next == i::Token::FUTURE_STRICT_RESERVED_WORD;
1428 } 1461 }
1429 } } // v8::preparser 1462 } } // v8::preparser
OLDNEW
« no previous file with comments | « src/preparser.h ('k') | src/scanner-base.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698