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/ast/scopes.h" | 5 #include "src/ast/scopes.h" |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 | 8 |
9 #include "src/accessors.h" | 9 #include "src/accessors.h" |
10 #include "src/ast/ast.h" | 10 #include "src/ast/ast.h" |
11 #include "src/bootstrapper.h" | 11 #include "src/bootstrapper.h" |
12 #include "src/counters.h" | 12 #include "src/counters.h" |
13 #include "src/messages.h" | 13 #include "src/messages.h" |
14 #include "src/objects-inl.h" | 14 #include "src/objects-inl.h" |
15 #include "src/objects/module-info.h" | 15 #include "src/objects/module-info.h" |
16 #include "src/objects/scope-info.h" | 16 #include "src/objects/scope-info.h" |
17 #include "src/parsing/parse-info.h" | 17 #include "src/parsing/parse-info.h" |
| 18 #include "src/parsing/preparsed-scope-data.h" |
18 | 19 |
19 namespace v8 { | 20 namespace v8 { |
20 namespace internal { | 21 namespace internal { |
21 | 22 |
22 namespace { | 23 namespace { |
23 void* kDummyPreParserVariable = reinterpret_cast<void*>(0x1); | 24 void* kDummyPreParserVariable = reinterpret_cast<void*>(0x1); |
24 void* kDummyPreParserLexicalVariable = reinterpret_cast<void*>(0x2); | 25 void* kDummyPreParserLexicalVariable = reinterpret_cast<void*>(0x2); |
25 | 26 |
26 bool IsLexical(Variable* variable) { | 27 bool IsLexical(Variable* variable) { |
27 if (variable == kDummyPreParserLexicalVariable) return true; | 28 if (variable == kDummyPreParserLexicalVariable) return true; |
(...skipping 1342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1370 } | 1371 } |
1371 | 1372 |
1372 #ifdef DEBUG | 1373 #ifdef DEBUG |
1373 needs_migration_ = false; | 1374 needs_migration_ = false; |
1374 is_being_lazily_parsed_ = false; | 1375 is_being_lazily_parsed_ = false; |
1375 #endif | 1376 #endif |
1376 | 1377 |
1377 was_lazily_parsed_ = !aborted; | 1378 was_lazily_parsed_ = !aborted; |
1378 } | 1379 } |
1379 | 1380 |
1380 void DeclarationScope::AnalyzePartially(AstNodeFactory* ast_node_factory) { | 1381 void DeclarationScope::AnalyzePartially( |
| 1382 AstNodeFactory* ast_node_factory, |
| 1383 PreParsedScopeData* preparsed_scope_data) { |
1381 DCHECK(!force_eager_compilation_); | 1384 DCHECK(!force_eager_compilation_); |
1382 VariableProxy* unresolved = nullptr; | 1385 VariableProxy* unresolved = nullptr; |
1383 | 1386 |
1384 if (!outer_scope_->is_script_scope()) { | 1387 if (!outer_scope_->is_script_scope()) { |
1385 // Try to resolve unresolved variables for this Scope and migrate those | 1388 // Try to resolve unresolved variables for this Scope and migrate those |
1386 // which cannot be resolved inside. It doesn't make sense to try to resolve | 1389 // which cannot be resolved inside. It doesn't make sense to try to resolve |
1387 // them in the outer Scopes here, because they are incomplete. | 1390 // them in the outer Scopes here, because they are incomplete. |
1388 for (VariableProxy* proxy = FetchFreeVariables(this); proxy != nullptr; | 1391 for (VariableProxy* proxy = FetchFreeVariables(this); proxy != nullptr; |
1389 proxy = proxy->next_unresolved()) { | 1392 proxy = proxy->next_unresolved()) { |
1390 DCHECK(!proxy->is_resolved()); | 1393 DCHECK(!proxy->is_resolved()); |
1391 VariableProxy* copy = ast_node_factory->CopyVariableProxy(proxy); | 1394 VariableProxy* copy = ast_node_factory->CopyVariableProxy(proxy); |
1392 copy->set_next_unresolved(unresolved); | 1395 copy->set_next_unresolved(unresolved); |
1393 unresolved = copy; | 1396 unresolved = copy; |
1394 } | 1397 } |
1395 | 1398 |
1396 // Clear arguments_ if unused. This is used as a signal for optimization. | 1399 // Clear arguments_ if unused. This is used as a signal for optimization. |
1397 if (arguments_ != nullptr && | 1400 if (arguments_ != nullptr && |
1398 !(MustAllocate(arguments_) && !has_arguments_parameter_)) { | 1401 !(MustAllocate(arguments_) && !has_arguments_parameter_)) { |
1399 arguments_ = nullptr; | 1402 arguments_ = nullptr; |
1400 } | 1403 } |
| 1404 |
| 1405 if (FLAG_preparser_scope_analysis) { |
| 1406 // Decide context allocation for the locals and parameters and store the |
| 1407 // info away. |
| 1408 AllocateVariablesRecursively(); |
| 1409 CollectVariableData(preparsed_scope_data); |
| 1410 } |
1401 } | 1411 } |
1402 | 1412 |
1403 ResetAfterPreparsing(ast_node_factory->ast_value_factory(), false); | 1413 ResetAfterPreparsing(ast_node_factory->ast_value_factory(), false); |
1404 | 1414 |
1405 unresolved_ = unresolved; | 1415 unresolved_ = unresolved; |
1406 } | 1416 } |
1407 | 1417 |
1408 #ifdef DEBUG | 1418 #ifdef DEBUG |
1409 namespace { | 1419 namespace { |
1410 | 1420 |
(...skipping 733 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2144 if (scope_info_.is_null()) { | 2154 if (scope_info_.is_null()) { |
2145 scope_info_ = ScopeInfo::Create(isolate, zone(), this, outer_scope); | 2155 scope_info_ = ScopeInfo::Create(isolate, zone(), this, outer_scope); |
2146 } | 2156 } |
2147 MaybeHandle<ScopeInfo> outer = NeedsContext() ? scope_info_ : outer_scope; | 2157 MaybeHandle<ScopeInfo> outer = NeedsContext() ? scope_info_ : outer_scope; |
2148 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { | 2158 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { |
2149 if (scope->is_function_scope()) continue; | 2159 if (scope->is_function_scope()) continue; |
2150 scope->AllocateDebuggerScopeInfos(isolate, outer); | 2160 scope->AllocateDebuggerScopeInfos(isolate, outer); |
2151 } | 2161 } |
2152 } | 2162 } |
2153 | 2163 |
| 2164 void Scope::CollectVariableData(PreParsedScopeData* data) { |
| 2165 PreParsedScopeData::ScopeScope scope_scope(data, scope_type(), |
| 2166 start_position(), end_position()); |
| 2167 // TODO(marja): Add data about the variables. |
| 2168 |
| 2169 for (Scope* inner = inner_scope_; inner != nullptr; inner = inner->sibling_) { |
| 2170 inner->CollectVariableData(data); |
| 2171 } |
| 2172 } |
| 2173 |
2154 int Scope::StackLocalCount() const { | 2174 int Scope::StackLocalCount() const { |
2155 Variable* function = | 2175 Variable* function = |
2156 is_function_scope() ? AsDeclarationScope()->function_var() : nullptr; | 2176 is_function_scope() ? AsDeclarationScope()->function_var() : nullptr; |
2157 return num_stack_slots() - | 2177 return num_stack_slots() - |
2158 (function != nullptr && function->IsStackLocal() ? 1 : 0); | 2178 (function != nullptr && function->IsStackLocal() ? 1 : 0); |
2159 } | 2179 } |
2160 | 2180 |
2161 | 2181 |
2162 int Scope::ContextLocalCount() const { | 2182 int Scope::ContextLocalCount() const { |
2163 if (num_heap_slots() == 0) return 0; | 2183 if (num_heap_slots() == 0) return 0; |
2164 Variable* function = | 2184 Variable* function = |
2165 is_function_scope() ? AsDeclarationScope()->function_var() : nullptr; | 2185 is_function_scope() ? AsDeclarationScope()->function_var() : nullptr; |
2166 bool is_function_var_in_context = | 2186 bool is_function_var_in_context = |
2167 function != nullptr && function->IsContextSlot(); | 2187 function != nullptr && function->IsContextSlot(); |
2168 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - | 2188 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - |
2169 (is_function_var_in_context ? 1 : 0); | 2189 (is_function_var_in_context ? 1 : 0); |
2170 } | 2190 } |
2171 | 2191 |
2172 } // namespace internal | 2192 } // namespace internal |
2173 } // namespace v8 | 2193 } // namespace v8 |
OLD | NEW |