OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |