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 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->hash(), | 70 ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->hash(), |
71 ZoneAllocationPolicy(zone)); | 71 ZoneAllocationPolicy(zone)); |
72 stmt->set_next(static_cast<SloppyBlockFunctionStatement*>(p->value)); | 72 stmt->set_next(static_cast<SloppyBlockFunctionStatement*>(p->value)); |
73 p->value = stmt; | 73 p->value = stmt; |
74 } | 74 } |
75 | 75 |
76 | 76 |
77 // ---------------------------------------------------------------------------- | 77 // ---------------------------------------------------------------------------- |
78 // Implementation of Scope | 78 // Implementation of Scope |
79 | 79 |
80 Scope::Scope(Zone* zone) | 80 Scope::Scope(Zone* zone, ScopeType scope_type) |
81 : zone_(zone), | 81 : zone_(zone), |
82 outer_scope_(nullptr), | 82 outer_scope_(nullptr), |
83 variables_(zone), | 83 variables_(zone), |
84 ordered_variables_(4, zone), | 84 ordered_variables_(4, zone), |
85 decls_(4, zone), | 85 decls_(4, zone), |
86 scope_type_(SCRIPT_SCOPE) { | 86 scope_type_(scope_type) { |
| 87 DCHECK(scope_type == SCRIPT_SCOPE || scope_type == WITH_SCOPE); |
87 SetDefaults(); | 88 SetDefaults(); |
| 89 #ifdef DEBUG |
| 90 if (scope_type == WITH_SCOPE) { |
| 91 already_resolved_ = true; |
| 92 } |
| 93 #endif |
88 } | 94 } |
89 | 95 |
90 Scope::Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type) | 96 Scope::Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type) |
91 : zone_(zone), | 97 : zone_(zone), |
92 outer_scope_(outer_scope), | 98 outer_scope_(outer_scope), |
93 variables_(zone), | 99 variables_(zone), |
94 ordered_variables_(4, zone), | 100 ordered_variables_(4, zone), |
95 decls_(4, zone), | 101 decls_(4, zone), |
96 scope_type_(scope_type) { | 102 scope_type_(scope_type) { |
97 DCHECK_NE(SCRIPT_SCOPE, scope_type); | 103 DCHECK_NE(SCRIPT_SCOPE, scope_type); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
130 } | 136 } |
131 | 137 |
132 ModuleScope::ModuleScope(Zone* zone, DeclarationScope* script_scope, | 138 ModuleScope::ModuleScope(Zone* zone, DeclarationScope* script_scope, |
133 AstValueFactory* ast_value_factory) | 139 AstValueFactory* ast_value_factory) |
134 : DeclarationScope(zone, script_scope, MODULE_SCOPE) { | 140 : DeclarationScope(zone, script_scope, MODULE_SCOPE) { |
135 module_descriptor_ = new (zone) ModuleDescriptor(zone); | 141 module_descriptor_ = new (zone) ModuleDescriptor(zone); |
136 set_language_mode(STRICT); | 142 set_language_mode(STRICT); |
137 DeclareThis(ast_value_factory); | 143 DeclareThis(ast_value_factory); |
138 } | 144 } |
139 | 145 |
140 Scope::Scope(Zone* zone, Scope* inner_scope, ScopeType scope_type, | 146 Scope::Scope(Zone* zone, ScopeType scope_type, Handle<ScopeInfo> scope_info) |
141 Handle<ScopeInfo> scope_info) | |
142 : zone_(zone), | 147 : zone_(zone), |
143 outer_scope_(nullptr), | 148 outer_scope_(nullptr), |
144 variables_(zone), | 149 variables_(zone), |
145 ordered_variables_(0, zone), | 150 ordered_variables_(0, zone), |
146 decls_(0, zone), | 151 decls_(0, zone), |
147 scope_info_(scope_info), | 152 scope_info_(scope_info), |
148 scope_type_(scope_type) { | 153 scope_type_(scope_type) { |
| 154 DCHECK(!scope_info.is_null()); |
149 SetDefaults(); | 155 SetDefaults(); |
150 #ifdef DEBUG | 156 #ifdef DEBUG |
151 already_resolved_ = true; | 157 already_resolved_ = true; |
152 #endif | 158 #endif |
153 if (scope_type == WITH_SCOPE) { | 159 if (scope_info->CallsEval()) RecordEvalCall(); |
154 DCHECK(scope_info.is_null()); | 160 set_language_mode(scope_info->language_mode()); |
155 } else { | 161 num_heap_slots_ = scope_info->ContextLength(); |
156 if (scope_info->CallsEval()) RecordEvalCall(); | |
157 set_language_mode(scope_info->language_mode()); | |
158 num_heap_slots_ = scope_info->ContextLength(); | |
159 } | |
160 DCHECK_LE(Context::MIN_CONTEXT_SLOTS, num_heap_slots_); | 162 DCHECK_LE(Context::MIN_CONTEXT_SLOTS, num_heap_slots_); |
161 | |
162 if (inner_scope != nullptr) AddInnerScope(inner_scope); | |
163 } | 163 } |
164 | 164 |
165 DeclarationScope::DeclarationScope(Zone* zone, Scope* inner_scope, | 165 DeclarationScope::DeclarationScope(Zone* zone, ScopeType scope_type, |
166 ScopeType scope_type, | |
167 Handle<ScopeInfo> scope_info) | 166 Handle<ScopeInfo> scope_info) |
168 : Scope(zone, inner_scope, scope_type, scope_info), | 167 : Scope(zone, scope_type, scope_info), |
169 function_kind_(scope_info->function_kind()), | 168 function_kind_(scope_info->function_kind()), |
170 temps_(0, zone), | 169 temps_(0, zone), |
171 params_(0, zone), | 170 params_(0, zone), |
172 sloppy_block_function_map_(zone) { | 171 sloppy_block_function_map_(zone) { |
173 SetDefaults(); | 172 SetDefaults(); |
174 } | 173 } |
175 | 174 |
176 Scope::Scope(Zone* zone, Scope* inner_scope, | 175 Scope::Scope(Zone* zone, const AstRawString* catch_variable_name) |
177 const AstRawString* catch_variable_name) | |
178 : zone_(zone), | 176 : zone_(zone), |
179 outer_scope_(nullptr), | 177 outer_scope_(nullptr), |
180 variables_(zone), | 178 variables_(zone), |
181 ordered_variables_(0, zone), | 179 ordered_variables_(0, zone), |
182 decls_(0, zone), | 180 decls_(0, zone), |
183 scope_type_(CATCH_SCOPE) { | 181 scope_type_(CATCH_SCOPE) { |
184 SetDefaults(); | 182 SetDefaults(); |
185 #ifdef DEBUG | 183 #ifdef DEBUG |
186 already_resolved_ = true; | 184 already_resolved_ = true; |
187 #endif | 185 #endif |
188 if (inner_scope != nullptr) AddInnerScope(inner_scope); | |
189 Variable* variable = | 186 Variable* variable = |
190 variables_.Declare(zone, this, catch_variable_name, VAR, Variable::NORMAL, | 187 variables_.Declare(zone, this, catch_variable_name, VAR, Variable::NORMAL, |
191 kCreatedInitialized); | 188 kCreatedInitialized); |
192 AllocateHeapSlot(variable); | 189 AllocateHeapSlot(variable); |
193 } | 190 } |
194 | 191 |
195 void DeclarationScope::SetDefaults() { | 192 void DeclarationScope::SetDefaults() { |
196 is_declaration_scope_ = true; | 193 is_declaration_scope_ = true; |
197 has_simple_parameters_ = true; | 194 has_simple_parameters_ = true; |
198 asm_module_ = false; | 195 asm_module_ = false; |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
253 } | 250 } |
254 | 251 |
255 Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone, | 252 Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone, |
256 Context* context, | 253 Context* context, |
257 DeclarationScope* script_scope, | 254 DeclarationScope* script_scope, |
258 AstValueFactory* ast_value_factory, | 255 AstValueFactory* ast_value_factory, |
259 DeserializationMode deserialization_mode) { | 256 DeserializationMode deserialization_mode) { |
260 // Reconstruct the outer scope chain from a closure's context chain. | 257 // Reconstruct the outer scope chain from a closure's context chain. |
261 Scope* current_scope = nullptr; | 258 Scope* current_scope = nullptr; |
262 Scope* innermost_scope = nullptr; | 259 Scope* innermost_scope = nullptr; |
| 260 Scope* outer_scope = nullptr; |
263 while (!context->IsNativeContext()) { | 261 while (!context->IsNativeContext()) { |
264 if (context->IsWithContext() || context->IsDebugEvaluateContext()) { | 262 if (context->IsWithContext() || context->IsDebugEvaluateContext()) { |
265 // For scope analysis, debug-evaluate is equivalent to a with scope. | 263 // For scope analysis, debug-evaluate is equivalent to a with scope. |
266 Scope* with_scope = new (zone) | 264 outer_scope = new (zone) Scope(zone, WITH_SCOPE); |
267 Scope(zone, current_scope, WITH_SCOPE, Handle<ScopeInfo>()); | 265 |
268 // TODO(yangguo): Remove once debug-evaluate properly keeps track of the | 266 // TODO(yangguo): Remove once debug-evaluate properly keeps track of the |
269 // function scope in which we are evaluating. | 267 // function scope in which we are evaluating. |
270 if (context->IsDebugEvaluateContext()) { | 268 if (context->IsDebugEvaluateContext()) { |
271 with_scope->set_is_debug_evaluate_scope(); | 269 outer_scope->set_is_debug_evaluate_scope(); |
272 } | 270 } |
273 current_scope = with_scope; | |
274 } else if (context->IsScriptContext()) { | 271 } else if (context->IsScriptContext()) { |
275 // If we reach a script context, it's the outermost context with scope | 272 // If we reach a script context, it's the outermost context with scope |
276 // info. The next context will be the native context. Install the scope | 273 // info. The next context will be the native context. Install the scope |
277 // info of this script context onto the existing script scope to avoid | 274 // info of this script context onto the existing script scope to avoid |
278 // nesting script scopes. | 275 // nesting script scopes. |
279 Handle<ScopeInfo> scope_info(context->scope_info(), isolate); | 276 Handle<ScopeInfo> scope_info(context->scope_info(), isolate); |
280 script_scope->SetScriptScopeInfo(scope_info); | 277 script_scope->SetScriptScopeInfo(scope_info); |
281 DCHECK(context->previous()->IsNativeContext()); | 278 DCHECK(context->previous()->IsNativeContext()); |
282 break; | 279 break; |
283 } else if (context->IsFunctionContext()) { | 280 } else if (context->IsFunctionContext()) { |
284 Handle<ScopeInfo> scope_info(context->closure()->shared()->scope_info(), | 281 Handle<ScopeInfo> scope_info(context->closure()->shared()->scope_info(), |
285 isolate); | 282 isolate); |
286 // TODO(neis): For an eval scope, we currently create an ordinary function | 283 // TODO(neis): For an eval scope, we currently create an ordinary function |
287 // context. This is wrong and needs to be fixed. | 284 // context. This is wrong and needs to be fixed. |
288 // https://bugs.chromium.org/p/v8/issues/detail?id=5295 | 285 // https://bugs.chromium.org/p/v8/issues/detail?id=5295 |
289 DCHECK(scope_info->scope_type() == FUNCTION_SCOPE || | 286 DCHECK(scope_info->scope_type() == FUNCTION_SCOPE || |
290 scope_info->scope_type() == EVAL_SCOPE); | 287 scope_info->scope_type() == EVAL_SCOPE); |
291 DeclarationScope* function_scope = new (zone) | 288 outer_scope = |
292 DeclarationScope(zone, current_scope, FUNCTION_SCOPE, scope_info); | 289 new (zone) DeclarationScope(zone, FUNCTION_SCOPE, scope_info); |
293 if (scope_info->IsAsmFunction()) function_scope->set_asm_function(); | 290 if (scope_info->IsAsmFunction()) |
294 if (scope_info->IsAsmModule()) function_scope->set_asm_module(); | 291 outer_scope->AsDeclarationScope()->set_asm_function(); |
295 current_scope = function_scope; | 292 if (scope_info->IsAsmModule()) |
| 293 outer_scope->AsDeclarationScope()->set_asm_module(); |
296 } else if (context->IsBlockContext()) { | 294 } else if (context->IsBlockContext()) { |
297 Handle<ScopeInfo> scope_info(context->scope_info(), isolate); | 295 Handle<ScopeInfo> scope_info(context->scope_info(), isolate); |
298 DCHECK_EQ(scope_info->scope_type(), BLOCK_SCOPE); | 296 DCHECK_EQ(scope_info->scope_type(), BLOCK_SCOPE); |
299 if (scope_info->is_declaration_scope()) { | 297 if (scope_info->is_declaration_scope()) { |
300 current_scope = new (zone) | 298 outer_scope = |
301 DeclarationScope(zone, current_scope, BLOCK_SCOPE, scope_info); | 299 new (zone) DeclarationScope(zone, BLOCK_SCOPE, scope_info); |
302 } else { | 300 } else { |
303 current_scope = | 301 outer_scope = new (zone) Scope(zone, BLOCK_SCOPE, scope_info); |
304 new (zone) Scope(zone, current_scope, BLOCK_SCOPE, scope_info); | |
305 } | 302 } |
306 } else { | 303 } else { |
307 DCHECK(context->IsCatchContext()); | 304 DCHECK(context->IsCatchContext()); |
308 String* name = context->catch_name(); | 305 String* name = context->catch_name(); |
309 current_scope = | 306 outer_scope = new (zone) |
310 new (zone) Scope(zone, current_scope, | 307 Scope(zone, ast_value_factory->GetString(handle(name, isolate))); |
311 ast_value_factory->GetString(handle(name, isolate))); | |
312 } | 308 } |
| 309 if (current_scope != nullptr) { |
| 310 outer_scope->AddInnerScope(current_scope); |
| 311 } |
| 312 current_scope = outer_scope; |
313 if (deserialization_mode == DeserializationMode::kDeserializeOffHeap) { | 313 if (deserialization_mode == DeserializationMode::kDeserializeOffHeap) { |
314 current_scope->DeserializeScopeInfo(isolate, ast_value_factory); | 314 current_scope->DeserializeScopeInfo(isolate, ast_value_factory); |
315 } | 315 } |
316 if (innermost_scope == nullptr) innermost_scope = current_scope; | 316 if (innermost_scope == nullptr) innermost_scope = current_scope; |
317 context = context->previous(); | 317 context = context->previous(); |
318 } | 318 } |
319 | 319 |
320 if (innermost_scope == nullptr) return script_scope; | 320 if (innermost_scope == nullptr) return script_scope; |
321 script_scope->AddInnerScope(current_scope); | 321 script_scope->AddInnerScope(current_scope); |
322 script_scope->PropagateScopeInfo(); | 322 script_scope->PropagateScopeInfo(); |
(...skipping 1358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1681 function != nullptr && function->IsContextSlot(); | 1681 function != nullptr && function->IsContextSlot(); |
1682 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - | 1682 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - |
1683 (is_function_var_in_context ? 1 : 0); | 1683 (is_function_var_in_context ? 1 : 0); |
1684 } | 1684 } |
1685 | 1685 |
1686 | 1686 |
1687 int Scope::ContextGlobalCount() const { return num_global_slots(); } | 1687 int Scope::ContextGlobalCount() const { return num_global_slots(); } |
1688 | 1688 |
1689 } // namespace internal | 1689 } // namespace internal |
1690 } // namespace v8 | 1690 } // namespace v8 |
OLD | NEW |