| 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 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 207 | 207 |
| 208 set_language_mode(SLOPPY); | 208 set_language_mode(SLOPPY); |
| 209 | 209 |
| 210 scope_calls_eval_ = false; | 210 scope_calls_eval_ = false; |
| 211 scope_uses_super_property_ = false; | 211 scope_uses_super_property_ = false; |
| 212 has_arguments_parameter_ = false; | 212 has_arguments_parameter_ = false; |
| 213 scope_nonlinear_ = false; | 213 scope_nonlinear_ = false; |
| 214 is_hidden_ = false; | 214 is_hidden_ = false; |
| 215 is_debug_evaluate_scope_ = false; | 215 is_debug_evaluate_scope_ = false; |
| 216 | 216 |
| 217 outer_scope_calls_sloppy_eval_ = false; | |
| 218 inner_scope_calls_eval_ = false; | 217 inner_scope_calls_eval_ = false; |
| 219 force_eager_compilation_ = false; | 218 force_eager_compilation_ = false; |
| 220 force_context_allocation_ = false; | 219 force_context_allocation_ = false; |
| 221 | 220 |
| 222 is_declaration_scope_ = false; | 221 is_declaration_scope_ = false; |
| 223 } | 222 } |
| 224 | 223 |
| 225 bool Scope::HasSimpleParameters() { | 224 bool Scope::HasSimpleParameters() { |
| 226 DeclarationScope* scope = GetClosureScope(); | 225 DeclarationScope* scope = GetClosureScope(); |
| 227 return !scope->is_function_scope() || scope->has_simple_parameters(); | 226 return !scope->is_function_scope() || scope->has_simple_parameters(); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 290 ast_value_factory->GetString(handle(name, isolate))); | 289 ast_value_factory->GetString(handle(name, isolate))); |
| 291 } | 290 } |
| 292 if (deserialization_mode == DeserializationMode::kDeserializeOffHeap) { | 291 if (deserialization_mode == DeserializationMode::kDeserializeOffHeap) { |
| 293 current_scope->DeserializeScopeInfo(isolate, ast_value_factory); | 292 current_scope->DeserializeScopeInfo(isolate, ast_value_factory); |
| 294 } | 293 } |
| 295 if (innermost_scope == nullptr) innermost_scope = current_scope; | 294 if (innermost_scope == nullptr) innermost_scope = current_scope; |
| 296 context = context->previous(); | 295 context = context->previous(); |
| 297 } | 296 } |
| 298 | 297 |
| 299 script_scope->AddInnerScope(current_scope); | 298 script_scope->AddInnerScope(current_scope); |
| 300 script_scope->PropagateScopeInfo(false); | 299 script_scope->PropagateScopeInfo(); |
| 301 return (innermost_scope == NULL) ? script_scope : innermost_scope; | 300 return (innermost_scope == NULL) ? script_scope : innermost_scope; |
| 302 } | 301 } |
| 303 | 302 |
| 304 void Scope::DeserializeScopeInfo(Isolate* isolate, | 303 void Scope::DeserializeScopeInfo(Isolate* isolate, |
| 305 AstValueFactory* ast_value_factory) { | 304 AstValueFactory* ast_value_factory) { |
| 306 if (scope_info_.is_null()) return; | 305 if (scope_info_.is_null()) return; |
| 307 | 306 |
| 308 DCHECK(ThreadId::Current().Equals(isolate->thread_id())); | 307 DCHECK(ThreadId::Current().Equals(isolate->thread_id())); |
| 309 | 308 |
| 310 std::set<const AstRawString*> names_seen; | 309 std::set<const AstRawString*> names_seen; |
| (...skipping 546 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 857 context_locals->Add(var, zone()); | 856 context_locals->Add(var, zone()); |
| 858 } else if (var->IsGlobalSlot()) { | 857 } else if (var->IsGlobalSlot()) { |
| 859 context_globals->Add(var, zone()); | 858 context_globals->Add(var, zone()); |
| 860 } | 859 } |
| 861 } | 860 } |
| 862 } | 861 } |
| 863 | 862 |
| 864 void DeclarationScope::AllocateVariables(ParseInfo* info, | 863 void DeclarationScope::AllocateVariables(ParseInfo* info, |
| 865 AstNodeFactory* factory) { | 864 AstNodeFactory* factory) { |
| 866 // 1) Propagate scope information. | 865 // 1) Propagate scope information. |
| 867 bool outer_scope_calls_sloppy_eval = false; | 866 PropagateScopeInfo(); |
| 868 if (outer_scope_ != NULL) { | |
| 869 outer_scope_calls_sloppy_eval = | |
| 870 outer_scope_->outer_scope_calls_sloppy_eval() | | |
| 871 outer_scope_->calls_sloppy_eval(); | |
| 872 } | |
| 873 PropagateScopeInfo(outer_scope_calls_sloppy_eval); | |
| 874 | 867 |
| 875 // 2) Resolve variables. | 868 // 2) Resolve variables. |
| 876 ResolveVariablesRecursively(info, factory); | 869 ResolveVariablesRecursively(info, factory); |
| 877 | 870 |
| 878 // 3) Allocate variables. | 871 // 3) Allocate variables. |
| 879 AllocateVariablesRecursively(); | 872 AllocateVariablesRecursively(); |
| 880 } | 873 } |
| 881 | 874 |
| 882 | 875 |
| 883 bool Scope::AllowsLazyParsing() const { | 876 bool Scope::AllowsLazyParsing() const { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 898 if (force_eager_compilation_) return false; | 891 if (force_eager_compilation_) return false; |
| 899 // Disallow lazy compilation without context if any outer scope needs a | 892 // Disallow lazy compilation without context if any outer scope needs a |
| 900 // context. | 893 // context. |
| 901 for (const Scope* scope = outer_scope_; scope != nullptr; | 894 for (const Scope* scope = outer_scope_; scope != nullptr; |
| 902 scope = scope->outer_scope_) { | 895 scope = scope->outer_scope_) { |
| 903 if (scope->NeedsContext()) return false; | 896 if (scope->NeedsContext()) return false; |
| 904 } | 897 } |
| 905 return true; | 898 return true; |
| 906 } | 899 } |
| 907 | 900 |
| 908 | 901 int Scope::ContextChainLength(Scope* scope) const { |
| 909 int Scope::ContextChainLength(Scope* scope) { | |
| 910 int n = 0; | 902 int n = 0; |
| 911 for (Scope* s = this; s != scope; s = s->outer_scope_) { | 903 for (const Scope* s = this; s != scope; s = s->outer_scope_) { |
| 912 DCHECK(s != NULL); // scope must be in the scope chain | 904 DCHECK(s != NULL); // scope must be in the scope chain |
| 913 if (s->NeedsContext()) n++; | 905 if (s->NeedsContext()) n++; |
| 914 } | 906 } |
| 915 return n; | 907 return n; |
| 916 } | 908 } |
| 917 | 909 |
| 910 int Scope::ContextChainLengthUntilOutermostSloppyEval() const { |
| 911 int result = 0; |
| 912 int length = 0; |
| 913 |
| 914 for (const Scope* s = this; s != nullptr; s = s->outer_scope()) { |
| 915 if (!s->NeedsContext()) continue; |
| 916 length++; |
| 917 if (s->calls_sloppy_eval()) result = length; |
| 918 } |
| 919 |
| 920 return result; |
| 921 } |
| 918 | 922 |
| 919 int Scope::MaxNestedContextChainLength() { | 923 int Scope::MaxNestedContextChainLength() { |
| 920 int max_context_chain_length = 0; | 924 int max_context_chain_length = 0; |
| 921 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { | 925 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { |
| 922 max_context_chain_length = std::max(scope->MaxNestedContextChainLength(), | 926 max_context_chain_length = std::max(scope->MaxNestedContextChainLength(), |
| 923 max_context_chain_length); | 927 max_context_chain_length); |
| 924 } | 928 } |
| 925 if (NeedsContext()) { | 929 if (NeedsContext()) { |
| 926 max_context_chain_length += 1; | 930 max_context_chain_length += 1; |
| 927 } | 931 } |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 969 for (VariableProxy* proxy = free_variables; proxy != nullptr; | 973 for (VariableProxy* proxy = free_variables; proxy != nullptr; |
| 970 proxy = proxy->next_unresolved()) { | 974 proxy = proxy->next_unresolved()) { |
| 971 non_locals = StringSet::Add(non_locals, proxy->name()); | 975 non_locals = StringSet::Add(non_locals, proxy->name()); |
| 972 } | 976 } |
| 973 return non_locals; | 977 return non_locals; |
| 974 } | 978 } |
| 975 | 979 |
| 976 void DeclarationScope::AnalyzePartially(DeclarationScope* migrate_to, | 980 void DeclarationScope::AnalyzePartially(DeclarationScope* migrate_to, |
| 977 AstNodeFactory* ast_node_factory) { | 981 AstNodeFactory* ast_node_factory) { |
| 978 // Gather info from inner scopes. | 982 // Gather info from inner scopes. |
| 979 PropagateScopeInfo(false); | 983 PropagateScopeInfo(); |
| 980 | 984 |
| 981 // Try to resolve unresolved variables for this Scope and migrate those which | 985 // Try to resolve unresolved variables for this Scope and migrate those which |
| 982 // cannot be resolved inside. It doesn't make sense to try to resolve them in | 986 // cannot be resolved inside. It doesn't make sense to try to resolve them in |
| 983 // the outer Scopes here, because they are incomplete. | 987 // the outer Scopes here, because they are incomplete. |
| 984 for (VariableProxy* proxy = FetchFreeVariables(this); proxy != nullptr; | 988 for (VariableProxy* proxy = FetchFreeVariables(this); proxy != nullptr; |
| 985 proxy = proxy->next_unresolved()) { | 989 proxy = proxy->next_unresolved()) { |
| 986 DCHECK(!proxy->is_resolved()); | 990 DCHECK(!proxy->is_resolved()); |
| 987 VariableProxy* copy = ast_node_factory->CopyVariableProxy(proxy); | 991 VariableProxy* copy = ast_node_factory->CopyVariableProxy(proxy); |
| 988 migrate_to->AddUnresolved(copy); | 992 migrate_to->AddUnresolved(copy); |
| 989 } | 993 } |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1147 | 1151 |
| 1148 // Scope info. | 1152 // Scope info. |
| 1149 if (is_strict(language_mode())) { | 1153 if (is_strict(language_mode())) { |
| 1150 Indent(n1, "// strict mode scope\n"); | 1154 Indent(n1, "// strict mode scope\n"); |
| 1151 } | 1155 } |
| 1152 if (IsAsmModule()) Indent(n1, "// scope is an asm module\n"); | 1156 if (IsAsmModule()) Indent(n1, "// scope is an asm module\n"); |
| 1153 if (IsAsmFunction()) Indent(n1, "// scope is an asm function\n"); | 1157 if (IsAsmFunction()) Indent(n1, "// scope is an asm function\n"); |
| 1154 if (scope_calls_eval_) Indent(n1, "// scope calls 'eval'\n"); | 1158 if (scope_calls_eval_) Indent(n1, "// scope calls 'eval'\n"); |
| 1155 if (scope_uses_super_property_) | 1159 if (scope_uses_super_property_) |
| 1156 Indent(n1, "// scope uses 'super' property\n"); | 1160 Indent(n1, "// scope uses 'super' property\n"); |
| 1157 if (outer_scope_calls_sloppy_eval_) { | |
| 1158 Indent(n1, "// outer scope calls 'eval' in sloppy context\n"); | |
| 1159 } | |
| 1160 if (inner_scope_calls_eval_) Indent(n1, "// inner scope calls 'eval'\n"); | 1161 if (inner_scope_calls_eval_) Indent(n1, "// inner scope calls 'eval'\n"); |
| 1161 if (num_stack_slots_ > 0) { | 1162 if (num_stack_slots_ > 0) { |
| 1162 Indent(n1, "// "); | 1163 Indent(n1, "// "); |
| 1163 PrintF("%d stack slots\n", num_stack_slots_); | 1164 PrintF("%d stack slots\n", num_stack_slots_); |
| 1164 } | 1165 } |
| 1165 if (num_heap_slots_ > 0) { | 1166 if (num_heap_slots_ > 0) { |
| 1166 Indent(n1, "// "); | 1167 Indent(n1, "// "); |
| 1167 PrintF("%d heap slots (including %d global slots)\n", num_heap_slots_, | 1168 PrintF("%d heap slots (including %d global slots)\n", num_heap_slots_, |
| 1168 num_global_slots_); | 1169 num_global_slots_); |
| 1169 } | 1170 } |
| (...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1457 // Clear unresolved_ as it's in an inconsistent state. | 1458 // Clear unresolved_ as it's in an inconsistent state. |
| 1458 unresolved_ = nullptr; | 1459 unresolved_ = nullptr; |
| 1459 | 1460 |
| 1460 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { | 1461 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { |
| 1461 stack = scope->FetchFreeVariables(max_outer_scope, info, stack); | 1462 stack = scope->FetchFreeVariables(max_outer_scope, info, stack); |
| 1462 } | 1463 } |
| 1463 | 1464 |
| 1464 return stack; | 1465 return stack; |
| 1465 } | 1466 } |
| 1466 | 1467 |
| 1467 void Scope::PropagateScopeInfo(bool outer_scope_calls_sloppy_eval) { | 1468 void Scope::PropagateScopeInfo() { |
| 1468 if (outer_scope_calls_sloppy_eval) { | |
| 1469 outer_scope_calls_sloppy_eval_ = true; | |
| 1470 } | |
| 1471 | |
| 1472 bool calls_sloppy_eval = | |
| 1473 this->calls_sloppy_eval() || outer_scope_calls_sloppy_eval_; | |
| 1474 for (Scope* inner = inner_scope_; inner != nullptr; inner = inner->sibling_) { | 1469 for (Scope* inner = inner_scope_; inner != nullptr; inner = inner->sibling_) { |
| 1475 inner->PropagateScopeInfo(calls_sloppy_eval); | 1470 inner->PropagateScopeInfo(); |
| 1476 if (inner->scope_calls_eval_ || inner->inner_scope_calls_eval_) { | 1471 if (inner->scope_calls_eval_ || inner->inner_scope_calls_eval_) { |
| 1477 inner_scope_calls_eval_ = true; | 1472 inner_scope_calls_eval_ = true; |
| 1478 } | 1473 } |
| 1479 if (inner->force_eager_compilation_) { | 1474 if (inner->force_eager_compilation_) { |
| 1480 force_eager_compilation_ = true; | 1475 force_eager_compilation_ = true; |
| 1481 } | 1476 } |
| 1482 if (IsAsmModule() && inner->is_function_scope()) { | 1477 if (IsAsmModule() && inner->is_function_scope()) { |
| 1483 inner->AsDeclarationScope()->set_asm_function(); | 1478 inner->AsDeclarationScope()->set_asm_function(); |
| 1484 } | 1479 } |
| 1485 } | 1480 } |
| (...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1766 function != nullptr && function->IsContextSlot(); | 1761 function != nullptr && function->IsContextSlot(); |
| 1767 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - | 1762 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - |
| 1768 (is_function_var_in_context ? 1 : 0); | 1763 (is_function_var_in_context ? 1 : 0); |
| 1769 } | 1764 } |
| 1770 | 1765 |
| 1771 | 1766 |
| 1772 int Scope::ContextGlobalCount() const { return num_global_slots(); } | 1767 int Scope::ContextGlobalCount() const { return num_global_slots(); } |
| 1773 | 1768 |
| 1774 } // namespace internal | 1769 } // namespace internal |
| 1775 } // namespace v8 | 1770 } // namespace v8 |
| OLD | NEW |