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