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 2591 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2602 Scanner::Location* first_spread_arg_loc, bool maybe_arrow, bool* ok) { | 2602 Scanner::Location* first_spread_arg_loc, bool maybe_arrow, bool* ok) { |
2603 // Arguments :: | 2603 // Arguments :: |
2604 // '(' (AssignmentExpression)*[','] ')' | 2604 // '(' (AssignmentExpression)*[','] ')' |
2605 | 2605 |
2606 Scanner::Location spread_arg = Scanner::Location::invalid(); | 2606 Scanner::Location spread_arg = Scanner::Location::invalid(); |
2607 ExpressionListT result = impl()->NewExpressionList(4); | 2607 ExpressionListT result = impl()->NewExpressionList(4); |
2608 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList)); | 2608 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList)); |
2609 bool done = (peek() == Token::RPAREN); | 2609 bool done = (peek() == Token::RPAREN); |
2610 bool was_unspread = false; | 2610 bool was_unspread = false; |
2611 int unspread_sequences_count = 0; | 2611 int unspread_sequences_count = 0; |
| 2612 int spread_count = 0; |
2612 while (!done) { | 2613 while (!done) { |
2613 int start_pos = peek_position(); | 2614 int start_pos = peek_position(); |
2614 bool is_spread = Check(Token::ELLIPSIS); | 2615 bool is_spread = Check(Token::ELLIPSIS); |
2615 int expr_pos = peek_position(); | 2616 int expr_pos = peek_position(); |
2616 | 2617 |
2617 ExpressionT argument = | 2618 ExpressionT argument = |
2618 ParseAssignmentExpression(true, CHECK_OK_CUSTOM(NullExpressionList)); | 2619 ParseAssignmentExpression(true, CHECK_OK_CUSTOM(NullExpressionList)); |
2619 if (!maybe_arrow) { | 2620 if (!maybe_arrow) { |
2620 impl()->RewriteNonPattern(CHECK_OK_CUSTOM(NullExpressionList)); | 2621 impl()->RewriteNonPattern(CHECK_OK_CUSTOM(NullExpressionList)); |
2621 } | 2622 } |
2622 if (is_spread) { | 2623 if (is_spread) { |
2623 if (!spread_arg.IsValid()) { | 2624 if (!spread_arg.IsValid()) { |
2624 spread_arg.beg_pos = start_pos; | 2625 spread_arg.beg_pos = start_pos; |
2625 spread_arg.end_pos = peek_position(); | 2626 spread_arg.end_pos = peek_position(); |
2626 } | 2627 } |
2627 argument = factory()->NewSpread(argument, start_pos, expr_pos); | 2628 argument = factory()->NewSpread(argument, start_pos, expr_pos); |
2628 } | 2629 } |
2629 result->Add(argument, zone_); | 2630 result->Add(argument, zone_); |
2630 | 2631 |
2631 // unspread_sequences_count is the number of sequences of parameters which | 2632 // unspread_sequences_count is the number of sequences of parameters which |
2632 // are not prefixed with a spread '...' operator. | 2633 // are not prefixed with a spread '...' operator. |
2633 if (is_spread) { | 2634 if (is_spread) { |
2634 was_unspread = false; | 2635 was_unspread = false; |
| 2636 spread_count++; |
2635 } else if (!was_unspread) { | 2637 } else if (!was_unspread) { |
2636 was_unspread = true; | 2638 was_unspread = true; |
2637 unspread_sequences_count++; | 2639 unspread_sequences_count++; |
2638 } | 2640 } |
2639 | 2641 |
2640 if (result->length() > Code::kMaxArguments) { | 2642 if (result->length() > Code::kMaxArguments) { |
2641 ReportMessage(MessageTemplate::kTooManyArguments); | 2643 ReportMessage(MessageTemplate::kTooManyArguments); |
2642 *ok = false; | 2644 *ok = false; |
2643 return impl()->NullExpressionList(); | 2645 return impl()->NullExpressionList(); |
2644 } | 2646 } |
(...skipping 15 matching lines...) Expand all Loading... |
2660 *first_spread_arg_loc = spread_arg; | 2662 *first_spread_arg_loc = spread_arg; |
2661 | 2663 |
2662 if (!maybe_arrow || peek() != Token::ARROW) { | 2664 if (!maybe_arrow || peek() != Token::ARROW) { |
2663 if (maybe_arrow) { | 2665 if (maybe_arrow) { |
2664 impl()->RewriteNonPattern(CHECK_OK_CUSTOM(NullExpressionList)); | 2666 impl()->RewriteNonPattern(CHECK_OK_CUSTOM(NullExpressionList)); |
2665 } | 2667 } |
2666 if (spread_arg.IsValid()) { | 2668 if (spread_arg.IsValid()) { |
2667 // Unspread parameter sequences are translated into array literals in the | 2669 // Unspread parameter sequences are translated into array literals in the |
2668 // parser. Ensure that the number of materialized literals matches between | 2670 // parser. Ensure that the number of materialized literals matches between |
2669 // the parser and preparser | 2671 // the parser and preparser |
2670 impl()->MaterializeUnspreadArgumentsLiterals(unspread_sequences_count); | 2672 if (was_unspread || spread_count > 1) { |
| 2673 // There was more than one spread, or the spread was not the final |
| 2674 // argument, so the parser will materialize literals. |
| 2675 impl()->MaterializeUnspreadArgumentsLiterals(unspread_sequences_count); |
| 2676 } |
2671 } | 2677 } |
2672 } | 2678 } |
2673 | 2679 |
2674 return result; | 2680 return result; |
2675 } | 2681 } |
2676 | 2682 |
2677 // Precedence = 2 | 2683 // Precedence = 2 |
2678 template <typename Impl> | 2684 template <typename Impl> |
2679 typename ParserBase<Impl>::ExpressionT | 2685 typename ParserBase<Impl>::ExpressionT |
2680 ParserBase<Impl>::ParseAssignmentExpression(bool accept_IN, bool* ok) { | 2686 ParserBase<Impl>::ParseAssignmentExpression(bool accept_IN, bool* ok) { |
(...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3202 // The calls that need special treatment are the | 3208 // The calls that need special treatment are the |
3203 // direct eval calls. These calls are all of the form eval(...), with | 3209 // direct eval calls. These calls are all of the form eval(...), with |
3204 // no explicit receiver. | 3210 // no explicit receiver. |
3205 // These calls are marked as potentially direct eval calls. Whether | 3211 // These calls are marked as potentially direct eval calls. Whether |
3206 // they are actually direct calls to eval is determined at run time. | 3212 // they are actually direct calls to eval is determined at run time. |
3207 Call::PossiblyEval is_possibly_eval = | 3213 Call::PossiblyEval is_possibly_eval = |
3208 CheckPossibleEvalCall(result, scope()); | 3214 CheckPossibleEvalCall(result, scope()); |
3209 | 3215 |
3210 bool is_super_call = result->IsSuperCallReference(); | 3216 bool is_super_call = result->IsSuperCallReference(); |
3211 if (spread_pos.IsValid()) { | 3217 if (spread_pos.IsValid()) { |
3212 result = impl()->SpreadCall(result, args, pos); | 3218 result = impl()->SpreadCall(result, args, pos, is_possibly_eval); |
3213 } else { | 3219 } else { |
3214 result = factory()->NewCall(result, args, pos, is_possibly_eval); | 3220 result = factory()->NewCall(result, args, pos, is_possibly_eval); |
3215 } | 3221 } |
3216 | 3222 |
3217 // Explicit calls to the super constructor using super() perform an | 3223 // Explicit calls to the super constructor using super() perform an |
3218 // implicit binding assignment to the 'this' variable. | 3224 // implicit binding assignment to the 'this' variable. |
3219 if (is_super_call) { | 3225 if (is_super_call) { |
3220 ExpressionT this_expr = impl()->ThisExpression(pos); | 3226 ExpressionT this_expr = impl()->ThisExpression(pos); |
3221 result = | 3227 result = |
3222 factory()->NewAssignment(Token::INIT, this_expr, result, pos); | 3228 factory()->NewAssignment(Token::INIT, this_expr, result, pos); |
(...skipping 2452 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5675 return; | 5681 return; |
5676 } | 5682 } |
5677 } | 5683 } |
5678 | 5684 |
5679 #undef CHECK_OK_VOID | 5685 #undef CHECK_OK_VOID |
5680 | 5686 |
5681 } // namespace internal | 5687 } // namespace internal |
5682 } // namespace v8 | 5688 } // namespace v8 |
5683 | 5689 |
5684 #endif // V8_PARSING_PARSER_BASE_H | 5690 #endif // V8_PARSING_PARSER_BASE_H |
OLD | NEW |