| 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 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 403 class FunctionState final : public ScopeState { | 403 class FunctionState final : public ScopeState { |
| 404 public: | 404 public: |
| 405 FunctionState(FunctionState** function_state_stack, | 405 FunctionState(FunctionState** function_state_stack, |
| 406 ScopeState** scope_stack, DeclarationScope* scope); | 406 ScopeState** scope_stack, DeclarationScope* scope); |
| 407 ~FunctionState(); | 407 ~FunctionState(); |
| 408 | 408 |
| 409 DeclarationScope* scope() const { | 409 DeclarationScope* scope() const { |
| 410 return ScopeState::scope()->AsDeclarationScope(); | 410 return ScopeState::scope()->AsDeclarationScope(); |
| 411 } | 411 } |
| 412 | 412 |
| 413 int NextMaterializedLiteralIndex() { | |
| 414 return next_materialized_literal_index_++; | |
| 415 } | |
| 416 int materialized_literal_count() { | |
| 417 return next_materialized_literal_index_; | |
| 418 } | |
| 419 | |
| 420 void SkipMaterializedLiterals(int count) { | |
| 421 next_materialized_literal_index_ += count; | |
| 422 } | |
| 423 | |
| 424 void AddProperty() { expected_property_count_++; } | 413 void AddProperty() { expected_property_count_++; } |
| 425 int expected_property_count() { return expected_property_count_; } | 414 int expected_property_count() { return expected_property_count_; } |
| 426 | 415 |
| 427 FunctionKind kind() const { return scope()->function_kind(); } | 416 FunctionKind kind() const { return scope()->function_kind(); } |
| 428 FunctionState* outer() const { return outer_function_state_; } | 417 FunctionState* outer() const { return outer_function_state_; } |
| 429 | 418 |
| 430 typename Types::Variable* generator_object_variable() const { | 419 typename Types::Variable* generator_object_variable() const { |
| 431 return scope()->generator_object_var(); | 420 return scope()->generator_object_var(); |
| 432 } | 421 } |
| 433 | 422 |
| (...skipping 1276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1710 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseRegExpLiteral( | 1699 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseRegExpLiteral( |
| 1711 bool* ok) { | 1700 bool* ok) { |
| 1712 int pos = peek_position(); | 1701 int pos = peek_position(); |
| 1713 if (!scanner()->ScanRegExpPattern()) { | 1702 if (!scanner()->ScanRegExpPattern()) { |
| 1714 Next(); | 1703 Next(); |
| 1715 ReportMessage(MessageTemplate::kUnterminatedRegExp); | 1704 ReportMessage(MessageTemplate::kUnterminatedRegExp); |
| 1716 *ok = false; | 1705 *ok = false; |
| 1717 return impl()->EmptyExpression(); | 1706 return impl()->EmptyExpression(); |
| 1718 } | 1707 } |
| 1719 | 1708 |
| 1720 function_state_->NextMaterializedLiteralIndex(); | |
| 1721 | |
| 1722 IdentifierT js_pattern = impl()->GetNextSymbol(); | 1709 IdentifierT js_pattern = impl()->GetNextSymbol(); |
| 1723 Maybe<RegExp::Flags> flags = scanner()->ScanRegExpFlags(); | 1710 Maybe<RegExp::Flags> flags = scanner()->ScanRegExpFlags(); |
| 1724 if (flags.IsNothing()) { | 1711 if (flags.IsNothing()) { |
| 1725 Next(); | 1712 Next(); |
| 1726 ReportMessage(MessageTemplate::kMalformedRegExpFlags); | 1713 ReportMessage(MessageTemplate::kMalformedRegExpFlags); |
| 1727 *ok = false; | 1714 *ok = false; |
| 1728 return impl()->EmptyExpression(); | 1715 return impl()->EmptyExpression(); |
| 1729 } | 1716 } |
| 1730 int js_flags = flags.FromJust(); | 1717 int js_flags = flags.FromJust(); |
| 1731 Next(); | 1718 Next(); |
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2000 elem = ParseAssignmentExpression(true, CHECK_OK); | 1987 elem = ParseAssignmentExpression(true, CHECK_OK); |
| 2001 CheckDestructuringElement(elem, beg_pos, scanner()->location().end_pos); | 1988 CheckDestructuringElement(elem, beg_pos, scanner()->location().end_pos); |
| 2002 } | 1989 } |
| 2003 values->Add(elem, zone_); | 1990 values->Add(elem, zone_); |
| 2004 if (peek() != Token::RBRACK) { | 1991 if (peek() != Token::RBRACK) { |
| 2005 Expect(Token::COMMA, CHECK_OK); | 1992 Expect(Token::COMMA, CHECK_OK); |
| 2006 } | 1993 } |
| 2007 } | 1994 } |
| 2008 Expect(Token::RBRACK, CHECK_OK); | 1995 Expect(Token::RBRACK, CHECK_OK); |
| 2009 | 1996 |
| 2010 // Update the scope information before the pre-parsing bailout. | |
| 2011 function_state_->NextMaterializedLiteralIndex(); | |
| 2012 | |
| 2013 ExpressionT result = | 1997 ExpressionT result = |
| 2014 factory()->NewArrayLiteral(values, first_spread_index, pos); | 1998 factory()->NewArrayLiteral(values, first_spread_index, pos); |
| 2015 if (first_spread_index >= 0) { | 1999 if (first_spread_index >= 0) { |
| 2016 result = factory()->NewRewritableExpression(result); | 2000 result = factory()->NewRewritableExpression(result); |
| 2017 impl()->QueueNonPatternForRewriting(result, ok); | 2001 impl()->QueueNonPatternForRewriting(result, ok); |
| 2018 if (!*ok) { | 2002 if (!*ok) { |
| 2019 // If the non-pattern rewriting mechanism is used in the future for | 2003 // If the non-pattern rewriting mechanism is used in the future for |
| 2020 // rewriting other things than spreads, this error message will have | 2004 // rewriting other things than spreads, this error message will have |
| 2021 // to change. Also, this error message will never appear while pre- | 2005 // to change. Also, this error message will never appear while pre- |
| 2022 // parsing (this is OK, as it is an implementation limitation). | 2006 // parsing (this is OK, as it is an implementation limitation). |
| (...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2350 true, CHECK_OK_CUSTOM(EmptyFunctionLiteral)); | 2334 true, CHECK_OK_CUSTOM(EmptyFunctionLiteral)); |
| 2351 impl()->RewriteNonPattern(CHECK_OK_CUSTOM(EmptyFunctionLiteral)); | 2335 impl()->RewriteNonPattern(CHECK_OK_CUSTOM(EmptyFunctionLiteral)); |
| 2352 } else { | 2336 } else { |
| 2353 value = factory()->NewUndefinedLiteral(kNoSourcePosition); | 2337 value = factory()->NewUndefinedLiteral(kNoSourcePosition); |
| 2354 } | 2338 } |
| 2355 initializer_scope->set_end_position(scanner()->location().end_pos); | 2339 initializer_scope->set_end_position(scanner()->location().end_pos); |
| 2356 typename Types::StatementList body = impl()->NewStatementList(1); | 2340 typename Types::StatementList body = impl()->NewStatementList(1); |
| 2357 body->Add(factory()->NewReturnStatement(value, kNoSourcePosition), zone()); | 2341 body->Add(factory()->NewReturnStatement(value, kNoSourcePosition), zone()); |
| 2358 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( | 2342 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( |
| 2359 impl()->EmptyIdentifierString(), initializer_scope, body, | 2343 impl()->EmptyIdentifierString(), initializer_scope, body, |
| 2360 initializer_state.materialized_literal_count(), | |
| 2361 initializer_state.expected_property_count(), 0, 0, | 2344 initializer_state.expected_property_count(), 0, 0, |
| 2362 FunctionLiteral::kNoDuplicateParameters, | 2345 FunctionLiteral::kNoDuplicateParameters, |
| 2363 FunctionLiteral::kAnonymousExpression, default_eager_compile_hint_, | 2346 FunctionLiteral::kAnonymousExpression, default_eager_compile_hint_, |
| 2364 initializer_scope->start_position(), true, GetNextFunctionLiteralId()); | 2347 initializer_scope->start_position(), true, GetNextFunctionLiteralId()); |
| 2365 return function_literal; | 2348 return function_literal; |
| 2366 } | 2349 } |
| 2367 | 2350 |
| 2368 template <typename Impl> | 2351 template <typename Impl> |
| 2369 typename ParserBase<Impl>::ObjectLiteralPropertyT | 2352 typename ParserBase<Impl>::ObjectLiteralPropertyT |
| 2370 ParserBase<Impl>::ParseObjectPropertyDefinition(ObjectLiteralChecker* checker, | 2353 ParserBase<Impl>::ParseObjectPropertyDefinition(ObjectLiteralChecker* checker, |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2601 | 2584 |
| 2602 if (peek() != Token::RBRACE) { | 2585 if (peek() != Token::RBRACE) { |
| 2603 // Need {} because of the CHECK_OK macro. | 2586 // Need {} because of the CHECK_OK macro. |
| 2604 Expect(Token::COMMA, CHECK_OK); | 2587 Expect(Token::COMMA, CHECK_OK); |
| 2605 } | 2588 } |
| 2606 | 2589 |
| 2607 if (fni_ != nullptr) fni_->Infer(); | 2590 if (fni_ != nullptr) fni_->Infer(); |
| 2608 } | 2591 } |
| 2609 Expect(Token::RBRACE, CHECK_OK); | 2592 Expect(Token::RBRACE, CHECK_OK); |
| 2610 | 2593 |
| 2611 // Computation of literal_index must happen before pre parse bailout. | |
| 2612 function_state_->NextMaterializedLiteralIndex(); | |
| 2613 | |
| 2614 // In pattern rewriter, we rewrite rest property to call out to a | 2594 // In pattern rewriter, we rewrite rest property to call out to a |
| 2615 // runtime function passing all the other properties as arguments to | 2595 // runtime function passing all the other properties as arguments to |
| 2616 // this runtime function. Here, we make sure that the number of | 2596 // this runtime function. Here, we make sure that the number of |
| 2617 // properties is less than number of arguments allowed for a runtime | 2597 // properties is less than number of arguments allowed for a runtime |
| 2618 // call. | 2598 // call. |
| 2619 if (has_rest_property && properties->length() > Code::kMaxArguments) { | 2599 if (has_rest_property && properties->length() > Code::kMaxArguments) { |
| 2620 this->classifier()->RecordPatternError(Scanner::Location(pos, position()), | 2600 this->classifier()->RecordPatternError(Scanner::Location(pos, position()), |
| 2621 MessageTemplate::kTooManyArguments); | 2601 MessageTemplate::kTooManyArguments); |
| 2622 } | 2602 } |
| 2623 | 2603 |
| 2624 return factory()->NewObjectLiteral( | 2604 return factory()->NewObjectLiteral( |
| 2625 properties, number_of_boilerplate_properties, pos, has_rest_property); | 2605 properties, number_of_boilerplate_properties, pos, has_rest_property); |
| 2626 } | 2606 } |
| 2627 | 2607 |
| 2628 template <typename Impl> | 2608 template <typename Impl> |
| 2629 typename ParserBase<Impl>::ExpressionListT ParserBase<Impl>::ParseArguments( | 2609 typename ParserBase<Impl>::ExpressionListT ParserBase<Impl>::ParseArguments( |
| 2630 Scanner::Location* first_spread_arg_loc, bool maybe_arrow, bool* ok) { | 2610 Scanner::Location* first_spread_arg_loc, bool maybe_arrow, bool* ok) { |
| 2631 // Arguments :: | 2611 // Arguments :: |
| 2632 // '(' (AssignmentExpression)*[','] ')' | 2612 // '(' (AssignmentExpression)*[','] ')' |
| 2633 | 2613 |
| 2634 Scanner::Location spread_arg = Scanner::Location::invalid(); | 2614 Scanner::Location spread_arg = Scanner::Location::invalid(); |
| 2635 ExpressionListT result = impl()->NewExpressionList(4); | 2615 ExpressionListT result = impl()->NewExpressionList(4); |
| 2636 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList)); | 2616 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList)); |
| 2637 bool done = (peek() == Token::RPAREN); | 2617 bool done = (peek() == Token::RPAREN); |
| 2638 bool was_unspread = false; | 2618 bool was_unspread = false; |
| 2639 int unspread_sequences_count = 0; | |
| 2640 int spread_count = 0; | 2619 int spread_count = 0; |
| 2641 while (!done) { | 2620 while (!done) { |
| 2642 int start_pos = peek_position(); | 2621 int start_pos = peek_position(); |
| 2643 bool is_spread = Check(Token::ELLIPSIS); | 2622 bool is_spread = Check(Token::ELLIPSIS); |
| 2644 int expr_pos = peek_position(); | 2623 int expr_pos = peek_position(); |
| 2645 | 2624 |
| 2646 ExpressionT argument = | 2625 ExpressionT argument = |
| 2647 ParseAssignmentExpression(true, CHECK_OK_CUSTOM(NullExpressionList)); | 2626 ParseAssignmentExpression(true, CHECK_OK_CUSTOM(NullExpressionList)); |
| 2648 if (!maybe_arrow) { | 2627 if (!maybe_arrow) { |
| 2649 impl()->RewriteNonPattern(CHECK_OK_CUSTOM(NullExpressionList)); | 2628 impl()->RewriteNonPattern(CHECK_OK_CUSTOM(NullExpressionList)); |
| 2650 } | 2629 } |
| 2651 if (is_spread) { | 2630 if (is_spread) { |
| 2652 if (!spread_arg.IsValid()) { | 2631 if (!spread_arg.IsValid()) { |
| 2653 spread_arg.beg_pos = start_pos; | 2632 spread_arg.beg_pos = start_pos; |
| 2654 spread_arg.end_pos = peek_position(); | 2633 spread_arg.end_pos = peek_position(); |
| 2655 } | 2634 } |
| 2656 argument = factory()->NewSpread(argument, start_pos, expr_pos); | 2635 argument = factory()->NewSpread(argument, start_pos, expr_pos); |
| 2657 } | 2636 } |
| 2658 result->Add(argument, zone_); | 2637 result->Add(argument, zone_); |
| 2659 | 2638 |
| 2660 // unspread_sequences_count is the number of sequences of parameters which | |
| 2661 // are not prefixed with a spread '...' operator. | |
| 2662 if (is_spread) { | 2639 if (is_spread) { |
| 2663 was_unspread = false; | 2640 was_unspread = false; |
| 2664 spread_count++; | 2641 spread_count++; |
| 2665 } else if (!was_unspread) { | 2642 } else if (!was_unspread) { |
| 2666 was_unspread = true; | 2643 was_unspread = true; |
| 2667 unspread_sequences_count++; | |
| 2668 } | 2644 } |
| 2669 | 2645 |
| 2670 if (result->length() > Code::kMaxArguments) { | 2646 if (result->length() > Code::kMaxArguments) { |
| 2671 ReportMessage(MessageTemplate::kTooManyArguments); | 2647 ReportMessage(MessageTemplate::kTooManyArguments); |
| 2672 *ok = false; | 2648 *ok = false; |
| 2673 return impl()->NullExpressionList(); | 2649 return impl()->NullExpressionList(); |
| 2674 } | 2650 } |
| 2675 done = (peek() != Token::COMMA); | 2651 done = (peek() != Token::COMMA); |
| 2676 if (!done) { | 2652 if (!done) { |
| 2677 Next(); | 2653 Next(); |
| 2678 if (allow_harmony_trailing_commas() && peek() == Token::RPAREN) { | 2654 if (allow_harmony_trailing_commas() && peek() == Token::RPAREN) { |
| 2679 // allow trailing comma | 2655 // allow trailing comma |
| 2680 done = true; | 2656 done = true; |
| 2681 } | 2657 } |
| 2682 } | 2658 } |
| 2683 } | 2659 } |
| 2684 Scanner::Location location = scanner_->location(); | 2660 Scanner::Location location = scanner_->location(); |
| 2685 if (Token::RPAREN != Next()) { | 2661 if (Token::RPAREN != Next()) { |
| 2686 impl()->ReportMessageAt(location, MessageTemplate::kUnterminatedArgList); | 2662 impl()->ReportMessageAt(location, MessageTemplate::kUnterminatedArgList); |
| 2687 *ok = false; | 2663 *ok = false; |
| 2688 return impl()->NullExpressionList(); | 2664 return impl()->NullExpressionList(); |
| 2689 } | 2665 } |
| 2690 *first_spread_arg_loc = spread_arg; | 2666 *first_spread_arg_loc = spread_arg; |
| 2691 | 2667 |
| 2692 if (!maybe_arrow || peek() != Token::ARROW) { | 2668 if (!maybe_arrow || peek() != Token::ARROW) { |
| 2693 if (maybe_arrow) { | 2669 if (maybe_arrow) { |
| 2694 impl()->RewriteNonPattern(CHECK_OK_CUSTOM(NullExpressionList)); | 2670 impl()->RewriteNonPattern(CHECK_OK_CUSTOM(NullExpressionList)); |
| 2695 } | 2671 } |
| 2696 if (spread_arg.IsValid()) { | |
| 2697 // Unspread parameter sequences are translated into array literals in the | |
| 2698 // parser. Ensure that the number of materialized literals matches between | |
| 2699 // the parser and preparser | |
| 2700 if (was_unspread || spread_count > 1) { | |
| 2701 // There was more than one spread, or the spread was not the final | |
| 2702 // argument, so the parser will materialize literals. | |
| 2703 impl()->MaterializeUnspreadArgumentsLiterals(unspread_sequences_count); | |
| 2704 } | |
| 2705 } | |
| 2706 } | 2672 } |
| 2707 | 2673 |
| 2708 return result; | 2674 return result; |
| 2709 } | 2675 } |
| 2710 | 2676 |
| 2711 // Precedence = 2 | 2677 // Precedence = 2 |
| 2712 template <typename Impl> | 2678 template <typename Impl> |
| 2713 typename ParserBase<Impl>::ExpressionT | 2679 typename ParserBase<Impl>::ExpressionT |
| 2714 ParserBase<Impl>::ParseAssignmentExpression(bool accept_IN, bool* ok) { | 2680 ParserBase<Impl>::ParseAssignmentExpression(bool accept_IN, bool* ok) { |
| 2715 // AssignmentExpression :: | 2681 // AssignmentExpression :: |
| (...skipping 1437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4153 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { | 4119 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { |
| 4154 // ASI inserts `;` after arrow parameters if a line terminator is found. | 4120 // ASI inserts `;` after arrow parameters if a line terminator is found. |
| 4155 // `=> ...` is never a valid expression, so report as syntax error. | 4121 // `=> ...` is never a valid expression, so report as syntax error. |
| 4156 // If next token is not `=>`, it's a syntax error anyways. | 4122 // If next token is not `=>`, it's a syntax error anyways. |
| 4157 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW); | 4123 ReportUnexpectedTokenAt(scanner_->peek_location(), Token::ARROW); |
| 4158 *ok = false; | 4124 *ok = false; |
| 4159 return impl()->EmptyExpression(); | 4125 return impl()->EmptyExpression(); |
| 4160 } | 4126 } |
| 4161 | 4127 |
| 4162 StatementListT body = impl()->NullStatementList(); | 4128 StatementListT body = impl()->NullStatementList(); |
| 4163 int materialized_literal_count = -1; | |
| 4164 int expected_property_count = -1; | 4129 int expected_property_count = -1; |
| 4165 int function_literal_id = GetNextFunctionLiteralId(); | 4130 int function_literal_id = GetNextFunctionLiteralId(); |
| 4166 | 4131 |
| 4167 FunctionKind kind = formal_parameters.scope->function_kind(); | 4132 FunctionKind kind = formal_parameters.scope->function_kind(); |
| 4168 FunctionLiteral::EagerCompileHint eager_compile_hint = | 4133 FunctionLiteral::EagerCompileHint eager_compile_hint = |
| 4169 default_eager_compile_hint_; | 4134 default_eager_compile_hint_; |
| 4170 bool can_preparse = impl()->parse_lazily() && | 4135 bool can_preparse = impl()->parse_lazily() && |
| 4171 eager_compile_hint == FunctionLiteral::kShouldLazyCompile; | 4136 eager_compile_hint == FunctionLiteral::kShouldLazyCompile; |
| 4172 // TODO(marja): consider lazy-parsing inner arrow functions too. is_this | 4137 // TODO(marja): consider lazy-parsing inner arrow functions too. is_this |
| 4173 // handling in Scope::ResolveVariable needs to change. | 4138 // handling in Scope::ResolveVariable needs to change. |
| 4174 bool is_lazy_top_level_function = | 4139 bool is_lazy_top_level_function = |
| 4175 can_preparse && impl()->AllowsLazyParsingWithoutUnresolvedVariables(); | 4140 can_preparse && impl()->AllowsLazyParsingWithoutUnresolvedVariables(); |
| 4176 bool should_be_used_once_hint = false; | 4141 bool should_be_used_once_hint = false; |
| 4177 bool has_braces = true; | 4142 bool has_braces = true; |
| 4178 { | 4143 { |
| 4179 FunctionState function_state(&function_state_, &scope_state_, | 4144 FunctionState function_state(&function_state_, &scope_state_, |
| 4180 formal_parameters.scope); | 4145 formal_parameters.scope); |
| 4181 | 4146 |
| 4182 function_state.SkipMaterializedLiterals( | |
| 4183 formal_parameters.materialized_literals_count); | |
| 4184 | |
| 4185 Expect(Token::ARROW, CHECK_OK); | 4147 Expect(Token::ARROW, CHECK_OK); |
| 4186 | 4148 |
| 4187 if (peek() == Token::LBRACE) { | 4149 if (peek() == Token::LBRACE) { |
| 4188 // Multiple statement body | 4150 // Multiple statement body |
| 4189 DCHECK_EQ(scope(), formal_parameters.scope); | 4151 DCHECK_EQ(scope(), formal_parameters.scope); |
| 4190 if (is_lazy_top_level_function) { | 4152 if (is_lazy_top_level_function) { |
| 4191 // FIXME(marja): Arrow function parameters will be parsed even if the | 4153 // FIXME(marja): Arrow function parameters will be parsed even if the |
| 4192 // body is preparsed; move relevant parts of parameter handling to | 4154 // body is preparsed; move relevant parts of parameter handling to |
| 4193 // simulate consistent parameter handling. | 4155 // simulate consistent parameter handling. |
| 4194 Scanner::BookmarkScope bookmark(scanner()); | 4156 Scanner::BookmarkScope bookmark(scanner()); |
| 4195 bookmark.Set(); | 4157 bookmark.Set(); |
| 4196 // For arrow functions, we don't need to retrieve data about function | 4158 // For arrow functions, we don't need to retrieve data about function |
| 4197 // parameters. | 4159 // parameters. |
| 4198 int dummy_num_parameters = -1; | 4160 int dummy_num_parameters = -1; |
| 4199 int dummy_function_length = -1; | 4161 int dummy_function_length = -1; |
| 4200 bool dummy_has_duplicate_parameters = false; | 4162 bool dummy_has_duplicate_parameters = false; |
| 4201 DCHECK((kind & FunctionKind::kArrowFunction) != 0); | 4163 DCHECK((kind & FunctionKind::kArrowFunction) != 0); |
| 4202 LazyParsingResult result = impl()->SkipFunction( | 4164 LazyParsingResult result = impl()->SkipFunction( |
| 4203 kind, formal_parameters.scope, &dummy_num_parameters, | 4165 kind, formal_parameters.scope, &dummy_num_parameters, |
| 4204 &dummy_function_length, &dummy_has_duplicate_parameters, | 4166 &dummy_function_length, &dummy_has_duplicate_parameters, |
| 4205 &materialized_literal_count, &expected_property_count, false, true, | 4167 &expected_property_count, false, true, CHECK_OK); |
| 4206 CHECK_OK); | |
| 4207 formal_parameters.scope->ResetAfterPreparsing( | 4168 formal_parameters.scope->ResetAfterPreparsing( |
| 4208 ast_value_factory_, result == kLazyParsingAborted); | 4169 ast_value_factory_, result == kLazyParsingAborted); |
| 4209 | 4170 |
| 4210 if (formal_parameters.materialized_literals_count > 0) { | |
| 4211 materialized_literal_count += | |
| 4212 formal_parameters.materialized_literals_count; | |
| 4213 } | |
| 4214 | |
| 4215 if (result == kLazyParsingAborted) { | 4171 if (result == kLazyParsingAborted) { |
| 4216 bookmark.Apply(); | 4172 bookmark.Apply(); |
| 4217 // Trigger eager (re-)parsing, just below this block. | 4173 // Trigger eager (re-)parsing, just below this block. |
| 4218 is_lazy_top_level_function = false; | 4174 is_lazy_top_level_function = false; |
| 4219 | 4175 |
| 4220 // This is probably an initialization function. Inform the compiler it | 4176 // This is probably an initialization function. Inform the compiler it |
| 4221 // should also eager-compile this function, and that we expect it to | 4177 // should also eager-compile this function, and that we expect it to |
| 4222 // be used once. | 4178 // be used once. |
| 4223 eager_compile_hint = FunctionLiteral::kShouldEagerCompile; | 4179 eager_compile_hint = FunctionLiteral::kShouldEagerCompile; |
| 4224 should_be_used_once_hint = true; | 4180 should_be_used_once_hint = true; |
| 4225 } | 4181 } |
| 4226 } | 4182 } |
| 4227 if (!is_lazy_top_level_function) { | 4183 if (!is_lazy_top_level_function) { |
| 4228 Consume(Token::LBRACE); | 4184 Consume(Token::LBRACE); |
| 4229 body = impl()->NewStatementList(8); | 4185 body = impl()->NewStatementList(8); |
| 4230 impl()->ParseFunctionBody(body, impl()->EmptyIdentifier(), | 4186 impl()->ParseFunctionBody(body, impl()->EmptyIdentifier(), |
| 4231 kNoSourcePosition, formal_parameters, kind, | 4187 kNoSourcePosition, formal_parameters, kind, |
| 4232 FunctionLiteral::kAnonymousExpression, | 4188 FunctionLiteral::kAnonymousExpression, |
| 4233 CHECK_OK); | 4189 CHECK_OK); |
| 4234 materialized_literal_count = | |
| 4235 function_state.materialized_literal_count(); | |
| 4236 expected_property_count = function_state.expected_property_count(); | 4190 expected_property_count = function_state.expected_property_count(); |
| 4237 } | 4191 } |
| 4238 } else { | 4192 } else { |
| 4239 // Single-expression body | 4193 // Single-expression body |
| 4240 has_braces = false; | 4194 has_braces = false; |
| 4241 int pos = position(); | 4195 int pos = position(); |
| 4242 DCHECK(ReturnExprContext::kInsideValidBlock == | 4196 DCHECK(ReturnExprContext::kInsideValidBlock == |
| 4243 function_state_->return_expr_context()); | 4197 function_state_->return_expr_context()); |
| 4244 ReturnExprScope allow_tail_calls( | 4198 ReturnExprScope allow_tail_calls( |
| 4245 function_state_, ReturnExprContext::kInsideValidReturnStatement); | 4199 function_state_, ReturnExprContext::kInsideValidReturnStatement); |
| 4246 body = impl()->NewStatementList(1); | 4200 body = impl()->NewStatementList(1); |
| 4247 impl()->AddParameterInitializationBlock( | 4201 impl()->AddParameterInitializationBlock( |
| 4248 formal_parameters, body, kind == kAsyncArrowFunction, CHECK_OK); | 4202 formal_parameters, body, kind == kAsyncArrowFunction, CHECK_OK); |
| 4249 ExpressionClassifier classifier(this); | 4203 ExpressionClassifier classifier(this); |
| 4250 if (kind == kAsyncArrowFunction) { | 4204 if (kind == kAsyncArrowFunction) { |
| 4251 ParseAsyncFunctionBody(scope(), body, kAsyncArrowFunction, | 4205 ParseAsyncFunctionBody(scope(), body, kAsyncArrowFunction, |
| 4252 FunctionBodyType::kSingleExpression, accept_IN, | 4206 FunctionBodyType::kSingleExpression, accept_IN, |
| 4253 pos, CHECK_OK); | 4207 pos, CHECK_OK); |
| 4254 impl()->RewriteNonPattern(CHECK_OK); | 4208 impl()->RewriteNonPattern(CHECK_OK); |
| 4255 } else { | 4209 } else { |
| 4256 ExpressionT expression = ParseAssignmentExpression(accept_IN, CHECK_OK); | 4210 ExpressionT expression = ParseAssignmentExpression(accept_IN, CHECK_OK); |
| 4257 impl()->RewriteNonPattern(CHECK_OK); | 4211 impl()->RewriteNonPattern(CHECK_OK); |
| 4258 body->Add(BuildReturnStatement(expression, expression->position()), | 4212 body->Add(BuildReturnStatement(expression, expression->position()), |
| 4259 zone()); | 4213 zone()); |
| 4260 if (allow_tailcalls() && !is_sloppy(language_mode())) { | 4214 if (allow_tailcalls() && !is_sloppy(language_mode())) { |
| 4261 // ES6 14.6.1 Static Semantics: IsInTailPosition | 4215 // ES6 14.6.1 Static Semantics: IsInTailPosition |
| 4262 impl()->MarkTailPosition(expression); | 4216 impl()->MarkTailPosition(expression); |
| 4263 } | 4217 } |
| 4264 } | 4218 } |
| 4265 materialized_literal_count = function_state.materialized_literal_count(); | |
| 4266 expected_property_count = function_state.expected_property_count(); | 4219 expected_property_count = function_state.expected_property_count(); |
| 4267 impl()->MarkCollectedTailCallExpressions(); | 4220 impl()->MarkCollectedTailCallExpressions(); |
| 4268 } | 4221 } |
| 4269 | 4222 |
| 4270 formal_parameters.scope->set_end_position(scanner()->location().end_pos); | 4223 formal_parameters.scope->set_end_position(scanner()->location().end_pos); |
| 4271 | 4224 |
| 4272 // Arrow function formal parameters are parsed as StrictFormalParameterList, | 4225 // Arrow function formal parameters are parsed as StrictFormalParameterList, |
| 4273 // which is not the same as "parameters of a strict function"; it only means | 4226 // which is not the same as "parameters of a strict function"; it only means |
| 4274 // that duplicates are not allowed. Of course, the arrow function may | 4227 // that duplicates are not allowed. Of course, the arrow function may |
| 4275 // itself be strict as well. | 4228 // itself be strict as well. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 4288 } | 4241 } |
| 4289 | 4242 |
| 4290 if (FLAG_trace_preparse) { | 4243 if (FLAG_trace_preparse) { |
| 4291 Scope* scope = formal_parameters.scope; | 4244 Scope* scope = formal_parameters.scope; |
| 4292 PrintF(" [%s]: %i-%i (arrow function)\n", | 4245 PrintF(" [%s]: %i-%i (arrow function)\n", |
| 4293 is_lazy_top_level_function ? "Preparse no-resolution" : "Full parse", | 4246 is_lazy_top_level_function ? "Preparse no-resolution" : "Full parse", |
| 4294 scope->start_position(), scope->end_position()); | 4247 scope->start_position(), scope->end_position()); |
| 4295 } | 4248 } |
| 4296 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( | 4249 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( |
| 4297 impl()->EmptyIdentifierString(), formal_parameters.scope, body, | 4250 impl()->EmptyIdentifierString(), formal_parameters.scope, body, |
| 4298 materialized_literal_count, expected_property_count, | 4251 expected_property_count, formal_parameters.num_parameters(), |
| 4299 formal_parameters.num_parameters(), formal_parameters.function_length, | 4252 formal_parameters.function_length, |
| 4300 FunctionLiteral::kNoDuplicateParameters, | 4253 FunctionLiteral::kNoDuplicateParameters, |
| 4301 FunctionLiteral::kAnonymousExpression, eager_compile_hint, | 4254 FunctionLiteral::kAnonymousExpression, eager_compile_hint, |
| 4302 formal_parameters.scope->start_position(), has_braces, | 4255 formal_parameters.scope->start_position(), has_braces, |
| 4303 function_literal_id); | 4256 function_literal_id); |
| 4304 | 4257 |
| 4305 function_literal->set_function_token_position( | 4258 function_literal->set_function_token_position( |
| 4306 formal_parameters.scope->start_position()); | 4259 formal_parameters.scope->start_position()); |
| 4307 if (should_be_used_once_hint) { | 4260 if (should_be_used_once_hint) { |
| 4308 function_literal->set_should_be_used_once_hint(); | 4261 function_literal->set_should_be_used_once_hint(); |
| 4309 } | 4262 } |
| (...skipping 1441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5751 } | 5704 } |
| 5752 | 5705 |
| 5753 #undef CHECK_OK | 5706 #undef CHECK_OK |
| 5754 #undef CHECK_OK_CUSTOM | 5707 #undef CHECK_OK_CUSTOM |
| 5755 #undef CHECK_OK_VOID | 5708 #undef CHECK_OK_VOID |
| 5756 | 5709 |
| 5757 } // namespace internal | 5710 } // namespace internal |
| 5758 } // namespace v8 | 5711 } // namespace v8 |
| 5759 | 5712 |
| 5760 #endif // V8_PARSING_PARSER_BASE_H | 5713 #endif // V8_PARSING_PARSER_BASE_H |
| OLD | NEW |