| 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 #ifndef V8_PARSING_PARSER_BASE_H | 5 #ifndef V8_PARSING_PARSER_BASE_H |
| 6 #define V8_PARSING_PARSER_BASE_H | 6 #define V8_PARSING_PARSER_BASE_H |
| 7 | 7 |
| 8 #include "src/ast/ast.h" | 8 #include "src/ast/ast.h" |
| 9 #include "src/ast/scopes.h" | 9 #include "src/ast/scopes.h" |
| 10 #include "src/bailout-reason.h" | 10 #include "src/bailout-reason.h" |
| (...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 287 | 287 |
| 288 class BlockState final : public ScopeState { | 288 class BlockState final : public ScopeState { |
| 289 public: | 289 public: |
| 290 BlockState(ScopeState** scope_stack, Scope* scope) | 290 BlockState(ScopeState** scope_stack, Scope* scope) |
| 291 : ScopeState(scope_stack, scope) {} | 291 : ScopeState(scope_stack, scope) {} |
| 292 | 292 |
| 293 // BlockState(ScopeState**) automatically manages Scope(BLOCK_SCOPE) | 293 // BlockState(ScopeState**) automatically manages Scope(BLOCK_SCOPE) |
| 294 // allocation. | 294 // allocation. |
| 295 // TODO(verwaest): Move to LazyBlockState class that only allocates the | 295 // TODO(verwaest): Move to LazyBlockState class that only allocates the |
| 296 // scope when needed. | 296 // scope when needed. |
| 297 explicit BlockState(ScopeState** scope_stack) | 297 explicit BlockState(Zone* zone, ScopeState** scope_stack) |
| 298 : ScopeState(scope_stack, NewScope(*scope_stack)) {} | 298 : ScopeState(scope_stack, NewScope(zone, *scope_stack)) {} |
| 299 | 299 |
| 300 void SetNonlinear() { this->scope()->SetNonlinear(); } | 300 void SetNonlinear() { this->scope()->SetNonlinear(); } |
| 301 void set_start_position(int pos) { this->scope()->set_start_position(pos); } | 301 void set_start_position(int pos) { this->scope()->set_start_position(pos); } |
| 302 void set_end_position(int pos) { this->scope()->set_end_position(pos); } | 302 void set_end_position(int pos) { this->scope()->set_end_position(pos); } |
| 303 void set_is_hidden() { this->scope()->set_is_hidden(); } | 303 void set_is_hidden() { this->scope()->set_is_hidden(); } |
| 304 Scope* FinalizedBlockScope() const { | 304 Scope* FinalizedBlockScope() const { |
| 305 return this->scope()->FinalizeBlockScope(); | 305 return this->scope()->FinalizeBlockScope(); |
| 306 } | 306 } |
| 307 LanguageMode language_mode() const { | 307 LanguageMode language_mode() const { |
| 308 return this->scope()->language_mode(); | 308 return this->scope()->language_mode(); |
| 309 } | 309 } |
| 310 | 310 |
| 311 private: | 311 private: |
| 312 Scope* NewScope(ScopeState* outer_state) { | 312 Scope* NewScope(Zone* zone, ScopeState* outer_state) { |
| 313 Scope* parent = outer_state->scope(); | 313 Scope* parent = outer_state->scope(); |
| 314 Zone* zone = outer_state->zone(); | |
| 315 return new (zone) Scope(zone, parent, BLOCK_SCOPE); | 314 return new (zone) Scope(zone, parent, BLOCK_SCOPE); |
| 316 } | 315 } |
| 317 }; | 316 }; |
| 318 | 317 |
| 319 struct DestructuringAssignment { | 318 struct DestructuringAssignment { |
| 320 public: | 319 public: |
| 321 DestructuringAssignment(ExpressionT expression, Scope* scope) | 320 DestructuringAssignment(ExpressionT expression, Scope* scope) |
| 322 : assignment(expression), scope(scope) {} | 321 : assignment(expression), scope(scope) {} |
| 323 | 322 |
| 324 ExpressionT assignment; | 323 ExpressionT assignment; |
| (...skipping 3509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3834 formal_parameters.scope | 3833 formal_parameters.scope |
| 3835 ->AllowsLazyParsingWithoutUnresolvedVariables()); | 3834 ->AllowsLazyParsingWithoutUnresolvedVariables()); |
| 3836 // TODO(marja): consider lazy-parsing inner arrow functions too. is_this | 3835 // TODO(marja): consider lazy-parsing inner arrow functions too. is_this |
| 3837 // handling in Scope::ResolveVariable needs to change. | 3836 // handling in Scope::ResolveVariable needs to change. |
| 3838 if (is_lazily_parsed) { | 3837 if (is_lazily_parsed) { |
| 3839 Scanner::BookmarkScope bookmark(scanner()); | 3838 Scanner::BookmarkScope bookmark(scanner()); |
| 3840 bookmark.Set(); | 3839 bookmark.Set(); |
| 3841 LazyParsingResult result = impl()->SkipLazyFunctionBody( | 3840 LazyParsingResult result = impl()->SkipLazyFunctionBody( |
| 3842 &materialized_literal_count, &expected_property_count, false, true, | 3841 &materialized_literal_count, &expected_property_count, false, true, |
| 3843 CHECK_OK); | 3842 CHECK_OK); |
| 3843 formal_parameters.scope->ResetAfterPreparsing(result == |
| 3844 kLazyParsingAborted); |
| 3844 | 3845 |
| 3845 if (formal_parameters.materialized_literals_count > 0) { | 3846 if (formal_parameters.materialized_literals_count > 0) { |
| 3846 materialized_literal_count += | 3847 materialized_literal_count += |
| 3847 formal_parameters.materialized_literals_count; | 3848 formal_parameters.materialized_literals_count; |
| 3848 } | 3849 } |
| 3849 | 3850 |
| 3850 if (result == kLazyParsingAborted) { | 3851 if (result == kLazyParsingAborted) { |
| 3851 bookmark.Apply(); | 3852 bookmark.Apply(); |
| 3852 // Trigger eager (re-)parsing, just below this block. | 3853 // Trigger eager (re-)parsing, just below this block. |
| 3853 is_lazily_parsed = false; | 3854 is_lazily_parsed = false; |
| (...skipping 569 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4423 ZoneList<const AstRawString*>* labels, bool* ok) { | 4424 ZoneList<const AstRawString*>* labels, bool* ok) { |
| 4424 // Block :: | 4425 // Block :: |
| 4425 // '{' StatementList '}' | 4426 // '{' StatementList '}' |
| 4426 | 4427 |
| 4427 // Construct block expecting 16 statements. | 4428 // Construct block expecting 16 statements. |
| 4428 BlockT body = factory()->NewBlock(labels, 16, false, kNoSourcePosition); | 4429 BlockT body = factory()->NewBlock(labels, 16, false, kNoSourcePosition); |
| 4429 | 4430 |
| 4430 // Parse the statements and collect escaping labels. | 4431 // Parse the statements and collect escaping labels. |
| 4431 Expect(Token::LBRACE, CHECK_OK_CUSTOM(NullBlock)); | 4432 Expect(Token::LBRACE, CHECK_OK_CUSTOM(NullBlock)); |
| 4432 { | 4433 { |
| 4433 BlockState block_state(&scope_state_); | 4434 BlockState block_state(zone(), &scope_state_); |
| 4434 block_state.set_start_position(scanner()->location().beg_pos); | 4435 block_state.set_start_position(scanner()->location().beg_pos); |
| 4435 typename Types::Target target(this, body); | 4436 typename Types::Target target(this, body); |
| 4436 | 4437 |
| 4437 while (peek() != Token::RBRACE) { | 4438 while (peek() != Token::RBRACE) { |
| 4438 StatementT stat = ParseStatementListItem(CHECK_OK_CUSTOM(NullBlock)); | 4439 StatementT stat = ParseStatementListItem(CHECK_OK_CUSTOM(NullBlock)); |
| 4439 if (!impl()->IsNullStatement(stat) && !impl()->IsEmptyStatement(stat)) { | 4440 if (!impl()->IsNullStatement(stat) && !impl()->IsEmptyStatement(stat)) { |
| 4440 body->statements()->Add(stat, zone()); | 4441 body->statements()->Add(stat, zone()); |
| 4441 } | 4442 } |
| 4442 } | 4443 } |
| 4443 | 4444 |
| 4444 Expect(Token::RBRACE, CHECK_OK_CUSTOM(NullBlock)); | 4445 Expect(Token::RBRACE, CHECK_OK_CUSTOM(NullBlock)); |
| 4445 block_state.set_end_position(scanner()->location().end_pos); | 4446 block_state.set_end_position(scanner()->location().end_pos); |
| 4446 body->set_scope(block_state.FinalizedBlockScope()); | 4447 body->set_scope(block_state.FinalizedBlockScope()); |
| 4447 } | 4448 } |
| 4448 return body; | 4449 return body; |
| 4449 } | 4450 } |
| 4450 | 4451 |
| 4451 template <typename Impl> | 4452 template <typename Impl> |
| 4452 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseScopedStatement( | 4453 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseScopedStatement( |
| 4453 ZoneList<const AstRawString*>* labels, bool legacy, bool* ok) { | 4454 ZoneList<const AstRawString*>* labels, bool legacy, bool* ok) { |
| 4454 if (is_strict(language_mode()) || peek() != Token::FUNCTION || | 4455 if (is_strict(language_mode()) || peek() != Token::FUNCTION || |
| 4455 (legacy && allow_harmony_restrictive_declarations())) { | 4456 (legacy && allow_harmony_restrictive_declarations())) { |
| 4456 return ParseStatement(labels, kDisallowLabelledFunctionStatement, ok); | 4457 return ParseStatement(labels, kDisallowLabelledFunctionStatement, ok); |
| 4457 } else { | 4458 } else { |
| 4458 if (legacy) { | 4459 if (legacy) { |
| 4459 impl()->CountUsage(v8::Isolate::kLegacyFunctionDeclaration); | 4460 impl()->CountUsage(v8::Isolate::kLegacyFunctionDeclaration); |
| 4460 } | 4461 } |
| 4461 // Make a block around the statement for a lexical binding | 4462 // Make a block around the statement for a lexical binding |
| 4462 // is introduced by a FunctionDeclaration. | 4463 // is introduced by a FunctionDeclaration. |
| 4463 BlockState block_state(&scope_state_); | 4464 BlockState block_state(zone(), &scope_state_); |
| 4464 block_state.set_start_position(scanner()->location().beg_pos); | 4465 block_state.set_start_position(scanner()->location().beg_pos); |
| 4465 BlockT block = factory()->NewBlock(NULL, 1, false, kNoSourcePosition); | 4466 BlockT block = factory()->NewBlock(NULL, 1, false, kNoSourcePosition); |
| 4466 StatementT body = impl()->ParseFunctionDeclaration(CHECK_OK); | 4467 StatementT body = impl()->ParseFunctionDeclaration(CHECK_OK); |
| 4467 block->statements()->Add(body, zone()); | 4468 block->statements()->Add(body, zone()); |
| 4468 block_state.set_end_position(scanner()->location().end_pos); | 4469 block_state.set_end_position(scanner()->location().end_pos); |
| 4469 block->set_scope(block_state.FinalizedBlockScope()); | 4470 block->set_scope(block_state.FinalizedBlockScope()); |
| 4470 return block; | 4471 return block; |
| 4471 } | 4472 } |
| 4472 } | 4473 } |
| 4473 | 4474 |
| (...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4824 int switch_pos = peek_position(); | 4825 int switch_pos = peek_position(); |
| 4825 | 4826 |
| 4826 Expect(Token::SWITCH, CHECK_OK); | 4827 Expect(Token::SWITCH, CHECK_OK); |
| 4827 Expect(Token::LPAREN, CHECK_OK); | 4828 Expect(Token::LPAREN, CHECK_OK); |
| 4828 ExpressionT tag = ParseExpression(true, CHECK_OK); | 4829 ExpressionT tag = ParseExpression(true, CHECK_OK); |
| 4829 Expect(Token::RPAREN, CHECK_OK); | 4830 Expect(Token::RPAREN, CHECK_OK); |
| 4830 | 4831 |
| 4831 auto switch_statement = factory()->NewSwitchStatement(labels, switch_pos); | 4832 auto switch_statement = factory()->NewSwitchStatement(labels, switch_pos); |
| 4832 | 4833 |
| 4833 { | 4834 { |
| 4834 BlockState cases_block_state(&scope_state_); | 4835 BlockState cases_block_state(zone(), &scope_state_); |
| 4835 cases_block_state.set_start_position(scanner()->location().beg_pos); | 4836 cases_block_state.set_start_position(scanner()->location().beg_pos); |
| 4836 cases_block_state.SetNonlinear(); | 4837 cases_block_state.SetNonlinear(); |
| 4837 typename Types::Target target(this, switch_statement); | 4838 typename Types::Target target(this, switch_statement); |
| 4838 | 4839 |
| 4839 bool default_seen = false; | 4840 bool default_seen = false; |
| 4840 auto cases = impl()->NewCaseClauseList(4); | 4841 auto cases = impl()->NewCaseClauseList(4); |
| 4841 Expect(Token::LBRACE, CHECK_OK); | 4842 Expect(Token::LBRACE, CHECK_OK); |
| 4842 while (peek() != Token::RBRACE) { | 4843 while (peek() != Token::RBRACE) { |
| 4843 // An empty label indicates the default case. | 4844 // An empty label indicates the default case. |
| 4844 ExpressionT label = impl()->EmptyExpression(); | 4845 ExpressionT label = impl()->EmptyExpression(); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4915 CollectExpressionsInTailPositionToListScope | 4916 CollectExpressionsInTailPositionToListScope |
| 4916 collect_tail_call_expressions_scope( | 4917 collect_tail_call_expressions_scope( |
| 4917 function_state_, &catch_info.tail_call_expressions); | 4918 function_state_, &catch_info.tail_call_expressions); |
| 4918 BlockState catch_block_state(&scope_state_, catch_info.scope); | 4919 BlockState catch_block_state(&scope_state_, catch_info.scope); |
| 4919 | 4920 |
| 4920 catch_block = factory()->NewBlock(nullptr, 16, false, kNoSourcePosition); | 4921 catch_block = factory()->NewBlock(nullptr, 16, false, kNoSourcePosition); |
| 4921 | 4922 |
| 4922 // Create a block scope to hold any lexical declarations created | 4923 // Create a block scope to hold any lexical declarations created |
| 4923 // as part of destructuring the catch parameter. | 4924 // as part of destructuring the catch parameter. |
| 4924 { | 4925 { |
| 4925 BlockState catch_variable_block_state(&scope_state_); | 4926 BlockState catch_variable_block_state(zone(), &scope_state_); |
| 4926 catch_variable_block_state.set_start_position( | 4927 catch_variable_block_state.set_start_position( |
| 4927 scanner()->location().beg_pos); | 4928 scanner()->location().beg_pos); |
| 4928 typename Types::Target target(this, catch_block); | 4929 typename Types::Target target(this, catch_block); |
| 4929 | 4930 |
| 4930 // This does not simply call ParsePrimaryExpression to avoid | 4931 // This does not simply call ParsePrimaryExpression to avoid |
| 4931 // ExpressionFromIdentifier from being called in the first | 4932 // ExpressionFromIdentifier from being called in the first |
| 4932 // branch, which would introduce an unresolved symbol and mess | 4933 // branch, which would introduce an unresolved symbol and mess |
| 4933 // with arrow function names. | 4934 // with arrow function names. |
| 4934 if (peek_any_identifier()) { | 4935 if (peek_any_identifier()) { |
| 4935 catch_info.name = | 4936 catch_info.name = |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4970 } | 4971 } |
| 4971 | 4972 |
| 4972 template <typename Impl> | 4973 template <typename Impl> |
| 4973 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseForStatement( | 4974 typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseForStatement( |
| 4974 ZoneList<const AstRawString*>* labels, bool* ok) { | 4975 ZoneList<const AstRawString*>* labels, bool* ok) { |
| 4975 int stmt_pos = peek_position(); | 4976 int stmt_pos = peek_position(); |
| 4976 ForInfo for_info(this); | 4977 ForInfo for_info(this); |
| 4977 bool bound_names_are_lexical = false; | 4978 bool bound_names_are_lexical = false; |
| 4978 | 4979 |
| 4979 // Create an in-between scope for let-bound iteration variables. | 4980 // Create an in-between scope for let-bound iteration variables. |
| 4980 BlockState for_state(&scope_state_); | 4981 BlockState for_state(zone(), &scope_state_); |
| 4981 Expect(Token::FOR, CHECK_OK); | 4982 Expect(Token::FOR, CHECK_OK); |
| 4982 Expect(Token::LPAREN, CHECK_OK); | 4983 Expect(Token::LPAREN, CHECK_OK); |
| 4983 for_state.set_start_position(scanner()->location().beg_pos); | 4984 for_state.set_start_position(scanner()->location().beg_pos); |
| 4984 for_state.set_is_hidden(); | 4985 for_state.set_is_hidden(); |
| 4985 | 4986 |
| 4986 StatementT init = impl()->NullStatement(); | 4987 StatementT init = impl()->NullStatement(); |
| 4987 if (peek() != Token::SEMICOLON) { | 4988 if (peek() != Token::SEMICOLON) { |
| 4988 // An initializer is present. | 4989 // An initializer is present. |
| 4989 if (peek() == Token::VAR || peek() == Token::CONST || | 4990 if (peek() == Token::VAR || peek() == Token::CONST || |
| 4990 (peek() == Token::LET && IsNextLetKeyword())) { | 4991 (peek() == Token::LET && IsNextLetKeyword())) { |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5041 } else { | 5042 } else { |
| 5042 enumerable = ParseExpression(true, CHECK_OK); | 5043 enumerable = ParseExpression(true, CHECK_OK); |
| 5043 } | 5044 } |
| 5044 | 5045 |
| 5045 Expect(Token::RPAREN, CHECK_OK); | 5046 Expect(Token::RPAREN, CHECK_OK); |
| 5046 | 5047 |
| 5047 StatementT final_loop = impl()->NullStatement(); | 5048 StatementT final_loop = impl()->NullStatement(); |
| 5048 { | 5049 { |
| 5049 ReturnExprScope no_tail_calls(function_state_, | 5050 ReturnExprScope no_tail_calls(function_state_, |
| 5050 ReturnExprContext::kInsideForInOfBody); | 5051 ReturnExprContext::kInsideForInOfBody); |
| 5051 BlockState block_state(&scope_state_); | 5052 BlockState block_state(zone(), &scope_state_); |
| 5052 block_state.set_start_position(scanner()->location().beg_pos); | 5053 block_state.set_start_position(scanner()->location().beg_pos); |
| 5053 | 5054 |
| 5054 StatementT body = ParseScopedStatement(nullptr, true, CHECK_OK); | 5055 StatementT body = ParseScopedStatement(nullptr, true, CHECK_OK); |
| 5055 | 5056 |
| 5056 BlockT body_block = impl()->NullBlock(); | 5057 BlockT body_block = impl()->NullBlock(); |
| 5057 ExpressionT each_variable = impl()->EmptyExpression(); | 5058 ExpressionT each_variable = impl()->EmptyExpression(); |
| 5058 impl()->DesugarBindingInForEachStatement(&for_info, &body_block, | 5059 impl()->DesugarBindingInForEachStatement(&for_info, &body_block, |
| 5059 &each_variable, CHECK_OK); | 5060 &each_variable, CHECK_OK); |
| 5060 body_block->statements()->Add(body, zone()); | 5061 body_block->statements()->Add(body, zone()); |
| 5061 final_loop = impl()->InitializeForEachStatement( | 5062 final_loop = impl()->InitializeForEachStatement( |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5124 impl()->RewriteNonPattern(CHECK_OK); | 5125 impl()->RewriteNonPattern(CHECK_OK); |
| 5125 } else { | 5126 } else { |
| 5126 enumerable = ParseExpression(true, CHECK_OK); | 5127 enumerable = ParseExpression(true, CHECK_OK); |
| 5127 } | 5128 } |
| 5128 | 5129 |
| 5129 Expect(Token::RPAREN, CHECK_OK); | 5130 Expect(Token::RPAREN, CHECK_OK); |
| 5130 | 5131 |
| 5131 { | 5132 { |
| 5132 ReturnExprScope no_tail_calls(function_state_, | 5133 ReturnExprScope no_tail_calls(function_state_, |
| 5133 ReturnExprContext::kInsideForInOfBody); | 5134 ReturnExprContext::kInsideForInOfBody); |
| 5134 BlockState block_state(&scope_state_); | 5135 BlockState block_state(zone(), &scope_state_); |
| 5135 block_state.set_start_position(scanner()->location().beg_pos); | 5136 block_state.set_start_position(scanner()->location().beg_pos); |
| 5136 | 5137 |
| 5137 // For legacy compat reasons, give for loops similar treatment to | 5138 // For legacy compat reasons, give for loops similar treatment to |
| 5138 // if statements in allowing a function declaration for a body | 5139 // if statements in allowing a function declaration for a body |
| 5139 StatementT body = ParseScopedStatement(nullptr, true, CHECK_OK); | 5140 StatementT body = ParseScopedStatement(nullptr, true, CHECK_OK); |
| 5140 block_state.set_end_position(scanner()->location().end_pos); | 5141 block_state.set_end_position(scanner()->location().end_pos); |
| 5141 StatementT final_loop = impl()->InitializeForEachStatement( | 5142 StatementT final_loop = impl()->InitializeForEachStatement( |
| 5142 loop, expression, enumerable, body, each_keyword_pos); | 5143 loop, expression, enumerable, body, each_keyword_pos); |
| 5143 | 5144 |
| 5144 Scope* for_scope = for_state.FinalizedBlockScope(); | 5145 Scope* for_scope = for_state.FinalizedBlockScope(); |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5284 has_seen_constructor_ = true; | 5285 has_seen_constructor_ = true; |
| 5285 return; | 5286 return; |
| 5286 } | 5287 } |
| 5287 } | 5288 } |
| 5288 | 5289 |
| 5289 | 5290 |
| 5290 } // namespace internal | 5291 } // namespace internal |
| 5291 } // namespace v8 | 5292 } // namespace v8 |
| 5292 | 5293 |
| 5293 #endif // V8_PARSING_PARSER_BASE_H | 5294 #endif // V8_PARSING_PARSER_BASE_H |
| OLD | NEW |