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 |