Chromium Code Reviews| 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 |