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 862 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
873 PropagateScopeInfo(outer_scope_calls_sloppy_eval); | 873 PropagateScopeInfo(outer_scope_calls_sloppy_eval); |
874 | 874 |
875 // 2) Resolve variables. | 875 // 2) Resolve variables. |
876 ResolveVariablesRecursively(info, factory); | 876 ResolveVariablesRecursively(info, factory); |
877 | 877 |
878 // 3) Allocate variables. | 878 // 3) Allocate variables. |
879 AllocateVariablesRecursively(); | 879 AllocateVariablesRecursively(); |
880 } | 880 } |
881 | 881 |
882 | 882 |
883 bool Scope::HasTrivialContext() const { | |
884 // A function scope has a trivial context if it always is the global | |
885 // context. We iteratively scan out the context chain to see if | |
886 // there is anything that makes this scope non-trivial; otherwise we | |
887 // return true. | |
888 for (const Scope* scope = this; scope != NULL; scope = scope->outer_scope_) { | |
889 if (scope->is_eval_scope()) return false; | |
890 if (scope->InsideWithScope()) return false; | |
891 if (scope->ContextLocalCount() > 0) return false; | |
892 if (scope->ContextGlobalCount() > 0) return false; | |
893 } | |
894 return true; | |
895 } | |
896 | |
897 | |
898 bool Scope::HasTrivialOuterContext() const { | |
899 if (outer_scope_ == nullptr) return true; | |
900 // Note that the outer context may be trivial in general, but the current | |
901 // scope may be inside a 'with' statement in which case the outer context | |
902 // for this scope is not trivial. | |
903 return !is_with_scope() && outer_scope_->HasTrivialContext(); | |
904 } | |
905 | |
906 | |
907 bool Scope::AllowsLazyParsing() const { | 883 bool Scope::AllowsLazyParsing() const { |
908 // If we are inside a block scope, we must parse eagerly to find out how | 884 // If we are inside a block scope, we must parse eagerly to find out how |
909 // to allocate variables on the block scope. At this point, declarations may | 885 // to allocate variables on the block scope. At this point, declarations may |
910 // not have yet been parsed. | 886 // not have yet been parsed. |
911 for (const Scope* scope = this; scope != NULL; scope = scope->outer_scope_) { | 887 for (const Scope* scope = this; scope != NULL; scope = scope->outer_scope_) { |
912 if (scope->is_block_scope()) return false; | 888 if (scope->is_block_scope()) return false; |
913 } | 889 } |
914 return AllowsLazyCompilation(); | 890 return AllowsLazyCompilation(); |
915 } | 891 } |
916 | 892 |
917 | 893 |
918 bool Scope::AllowsLazyCompilation() const { return !force_eager_compilation_; } | 894 bool Scope::AllowsLazyCompilation() const { return !force_eager_compilation_; } |
919 | 895 |
920 | 896 |
921 bool Scope::AllowsLazyCompilationWithoutContext() const { | 897 bool Scope::AllowsLazyCompilationWithoutContext() const { |
922 return !force_eager_compilation_ && HasTrivialOuterContext(); | 898 if (force_eager_compilation_) return false; |
| 899 // Disallow lazy compilation without context if any outer scope needs a |
| 900 // context. |
| 901 for (const Scope* scope = outer_scope_; scope != nullptr; |
| 902 scope = scope->outer_scope_) { |
| 903 if (scope->NeedsContext()) return false; |
| 904 } |
| 905 return true; |
923 } | 906 } |
924 | 907 |
925 | 908 |
926 int Scope::ContextChainLength(Scope* scope) { | 909 int Scope::ContextChainLength(Scope* scope) { |
927 int n = 0; | 910 int n = 0; |
928 for (Scope* s = this; s != scope; s = s->outer_scope_) { | 911 for (Scope* s = this; s != scope; s = s->outer_scope_) { |
929 DCHECK(s != NULL); // scope must be in the scope chain | 912 DCHECK(s != NULL); // scope must be in the scope chain |
930 if (s->NeedsContext()) n++; | 913 if (s->NeedsContext()) n++; |
931 } | 914 } |
932 return n; | 915 return n; |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1156 PrintF(" { // (%d, %d)\n", start_position(), end_position()); | 1139 PrintF(" { // (%d, %d)\n", start_position(), end_position()); |
1157 | 1140 |
1158 // Function name, if any (named function literals, only). | 1141 // Function name, if any (named function literals, only). |
1159 if (function != nullptr) { | 1142 if (function != nullptr) { |
1160 Indent(n1, "// (local) function name: "); | 1143 Indent(n1, "// (local) function name: "); |
1161 PrintName(function->raw_name()); | 1144 PrintName(function->raw_name()); |
1162 PrintF("\n"); | 1145 PrintF("\n"); |
1163 } | 1146 } |
1164 | 1147 |
1165 // Scope info. | 1148 // Scope info. |
1166 if (HasTrivialOuterContext()) { | |
1167 Indent(n1, "// scope has trivial outer context\n"); | |
1168 } | |
1169 if (is_strict(language_mode())) { | 1149 if (is_strict(language_mode())) { |
1170 Indent(n1, "// strict mode scope\n"); | 1150 Indent(n1, "// strict mode scope\n"); |
1171 } | 1151 } |
1172 if (IsAsmModule()) Indent(n1, "// scope is an asm module\n"); | 1152 if (IsAsmModule()) Indent(n1, "// scope is an asm module\n"); |
1173 if (IsAsmFunction()) Indent(n1, "// scope is an asm function\n"); | 1153 if (IsAsmFunction()) Indent(n1, "// scope is an asm function\n"); |
1174 if (scope_calls_eval_) Indent(n1, "// scope calls 'eval'\n"); | 1154 if (scope_calls_eval_) Indent(n1, "// scope calls 'eval'\n"); |
1175 if (scope_uses_super_property_) | 1155 if (scope_uses_super_property_) |
1176 Indent(n1, "// scope uses 'super' property\n"); | 1156 Indent(n1, "// scope uses 'super' property\n"); |
1177 if (outer_scope_calls_sloppy_eval_) { | 1157 if (outer_scope_calls_sloppy_eval_) { |
1178 Indent(n1, "// outer scope calls 'eval' in sloppy context\n"); | 1158 Indent(n1, "// outer scope calls 'eval' in sloppy context\n"); |
(...skipping 607 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1786 function != nullptr && function->IsContextSlot(); | 1766 function != nullptr && function->IsContextSlot(); |
1787 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - | 1767 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - |
1788 (is_function_var_in_context ? 1 : 0); | 1768 (is_function_var_in_context ? 1 : 0); |
1789 } | 1769 } |
1790 | 1770 |
1791 | 1771 |
1792 int Scope::ContextGlobalCount() const { return num_global_slots(); } | 1772 int Scope::ContextGlobalCount() const { return num_global_slots(); } |
1793 | 1773 |
1794 } // namespace internal | 1774 } // namespace internal |
1795 } // namespace v8 | 1775 } // namespace v8 |
OLD | NEW |