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 94 matching lines...) Loading... |
105 | 105 |
106 // Helper for putting parts of the parse results into a temporary zone when | 106 // Helper for putting parts of the parse results into a temporary zone when |
107 // parsing inner function bodies. | 107 // parsing inner function bodies. |
108 class DiscardableZoneScope { | 108 class DiscardableZoneScope { |
109 public: | 109 public: |
110 DiscardableZoneScope(Parser* parser, Zone* temp_zone, bool use_temp_zone) | 110 DiscardableZoneScope(Parser* parser, Zone* temp_zone, bool use_temp_zone) |
111 : ast_node_factory_scope_(parser->factory(), temp_zone, use_temp_zone), | 111 : ast_node_factory_scope_(parser->factory(), temp_zone, use_temp_zone), |
112 fni_(parser->ast_value_factory_, temp_zone), | 112 fni_(parser->ast_value_factory_, temp_zone), |
113 parser_(parser), | 113 parser_(parser), |
114 prev_fni_(parser->fni_), | 114 prev_fni_(parser->fni_), |
115 prev_zone_(parser->zone_) { | 115 prev_zone_(parser->zone_), |
| 116 prev_allow_lazy_(parser->allow_lazy_), |
| 117 prev_temp_zoned_(parser->temp_zoned_) { |
116 if (use_temp_zone) { | 118 if (use_temp_zone) { |
| 119 DCHECK(!parser_->temp_zoned_); |
| 120 parser_->allow_lazy_ = false; |
| 121 parser_->temp_zoned_ = true; |
117 parser_->fni_ = &fni_; | 122 parser_->fni_ = &fni_; |
118 parser_->zone_ = temp_zone; | 123 parser_->zone_ = temp_zone; |
119 if (parser_->reusable_preparser_ != nullptr) { | 124 if (parser_->reusable_preparser_ != nullptr) { |
120 parser_->reusable_preparser_->zone_ = temp_zone; | 125 parser_->reusable_preparser_->zone_ = temp_zone; |
121 parser_->reusable_preparser_->factory()->set_zone(temp_zone); | 126 parser_->reusable_preparser_->factory()->set_zone(temp_zone); |
122 } | 127 } |
123 } | 128 } |
124 } | 129 } |
125 void Reset() { | 130 void Reset() { |
126 parser_->fni_ = prev_fni_; | 131 parser_->fni_ = prev_fni_; |
127 parser_->zone_ = prev_zone_; | 132 parser_->zone_ = prev_zone_; |
| 133 parser_->allow_lazy_ = prev_allow_lazy_; |
| 134 parser_->temp_zoned_ = prev_temp_zoned_; |
128 if (parser_->reusable_preparser_ != nullptr) { | 135 if (parser_->reusable_preparser_ != nullptr) { |
129 parser_->reusable_preparser_->zone_ = prev_zone_; | 136 parser_->reusable_preparser_->zone_ = prev_zone_; |
130 parser_->reusable_preparser_->factory()->set_zone(prev_zone_); | 137 parser_->reusable_preparser_->factory()->set_zone(prev_zone_); |
131 } | 138 } |
132 ast_node_factory_scope_.Reset(); | 139 ast_node_factory_scope_.Reset(); |
133 } | 140 } |
134 ~DiscardableZoneScope() { Reset(); } | 141 ~DiscardableZoneScope() { Reset(); } |
135 | 142 |
136 private: | 143 private: |
137 AstNodeFactory::BodyScope ast_node_factory_scope_; | 144 AstNodeFactory::BodyScope ast_node_factory_scope_; |
138 FuncNameInferrer fni_; | 145 FuncNameInferrer fni_; |
139 Parser* parser_; | 146 Parser* parser_; |
140 FuncNameInferrer* prev_fni_; | 147 FuncNameInferrer* prev_fni_; |
141 Zone* prev_zone_; | 148 Zone* prev_zone_; |
| 149 bool prev_allow_lazy_; |
| 150 bool prev_temp_zoned_; |
142 | 151 |
143 DISALLOW_COPY_AND_ASSIGN(DiscardableZoneScope); | 152 DISALLOW_COPY_AND_ASSIGN(DiscardableZoneScope); |
144 }; | 153 }; |
145 | 154 |
146 void Parser::SetCachedData(ParseInfo* info) { | 155 void Parser::SetCachedData(ParseInfo* info) { |
147 DCHECK_NULL(cached_parse_data_); | 156 DCHECK_NULL(cached_parse_data_); |
148 if (consume_cached_parse_data()) { | 157 if (consume_cached_parse_data()) { |
149 cached_parse_data_ = ParseData::FromCachedData(*info->cached_data()); | 158 if (allow_lazy_) { |
150 if (cached_parse_data_ == nullptr) { | 159 cached_parse_data_ = ParseData::FromCachedData(*info->cached_data()); |
151 compile_options_ = ScriptCompiler::kNoCompileOptions; | 160 if (cached_parse_data_ != nullptr) return; |
152 } | 161 } |
| 162 compile_options_ = ScriptCompiler::kNoCompileOptions; |
153 } | 163 } |
154 } | 164 } |
155 | 165 |
156 Expression* Parser::CallClassFieldInitializer(Scope* scope, | 166 Expression* Parser::CallClassFieldInitializer(Scope* scope, |
157 Expression* this_expr) { | 167 Expression* this_expr) { |
158 // This produces the expression | 168 // This produces the expression |
159 // `.class_field_intializer(this_expr)`, where '.class_field_intializer' is | 169 // `.class_field_intializer(this_expr)`, where '.class_field_intializer' is |
160 // the name | 170 // the name |
161 // of a synthetic variable. | 171 // of a synthetic variable. |
162 // 'this_expr' will be 'this' in a base constructor and the result of calling | 172 // 'this_expr' will be 'this' in a base constructor and the result of calling |
(...skipping 422 matching lines...) Loading... |
585 info->isolate()->counters()->runtime_call_stats(), | 595 info->isolate()->counters()->runtime_call_stats(), |
586 true), | 596 true), |
587 scanner_(info->unicode_cache()), | 597 scanner_(info->unicode_cache()), |
588 reusable_preparser_(nullptr), | 598 reusable_preparser_(nullptr), |
589 original_scope_(nullptr), | 599 original_scope_(nullptr), |
590 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly. | 600 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly. |
591 target_stack_(nullptr), | 601 target_stack_(nullptr), |
592 compile_options_(info->compile_options()), | 602 compile_options_(info->compile_options()), |
593 cached_parse_data_(nullptr), | 603 cached_parse_data_(nullptr), |
594 total_preparse_skipped_(0), | 604 total_preparse_skipped_(0), |
| 605 temp_zoned_(false), |
595 log_(nullptr) { | 606 log_(nullptr) { |
596 // Even though we were passed ParseInfo, we should not store it in | 607 // Even though we were passed ParseInfo, we should not store it in |
597 // Parser - this makes sure that Isolate is not accidentally accessed via | 608 // Parser - this makes sure that Isolate is not accidentally accessed via |
598 // ParseInfo during background parsing. | 609 // ParseInfo during background parsing. |
599 DCHECK(!info->script().is_null() || info->source_stream() != nullptr || | 610 DCHECK(!info->script().is_null() || info->source_stream() != nullptr || |
600 info->character_stream() != nullptr); | 611 info->character_stream() != nullptr); |
601 // Determine if functions can be lazily compiled. This is necessary to | 612 // Determine if functions can be lazily compiled. This is necessary to |
602 // allow some of our builtin JS files to be lazily compiled. These | 613 // allow some of our builtin JS files to be lazily compiled. These |
603 // builtins cannot be handled lazily by the parser, since we have to know | 614 // builtins cannot be handled lazily by the parser, since we have to know |
604 // if a function uses the special natives syntax, which is something the | 615 // if a function uses the special natives syntax, which is something the |
(...skipping 68 matching lines...) Loading... |
673 base::ElapsedTimer timer; | 684 base::ElapsedTimer timer; |
674 if (FLAG_trace_parse) { | 685 if (FLAG_trace_parse) { |
675 timer.Start(); | 686 timer.Start(); |
676 } | 687 } |
677 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); | 688 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); |
678 | 689 |
679 // Initialize parser state. | 690 // Initialize parser state. |
680 ParserLogger logger; | 691 ParserLogger logger; |
681 | 692 |
682 if (produce_cached_parse_data()) { | 693 if (produce_cached_parse_data()) { |
683 log_ = &logger; | 694 if (allow_lazy_) { |
| 695 log_ = &logger; |
| 696 } else { |
| 697 compile_options_ = ScriptCompiler::kNoCompileOptions; |
| 698 } |
684 } else if (consume_cached_parse_data()) { | 699 } else if (consume_cached_parse_data()) { |
685 cached_parse_data_->Initialize(); | 700 cached_parse_data_->Initialize(); |
686 } | 701 } |
687 | 702 |
688 DeserializeScopeChain(info, info->maybe_outer_scope_info()); | 703 DeserializeScopeChain(info, info->maybe_outer_scope_info()); |
689 | 704 |
690 source = String::Flatten(source); | 705 source = String::Flatten(source); |
691 FunctionLiteral* result; | 706 FunctionLiteral* result; |
692 | 707 |
693 { | 708 { |
(...skipping 1991 matching lines...) Loading... |
2685 } | 2700 } |
2686 | 2701 |
2687 DCHECK(use_temp_zone || !is_lazy_top_level_function); | 2702 DCHECK(use_temp_zone || !is_lazy_top_level_function); |
2688 if (use_temp_zone) { | 2703 if (use_temp_zone) { |
2689 // If the preconditions are correct the function body should never be | 2704 // If the preconditions are correct the function body should never be |
2690 // accessed, but do this anyway for better behaviour if they're wrong. | 2705 // accessed, but do this anyway for better behaviour if they're wrong. |
2691 body = nullptr; | 2706 body = nullptr; |
2692 scope->AnalyzePartially(&previous_zone_ast_node_factory); | 2707 scope->AnalyzePartially(&previous_zone_ast_node_factory); |
2693 } | 2708 } |
2694 | 2709 |
| 2710 DCHECK_IMPLIES(use_temp_zone, temp_zoned_); |
2695 if (FLAG_trace_preparse) { | 2711 if (FLAG_trace_preparse) { |
2696 PrintF(" [%s]: %i-%i %.*s\n", | 2712 PrintF(" [%s]: %i-%i %.*s\n", |
2697 is_lazy_top_level_function | 2713 is_lazy_top_level_function |
2698 ? "Preparse no-resolution" | 2714 ? "Preparse no-resolution" |
2699 : (use_temp_zone ? "Preparse resolution" : "Full parse"), | 2715 : (temp_zoned_ ? "Preparse resolution" : "Full parse"), |
2700 scope->start_position(), scope->end_position(), | 2716 scope->start_position(), scope->end_position(), |
2701 function_name->byte_length(), function_name->raw_data()); | 2717 function_name->byte_length(), function_name->raw_data()); |
2702 } | 2718 } |
2703 if (is_lazy_top_level_function) { | 2719 if (is_lazy_top_level_function) { |
2704 CHANGE_CURRENT_RUNTIME_COUNTER(runtime_call_stats_, | 2720 CHANGE_CURRENT_RUNTIME_COUNTER(runtime_call_stats_, |
2705 PreParseNoVariableResolution); | 2721 PreParseNoVariableResolution); |
2706 } else if (use_temp_zone) { | 2722 } else if (temp_zoned_) { |
2707 CHANGE_CURRENT_RUNTIME_COUNTER(runtime_call_stats_, | 2723 CHANGE_CURRENT_RUNTIME_COUNTER(runtime_call_stats_, |
2708 PreParseWithVariableResolution); | 2724 PreParseWithVariableResolution); |
2709 } | 2725 } |
2710 | 2726 |
2711 // Validate function name. We can do this only after parsing the function, | 2727 // Validate function name. We can do this only after parsing the function, |
2712 // since the function can declare itself strict. | 2728 // since the function can declare itself strict. |
2713 language_mode = scope->language_mode(); | 2729 language_mode = scope->language_mode(); |
2714 CheckFunctionName(language_mode, function_name, function_name_validity, | 2730 CheckFunctionName(language_mode, function_name, function_name_validity, |
2715 function_name_location, CHECK_OK); | 2731 function_name_location, CHECK_OK); |
2716 | 2732 |
(...skipping 392 matching lines...) Loading... |
3109 return factory()->NewYield(get_proxy, assignment, scope()->start_position(), | 3125 return factory()->NewYield(get_proxy, assignment, scope()->start_position(), |
3110 Yield::kOnExceptionThrow); | 3126 Yield::kOnExceptionThrow); |
3111 } | 3127 } |
3112 | 3128 |
3113 ZoneList<Statement*>* Parser::ParseFunction( | 3129 ZoneList<Statement*>* Parser::ParseFunction( |
3114 const AstRawString* function_name, int pos, FunctionKind kind, | 3130 const AstRawString* function_name, int pos, FunctionKind kind, |
3115 FunctionLiteral::FunctionType function_type, | 3131 FunctionLiteral::FunctionType function_type, |
3116 DeclarationScope* function_scope, int* num_parameters, int* function_length, | 3132 DeclarationScope* function_scope, int* num_parameters, int* function_length, |
3117 bool* has_duplicate_parameters, int* materialized_literal_count, | 3133 bool* has_duplicate_parameters, int* materialized_literal_count, |
3118 int* expected_property_count, bool* ok) { | 3134 int* expected_property_count, bool* ok) { |
| 3135 ParsingModeScope mode(this, allow_lazy_ ? PARSE_LAZILY : PARSE_EAGERLY); |
| 3136 |
3119 FunctionState function_state(&function_state_, &scope_state_, function_scope); | 3137 FunctionState function_state(&function_state_, &scope_state_, function_scope); |
3120 | 3138 |
3121 DuplicateFinder duplicate_finder(scanner()->unicode_cache()); | 3139 DuplicateFinder duplicate_finder(scanner()->unicode_cache()); |
3122 ExpressionClassifier formals_classifier(this, &duplicate_finder); | 3140 ExpressionClassifier formals_classifier(this, &duplicate_finder); |
3123 | 3141 |
3124 if (IsGeneratorFunction(kind)) PrepareGeneratorVariables(&function_state); | 3142 if (IsGeneratorFunction(kind)) PrepareGeneratorVariables(&function_state); |
3125 | 3143 |
3126 ParserFormalParameters formals(function_scope); | 3144 ParserFormalParameters formals(function_scope); |
3127 ParseFormalParameterList(&formals, CHECK_OK); | 3145 ParseFormalParameterList(&formals, CHECK_OK); |
3128 Expect(Token::RPAREN, CHECK_OK); | 3146 Expect(Token::RPAREN, CHECK_OK); |
(...skipping 24 matching lines...) Loading... |
3153 | 3171 |
3154 *materialized_literal_count = function_state.materialized_literal_count(); | 3172 *materialized_literal_count = function_state.materialized_literal_count(); |
3155 *expected_property_count = function_state.expected_property_count(); | 3173 *expected_property_count = function_state.expected_property_count(); |
3156 return body; | 3174 return body; |
3157 } | 3175 } |
3158 | 3176 |
3159 ZoneList<Statement*>* Parser::ParseEagerFunctionBody( | 3177 ZoneList<Statement*>* Parser::ParseEagerFunctionBody( |
3160 const AstRawString* function_name, int pos, | 3178 const AstRawString* function_name, int pos, |
3161 const ParserFormalParameters& parameters, FunctionKind kind, | 3179 const ParserFormalParameters& parameters, FunctionKind kind, |
3162 FunctionLiteral::FunctionType function_type, bool* ok) { | 3180 FunctionLiteral::FunctionType function_type, bool* ok) { |
3163 ParsingModeScope mode(this, allow_lazy_ ? PARSE_LAZILY : PARSE_EAGERLY); | |
3164 ZoneList<Statement*>* result = new(zone()) ZoneList<Statement*>(8, zone()); | 3181 ZoneList<Statement*>* result = new(zone()) ZoneList<Statement*>(8, zone()); |
3165 | 3182 |
3166 static const int kFunctionNameAssignmentIndex = 0; | 3183 static const int kFunctionNameAssignmentIndex = 0; |
3167 if (function_type == FunctionLiteral::kNamedExpression) { | 3184 if (function_type == FunctionLiteral::kNamedExpression) { |
3168 DCHECK(function_name != NULL); | 3185 DCHECK(function_name != NULL); |
3169 // If we have a named function expression, we add a local variable | 3186 // If we have a named function expression, we add a local variable |
3170 // declaration to the body of the function with the name of the | 3187 // declaration to the body of the function with the name of the |
3171 // function and let it refer to the function itself (closure). | 3188 // function and let it refer to the function itself (closure). |
3172 // Not having parsed the function body, the language mode may still change, | 3189 // Not having parsed the function body, the language mode may still change, |
3173 // so we reserve a spot and create the actual const assignment later. | 3190 // so we reserve a spot and create the actual const assignment later. |
(...skipping 638 matching lines...) Loading... |
3812 } | 3829 } |
3813 | 3830 |
3814 | 3831 |
3815 void Parser::ParseOnBackground(ParseInfo* info) { | 3832 void Parser::ParseOnBackground(ParseInfo* info) { |
3816 parsing_on_main_thread_ = false; | 3833 parsing_on_main_thread_ = false; |
3817 | 3834 |
3818 DCHECK(info->literal() == NULL); | 3835 DCHECK(info->literal() == NULL); |
3819 FunctionLiteral* result = NULL; | 3836 FunctionLiteral* result = NULL; |
3820 | 3837 |
3821 ParserLogger logger; | 3838 ParserLogger logger; |
3822 if (produce_cached_parse_data()) log_ = &logger; | 3839 if (produce_cached_parse_data()) { |
| 3840 if (allow_lazy_) { |
| 3841 log_ = &logger; |
| 3842 } else { |
| 3843 compile_options_ = ScriptCompiler::kNoCompileOptions; |
| 3844 } |
| 3845 } |
3823 if (FLAG_runtime_stats) { | 3846 if (FLAG_runtime_stats) { |
3824 // Create separate runtime stats for background parsing. | 3847 // Create separate runtime stats for background parsing. |
3825 runtime_call_stats_ = new (zone()) RuntimeCallStats(); | 3848 runtime_call_stats_ = new (zone()) RuntimeCallStats(); |
3826 } | 3849 } |
3827 | 3850 |
3828 std::unique_ptr<Utf16CharacterStream> stream; | 3851 std::unique_ptr<Utf16CharacterStream> stream; |
3829 Utf16CharacterStream* stream_ptr; | 3852 Utf16CharacterStream* stream_ptr; |
3830 if (info->character_stream()) { | 3853 if (info->character_stream()) { |
3831 DCHECK(info->source_stream() == nullptr); | 3854 DCHECK(info->source_stream() == nullptr); |
3832 stream_ptr = info->character_stream(); | 3855 stream_ptr = info->character_stream(); |
(...skipping 1604 matching lines...) Loading... |
5437 | 5460 |
5438 return final_loop; | 5461 return final_loop; |
5439 } | 5462 } |
5440 | 5463 |
5441 #undef CHECK_OK | 5464 #undef CHECK_OK |
5442 #undef CHECK_OK_VOID | 5465 #undef CHECK_OK_VOID |
5443 #undef CHECK_FAILED | 5466 #undef CHECK_FAILED |
5444 | 5467 |
5445 } // namespace internal | 5468 } // namespace internal |
5446 } // namespace v8 | 5469 } // namespace v8 |
OLD | NEW |