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 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
289 | 289 |
290 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) { | 290 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) { |
291 // FunctionDeclaration :: | 291 // FunctionDeclaration :: |
292 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' | 292 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' |
293 // GeneratorDeclaration :: | 293 // GeneratorDeclaration :: |
294 // 'function' '*' Identifier '(' FormalParameterListopt ')' | 294 // 'function' '*' Identifier '(' FormalParameterListopt ')' |
295 // '{' FunctionBody '}' | 295 // '{' FunctionBody '}' |
296 Expect(Token::FUNCTION, CHECK_OK); | 296 Expect(Token::FUNCTION, CHECK_OK); |
297 | 297 |
298 bool is_generator = allow_generators() && Check(Token::MUL); | 298 bool is_generator = allow_generators() && Check(Token::MUL); |
299 Identifier identifier = ParseIdentifier(CHECK_OK); | 299 Identifier identifier = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
300 Scanner::Location location = scanner()->location(); | 300 Scanner::Location location = scanner()->location(); |
301 | 301 |
302 Expression function_value = ParseFunctionLiteral(is_generator, CHECK_OK); | 302 Expression function_value = ParseFunctionLiteral(is_generator, CHECK_OK); |
303 | 303 |
| 304 // If we're in strict mode, ParseIdentifier will catch using eval, arguments |
| 305 // or a strict reserved word as function name. However, if only the function |
| 306 // is strict, we need to do an extra check. |
304 if (function_value.IsStrictFunction() && | 307 if (function_value.IsStrictFunction() && |
305 !identifier.IsValidStrictVariable()) { | 308 !identifier.IsValidStrictVariable()) { |
306 // Strict mode violation, using either reserved word or eval/arguments | 309 // Strict mode violation, using either reserved word or eval/arguments |
307 // as name of strict function. | 310 // as name of strict function. |
308 const char* type = "strict_function_name"; | 311 const char* type = "strict_eval_arguments"; |
309 if (identifier.IsFutureStrictReserved() || identifier.IsYield()) { | 312 if (identifier.IsFutureStrictReserved() || identifier.IsYield()) { |
310 type = "unexpected_strict_reserved"; | 313 type = "unexpected_strict_reserved"; |
311 } | 314 } |
312 ReportMessageAt(location, type, NULL); | 315 ReportMessageAt(location, type, NULL); |
313 *ok = false; | 316 *ok = false; |
314 } | 317 } |
315 return Statement::FunctionDeclaration(); | 318 return Statement::FunctionDeclaration(); |
316 } | 319 } |
317 | 320 |
318 | 321 |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
439 } | 442 } |
440 | 443 |
441 // The scope of a var/const declared variable anywhere inside a function | 444 // The scope of a var/const declared variable anywhere inside a function |
442 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope | 445 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). The scope |
443 // of a let declared variable is the scope of the immediately enclosing | 446 // of a let declared variable is the scope of the immediately enclosing |
444 // block. | 447 // block. |
445 int nvars = 0; // the number of variables declared | 448 int nvars = 0; // the number of variables declared |
446 do { | 449 do { |
447 // Parse variable name. | 450 // Parse variable name. |
448 if (nvars > 0) Consume(Token::COMMA); | 451 if (nvars > 0) Consume(Token::COMMA); |
449 Identifier identifier = ParseIdentifier(CHECK_OK); | 452 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
450 if (!is_classic_mode() && !identifier.IsValidStrictVariable()) { | |
451 StrictModeIdentifierViolation(scanner()->location(), | |
452 "strict_var_name", | |
453 identifier, | |
454 ok); | |
455 return Statement::Default(); | |
456 } | |
457 nvars++; | 453 nvars++; |
458 if (peek() == Token::ASSIGN || require_initializer) { | 454 if (peek() == Token::ASSIGN || require_initializer) { |
459 Expect(Token::ASSIGN, CHECK_OK); | 455 Expect(Token::ASSIGN, CHECK_OK); |
460 ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); | 456 ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); |
461 if (decl_props != NULL) *decl_props = kHasInitializers; | 457 if (decl_props != NULL) *decl_props = kHasInitializers; |
462 } | 458 } |
463 } while (peek() == Token::COMMA); | 459 } while (peek() == Token::COMMA); |
464 | 460 |
465 if (num_decl != NULL) *num_decl = nvars; | 461 if (num_decl != NULL) *num_decl = nvars; |
466 return Statement::Default(); | 462 return Statement::Default(); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
512 PreParser::Statement PreParser::ParseContinueStatement(bool* ok) { | 508 PreParser::Statement PreParser::ParseContinueStatement(bool* ok) { |
513 // ContinueStatement :: | 509 // ContinueStatement :: |
514 // 'continue' [no line terminator] Identifier? ';' | 510 // 'continue' [no line terminator] Identifier? ';' |
515 | 511 |
516 Expect(Token::CONTINUE, CHECK_OK); | 512 Expect(Token::CONTINUE, CHECK_OK); |
517 Token::Value tok = peek(); | 513 Token::Value tok = peek(); |
518 if (!scanner()->HasAnyLineTerminatorBeforeNext() && | 514 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
519 tok != Token::SEMICOLON && | 515 tok != Token::SEMICOLON && |
520 tok != Token::RBRACE && | 516 tok != Token::RBRACE && |
521 tok != Token::EOS) { | 517 tok != Token::EOS) { |
522 ParseIdentifier(CHECK_OK); | 518 // ECMA allows "eval" or "arguments" as labels even in strict mode. |
| 519 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
523 } | 520 } |
524 ExpectSemicolon(CHECK_OK); | 521 ExpectSemicolon(CHECK_OK); |
525 return Statement::Default(); | 522 return Statement::Default(); |
526 } | 523 } |
527 | 524 |
528 | 525 |
529 PreParser::Statement PreParser::ParseBreakStatement(bool* ok) { | 526 PreParser::Statement PreParser::ParseBreakStatement(bool* ok) { |
530 // BreakStatement :: | 527 // BreakStatement :: |
531 // 'break' [no line terminator] Identifier? ';' | 528 // 'break' [no line terminator] Identifier? ';' |
532 | 529 |
533 Expect(Token::BREAK, CHECK_OK); | 530 Expect(Token::BREAK, CHECK_OK); |
534 Token::Value tok = peek(); | 531 Token::Value tok = peek(); |
535 if (!scanner()->HasAnyLineTerminatorBeforeNext() && | 532 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
536 tok != Token::SEMICOLON && | 533 tok != Token::SEMICOLON && |
537 tok != Token::RBRACE && | 534 tok != Token::RBRACE && |
538 tok != Token::EOS) { | 535 tok != Token::EOS) { |
539 ParseIdentifier(CHECK_OK); | 536 // ECMA allows "eval" or "arguments" as labels even in strict mode. |
| 537 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
540 } | 538 } |
541 ExpectSemicolon(CHECK_OK); | 539 ExpectSemicolon(CHECK_OK); |
542 return Statement::Default(); | 540 return Statement::Default(); |
543 } | 541 } |
544 | 542 |
545 | 543 |
546 PreParser::Statement PreParser::ParseReturnStatement(bool* ok) { | 544 PreParser::Statement PreParser::ParseReturnStatement(bool* ok) { |
547 // ReturnStatement :: | 545 // ReturnStatement :: |
548 // 'return' [no line terminator] Expression? ';' | 546 // 'return' [no line terminator] Expression? ';' |
549 | 547 |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
746 // of both. | 744 // of both. |
747 | 745 |
748 Expect(Token::TRY, CHECK_OK); | 746 Expect(Token::TRY, CHECK_OK); |
749 | 747 |
750 ParseBlock(CHECK_OK); | 748 ParseBlock(CHECK_OK); |
751 | 749 |
752 bool catch_or_finally_seen = false; | 750 bool catch_or_finally_seen = false; |
753 if (peek() == Token::CATCH) { | 751 if (peek() == Token::CATCH) { |
754 Consume(Token::CATCH); | 752 Consume(Token::CATCH); |
755 Expect(Token::LPAREN, CHECK_OK); | 753 Expect(Token::LPAREN, CHECK_OK); |
756 Identifier id = ParseIdentifier(CHECK_OK); | 754 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
757 if (!is_classic_mode() && !id.IsValidStrictVariable()) { | |
758 StrictModeIdentifierViolation(scanner()->location(), | |
759 "strict_catch_variable", | |
760 id, | |
761 ok); | |
762 return Statement::Default(); | |
763 } | |
764 Expect(Token::RPAREN, CHECK_OK); | 755 Expect(Token::RPAREN, CHECK_OK); |
765 { Scope::InsideWith iw(scope_); | 756 { Scope::InsideWith iw(scope_); |
766 ParseBlock(CHECK_OK); | 757 ParseBlock(CHECK_OK); |
767 } | 758 } |
768 catch_or_finally_seen = true; | 759 catch_or_finally_seen = true; |
769 } | 760 } |
770 if (peek() == Token::FINALLY) { | 761 if (peek() == Token::FINALLY) { |
771 Consume(Token::FINALLY); | 762 Consume(Token::FINALLY); |
772 ParseBlock(CHECK_OK); | 763 ParseBlock(CHECK_OK); |
773 catch_or_finally_seen = true; | 764 catch_or_finally_seen = true; |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
834 if (!Token::IsAssignmentOp(peek())) { | 825 if (!Token::IsAssignmentOp(peek())) { |
835 // Parsed conditional expression only (no assignment). | 826 // Parsed conditional expression only (no assignment). |
836 return expression; | 827 return expression; |
837 } | 828 } |
838 | 829 |
839 if (!is_classic_mode() && | 830 if (!is_classic_mode() && |
840 expression.IsIdentifier() && | 831 expression.IsIdentifier() && |
841 expression.AsIdentifier().IsEvalOrArguments()) { | 832 expression.AsIdentifier().IsEvalOrArguments()) { |
842 Scanner::Location after = scanner()->location(); | 833 Scanner::Location after = scanner()->location(); |
843 ReportMessageAt(before.beg_pos, after.end_pos, | 834 ReportMessageAt(before.beg_pos, after.end_pos, |
844 "strict_lhs_assignment", NULL); | 835 "strict_eval_arguments", NULL); |
845 *ok = false; | 836 *ok = false; |
846 return Expression::Default(); | 837 return Expression::Default(); |
847 } | 838 } |
848 | 839 |
849 Token::Value op = Next(); // Get assignment operator. | 840 Token::Value op = Next(); // Get assignment operator. |
850 ParseAssignmentExpression(accept_IN, CHECK_OK); | 841 ParseAssignmentExpression(accept_IN, CHECK_OK); |
851 | 842 |
852 if ((op == Token::ASSIGN) && expression.IsThisProperty()) { | 843 if ((op == Token::ASSIGN) && expression.IsThisProperty()) { |
853 scope_->AddProperty(); | 844 scope_->AddProperty(); |
854 } | 845 } |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
928 return Expression::Default(); | 919 return Expression::Default(); |
929 } else if (Token::IsCountOp(op)) { | 920 } else if (Token::IsCountOp(op)) { |
930 op = Next(); | 921 op = Next(); |
931 Scanner::Location before = scanner()->peek_location(); | 922 Scanner::Location before = scanner()->peek_location(); |
932 Expression expression = ParseUnaryExpression(CHECK_OK); | 923 Expression expression = ParseUnaryExpression(CHECK_OK); |
933 if (!is_classic_mode() && | 924 if (!is_classic_mode() && |
934 expression.IsIdentifier() && | 925 expression.IsIdentifier() && |
935 expression.AsIdentifier().IsEvalOrArguments()) { | 926 expression.AsIdentifier().IsEvalOrArguments()) { |
936 Scanner::Location after = scanner()->location(); | 927 Scanner::Location after = scanner()->location(); |
937 ReportMessageAt(before.beg_pos, after.end_pos, | 928 ReportMessageAt(before.beg_pos, after.end_pos, |
938 "strict_lhs_prefix", NULL); | 929 "strict_eval_arguments", NULL); |
939 *ok = false; | 930 *ok = false; |
940 } | 931 } |
941 return Expression::Default(); | 932 return Expression::Default(); |
942 } else { | 933 } else { |
943 return ParsePostfixExpression(ok); | 934 return ParsePostfixExpression(ok); |
944 } | 935 } |
945 } | 936 } |
946 | 937 |
947 | 938 |
948 PreParser::Expression PreParser::ParsePostfixExpression(bool* ok) { | 939 PreParser::Expression PreParser::ParsePostfixExpression(bool* ok) { |
949 // PostfixExpression :: | 940 // PostfixExpression :: |
950 // LeftHandSideExpression ('++' | '--')? | 941 // LeftHandSideExpression ('++' | '--')? |
951 | 942 |
952 Scanner::Location before = scanner()->peek_location(); | 943 Scanner::Location before = scanner()->peek_location(); |
953 Expression expression = ParseLeftHandSideExpression(CHECK_OK); | 944 Expression expression = ParseLeftHandSideExpression(CHECK_OK); |
954 if (!scanner()->HasAnyLineTerminatorBeforeNext() && | 945 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
955 Token::IsCountOp(peek())) { | 946 Token::IsCountOp(peek())) { |
956 if (!is_classic_mode() && | 947 if (!is_classic_mode() && |
957 expression.IsIdentifier() && | 948 expression.IsIdentifier() && |
958 expression.AsIdentifier().IsEvalOrArguments()) { | 949 expression.AsIdentifier().IsEvalOrArguments()) { |
959 Scanner::Location after = scanner()->location(); | 950 Scanner::Location after = scanner()->location(); |
960 ReportMessageAt(before.beg_pos, after.end_pos, | 951 ReportMessageAt(before.beg_pos, after.end_pos, |
961 "strict_lhs_postfix", NULL); | 952 "strict_eval_arguments", NULL); |
962 *ok = false; | 953 *ok = false; |
963 return Expression::Default(); | 954 return Expression::Default(); |
964 } | 955 } |
965 Next(); | 956 Next(); |
966 return Expression::Default(); | 957 return Expression::Default(); |
967 } | 958 } |
968 return expression; | 959 return expression; |
969 } | 960 } |
970 | 961 |
971 | 962 |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1052 // ('[' Expression ']' | '.' Identifier | Arguments)* | 1043 // ('[' Expression ']' | '.' Identifier | Arguments)* |
1053 | 1044 |
1054 // Parse the initial primary or function expression. | 1045 // Parse the initial primary or function expression. |
1055 Expression result = Expression::Default(); | 1046 Expression result = Expression::Default(); |
1056 if (peek() == Token::FUNCTION) { | 1047 if (peek() == Token::FUNCTION) { |
1057 Consume(Token::FUNCTION); | 1048 Consume(Token::FUNCTION); |
1058 | 1049 |
1059 bool is_generator = allow_generators() && Check(Token::MUL); | 1050 bool is_generator = allow_generators() && Check(Token::MUL); |
1060 Identifier identifier = Identifier::Default(); | 1051 Identifier identifier = Identifier::Default(); |
1061 if (peek_any_identifier()) { | 1052 if (peek_any_identifier()) { |
1062 identifier = ParseIdentifier(CHECK_OK); | 1053 identifier = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
1063 } | 1054 } |
1064 result = ParseFunctionLiteral(is_generator, CHECK_OK); | 1055 result = ParseFunctionLiteral(is_generator, CHECK_OK); |
| 1056 // If we're in strict mode, ParseIdentifier will catch using eval, arguments |
| 1057 // or a strict reserved word as function name. However, if only the function |
| 1058 // is strict, we need to do an extra check. |
1065 if (result.IsStrictFunction() && !identifier.IsValidStrictVariable()) { | 1059 if (result.IsStrictFunction() && !identifier.IsValidStrictVariable()) { |
1066 StrictModeIdentifierViolation(scanner()->location(), | 1060 StrictModeIdentifierViolation(scanner()->location(), |
1067 "strict_function_name", | 1061 "strict_eval_arguments", |
1068 identifier, | 1062 identifier, |
1069 ok); | 1063 ok); |
1070 return Expression::Default(); | 1064 return Expression::Default(); |
1071 } | 1065 } |
1072 } else { | 1066 } else { |
1073 result = ParsePrimaryExpression(CHECK_OK); | 1067 result = ParsePrimaryExpression(CHECK_OK); |
1074 } | 1068 } |
1075 | 1069 |
1076 while (true) { | 1070 while (true) { |
1077 switch (peek()) { | 1071 switch (peek()) { |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1130 case Token::THIS: { | 1124 case Token::THIS: { |
1131 Next(); | 1125 Next(); |
1132 result = Expression::This(); | 1126 result = Expression::This(); |
1133 break; | 1127 break; |
1134 } | 1128 } |
1135 | 1129 |
1136 case Token::FUTURE_RESERVED_WORD: | 1130 case Token::FUTURE_RESERVED_WORD: |
1137 case Token::FUTURE_STRICT_RESERVED_WORD: | 1131 case Token::FUTURE_STRICT_RESERVED_WORD: |
1138 case Token::YIELD: | 1132 case Token::YIELD: |
1139 case Token::IDENTIFIER: { | 1133 case Token::IDENTIFIER: { |
1140 Identifier id = ParseIdentifier(CHECK_OK); | 1134 // Using eval or arguments in this context is OK even in strict mode. |
| 1135 Identifier id = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
1141 result = Expression::FromIdentifier(id); | 1136 result = Expression::FromIdentifier(id); |
1142 break; | 1137 break; |
1143 } | 1138 } |
1144 | 1139 |
1145 case Token::NULL_LITERAL: | 1140 case Token::NULL_LITERAL: |
1146 case Token::TRUE_LITERAL: | 1141 case Token::TRUE_LITERAL: |
1147 case Token::FALSE_LITERAL: | 1142 case Token::FALSE_LITERAL: |
1148 case Token::NUMBER: { | 1143 case Token::NUMBER: { |
1149 Next(); | 1144 Next(); |
1150 break; | 1145 break; |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1347 bool inside_with = scope_->IsInsideWith(); | 1342 bool inside_with = scope_->IsInsideWith(); |
1348 Scope function_scope(&scope_, kFunctionScope); | 1343 Scope function_scope(&scope_, kFunctionScope); |
1349 function_scope.set_is_generator(is_generator); | 1344 function_scope.set_is_generator(is_generator); |
1350 // FormalParameterList :: | 1345 // FormalParameterList :: |
1351 // '(' (Identifier)*[','] ')' | 1346 // '(' (Identifier)*[','] ')' |
1352 Expect(Token::LPAREN, CHECK_OK); | 1347 Expect(Token::LPAREN, CHECK_OK); |
1353 int start_position = position(); | 1348 int start_position = position(); |
1354 bool done = (peek() == Token::RPAREN); | 1349 bool done = (peek() == Token::RPAREN); |
1355 DuplicateFinder duplicate_finder(scanner()->unicode_cache()); | 1350 DuplicateFinder duplicate_finder(scanner()->unicode_cache()); |
1356 while (!done) { | 1351 while (!done) { |
1357 Identifier id = ParseIdentifier(CHECK_OK); | 1352 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
1358 if (!id.IsValidStrictVariable()) { | |
1359 StrictModeIdentifierViolation(scanner()->location(), | |
1360 "strict_param_name", | |
1361 id, | |
1362 CHECK_OK); | |
1363 } | |
1364 int prev_value; | 1353 int prev_value; |
1365 if (scanner()->is_literal_ascii()) { | 1354 if (scanner()->is_literal_ascii()) { |
1366 prev_value = | 1355 prev_value = |
1367 duplicate_finder.AddAsciiSymbol(scanner()->literal_ascii_string(), 1); | 1356 duplicate_finder.AddAsciiSymbol(scanner()->literal_ascii_string(), 1); |
1368 } else { | 1357 } else { |
1369 prev_value = | 1358 prev_value = |
1370 duplicate_finder.AddUtf16Symbol(scanner()->literal_utf16_string(), 1); | 1359 duplicate_finder.AddUtf16Symbol(scanner()->literal_utf16_string(), 1); |
1371 } | 1360 } |
1372 | 1361 |
1373 if (prev_value != 0) { | 1362 if (prev_value != 0) { |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1427 | 1416 |
1428 | 1417 |
1429 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) { | 1418 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) { |
1430 // CallRuntime :: | 1419 // CallRuntime :: |
1431 // '%' Identifier Arguments | 1420 // '%' Identifier Arguments |
1432 Expect(Token::MOD, CHECK_OK); | 1421 Expect(Token::MOD, CHECK_OK); |
1433 if (!allow_natives_syntax()) { | 1422 if (!allow_natives_syntax()) { |
1434 *ok = false; | 1423 *ok = false; |
1435 return Expression::Default(); | 1424 return Expression::Default(); |
1436 } | 1425 } |
1437 ParseIdentifier(CHECK_OK); | 1426 // Allow "eval" or "arguments" for backward compatibility. |
| 1427 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
1438 ParseArguments(ok); | 1428 ParseArguments(ok); |
1439 | 1429 |
1440 return Expression::Default(); | 1430 return Expression::Default(); |
1441 } | 1431 } |
1442 | 1432 |
1443 #undef CHECK_OK | 1433 #undef CHECK_OK |
1444 | 1434 |
1445 | 1435 |
1446 void PreParser::LogSymbol() { | 1436 void PreParser::LogSymbol() { |
1447 int identifier_pos = position(); | 1437 int identifier_pos = position(); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1486 } | 1476 } |
1487 if (scanner()->literal_length() == 9 && | 1477 if (scanner()->literal_length() == 9 && |
1488 !strncmp(scanner()->literal_ascii_string().start(), "arguments", 9)) { | 1478 !strncmp(scanner()->literal_ascii_string().start(), "arguments", 9)) { |
1489 return Identifier::Arguments(); | 1479 return Identifier::Arguments(); |
1490 } | 1480 } |
1491 } | 1481 } |
1492 return Identifier::Default(); | 1482 return Identifier::Default(); |
1493 } | 1483 } |
1494 | 1484 |
1495 | 1485 |
1496 PreParser::Identifier PreParser::ParseIdentifier(bool* ok) { | 1486 // Parses an identifier that is valid for the current scope, in particular it |
| 1487 // fails on strict mode future reserved keywords in a strict scope. If |
| 1488 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or |
| 1489 // "arguments" as identifier even in strict mode (this is needed in cases like |
| 1490 // "var foo = eval;"). |
| 1491 PreParser::Identifier PreParser::ParseIdentifier( |
| 1492 AllowEvalOrArgumentsAsIdentifier allow_eval_or_arguments, |
| 1493 bool* ok) { |
1497 Token::Value next = Next(); | 1494 Token::Value next = Next(); |
1498 if (next == Token::IDENTIFIER || | 1495 if (next == Token::IDENTIFIER) { |
1499 (is_classic_mode() && | 1496 PreParser::Identifier name = GetIdentifierSymbol(); |
1500 (next == Token::FUTURE_STRICT_RESERVED_WORD || | 1497 if (allow_eval_or_arguments == kDontAllowEvalOrArguments && |
1501 (next == Token::YIELD && !scope_->is_generator())))) { | 1498 !is_classic_mode() && name.IsEvalOrArguments()) { |
| 1499 StrictModeIdentifierViolation( |
| 1500 scanner()->location(), "strict_eval_arguments", name, ok); |
| 1501 } |
| 1502 return name; |
| 1503 } else if (is_classic_mode() && |
| 1504 (next == Token::FUTURE_STRICT_RESERVED_WORD || |
| 1505 (next == Token::YIELD && !scope_->is_generator()))) { |
1502 return GetIdentifierSymbol(); | 1506 return GetIdentifierSymbol(); |
1503 } else { | 1507 } else { |
1504 ReportUnexpectedToken(next); | 1508 ReportUnexpectedToken(next); |
1505 *ok = false; | 1509 *ok = false; |
1506 return Identifier::Default(); | 1510 return Identifier::Default(); |
1507 } | 1511 } |
1508 } | 1512 } |
1509 | 1513 |
1510 | 1514 |
1511 void PreParser::SetStrictModeViolation(Scanner::Location location, | 1515 void PreParser::SetStrictModeViolation(Scanner::Location location, |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1624 ASSERT(IsAccessorAccessorConflict(old_type, type)); | 1628 ASSERT(IsAccessorAccessorConflict(old_type, type)); |
1625 // Both accessors of the same type. | 1629 // Both accessors of the same type. |
1626 parser()->ReportMessageAt(scanner()->location(), | 1630 parser()->ReportMessageAt(scanner()->location(), |
1627 "accessor_get_set"); | 1631 "accessor_get_set"); |
1628 } | 1632 } |
1629 *ok = false; | 1633 *ok = false; |
1630 } | 1634 } |
1631 } | 1635 } |
1632 | 1636 |
1633 } } // v8::internal | 1637 } } // v8::internal |
OLD | NEW |