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 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |