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

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

Issue 2349473004: Revert of Preparse inner functions. (Closed)
Patch Set: Created 4 years, 3 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 2847 matching lines...) Expand 10 before | Expand all | Expand 10 after
2993 // - It must not have been prohibited by the caller to Parse (some callers 2987 // - It must not have been prohibited by the caller to Parse (some callers
2994 // need a full AST). 2988 // need a full AST).
2995 // - The outer scope must allow lazy compilation of inner functions. 2989 // - The outer scope must allow lazy compilation of inner functions.
2996 // - The function mustn't be a function expression with an open parenthesis 2990 // - The function mustn't be a function expression with an open parenthesis
2997 // before; we consider that a hint that the function will be called 2991 // before; we consider that a hint that the function will be called
2998 // immediately, and it would be a waste of time to make it lazily 2992 // immediately, and it would be a waste of time to make it lazily
2999 // compiled. 2993 // compiled.
3000 // These are all things we can know at this point, without looking at the 2994 // These are all things we can know at this point, without looking at the
3001 // function itself. 2995 // function itself.
3002 2996
3003 // We separate between lazy parsing top level functions and lazy parsing inner 2997 // In addition, we need to distinguish between these cases:
3004 // functions, because the latter needs to do more work. In particular, we need
3005 // to track unresolved variables to distinguish between these cases:
3006 // (function foo() { 2998 // (function foo() {
3007 // bar = function() { return 1; } 2999 // bar = function() { return 1; }
3008 // })(); 3000 // })();
3009 // and 3001 // and
3010 // (function foo() { 3002 // (function foo() {
3011 // var a = 1; 3003 // var a = 1;
3012 // bar = function() { return a; } 3004 // bar = function() { return a; }
3013 // })(); 3005 // })();
3014 3006
3015 // Now foo will be parsed eagerly and compiled eagerly (optimization: assume 3007 // Now foo will be parsed eagerly and compiled eagerly (optimization: assume
3016 // parenthesis before the function means that it will be called 3008 // parenthesis before the function means that it will be called
3017 // immediately). bar can be parsed lazily, but we need to parse it in a mode 3009 // immediately). The inner function *must* be parsed eagerly to resolve the
3018 // that tracks unresolved variables. 3010 // possible reference to the variable in foo's scope. However, it's possible
3019 DCHECK_IMPLIES(mode() == PARSE_LAZILY, FLAG_lazy); 3011 // that it will be compiled lazily.
3020 DCHECK_IMPLIES(mode() == PARSE_LAZILY, allow_lazy());
3021 DCHECK_IMPLIES(mode() == PARSE_LAZILY, !allow_natives());
3022 DCHECK_IMPLIES(mode() == PARSE_LAZILY, extension_ == nullptr);
3023 3012
3024 bool is_lazy_top_level_function = 3013 // To make this additional case work, both Parser and PreParser implement a
3025 mode() == PARSE_LAZILY && 3014 // logic where only top-level functions will be parsed lazily.
3026 eager_compile_hint == FunctionLiteral::kShouldLazyCompile && 3015 bool is_lazily_parsed = mode() == PARSE_LAZILY &&
3027 scope()->AllowsLazyParsingWithoutUnresolvedVariables(); 3016 scope()->AllowsLazyParsing() &&
3017 !function_state_->next_function_is_parenthesized();
3028 3018
3029 // Determine whether we can still do the inner function lazy parsing. 3019 // Determine whether the function body can be discarded after parsing.
3030 // The preconditions are: 3020 // The preconditions are:
3031 // - Lazy compilation has to be enabled. 3021 // - Lazy compilation has to be enabled.
3032 // - Neither V8 natives nor native function declarations can be allowed, 3022 // - Neither V8 natives nor native function declarations can be allowed,
3033 // since parsing one would retroactively force the function to be 3023 // since parsing one would retroactively force the function to be
3034 // eagerly compiled. 3024 // eagerly compiled.
3035 // - The invoker of this parser can't depend on the AST being eagerly 3025 // - The invoker of this parser can't depend on the AST being eagerly
3036 // built (either because the function is about to be compiled, or 3026 // built (either because the function is about to be compiled, or
3037 // because the AST is going to be inspected for some reason). 3027 // because the AST is going to be inspected for some reason).
3038 // - Because of the above, we can't be attempting to parse a 3028 // - Because of the above, we can't be attempting to parse a
3039 // FunctionExpression; even without enclosing parentheses it might be 3029 // FunctionExpression; even without enclosing parentheses it might be
3040 // immediately invoked. 3030 // immediately invoked.
3041 // - The function literal shouldn't be hinted to eagerly compile. 3031 // - The function literal shouldn't be hinted to eagerly compile.
3042 // - For asm.js functions the body needs to be available when module 3032 // - For asm.js functions the body needs to be available when module
3043 // validation is active, because we examine the entire module at once. 3033 // validation is active, because we examine the entire module at once.
3044 3034 bool use_temp_zone =
3045 // Inner functions will be parsed by using a temporary Zone. After parsing, we 3035 !is_lazily_parsed && FLAG_lazy && !allow_natives() &&
3046 // will migrate unresolved variable into a Scope in the main Zone.
3047 // TODO(marja): Refactor parsing modes: simplify this.
3048 bool is_lazy_inner_function =
3049 !is_lazy_top_level_function && FLAG_lazy && !allow_natives() &&
3050 extension_ == NULL && allow_lazy() && 3036 extension_ == NULL && allow_lazy() &&
3051 function_type == FunctionLiteral::kDeclaration && 3037 function_type == FunctionLiteral::kDeclaration &&
3052 eager_compile_hint != FunctionLiteral::kShouldEagerCompile && 3038 eager_compile_hint != FunctionLiteral::kShouldEagerCompile &&
3053 !(FLAG_validate_asm && scope()->IsAsmModule()); 3039 !(FLAG_validate_asm && scope()->IsAsmModule());
3054 3040
3055 DeclarationScope* main_scope = nullptr; 3041 DeclarationScope* main_scope = nullptr;
3056 if (is_lazy_inner_function) { 3042 if (use_temp_zone) {
3057 // This Scope lives in the main Zone; we'll migrate data into it later. 3043 // This Scope lives in the main Zone; we'll migrate data into it later.
3058 main_scope = NewFunctionScope(kind); 3044 main_scope = NewFunctionScope(kind);
3059 } 3045 }
3060 3046
3061 ZoneList<Statement*>* body = nullptr; 3047 ZoneList<Statement*>* body = nullptr;
3062 int arity = -1; 3048 int arity = -1;
3063 int materialized_literal_count = -1; 3049 int materialized_literal_count = -1;
3064 int expected_property_count = -1; 3050 int expected_property_count = -1;
3065 DuplicateFinder duplicate_finder(scanner()->unicode_cache()); 3051 DuplicateFinder duplicate_finder(scanner()->unicode_cache());
3066 bool should_be_used_once_hint = false; 3052 bool should_be_used_once_hint = false;
3067 bool has_duplicate_parameters; 3053 bool has_duplicate_parameters;
3068 3054
3069 { 3055 {
3070 // Temporary zones can nest. When we migrate free variables (see below), we 3056 // Temporary zones can nest. When we migrate free variables (see below), we
3071 // need to recreate them in the previous Zone. 3057 // need to recreate them in the previous Zone.
3072 AstNodeFactory previous_zone_ast_node_factory(ast_value_factory()); 3058 AstNodeFactory previous_zone_ast_node_factory(ast_value_factory());
3073 previous_zone_ast_node_factory.set_zone(zone()); 3059 previous_zone_ast_node_factory.set_zone(zone());
3074 3060
3075 // Open a new zone scope, which sets our AstNodeFactory to allocate in the 3061 // Open a new zone scope, which sets our AstNodeFactory to allocate in the
3076 // new temporary zone if the preconditions are satisfied, and ensures that 3062 // new temporary zone if the preconditions are satisfied, and ensures that
3077 // the previous zone is always restored after parsing the body. To be able 3063 // the previous zone is always restored after parsing the body. To be able
3078 // to do scope analysis correctly after full parsing, we migrate needed 3064 // to do scope analysis correctly after full parsing, we migrate needed
3079 // information from scope into main_scope when the function has been parsed. 3065 // information from scope into main_scope when the function has been parsed.
3080 Zone temp_zone(zone()->allocator()); 3066 Zone temp_zone(zone()->allocator());
3081 DiscardableZoneScope zone_scope(this, &temp_zone, is_lazy_inner_function); 3067 DiscardableZoneScope zone_scope(this, &temp_zone, use_temp_zone);
3082 3068
3083 DeclarationScope* scope = NewFunctionScope(kind); 3069 DeclarationScope* scope = NewFunctionScope(kind);
3084 SetLanguageMode(scope, language_mode); 3070 SetLanguageMode(scope, language_mode);
3085 if (!is_lazy_inner_function) { 3071 if (!use_temp_zone) {
3086 main_scope = scope; 3072 main_scope = scope;
3087 } else { 3073 } else {
3088 DCHECK(main_scope->zone() != scope->zone()); 3074 DCHECK(main_scope->zone() != scope->zone());
3089 } 3075 }
3090 3076
3091 FunctionState function_state(&function_state_, &scope_state_, scope, kind); 3077 FunctionState function_state(&function_state_, &scope_state_, scope, kind);
3092 #ifdef DEBUG 3078 #ifdef DEBUG
3093 scope->SetScopeName(function_name); 3079 scope->SetScopeName(function_name);
3094 #endif 3080 #endif
3095 ExpressionClassifier formals_classifier(this, &duplicate_finder); 3081 ExpressionClassifier formals_classifier(this, &duplicate_finder);
(...skipping 23 matching lines...) Expand all
3119 int formals_end_position = scanner()->location().end_pos; 3105 int formals_end_position = scanner()->location().end_pos;
3120 3106
3121 CheckArityRestrictions(arity, kind, formals.has_rest, start_position, 3107 CheckArityRestrictions(arity, kind, formals.has_rest, start_position,
3122 formals_end_position, CHECK_OK); 3108 formals_end_position, CHECK_OK);
3123 Expect(Token::LBRACE, CHECK_OK); 3109 Expect(Token::LBRACE, CHECK_OK);
3124 // Don't include the rest parameter into the function's formal parameter 3110 // Don't include the rest parameter into the function's formal parameter
3125 // count (esp. the SharedFunctionInfo::internal_formal_parameter_count, 3111 // count (esp. the SharedFunctionInfo::internal_formal_parameter_count,
3126 // which says whether we need to create an arguments adaptor frame). 3112 // which says whether we need to create an arguments adaptor frame).
3127 if (formals.has_rest) arity--; 3113 if (formals.has_rest) arity--;
3128 3114
3129 // Eager or lazy parse? If is_lazy_top_level_function, we'll parse 3115 // Eager or lazy parse?
3130 // lazily. We'll call SkipLazyFunctionBody, which may decide to abort lazy 3116 // If is_lazily_parsed, we'll parse lazily. We'll call SkipLazyFunctionBody,
3131 // parsing if it suspects that wasn't a good idea. If so (in which case the 3117 // which may decide to abort lazy parsing if it suspects that wasn't a good
3132 // parser is expected to have backtracked), or if we didn't try to lazy 3118 // idea. If so (in which case the parser is expected to have backtracked),
3133 // parse in the first place, we'll have to parse eagerly. 3119 // or if we didn't try to lazy parse in the first place, we'll have to parse
3134 if (is_lazy_top_level_function) { 3120 // eagerly.
3121 if (is_lazily_parsed) {
3135 Scanner::BookmarkScope bookmark(scanner()); 3122 Scanner::BookmarkScope bookmark(scanner());
3136 bool may_abort = bookmark.Set(); 3123 bool may_abort = bookmark.Set();
3137 LazyParsingResult result = SkipLazyFunctionBody( 3124 LazyParsingResult result =
3138 &materialized_literal_count, &expected_property_count, false, 3125 SkipLazyFunctionBody(&materialized_literal_count,
3139 may_abort, CHECK_OK); 3126 &expected_property_count, may_abort, CHECK_OK);
3140 3127
3141 materialized_literal_count += formals.materialized_literals_count + 3128 materialized_literal_count += formals.materialized_literals_count +
3142 function_state.materialized_literal_count(); 3129 function_state.materialized_literal_count();
3143 3130
3144 if (result == kLazyParsingAborted) { 3131 if (result == kLazyParsingAborted) {
3145 bookmark.Reset(); 3132 bookmark.Reset();
3146 // Trigger eager (re-)parsing, just below this block. 3133 // Trigger eager (re-)parsing, just below this block.
3147 is_lazy_top_level_function = false; 3134 is_lazily_parsed = false;
3148 3135
3149 // This is probably an initialization function. Inform the compiler it 3136 // This is probably an initialization function. Inform the compiler it
3150 // should also eager-compile this function, and that we expect it to be 3137 // should also eager-compile this function, and that we expect it to be
3151 // used once. 3138 // used once.
3152 eager_compile_hint = FunctionLiteral::kShouldEagerCompile; 3139 eager_compile_hint = FunctionLiteral::kShouldEagerCompile;
3153 should_be_used_once_hint = true; 3140 should_be_used_once_hint = true;
3154 } 3141 }
3155 } 3142 }
3156 if (is_lazy_inner_function) { 3143 if (!is_lazily_parsed) {
3157 if (FLAG_lazy_inner_functions) {
3158 LazyParsingResult result = SkipLazyFunctionBody(
3159 &materialized_literal_count, &expected_property_count, true, false,
3160 CHECK_OK);
3161 materialized_literal_count +=
3162 formals.materialized_literals_count +
3163 function_state.materialized_literal_count();
3164 DCHECK(result != kLazyParsingAborted);
3165 USE(result);
3166 } else {
3167 ParseEagerFunctionBody(function_name, pos, formals, kind, function_type,
3168 CHECK_OK);
3169 materialized_literal_count =
3170 function_state.materialized_literal_count();
3171 expected_property_count = function_state.expected_property_count();
3172 }
3173 } else if (!is_lazy_top_level_function) {
3174 body = ParseEagerFunctionBody(function_name, pos, formals, kind, 3144 body = ParseEagerFunctionBody(function_name, pos, formals, kind,
3175 function_type, CHECK_OK); 3145 function_type, CHECK_OK);
3176 3146
3177 materialized_literal_count = function_state.materialized_literal_count(); 3147 materialized_literal_count = function_state.materialized_literal_count();
3178 expected_property_count = function_state.expected_property_count(); 3148 expected_property_count = function_state.expected_property_count();
3149 if (use_temp_zone) {
3150 // If the preconditions are correct the function body should never be
3151 // accessed, but do this anyway for better behaviour if they're wrong.
3152 body = nullptr;
3153 }
3179 } 3154 }
3180 3155
3181 // Parsing the body may change the language mode in our scope. 3156 // Parsing the body may change the language mode in our scope.
3182 language_mode = scope->language_mode(); 3157 language_mode = scope->language_mode();
3183 scope->DeclareArguments(ast_value_factory()); 3158 scope->DeclareArguments(ast_value_factory());
3184 if (main_scope != scope) { 3159 if (main_scope != scope) {
3185 main_scope->DeclareArguments(ast_value_factory()); 3160 main_scope->DeclareArguments(ast_value_factory());
3186 } 3161 }
3187 3162
3188 // Validate name and parameter names. We can do this only after parsing the 3163 // Validate name and parameter names. We can do this only after parsing the
(...skipping 13 matching lines...) Expand all
3202 } 3177 }
3203 CheckConflictingVarDeclarations(scope, CHECK_OK); 3178 CheckConflictingVarDeclarations(scope, CHECK_OK);
3204 3179
3205 if (body) { 3180 if (body) {
3206 // If body can be inspected, rewrite queued destructuring assignments 3181 // If body can be inspected, rewrite queued destructuring assignments
3207 RewriteDestructuringAssignments(); 3182 RewriteDestructuringAssignments();
3208 } 3183 }
3209 has_duplicate_parameters = 3184 has_duplicate_parameters =
3210 !classifier()->is_valid_formal_parameter_list_without_duplicates(); 3185 !classifier()->is_valid_formal_parameter_list_without_duplicates();
3211 3186
3212 if (is_lazy_inner_function) { 3187 if (use_temp_zone) {
3213 DCHECK(main_scope != scope); 3188 DCHECK(main_scope != scope);
3214 scope->AnalyzePartially(main_scope, &previous_zone_ast_node_factory); 3189 scope->AnalyzePartially(main_scope, &previous_zone_ast_node_factory);
3215 } 3190 }
3216 } // DiscardableZoneScope goes out of scope. 3191 } // DiscardableZoneScope goes out of scope.
3217 3192
3218 FunctionLiteral::ParameterFlag duplicate_parameters = 3193 FunctionLiteral::ParameterFlag duplicate_parameters =
3219 has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters 3194 has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters
3220 : FunctionLiteral::kNoDuplicateParameters; 3195 : FunctionLiteral::kNoDuplicateParameters;
3221 3196
3222 // Note that the FunctionLiteral needs to be created in the main Zone again. 3197 // Note that the FunctionLiteral needs to be created in the main Zone again.
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
3256 } 3231 }
3257 return ParseFunctionLiteral(name, scanner()->location(), 3232 return ParseFunctionLiteral(name, scanner()->location(),
3258 is_strict_reserved ? kFunctionNameIsStrictReserved 3233 is_strict_reserved ? kFunctionNameIsStrictReserved
3259 : kFunctionNameValidityUnknown, 3234 : kFunctionNameValidityUnknown,
3260 FunctionKind::kAsyncFunction, pos, type, 3235 FunctionKind::kAsyncFunction, pos, type,
3261 language_mode(), CHECK_OK); 3236 language_mode(), CHECK_OK);
3262 } 3237 }
3263 3238
3264 Parser::LazyParsingResult Parser::SkipLazyFunctionBody( 3239 Parser::LazyParsingResult Parser::SkipLazyFunctionBody(
3265 int* materialized_literal_count, int* expected_property_count, 3240 int* materialized_literal_count, int* expected_property_count,
3266 bool is_inner_function, bool may_abort, bool* ok) { 3241 bool may_abort, bool* ok) {
3267 if (produce_cached_parse_data()) CHECK(log_); 3242 if (produce_cached_parse_data()) CHECK(log_);
3268 3243
3269 int function_block_pos = position(); 3244 int function_block_pos = position();
3270 DeclarationScope* scope = this->scope()->AsDeclarationScope(); 3245 DeclarationScope* scope = this->scope()->AsDeclarationScope();
3271 DCHECK(scope->is_function_scope()); 3246 DCHECK(scope->is_function_scope());
3272 // Inner functions are not part of the cached data. 3247 if (consume_cached_parse_data() && !cached_parse_data_->rejected()) {
3273 if (!is_inner_function && consume_cached_parse_data() &&
3274 !cached_parse_data_->rejected()) {
3275 // If we have cached data, we use it to skip parsing the function body. The 3248 // If we have cached data, we use it to skip parsing the function body. The
3276 // data contains the information we need to construct the lazy function. 3249 // data contains the information we need to construct the lazy function.
3277 FunctionEntry entry = 3250 FunctionEntry entry =
3278 cached_parse_data_->GetFunctionEntry(function_block_pos); 3251 cached_parse_data_->GetFunctionEntry(function_block_pos);
3279 // Check that cached data is valid. If not, mark it as invalid (the embedder 3252 // Check that cached data is valid. If not, mark it as invalid (the embedder
3280 // handles it). Note that end position greater than end of stream is safe, 3253 // handles it). Note that end position greater than end of stream is safe,
3281 // and hard to check. 3254 // and hard to check.
3282 if (entry.is_valid() && entry.end_pos() > function_block_pos) { 3255 if (entry.is_valid() && entry.end_pos() > function_block_pos) {
3283 scanner()->SeekForward(entry.end_pos() - 1); 3256 scanner()->SeekForward(entry.end_pos() - 1);
3284 3257
3285 scope->set_end_position(entry.end_pos()); 3258 scope->set_end_position(entry.end_pos());
3286 Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete)); 3259 Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete));
3287 total_preparse_skipped_ += scope->end_position() - function_block_pos; 3260 total_preparse_skipped_ += scope->end_position() - function_block_pos;
3288 *materialized_literal_count = entry.literal_count(); 3261 *materialized_literal_count = entry.literal_count();
3289 *expected_property_count = entry.property_count(); 3262 *expected_property_count = entry.property_count();
3290 SetLanguageMode(scope, entry.language_mode()); 3263 SetLanguageMode(scope, entry.language_mode());
3291 if (entry.uses_super_property()) scope->RecordSuperPropertyUsage(); 3264 if (entry.uses_super_property()) scope->RecordSuperPropertyUsage();
3292 if (entry.calls_eval()) scope->RecordEvalCall(); 3265 if (entry.calls_eval()) scope->RecordEvalCall();
3293 return kLazyParsingComplete; 3266 return kLazyParsingComplete;
3294 } 3267 }
3295 cached_parse_data_->Reject(); 3268 cached_parse_data_->Reject();
3296 } 3269 }
3297 // With no cached data, we partially parse the function, without building an 3270 // With no cached data, we partially parse the function, without building an
3298 // AST. This gathers the data needed to build a lazy function. 3271 // AST. This gathers the data needed to build a lazy function.
3299 SingletonLogger logger; 3272 SingletonLogger logger;
3300 PreParser::PreParseResult result = 3273 PreParser::PreParseResult result =
3301 ParseLazyFunctionBodyWithPreParser(&logger, is_inner_function, may_abort); 3274 ParseLazyFunctionBodyWithPreParser(&logger, may_abort);
3302 // Return immediately if pre-parser decided to abort parsing. 3275 // Return immediately if pre-parser decided to abort parsing.
3303 if (result == PreParser::kPreParseAbort) { 3276 if (result == PreParser::kPreParseAbort) {
3304 return kLazyParsingAborted; 3277 return kLazyParsingAborted;
3305 } 3278 }
3306 if (result == PreParser::kPreParseStackOverflow) { 3279 if (result == PreParser::kPreParseStackOverflow) {
3307 // Propagate stack overflow. 3280 // Propagate stack overflow.
3308 set_stack_overflow(); 3281 set_stack_overflow();
3309 *ok = false; 3282 *ok = false;
3310 return kLazyParsingComplete; 3283 return kLazyParsingComplete;
3311 } 3284 }
3312 if (logger.has_error()) { 3285 if (logger.has_error()) {
3313 ReportMessageAt(Scanner::Location(logger.start(), logger.end()), 3286 ReportMessageAt(Scanner::Location(logger.start(), logger.end()),
3314 logger.message(), logger.argument_opt(), 3287 logger.message(), logger.argument_opt(),
3315 logger.error_type()); 3288 logger.error_type());
3316 *ok = false; 3289 *ok = false;
3317 return kLazyParsingComplete; 3290 return kLazyParsingComplete;
3318 } 3291 }
3319 scope->set_end_position(logger.end()); 3292 scope->set_end_position(logger.end());
3320 Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete)); 3293 Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete));
3321 total_preparse_skipped_ += scope->end_position() - function_block_pos; 3294 total_preparse_skipped_ += scope->end_position() - function_block_pos;
3322 *materialized_literal_count = logger.literals(); 3295 *materialized_literal_count = logger.literals();
3323 *expected_property_count = logger.properties(); 3296 *expected_property_count = logger.properties();
3324 SetLanguageMode(scope, logger.language_mode()); 3297 SetLanguageMode(scope, logger.language_mode());
3325 if (logger.uses_super_property()) scope->RecordSuperPropertyUsage(); 3298 if (logger.uses_super_property()) scope->RecordSuperPropertyUsage();
3326 if (logger.calls_eval()) scope->RecordEvalCall(); 3299 if (logger.calls_eval()) scope->RecordEvalCall();
3327 if (!is_inner_function && produce_cached_parse_data()) { 3300 if (produce_cached_parse_data()) {
3328 DCHECK(log_); 3301 DCHECK(log_);
3329 // Position right after terminal '}'. 3302 // Position right after terminal '}'.
3330 int body_end = scanner()->location().end_pos; 3303 int body_end = scanner()->location().end_pos;
3331 log_->LogFunction(function_block_pos, body_end, *materialized_literal_count, 3304 log_->LogFunction(function_block_pos, body_end, *materialized_literal_count,
3332 *expected_property_count, language_mode(), 3305 *expected_property_count, language_mode(),
3333 scope->uses_super_property(), scope->calls_eval()); 3306 scope->uses_super_property(), scope->calls_eval());
3334 } 3307 }
3335 return kLazyParsingComplete; 3308 return kLazyParsingComplete;
3336 } 3309 }
3337 3310
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after
3619 } 3592 }
3620 3593
3621 VariableProxy* Parser::BuildDotDebugIsActive() { 3594 VariableProxy* Parser::BuildDotDebugIsActive() {
3622 return NewUnresolved(ast_value_factory()->dot_debug_is_active_string(), VAR); 3595 return NewUnresolved(ast_value_factory()->dot_debug_is_active_string(), VAR);
3623 } 3596 }
3624 3597
3625 ZoneList<Statement*>* Parser::ParseEagerFunctionBody( 3598 ZoneList<Statement*>* Parser::ParseEagerFunctionBody(
3626 const AstRawString* function_name, int pos, 3599 const AstRawString* function_name, int pos,
3627 const ParserFormalParameters& parameters, FunctionKind kind, 3600 const ParserFormalParameters& parameters, FunctionKind kind,
3628 FunctionLiteral::FunctionType function_type, bool* ok) { 3601 FunctionLiteral::FunctionType function_type, bool* ok) {
3629 // Everything inside an eagerly parsed function will be parsed eagerly (see 3602 // Everything inside an eagerly parsed function will be parsed eagerly
3630 // comment above). Lazy inner functions are handled separately and they won't 3603 // (see comment above).
3631 // require the mode to be PARSE_LAZILY (see ParseFunctionLiteral).
3632 // TODO(marja): Refactor parsing modes: remove this.
3633 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); 3604 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
3634 ZoneList<Statement*>* result = new(zone()) ZoneList<Statement*>(8, zone()); 3605 ZoneList<Statement*>* result = new(zone()) ZoneList<Statement*>(8, zone());
3606
3635 static const int kFunctionNameAssignmentIndex = 0; 3607 static const int kFunctionNameAssignmentIndex = 0;
3636 if (function_type == FunctionLiteral::kNamedExpression) { 3608 if (function_type == FunctionLiteral::kNamedExpression) {
3637 DCHECK(function_name != NULL); 3609 DCHECK(function_name != NULL);
3638 // If we have a named function expression, we add a local variable 3610 // If we have a named function expression, we add a local variable
3639 // declaration to the body of the function with the name of the 3611 // declaration to the body of the function with the name of the
3640 // function and let it refer to the function itself (closure). 3612 // function and let it refer to the function itself (closure).
3641 // Not having parsed the function body, the language mode may still change, 3613 // Not having parsed the function body, the language mode may still change,
3642 // so we reserve a spot and create the actual const assignment later. 3614 // so we reserve a spot and create the actual const assignment later.
3643 DCHECK_EQ(kFunctionNameAssignmentIndex, result->length()); 3615 DCHECK_EQ(kFunctionNameAssignmentIndex, result->length());
3644 result->Add(NULL, zone()); 3616 result->Add(NULL, zone());
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
3780 factory()->NewThisFunction(pos), 3752 factory()->NewThisFunction(pos),
3781 kNoSourcePosition), 3753 kNoSourcePosition),
3782 kNoSourcePosition)); 3754 kNoSourcePosition));
3783 } 3755 }
3784 3756
3785 MarkCollectedTailCallExpressions(); 3757 MarkCollectedTailCallExpressions();
3786 return result; 3758 return result;
3787 } 3759 }
3788 3760
3789 PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser( 3761 PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser(
3790 SingletonLogger* logger, bool is_inner_function, bool may_abort) { 3762 SingletonLogger* logger, bool may_abort) {
3791 // This function may be called on a background thread too; record only the 3763 // This function may be called on a background thread too; record only the
3792 // main thread preparse times. 3764 // main thread preparse times.
3793 if (pre_parse_timer_ != NULL) { 3765 if (pre_parse_timer_ != NULL) {
3794 pre_parse_timer_->Start(); 3766 pre_parse_timer_->Start();
3795 } 3767 }
3796 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.PreParse"); 3768 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.PreParse");
3797 3769
3798 DCHECK_EQ(Token::LBRACE, scanner()->current_token()); 3770 DCHECK_EQ(Token::LBRACE, scanner()->current_token());
3799 3771
3800 if (reusable_preparser_ == NULL) { 3772 if (reusable_preparser_ == NULL) {
3801 reusable_preparser_ = new PreParser(zone(), &scanner_, ast_value_factory(), 3773 reusable_preparser_ = new PreParser(zone(), &scanner_, ast_value_factory(),
3802 NULL, stack_limit_); 3774 NULL, stack_limit_);
3803 reusable_preparser_->set_allow_lazy(true); 3775 reusable_preparser_->set_allow_lazy(true);
3804 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name()); 3776 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name());
3805 SET_ALLOW(natives); 3777 SET_ALLOW(natives);
3806 SET_ALLOW(harmony_do_expressions); 3778 SET_ALLOW(harmony_do_expressions);
3807 SET_ALLOW(harmony_for_in); 3779 SET_ALLOW(harmony_for_in);
3808 SET_ALLOW(harmony_function_sent); 3780 SET_ALLOW(harmony_function_sent);
3809 SET_ALLOW(harmony_restrictive_declarations); 3781 SET_ALLOW(harmony_restrictive_declarations);
3810 SET_ALLOW(harmony_async_await); 3782 SET_ALLOW(harmony_async_await);
3811 SET_ALLOW(harmony_trailing_commas); 3783 SET_ALLOW(harmony_trailing_commas);
3812 SET_ALLOW(harmony_class_fields); 3784 SET_ALLOW(harmony_class_fields);
3813 #undef SET_ALLOW 3785 #undef SET_ALLOW
3814 } 3786 }
3815 // Aborting inner function preparsing would leave scopes in an inconsistent 3787 PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction(
3816 // state; we don't parse inner functions in the abortable mode anyway. 3788 language_mode(), function_state_->kind(),
3817 DCHECK(!is_inner_function || !may_abort); 3789 scope()->AsDeclarationScope()->has_simple_parameters(), parsing_module_,
3818 3790 logger, may_abort, use_counts_);
3819 FunctionKind kind = function_state_->kind();
3820 PreParser::PreParseResult result;
3821 if (!is_inner_function) {
3822 // If we don't need to look at the scope, construct a dummy scope chain
3823 // which is not connected to the real scope chain.
3824 LanguageMode mode = language_mode();
3825 bool has_simple_parameters =
3826 scope()->AsDeclarationScope()->has_simple_parameters();
3827 DeclarationScope* top_scope = NewScriptScope();
3828 top_scope->SetLanguageMode(mode);
3829 FunctionState top_state(&function_state_, &scope_state_, top_scope,
3830 kNormalFunction);
3831 DeclarationScope* function_scope = NewFunctionScope(kind);
3832 if (!has_simple_parameters) {
3833 function_scope->SetHasNonSimpleParameters();
3834 }
3835 result = reusable_preparser_->PreParseLazyFunction(
3836 kind, function_scope, parsing_module_, logger, is_inner_function,
3837 may_abort, use_counts_);
3838 } else {
3839 // Detaching the scopes created by PreParser from the Scope chain must be
3840 // done above (see ParseFunctionLiteral & AnalyzePartially).
3841 result = reusable_preparser_->PreParseLazyFunction(
3842 kind, scope()->AsDeclarationScope(), parsing_module_, logger,
3843 is_inner_function, may_abort, use_counts_);
3844 }
3845 if (pre_parse_timer_ != NULL) { 3791 if (pre_parse_timer_ != NULL) {
3846 pre_parse_timer_->Stop(); 3792 pre_parse_timer_->Stop();
3847 } 3793 }
3848 return result; 3794 return result;
3849 } 3795 }
3850 3796
3851 Expression* Parser::InstallHomeObject(Expression* function_literal, 3797 Expression* Parser::InstallHomeObject(Expression* function_literal,
3852 Expression* home_object) { 3798 Expression* home_object) {
3853 Block* do_block = factory()->NewBlock(nullptr, 1, false, kNoSourcePosition); 3799 Block* do_block = factory()->NewBlock(nullptr, 1, false, kNoSourcePosition);
3854 Variable* result_var = 3800 Variable* result_var =
(...skipping 2092 matching lines...) Expand 10 before | Expand all | Expand 10 after
5947 node->Print(Isolate::Current()); 5893 node->Print(Isolate::Current());
5948 } 5894 }
5949 #endif // DEBUG 5895 #endif // DEBUG
5950 5896
5951 #undef CHECK_OK 5897 #undef CHECK_OK
5952 #undef CHECK_OK_VOID 5898 #undef CHECK_OK_VOID
5953 #undef CHECK_FAILED 5899 #undef CHECK_FAILED
5954 5900
5955 } // namespace internal 5901 } // namespace internal
5956 } // namespace v8 5902 } // 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