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 "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/ast/scopeinfo.h" | 8 #include "src/ast/scopeinfo.h" |
9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/messages.h" | 10 #include "src/messages.h" |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
76 } | 76 } |
77 Vector* delegates = static_cast<Vector*>(p->value); | 77 Vector* delegates = static_cast<Vector*>(p->value); |
78 delegates->push_back(stmt); | 78 delegates->push_back(stmt); |
79 } | 79 } |
80 | 80 |
81 | 81 |
82 // ---------------------------------------------------------------------------- | 82 // ---------------------------------------------------------------------------- |
83 // Implementation of Scope | 83 // Implementation of Scope |
84 | 84 |
85 Scope::Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type, | 85 Scope::Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type, |
86 AstValueFactory* ast_value_factory, FunctionKind function_kind) | 86 FunctionKind function_kind) |
87 : inner_scopes_(4, zone), | 87 : inner_scopes_(4, zone), |
88 variables_(zone), | 88 variables_(zone), |
89 temps_(4, zone), | 89 temps_(4, zone), |
90 params_(4, zone), | 90 params_(4, zone), |
91 unresolved_(nullptr), | 91 unresolved_(nullptr), |
92 decls_(4, zone), | 92 decls_(4, zone), |
93 module_descriptor_(scope_type == MODULE_SCOPE ? new (zone) | 93 module_descriptor_(scope_type == MODULE_SCOPE ? new (zone) |
94 ModuleDescriptor(zone) | 94 ModuleDescriptor(zone) |
95 : NULL), | 95 : NULL), |
96 sloppy_block_function_map_(zone), | 96 sloppy_block_function_map_(zone), |
97 already_resolved_(false), | 97 already_resolved_(false), |
98 ast_value_factory_(ast_value_factory), | |
99 zone_(zone) { | 98 zone_(zone) { |
100 SetDefaults(scope_type, outer_scope, Handle<ScopeInfo>::null(), | 99 SetDefaults(scope_type, outer_scope, Handle<ScopeInfo>::null(), |
101 function_kind); | 100 function_kind); |
102 // The outermost scope must be a script scope. | 101 // The outermost scope must be a script scope. |
103 DCHECK(scope_type == SCRIPT_SCOPE || outer_scope != NULL); | 102 DCHECK(scope_type == SCRIPT_SCOPE || outer_scope != NULL); |
104 } | 103 } |
105 | 104 |
106 Scope::Scope(Zone* zone, Scope* inner_scope, ScopeType scope_type, | 105 Scope::Scope(Zone* zone, Scope* inner_scope, ScopeType scope_type, |
107 Handle<ScopeInfo> scope_info, AstValueFactory* value_factory) | 106 Handle<ScopeInfo> scope_info) |
108 : inner_scopes_(4, zone), | 107 : inner_scopes_(4, zone), |
109 variables_(zone), | 108 variables_(zone), |
110 temps_(4, zone), | 109 temps_(4, zone), |
111 params_(4, zone), | 110 params_(4, zone), |
112 unresolved_(nullptr), | 111 unresolved_(nullptr), |
113 decls_(4, zone), | 112 decls_(4, zone), |
114 module_descriptor_(NULL), | 113 module_descriptor_(NULL), |
115 sloppy_block_function_map_(zone), | 114 sloppy_block_function_map_(zone), |
116 already_resolved_(true), | 115 already_resolved_(true), |
117 ast_value_factory_(value_factory), | |
118 zone_(zone) { | 116 zone_(zone) { |
119 SetDefaults(scope_type, NULL, scope_info); | 117 SetDefaults(scope_type, NULL, scope_info); |
120 if (!scope_info.is_null()) { | 118 if (!scope_info.is_null()) { |
121 num_heap_slots_ = scope_info_->ContextLength(); | 119 num_heap_slots_ = scope_info_->ContextLength(); |
122 } | 120 } |
123 // Ensure at least MIN_CONTEXT_SLOTS to indicate a materialized context. | 121 // Ensure at least MIN_CONTEXT_SLOTS to indicate a materialized context. |
124 num_heap_slots_ = Max(num_heap_slots_, | 122 num_heap_slots_ = Max(num_heap_slots_, |
125 static_cast<int>(Context::MIN_CONTEXT_SLOTS)); | 123 static_cast<int>(Context::MIN_CONTEXT_SLOTS)); |
126 AddInnerScope(inner_scope); | 124 AddInnerScope(inner_scope); |
127 } | 125 } |
128 | 126 |
129 Scope::Scope(Zone* zone, Scope* inner_scope, | 127 Scope::Scope(Zone* zone, Scope* inner_scope, |
130 const AstRawString* catch_variable_name, | 128 const AstRawString* catch_variable_name) |
131 AstValueFactory* value_factory) | |
132 : inner_scopes_(1, zone), | 129 : inner_scopes_(1, zone), |
133 variables_(zone), | 130 variables_(zone), |
134 temps_(0, zone), | 131 temps_(0, zone), |
135 params_(0, zone), | 132 params_(0, zone), |
136 unresolved_(nullptr), | 133 unresolved_(nullptr), |
137 decls_(0, zone), | 134 decls_(0, zone), |
138 module_descriptor_(NULL), | 135 module_descriptor_(NULL), |
139 sloppy_block_function_map_(zone), | 136 sloppy_block_function_map_(zone), |
140 already_resolved_(true), | 137 already_resolved_(true), |
141 ast_value_factory_(value_factory), | |
142 zone_(zone) { | 138 zone_(zone) { |
143 SetDefaults(CATCH_SCOPE, NULL, Handle<ScopeInfo>::null()); | 139 SetDefaults(CATCH_SCOPE, NULL, Handle<ScopeInfo>::null()); |
144 AddInnerScope(inner_scope); | 140 AddInnerScope(inner_scope); |
145 ++num_var_; | 141 ++num_var_; |
146 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; | 142 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; |
147 Variable* variable = variables_.Declare(this, | 143 Variable* variable = variables_.Declare(this, |
148 catch_variable_name, | 144 catch_variable_name, |
149 VAR, | 145 VAR, |
150 Variable::NORMAL, | 146 Variable::NORMAL, |
151 kCreatedInitialized); | 147 kCreatedInitialized); |
152 AllocateHeapSlot(variable); | 148 AllocateHeapSlot(variable); |
153 } | 149 } |
154 | 150 |
155 | 151 |
156 void Scope::SetDefaults(ScopeType scope_type, Scope* outer_scope, | 152 void Scope::SetDefaults(ScopeType scope_type, Scope* outer_scope, |
157 Handle<ScopeInfo> scope_info, | 153 Handle<ScopeInfo> scope_info, |
158 FunctionKind function_kind) { | 154 FunctionKind function_kind) { |
159 outer_scope_ = outer_scope; | 155 outer_scope_ = outer_scope; |
160 scope_type_ = scope_type; | 156 scope_type_ = scope_type; |
161 is_declaration_scope_ = | 157 is_declaration_scope_ = |
162 is_eval_scope() || is_function_scope() || | 158 is_eval_scope() || is_function_scope() || |
163 is_module_scope() || is_script_scope(); | 159 is_module_scope() || is_script_scope(); |
164 function_kind_ = function_kind; | 160 function_kind_ = function_kind; |
165 scope_name_ = ast_value_factory_->empty_string(); | 161 scope_name_ = nullptr; |
166 dynamics_ = nullptr; | 162 dynamics_ = nullptr; |
167 receiver_ = nullptr; | 163 receiver_ = nullptr; |
168 new_target_ = nullptr; | 164 new_target_ = nullptr; |
169 function_ = nullptr; | 165 function_ = nullptr; |
170 arguments_ = nullptr; | 166 arguments_ = nullptr; |
171 this_function_ = nullptr; | 167 this_function_ = nullptr; |
172 scope_inside_with_ = false; | 168 scope_inside_with_ = false; |
173 scope_calls_eval_ = false; | 169 scope_calls_eval_ = false; |
174 scope_uses_arguments_ = false; | 170 scope_uses_arguments_ = false; |
175 scope_uses_super_property_ = false; | 171 scope_uses_super_property_ = false; |
(...skipping 23 matching lines...) Expand all Loading... |
199 end_position_ = kNoSourcePosition; | 195 end_position_ = kNoSourcePosition; |
200 is_hidden_ = false; | 196 is_hidden_ = false; |
201 if (!scope_info.is_null()) { | 197 if (!scope_info.is_null()) { |
202 scope_calls_eval_ = scope_info->CallsEval(); | 198 scope_calls_eval_ = scope_info->CallsEval(); |
203 language_mode_ = scope_info->language_mode(); | 199 language_mode_ = scope_info->language_mode(); |
204 is_declaration_scope_ = scope_info->is_declaration_scope(); | 200 is_declaration_scope_ = scope_info->is_declaration_scope(); |
205 function_kind_ = scope_info->function_kind(); | 201 function_kind_ = scope_info->function_kind(); |
206 } | 202 } |
207 } | 203 } |
208 | 204 |
209 | |
210 Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone, | 205 Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone, |
211 Context* context, Scope* script_scope) { | 206 Context* context, Scope* script_scope, |
| 207 AstValueFactory* ast_value_factory) { |
212 // Reconstruct the outer scope chain from a closure's context chain. | 208 // Reconstruct the outer scope chain from a closure's context chain. |
213 Scope* current_scope = NULL; | 209 Scope* current_scope = NULL; |
214 Scope* innermost_scope = NULL; | 210 Scope* innermost_scope = NULL; |
215 while (!context->IsNativeContext()) { | 211 while (!context->IsNativeContext()) { |
216 if (context->IsWithContext() || context->IsDebugEvaluateContext()) { | 212 if (context->IsWithContext() || context->IsDebugEvaluateContext()) { |
217 // For scope analysis, debug-evaluate is equivalent to a with scope. | 213 // For scope analysis, debug-evaluate is equivalent to a with scope. |
218 Scope* with_scope = new (zone) | 214 Scope* with_scope = new (zone) |
219 Scope(zone, current_scope, WITH_SCOPE, Handle<ScopeInfo>::null(), | 215 Scope(zone, current_scope, WITH_SCOPE, Handle<ScopeInfo>::null()); |
220 script_scope->ast_value_factory_); | |
221 current_scope = with_scope; | 216 current_scope = with_scope; |
222 // All the inner scopes are inside a with. | 217 // All the inner scopes are inside a with. |
223 for (Scope* s = innermost_scope; s != NULL; s = s->outer_scope()) { | 218 for (Scope* s = innermost_scope; s != NULL; s = s->outer_scope()) { |
224 s->scope_inside_with_ = true; | 219 s->scope_inside_with_ = true; |
225 } | 220 } |
226 } else if (context->IsScriptContext()) { | 221 } else if (context->IsScriptContext()) { |
227 ScopeInfo* scope_info = context->scope_info(); | 222 ScopeInfo* scope_info = context->scope_info(); |
228 current_scope = new (zone) Scope(zone, current_scope, SCRIPT_SCOPE, | 223 current_scope = new (zone) Scope(zone, current_scope, SCRIPT_SCOPE, |
229 Handle<ScopeInfo>(scope_info), | 224 Handle<ScopeInfo>(scope_info)); |
230 script_scope->ast_value_factory_); | |
231 } else if (context->IsFunctionContext()) { | 225 } else if (context->IsFunctionContext()) { |
232 ScopeInfo* scope_info = context->closure()->shared()->scope_info(); | 226 ScopeInfo* scope_info = context->closure()->shared()->scope_info(); |
233 current_scope = new (zone) Scope(zone, current_scope, FUNCTION_SCOPE, | 227 current_scope = new (zone) Scope(zone, current_scope, FUNCTION_SCOPE, |
234 Handle<ScopeInfo>(scope_info), | 228 Handle<ScopeInfo>(scope_info)); |
235 script_scope->ast_value_factory_); | |
236 if (scope_info->IsAsmFunction()) current_scope->asm_function_ = true; | 229 if (scope_info->IsAsmFunction()) current_scope->asm_function_ = true; |
237 if (scope_info->IsAsmModule()) current_scope->asm_module_ = true; | 230 if (scope_info->IsAsmModule()) current_scope->asm_module_ = true; |
238 } else if (context->IsBlockContext()) { | 231 } else if (context->IsBlockContext()) { |
239 ScopeInfo* scope_info = context->scope_info(); | 232 ScopeInfo* scope_info = context->scope_info(); |
240 current_scope = new (zone) | 233 current_scope = new (zone) Scope(zone, current_scope, BLOCK_SCOPE, |
241 Scope(zone, current_scope, BLOCK_SCOPE, Handle<ScopeInfo>(scope_info), | 234 Handle<ScopeInfo>(scope_info)); |
242 script_scope->ast_value_factory_); | |
243 } else { | 235 } else { |
244 DCHECK(context->IsCatchContext()); | 236 DCHECK(context->IsCatchContext()); |
245 String* name = context->catch_name(); | 237 String* name = context->catch_name(); |
246 current_scope = new (zone) Scope( | 238 current_scope = |
247 zone, current_scope, | 239 new (zone) Scope(zone, current_scope, |
248 script_scope->ast_value_factory_->GetString(Handle<String>(name)), | 240 ast_value_factory->GetString(handle(name, isolate))); |
249 script_scope->ast_value_factory_); | |
250 } | 241 } |
251 if (innermost_scope == NULL) innermost_scope = current_scope; | 242 if (innermost_scope == NULL) innermost_scope = current_scope; |
252 context = context->previous(); | 243 context = context->previous(); |
253 } | 244 } |
254 | 245 |
255 script_scope->AddInnerScope(current_scope); | 246 script_scope->AddInnerScope(current_scope); |
256 script_scope->PropagateScopeInfo(false); | 247 script_scope->PropagateScopeInfo(false); |
257 return (innermost_scope == NULL) ? script_scope : innermost_scope; | 248 return (innermost_scope == NULL) ? script_scope : innermost_scope; |
258 } | 249 } |
259 | 250 |
(...skipping 30 matching lines...) Expand all Loading... |
290 scope->CheckScopePositions(); | 281 scope->CheckScopePositions(); |
291 #endif | 282 #endif |
292 | 283 |
293 info->set_scope(scope); | 284 info->set_scope(scope); |
294 return true; | 285 return true; |
295 } | 286 } |
296 | 287 |
297 | 288 |
298 void Scope::Initialize() { | 289 void Scope::Initialize() { |
299 DCHECK(!already_resolved()); | 290 DCHECK(!already_resolved()); |
300 | 291 if (outer_scope_ == nullptr) { |
301 // Add this scope as a new inner scope of the outer scope. | 292 scope_inside_with_ = is_with_scope(); |
302 if (outer_scope_ != NULL) { | 293 } else { |
303 outer_scope_->inner_scopes_.Add(this, zone()); | 294 outer_scope_->inner_scopes_.Add(this, zone()); |
304 scope_inside_with_ = outer_scope_->scope_inside_with_ || is_with_scope(); | 295 scope_inside_with_ = outer_scope_->scope_inside_with_ || is_with_scope(); |
305 } else { | |
306 scope_inside_with_ = is_with_scope(); | |
307 } | |
308 | |
309 // Declare convenience variables and the receiver. | |
310 if (is_declaration_scope() && has_this_declaration()) { | |
311 bool subclass_constructor = IsSubclassConstructor(function_kind_); | |
312 Variable* var = variables_.Declare( | |
313 this, ast_value_factory_->this_string(), | |
314 subclass_constructor ? CONST : VAR, Variable::THIS, | |
315 subclass_constructor ? kNeedsInitialization : kCreatedInitialized); | |
316 receiver_ = var; | |
317 } | |
318 | |
319 if (is_function_scope() && !is_arrow_scope()) { | |
320 // Declare 'arguments' variable which exists in all non arrow functions. | |
321 // Note that it might never be accessed, in which case it won't be | |
322 // allocated during variable allocation. | |
323 arguments_ = | |
324 variables_.Declare(this, ast_value_factory_->arguments_string(), VAR, | |
325 Variable::ARGUMENTS, kCreatedInitialized); | |
326 | |
327 new_target_ = | |
328 variables_.Declare(this, ast_value_factory_->new_target_string(), CONST, | |
329 Variable::NORMAL, kCreatedInitialized); | |
330 | |
331 if (IsConciseMethod(function_kind_) || IsClassConstructor(function_kind_) || | |
332 IsAccessorFunction(function_kind_)) { | |
333 this_function_ = | |
334 variables_.Declare(this, ast_value_factory_->this_function_string(), | |
335 CONST, Variable::NORMAL, kCreatedInitialized); | |
336 } | |
337 } | 296 } |
338 } | 297 } |
339 | 298 |
| 299 void Scope::DeclareThis(AstValueFactory* ast_value_factory) { |
| 300 DCHECK(!already_resolved()); |
| 301 DCHECK(is_declaration_scope()); |
| 302 DCHECK(has_this_declaration()); |
| 303 |
| 304 bool subclass_constructor = IsSubclassConstructor(function_kind_); |
| 305 Variable* var = variables_.Declare( |
| 306 this, ast_value_factory->this_string(), |
| 307 subclass_constructor ? CONST : VAR, Variable::THIS, |
| 308 subclass_constructor ? kNeedsInitialization : kCreatedInitialized); |
| 309 receiver_ = var; |
| 310 } |
| 311 |
| 312 void Scope::DeclareDefaultFunctionVariables( |
| 313 AstValueFactory* ast_value_factory) { |
| 314 DCHECK(is_function_scope()); |
| 315 DCHECK(!is_arrow_scope()); |
| 316 // Declare 'arguments' variable which exists in all non arrow functions. |
| 317 // Note that it might never be accessed, in which case it won't be |
| 318 // allocated during variable allocation. |
| 319 arguments_ = |
| 320 variables_.Declare(this, ast_value_factory->arguments_string(), VAR, |
| 321 Variable::ARGUMENTS, kCreatedInitialized); |
| 322 |
| 323 new_target_ = |
| 324 variables_.Declare(this, ast_value_factory->new_target_string(), CONST, |
| 325 Variable::NORMAL, kCreatedInitialized); |
| 326 |
| 327 if (IsConciseMethod(function_kind_) || IsClassConstructor(function_kind_) || |
| 328 IsAccessorFunction(function_kind_)) { |
| 329 this_function_ = |
| 330 variables_.Declare(this, ast_value_factory->this_function_string(), |
| 331 CONST, Variable::NORMAL, kCreatedInitialized); |
| 332 } |
| 333 } |
| 334 |
340 | 335 |
341 Scope* Scope::FinalizeBlockScope() { | 336 Scope* Scope::FinalizeBlockScope() { |
342 DCHECK(is_block_scope()); | 337 DCHECK(is_block_scope()); |
343 DCHECK(temps_.is_empty()); | 338 DCHECK(temps_.is_empty()); |
344 DCHECK(params_.is_empty()); | 339 DCHECK(params_.is_empty()); |
345 | 340 |
346 if (num_var() > 0 || (is_declaration_scope() && calls_sloppy_eval())) { | 341 if (num_var() > 0 || (is_declaration_scope() && calls_sloppy_eval())) { |
347 return this; | 342 return this; |
348 } | 343 } |
349 | 344 |
(...skipping 1201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1551 function_ != NULL && function_->proxy()->var()->IsContextSlot(); | 1546 function_ != NULL && function_->proxy()->var()->IsContextSlot(); |
1552 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - | 1547 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - |
1553 (is_function_var_in_context ? 1 : 0); | 1548 (is_function_var_in_context ? 1 : 0); |
1554 } | 1549 } |
1555 | 1550 |
1556 | 1551 |
1557 int Scope::ContextGlobalCount() const { return num_global_slots(); } | 1552 int Scope::ContextGlobalCount() const { return num_global_slots(); } |
1558 | 1553 |
1559 } // namespace internal | 1554 } // namespace internal |
1560 } // namespace v8 | 1555 } // namespace v8 |
OLD | NEW |