| 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 <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #include "src/api.h" | 9 #include "src/api.h" |
| 10 #include "src/ast/ast-expression-rewriter.h" | 10 #include "src/ast/ast-expression-rewriter.h" |
| (...skipping 1889 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1900 } | 1900 } |
| 1901 } | 1901 } |
| 1902 | 1902 |
| 1903 Expect(Token::RBRACE, CHECK_OK); | 1903 Expect(Token::RBRACE, CHECK_OK); |
| 1904 block_state.set_end_position(scanner()->location().end_pos); | 1904 block_state.set_end_position(scanner()->location().end_pos); |
| 1905 body->set_scope(block_state.FinalizedBlockScope()); | 1905 body->set_scope(block_state.FinalizedBlockScope()); |
| 1906 } | 1906 } |
| 1907 return body; | 1907 return body; |
| 1908 } | 1908 } |
| 1909 | 1909 |
| 1910 | 1910 Block* Parser::BuildInitializationBlock( |
| 1911 Block* Parser::DeclarationParsingResult::BuildInitializationBlock( | 1911 DeclarationParsingResult* parsing_result, |
| 1912 ZoneList<const AstRawString*>* names, bool* ok) { | 1912 ZoneList<const AstRawString*>* names, bool* ok) { |
| 1913 Block* result = descriptor.parser->factory()->NewBlock( | 1913 Block* result = factory()->NewBlock( |
| 1914 NULL, 1, true, descriptor.declaration_pos); | 1914 NULL, 1, true, parsing_result->descriptor.declaration_pos); |
| 1915 for (auto declaration : declarations) { | 1915 for (auto declaration : parsing_result->declarations) { |
| 1916 PatternRewriter::DeclareAndInitializeVariables( | 1916 PatternRewriter::DeclareAndInitializeVariables( |
| 1917 result, &descriptor, &declaration, names, CHECK_OK); | 1917 this, result, &(parsing_result->descriptor), &declaration, names, |
| 1918 CHECK_OK); |
| 1918 } | 1919 } |
| 1919 return result; | 1920 return result; |
| 1920 } | 1921 } |
| 1921 | 1922 |
| 1922 | 1923 |
| 1923 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context, | 1924 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context, |
| 1924 ZoneList<const AstRawString*>* names, | 1925 ZoneList<const AstRawString*>* names, |
| 1925 bool* ok) { | 1926 bool* ok) { |
| 1926 // VariableStatement :: | 1927 // VariableStatement :: |
| 1927 // VariableDeclarations ';' | 1928 // VariableDeclarations ';' |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1956 // | 1957 // |
| 1957 // ConstDeclaration :: | 1958 // ConstDeclaration :: |
| 1958 // const ConstBinding (',' ConstBinding)* ';' | 1959 // const ConstBinding (',' ConstBinding)* ';' |
| 1959 // ConstBinding :: | 1960 // ConstBinding :: |
| 1960 // Identifier '=' AssignmentExpression | 1961 // Identifier '=' AssignmentExpression |
| 1961 // | 1962 // |
| 1962 // TODO(ES6): | 1963 // TODO(ES6): |
| 1963 // ConstBinding :: | 1964 // ConstBinding :: |
| 1964 // BindingPattern '=' AssignmentExpression | 1965 // BindingPattern '=' AssignmentExpression |
| 1965 | 1966 |
| 1966 parsing_result->descriptor.parser = this; | |
| 1967 parsing_result->descriptor.declaration_kind = DeclarationDescriptor::NORMAL; | 1967 parsing_result->descriptor.declaration_kind = DeclarationDescriptor::NORMAL; |
| 1968 parsing_result->descriptor.declaration_pos = peek_position(); | 1968 parsing_result->descriptor.declaration_pos = peek_position(); |
| 1969 parsing_result->descriptor.initialization_pos = peek_position(); | 1969 parsing_result->descriptor.initialization_pos = peek_position(); |
| 1970 parsing_result->descriptor.mode = VAR; | 1970 parsing_result->descriptor.mode = VAR; |
| 1971 | 1971 |
| 1972 Block* init_block = nullptr; | 1972 Block* init_block = nullptr; |
| 1973 if (var_context != kForStatement) { | 1973 if (var_context != kForStatement) { |
| 1974 init_block = factory()->NewBlock( | 1974 init_block = factory()->NewBlock( |
| 1975 NULL, 1, true, parsing_result->descriptor.declaration_pos); | 1975 NULL, 1, true, parsing_result->descriptor.declaration_pos); |
| 1976 } | 1976 } |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2077 if (var_context == kForStatement) { | 2077 if (var_context == kForStatement) { |
| 2078 // Save the declaration for further handling in ParseForStatement. | 2078 // Save the declaration for further handling in ParseForStatement. |
| 2079 parsing_result->declarations.Add(decl); | 2079 parsing_result->declarations.Add(decl); |
| 2080 } else { | 2080 } else { |
| 2081 // Immediately declare the variable otherwise. This avoids O(N^2) | 2081 // Immediately declare the variable otherwise. This avoids O(N^2) |
| 2082 // behavior (where N is the number of variables in a single | 2082 // behavior (where N is the number of variables in a single |
| 2083 // declaration) in the PatternRewriter having to do with removing | 2083 // declaration) in the PatternRewriter having to do with removing |
| 2084 // and adding VariableProxies to the Scope (see bug 4699). | 2084 // and adding VariableProxies to the Scope (see bug 4699). |
| 2085 DCHECK_NOT_NULL(init_block); | 2085 DCHECK_NOT_NULL(init_block); |
| 2086 PatternRewriter::DeclareAndInitializeVariables( | 2086 PatternRewriter::DeclareAndInitializeVariables( |
| 2087 init_block, &parsing_result->descriptor, &decl, names, CHECK_OK); | 2087 this, init_block, &parsing_result->descriptor, &decl, names, |
| 2088 CHECK_OK); |
| 2088 } | 2089 } |
| 2089 first_declaration = false; | 2090 first_declaration = false; |
| 2090 } while (peek() == Token::COMMA); | 2091 } while (peek() == Token::COMMA); |
| 2091 | 2092 |
| 2092 parsing_result->bindings_loc = | 2093 parsing_result->bindings_loc = |
| 2093 Scanner::Location(bindings_start, scanner()->location().end_pos); | 2094 Scanner::Location(bindings_start, scanner()->location().end_pos); |
| 2094 | 2095 |
| 2095 DCHECK(*ok); | 2096 DCHECK(*ok); |
| 2096 return init_block; | 2097 return init_block; |
| 2097 } | 2098 } |
| (...skipping 527 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2625 } | 2626 } |
| 2626 catch_variable = catch_scope->DeclareLocal( | 2627 catch_variable = catch_scope->DeclareLocal( |
| 2627 name, VAR, kCreatedInitialized, Variable::NORMAL); | 2628 name, VAR, kCreatedInitialized, Variable::NORMAL); |
| 2628 | 2629 |
| 2629 Expect(Token::RPAREN, CHECK_OK); | 2630 Expect(Token::RPAREN, CHECK_OK); |
| 2630 | 2631 |
| 2631 ZoneList<const AstRawString*> bound_names(1, zone()); | 2632 ZoneList<const AstRawString*> bound_names(1, zone()); |
| 2632 if (pattern != nullptr) { | 2633 if (pattern != nullptr) { |
| 2633 DeclarationDescriptor descriptor; | 2634 DeclarationDescriptor descriptor; |
| 2634 descriptor.declaration_kind = DeclarationDescriptor::NORMAL; | 2635 descriptor.declaration_kind = DeclarationDescriptor::NORMAL; |
| 2635 descriptor.parser = this; | |
| 2636 descriptor.scope = scope(); | 2636 descriptor.scope = scope(); |
| 2637 descriptor.hoist_scope = nullptr; | 2637 descriptor.hoist_scope = nullptr; |
| 2638 descriptor.mode = LET; | 2638 descriptor.mode = LET; |
| 2639 descriptor.declaration_pos = pattern->position(); | 2639 descriptor.declaration_pos = pattern->position(); |
| 2640 descriptor.initialization_pos = pattern->position(); | 2640 descriptor.initialization_pos = pattern->position(); |
| 2641 | 2641 |
| 2642 // Initializer position for variables declared by the pattern. | 2642 // Initializer position for variables declared by the pattern. |
| 2643 const int initializer_position = position(); | 2643 const int initializer_position = position(); |
| 2644 | 2644 |
| 2645 DeclarationParsingResult::Declaration decl( | 2645 DeclarationParsingResult::Declaration decl( |
| 2646 pattern, initializer_position, | 2646 pattern, initializer_position, |
| 2647 factory()->NewVariableProxy(catch_variable)); | 2647 factory()->NewVariableProxy(catch_variable)); |
| 2648 | 2648 |
| 2649 Block* init_block = | 2649 Block* init_block = |
| 2650 factory()->NewBlock(nullptr, 8, true, kNoSourcePosition); | 2650 factory()->NewBlock(nullptr, 8, true, kNoSourcePosition); |
| 2651 PatternRewriter::DeclareAndInitializeVariables( | 2651 PatternRewriter::DeclareAndInitializeVariables( |
| 2652 init_block, &descriptor, &decl, &bound_names, CHECK_OK); | 2652 this, init_block, &descriptor, &decl, &bound_names, CHECK_OK); |
| 2653 catch_block->statements()->Add(init_block, zone()); | 2653 catch_block->statements()->Add(init_block, zone()); |
| 2654 } else { | 2654 } else { |
| 2655 bound_names.Add(name, zone()); | 2655 bound_names.Add(name, zone()); |
| 2656 } | 2656 } |
| 2657 | 2657 |
| 2658 Block* inner_block = ParseBlock(nullptr, CHECK_OK); | 2658 Block* inner_block = ParseBlock(nullptr, CHECK_OK); |
| 2659 catch_block->statements()->Add(inner_block, zone()); | 2659 catch_block->statements()->Add(inner_block, zone()); |
| 2660 | 2660 |
| 2661 // Check for `catch(e) { let e; }` and similar errors. | 2661 // Check for `catch(e) { let e; }` and similar errors. |
| 2662 Scope* inner_block_scope = inner_block->scope(); | 2662 Scope* inner_block_scope = inner_block->scope(); |
| (...skipping 708 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3371 auto descriptor = parsing_result.descriptor; | 3371 auto descriptor = parsing_result.descriptor; |
| 3372 descriptor.declaration_pos = kNoSourcePosition; | 3372 descriptor.declaration_pos = kNoSourcePosition; |
| 3373 descriptor.initialization_pos = kNoSourcePosition; | 3373 descriptor.initialization_pos = kNoSourcePosition; |
| 3374 decl.initializer = factory()->NewVariableProxy(temp); | 3374 decl.initializer = factory()->NewVariableProxy(temp); |
| 3375 | 3375 |
| 3376 bool is_for_var_of = | 3376 bool is_for_var_of = |
| 3377 mode == ForEachStatement::ITERATE && | 3377 mode == ForEachStatement::ITERATE && |
| 3378 parsing_result.descriptor.mode == VariableMode::VAR; | 3378 parsing_result.descriptor.mode == VariableMode::VAR; |
| 3379 | 3379 |
| 3380 PatternRewriter::DeclareAndInitializeVariables( | 3380 PatternRewriter::DeclareAndInitializeVariables( |
| 3381 each_initialization_block, &descriptor, &decl, | 3381 this, each_initialization_block, &descriptor, &decl, |
| 3382 bound_names_are_lexical || is_for_var_of ? &bound_names | 3382 bound_names_are_lexical || is_for_var_of ? &bound_names |
| 3383 : nullptr, | 3383 : nullptr, |
| 3384 CHECK_OK); | 3384 CHECK_OK); |
| 3385 | 3385 |
| 3386 // Annex B.3.5 prohibits the form | 3386 // Annex B.3.5 prohibits the form |
| 3387 // `try {} catch(e) { for (var e of {}); }` | 3387 // `try {} catch(e) { for (var e of {}); }` |
| 3388 // So if we are parsing a statement like `for (var ... of ...)` | 3388 // So if we are parsing a statement like `for (var ... of ...)` |
| 3389 // we need to walk up the scope chain and look for catch scopes | 3389 // we need to walk up the scope chain and look for catch scopes |
| 3390 // which have a simple binding, then compare their binding against | 3390 // which have a simple binding, then compare their binding against |
| 3391 // all of the names declared in the init of the for-of we're | 3391 // all of the names declared in the init of the for-of we're |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3446 init_block->statements()->Add(final_loop, zone()); | 3446 init_block->statements()->Add(final_loop, zone()); |
| 3447 init_block->set_scope(for_scope); | 3447 init_block->set_scope(for_scope); |
| 3448 return init_block; | 3448 return init_block; |
| 3449 } else { | 3449 } else { |
| 3450 DCHECK_NULL(for_scope); | 3450 DCHECK_NULL(for_scope); |
| 3451 return final_loop; | 3451 return final_loop; |
| 3452 } | 3452 } |
| 3453 } else { | 3453 } else { |
| 3454 bound_names_are_lexical = | 3454 bound_names_are_lexical = |
| 3455 IsLexicalVariableMode(parsing_result.descriptor.mode); | 3455 IsLexicalVariableMode(parsing_result.descriptor.mode); |
| 3456 init = parsing_result.BuildInitializationBlock( | 3456 init = BuildInitializationBlock( |
| 3457 bound_names_are_lexical ? &bound_names : nullptr, CHECK_OK); | 3457 &parsing_result, bound_names_are_lexical ? &bound_names : nullptr, |
| 3458 CHECK_OK); |
| 3458 } | 3459 } |
| 3459 } else { | 3460 } else { |
| 3460 int lhs_beg_pos = peek_position(); | 3461 int lhs_beg_pos = peek_position(); |
| 3461 ExpressionClassifier classifier(this); | 3462 ExpressionClassifier classifier(this); |
| 3462 Expression* expression = ParseExpression(false, &classifier, CHECK_OK); | 3463 Expression* expression = ParseExpression(false, &classifier, CHECK_OK); |
| 3463 int lhs_end_pos = scanner()->location().end_pos; | 3464 int lhs_end_pos = scanner()->location().end_pos; |
| 3464 ForEachStatement::VisitMode mode = ForEachStatement::ENUMERATE; | 3465 ForEachStatement::VisitMode mode = ForEachStatement::ENUMERATE; |
| 3465 | 3466 |
| 3466 bool is_for_each = CheckInOrOf(&mode, CHECK_OK); | 3467 bool is_for_each = CheckInOrOf(&mode, CHECK_OK); |
| 3467 bool is_destructuring = is_for_each && (expression->IsArrayLiteral() || | 3468 bool is_destructuring = is_for_each && (expression->IsArrayLiteral() || |
| (...skipping 760 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4228 Block* Parser::BuildParameterInitializationBlock( | 4229 Block* Parser::BuildParameterInitializationBlock( |
| 4229 const ParserFormalParameters& parameters, bool* ok) { | 4230 const ParserFormalParameters& parameters, bool* ok) { |
| 4230 DCHECK(!parameters.is_simple); | 4231 DCHECK(!parameters.is_simple); |
| 4231 DCHECK(scope()->is_function_scope()); | 4232 DCHECK(scope()->is_function_scope()); |
| 4232 Block* init_block = factory()->NewBlock(NULL, 1, true, kNoSourcePosition); | 4233 Block* init_block = factory()->NewBlock(NULL, 1, true, kNoSourcePosition); |
| 4233 for (int i = 0; i < parameters.params.length(); ++i) { | 4234 for (int i = 0; i < parameters.params.length(); ++i) { |
| 4234 auto parameter = parameters.params[i]; | 4235 auto parameter = parameters.params[i]; |
| 4235 if (parameter.is_rest && parameter.pattern->IsVariableProxy()) break; | 4236 if (parameter.is_rest && parameter.pattern->IsVariableProxy()) break; |
| 4236 DeclarationDescriptor descriptor; | 4237 DeclarationDescriptor descriptor; |
| 4237 descriptor.declaration_kind = DeclarationDescriptor::PARAMETER; | 4238 descriptor.declaration_kind = DeclarationDescriptor::PARAMETER; |
| 4238 descriptor.parser = this; | |
| 4239 descriptor.scope = scope(); | 4239 descriptor.scope = scope(); |
| 4240 descriptor.hoist_scope = nullptr; | 4240 descriptor.hoist_scope = nullptr; |
| 4241 descriptor.mode = LET; | 4241 descriptor.mode = LET; |
| 4242 descriptor.declaration_pos = parameter.pattern->position(); | 4242 descriptor.declaration_pos = parameter.pattern->position(); |
| 4243 // The position that will be used by the AssignmentExpression | 4243 // The position that will be used by the AssignmentExpression |
| 4244 // which copies from the temp parameter to the pattern. | 4244 // which copies from the temp parameter to the pattern. |
| 4245 // | 4245 // |
| 4246 // TODO(adamk): Should this be kNoSourcePosition, since | 4246 // TODO(adamk): Should this be kNoSourcePosition, since |
| 4247 // it's just copying from a temp var to the real param var? | 4247 // it's just copying from a temp var to the real param var? |
| 4248 descriptor.initialization_pos = parameter.pattern->position(); | 4248 descriptor.initialization_pos = parameter.pattern->position(); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4281 // rewrite inner initializers of the pattern to param_scope | 4281 // rewrite inner initializers of the pattern to param_scope |
| 4282 descriptor.scope = param_scope; | 4282 descriptor.scope = param_scope; |
| 4283 // Rewrite the outer initializer to point to param_scope | 4283 // Rewrite the outer initializer to point to param_scope |
| 4284 ReparentParameterExpressionScope(stack_limit(), initial_value, | 4284 ReparentParameterExpressionScope(stack_limit(), initial_value, |
| 4285 param_scope); | 4285 param_scope); |
| 4286 } | 4286 } |
| 4287 | 4287 |
| 4288 BlockState block_state(&scope_state_, param_scope); | 4288 BlockState block_state(&scope_state_, param_scope); |
| 4289 DeclarationParsingResult::Declaration decl( | 4289 DeclarationParsingResult::Declaration decl( |
| 4290 parameter.pattern, initializer_position, initial_value); | 4290 parameter.pattern, initializer_position, initial_value); |
| 4291 PatternRewriter::DeclareAndInitializeVariables(param_block, &descriptor, | 4291 PatternRewriter::DeclareAndInitializeVariables( |
| 4292 &decl, nullptr, CHECK_OK); | 4292 this, param_block, &descriptor, &decl, nullptr, CHECK_OK); |
| 4293 | 4293 |
| 4294 if (param_block != init_block) { | 4294 if (param_block != init_block) { |
| 4295 param_scope = block_state.FinalizedBlockScope(); | 4295 param_scope = block_state.FinalizedBlockScope(); |
| 4296 if (param_scope != nullptr) { | 4296 if (param_scope != nullptr) { |
| 4297 CheckConflictingVarDeclarations(param_scope, CHECK_OK); | 4297 CheckConflictingVarDeclarations(param_scope, CHECK_OK); |
| 4298 } | 4298 } |
| 4299 init_block->statements()->Add(param_block, zone()); | 4299 init_block->statements()->Add(param_block, zone()); |
| 4300 } | 4300 } |
| 4301 } | 4301 } |
| 4302 return init_block; | 4302 return init_block; |
| (...skipping 2355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6658 node->Print(Isolate::Current()); | 6658 node->Print(Isolate::Current()); |
| 6659 } | 6659 } |
| 6660 #endif // DEBUG | 6660 #endif // DEBUG |
| 6661 | 6661 |
| 6662 #undef CHECK_OK | 6662 #undef CHECK_OK |
| 6663 #undef CHECK_OK_VOID | 6663 #undef CHECK_OK_VOID |
| 6664 #undef CHECK_FAILED | 6664 #undef CHECK_FAILED |
| 6665 | 6665 |
| 6666 } // namespace internal | 6666 } // namespace internal |
| 6667 } // namespace v8 | 6667 } // namespace v8 |
| OLD | NEW |