| 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 |