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 2514 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2525 // | 2525 // |
2526 // Getter :: | 2526 // Getter :: |
2527 // '(' ')' '{' FunctionBody '}' | 2527 // '(' ')' '{' FunctionBody '}' |
2528 // | 2528 // |
2529 // Setter :: | 2529 // Setter :: |
2530 // '(' PropertySetParameterList ')' '{' FunctionBody '}' | 2530 // '(' PropertySetParameterList ')' '{' FunctionBody '}' |
2531 | 2531 |
2532 int pos = function_token_pos == kNoSourcePosition ? peek_position() | 2532 int pos = function_token_pos == kNoSourcePosition ? peek_position() |
2533 : function_token_pos; | 2533 : function_token_pos; |
2534 | 2534 |
2535 bool is_generator = IsGeneratorFunction(kind); | |
2536 | |
2537 // Anonymous functions were passed either the empty symbol or a null | 2535 // Anonymous functions were passed either the empty symbol or a null |
2538 // handle as the function name. Remember if we were passed a non-empty | 2536 // handle as the function name. Remember if we were passed a non-empty |
2539 // handle to decide whether to invoke function name inference. | 2537 // handle to decide whether to invoke function name inference. |
2540 bool should_infer_name = function_name == NULL; | 2538 bool should_infer_name = function_name == NULL; |
2541 | 2539 |
2542 // We want a non-null handle as the function name. | 2540 // We want a non-null handle as the function name. |
2543 if (should_infer_name) { | 2541 if (should_infer_name) { |
2544 function_name = ast_value_factory()->empty_string(); | 2542 function_name = ast_value_factory()->empty_string(); |
2545 } | 2543 } |
2546 | 2544 |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2616 : (is_lazy_top_level_function || | 2614 : (is_lazy_top_level_function || |
2617 (allow_lazy() && function_type == FunctionLiteral::kDeclaration && | 2615 (allow_lazy() && function_type == FunctionLiteral::kDeclaration && |
2618 eager_compile_hint == FunctionLiteral::kShouldLazyCompile))) && | 2616 eager_compile_hint == FunctionLiteral::kShouldLazyCompile))) && |
2619 !(FLAG_validate_asm && scope()->IsAsmModule()); | 2617 !(FLAG_validate_asm && scope()->IsAsmModule()); |
2620 bool is_lazy_inner_function = | 2618 bool is_lazy_inner_function = |
2621 use_temp_zone && FLAG_lazy_inner_functions && !is_lazy_top_level_function; | 2619 use_temp_zone && FLAG_lazy_inner_functions && !is_lazy_top_level_function; |
2622 | 2620 |
2623 // This Scope lives in the main zone. We'll migrate data into that zone later. | 2621 // This Scope lives in the main zone. We'll migrate data into that zone later. |
2624 DeclarationScope* scope = NewFunctionScope(kind); | 2622 DeclarationScope* scope = NewFunctionScope(kind); |
2625 SetLanguageMode(scope, language_mode); | 2623 SetLanguageMode(scope, language_mode); |
| 2624 #ifdef DEBUG |
| 2625 scope->SetScopeName(function_name); |
| 2626 #endif |
2626 | 2627 |
2627 ZoneList<Statement*>* body = nullptr; | 2628 ZoneList<Statement*>* body = nullptr; |
2628 int materialized_literal_count = -1; | 2629 int materialized_literal_count = -1; |
2629 int expected_property_count = -1; | 2630 int expected_property_count = -1; |
2630 DuplicateFinder duplicate_finder(scanner()->unicode_cache()); | |
2631 bool should_be_used_once_hint = false; | 2631 bool should_be_used_once_hint = false; |
2632 bool has_duplicate_parameters; | 2632 int num_parameters = -1; |
2633 | 2633 int function_length = -1; |
2634 FunctionState function_state(&function_state_, &scope_state_, scope); | 2634 bool has_duplicate_parameters = false; |
2635 #ifdef DEBUG | |
2636 scope->SetScopeName(function_name); | |
2637 #endif | |
2638 | |
2639 ExpressionClassifier formals_classifier(this, &duplicate_finder); | |
2640 | |
2641 if (is_generator) PrepareGeneratorVariables(&function_state); | |
2642 | |
2643 Expect(Token::LPAREN, CHECK_OK); | |
2644 int start_position = scanner()->location().beg_pos; | |
2645 this->scope()->set_start_position(start_position); | |
2646 ParserFormalParameters formals(scope); | |
2647 ParseFormalParameterList(&formals, CHECK_OK); | |
2648 Expect(Token::RPAREN, CHECK_OK); | |
2649 int formals_end_position = scanner()->location().end_pos; | |
2650 | |
2651 CheckArityRestrictions(formals.arity, kind, formals.has_rest, start_position, | |
2652 formals_end_position, CHECK_OK); | |
2653 Expect(Token::LBRACE, CHECK_OK); | |
2654 | 2635 |
2655 { | 2636 { |
2656 // Temporary zones can nest. When we migrate free variables (see below), we | 2637 // Temporary zones can nest. When we migrate free variables (see below), we |
2657 // need to recreate them in the previous Zone. | 2638 // need to recreate them in the previous Zone. |
2658 AstNodeFactory previous_zone_ast_node_factory(ast_value_factory()); | 2639 AstNodeFactory previous_zone_ast_node_factory(ast_value_factory()); |
2659 previous_zone_ast_node_factory.set_zone(zone()); | 2640 previous_zone_ast_node_factory.set_zone(zone()); |
2660 | 2641 |
2661 // Open a new zone scope, which sets our AstNodeFactory to allocate in the | 2642 // Open a new zone scope, which sets our AstNodeFactory to allocate in the |
2662 // new temporary zone if the preconditions are satisfied, and ensures that | 2643 // new temporary zone if the preconditions are satisfied, and ensures that |
2663 // the previous zone is always restored after parsing the body. To be able | 2644 // the previous zone is always restored after parsing the body. To be able |
2664 // to do scope analysis correctly after full parsing, we migrate needed | 2645 // to do scope analysis correctly after full parsing, we migrate needed |
2665 // information when the function is parsed. | 2646 // information when the function is parsed. |
2666 Zone temp_zone(zone()->allocator(), ZONE_NAME); | 2647 Zone temp_zone(zone()->allocator(), ZONE_NAME); |
2667 DiscardableZoneScope zone_scope(this, &temp_zone, use_temp_zone); | 2648 DiscardableZoneScope zone_scope(this, &temp_zone, use_temp_zone); |
2668 #ifdef DEBUG | 2649 #ifdef DEBUG |
2669 if (use_temp_zone) scope->set_needs_migration(); | 2650 if (use_temp_zone) scope->set_needs_migration(); |
2670 #endif | 2651 #endif |
2671 | 2652 |
2672 // Eager or lazy parse? If is_lazy_top_level_function, we'll parse | 2653 // Eager or lazy parse? If is_lazy_top_level_function, we'll parse |
2673 // lazily. We'll call SkipLazyFunctionBody, which may decide to abort lazy | 2654 // lazily. We'll call SkipLazyFunction, which may decide to |
2674 // parsing if it suspects that wasn't a good idea. If so (in which case the | 2655 // abort lazy parsing if it suspects that wasn't a good idea. If so (in |
2675 // parser is expected to have backtracked), or if we didn't try to lazy | 2656 // which case the parser is expected to have backtracked), or if we didn't |
2676 // parse in the first place, we'll have to parse eagerly. | 2657 // try to lazy parse in the first place, we'll have to parse eagerly. |
2677 if (is_lazy_top_level_function || is_lazy_inner_function) { | 2658 if (is_lazy_top_level_function || is_lazy_inner_function) { |
2678 Scanner::BookmarkScope bookmark(scanner()); | 2659 Scanner::BookmarkScope bookmark(scanner()); |
2679 bookmark.Set(); | 2660 bookmark.Set(); |
2680 LazyParsingResult result = SkipLazyFunctionBody( | 2661 LazyParsingResult result = SkipLazyFunction( |
2681 &materialized_literal_count, &expected_property_count, | 2662 kind, scope, &num_parameters, &function_length, |
2682 is_lazy_inner_function, is_lazy_top_level_function, CHECK_OK); | 2663 &has_duplicate_parameters, &materialized_literal_count, |
2683 | 2664 &expected_property_count, is_lazy_inner_function, |
2684 materialized_literal_count += formals.materialized_literals_count + | 2665 is_lazy_top_level_function, CHECK_OK); |
2685 function_state.materialized_literal_count(); | |
2686 | 2666 |
2687 if (result == kLazyParsingAborted) { | 2667 if (result == kLazyParsingAborted) { |
2688 DCHECK(is_lazy_top_level_function); | 2668 DCHECK(is_lazy_top_level_function); |
2689 bookmark.Apply(); | 2669 bookmark.Apply(); |
2690 // Trigger eager (re-)parsing, just below this block. | 2670 // Trigger eager (re-)parsing, just below this block. |
2691 is_lazy_top_level_function = false; | 2671 is_lazy_top_level_function = false; |
2692 | 2672 |
2693 // This is probably an initialization function. Inform the compiler it | 2673 // This is probably an initialization function. Inform the compiler it |
2694 // should also eager-compile this function, and that we expect it to be | 2674 // should also eager-compile this function, and that we expect it to be |
2695 // used once. | 2675 // used once. |
2696 eager_compile_hint = FunctionLiteral::kShouldEagerCompile; | 2676 eager_compile_hint = FunctionLiteral::kShouldEagerCompile; |
2697 should_be_used_once_hint = true; | 2677 should_be_used_once_hint = true; |
2698 scope->ResetAfterPreparsing(ast_value_factory(), true); | 2678 scope->ResetAfterPreparsing(ast_value_factory(), true); |
2699 zone_scope.Reset(); | 2679 zone_scope.Reset(); |
2700 use_temp_zone = false; | 2680 use_temp_zone = false; |
2701 } | 2681 } |
2702 } | 2682 } |
2703 | 2683 |
2704 if (!is_lazy_top_level_function && !is_lazy_inner_function) { | 2684 if (!is_lazy_top_level_function && !is_lazy_inner_function) { |
2705 body = ParseEagerFunctionBody(function_name, pos, formals, kind, | 2685 body = ParseFunctionParametersAndBodyEagerly( |
2706 function_type, CHECK_OK); | 2686 function_name, pos, kind, function_type, scope, &num_parameters, |
2707 | 2687 &function_length, &has_duplicate_parameters, |
2708 materialized_literal_count = function_state.materialized_literal_count(); | 2688 &materialized_literal_count, &expected_property_count, CHECK_OK); |
2709 expected_property_count = function_state.expected_property_count(); | |
2710 } | 2689 } |
2711 | 2690 |
2712 DCHECK(use_temp_zone || !is_lazy_top_level_function); | 2691 DCHECK(use_temp_zone || !is_lazy_top_level_function); |
2713 if (use_temp_zone) { | 2692 if (use_temp_zone) { |
2714 // If the preconditions are correct the function body should never be | 2693 // If the preconditions are correct the function body should never be |
2715 // accessed, but do this anyway for better behaviour if they're wrong. | 2694 // accessed, but do this anyway for better behaviour if they're wrong. |
2716 body = nullptr; | 2695 body = nullptr; |
2717 scope->AnalyzePartially(&previous_zone_ast_node_factory); | 2696 scope->AnalyzePartially(&previous_zone_ast_node_factory); |
2718 } | 2697 } |
2719 | 2698 |
2720 if (FLAG_trace_preparse) { | 2699 if (FLAG_trace_preparse) { |
2721 PrintF(" [%s]: %i-%i %.*s\n", | 2700 PrintF(" [%s]: %i-%i %.*s\n", |
2722 is_lazy_top_level_function | 2701 is_lazy_top_level_function |
2723 ? "Preparse no-resolution" | 2702 ? "Preparse no-resolution" |
2724 : (use_temp_zone ? "Preparse resolution" : "Full parse"), | 2703 : (use_temp_zone ? "Preparse resolution" : "Full parse"), |
2725 scope->start_position(), scope->end_position(), | 2704 scope->start_position(), scope->end_position(), |
2726 function_name->byte_length(), function_name->raw_data()); | 2705 function_name->byte_length(), function_name->raw_data()); |
2727 } | 2706 } |
2728 | 2707 |
2729 // Parsing the body may change the language mode in our scope. | 2708 // Validate function name. We can do this only after parsing the function, |
| 2709 // since the function can declare itself strict. |
2730 language_mode = scope->language_mode(); | 2710 language_mode = scope->language_mode(); |
2731 | |
2732 // Validate name and parameter names. We can do this only after parsing the | |
2733 // function, since the function can declare itself strict. | |
2734 CheckFunctionName(language_mode, function_name, function_name_validity, | 2711 CheckFunctionName(language_mode, function_name, function_name_validity, |
2735 function_name_location, CHECK_OK); | 2712 function_name_location, CHECK_OK); |
2736 const bool allow_duplicate_parameters = | |
2737 is_sloppy(language_mode) && formals.is_simple && !IsConciseMethod(kind); | |
2738 ValidateFormalParameters(language_mode, allow_duplicate_parameters, | |
2739 CHECK_OK); | |
2740 | 2713 |
2741 if (is_strict(language_mode)) { | 2714 if (is_strict(language_mode)) { |
2742 CheckStrictOctalLiteral(scope->start_position(), scope->end_position(), | 2715 CheckStrictOctalLiteral(scope->start_position(), scope->end_position(), |
2743 CHECK_OK); | 2716 CHECK_OK); |
2744 CheckDecimalLiteralWithLeadingZero(scope->start_position(), | 2717 CheckDecimalLiteralWithLeadingZero(scope->start_position(), |
2745 scope->end_position()); | 2718 scope->end_position()); |
2746 } | 2719 } |
2747 CheckConflictingVarDeclarations(scope, CHECK_OK); | 2720 CheckConflictingVarDeclarations(scope, CHECK_OK); |
2748 | |
2749 if (body) { | |
2750 // If body can be inspected, rewrite queued destructuring assignments | |
2751 RewriteDestructuringAssignments(); | |
2752 } | |
2753 has_duplicate_parameters = | |
2754 !classifier()->is_valid_formal_parameter_list_without_duplicates(); | |
2755 } // DiscardableZoneScope goes out of scope. | 2721 } // DiscardableZoneScope goes out of scope. |
2756 | 2722 |
2757 FunctionLiteral::ParameterFlag duplicate_parameters = | 2723 FunctionLiteral::ParameterFlag duplicate_parameters = |
2758 has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters | 2724 has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters |
2759 : FunctionLiteral::kNoDuplicateParameters; | 2725 : FunctionLiteral::kNoDuplicateParameters; |
2760 | 2726 |
2761 // Note that the FunctionLiteral needs to be created in the main Zone again. | 2727 // Note that the FunctionLiteral needs to be created in the main Zone again. |
2762 FunctionLiteral* function_literal = factory()->NewFunctionLiteral( | 2728 FunctionLiteral* function_literal = factory()->NewFunctionLiteral( |
2763 function_name, scope, body, materialized_literal_count, | 2729 function_name, scope, body, materialized_literal_count, |
2764 expected_property_count, formals.num_parameters(), | 2730 expected_property_count, num_parameters, function_length, |
2765 formals.function_length, duplicate_parameters, function_type, | 2731 duplicate_parameters, function_type, eager_compile_hint, pos); |
2766 eager_compile_hint, pos); | |
2767 function_literal->set_function_token_position(function_token_pos); | 2732 function_literal->set_function_token_position(function_token_pos); |
2768 if (should_be_used_once_hint) | 2733 if (should_be_used_once_hint) |
2769 function_literal->set_should_be_used_once_hint(); | 2734 function_literal->set_should_be_used_once_hint(); |
2770 | 2735 |
2771 if (should_infer_name) { | 2736 if (should_infer_name) { |
2772 DCHECK_NOT_NULL(fni_); | 2737 DCHECK_NOT_NULL(fni_); |
2773 fni_->AddFunction(function_literal); | 2738 fni_->AddFunction(function_literal); |
2774 } | 2739 } |
2775 return function_literal; | 2740 return function_literal; |
2776 } | 2741 } |
2777 | 2742 |
2778 Parser::LazyParsingResult Parser::SkipLazyFunctionBody( | 2743 Parser::LazyParsingResult Parser::SkipLazyFunction( |
| 2744 FunctionKind kind, DeclarationScope* function_scope, int* num_parameters, |
| 2745 int* function_length, bool* has_duplicate_parameters, |
2779 int* materialized_literal_count, int* expected_property_count, | 2746 int* materialized_literal_count, int* expected_property_count, |
2780 bool is_inner_function, bool may_abort, bool* ok) { | 2747 bool is_inner_function, bool may_abort, bool* ok) { |
2781 if (produce_cached_parse_data()) CHECK(log_); | 2748 if (produce_cached_parse_data()) CHECK(log_); |
2782 | 2749 |
2783 int function_block_pos = position(); | 2750 // For normal functions, this is the position just before the left paren |
2784 DeclarationScope* scope = function_state_->scope(); | 2751 // (assuming the function is syntactically correct - however, it might not be, |
2785 DCHECK(scope->is_function_scope()); | 2752 // so we cannot DCHECK for Token::LPAREN here). For arrow functions, this is |
| 2753 // the position of the arrow. |
| 2754 int cache_key_position = peek_position(); |
| 2755 DCHECK_IMPLIES((kind & FunctionKind::kArrowFunction) != 0, |
| 2756 scanner()->current_token() == Token::ARROW); |
| 2757 |
2786 // Inner functions are not part of the cached data. | 2758 // Inner functions are not part of the cached data. |
2787 if (!is_inner_function && consume_cached_parse_data() && | 2759 if (!is_inner_function && consume_cached_parse_data() && |
2788 !cached_parse_data_->rejected()) { | 2760 !cached_parse_data_->rejected()) { |
2789 // If we have cached data, we use it to skip parsing the function body. The | 2761 // If we have cached data, we use it to skip parsing the function. The data |
2790 // data contains the information we need to construct the lazy function. | 2762 // contains the information we need to construct the lazy function. |
2791 FunctionEntry entry = | 2763 FunctionEntry entry = |
2792 cached_parse_data_->GetFunctionEntry(function_block_pos); | 2764 cached_parse_data_->GetFunctionEntry(cache_key_position); |
2793 // Check that cached data is valid. If not, mark it as invalid (the embedder | 2765 // Check that cached data is valid. If not, mark it as invalid (the embedder |
2794 // handles it). Note that end position greater than end of stream is safe, | 2766 // handles it). Note that end position greater than end of stream is safe, |
2795 // and hard to check. | 2767 // and hard to check. |
2796 if (entry.is_valid() && entry.end_pos() > function_block_pos) { | 2768 if (entry.is_valid() && entry.end_pos() > cache_key_position) { |
2797 scanner()->SeekForward(entry.end_pos() - 1); | 2769 scanner()->SeekForward(entry.end_pos() - 1); |
2798 | 2770 // We need the start position separately from the cache key, since for |
2799 scope->set_end_position(entry.end_pos()); | 2771 // arrow functions, the scope start position is at the lparen of the |
| 2772 // parameter list, and we've already read past it. |
| 2773 function_scope->set_start_position(entry.start_pos()); |
| 2774 function_scope->set_end_position(entry.end_pos()); |
2800 Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete)); | 2775 Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete)); |
2801 total_preparse_skipped_ += scope->end_position() - function_block_pos; | 2776 total_preparse_skipped_ += |
| 2777 function_scope->end_position() - function_scope->start_position(); |
| 2778 *num_parameters = entry.num_parameters(); |
| 2779 *function_length = entry.function_length(); |
| 2780 *has_duplicate_parameters = entry.has_duplicate_parameters(); |
2802 *materialized_literal_count = entry.literal_count(); | 2781 *materialized_literal_count = entry.literal_count(); |
2803 *expected_property_count = entry.property_count(); | 2782 *expected_property_count = entry.property_count(); |
2804 SetLanguageMode(scope, entry.language_mode()); | 2783 SetLanguageMode(function_scope, entry.language_mode()); |
2805 if (entry.uses_super_property()) scope->RecordSuperPropertyUsage(); | 2784 if (entry.uses_super_property()) |
2806 if (entry.calls_eval()) scope->RecordEvalCall(); | 2785 function_scope->RecordSuperPropertyUsage(); |
| 2786 if (entry.calls_eval()) function_scope->RecordEvalCall(); |
2807 return kLazyParsingComplete; | 2787 return kLazyParsingComplete; |
2808 } | 2788 } |
2809 cached_parse_data_->Reject(); | 2789 cached_parse_data_->Reject(); |
2810 } | 2790 } |
2811 // With no cached data, we partially parse the function, without building an | 2791 // With no cached data, we partially parse the function, without building an |
2812 // AST. This gathers the data needed to build a lazy function. | 2792 // AST. This gathers the data needed to build a lazy function. |
2813 SingletonLogger logger; | 2793 SingletonLogger logger; |
2814 PreParser::PreParseResult result = | 2794 PreParser::PreParseResult result = ParseFunctionWithPreParser( |
2815 ParseFunctionBodyWithPreParser(&logger, is_inner_function, may_abort); | 2795 kind, function_scope, &logger, is_inner_function, may_abort); |
2816 | 2796 |
2817 // Return immediately if pre-parser decided to abort parsing. | 2797 // Return immediately if pre-parser decided to abort parsing. |
2818 if (result == PreParser::kPreParseAbort) return kLazyParsingAborted; | 2798 if (result == PreParser::kPreParseAbort) return kLazyParsingAborted; |
2819 if (result == PreParser::kPreParseStackOverflow) { | 2799 if (result == PreParser::kPreParseStackOverflow) { |
2820 // Propagate stack overflow. | 2800 // Propagate stack overflow. |
2821 set_stack_overflow(); | 2801 set_stack_overflow(); |
2822 *ok = false; | 2802 *ok = false; |
2823 return kLazyParsingComplete; | 2803 return kLazyParsingComplete; |
2824 } | 2804 } |
2825 if (logger.has_error()) { | 2805 if (logger.has_error()) { |
2826 ReportMessageAt(Scanner::Location(logger.start(), logger.end()), | 2806 ReportMessageAt(Scanner::Location(logger.start(), logger.end()), |
2827 logger.message(), logger.argument_opt(), | 2807 logger.message(), logger.argument_opt(), |
2828 logger.error_type()); | 2808 logger.error_type()); |
2829 *ok = false; | 2809 *ok = false; |
2830 return kLazyParsingComplete; | 2810 return kLazyParsingComplete; |
2831 } | 2811 } |
2832 scope->set_end_position(logger.end()); | 2812 DCHECK_NE(kNoSourcePosition, function_scope->start_position()); |
| 2813 function_scope->set_end_position(logger.end()); |
2833 Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete)); | 2814 Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete)); |
2834 total_preparse_skipped_ += scope->end_position() - function_block_pos; | 2815 total_preparse_skipped_ += |
| 2816 function_scope->end_position() - function_scope->start_position(); |
| 2817 *num_parameters = logger.num_parameters(); |
| 2818 *function_length = logger.function_length(); |
| 2819 *has_duplicate_parameters = logger.has_duplicate_parameters(); |
2835 *materialized_literal_count = logger.literals(); | 2820 *materialized_literal_count = logger.literals(); |
2836 *expected_property_count = logger.properties(); | 2821 *expected_property_count = logger.properties(); |
2837 SetLanguageMode(scope, logger.language_mode()); | 2822 SetLanguageMode(function_scope, logger.language_mode()); |
2838 if (logger.uses_super_property()) scope->RecordSuperPropertyUsage(); | 2823 if (logger.uses_super_property()) function_scope->RecordSuperPropertyUsage(); |
2839 if (logger.calls_eval()) scope->RecordEvalCall(); | 2824 if (logger.calls_eval()) function_scope->RecordEvalCall(); |
2840 if (!is_inner_function && produce_cached_parse_data()) { | 2825 if (!is_inner_function && produce_cached_parse_data()) { |
2841 DCHECK(log_); | 2826 DCHECK(log_); |
2842 // Position right after terminal '}'. | 2827 log_->LogFunction(cache_key_position, function_scope->start_position(), |
2843 int body_end = scanner()->location().end_pos; | 2828 function_scope->end_position(), *num_parameters, |
2844 log_->LogFunction(function_block_pos, body_end, *materialized_literal_count, | 2829 *function_length, *has_duplicate_parameters, |
2845 *expected_property_count, language_mode(), | 2830 *materialized_literal_count, *expected_property_count, |
2846 scope->uses_super_property(), scope->calls_eval()); | 2831 language_mode(), function_scope->uses_super_property(), |
| 2832 function_scope->calls_eval()); |
2847 } | 2833 } |
2848 return kLazyParsingComplete; | 2834 return kLazyParsingComplete; |
2849 } | 2835 } |
2850 | 2836 |
2851 | 2837 |
2852 Statement* Parser::BuildAssertIsCoercible(Variable* var) { | 2838 Statement* Parser::BuildAssertIsCoercible(Variable* var) { |
2853 // if (var === null || var === undefined) | 2839 // if (var === null || var === undefined) |
2854 // throw /* type error kNonCoercible) */; | 2840 // throw /* type error kNonCoercible) */; |
2855 | 2841 |
2856 Expression* condition = factory()->NewBinaryOperation( | 2842 Expression* condition = factory()->NewBinaryOperation( |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3109 Token::INIT, init_proxy, allocation, kNoSourcePosition); | 3095 Token::INIT, init_proxy, allocation, kNoSourcePosition); |
3110 VariableProxy* get_proxy = | 3096 VariableProxy* get_proxy = |
3111 factory()->NewVariableProxy(function_state_->generator_object_variable()); | 3097 factory()->NewVariableProxy(function_state_->generator_object_variable()); |
3112 // The position of the yield is important for reporting the exception | 3098 // The position of the yield is important for reporting the exception |
3113 // caused by calling the .throw method on a generator suspended at the | 3099 // caused by calling the .throw method on a generator suspended at the |
3114 // initial yield (i.e. right after generator instantiation). | 3100 // initial yield (i.e. right after generator instantiation). |
3115 return factory()->NewYield(get_proxy, assignment, scope()->start_position(), | 3101 return factory()->NewYield(get_proxy, assignment, scope()->start_position(), |
3116 Yield::kOnExceptionThrow); | 3102 Yield::kOnExceptionThrow); |
3117 } | 3103 } |
3118 | 3104 |
| 3105 ZoneList<Statement*>* Parser::ParseFunctionParametersAndBodyEagerly( |
| 3106 const AstRawString* function_name, int pos, FunctionKind kind, |
| 3107 FunctionLiteral::FunctionType function_type, |
| 3108 DeclarationScope* function_scope, int* num_parameters, int* function_length, |
| 3109 bool* has_duplicate_parameters, int* materialized_literal_count, |
| 3110 int* expected_property_count, bool* ok) { |
| 3111 FunctionState function_state(&function_state_, &scope_state_, function_scope); |
| 3112 |
| 3113 DuplicateFinder duplicate_finder(scanner()->unicode_cache()); |
| 3114 ExpressionClassifier formals_classifier(this, &duplicate_finder); |
| 3115 |
| 3116 if (IsGeneratorFunction(kind)) PrepareGeneratorVariables(&function_state); |
| 3117 |
| 3118 Expect(Token::LPAREN, CHECK_OK); |
| 3119 int start_position = scanner()->location().beg_pos; |
| 3120 function_scope->set_start_position(start_position); |
| 3121 ParserFormalParameters formals(function_scope); |
| 3122 ParseFormalParameterList(&formals, CHECK_OK); |
| 3123 Expect(Token::RPAREN, CHECK_OK); |
| 3124 int formals_end_position = scanner()->location().end_pos; |
| 3125 *num_parameters = formals.num_parameters(); |
| 3126 *function_length = formals.function_length; |
| 3127 |
| 3128 CheckArityRestrictions(formals.arity, kind, formals.has_rest, start_position, |
| 3129 formals_end_position, CHECK_OK); |
| 3130 Expect(Token::LBRACE, CHECK_OK); |
| 3131 |
| 3132 ZoneList<Statement*>* body = ParseEagerFunctionBody( |
| 3133 function_name, pos, formals, kind, function_type, ok); |
| 3134 |
| 3135 // Validate parameter names. We can do this only after parsing the function, |
| 3136 // since the function can declare itself strict. |
| 3137 const bool allow_duplicate_parameters = |
| 3138 is_sloppy(function_scope->language_mode()) && formals.is_simple && |
| 3139 !IsConciseMethod(kind); |
| 3140 ValidateFormalParameters(function_scope->language_mode(), |
| 3141 allow_duplicate_parameters, CHECK_OK); |
| 3142 |
| 3143 RewriteDestructuringAssignments(); |
| 3144 |
| 3145 *has_duplicate_parameters = |
| 3146 !classifier()->is_valid_formal_parameter_list_without_duplicates(); |
| 3147 |
| 3148 *materialized_literal_count = function_state.materialized_literal_count(); |
| 3149 *expected_property_count = function_state.expected_property_count(); |
| 3150 return body; |
| 3151 } |
| 3152 |
3119 ZoneList<Statement*>* Parser::ParseEagerFunctionBody( | 3153 ZoneList<Statement*>* Parser::ParseEagerFunctionBody( |
3120 const AstRawString* function_name, int pos, | 3154 const AstRawString* function_name, int pos, |
3121 const ParserFormalParameters& parameters, FunctionKind kind, | 3155 const ParserFormalParameters& parameters, FunctionKind kind, |
3122 FunctionLiteral::FunctionType function_type, bool* ok) { | 3156 FunctionLiteral::FunctionType function_type, bool* ok) { |
3123 ParsingModeScope mode(this, allow_lazy() ? PARSE_LAZILY : PARSE_EAGERLY); | 3157 ParsingModeScope mode(this, allow_lazy() ? PARSE_LAZILY : PARSE_EAGERLY); |
3124 ZoneList<Statement*>* result = new(zone()) ZoneList<Statement*>(8, zone()); | 3158 ZoneList<Statement*>* result = new(zone()) ZoneList<Statement*>(8, zone()); |
3125 | 3159 |
3126 static const int kFunctionNameAssignmentIndex = 0; | 3160 static const int kFunctionNameAssignmentIndex = 0; |
3127 if (function_type == FunctionLiteral::kNamedExpression) { | 3161 if (function_type == FunctionLiteral::kNamedExpression) { |
3128 DCHECK(function_name != NULL); | 3162 DCHECK(function_name != NULL); |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3265 } else { | 3299 } else { |
3266 statement = factory()->NewEmptyStatement(kNoSourcePosition); | 3300 statement = factory()->NewEmptyStatement(kNoSourcePosition); |
3267 } | 3301 } |
3268 result->Set(kFunctionNameAssignmentIndex, statement); | 3302 result->Set(kFunctionNameAssignmentIndex, statement); |
3269 } | 3303 } |
3270 | 3304 |
3271 MarkCollectedTailCallExpressions(); | 3305 MarkCollectedTailCallExpressions(); |
3272 return result; | 3306 return result; |
3273 } | 3307 } |
3274 | 3308 |
3275 PreParser::PreParseResult Parser::ParseFunctionBodyWithPreParser( | 3309 PreParser::PreParseResult Parser::ParseFunctionWithPreParser( |
| 3310 FunctionKind kind, DeclarationScope* function_scope, |
3276 SingletonLogger* logger, bool is_inner_function, bool may_abort) { | 3311 SingletonLogger* logger, bool is_inner_function, bool may_abort) { |
3277 // This function may be called on a background thread too; record only the | 3312 // This function may be called on a background thread too; record only the |
3278 // main thread preparse times. | 3313 // main thread preparse times. |
3279 if (pre_parse_timer_ != NULL) { | 3314 if (pre_parse_timer_ != NULL) { |
3280 pre_parse_timer_->Start(); | 3315 pre_parse_timer_->Start(); |
3281 } | 3316 } |
3282 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.PreParse"); | 3317 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.PreParse"); |
3283 | 3318 |
3284 DCHECK_EQ(Token::LBRACE, scanner()->current_token()); | |
3285 | |
3286 if (reusable_preparser_ == NULL) { | 3319 if (reusable_preparser_ == NULL) { |
3287 reusable_preparser_ = new PreParser(zone(), &scanner_, ast_value_factory(), | 3320 reusable_preparser_ = new PreParser(zone(), &scanner_, ast_value_factory(), |
3288 NULL, stack_limit_); | 3321 NULL, stack_limit_); |
3289 reusable_preparser_->set_allow_lazy(true); | 3322 reusable_preparser_->set_allow_lazy(true); |
3290 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name()); | 3323 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name()); |
3291 SET_ALLOW(natives); | 3324 SET_ALLOW(natives); |
3292 SET_ALLOW(harmony_do_expressions); | 3325 SET_ALLOW(harmony_do_expressions); |
3293 SET_ALLOW(harmony_function_sent); | 3326 SET_ALLOW(harmony_function_sent); |
3294 SET_ALLOW(harmony_restrictive_declarations); | 3327 SET_ALLOW(harmony_restrictive_declarations); |
3295 SET_ALLOW(harmony_async_await); | 3328 SET_ALLOW(harmony_async_await); |
3296 SET_ALLOW(harmony_trailing_commas); | 3329 SET_ALLOW(harmony_trailing_commas); |
3297 SET_ALLOW(harmony_class_fields); | 3330 SET_ALLOW(harmony_class_fields); |
3298 #undef SET_ALLOW | 3331 #undef SET_ALLOW |
3299 } | 3332 } |
3300 // Aborting inner function preparsing would leave scopes in an inconsistent | 3333 // Aborting inner function preparsing would leave scopes in an inconsistent |
3301 // state; we don't parse inner functions in the abortable mode anyway. | 3334 // state; we don't parse inner functions in the abortable mode anyway. |
3302 DCHECK(!is_inner_function || !may_abort); | 3335 DCHECK(!is_inner_function || !may_abort); |
3303 | 3336 |
3304 DeclarationScope* function_scope = function_state_->scope(); | |
3305 PreParser::PreParseResult result = reusable_preparser_->PreParseFunction( | 3337 PreParser::PreParseResult result = reusable_preparser_->PreParseFunction( |
3306 function_scope, parsing_module_, logger, is_inner_function, may_abort, | 3338 kind, function_scope, parsing_module_, logger, is_inner_function, |
3307 use_counts_); | 3339 may_abort, use_counts_); |
3308 if (pre_parse_timer_ != NULL) { | 3340 if (pre_parse_timer_ != NULL) { |
3309 pre_parse_timer_->Stop(); | 3341 pre_parse_timer_->Stop(); |
3310 } | 3342 } |
3311 return result; | 3343 return result; |
3312 } | 3344 } |
3313 | 3345 |
3314 Expression* Parser::InstallHomeObject(Expression* function_literal, | 3346 Expression* Parser::InstallHomeObject(Expression* function_literal, |
3315 Expression* home_object) { | 3347 Expression* home_object) { |
3316 Block* do_block = factory()->NewBlock(nullptr, 1, false, kNoSourcePosition); | 3348 Block* do_block = factory()->NewBlock(nullptr, 1, false, kNoSourcePosition); |
3317 Variable* result_var = | 3349 Variable* result_var = |
(...skipping 2103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5421 | 5453 |
5422 return final_loop; | 5454 return final_loop; |
5423 } | 5455 } |
5424 | 5456 |
5425 #undef CHECK_OK | 5457 #undef CHECK_OK |
5426 #undef CHECK_OK_VOID | 5458 #undef CHECK_OK_VOID |
5427 #undef CHECK_FAILED | 5459 #undef CHECK_FAILED |
5428 | 5460 |
5429 } // namespace internal | 5461 } // namespace internal |
5430 } // namespace v8 | 5462 } // namespace v8 |
OLD | NEW |