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