| 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/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 244 force_context_allocation_ = false; | 244 force_context_allocation_ = false; |
| 245 | 245 |
| 246 is_declaration_scope_ = false; | 246 is_declaration_scope_ = false; |
| 247 } | 247 } |
| 248 | 248 |
| 249 bool Scope::HasSimpleParameters() { | 249 bool Scope::HasSimpleParameters() { |
| 250 DeclarationScope* scope = GetClosureScope(); | 250 DeclarationScope* scope = GetClosureScope(); |
| 251 return !scope->is_function_scope() || scope->has_simple_parameters(); | 251 return !scope->is_function_scope() || scope->has_simple_parameters(); |
| 252 } | 252 } |
| 253 | 253 |
| 254 void DeclarationScope::set_asm_module() { |
| 255 asm_module_ = true; |
| 256 // Mark any existing inner function scopes as asm function scopes. |
| 257 for (Scope* inner = inner_scope_; inner != nullptr; inner = inner->sibling_) { |
| 258 if (inner->is_function_scope()) { |
| 259 inner->AsDeclarationScope()->set_asm_function(); |
| 260 } |
| 261 } |
| 262 } |
| 263 |
| 254 bool Scope::IsAsmModule() const { | 264 bool Scope::IsAsmModule() const { |
| 255 return is_function_scope() && AsDeclarationScope()->asm_module(); | 265 return is_function_scope() && AsDeclarationScope()->asm_module(); |
| 256 } | 266 } |
| 257 | 267 |
| 258 bool Scope::IsAsmFunction() const { | 268 bool Scope::IsAsmFunction() const { |
| 259 return is_function_scope() && AsDeclarationScope()->asm_function(); | 269 return is_function_scope() && AsDeclarationScope()->asm_function(); |
| 260 } | 270 } |
| 261 | 271 |
| 262 Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone, | 272 Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone, |
| 263 Context* context, | 273 Context* context, |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 322 current_scope = outer_scope; | 332 current_scope = outer_scope; |
| 323 if (deserialization_mode == DeserializationMode::kDeserializeOffHeap) { | 333 if (deserialization_mode == DeserializationMode::kDeserializeOffHeap) { |
| 324 current_scope->DeserializeScopeInfo(isolate, ast_value_factory); | 334 current_scope->DeserializeScopeInfo(isolate, ast_value_factory); |
| 325 } | 335 } |
| 326 if (innermost_scope == nullptr) innermost_scope = current_scope; | 336 if (innermost_scope == nullptr) innermost_scope = current_scope; |
| 327 context = context->previous(); | 337 context = context->previous(); |
| 328 } | 338 } |
| 329 | 339 |
| 330 if (innermost_scope == nullptr) return script_scope; | 340 if (innermost_scope == nullptr) return script_scope; |
| 331 script_scope->AddInnerScope(current_scope); | 341 script_scope->AddInnerScope(current_scope); |
| 332 script_scope->PropagateScopeInfo(); | |
| 333 return innermost_scope; | 342 return innermost_scope; |
| 334 } | 343 } |
| 335 | 344 |
| 336 void Scope::DeserializeScopeInfo(Isolate* isolate, | 345 void Scope::DeserializeScopeInfo(Isolate* isolate, |
| 337 AstValueFactory* ast_value_factory) { | 346 AstValueFactory* ast_value_factory) { |
| 338 if (scope_info_.is_null()) return; | 347 if (scope_info_.is_null()) return; |
| 339 | 348 |
| 340 DCHECK(ThreadId::Current().Equals(isolate->thread_id())); | 349 DCHECK(ThreadId::Current().Equals(isolate->thread_id())); |
| 341 | 350 |
| 342 // Internalize context local variables. | 351 // Internalize context local variables. |
| (...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 871 return decls_[j]; | 880 return decls_[j]; |
| 872 } | 881 } |
| 873 } | 882 } |
| 874 DCHECK(false); | 883 DCHECK(false); |
| 875 } | 884 } |
| 876 } | 885 } |
| 877 return nullptr; | 886 return nullptr; |
| 878 } | 887 } |
| 879 | 888 |
| 880 void DeclarationScope::AllocateVariables(ParseInfo* info, AnalyzeMode mode) { | 889 void DeclarationScope::AllocateVariables(ParseInfo* info, AnalyzeMode mode) { |
| 881 PropagateScopeInfo(); | |
| 882 ResolveVariablesRecursively(info); | 890 ResolveVariablesRecursively(info); |
| 883 AllocateVariablesRecursively(); | 891 AllocateVariablesRecursively(); |
| 884 AllocateScopeInfosRecursively(info->isolate(), mode); | 892 AllocateScopeInfosRecursively(info->isolate(), mode); |
| 885 } | 893 } |
| 886 | 894 |
| 887 bool Scope::AllowsLazyParsing() const { | 895 bool Scope::AllowsLazyParsing() const { |
| 888 // If we are inside a block scope, we must parse eagerly to find out how | 896 // If we are inside a block scope, we must parse eagerly to find out how |
| 889 // to allocate variables on the block scope. At this point, declarations may | 897 // to allocate variables on the block scope. At this point, declarations may |
| 890 // not have yet been parsed. | 898 // not have yet been parsed. |
| 891 for (const Scope* s = this; s != nullptr; s = s->outer_scope_) { | 899 for (const Scope* s = this; s != nullptr; s = s->outer_scope_) { |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 974 VariableProxy* free_variables = FetchFreeVariables(this, info); | 982 VariableProxy* free_variables = FetchFreeVariables(this, info); |
| 975 for (VariableProxy* proxy = free_variables; proxy != nullptr; | 983 for (VariableProxy* proxy = free_variables; proxy != nullptr; |
| 976 proxy = proxy->next_unresolved()) { | 984 proxy = proxy->next_unresolved()) { |
| 977 non_locals = StringSet::Add(non_locals, proxy->name()); | 985 non_locals = StringSet::Add(non_locals, proxy->name()); |
| 978 } | 986 } |
| 979 return non_locals; | 987 return non_locals; |
| 980 } | 988 } |
| 981 | 989 |
| 982 void DeclarationScope::AnalyzePartially(DeclarationScope* migrate_to, | 990 void DeclarationScope::AnalyzePartially(DeclarationScope* migrate_to, |
| 983 AstNodeFactory* ast_node_factory) { | 991 AstNodeFactory* ast_node_factory) { |
| 984 // Gather info from inner scopes. | |
| 985 PropagateScopeInfo(); | |
| 986 | |
| 987 // Try to resolve unresolved variables for this Scope and migrate those which | 992 // Try to resolve unresolved variables for this Scope and migrate those which |
| 988 // cannot be resolved inside. It doesn't make sense to try to resolve them in | 993 // cannot be resolved inside. It doesn't make sense to try to resolve them in |
| 989 // the outer Scopes here, because they are incomplete. | 994 // the outer Scopes here, because they are incomplete. |
| 990 for (VariableProxy* proxy = FetchFreeVariables(this); proxy != nullptr; | 995 for (VariableProxy* proxy = FetchFreeVariables(this); proxy != nullptr; |
| 991 proxy = proxy->next_unresolved()) { | 996 proxy = proxy->next_unresolved()) { |
| 992 DCHECK(!proxy->is_resolved()); | 997 DCHECK(!proxy->is_resolved()); |
| 993 VariableProxy* copy = ast_node_factory->CopyVariableProxy(proxy); | 998 VariableProxy* copy = ast_node_factory->CopyVariableProxy(proxy); |
| 994 migrate_to->AddUnresolved(copy); | 999 migrate_to->AddUnresolved(copy); |
| 995 } | 1000 } |
| 996 | 1001 |
| (...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1396 // Clear unresolved_ as it's in an inconsistent state. | 1401 // Clear unresolved_ as it's in an inconsistent state. |
| 1397 unresolved_ = nullptr; | 1402 unresolved_ = nullptr; |
| 1398 | 1403 |
| 1399 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { | 1404 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { |
| 1400 stack = scope->FetchFreeVariables(max_outer_scope, info, stack); | 1405 stack = scope->FetchFreeVariables(max_outer_scope, info, stack); |
| 1401 } | 1406 } |
| 1402 | 1407 |
| 1403 return stack; | 1408 return stack; |
| 1404 } | 1409 } |
| 1405 | 1410 |
| 1406 void Scope::PropagateScopeInfo() { | |
| 1407 for (Scope* inner = inner_scope_; inner != nullptr; inner = inner->sibling_) { | |
| 1408 inner->PropagateScopeInfo(); | |
| 1409 if (IsAsmModule() && inner->is_function_scope()) { | |
| 1410 inner->AsDeclarationScope()->set_asm_function(); | |
| 1411 } | |
| 1412 } | |
| 1413 } | |
| 1414 | |
| 1415 | |
| 1416 bool Scope::MustAllocate(Variable* var) { | 1411 bool Scope::MustAllocate(Variable* var) { |
| 1417 DCHECK(var->location() != VariableLocation::MODULE); | 1412 DCHECK(var->location() != VariableLocation::MODULE); |
| 1418 // Give var a read/write use if there is a chance it might be accessed | 1413 // Give var a read/write use if there is a chance it might be accessed |
| 1419 // via an eval() call. This is only possible if the variable has a | 1414 // via an eval() call. This is only possible if the variable has a |
| 1420 // visible name. | 1415 // visible name. |
| 1421 if ((var->is_this() || !var->raw_name()->IsEmpty()) && | 1416 if ((var->is_this() || !var->raw_name()->IsEmpty()) && |
| 1422 (inner_scope_calls_eval_ || is_catch_scope() || is_script_scope())) { | 1417 (inner_scope_calls_eval_ || is_catch_scope() || is_script_scope())) { |
| 1423 var->set_is_used(); | 1418 var->set_is_used(); |
| 1424 if (inner_scope_calls_eval_) var->set_maybe_assigned(); | 1419 if (inner_scope_calls_eval_) var->set_maybe_assigned(); |
| 1425 } | 1420 } |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1653 Variable* function = | 1648 Variable* function = |
| 1654 is_function_scope() ? AsDeclarationScope()->function_var() : nullptr; | 1649 is_function_scope() ? AsDeclarationScope()->function_var() : nullptr; |
| 1655 bool is_function_var_in_context = | 1650 bool is_function_var_in_context = |
| 1656 function != nullptr && function->IsContextSlot(); | 1651 function != nullptr && function->IsContextSlot(); |
| 1657 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - | 1652 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - |
| 1658 (is_function_var_in_context ? 1 : 0); | 1653 (is_function_var_in_context ? 1 : 0); |
| 1659 } | 1654 } |
| 1660 | 1655 |
| 1661 } // namespace internal | 1656 } // namespace internal |
| 1662 } // namespace v8 | 1657 } // namespace v8 |
| OLD | NEW |