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