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

Side by Side Diff: src/parsing/parser.cc

Issue 1858943002: Remove runtime flags for sloppy mode block scoping features (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebased Created 4 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
« no previous file with comments | « src/messages.h ('k') | src/parsing/parser-base.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/parsing/parser.h" 5 #include "src/parsing/parser.h"
6 6
7 #include "src/api.h" 7 #include "src/api.h"
8 #include "src/ast/ast.h" 8 #include "src/ast/ast.h"
9 #include "src/ast/ast-expression-rewriter.h" 9 #include "src/ast/ast-expression-rewriter.h"
10 #include "src/ast/ast-expression-visitor.h" 10 #include "src/ast/ast-expression-visitor.h"
(...skipping 768 matching lines...) Expand 10 before | Expand all | Expand 10 after
779 pre_parse_timer_(NULL), 779 pre_parse_timer_(NULL),
780 parsing_on_main_thread_(true) { 780 parsing_on_main_thread_(true) {
781 // Even though we were passed ParseInfo, we should not store it in 781 // Even though we were passed ParseInfo, we should not store it in
782 // Parser - this makes sure that Isolate is not accidentally accessed via 782 // Parser - this makes sure that Isolate is not accidentally accessed via
783 // ParseInfo during background parsing. 783 // ParseInfo during background parsing.
784 DCHECK(!info->script().is_null() || info->source_stream() != NULL); 784 DCHECK(!info->script().is_null() || info->source_stream() != NULL);
785 set_allow_lazy(info->allow_lazy_parsing()); 785 set_allow_lazy(info->allow_lazy_parsing());
786 set_allow_natives(FLAG_allow_natives_syntax || info->is_native()); 786 set_allow_natives(FLAG_allow_natives_syntax || info->is_native());
787 set_allow_tailcalls(FLAG_harmony_tailcalls && !info->is_native() && 787 set_allow_tailcalls(FLAG_harmony_tailcalls && !info->is_native() &&
788 info->isolate()->is_tail_call_elimination_enabled()); 788 info->isolate()->is_tail_call_elimination_enabled());
789 set_allow_harmony_sloppy(FLAG_harmony_sloppy);
790 set_allow_harmony_sloppy_function(FLAG_harmony_sloppy_function);
791 set_allow_harmony_sloppy_let(FLAG_harmony_sloppy_let);
792 set_allow_harmony_do_expressions(FLAG_harmony_do_expressions); 789 set_allow_harmony_do_expressions(FLAG_harmony_do_expressions);
793 set_allow_harmony_function_name(FLAG_harmony_function_name); 790 set_allow_harmony_function_name(FLAG_harmony_function_name);
794 set_allow_harmony_function_sent(FLAG_harmony_function_sent); 791 set_allow_harmony_function_sent(FLAG_harmony_function_sent);
795 set_allow_harmony_restrictive_declarations( 792 set_allow_harmony_restrictive_declarations(
796 FLAG_harmony_restrictive_declarations); 793 FLAG_harmony_restrictive_declarations);
797 set_allow_harmony_exponentiation_operator( 794 set_allow_harmony_exponentiation_operator(
798 FLAG_harmony_exponentiation_operator); 795 FLAG_harmony_exponentiation_operator);
799 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; 796 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
800 ++feature) { 797 ++feature) {
801 use_counts_[feature] = 0; 798 use_counts_[feature] = 0;
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
934 ParseStatementList(body, Token::EOS, &ok); 931 ParseStatementList(body, Token::EOS, &ok);
935 } 932 }
936 933
937 // The parser will peek but not consume EOS. Our scope logically goes all 934 // The parser will peek but not consume EOS. Our scope logically goes all
938 // the way to the EOS, though. 935 // the way to the EOS, though.
939 scope->set_end_position(scanner()->peek_location().beg_pos); 936 scope->set_end_position(scanner()->peek_location().beg_pos);
940 937
941 if (ok && is_strict(language_mode())) { 938 if (ok && is_strict(language_mode())) {
942 CheckStrictOctalLiteral(beg_pos, scanner()->location().end_pos, &ok); 939 CheckStrictOctalLiteral(beg_pos, scanner()->location().end_pos, &ok);
943 } 940 }
944 if (ok && is_sloppy(language_mode()) && allow_harmony_sloppy_function()) { 941 if (ok && is_sloppy(language_mode())) {
945 // TODO(littledan): Function bindings on the global object that modify 942 // TODO(littledan): Function bindings on the global object that modify
946 // pre-existing bindings should be made writable, enumerable and 943 // pre-existing bindings should be made writable, enumerable and
947 // nonconfigurable if possible, whereas this code will leave attributes 944 // nonconfigurable if possible, whereas this code will leave attributes
948 // unchanged if the property already exists. 945 // unchanged if the property already exists.
949 InsertSloppyBlockFunctionVarBindings(scope, &ok); 946 InsertSloppyBlockFunctionVarBindings(scope, &ok);
950 } 947 }
951 if (ok) { 948 if (ok) {
952 CheckConflictingVarDeclarations(scope_, &ok); 949 CheckConflictingVarDeclarations(scope_, &ok);
953 } 950 }
954 951
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after
1251 // Statement 1248 // Statement
1252 // Declaration 1249 // Declaration
1253 1250
1254 switch (peek()) { 1251 switch (peek()) {
1255 case Token::FUNCTION: 1252 case Token::FUNCTION:
1256 return ParseFunctionDeclaration(NULL, ok); 1253 return ParseFunctionDeclaration(NULL, ok);
1257 case Token::CLASS: 1254 case Token::CLASS:
1258 Consume(Token::CLASS); 1255 Consume(Token::CLASS);
1259 return ParseClassDeclaration(NULL, ok); 1256 return ParseClassDeclaration(NULL, ok);
1260 case Token::CONST: 1257 case Token::CONST:
1261 if (allow_const()) { 1258 return ParseVariableStatement(kStatementListItem, NULL, ok);
1262 return ParseVariableStatement(kStatementListItem, NULL, ok);
1263 }
1264 break;
1265 case Token::VAR: 1259 case Token::VAR:
1266 return ParseVariableStatement(kStatementListItem, NULL, ok); 1260 return ParseVariableStatement(kStatementListItem, NULL, ok);
1267 case Token::LET: 1261 case Token::LET:
1268 if (IsNextLetKeyword()) { 1262 if (IsNextLetKeyword()) {
1269 return ParseVariableStatement(kStatementListItem, NULL, ok); 1263 return ParseVariableStatement(kStatementListItem, NULL, ok);
1270 } 1264 }
1271 break; 1265 break;
1272 default: 1266 default:
1273 break; 1267 break;
1274 } 1268 }
(...skipping 627 matching lines...) Expand 10 before | Expand all | Expand 10 after
1902 // Declare the variable in the declaration scope. 1896 // Declare the variable in the declaration scope.
1903 var = declaration_scope->LookupLocal(name); 1897 var = declaration_scope->LookupLocal(name);
1904 if (var == NULL) { 1898 if (var == NULL) {
1905 // Declare the name. 1899 // Declare the name.
1906 Variable::Kind kind = Variable::NORMAL; 1900 Variable::Kind kind = Variable::NORMAL;
1907 if (is_function_declaration) { 1901 if (is_function_declaration) {
1908 kind = Variable::FUNCTION; 1902 kind = Variable::FUNCTION;
1909 } 1903 }
1910 var = declaration_scope->DeclareLocal( 1904 var = declaration_scope->DeclareLocal(
1911 name, mode, declaration->initialization(), kind, kNotAssigned); 1905 name, mode, declaration->initialization(), kind, kNotAssigned);
1912 } else if ((IsLexicalVariableMode(mode) || 1906 } else if (IsLexicalVariableMode(mode) ||
1913 IsLexicalVariableMode(var->mode())) && 1907 IsLexicalVariableMode(var->mode())) {
1914 // Lexical bindings may appear for some parameters in sloppy
1915 // mode even with --harmony-sloppy off.
1916 (is_strict(language_mode()) || allow_harmony_sloppy())) {
1917 // Allow duplicate function decls for web compat, see bug 4693. 1908 // Allow duplicate function decls for web compat, see bug 4693.
1918 if (is_sloppy(language_mode()) && is_function_declaration && 1909 if (is_sloppy(language_mode()) && is_function_declaration &&
1919 var->is_function()) { 1910 var->is_function()) {
1920 DCHECK(IsLexicalVariableMode(mode) && 1911 DCHECK(IsLexicalVariableMode(mode) &&
1921 IsLexicalVariableMode(var->mode())); 1912 IsLexicalVariableMode(var->mode()));
1922 ++use_counts_[v8::Isolate::kSloppyModeBlockScopedFunctionRedefinition]; 1913 ++use_counts_[v8::Isolate::kSloppyModeBlockScopedFunctionRedefinition];
1923 } else { 1914 } else {
1924 // The name was declared in this scope before; check for conflicting 1915 // The name was declared in this scope before; check for conflicting
1925 // re-declarations. We have a conflict if either of the declarations 1916 // re-declarations. We have a conflict if either of the declarations
1926 // is not a var (in script scope, we also have to ignore legacy const 1917 // is not a var (in script scope, we also have to ignore legacy const
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
2096 : kFunctionNameValidityUnknown, 2087 : kFunctionNameValidityUnknown,
2097 is_generator ? FunctionKind::kGeneratorFunction 2088 is_generator ? FunctionKind::kGeneratorFunction
2098 : FunctionKind::kNormalFunction, 2089 : FunctionKind::kNormalFunction,
2099 pos, FunctionLiteral::kDeclaration, language_mode(), CHECK_OK); 2090 pos, FunctionLiteral::kDeclaration, language_mode(), CHECK_OK);
2100 2091
2101 // Even if we're not at the top-level of the global or a function 2092 // Even if we're not at the top-level of the global or a function
2102 // scope, we treat it as such and introduce the function with its 2093 // scope, we treat it as such and introduce the function with its
2103 // initial value upon entering the corresponding scope. 2094 // initial value upon entering the corresponding scope.
2104 // In ES6, a function behaves as a lexical binding, except in 2095 // In ES6, a function behaves as a lexical binding, except in
2105 // a script scope, or the initial scope of eval or another function. 2096 // a script scope, or the initial scope of eval or another function.
2106 VariableMode mode = 2097 VariableMode mode = !scope_->is_declaration_scope() ? LET : VAR;
2107 (is_strict(language_mode()) || allow_harmony_sloppy_function()) &&
2108 !scope_->is_declaration_scope()
2109 ? LET
2110 : VAR;
2111 VariableProxy* proxy = NewUnresolved(name, mode); 2098 VariableProxy* proxy = NewUnresolved(name, mode);
2112 Declaration* declaration = 2099 Declaration* declaration =
2113 factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos); 2100 factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos);
2114 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK); 2101 Declare(declaration, DeclarationDescriptor::NORMAL, true, CHECK_OK);
2115 if (names) names->Add(name, zone()); 2102 if (names) names->Add(name, zone());
2116 EmptyStatement* empty = factory()->NewEmptyStatement(RelocInfo::kNoPosition); 2103 EmptyStatement* empty = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
2117 if (is_sloppy(language_mode()) && allow_harmony_sloppy_function() && 2104 if (is_sloppy(language_mode()) && !scope_->is_declaration_scope()) {
2118 !scope_->is_declaration_scope()) {
2119 SloppyBlockFunctionStatement* delegate = 2105 SloppyBlockFunctionStatement* delegate =
2120 factory()->NewSloppyBlockFunctionStatement(empty, scope_); 2106 factory()->NewSloppyBlockFunctionStatement(empty, scope_);
2121 scope_->DeclarationScope()->sloppy_block_function_map()->Declare(name, 2107 scope_->DeclarationScope()->sloppy_block_function_map()->Declare(name,
2122 delegate); 2108 delegate);
2123 return delegate; 2109 return delegate;
2124 } 2110 }
2125 return empty; 2111 return empty;
2126 } 2112 }
2127 2113
2128 2114
2129 Statement* Parser::ParseClassDeclaration(ZoneList<const AstRawString*>* names, 2115 Statement* Parser::ParseClassDeclaration(ZoneList<const AstRawString*>* names,
2130 bool* ok) { 2116 bool* ok) {
2131 // ClassDeclaration :: 2117 // ClassDeclaration ::
2132 // 'class' Identifier ('extends' LeftHandExpression)? '{' ClassBody '}' 2118 // 'class' Identifier ('extends' LeftHandExpression)? '{' ClassBody '}'
2133 // 2119 //
2134 // 'class' is expected to be consumed by the caller. 2120 // 'class' is expected to be consumed by the caller.
2135 // 2121 //
2136 // A ClassDeclaration 2122 // A ClassDeclaration
2137 // 2123 //
2138 // class C { ... } 2124 // class C { ... }
2139 // 2125 //
2140 // has the same semantics as: 2126 // has the same semantics as:
2141 // 2127 //
2142 // let C = class C { ... }; 2128 // let C = class C { ... };
2143 // 2129 //
2144 // so rewrite it as such. 2130 // so rewrite it as such.
2145 2131
2146 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) {
2147 ReportMessage(MessageTemplate::kSloppyLexical);
2148 *ok = false;
2149 return NULL;
2150 }
2151
2152 int pos = position(); 2132 int pos = position();
2153 bool is_strict_reserved = false; 2133 bool is_strict_reserved = false;
2154 const AstRawString* name = 2134 const AstRawString* name =
2155 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); 2135 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
2156 ClassLiteral* value = ParseClassLiteral(name, scanner()->location(), 2136 ClassLiteral* value = ParseClassLiteral(name, scanner()->location(),
2157 is_strict_reserved, pos, CHECK_OK); 2137 is_strict_reserved, pos, CHECK_OK);
2158 2138
2159 VariableProxy* proxy = NewUnresolved(name, LET); 2139 VariableProxy* proxy = NewUnresolved(name, LET);
2160 Declaration* declaration = 2140 Declaration* declaration =
2161 factory()->NewVariableDeclaration(proxy, LET, scope_, pos); 2141 factory()->NewVariableDeclaration(proxy, LET, scope_, pos);
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
2272 parsing_result->descriptor.mode = VAR; 2252 parsing_result->descriptor.mode = VAR;
2273 2253
2274 Block* init_block = nullptr; 2254 Block* init_block = nullptr;
2275 if (var_context != kForStatement) { 2255 if (var_context != kForStatement) {
2276 init_block = factory()->NewBlock( 2256 init_block = factory()->NewBlock(
2277 NULL, 1, true, parsing_result->descriptor.declaration_pos); 2257 NULL, 1, true, parsing_result->descriptor.declaration_pos);
2278 } 2258 }
2279 2259
2280 if (peek() == Token::VAR) { 2260 if (peek() == Token::VAR) {
2281 Consume(Token::VAR); 2261 Consume(Token::VAR);
2282 } else if (peek() == Token::CONST && allow_const()) { 2262 } else if (peek() == Token::CONST) {
2283 Consume(Token::CONST); 2263 Consume(Token::CONST);
2284 DCHECK(is_strict(language_mode()) || allow_harmony_sloppy());
2285 DCHECK(var_context != kStatement); 2264 DCHECK(var_context != kStatement);
2286 parsing_result->descriptor.mode = CONST; 2265 parsing_result->descriptor.mode = CONST;
2287 } else if (peek() == Token::LET && allow_let()) { 2266 } else if (peek() == Token::LET) {
2288 Consume(Token::LET); 2267 Consume(Token::LET);
2289 DCHECK(var_context != kStatement); 2268 DCHECK(var_context != kStatement);
2290 parsing_result->descriptor.mode = LET; 2269 parsing_result->descriptor.mode = LET;
2291 } else { 2270 } else {
2292 UNREACHABLE(); // by current callers 2271 UNREACHABLE(); // by current callers
2293 } 2272 }
2294 2273
2295 parsing_result->descriptor.scope = scope_; 2274 parsing_result->descriptor.scope = scope_;
2296 parsing_result->descriptor.hoist_scope = nullptr; 2275 parsing_result->descriptor.hoist_scope = nullptr;
2297 2276
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
2486 if (extension_ != NULL && peek() == Token::FUNCTION && 2465 if (extension_ != NULL && peek() == Token::FUNCTION &&
2487 !scanner()->HasAnyLineTerminatorBeforeNext() && expr != NULL && 2466 !scanner()->HasAnyLineTerminatorBeforeNext() && expr != NULL &&
2488 expr->AsVariableProxy() != NULL && 2467 expr->AsVariableProxy() != NULL &&
2489 expr->AsVariableProxy()->raw_name() == 2468 expr->AsVariableProxy()->raw_name() ==
2490 ast_value_factory()->native_string() && 2469 ast_value_factory()->native_string() &&
2491 !scanner()->literal_contains_escapes()) { 2470 !scanner()->literal_contains_escapes()) {
2492 return ParseNativeDeclaration(ok); 2471 return ParseNativeDeclaration(ok);
2493 } 2472 }
2494 2473
2495 // Parsed expression statement, followed by semicolon. 2474 // Parsed expression statement, followed by semicolon.
2496 // Detect attempts at 'let' declarations in sloppy mode.
2497 if (!allow_harmony_sloppy_let() && peek() == Token::IDENTIFIER &&
2498 expr->AsVariableProxy() != NULL &&
2499 expr->AsVariableProxy()->raw_name() ==
2500 ast_value_factory()->let_string()) {
2501 ReportMessage(MessageTemplate::kSloppyLexical, NULL);
2502 *ok = false;
2503 return NULL;
2504 }
2505 ExpectSemicolon(CHECK_OK); 2475 ExpectSemicolon(CHECK_OK);
2506 return factory()->NewExpressionStatement(expr, pos); 2476 return factory()->NewExpressionStatement(expr, pos);
2507 } 2477 }
2508 2478
2509 2479
2510 IfStatement* Parser::ParseIfStatement(ZoneList<const AstRawString*>* labels, 2480 IfStatement* Parser::ParseIfStatement(ZoneList<const AstRawString*>* labels,
2511 bool* ok) { 2481 bool* ok) {
2512 // IfStatement :: 2482 // IfStatement ::
2513 // 'if' '(' Expression ')' Statement ('else' Statement)? 2483 // 'if' '(' Expression ')' Statement ('else' Statement)?
2514 2484
(...skipping 975 matching lines...) Expand 10 before | Expand all | Expand 10 after
3490 Statement* init = NULL; 3460 Statement* init = NULL;
3491 ZoneList<const AstRawString*> lexical_bindings(1, zone()); 3461 ZoneList<const AstRawString*> lexical_bindings(1, zone());
3492 3462
3493 // Create an in-between scope for let-bound iteration variables. 3463 // Create an in-between scope for let-bound iteration variables.
3494 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE); 3464 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE);
3495 3465
3496 BlockState block_state(&scope_, for_scope); 3466 BlockState block_state(&scope_, for_scope);
3497 Expect(Token::FOR, CHECK_OK); 3467 Expect(Token::FOR, CHECK_OK);
3498 Expect(Token::LPAREN, CHECK_OK); 3468 Expect(Token::LPAREN, CHECK_OK);
3499 for_scope->set_start_position(scanner()->location().beg_pos); 3469 for_scope->set_start_position(scanner()->location().beg_pos);
3500 bool is_let_identifier_expression = false;
3501 DeclarationParsingResult parsing_result; 3470 DeclarationParsingResult parsing_result;
3502 if (peek() != Token::SEMICOLON) { 3471 if (peek() != Token::SEMICOLON) {
3503 if (peek() == Token::VAR || (peek() == Token::CONST && allow_const()) || 3472 if (peek() == Token::VAR || peek() == Token::CONST ||
3504 (peek() == Token::LET && IsNextLetKeyword())) { 3473 (peek() == Token::LET && IsNextLetKeyword())) {
3505 ParseVariableDeclarations(kForStatement, &parsing_result, nullptr, 3474 ParseVariableDeclarations(kForStatement, &parsing_result, nullptr,
3506 CHECK_OK); 3475 CHECK_OK);
3507 3476
3508 ForEachStatement::VisitMode mode = ForEachStatement::ENUMERATE; 3477 ForEachStatement::VisitMode mode = ForEachStatement::ENUMERATE;
3509 int each_beg_pos = scanner()->location().beg_pos; 3478 int each_beg_pos = scanner()->location().beg_pos;
3510 int each_end_pos = scanner()->location().end_pos; 3479 int each_end_pos = scanner()->location().end_pos;
3511 3480
3512 if (CheckInOrOf(&mode, ok)) { 3481 if (CheckInOrOf(&mode, ok)) {
3513 if (!*ok) return nullptr; 3482 if (!*ok) return nullptr;
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
3666 ? &lexical_bindings 3635 ? &lexical_bindings
3667 : nullptr, 3636 : nullptr,
3668 CHECK_OK); 3637 CHECK_OK);
3669 } 3638 }
3670 } else { 3639 } else {
3671 int lhs_beg_pos = peek_position(); 3640 int lhs_beg_pos = peek_position();
3672 ExpressionClassifier classifier(this); 3641 ExpressionClassifier classifier(this);
3673 Expression* expression = ParseExpression(false, &classifier, CHECK_OK); 3642 Expression* expression = ParseExpression(false, &classifier, CHECK_OK);
3674 int lhs_end_pos = scanner()->location().end_pos; 3643 int lhs_end_pos = scanner()->location().end_pos;
3675 ForEachStatement::VisitMode mode = ForEachStatement::ENUMERATE; 3644 ForEachStatement::VisitMode mode = ForEachStatement::ENUMERATE;
3676 is_let_identifier_expression =
3677 expression->IsVariableProxy() &&
3678 expression->AsVariableProxy()->raw_name() ==
3679 ast_value_factory()->let_string();
3680 3645
3681 bool is_for_each = CheckInOrOf(&mode, ok); 3646 bool is_for_each = CheckInOrOf(&mode, ok);
3682 if (!*ok) return nullptr; 3647 if (!*ok) return nullptr;
3683 bool is_destructuring = is_for_each && (expression->IsArrayLiteral() || 3648 bool is_destructuring = is_for_each && (expression->IsArrayLiteral() ||
3684 expression->IsObjectLiteral()); 3649 expression->IsObjectLiteral());
3685 3650
3686 if (is_destructuring) { 3651 if (is_destructuring) {
3687 ValidateAssignmentPattern(&classifier, CHECK_OK); 3652 ValidateAssignmentPattern(&classifier, CHECK_OK);
3688 } else { 3653 } else {
3689 RewriteNonPattern(&classifier, CHECK_OK); 3654 RewriteNonPattern(&classifier, CHECK_OK);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
3730 init = factory()->NewExpressionStatement(expression, lhs_beg_pos); 3695 init = factory()->NewExpressionStatement(expression, lhs_beg_pos);
3731 } 3696 }
3732 } 3697 }
3733 } 3698 }
3734 3699
3735 // Standard 'for' loop 3700 // Standard 'for' loop
3736 ForStatement* loop = factory()->NewForStatement(labels, stmt_pos); 3701 ForStatement* loop = factory()->NewForStatement(labels, stmt_pos);
3737 Target target(&this->target_stack_, loop); 3702 Target target(&this->target_stack_, loop);
3738 3703
3739 // Parsed initializer at this point. 3704 // Parsed initializer at this point.
3740 // Detect attempts at 'let' declarations in sloppy mode.
3741 if (!allow_harmony_sloppy_let() && peek() == Token::IDENTIFIER &&
3742 is_sloppy(language_mode()) && is_let_identifier_expression) {
3743 ReportMessage(MessageTemplate::kSloppyLexical, NULL);
3744 *ok = false;
3745 return NULL;
3746 }
3747 Expect(Token::SEMICOLON, CHECK_OK); 3705 Expect(Token::SEMICOLON, CHECK_OK);
3748 3706
3749 Expression* cond = NULL; 3707 Expression* cond = NULL;
3750 Statement* next = NULL; 3708 Statement* next = NULL;
3751 Statement* body = NULL; 3709 Statement* body = NULL;
3752 3710
3753 // If there are let bindings, then condition and the next statement of the 3711 // If there are let bindings, then condition and the next statement of the
3754 // for loop must be parsed in a new scope. 3712 // for loop must be parsed in a new scope.
3755 Scope* inner_scope = scope_; 3713 Scope* inner_scope = scope_;
3756 if (lexical_bindings.length() > 0) { 3714 if (lexical_bindings.length() > 0) {
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
4032 // Anonymous functions were passed either the empty symbol or a null 3990 // Anonymous functions were passed either the empty symbol or a null
4033 // handle as the function name. Remember if we were passed a non-empty 3991 // handle as the function name. Remember if we were passed a non-empty
4034 // handle to decide whether to invoke function name inference. 3992 // handle to decide whether to invoke function name inference.
4035 bool should_infer_name = function_name == NULL; 3993 bool should_infer_name = function_name == NULL;
4036 3994
4037 // We want a non-null handle as the function name. 3995 // We want a non-null handle as the function name.
4038 if (should_infer_name) { 3996 if (should_infer_name) {
4039 function_name = ast_value_factory()->empty_string(); 3997 function_name = ast_value_factory()->empty_string();
4040 } 3998 }
4041 3999
4042 // Function declarations are function scoped in normal mode, so they are 4000 Scope* scope = NewScope(scope_, FUNCTION_SCOPE, kind);
4043 // hoisted. In harmony block scoping mode they are block scoped, so they
4044 // are not hoisted.
4045 //
4046 // One tricky case are function declarations in a local sloppy-mode eval:
4047 // their declaration is hoisted, but they still see the local scope. E.g.,
4048 //
4049 // function() {
4050 // var x = 0
4051 // try { throw 1 } catch (x) { eval("function g() { return x }") }
4052 // return g()
4053 // }
4054 //
4055 // needs to return 1. To distinguish such cases, we need to detect
4056 // (1) whether a function stems from a sloppy eval, and
4057 // (2) whether it actually hoists across the eval.
4058 // Unfortunately, we do not represent sloppy eval scopes, so we do not have
4059 // either information available directly, especially not when lazily compiling
4060 // a function like 'g'. We hence rely on the following invariants:
4061 // - (1) is the case iff the innermost scope of the deserialized scope chain
4062 // under which we compile is _not_ a declaration scope. This holds because
4063 // in all normal cases, function declarations are fully hoisted to a
4064 // declaration scope and compiled relative to that.
4065 // - (2) is the case iff the current declaration scope is still the original
4066 // one relative to the deserialized scope chain. Otherwise we must be
4067 // compiling a function in an inner declaration scope in the eval, e.g. a
4068 // nested function, and hoisting works normally relative to that.
4069 Scope* declaration_scope = scope_->DeclarationScope();
4070 Scope* original_declaration_scope = original_scope_->DeclarationScope();
4071 Scope* scope = function_type == FunctionLiteral::kDeclaration &&
4072 is_sloppy(language_mode) &&
4073 !allow_harmony_sloppy_function() &&
4074 (original_scope_ == original_declaration_scope ||
4075 declaration_scope != original_declaration_scope)
4076 ? NewScope(declaration_scope, FUNCTION_SCOPE, kind)
4077 : NewScope(scope_, FUNCTION_SCOPE, kind);
4078 SetLanguageMode(scope, language_mode); 4001 SetLanguageMode(scope, language_mode);
4079 ZoneList<Statement*>* body = NULL; 4002 ZoneList<Statement*>* body = NULL;
4080 int arity = -1; 4003 int arity = -1;
4081 int materialized_literal_count = -1; 4004 int materialized_literal_count = -1;
4082 int expected_property_count = -1; 4005 int expected_property_count = -1;
4083 DuplicateFinder duplicate_finder(scanner()->unicode_cache()); 4006 DuplicateFinder duplicate_finder(scanner()->unicode_cache());
4084 FunctionLiteral::EagerCompileHint eager_compile_hint = 4007 FunctionLiteral::EagerCompileHint eager_compile_hint =
4085 parenthesized_function_ ? FunctionLiteral::kShouldEagerCompile 4008 parenthesized_function_ ? FunctionLiteral::kShouldEagerCompile
4086 : FunctionLiteral::kShouldLazyCompile; 4009 : FunctionLiteral::kShouldLazyCompile;
4087 bool should_be_used_once_hint = false; 4010 bool should_be_used_once_hint = false;
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
4242 function_name_location, CHECK_OK); 4165 function_name_location, CHECK_OK);
4243 const bool allow_duplicate_parameters = 4166 const bool allow_duplicate_parameters =
4244 is_sloppy(language_mode) && formals.is_simple && !IsConciseMethod(kind); 4167 is_sloppy(language_mode) && formals.is_simple && !IsConciseMethod(kind);
4245 ValidateFormalParameters(&formals_classifier, language_mode, 4168 ValidateFormalParameters(&formals_classifier, language_mode,
4246 allow_duplicate_parameters, CHECK_OK); 4169 allow_duplicate_parameters, CHECK_OK);
4247 4170
4248 if (is_strict(language_mode)) { 4171 if (is_strict(language_mode)) {
4249 CheckStrictOctalLiteral(scope->start_position(), scope->end_position(), 4172 CheckStrictOctalLiteral(scope->start_position(), scope->end_position(),
4250 CHECK_OK); 4173 CHECK_OK);
4251 } 4174 }
4252 if (is_sloppy(language_mode) && allow_harmony_sloppy_function()) { 4175 if (is_sloppy(language_mode)) {
4253 InsertSloppyBlockFunctionVarBindings(scope, CHECK_OK); 4176 InsertSloppyBlockFunctionVarBindings(scope, CHECK_OK);
4254 } 4177 }
4255 CheckConflictingVarDeclarations(scope, CHECK_OK); 4178 CheckConflictingVarDeclarations(scope, CHECK_OK);
4256 4179
4257 if (body) { 4180 if (body) {
4258 // If body can be inspected, rewrite queued destructuring assignments 4181 // If body can be inspected, rewrite queued destructuring assignments
4259 ParserTraits::RewriteDestructuringAssignments(); 4182 ParserTraits::RewriteDestructuringAssignments();
4260 } 4183 }
4261 has_duplicate_parameters = 4184 has_duplicate_parameters =
4262 !formals_classifier.is_valid_formal_parameter_list_without_duplicates(); 4185 !formals_classifier.is_valid_formal_parameter_list_without_duplicates();
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after
4666 TRACE_EVENT0("v8", "V8.PreParse"); 4589 TRACE_EVENT0("v8", "V8.PreParse");
4667 4590
4668 DCHECK_EQ(Token::LBRACE, scanner()->current_token()); 4591 DCHECK_EQ(Token::LBRACE, scanner()->current_token());
4669 4592
4670 if (reusable_preparser_ == NULL) { 4593 if (reusable_preparser_ == NULL) {
4671 reusable_preparser_ = new PreParser(zone(), &scanner_, ast_value_factory(), 4594 reusable_preparser_ = new PreParser(zone(), &scanner_, ast_value_factory(),
4672 NULL, stack_limit_); 4595 NULL, stack_limit_);
4673 reusable_preparser_->set_allow_lazy(true); 4596 reusable_preparser_->set_allow_lazy(true);
4674 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name()); 4597 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name());
4675 SET_ALLOW(natives); 4598 SET_ALLOW(natives);
4676 SET_ALLOW(harmony_sloppy);
4677 SET_ALLOW(harmony_sloppy_function);
4678 SET_ALLOW(harmony_sloppy_let);
4679 SET_ALLOW(harmony_do_expressions); 4599 SET_ALLOW(harmony_do_expressions);
4680 SET_ALLOW(harmony_function_name); 4600 SET_ALLOW(harmony_function_name);
4681 SET_ALLOW(harmony_function_sent); 4601 SET_ALLOW(harmony_function_sent);
4682 SET_ALLOW(harmony_exponentiation_operator); 4602 SET_ALLOW(harmony_exponentiation_operator);
4683 SET_ALLOW(harmony_restrictive_declarations); 4603 SET_ALLOW(harmony_restrictive_declarations);
4684 #undef SET_ALLOW 4604 #undef SET_ALLOW
4685 } 4605 }
4686 PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction( 4606 PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction(
4687 language_mode(), function_state_->kind(), scope_->has_simple_parameters(), 4607 language_mode(), function_state_->kind(), scope_->has_simple_parameters(),
4688 logger, bookmark); 4608 logger, bookmark);
(...skipping 2180 matching lines...) Expand 10 before | Expand all | Expand 10 after
6869 try_block, target); 6789 try_block, target);
6870 final_loop = target; 6790 final_loop = target;
6871 } 6791 }
6872 6792
6873 return final_loop; 6793 return final_loop;
6874 } 6794 }
6875 6795
6876 6796
6877 } // namespace internal 6797 } // namespace internal
6878 } // namespace v8 6798 } // namespace v8
OLDNEW
« no previous file with comments | « src/messages.h ('k') | src/parsing/parser-base.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698