Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/parsing/parser.cc

Issue 2373443003: Revert of Preparse inner functions (new try) (Closed)
Patch Set: Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/parsing/parser.h ('k') | src/parsing/parser-base.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 public: 115 public:
116 DiscardableZoneScope(Parser* parser, Zone* temp_zone, bool use_temp_zone) 116 DiscardableZoneScope(Parser* parser, Zone* temp_zone, bool use_temp_zone)
117 : ast_node_factory_scope_(parser->factory(), temp_zone, use_temp_zone), 117 : ast_node_factory_scope_(parser->factory(), temp_zone, use_temp_zone),
118 fni_(parser->ast_value_factory_, temp_zone), 118 fni_(parser->ast_value_factory_, temp_zone),
119 parser_(parser), 119 parser_(parser),
120 prev_fni_(parser->fni_), 120 prev_fni_(parser->fni_),
121 prev_zone_(parser->zone_) { 121 prev_zone_(parser->zone_) {
122 if (use_temp_zone) { 122 if (use_temp_zone) {
123 parser_->fni_ = &fni_; 123 parser_->fni_ = &fni_;
124 parser_->zone_ = temp_zone; 124 parser_->zone_ = temp_zone;
125 if (parser_->reusable_preparser_ != nullptr) {
126 parser_->reusable_preparser_->zone_ = temp_zone;
127 }
128 } 125 }
129 } 126 }
130 ~DiscardableZoneScope() { 127 ~DiscardableZoneScope() {
131 parser_->fni_ = prev_fni_; 128 parser_->fni_ = prev_fni_;
132 parser_->zone_ = prev_zone_; 129 parser_->zone_ = prev_zone_;
133 if (parser_->reusable_preparser_ != nullptr) {
134 parser_->reusable_preparser_->zone_ = prev_zone_;
135 }
136 } 130 }
137 131
138 private: 132 private:
139 AstNodeFactory::BodyScope ast_node_factory_scope_; 133 AstNodeFactory::BodyScope ast_node_factory_scope_;
140 FuncNameInferrer fni_; 134 FuncNameInferrer fni_;
141 Parser* parser_; 135 Parser* parser_;
142 FuncNameInferrer* prev_fni_; 136 FuncNameInferrer* prev_fni_;
143 Zone* prev_zone_; 137 Zone* prev_zone_;
144 138
145 DISALLOW_COPY_AND_ASSIGN(DiscardableZoneScope); 139 DISALLOW_COPY_AND_ASSIGN(DiscardableZoneScope);
(...skipping 2536 matching lines...) Expand 10 before | Expand all | Expand 10 after
2682 // - It must not have been prohibited by the caller to Parse (some callers 2676 // - It must not have been prohibited by the caller to Parse (some callers
2683 // need a full AST). 2677 // need a full AST).
2684 // - The outer scope must allow lazy compilation of inner functions. 2678 // - The outer scope must allow lazy compilation of inner functions.
2685 // - The function mustn't be a function expression with an open parenthesis 2679 // - The function mustn't be a function expression with an open parenthesis
2686 // before; we consider that a hint that the function will be called 2680 // before; we consider that a hint that the function will be called
2687 // immediately, and it would be a waste of time to make it lazily 2681 // immediately, and it would be a waste of time to make it lazily
2688 // compiled. 2682 // compiled.
2689 // These are all things we can know at this point, without looking at the 2683 // These are all things we can know at this point, without looking at the
2690 // function itself. 2684 // function itself.
2691 2685
2692 // We separate between lazy parsing top level functions and lazy parsing inner 2686 // In addition, we need to distinguish between these cases:
2693 // functions, because the latter needs to do more work. In particular, we need
2694 // to track unresolved variables to distinguish between these cases:
2695 // (function foo() { 2687 // (function foo() {
2696 // bar = function() { return 1; } 2688 // bar = function() { return 1; }
2697 // })(); 2689 // })();
2698 // and 2690 // and
2699 // (function foo() { 2691 // (function foo() {
2700 // var a = 1; 2692 // var a = 1;
2701 // bar = function() { return a; } 2693 // bar = function() { return a; }
2702 // })(); 2694 // })();
2703 2695
2704 // Now foo will be parsed eagerly and compiled eagerly (optimization: assume 2696 // Now foo will be parsed eagerly and compiled eagerly (optimization: assume
2705 // parenthesis before the function means that it will be called 2697 // parenthesis before the function means that it will be called
2706 // immediately). bar can be parsed lazily, but we need to parse it in a mode 2698 // immediately). The inner function *must* be parsed eagerly to resolve the
2707 // that tracks unresolved variables. 2699 // possible reference to the variable in foo's scope. However, it's possible
2708 DCHECK_IMPLIES(mode() == PARSE_LAZILY, FLAG_lazy); 2700 // that it will be compiled lazily.
2709 DCHECK_IMPLIES(mode() == PARSE_LAZILY, allow_lazy());
2710 DCHECK_IMPLIES(mode() == PARSE_LAZILY, extension_ == nullptr);
2711 2701
2712 bool is_lazy_top_level_function = 2702 // To make this additional case work, both Parser and PreParser implement a
2713 mode() == PARSE_LAZILY && 2703 // logic where only top-level functions will be parsed lazily.
2714 eager_compile_hint == FunctionLiteral::kShouldLazyCompile && 2704 bool is_lazily_parsed = mode() == PARSE_LAZILY &&
2715 scope()->AllowsLazyParsingWithoutUnresolvedVariables(); 2705 scope()->AllowsLazyParsing() &&
2706 !function_state_->next_function_is_parenthesized();
2716 2707
2717 // Determine whether we can still lazy parse the inner function. 2708 // Determine whether the function body can be discarded after parsing.
2718 // The preconditions are: 2709 // The preconditions are:
2719 // - Lazy compilation has to be enabled. 2710 // - Lazy compilation has to be enabled.
2720 // - Neither V8 natives nor native function declarations can be allowed, 2711 // - Neither V8 natives nor native function declarations can be allowed,
2721 // since parsing one would retroactively force the function to be 2712 // since parsing one would retroactively force the function to be
2722 // eagerly compiled. 2713 // eagerly compiled.
2723 // - The invoker of this parser can't depend on the AST being eagerly 2714 // - The invoker of this parser can't depend on the AST being eagerly
2724 // built (either because the function is about to be compiled, or 2715 // built (either because the function is about to be compiled, or
2725 // because the AST is going to be inspected for some reason). 2716 // because the AST is going to be inspected for some reason).
2726 // - Because of the above, we can't be attempting to parse a 2717 // - Because of the above, we can't be attempting to parse a
2727 // FunctionExpression; even without enclosing parentheses it might be 2718 // FunctionExpression; even without enclosing parentheses it might be
2728 // immediately invoked. 2719 // immediately invoked.
2729 // - The function literal shouldn't be hinted to eagerly compile. 2720 // - The function literal shouldn't be hinted to eagerly compile.
2730 // - For asm.js functions the body needs to be available when module 2721 // - For asm.js functions the body needs to be available when module
2731 // validation is active, because we examine the entire module at once. 2722 // validation is active, because we examine the entire module at once.
2732
2733 // Inner functions will be parsed using a temporary Zone. After parsing, we
2734 // will migrate unresolved variable into a Scope in the main Zone.
2735 // TODO(marja): Refactor parsing modes: simplify this.
2736 bool use_temp_zone = 2723 bool use_temp_zone =
2737 !is_lazy_top_level_function && allow_lazy() && 2724 !is_lazily_parsed && allow_lazy() &&
2738 function_type == FunctionLiteral::kDeclaration && 2725 function_type == FunctionLiteral::kDeclaration &&
2739 eager_compile_hint != FunctionLiteral::kShouldEagerCompile && 2726 eager_compile_hint != FunctionLiteral::kShouldEagerCompile &&
2740 !(FLAG_validate_asm && scope()->IsAsmModule()); 2727 !(FLAG_validate_asm && scope()->IsAsmModule());
2741 bool is_lazy_inner_function = use_temp_zone && FLAG_lazy_inner_functions;
2742 2728
2743 DeclarationScope* main_scope = nullptr; 2729 DeclarationScope* main_scope = nullptr;
2744 if (use_temp_zone) { 2730 if (use_temp_zone) {
2745 // This Scope lives in the main Zone; we'll migrate data into it later. 2731 // This Scope lives in the main Zone; we'll migrate data into it later.
2746 main_scope = NewFunctionScope(kind); 2732 main_scope = NewFunctionScope(kind);
2747 } 2733 }
2748 2734
2749 ZoneList<Statement*>* body = nullptr; 2735 ZoneList<Statement*>* body = nullptr;
2750 int arity = -1; 2736 int arity = -1;
2751 int materialized_literal_count = -1; 2737 int materialized_literal_count = -1;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
2807 int formals_end_position = scanner()->location().end_pos; 2793 int formals_end_position = scanner()->location().end_pos;
2808 2794
2809 CheckArityRestrictions(arity, kind, formals.has_rest, start_position, 2795 CheckArityRestrictions(arity, kind, formals.has_rest, start_position,
2810 formals_end_position, CHECK_OK); 2796 formals_end_position, CHECK_OK);
2811 Expect(Token::LBRACE, CHECK_OK); 2797 Expect(Token::LBRACE, CHECK_OK);
2812 // Don't include the rest parameter into the function's formal parameter 2798 // Don't include the rest parameter into the function's formal parameter
2813 // count (esp. the SharedFunctionInfo::internal_formal_parameter_count, 2799 // count (esp. the SharedFunctionInfo::internal_formal_parameter_count,
2814 // which says whether we need to create an arguments adaptor frame). 2800 // which says whether we need to create an arguments adaptor frame).
2815 if (formals.has_rest) arity--; 2801 if (formals.has_rest) arity--;
2816 2802
2817 // Eager or lazy parse? If is_lazy_top_level_function, we'll parse 2803 // Eager or lazy parse?
2818 // lazily. We'll call SkipLazyFunctionBody, which may decide to abort lazy 2804 // If is_lazily_parsed, we'll parse lazily. We'll call SkipLazyFunctionBody,
2819 // parsing if it suspects that wasn't a good idea. If so (in which case the 2805 // which may decide to abort lazy parsing if it suspects that wasn't a good
2820 // parser is expected to have backtracked), or if we didn't try to lazy 2806 // idea. If so (in which case the parser is expected to have backtracked),
2821 // parse in the first place, we'll have to parse eagerly. 2807 // or if we didn't try to lazy parse in the first place, we'll have to parse
2822 if (is_lazy_top_level_function || is_lazy_inner_function) { 2808 // eagerly.
2809 if (is_lazily_parsed) {
2823 Scanner::BookmarkScope bookmark(scanner()); 2810 Scanner::BookmarkScope bookmark(scanner());
2824 bookmark.Set(); 2811 bookmark.Set();
2825 LazyParsingResult result = SkipLazyFunctionBody( 2812 LazyParsingResult result =
2826 &materialized_literal_count, &expected_property_count, 2813 SkipLazyFunctionBody(&materialized_literal_count,
2827 is_lazy_inner_function, is_lazy_top_level_function, CHECK_OK); 2814 &expected_property_count, true, CHECK_OK);
2828 2815
2829 materialized_literal_count += formals.materialized_literals_count + 2816 materialized_literal_count += formals.materialized_literals_count +
2830 function_state.materialized_literal_count(); 2817 function_state.materialized_literal_count();
2831 2818
2832 if (result == kLazyParsingAborted) { 2819 if (result == kLazyParsingAborted) {
2833 DCHECK(is_lazy_top_level_function);
2834 bookmark.Apply(); 2820 bookmark.Apply();
2835 // Trigger eager (re-)parsing, just below this block. 2821 // Trigger eager (re-)parsing, just below this block.
2836 is_lazy_top_level_function = false; 2822 is_lazily_parsed = false;
2837 2823
2838 // This is probably an initialization function. Inform the compiler it 2824 // This is probably an initialization function. Inform the compiler it
2839 // should also eager-compile this function, and that we expect it to be 2825 // should also eager-compile this function, and that we expect it to be
2840 // used once. 2826 // used once.
2841 eager_compile_hint = FunctionLiteral::kShouldEagerCompile; 2827 eager_compile_hint = FunctionLiteral::kShouldEagerCompile;
2842 should_be_used_once_hint = true; 2828 should_be_used_once_hint = true;
2843 } else if (is_lazy_inner_function) {
2844 DCHECK(main_scope != scope);
2845 scope->AnalyzePartially(main_scope, &previous_zone_ast_node_factory);
2846 } 2829 }
2847 } 2830 }
2848 if (!is_lazy_top_level_function && !is_lazy_inner_function) { 2831 if (!is_lazily_parsed) {
2849 body = ParseEagerFunctionBody(function_name, pos, formals, kind, 2832 body = ParseEagerFunctionBody(function_name, pos, formals, kind,
2850 function_type, CHECK_OK); 2833 function_type, CHECK_OK);
2851 2834
2852 materialized_literal_count = function_state.materialized_literal_count(); 2835 materialized_literal_count = function_state.materialized_literal_count();
2853 expected_property_count = function_state.expected_property_count(); 2836 expected_property_count = function_state.expected_property_count();
2854 if (use_temp_zone) { 2837 if (use_temp_zone) {
2855 // If the preconditions are correct the function body should never be 2838 // If the preconditions are correct the function body should never be
2856 // accessed, but do this anyway for better behaviour if they're wrong. 2839 // accessed, but do this anyway for better behaviour if they're wrong.
2857 body = nullptr; 2840 body = nullptr;
2858 DCHECK(main_scope != scope);
2859 scope->AnalyzePartially(main_scope, &previous_zone_ast_node_factory);
2860 } 2841 }
2861 } 2842 }
2862 2843
2863 // Parsing the body may change the language mode in our scope. 2844 // Parsing the body may change the language mode in our scope.
2864 language_mode = scope->language_mode(); 2845 language_mode = scope->language_mode();
2865 2846
2866 // Validate name and parameter names. We can do this only after parsing the 2847 // Validate name and parameter names. We can do this only after parsing the
2867 // function, since the function can declare itself strict. 2848 // function, since the function can declare itself strict.
2868 CheckFunctionName(language_mode, function_name, function_name_validity, 2849 CheckFunctionName(language_mode, function_name, function_name_validity,
2869 function_name_location, CHECK_OK); 2850 function_name_location, CHECK_OK);
2870 const bool allow_duplicate_parameters = 2851 const bool allow_duplicate_parameters =
2871 is_sloppy(language_mode) && formals.is_simple && !IsConciseMethod(kind); 2852 is_sloppy(language_mode) && formals.is_simple && !IsConciseMethod(kind);
2872 ValidateFormalParameters(language_mode, allow_duplicate_parameters, 2853 ValidateFormalParameters(language_mode, allow_duplicate_parameters,
2873 CHECK_OK); 2854 CHECK_OK);
2874 2855
2875 if (is_strict(language_mode)) { 2856 if (is_strict(language_mode)) {
2876 CheckStrictOctalLiteral(scope->start_position(), scope->end_position(), 2857 CheckStrictOctalLiteral(scope->start_position(), scope->end_position(),
2877 CHECK_OK); 2858 CHECK_OK);
2878 CheckDecimalLiteralWithLeadingZero(scope->start_position(), 2859 CheckDecimalLiteralWithLeadingZero(scope->start_position(),
2879 scope->end_position()); 2860 scope->end_position());
2880 } 2861 }
2881 CheckConflictingVarDeclarations(scope, CHECK_OK); 2862 CheckConflictingVarDeclarations(scope, CHECK_OK);
2882 2863
2883 if (body) { 2864 if (body) {
2884 // If body can be inspected, rewrite queued destructuring assignments 2865 // If body can be inspected, rewrite queued destructuring assignments
2885 RewriteDestructuringAssignments(); 2866 RewriteDestructuringAssignments();
2886 } 2867 }
2887 has_duplicate_parameters = 2868 has_duplicate_parameters =
2888 !classifier()->is_valid_formal_parameter_list_without_duplicates(); 2869 !classifier()->is_valid_formal_parameter_list_without_duplicates();
2870
2871 if (use_temp_zone) {
2872 DCHECK(main_scope != scope);
2873 scope->AnalyzePartially(main_scope, &previous_zone_ast_node_factory);
2874 }
2889 } // DiscardableZoneScope goes out of scope. 2875 } // DiscardableZoneScope goes out of scope.
2890 2876
2891 FunctionLiteral::ParameterFlag duplicate_parameters = 2877 FunctionLiteral::ParameterFlag duplicate_parameters =
2892 has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters 2878 has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters
2893 : FunctionLiteral::kNoDuplicateParameters; 2879 : FunctionLiteral::kNoDuplicateParameters;
2894 2880
2895 // Note that the FunctionLiteral needs to be created in the main Zone again. 2881 // Note that the FunctionLiteral needs to be created in the main Zone again.
2896 FunctionLiteral* function_literal = factory()->NewFunctionLiteral( 2882 FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
2897 function_name, main_scope, body, materialized_literal_count, 2883 function_name, main_scope, body, materialized_literal_count,
2898 expected_property_count, arity, duplicate_parameters, function_type, 2884 expected_property_count, arity, duplicate_parameters, function_type,
(...skipping 30 matching lines...) Expand all
2929 } 2915 }
2930 return ParseFunctionLiteral(name, scanner()->location(), 2916 return ParseFunctionLiteral(name, scanner()->location(),
2931 is_strict_reserved ? kFunctionNameIsStrictReserved 2917 is_strict_reserved ? kFunctionNameIsStrictReserved
2932 : kFunctionNameValidityUnknown, 2918 : kFunctionNameValidityUnknown,
2933 FunctionKind::kAsyncFunction, pos, type, 2919 FunctionKind::kAsyncFunction, pos, type,
2934 language_mode(), CHECK_OK); 2920 language_mode(), CHECK_OK);
2935 } 2921 }
2936 2922
2937 Parser::LazyParsingResult Parser::SkipLazyFunctionBody( 2923 Parser::LazyParsingResult Parser::SkipLazyFunctionBody(
2938 int* materialized_literal_count, int* expected_property_count, 2924 int* materialized_literal_count, int* expected_property_count,
2939 bool is_inner_function, bool may_abort, bool* ok) { 2925 bool may_abort, bool* ok) {
2940 if (produce_cached_parse_data()) CHECK(log_); 2926 if (produce_cached_parse_data()) CHECK(log_);
2941 2927
2942 int function_block_pos = position(); 2928 int function_block_pos = position();
2943 DeclarationScope* scope = this->scope()->AsDeclarationScope(); 2929 DeclarationScope* scope = this->scope()->AsDeclarationScope();
2944 DCHECK(scope->is_function_scope()); 2930 DCHECK(scope->is_function_scope());
2945 scope->set_is_lazily_parsed(true); 2931 scope->set_is_lazily_parsed(true);
2946 // Inner functions are not part of the cached data. 2932 if (consume_cached_parse_data() && !cached_parse_data_->rejected()) {
2947 if (!is_inner_function && consume_cached_parse_data() &&
2948 !cached_parse_data_->rejected()) {
2949 // If we have cached data, we use it to skip parsing the function body. The 2933 // If we have cached data, we use it to skip parsing the function body. The
2950 // data contains the information we need to construct the lazy function. 2934 // data contains the information we need to construct the lazy function.
2951 FunctionEntry entry = 2935 FunctionEntry entry =
2952 cached_parse_data_->GetFunctionEntry(function_block_pos); 2936 cached_parse_data_->GetFunctionEntry(function_block_pos);
2953 // Check that cached data is valid. If not, mark it as invalid (the embedder 2937 // Check that cached data is valid. If not, mark it as invalid (the embedder
2954 // handles it). Note that end position greater than end of stream is safe, 2938 // handles it). Note that end position greater than end of stream is safe,
2955 // and hard to check. 2939 // and hard to check.
2956 if (entry.is_valid() && entry.end_pos() > function_block_pos) { 2940 if (entry.is_valid() && entry.end_pos() > function_block_pos) {
2957 scanner()->SeekForward(entry.end_pos() - 1); 2941 scanner()->SeekForward(entry.end_pos() - 1);
2958 2942
2959 scope->set_end_position(entry.end_pos()); 2943 scope->set_end_position(entry.end_pos());
2960 Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete)); 2944 Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete));
2961 total_preparse_skipped_ += scope->end_position() - function_block_pos; 2945 total_preparse_skipped_ += scope->end_position() - function_block_pos;
2962 *materialized_literal_count = entry.literal_count(); 2946 *materialized_literal_count = entry.literal_count();
2963 *expected_property_count = entry.property_count(); 2947 *expected_property_count = entry.property_count();
2964 SetLanguageMode(scope, entry.language_mode()); 2948 SetLanguageMode(scope, entry.language_mode());
2965 if (entry.uses_super_property()) scope->RecordSuperPropertyUsage(); 2949 if (entry.uses_super_property()) scope->RecordSuperPropertyUsage();
2966 if (entry.calls_eval()) scope->RecordEvalCall(); 2950 if (entry.calls_eval()) scope->RecordEvalCall();
2967 return kLazyParsingComplete; 2951 return kLazyParsingComplete;
2968 } 2952 }
2969 cached_parse_data_->Reject(); 2953 cached_parse_data_->Reject();
2970 } 2954 }
2971 // With no cached data, we partially parse the function, without building an 2955 // With no cached data, we partially parse the function, without building an
2972 // AST. This gathers the data needed to build a lazy function. 2956 // AST. This gathers the data needed to build a lazy function.
2973 SingletonLogger logger; 2957 SingletonLogger logger;
2974 PreParser::PreParseResult result = 2958 PreParser::PreParseResult result =
2975 ParseLazyFunctionBodyWithPreParser(&logger, is_inner_function, may_abort); 2959 ParseLazyFunctionBodyWithPreParser(&logger, may_abort);
2976 // Return immediately if pre-parser decided to abort parsing. 2960 // Return immediately if pre-parser decided to abort parsing.
2977 if (result == PreParser::kPreParseAbort) { 2961 if (result == PreParser::kPreParseAbort) {
2978 scope->set_is_lazily_parsed(false); 2962 scope->set_is_lazily_parsed(false);
2979 return kLazyParsingAborted; 2963 return kLazyParsingAborted;
2980 } 2964 }
2981 if (result == PreParser::kPreParseStackOverflow) { 2965 if (result == PreParser::kPreParseStackOverflow) {
2982 // Propagate stack overflow. 2966 // Propagate stack overflow.
2983 set_stack_overflow(); 2967 set_stack_overflow();
2984 *ok = false; 2968 *ok = false;
2985 return kLazyParsingComplete; 2969 return kLazyParsingComplete;
2986 } 2970 }
2987 if (logger.has_error()) { 2971 if (logger.has_error()) {
2988 ReportMessageAt(Scanner::Location(logger.start(), logger.end()), 2972 ReportMessageAt(Scanner::Location(logger.start(), logger.end()),
2989 logger.message(), logger.argument_opt(), 2973 logger.message(), logger.argument_opt(),
2990 logger.error_type()); 2974 logger.error_type());
2991 *ok = false; 2975 *ok = false;
2992 return kLazyParsingComplete; 2976 return kLazyParsingComplete;
2993 } 2977 }
2994 scope->set_end_position(logger.end()); 2978 scope->set_end_position(logger.end());
2995 Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete)); 2979 Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete));
2996 total_preparse_skipped_ += scope->end_position() - function_block_pos; 2980 total_preparse_skipped_ += scope->end_position() - function_block_pos;
2997 *materialized_literal_count = logger.literals(); 2981 *materialized_literal_count = logger.literals();
2998 *expected_property_count = logger.properties(); 2982 *expected_property_count = logger.properties();
2999 SetLanguageMode(scope, logger.language_mode()); 2983 SetLanguageMode(scope, logger.language_mode());
3000 if (logger.uses_super_property()) scope->RecordSuperPropertyUsage(); 2984 if (logger.uses_super_property()) scope->RecordSuperPropertyUsage();
3001 if (logger.calls_eval()) scope->RecordEvalCall(); 2985 if (logger.calls_eval()) scope->RecordEvalCall();
3002 if (!is_inner_function && produce_cached_parse_data()) { 2986 if (produce_cached_parse_data()) {
3003 DCHECK(log_); 2987 DCHECK(log_);
3004 // Position right after terminal '}'. 2988 // Position right after terminal '}'.
3005 int body_end = scanner()->location().end_pos; 2989 int body_end = scanner()->location().end_pos;
3006 log_->LogFunction(function_block_pos, body_end, *materialized_literal_count, 2990 log_->LogFunction(function_block_pos, body_end, *materialized_literal_count,
3007 *expected_property_count, language_mode(), 2991 *expected_property_count, language_mode(),
3008 scope->uses_super_property(), scope->calls_eval()); 2992 scope->uses_super_property(), scope->calls_eval());
3009 } 2993 }
3010 return kLazyParsingComplete; 2994 return kLazyParsingComplete;
3011 } 2995 }
3012 2996
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
3264 promise = scope()->NewTemporary(ast_value_factory()->empty_string()); 3248 promise = scope()->NewTemporary(ast_value_factory()->empty_string());
3265 function_state_->set_promise_variable(promise); 3249 function_state_->set_promise_variable(promise);
3266 } 3250 }
3267 return promise; 3251 return promise;
3268 } 3252 }
3269 3253
3270 ZoneList<Statement*>* Parser::ParseEagerFunctionBody( 3254 ZoneList<Statement*>* Parser::ParseEagerFunctionBody(
3271 const AstRawString* function_name, int pos, 3255 const AstRawString* function_name, int pos,
3272 const ParserFormalParameters& parameters, FunctionKind kind, 3256 const ParserFormalParameters& parameters, FunctionKind kind,
3273 FunctionLiteral::FunctionType function_type, bool* ok) { 3257 FunctionLiteral::FunctionType function_type, bool* ok) {
3274 // Everything inside an eagerly parsed function will be parsed eagerly (see 3258 // Everything inside an eagerly parsed function will be parsed eagerly
3275 // comment above). Lazy inner functions are handled separately and they won't 3259 // (see comment above).
3276 // require the mode to be PARSE_LAZILY (see ParseFunctionLiteral).
3277 // TODO(marja): Refactor parsing modes: remove this.
3278 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); 3260 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
3279 ZoneList<Statement*>* result = new(zone()) ZoneList<Statement*>(8, zone()); 3261 ZoneList<Statement*>* result = new(zone()) ZoneList<Statement*>(8, zone());
3280 3262
3281 static const int kFunctionNameAssignmentIndex = 0; 3263 static const int kFunctionNameAssignmentIndex = 0;
3282 if (function_type == FunctionLiteral::kNamedExpression) { 3264 if (function_type == FunctionLiteral::kNamedExpression) {
3283 DCHECK(function_name != NULL); 3265 DCHECK(function_name != NULL);
3284 // If we have a named function expression, we add a local variable 3266 // If we have a named function expression, we add a local variable
3285 // declaration to the body of the function with the name of the 3267 // declaration to the body of the function with the name of the
3286 // function and let it refer to the function itself (closure). 3268 // function and let it refer to the function itself (closure).
3287 // Not having parsed the function body, the language mode may still change, 3269 // Not having parsed the function body, the language mode may still change,
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
3438 statement = factory()->NewEmptyStatement(kNoSourcePosition); 3420 statement = factory()->NewEmptyStatement(kNoSourcePosition);
3439 } 3421 }
3440 result->Set(kFunctionNameAssignmentIndex, statement); 3422 result->Set(kFunctionNameAssignmentIndex, statement);
3441 } 3423 }
3442 3424
3443 MarkCollectedTailCallExpressions(); 3425 MarkCollectedTailCallExpressions();
3444 return result; 3426 return result;
3445 } 3427 }
3446 3428
3447 PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser( 3429 PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser(
3448 SingletonLogger* logger, bool is_inner_function, bool may_abort) { 3430 SingletonLogger* logger, bool may_abort) {
3449 // This function may be called on a background thread too; record only the 3431 // This function may be called on a background thread too; record only the
3450 // main thread preparse times. 3432 // main thread preparse times.
3451 if (pre_parse_timer_ != NULL) { 3433 if (pre_parse_timer_ != NULL) {
3452 pre_parse_timer_->Start(); 3434 pre_parse_timer_->Start();
3453 } 3435 }
3454 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.PreParse"); 3436 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.PreParse");
3455 3437
3456 DCHECK_EQ(Token::LBRACE, scanner()->current_token()); 3438 DCHECK_EQ(Token::LBRACE, scanner()->current_token());
3457 3439
3458 if (reusable_preparser_ == NULL) { 3440 if (reusable_preparser_ == NULL) {
3459 reusable_preparser_ = new PreParser(zone(), &scanner_, ast_value_factory(), 3441 reusable_preparser_ = new PreParser(zone(), &scanner_, ast_value_factory(),
3460 NULL, stack_limit_); 3442 NULL, stack_limit_);
3461 reusable_preparser_->set_allow_lazy(true); 3443 reusable_preparser_->set_allow_lazy(true);
3462 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name()); 3444 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name());
3463 SET_ALLOW(natives); 3445 SET_ALLOW(natives);
3464 SET_ALLOW(harmony_do_expressions); 3446 SET_ALLOW(harmony_do_expressions);
3465 SET_ALLOW(harmony_for_in); 3447 SET_ALLOW(harmony_for_in);
3466 SET_ALLOW(harmony_function_sent); 3448 SET_ALLOW(harmony_function_sent);
3467 SET_ALLOW(harmony_restrictive_declarations); 3449 SET_ALLOW(harmony_restrictive_declarations);
3468 SET_ALLOW(harmony_async_await); 3450 SET_ALLOW(harmony_async_await);
3469 SET_ALLOW(harmony_trailing_commas); 3451 SET_ALLOW(harmony_trailing_commas);
3470 SET_ALLOW(harmony_class_fields); 3452 SET_ALLOW(harmony_class_fields);
3471 #undef SET_ALLOW 3453 #undef SET_ALLOW
3472 } 3454 }
3473 // Aborting inner function preparsing would leave scopes in an inconsistent 3455 PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction(
3474 // state; we don't parse inner functions in the abortable mode anyway. 3456 language_mode(), function_state_->kind(),
3475 DCHECK(!is_inner_function || !may_abort); 3457 scope()->AsDeclarationScope()->has_simple_parameters(), parsing_module_,
3476 3458 logger, may_abort, use_counts_);
3477 FunctionKind kind = function_state_->kind();
3478 PreParser::PreParseResult result;
3479 if (!is_inner_function) {
3480 // If we don't need to look at the scope, construct a dummy scope chain
3481 // which is not connected to the real scope chain.
3482 LanguageMode mode = language_mode();
3483 bool has_simple_parameters =
3484 scope()->AsDeclarationScope()->has_simple_parameters();
3485 DeclarationScope* top_scope = NewScriptScope();
3486 top_scope->SetLanguageMode(mode);
3487 FunctionState top_state(&function_state_, &scope_state_, top_scope,
3488 kNormalFunction);
3489 DeclarationScope* function_scope = NewFunctionScope(kind);
3490 if (!has_simple_parameters) {
3491 function_scope->SetHasNonSimpleParameters();
3492 }
3493 result = reusable_preparser_->PreParseLazyFunction(
3494 kind, function_scope, parsing_module_, logger, is_inner_function,
3495 may_abort, use_counts_);
3496 } else {
3497 // Detaching the scopes created by PreParser from the Scope chain must be
3498 // done above (see ParseFunctionLiteral & AnalyzePartially).
3499 result = reusable_preparser_->PreParseLazyFunction(
3500 kind, scope()->AsDeclarationScope(), parsing_module_, logger,
3501 is_inner_function, may_abort, use_counts_);
3502 }
3503 if (pre_parse_timer_ != NULL) { 3459 if (pre_parse_timer_ != NULL) {
3504 pre_parse_timer_->Stop(); 3460 pre_parse_timer_->Stop();
3505 } 3461 }
3506 return result; 3462 return result;
3507 } 3463 }
3508 3464
3509 Expression* Parser::InstallHomeObject(Expression* function_literal, 3465 Expression* Parser::InstallHomeObject(Expression* function_literal,
3510 Expression* home_object) { 3466 Expression* home_object) {
3511 Block* do_block = factory()->NewBlock(nullptr, 1, false, kNoSourcePosition); 3467 Block* do_block = factory()->NewBlock(nullptr, 1, false, kNoSourcePosition);
3512 Variable* result_var = 3468 Variable* result_var =
(...skipping 2103 matching lines...) Expand 10 before | Expand all | Expand 10 after
5616 5572
5617 return final_loop; 5573 return final_loop;
5618 } 5574 }
5619 5575
5620 #undef CHECK_OK 5576 #undef CHECK_OK
5621 #undef CHECK_OK_VOID 5577 #undef CHECK_OK_VOID
5622 #undef CHECK_FAILED 5578 #undef CHECK_FAILED
5623 5579
5624 } // namespace internal 5580 } // namespace internal
5625 } // namespace v8 5581 } // namespace v8
OLDNEW
« no previous file with comments | « src/parsing/parser.h ('k') | src/parsing/parser-base.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698