OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |