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 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
128 decls_(0, zone), | 128 decls_(0, zone), |
129 scope_info_(scope_info), | 129 scope_info_(scope_info), |
130 scope_type_(scope_type) { | 130 scope_type_(scope_type) { |
131 SetDefaults(); | 131 SetDefaults(); |
132 #ifdef DEBUG | 132 #ifdef DEBUG |
133 already_resolved_ = true; | 133 already_resolved_ = true; |
134 #endif | 134 #endif |
135 if (scope_type == WITH_SCOPE) { | 135 if (scope_type == WITH_SCOPE) { |
136 DCHECK(scope_info.is_null()); | 136 DCHECK(scope_info.is_null()); |
137 } else { | 137 } else { |
138 scope_calls_eval_ = scope_info->CallsEval(); | 138 if (scope_info->CallsEval()) RecordEvalCall(); |
139 set_language_mode(scope_info->language_mode()); | 139 set_language_mode(scope_info->language_mode()); |
140 num_heap_slots_ = scope_info->ContextLength(); | 140 num_heap_slots_ = scope_info->ContextLength(); |
141 } | 141 } |
142 DCHECK_LE(Context::MIN_CONTEXT_SLOTS, num_heap_slots_); | 142 DCHECK_LE(Context::MIN_CONTEXT_SLOTS, num_heap_slots_); |
143 | 143 |
144 if (inner_scope != nullptr) AddInnerScope(inner_scope); | 144 if (inner_scope != nullptr) AddInnerScope(inner_scope); |
145 } | 145 } |
146 | 146 |
147 DeclarationScope::DeclarationScope(Zone* zone, Scope* inner_scope, | 147 DeclarationScope::DeclarationScope(Zone* zone, Scope* inner_scope, |
148 ScopeType scope_type, | 148 ScopeType scope_type, |
(...skipping 22 matching lines...) Expand all Loading... |
171 variables_.Declare(zone, this, catch_variable_name, VAR, Variable::NORMAL, | 171 variables_.Declare(zone, this, catch_variable_name, VAR, Variable::NORMAL, |
172 kCreatedInitialized); | 172 kCreatedInitialized); |
173 AllocateHeapSlot(variable); | 173 AllocateHeapSlot(variable); |
174 } | 174 } |
175 | 175 |
176 void DeclarationScope::SetDefaults() { | 176 void DeclarationScope::SetDefaults() { |
177 is_declaration_scope_ = true; | 177 is_declaration_scope_ = true; |
178 has_simple_parameters_ = true; | 178 has_simple_parameters_ = true; |
179 asm_module_ = false; | 179 asm_module_ = false; |
180 asm_function_ = false; | 180 asm_function_ = false; |
| 181 force_eager_compilation_ = false; |
181 has_arguments_parameter_ = false; | 182 has_arguments_parameter_ = false; |
182 receiver_ = nullptr; | 183 receiver_ = nullptr; |
183 new_target_ = nullptr; | 184 new_target_ = nullptr; |
184 function_ = nullptr; | 185 function_ = nullptr; |
185 arguments_ = nullptr; | 186 arguments_ = nullptr; |
186 this_function_ = nullptr; | 187 this_function_ = nullptr; |
187 arity_ = 0; | 188 arity_ = 0; |
188 rest_parameter_ = nullptr; | 189 rest_parameter_ = nullptr; |
189 rest_index_ = -1; | 190 rest_index_ = -1; |
190 } | 191 } |
(...skipping 17 matching lines...) Expand all Loading... |
208 | 209 |
209 set_language_mode(SLOPPY); | 210 set_language_mode(SLOPPY); |
210 | 211 |
211 scope_calls_eval_ = false; | 212 scope_calls_eval_ = false; |
212 scope_uses_super_property_ = false; | 213 scope_uses_super_property_ = false; |
213 scope_nonlinear_ = false; | 214 scope_nonlinear_ = false; |
214 is_hidden_ = false; | 215 is_hidden_ = false; |
215 is_debug_evaluate_scope_ = false; | 216 is_debug_evaluate_scope_ = false; |
216 | 217 |
217 inner_scope_calls_eval_ = false; | 218 inner_scope_calls_eval_ = false; |
218 force_eager_compilation_ = false; | |
219 force_context_allocation_ = false; | 219 force_context_allocation_ = false; |
220 | 220 |
221 is_declaration_scope_ = false; | 221 is_declaration_scope_ = false; |
222 } | 222 } |
223 | 223 |
224 bool Scope::HasSimpleParameters() { | 224 bool Scope::HasSimpleParameters() { |
225 DeclarationScope* scope = GetClosureScope(); | 225 DeclarationScope* scope = GetClosureScope(); |
226 return !scope->is_function_scope() || scope->has_simple_parameters(); | 226 return !scope->is_function_scope() || scope->has_simple_parameters(); |
227 } | 227 } |
228 | 228 |
(...skipping 641 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
870 | 870 |
871 // 3) Allocate variables. | 871 // 3) Allocate variables. |
872 AllocateVariablesRecursively(); | 872 AllocateVariablesRecursively(); |
873 } | 873 } |
874 | 874 |
875 | 875 |
876 bool Scope::AllowsLazyParsing() const { | 876 bool Scope::AllowsLazyParsing() const { |
877 // If we are inside a block scope, we must parse eagerly to find out how | 877 // If we are inside a block scope, we must parse eagerly to find out how |
878 // to allocate variables on the block scope. At this point, declarations may | 878 // to allocate variables on the block scope. At this point, declarations may |
879 // not have yet been parsed. | 879 // not have yet been parsed. |
880 for (const Scope* scope = this; scope != NULL; scope = scope->outer_scope_) { | 880 for (const Scope* s = this; s != nullptr; s = s->outer_scope_) { |
881 if (scope->is_block_scope()) return false; | 881 if (s->is_block_scope()) return false; |
882 } | 882 } |
883 return AllowsLazyCompilation(); | 883 return true; |
884 } | 884 } |
885 | 885 |
| 886 bool DeclarationScope::AllowsLazyCompilation() const { |
| 887 return !force_eager_compilation_; |
| 888 } |
886 | 889 |
887 bool Scope::AllowsLazyCompilation() const { return !force_eager_compilation_; } | 890 bool DeclarationScope::AllowsLazyCompilationWithoutContext() const { |
888 | |
889 | |
890 bool Scope::AllowsLazyCompilationWithoutContext() const { | |
891 if (force_eager_compilation_) return false; | 891 if (force_eager_compilation_) return false; |
892 // Disallow lazy compilation without context if any outer scope needs a | 892 // Disallow lazy compilation without context if any outer scope needs a |
893 // context. | 893 // context. |
894 for (const Scope* scope = outer_scope_; scope != nullptr; | 894 for (const Scope* scope = outer_scope_; scope != nullptr; |
895 scope = scope->outer_scope_) { | 895 scope = scope->outer_scope_) { |
896 if (scope->NeedsContext()) return false; | 896 if (scope->NeedsContext()) return false; |
897 } | 897 } |
898 return true; | 898 return true; |
899 } | 899 } |
900 | 900 |
(...skipping 560 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1461 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { | 1461 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { |
1462 stack = scope->FetchFreeVariables(max_outer_scope, info, stack); | 1462 stack = scope->FetchFreeVariables(max_outer_scope, info, stack); |
1463 } | 1463 } |
1464 | 1464 |
1465 return stack; | 1465 return stack; |
1466 } | 1466 } |
1467 | 1467 |
1468 void Scope::PropagateScopeInfo() { | 1468 void Scope::PropagateScopeInfo() { |
1469 for (Scope* inner = inner_scope_; inner != nullptr; inner = inner->sibling_) { | 1469 for (Scope* inner = inner_scope_; inner != nullptr; inner = inner->sibling_) { |
1470 inner->PropagateScopeInfo(); | 1470 inner->PropagateScopeInfo(); |
1471 if (inner->scope_calls_eval_ || inner->inner_scope_calls_eval_) { | |
1472 inner_scope_calls_eval_ = true; | |
1473 } | |
1474 if (inner->force_eager_compilation_) { | |
1475 force_eager_compilation_ = true; | |
1476 } | |
1477 if (IsAsmModule() && inner->is_function_scope()) { | 1471 if (IsAsmModule() && inner->is_function_scope()) { |
1478 inner->AsDeclarationScope()->set_asm_function(); | 1472 inner->AsDeclarationScope()->set_asm_function(); |
1479 } | 1473 } |
1480 } | 1474 } |
1481 } | 1475 } |
1482 | 1476 |
1483 | 1477 |
1484 bool Scope::MustAllocate(Variable* var) { | 1478 bool Scope::MustAllocate(Variable* var) { |
1485 DCHECK(var->location() != VariableLocation::MODULE); | 1479 DCHECK(var->location() != VariableLocation::MODULE); |
1486 // Give var a read/write use if there is a chance it might be accessed | 1480 // Give var a read/write use if there is a chance it might be accessed |
1487 // via an eval() call. This is only possible if the variable has a | 1481 // via an eval() call. This is only possible if the variable has a |
1488 // visible name. | 1482 // visible name. |
1489 if ((var->is_this() || !var->raw_name()->IsEmpty()) && | 1483 if ((var->is_this() || !var->raw_name()->IsEmpty()) && |
1490 (scope_calls_eval_ || inner_scope_calls_eval_ || is_catch_scope() || | 1484 (inner_scope_calls_eval_ || is_catch_scope() || is_script_scope())) { |
1491 is_script_scope())) { | |
1492 var->set_is_used(); | 1485 var->set_is_used(); |
1493 if (scope_calls_eval_ || inner_scope_calls_eval_) var->set_maybe_assigned(); | 1486 if (inner_scope_calls_eval_) var->set_maybe_assigned(); |
1494 } | 1487 } |
1495 DCHECK(!var->has_forced_context_allocation() || var->is_used()); | 1488 DCHECK(!var->has_forced_context_allocation() || var->is_used()); |
1496 // Global variables do not need to be allocated. | 1489 // Global variables do not need to be allocated. |
1497 return !var->IsGlobalObjectProperty() && var->is_used(); | 1490 return !var->IsGlobalObjectProperty() && var->is_used(); |
1498 } | 1491 } |
1499 | 1492 |
1500 | 1493 |
1501 bool Scope::MustAllocateInContext(Variable* var) { | 1494 bool Scope::MustAllocateInContext(Variable* var) { |
1502 // If var is accessed from an inner scope, or if there is a possibility | 1495 // If var is accessed from an inner scope, or if there is a possibility |
1503 // that it might be accessed from the current or an inner scope (through | 1496 // that it might be accessed from the current or an inner scope (through |
1504 // an eval() call or a runtime with lookup), it must be allocated in the | 1497 // an eval() call or a runtime with lookup), it must be allocated in the |
1505 // context. | 1498 // context. |
1506 // | 1499 // |
1507 // Exceptions: If the scope as a whole has forced context allocation, all | 1500 // Exceptions: If the scope as a whole has forced context allocation, all |
1508 // variables will have context allocation, even temporaries. Otherwise | 1501 // variables will have context allocation, even temporaries. Otherwise |
1509 // temporary variables are always stack-allocated. Catch-bound variables are | 1502 // temporary variables are always stack-allocated. Catch-bound variables are |
1510 // always context-allocated. | 1503 // always context-allocated. |
1511 if (has_forced_context_allocation()) return true; | 1504 if (has_forced_context_allocation()) return true; |
1512 if (var->mode() == TEMPORARY) return false; | 1505 if (var->mode() == TEMPORARY) return false; |
1513 if (is_catch_scope()) return true; | 1506 if (is_catch_scope()) return true; |
1514 if (is_script_scope() && IsLexicalVariableMode(var->mode())) return true; | 1507 if (is_script_scope() && IsLexicalVariableMode(var->mode())) return true; |
1515 return var->has_forced_context_allocation() || scope_calls_eval_ || | 1508 return var->has_forced_context_allocation() || inner_scope_calls_eval_; |
1516 inner_scope_calls_eval_; | |
1517 } | 1509 } |
1518 | 1510 |
1519 | 1511 |
1520 void Scope::AllocateStackSlot(Variable* var) { | 1512 void Scope::AllocateStackSlot(Variable* var) { |
1521 if (is_block_scope()) { | 1513 if (is_block_scope()) { |
1522 outer_scope()->GetDeclarationScope()->AllocateStackSlot(var); | 1514 outer_scope()->GetDeclarationScope()->AllocateStackSlot(var); |
1523 } else { | 1515 } else { |
1524 var->AllocateTo(VariableLocation::LOCAL, num_stack_slots_++); | 1516 var->AllocateTo(VariableLocation::LOCAL, num_stack_slots_++); |
1525 } | 1517 } |
1526 } | 1518 } |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1761 function != nullptr && function->IsContextSlot(); | 1753 function != nullptr && function->IsContextSlot(); |
1762 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - | 1754 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - |
1763 (is_function_var_in_context ? 1 : 0); | 1755 (is_function_var_in_context ? 1 : 0); |
1764 } | 1756 } |
1765 | 1757 |
1766 | 1758 |
1767 int Scope::ContextGlobalCount() const { return num_global_slots(); } | 1759 int Scope::ContextGlobalCount() const { return num_global_slots(); } |
1768 | 1760 |
1769 } // namespace internal | 1761 } // namespace internal |
1770 } // namespace v8 | 1762 } // namespace v8 |
OLD | NEW |