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

Side by Side Diff: src/parser.cc

Issue 1070633002: [strong] Implement static restrictions on binding/assignment to 'undefined' identifier. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: improve tests (rebase, only undefined.js has changed) Created 5 years, 8 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
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/api.h" 7 #include "src/api.h"
8 #include "src/ast.h" 8 #include "src/ast.h"
9 #include "src/bailout-reason.h" 9 #include "src/bailout-reason.h"
10 #include "src/base/platform/platform.h" 10 #include "src/base/platform/platform.h"
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 458
459 bool ParserTraits::IsArguments(const AstRawString* identifier) const { 459 bool ParserTraits::IsArguments(const AstRawString* identifier) const {
460 return identifier == parser_->ast_value_factory()->arguments_string(); 460 return identifier == parser_->ast_value_factory()->arguments_string();
461 } 461 }
462 462
463 463
464 bool ParserTraits::IsEvalOrArguments(const AstRawString* identifier) const { 464 bool ParserTraits::IsEvalOrArguments(const AstRawString* identifier) const {
465 return IsEval(identifier) || IsArguments(identifier); 465 return IsEval(identifier) || IsArguments(identifier);
466 } 466 }
467 467
468 bool ParserTraits::IsUndefined(const AstRawString* identifier) const {
469 return identifier == parser_->ast_value_factory()->undefined_string();
470 }
468 471
469 bool ParserTraits::IsPrototype(const AstRawString* identifier) const { 472 bool ParserTraits::IsPrototype(const AstRawString* identifier) const {
470 return identifier == parser_->ast_value_factory()->prototype_string(); 473 return identifier == parser_->ast_value_factory()->prototype_string();
471 } 474 }
472 475
473 476
474 bool ParserTraits::IsConstructor(const AstRawString* identifier) const { 477 bool ParserTraits::IsConstructor(const AstRawString* identifier) const {
475 return identifier == parser_->ast_value_factory()->constructor_string(); 478 return identifier == parser_->ast_value_factory()->constructor_string();
476 } 479 }
477 480
(...skipping 990 matching lines...) Expand 10 before | Expand all | Expand 10 after
1468 local_name = ParseIdentifierName(CHECK_OK); 1471 local_name = ParseIdentifierName(CHECK_OK);
1469 } 1472 }
1470 if (!Token::IsIdentifier(scanner()->current_token(), STRICT, false)) { 1473 if (!Token::IsIdentifier(scanner()->current_token(), STRICT, false)) {
1471 *ok = false; 1474 *ok = false;
1472 ReportMessage("unexpected_reserved"); 1475 ReportMessage("unexpected_reserved");
1473 return NULL; 1476 return NULL;
1474 } else if (IsEvalOrArguments(local_name)) { 1477 } else if (IsEvalOrArguments(local_name)) {
1475 *ok = false; 1478 *ok = false;
1476 ReportMessage("strict_eval_arguments"); 1479 ReportMessage("strict_eval_arguments");
1477 return NULL; 1480 return NULL;
1481 } else if (is_strong(language_mode()) && IsUndefined(local_name)) {
1482 *ok = false;
1483 ReportMessage("strong_undefined");
1484 return NULL;
1478 } 1485 }
1479 VariableProxy* proxy = NewUnresolved(local_name, IMPORT); 1486 VariableProxy* proxy = NewUnresolved(local_name, IMPORT);
1480 ImportDeclaration* declaration = 1487 ImportDeclaration* declaration =
1481 factory()->NewImportDeclaration(proxy, import_name, NULL, scope_, pos); 1488 factory()->NewImportDeclaration(proxy, import_name, NULL, scope_, pos);
1482 Declare(declaration, true, CHECK_OK); 1489 Declare(declaration, true, CHECK_OK);
1483 result->Add(declaration, zone()); 1490 result->Add(declaration, zone());
1484 if (peek() == Token::RBRACE) break; 1491 if (peek() == Token::RBRACE) break;
1485 Expect(Token::COMMA, CHECK_OK); 1492 Expect(Token::COMMA, CHECK_OK);
1486 } 1493 }
1487 1494
(...skipping 29 matching lines...) Expand all
1517 ExpectSemicolon(CHECK_OK); 1524 ExpectSemicolon(CHECK_OK);
1518 // TODO(ES6): Add module to the requested modules of scope_->module(). 1525 // TODO(ES6): Add module to the requested modules of scope_->module().
1519 USE(module_specifier); 1526 USE(module_specifier);
1520 return factory()->NewEmptyStatement(pos); 1527 return factory()->NewEmptyStatement(pos);
1521 } 1528 }
1522 1529
1523 // Parse ImportedDefaultBinding if present. 1530 // Parse ImportedDefaultBinding if present.
1524 ImportDeclaration* import_default_declaration = NULL; 1531 ImportDeclaration* import_default_declaration = NULL;
1525 if (tok != Token::MUL && tok != Token::LBRACE) { 1532 if (tok != Token::MUL && tok != Token::LBRACE) {
1526 const AstRawString* local_name = 1533 const AstRawString* local_name =
1527 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); 1534 ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK);
1528 VariableProxy* proxy = NewUnresolved(local_name, IMPORT); 1535 VariableProxy* proxy = NewUnresolved(local_name, IMPORT);
1529 import_default_declaration = factory()->NewImportDeclaration( 1536 import_default_declaration = factory()->NewImportDeclaration(
1530 proxy, ast_value_factory()->default_string(), NULL, scope_, pos); 1537 proxy, ast_value_factory()->default_string(), NULL, scope_, pos);
1531 Declare(import_default_declaration, true, CHECK_OK); 1538 Declare(import_default_declaration, true, CHECK_OK);
1532 } 1539 }
1533 1540
1534 const AstRawString* module_instance_binding = NULL; 1541 const AstRawString* module_instance_binding = NULL;
1535 ZoneList<ImportDeclaration*>* named_declarations = NULL; 1542 ZoneList<ImportDeclaration*>* named_declarations = NULL;
1536 if (import_default_declaration == NULL || Check(Token::COMMA)) { 1543 if (import_default_declaration == NULL || Check(Token::COMMA)) {
1537 switch (peek()) { 1544 switch (peek()) {
1538 case Token::MUL: { 1545 case Token::MUL: {
1539 Consume(Token::MUL); 1546 Consume(Token::MUL);
1540 ExpectContextualKeyword(CStrVector("as"), CHECK_OK); 1547 ExpectContextualKeyword(CStrVector("as"), CHECK_OK);
1541 module_instance_binding = 1548 module_instance_binding =
1542 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); 1549 ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK);
1543 // TODO(ES6): Add an appropriate declaration. 1550 // TODO(ES6): Add an appropriate declaration.
1544 break; 1551 break;
1545 } 1552 }
1546 1553
1547 case Token::LBRACE: 1554 case Token::LBRACE:
1548 named_declarations = ParseNamedImports(pos, CHECK_OK); 1555 named_declarations = ParseNamedImports(pos, CHECK_OK);
1549 break; 1556 break;
1550 1557
1551 default: 1558 default:
1552 *ok = false; 1559 *ok = false;
(...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after
2021 2028
2022 2029
2023 // Language extension which is only enabled for source files loaded 2030 // Language extension which is only enabled for source files loaded
2024 // through the API's extension mechanism. A native function 2031 // through the API's extension mechanism. A native function
2025 // declaration is resolved by looking up the function through a 2032 // declaration is resolved by looking up the function through a
2026 // callback provided by the extension. 2033 // callback provided by the extension.
2027 Statement* Parser::ParseNativeDeclaration(bool* ok) { 2034 Statement* Parser::ParseNativeDeclaration(bool* ok) {
2028 int pos = peek_position(); 2035 int pos = peek_position();
2029 Expect(Token::FUNCTION, CHECK_OK); 2036 Expect(Token::FUNCTION, CHECK_OK);
2030 // Allow "eval" or "arguments" for backward compatibility. 2037 // Allow "eval" or "arguments" for backward compatibility.
2031 const AstRawString* name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); 2038 const AstRawString* name =
2039 ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
2032 Expect(Token::LPAREN, CHECK_OK); 2040 Expect(Token::LPAREN, CHECK_OK);
2033 bool done = (peek() == Token::RPAREN); 2041 bool done = (peek() == Token::RPAREN);
2034 while (!done) { 2042 while (!done) {
2035 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); 2043 ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
2036 done = (peek() == Token::RPAREN); 2044 done = (peek() == Token::RPAREN);
2037 if (!done) { 2045 if (!done) {
2038 Expect(Token::COMMA, CHECK_OK); 2046 Expect(Token::COMMA, CHECK_OK);
2039 } 2047 }
2040 } 2048 }
2041 Expect(Token::RPAREN, CHECK_OK); 2049 Expect(Token::RPAREN, CHECK_OK);
2042 Expect(Token::SEMICOLON, CHECK_OK); 2050 Expect(Token::SEMICOLON, CHECK_OK);
2043 2051
2044 // Make sure that the function containing the native declaration 2052 // Make sure that the function containing the native declaration
2045 // isn't lazily compiled. The extension structures are only 2053 // isn't lazily compiled. The extension structures are only
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
2307 int nvars = 0; // the number of variables declared 2315 int nvars = 0; // the number of variables declared
2308 int bindings_start = peek_position(); 2316 int bindings_start = peek_position();
2309 const AstRawString* name = NULL; 2317 const AstRawString* name = NULL;
2310 const AstRawString* first_name = NULL; 2318 const AstRawString* first_name = NULL;
2311 bool is_for_iteration_variable; 2319 bool is_for_iteration_variable;
2312 do { 2320 do {
2313 if (fni_ != NULL) fni_->Enter(); 2321 if (fni_ != NULL) fni_->Enter();
2314 2322
2315 // Parse variable name. 2323 // Parse variable name.
2316 if (nvars > 0) Consume(Token::COMMA); 2324 if (nvars > 0) Consume(Token::COMMA);
2317 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); 2325 name = ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK);
2318 if (!first_name) first_name = name; 2326 if (!first_name) first_name = name;
2319 Scanner::Location variable_loc = scanner()->location(); 2327 Scanner::Location variable_loc = scanner()->location();
2320 if (fni_ != NULL) fni_->PushVariableName(name); 2328 if (fni_ != NULL) fni_->PushVariableName(name);
2321 2329
2322 // Declare variable. 2330 // Declare variable.
2323 // Note that we *always* must treat the initial value via a separate init 2331 // Note that we *always* must treat the initial value via a separate init
2324 // assignment for variables and constants because the value must be assigned 2332 // assignment for variables and constants because the value must be assigned
2325 // when the variable is encountered in the source. But the variable/constant 2333 // when the variable is encountered in the source. But the variable/constant
2326 // is declared (and set to 'undefined') upon entering the function within 2334 // is declared (and set to 'undefined') upon entering the function within
2327 // which the variable or constant is declared. Only function variables have 2335 // which the variable or constant is declared. Only function variables have
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after
2659 // ContinueStatement :: 2667 // ContinueStatement ::
2660 // 'continue' Identifier? ';' 2668 // 'continue' Identifier? ';'
2661 2669
2662 int pos = peek_position(); 2670 int pos = peek_position();
2663 Expect(Token::CONTINUE, CHECK_OK); 2671 Expect(Token::CONTINUE, CHECK_OK);
2664 const AstRawString* label = NULL; 2672 const AstRawString* label = NULL;
2665 Token::Value tok = peek(); 2673 Token::Value tok = peek();
2666 if (!scanner()->HasAnyLineTerminatorBeforeNext() && 2674 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
2667 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { 2675 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
2668 // ECMA allows "eval" or "arguments" as labels even in strict mode. 2676 // ECMA allows "eval" or "arguments" as labels even in strict mode.
2669 label = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); 2677 label = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
2670 } 2678 }
2671 IterationStatement* target = LookupContinueTarget(label, CHECK_OK); 2679 IterationStatement* target = LookupContinueTarget(label, CHECK_OK);
2672 if (target == NULL) { 2680 if (target == NULL) {
2673 // Illegal continue statement. 2681 // Illegal continue statement.
2674 const char* message = "illegal_continue"; 2682 const char* message = "illegal_continue";
2675 if (label != NULL) { 2683 if (label != NULL) {
2676 message = "unknown_label"; 2684 message = "unknown_label";
2677 } 2685 }
2678 ParserTraits::ReportMessage(message, label); 2686 ParserTraits::ReportMessage(message, label);
2679 *ok = false; 2687 *ok = false;
2680 return NULL; 2688 return NULL;
2681 } 2689 }
2682 ExpectSemicolon(CHECK_OK); 2690 ExpectSemicolon(CHECK_OK);
2683 return factory()->NewContinueStatement(target, pos); 2691 return factory()->NewContinueStatement(target, pos);
2684 } 2692 }
2685 2693
2686 2694
2687 Statement* Parser::ParseBreakStatement(ZoneList<const AstRawString*>* labels, 2695 Statement* Parser::ParseBreakStatement(ZoneList<const AstRawString*>* labels,
2688 bool* ok) { 2696 bool* ok) {
2689 // BreakStatement :: 2697 // BreakStatement ::
2690 // 'break' Identifier? ';' 2698 // 'break' Identifier? ';'
2691 2699
2692 int pos = peek_position(); 2700 int pos = peek_position();
2693 Expect(Token::BREAK, CHECK_OK); 2701 Expect(Token::BREAK, CHECK_OK);
2694 const AstRawString* label = NULL; 2702 const AstRawString* label = NULL;
2695 Token::Value tok = peek(); 2703 Token::Value tok = peek();
2696 if (!scanner()->HasAnyLineTerminatorBeforeNext() && 2704 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
2697 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { 2705 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
2698 // ECMA allows "eval" or "arguments" as labels even in strict mode. 2706 // ECMA allows "eval" or "arguments" as labels even in strict mode.
2699 label = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); 2707 label = ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
2700 } 2708 }
2701 // Parse labeled break statements that target themselves into 2709 // Parse labeled break statements that target themselves into
2702 // empty statements, e.g. 'l1: l2: l3: break l2;' 2710 // empty statements, e.g. 'l1: l2: l3: break l2;'
2703 if (label != NULL && ContainsLabel(labels, label)) { 2711 if (label != NULL && ContainsLabel(labels, label)) {
2704 ExpectSemicolon(CHECK_OK); 2712 ExpectSemicolon(CHECK_OK);
2705 return factory()->NewEmptyStatement(pos); 2713 return factory()->NewEmptyStatement(pos);
2706 } 2714 }
2707 BreakableStatement* target = NULL; 2715 BreakableStatement* target = NULL;
2708 target = LookupBreakTarget(label, CHECK_OK); 2716 target = LookupBreakTarget(label, CHECK_OK);
2709 if (target == NULL) { 2717 if (target == NULL) {
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
2914 Scope* catch_scope = NULL; 2922 Scope* catch_scope = NULL;
2915 Variable* catch_variable = NULL; 2923 Variable* catch_variable = NULL;
2916 Block* catch_block = NULL; 2924 Block* catch_block = NULL;
2917 const AstRawString* name = NULL; 2925 const AstRawString* name = NULL;
2918 if (tok == Token::CATCH) { 2926 if (tok == Token::CATCH) {
2919 Consume(Token::CATCH); 2927 Consume(Token::CATCH);
2920 2928
2921 Expect(Token::LPAREN, CHECK_OK); 2929 Expect(Token::LPAREN, CHECK_OK);
2922 catch_scope = NewScope(scope_, CATCH_SCOPE); 2930 catch_scope = NewScope(scope_, CATCH_SCOPE);
2923 catch_scope->set_start_position(scanner()->location().beg_pos); 2931 catch_scope->set_start_position(scanner()->location().beg_pos);
2924 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); 2932 name = ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK);
2925 2933
2926 Expect(Token::RPAREN, CHECK_OK); 2934 Expect(Token::RPAREN, CHECK_OK);
2927 2935
2928 catch_variable = catch_scope->DeclareLocal(name, VAR, kCreatedInitialized, 2936 catch_variable = catch_scope->DeclareLocal(name, VAR, kCreatedInitialized,
2929 Variable::NORMAL); 2937 Variable::NORMAL);
2930 BlockState block_state(&scope_, catch_scope); 2938 BlockState block_state(&scope_, catch_scope);
2931 catch_block = ParseBlock(NULL, CHECK_OK); 2939 catch_block = ParseBlock(NULL, CHECK_OK);
2932 2940
2933 catch_scope->set_end_position(scanner()->location().end_pos); 2941 catch_scope->set_end_position(scanner()->location().end_pos);
2934 tok = peek(); 2942 tok = peek();
(...skipping 926 matching lines...) Expand 10 before | Expand all | Expand 10 after
3861 Expect(Token::LPAREN, CHECK_OK); 3869 Expect(Token::LPAREN, CHECK_OK);
3862 scope->set_start_position(scanner()->location().beg_pos); 3870 scope->set_start_position(scanner()->location().beg_pos);
3863 3871
3864 // We don't yet know if the function will be strict, so we cannot yet 3872 // We don't yet know if the function will be strict, so we cannot yet
3865 // produce errors for parameter names or duplicates. However, we remember 3873 // produce errors for parameter names or duplicates. However, we remember
3866 // the locations of these errors if they occur and produce the errors later. 3874 // the locations of these errors if they occur and produce the errors later.
3867 Scanner::Location eval_args_error_loc = Scanner::Location::invalid(); 3875 Scanner::Location eval_args_error_loc = Scanner::Location::invalid();
3868 Scanner::Location dupe_error_loc = Scanner::Location::invalid(); 3876 Scanner::Location dupe_error_loc = Scanner::Location::invalid();
3869 Scanner::Location reserved_error_loc = Scanner::Location::invalid(); 3877 Scanner::Location reserved_error_loc = Scanner::Location::invalid();
3870 3878
3879 // Similarly for strong mode.
3880 Scanner::Location undefined_error_loc = Scanner::Location::invalid();
3881
3871 bool is_rest = false; 3882 bool is_rest = false;
3872 bool done = arity_restriction == FunctionLiteral::GETTER_ARITY || 3883 bool done = arity_restriction == FunctionLiteral::GETTER_ARITY ||
3873 (peek() == Token::RPAREN && 3884 (peek() == Token::RPAREN &&
3874 arity_restriction != FunctionLiteral::SETTER_ARITY); 3885 arity_restriction != FunctionLiteral::SETTER_ARITY);
3875 while (!done) { 3886 while (!done) {
3876 bool is_strict_reserved = false; 3887 bool is_strict_reserved = false;
3877 is_rest = peek() == Token::ELLIPSIS && allow_harmony_rest_params(); 3888 is_rest = peek() == Token::ELLIPSIS && allow_harmony_rest_params();
3878 if (is_rest) { 3889 if (is_rest) {
3879 Consume(Token::ELLIPSIS); 3890 Consume(Token::ELLIPSIS);
3880 } 3891 }
3881 3892
3882 const AstRawString* param_name = 3893 const AstRawString* param_name =
3883 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); 3894 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
3884 3895
3885 // Store locations for possible future error reports. 3896 // Store locations for possible future error reports.
3886 if (!eval_args_error_loc.IsValid() && IsEvalOrArguments(param_name)) { 3897 if (!eval_args_error_loc.IsValid() && IsEvalOrArguments(param_name)) {
3887 eval_args_error_loc = scanner()->location(); 3898 eval_args_error_loc = scanner()->location();
3888 } 3899 }
3900 if (!undefined_error_loc.IsValid() && IsUndefined(param_name)) {
3901 undefined_error_loc = scanner()->location();
3902 }
3889 if (!reserved_error_loc.IsValid() && is_strict_reserved) { 3903 if (!reserved_error_loc.IsValid() && is_strict_reserved) {
3890 reserved_error_loc = scanner()->location(); 3904 reserved_error_loc = scanner()->location();
3891 } 3905 }
3892 if (!dupe_error_loc.IsValid() && 3906 if (!dupe_error_loc.IsValid() &&
3893 scope_->IsDeclaredParameter(param_name)) { 3907 scope_->IsDeclaredParameter(param_name)) {
3894 duplicate_parameters = FunctionLiteral::kHasDuplicateParameters; 3908 duplicate_parameters = FunctionLiteral::kHasDuplicateParameters;
3895 dupe_error_loc = scanner()->location(); 3909 dupe_error_loc = scanner()->location();
3896 } 3910 }
3897 3911
3898 Variable* var = scope_->DeclareParameter(param_name, VAR, is_rest); 3912 Variable* var = scope_->DeclareParameter(param_name, VAR, is_rest);
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
3997 handler_count = function_state.handler_count(); 4011 handler_count = function_state.handler_count();
3998 } 4012 }
3999 4013
4000 // Validate name and parameter names. We can do this only after parsing the 4014 // Validate name and parameter names. We can do this only after parsing the
4001 // function, since the function can declare itself strict. 4015 // function, since the function can declare itself strict.
4002 CheckFunctionName(language_mode(), kind, function_name, 4016 CheckFunctionName(language_mode(), kind, function_name,
4003 name_is_strict_reserved, function_name_location, 4017 name_is_strict_reserved, function_name_location,
4004 CHECK_OK); 4018 CHECK_OK);
4005 const bool use_strict_params = is_rest || IsConciseMethod(kind); 4019 const bool use_strict_params = is_rest || IsConciseMethod(kind);
4006 CheckFunctionParameterNames(language_mode(), use_strict_params, 4020 CheckFunctionParameterNames(language_mode(), use_strict_params,
4007 eval_args_error_loc, dupe_error_loc, 4021 eval_args_error_loc, undefined_error_loc,
4008 reserved_error_loc, CHECK_OK); 4022 dupe_error_loc, reserved_error_loc, CHECK_OK);
4009 4023
4010 if (is_strict(language_mode())) { 4024 if (is_strict(language_mode())) {
4011 CheckStrictOctalLiteral(scope->start_position(), scope->end_position(), 4025 CheckStrictOctalLiteral(scope->start_position(), scope->end_position(),
4012 CHECK_OK); 4026 CHECK_OK);
4013 } 4027 }
4014 if (is_strict(language_mode())) { 4028 if (is_strict(language_mode())) {
4015 CheckConflictingVarDeclarations(scope, CHECK_OK); 4029 CheckConflictingVarDeclarations(scope, CHECK_OK);
4016 } 4030 }
4017 if (is_strong(language_mode()) && IsSubclassConstructor(kind)) { 4031 if (is_strong(language_mode()) && IsSubclassConstructor(kind)) {
4018 if (!function_state.super_call_location().IsValid()) { 4032 if (!function_state.super_call_location().IsValid()) {
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
4250 if (name_is_strict_reserved) { 4264 if (name_is_strict_reserved) {
4251 ReportMessageAt(class_name_location, "unexpected_strict_reserved"); 4265 ReportMessageAt(class_name_location, "unexpected_strict_reserved");
4252 *ok = false; 4266 *ok = false;
4253 return NULL; 4267 return NULL;
4254 } 4268 }
4255 if (IsEvalOrArguments(name)) { 4269 if (IsEvalOrArguments(name)) {
4256 ReportMessageAt(class_name_location, "strict_eval_arguments"); 4270 ReportMessageAt(class_name_location, "strict_eval_arguments");
4257 *ok = false; 4271 *ok = false;
4258 return NULL; 4272 return NULL;
4259 } 4273 }
4274 if (is_strong(language_mode()) && IsUndefined(name)) {
4275 ReportMessageAt(class_name_location, "strong_undefined");
4276 *ok = false;
4277 return NULL;
4278 }
4260 4279
4261 // Create a block scope which is additionally tagged as class scope; this is 4280 // Create a block scope which is additionally tagged as class scope; this is
4262 // important for resolving variable references to the class name in the strong 4281 // important for resolving variable references to the class name in the strong
4263 // mode. 4282 // mode.
4264 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE); 4283 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE);
4265 block_scope->tag_as_class_scope(); 4284 block_scope->tag_as_class_scope();
4266 BlockState block_state(&scope_, block_scope); 4285 BlockState block_state(&scope_, block_scope);
4267 scope_->SetLanguageMode( 4286 scope_->SetLanguageMode(
4268 static_cast<LanguageMode>(scope_->language_mode() | STRICT_BIT)); 4287 static_cast<LanguageMode>(scope_->language_mode() | STRICT_BIT));
4269 scope_->SetScopeName(name); 4288 scope_->SetScopeName(name);
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
4341 } 4360 }
4342 4361
4343 4362
4344 Expression* Parser::ParseV8Intrinsic(bool* ok) { 4363 Expression* Parser::ParseV8Intrinsic(bool* ok) {
4345 // CallRuntime :: 4364 // CallRuntime ::
4346 // '%' Identifier Arguments 4365 // '%' Identifier Arguments
4347 4366
4348 int pos = peek_position(); 4367 int pos = peek_position();
4349 Expect(Token::MOD, CHECK_OK); 4368 Expect(Token::MOD, CHECK_OK);
4350 // Allow "eval" or "arguments" for backward compatibility. 4369 // Allow "eval" or "arguments" for backward compatibility.
4351 const AstRawString* name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); 4370 const AstRawString* name =
4371 ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
4352 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); 4372 ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
4353 4373
4354 if (extension_ != NULL) { 4374 if (extension_ != NULL) {
4355 // The extension structures are only accessible while parsing the 4375 // The extension structures are only accessible while parsing the
4356 // very first time not when reparsing because of lazy compilation. 4376 // very first time not when reparsing because of lazy compilation.
4357 scope_->DeclarationScope()->ForceEagerCompilation(); 4377 scope_->DeclarationScope()->ForceEagerCompilation();
4358 } 4378 }
4359 4379
4360 const Runtime::Function* function = Runtime::FunctionForName(name->string()); 4380 const Runtime::Function* function = Runtime::FunctionForName(name->string());
4361 4381
(...skipping 1246 matching lines...) Expand 10 before | Expand all | Expand 10 after
5608 } else { 5628 } else {
5609 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data()); 5629 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data());
5610 running_hash = StringHasher::ComputeRunningHash(running_hash, data, 5630 running_hash = StringHasher::ComputeRunningHash(running_hash, data,
5611 raw_string->length()); 5631 raw_string->length());
5612 } 5632 }
5613 } 5633 }
5614 5634
5615 return running_hash; 5635 return running_hash;
5616 } 5636 }
5617 } } // namespace v8::internal 5637 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/parser.h ('k') | src/preparser.h » ('j') | test/mjsunit/strong/undefined.js » ('J')

Powered by Google App Engine
This is Rietveld 408576698