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 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
84 SetDefaults(); | 84 SetDefaults(); |
85 if (outer_scope == nullptr) { | 85 if (outer_scope == nullptr) { |
86 // If the outer scope is null, this cannot be a with scope. The outermost | 86 // If the outer scope is null, this cannot be a with scope. The outermost |
87 // scope must be a script scope. | 87 // scope must be a script scope. |
88 DCHECK_EQ(SCRIPT_SCOPE, scope_type); | 88 DCHECK_EQ(SCRIPT_SCOPE, scope_type); |
89 } else { | 89 } else { |
90 set_language_mode(outer_scope->language_mode()); | 90 set_language_mode(outer_scope->language_mode()); |
91 force_context_allocation_ = | 91 force_context_allocation_ = |
92 !is_function_scope() && outer_scope->has_forced_context_allocation(); | 92 !is_function_scope() && outer_scope->has_forced_context_allocation(); |
93 outer_scope_->AddInnerScope(this); | 93 outer_scope_->AddInnerScope(this); |
94 scope_inside_with_ = outer_scope_->scope_inside_with_ || is_with_scope(); | |
95 } | 94 } |
96 } | 95 } |
97 | 96 |
98 Scope::Snapshot::Snapshot(Scope* scope) | 97 Scope::Snapshot::Snapshot(Scope* scope) |
99 : outer_scope_(scope), | 98 : outer_scope_(scope), |
100 top_inner_scope_(scope->inner_scope_), | 99 top_inner_scope_(scope->inner_scope_), |
101 top_unresolved_(scope->unresolved_), | 100 top_unresolved_(scope->unresolved_), |
102 top_temp_(scope->GetClosureScope()->temps()->length()) {} | 101 top_temp_(scope->GetClosureScope()->temps()->length()) {} |
103 | 102 |
104 DeclarationScope::DeclarationScope(Zone* zone, Scope* outer_scope, | 103 DeclarationScope::DeclarationScope(Zone* zone, Scope* outer_scope, |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
201 | 200 |
202 start_position_ = kNoSourcePosition; | 201 start_position_ = kNoSourcePosition; |
203 end_position_ = kNoSourcePosition; | 202 end_position_ = kNoSourcePosition; |
204 | 203 |
205 num_stack_slots_ = 0; | 204 num_stack_slots_ = 0; |
206 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; | 205 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; |
207 num_global_slots_ = 0; | 206 num_global_slots_ = 0; |
208 | 207 |
209 set_language_mode(SLOPPY); | 208 set_language_mode(SLOPPY); |
210 | 209 |
211 scope_inside_with_ = false; | |
212 scope_calls_eval_ = false; | 210 scope_calls_eval_ = false; |
213 scope_uses_super_property_ = false; | 211 scope_uses_super_property_ = false; |
214 has_arguments_parameter_ = false; | 212 has_arguments_parameter_ = false; |
215 scope_nonlinear_ = false; | 213 scope_nonlinear_ = false; |
216 is_hidden_ = false; | 214 is_hidden_ = false; |
217 is_debug_evaluate_scope_ = false; | 215 is_debug_evaluate_scope_ = false; |
218 | 216 |
219 outer_scope_calls_sloppy_eval_ = false; | 217 outer_scope_calls_sloppy_eval_ = false; |
220 inner_scope_calls_eval_ = false; | 218 inner_scope_calls_eval_ = false; |
221 force_eager_compilation_ = false; | 219 force_eager_compilation_ = false; |
(...skipping 27 matching lines...) Expand all Loading... | |
249 if (context->IsWithContext() || context->IsDebugEvaluateContext()) { | 247 if (context->IsWithContext() || context->IsDebugEvaluateContext()) { |
250 // For scope analysis, debug-evaluate is equivalent to a with scope. | 248 // For scope analysis, debug-evaluate is equivalent to a with scope. |
251 Scope* with_scope = new (zone) | 249 Scope* with_scope = new (zone) |
252 Scope(zone, current_scope, WITH_SCOPE, Handle<ScopeInfo>()); | 250 Scope(zone, current_scope, WITH_SCOPE, Handle<ScopeInfo>()); |
253 // TODO(yangguo): Remove once debug-evaluate properly keeps track of the | 251 // TODO(yangguo): Remove once debug-evaluate properly keeps track of the |
254 // function scope in which we are evaluating. | 252 // function scope in which we are evaluating. |
255 if (context->IsDebugEvaluateContext()) { | 253 if (context->IsDebugEvaluateContext()) { |
256 with_scope->set_is_debug_evaluate_scope(); | 254 with_scope->set_is_debug_evaluate_scope(); |
257 } | 255 } |
258 current_scope = with_scope; | 256 current_scope = with_scope; |
259 // All the inner scopes are inside a with. | |
260 for (Scope* s = innermost_scope; s != nullptr; s = s->outer_scope()) { | |
261 s->scope_inside_with_ = true; | |
262 } | |
263 } else if (context->IsScriptContext()) { | 257 } else if (context->IsScriptContext()) { |
264 Handle<ScopeInfo> scope_info(context->scope_info(), isolate); | 258 Handle<ScopeInfo> scope_info(context->scope_info(), isolate); |
265 current_scope = new (zone) | 259 current_scope = new (zone) |
266 DeclarationScope(zone, current_scope, SCRIPT_SCOPE, scope_info); | 260 DeclarationScope(zone, current_scope, SCRIPT_SCOPE, scope_info); |
267 } else if (context->IsFunctionContext()) { | 261 } else if (context->IsFunctionContext()) { |
268 Handle<ScopeInfo> scope_info(context->closure()->shared()->scope_info(), | 262 Handle<ScopeInfo> scope_info(context->closure()->shared()->scope_info(), |
269 isolate); | 263 isolate); |
270 DeclarationScope* function_scope = new (zone) | 264 DeclarationScope* function_scope = new (zone) |
271 DeclarationScope(zone, current_scope, FUNCTION_SCOPE, scope_info); | 265 DeclarationScope(zone, current_scope, FUNCTION_SCOPE, scope_info); |
272 if (scope_info->IsAsmFunction()) function_scope->set_asm_function(); | 266 if (scope_info->IsAsmFunction()) function_scope->set_asm_function(); |
(...skipping 606 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
879 } | 873 } |
880 | 874 |
881 | 875 |
882 bool Scope::HasTrivialContext() const { | 876 bool Scope::HasTrivialContext() const { |
883 // A function scope has a trivial context if it always is the global | 877 // A function scope has a trivial context if it always is the global |
884 // context. We iteratively scan out the context chain to see if | 878 // context. We iteratively scan out the context chain to see if |
885 // there is anything that makes this scope non-trivial; otherwise we | 879 // there is anything that makes this scope non-trivial; otherwise we |
886 // return true. | 880 // return true. |
887 for (const Scope* scope = this; scope != NULL; scope = scope->outer_scope_) { | 881 for (const Scope* scope = this; scope != NULL; scope = scope->outer_scope_) { |
888 if (scope->is_eval_scope()) return false; | 882 if (scope->is_eval_scope()) return false; |
889 if (scope->scope_inside_with_) return false; | 883 if (scope->InsideWithScope()) return false; |
890 if (scope->ContextLocalCount() > 0) return false; | 884 if (scope->ContextLocalCount() > 0) return false; |
891 if (scope->ContextGlobalCount() > 0) return false; | 885 if (scope->ContextGlobalCount() > 0) return false; |
892 } | 886 } |
893 return true; | 887 return true; |
894 } | 888 } |
895 | 889 |
896 | 890 |
897 bool Scope::HasTrivialOuterContext() const { | 891 bool Scope::HasTrivialOuterContext() const { |
898 Scope* outer = outer_scope_; | 892 if (outer_scope_ == nullptr) return true; |
899 if (outer == NULL) return true; | |
900 // Note that the outer context may be trivial in general, but the current | 893 // 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 | 894 // scope may be inside a 'with' statement in which case the outer context |
902 // for this scope is not trivial. | 895 // for this scope is not trivial. |
903 return !scope_inside_with_ && outer->HasTrivialContext(); | 896 return !is_with_scope() && outer_scope_->HasTrivialContext(); |
neis
2016/08/19 14:33:41
Now the code doesn't quite match the comment anymo
Toon Verwaest
2016/08/19 18:00:35
I'll do so in a follow-up
| |
904 } | 897 } |
905 | 898 |
906 | 899 |
907 bool Scope::AllowsLazyParsing() const { | 900 bool Scope::AllowsLazyParsing() const { |
908 // If we are inside a block scope, we must parse eagerly to find out how | 901 // 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 | 902 // to allocate variables on the block scope. At this point, declarations may |
910 // not have yet been parsed. | 903 // not have yet been parsed. |
911 for (const Scope* scope = this; scope != NULL; scope = scope->outer_scope_) { | 904 for (const Scope* scope = this; scope != NULL; scope = scope->outer_scope_) { |
912 if (scope->is_block_scope()) return false; | 905 if (scope->is_block_scope()) return false; |
913 } | 906 } |
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1164 | 1157 |
1165 // Scope info. | 1158 // Scope info. |
1166 if (HasTrivialOuterContext()) { | 1159 if (HasTrivialOuterContext()) { |
1167 Indent(n1, "// scope has trivial outer context\n"); | 1160 Indent(n1, "// scope has trivial outer context\n"); |
1168 } | 1161 } |
1169 if (is_strict(language_mode())) { | 1162 if (is_strict(language_mode())) { |
1170 Indent(n1, "// strict mode scope\n"); | 1163 Indent(n1, "// strict mode scope\n"); |
1171 } | 1164 } |
1172 if (IsAsmModule()) Indent(n1, "// scope is an asm module\n"); | 1165 if (IsAsmModule()) Indent(n1, "// scope is an asm module\n"); |
1173 if (IsAsmFunction()) Indent(n1, "// scope is an asm function\n"); | 1166 if (IsAsmFunction()) Indent(n1, "// scope is an asm function\n"); |
1174 if (scope_inside_with_) Indent(n1, "// scope inside 'with'\n"); | |
1175 if (scope_calls_eval_) Indent(n1, "// scope calls 'eval'\n"); | 1167 if (scope_calls_eval_) Indent(n1, "// scope calls 'eval'\n"); |
1176 if (scope_uses_super_property_) | 1168 if (scope_uses_super_property_) |
1177 Indent(n1, "// scope uses 'super' property\n"); | 1169 Indent(n1, "// scope uses 'super' property\n"); |
1178 if (outer_scope_calls_sloppy_eval_) { | 1170 if (outer_scope_calls_sloppy_eval_) { |
1179 Indent(n1, "// outer scope calls 'eval' in sloppy context\n"); | 1171 Indent(n1, "// outer scope calls 'eval' in sloppy context\n"); |
1180 } | 1172 } |
1181 if (inner_scope_calls_eval_) Indent(n1, "// inner scope calls 'eval'\n"); | 1173 if (inner_scope_calls_eval_) Indent(n1, "// inner scope calls 'eval'\n"); |
1182 if (num_stack_slots_ > 0) { | 1174 if (num_stack_slots_ > 0) { |
1183 Indent(n1, "// "); | 1175 Indent(n1, "// "); |
1184 PrintF("%d stack slots\n", num_stack_slots_); | 1176 PrintF("%d stack slots\n", num_stack_slots_); |
(...skipping 602 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1787 function != nullptr && function->IsContextSlot(); | 1779 function != nullptr && function->IsContextSlot(); |
1788 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - | 1780 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - |
1789 (is_function_var_in_context ? 1 : 0); | 1781 (is_function_var_in_context ? 1 : 0); |
1790 } | 1782 } |
1791 | 1783 |
1792 | 1784 |
1793 int Scope::ContextGlobalCount() const { return num_global_slots(); } | 1785 int Scope::ContextGlobalCount() const { return num_global_slots(); } |
1794 | 1786 |
1795 } // namespace internal | 1787 } // namespace internal |
1796 } // namespace v8 | 1788 } // namespace v8 |
OLD | NEW |