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/bootstrapper.h" | 8 #include "src/bootstrapper.h" |
9 #include "src/messages.h" | 9 #include "src/messages.h" |
10 #include "src/parsing/parser.h" // for ParseInfo | 10 #include "src/parsing/parser.h" // for ParseInfo |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
74 p->value = new (zone_->New(sizeof(Vector))) Vector(zone_); | 74 p->value = new (zone_->New(sizeof(Vector))) Vector(zone_); |
75 } | 75 } |
76 Vector* delegates = static_cast<Vector*>(p->value); | 76 Vector* delegates = static_cast<Vector*>(p->value); |
77 delegates->push_back(stmt); | 77 delegates->push_back(stmt); |
78 } | 78 } |
79 | 79 |
80 | 80 |
81 // ---------------------------------------------------------------------------- | 81 // ---------------------------------------------------------------------------- |
82 // Implementation of Scope | 82 // Implementation of Scope |
83 | 83 |
84 Scope::Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type, | 84 Scope::Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type) |
85 FunctionKind function_kind) | |
86 : outer_scope_(outer_scope), | 85 : outer_scope_(outer_scope), |
87 variables_(zone), | 86 variables_(zone), |
88 temps_(4, zone), | |
89 params_(4, zone), | |
90 decls_(4, zone), | 87 decls_(4, zone), |
91 module_descriptor_(scope_type == MODULE_SCOPE ? new (zone) | |
92 ModuleDescriptor(zone) | |
93 : NULL), | |
94 sloppy_block_function_map_(zone), | |
95 scope_type_(scope_type), | 88 scope_type_(scope_type), |
96 function_kind_(function_kind), | |
97 already_resolved_(false) { | 89 already_resolved_(false) { |
98 SetDefaults(); | 90 SetDefaults(); |
99 if (outer_scope == nullptr) { | 91 if (outer_scope == nullptr) { |
100 // If the outer scope is null, this cannot be a with scope. The outermost | 92 // If the outer scope is null, this cannot be a with scope. The outermost |
101 // scope must be a script scope. | 93 // scope must be a script scope. |
102 DCHECK_EQ(SCRIPT_SCOPE, scope_type); | 94 DCHECK_EQ(SCRIPT_SCOPE, scope_type); |
103 } else { | 95 } else { |
104 asm_function_ = outer_scope_->asm_module_; | 96 asm_function_ = outer_scope_->asm_module_; |
105 // Inherit the language mode from the parent scope unless we're a module | 97 // Inherit the language mode from the parent scope unless we're a module |
106 // scope. | 98 // scope. |
107 if (!is_module_scope()) language_mode_ = outer_scope->language_mode_; | 99 if (!is_module_scope()) language_mode_ = outer_scope->language_mode_; |
108 force_context_allocation_ = | 100 force_context_allocation_ = |
109 !is_function_scope() && outer_scope->has_forced_context_allocation(); | 101 !is_function_scope() && outer_scope->has_forced_context_allocation(); |
110 outer_scope_->AddInnerScope(this); | 102 outer_scope_->AddInnerScope(this); |
111 scope_inside_with_ = outer_scope_->scope_inside_with_ || is_with_scope(); | 103 scope_inside_with_ = outer_scope_->scope_inside_with_ || is_with_scope(); |
112 } | 104 } |
113 } | 105 } |
114 | 106 |
107 Scope::Snapshot::Snapshot(Scope* scope) | |
108 : outer_scope_(scope), | |
109 top_inner_scope_(scope->inner_scope_), | |
110 top_unresolved_(scope->unresolved_), | |
111 top_temp_(scope->GetClosureScope()->temps()->length()) {} | |
112 | |
113 DeclarationScope::DeclarationScope(Zone* zone, Scope* outer_scope, | |
114 ScopeType scope_type, | |
115 FunctionKind function_kind) | |
116 : Scope(zone, outer_scope, scope_type), | |
117 function_kind_(function_kind), | |
118 temps_(4, zone), | |
119 params_(4, zone), | |
120 sloppy_block_function_map_(zone), | |
121 module_descriptor_(scope_type == MODULE_SCOPE ? new (zone) | |
122 ModuleDescriptor(zone) | |
123 : NULL) { | |
124 SetDefaults(); | |
125 } | |
126 | |
115 Scope::Scope(Zone* zone, Scope* inner_scope, ScopeType scope_type, | 127 Scope::Scope(Zone* zone, Scope* inner_scope, ScopeType scope_type, |
116 Handle<ScopeInfo> scope_info) | 128 Handle<ScopeInfo> scope_info) |
117 : outer_scope_(nullptr), | 129 : outer_scope_(nullptr), |
118 variables_(zone), | 130 variables_(zone), |
119 temps_(4, zone), | |
120 params_(4, zone), | |
121 decls_(4, zone), | 131 decls_(4, zone), |
122 module_descriptor_(nullptr), | |
123 sloppy_block_function_map_(zone), | |
124 scope_type_(scope_type), | 132 scope_type_(scope_type), |
125 function_kind_(scope_info.is_null() ? kNormalFunction | |
126 : scope_info->function_kind()), | |
127 already_resolved_(true), | 133 already_resolved_(true), |
128 scope_info_(scope_info) { | 134 scope_info_(scope_info) { |
129 SetDefaults(); | 135 SetDefaults(); |
130 if (!scope_info.is_null()) { | 136 if (!scope_info.is_null()) { |
131 scope_calls_eval_ = scope_info->CallsEval(); | 137 scope_calls_eval_ = scope_info->CallsEval(); |
132 language_mode_ = scope_info->language_mode(); | 138 language_mode_ = scope_info->language_mode(); |
133 is_declaration_scope_ = scope_info->is_declaration_scope(); | |
134 num_heap_slots_ = scope_info_->ContextLength(); | 139 num_heap_slots_ = scope_info_->ContextLength(); |
135 } | 140 } |
136 // Ensure at least MIN_CONTEXT_SLOTS to indicate a materialized context. | 141 // Ensure at least MIN_CONTEXT_SLOTS to indicate a materialized context. |
137 num_heap_slots_ = Max(num_heap_slots_, | 142 num_heap_slots_ = Max(num_heap_slots_, |
138 static_cast<int>(Context::MIN_CONTEXT_SLOTS)); | 143 static_cast<int>(Context::MIN_CONTEXT_SLOTS)); |
139 AddInnerScope(inner_scope); | 144 AddInnerScope(inner_scope); |
140 } | 145 } |
141 | 146 |
147 DeclarationScope::DeclarationScope(Zone* zone, Scope* inner_scope, | |
148 ScopeType scope_type, | |
149 Handle<ScopeInfo> scope_info) | |
150 : Scope(zone, inner_scope, scope_type, scope_info), | |
151 function_kind_(scope_info.is_null() ? kNormalFunction | |
152 : scope_info->function_kind()), | |
153 temps_(4, zone), | |
154 params_(4, zone), | |
155 sloppy_block_function_map_(zone), | |
156 module_descriptor_(nullptr) { | |
157 SetDefaults(); | |
158 } | |
159 | |
142 Scope::Scope(Zone* zone, Scope* inner_scope, | 160 Scope::Scope(Zone* zone, Scope* inner_scope, |
143 const AstRawString* catch_variable_name) | 161 const AstRawString* catch_variable_name) |
144 : outer_scope_(nullptr), | 162 : outer_scope_(nullptr), |
145 variables_(zone), | 163 variables_(zone), |
146 temps_(0, zone), | |
147 params_(0, zone), | |
148 decls_(0, zone), | 164 decls_(0, zone), |
149 module_descriptor_(nullptr), | |
150 sloppy_block_function_map_(zone), | |
151 scope_type_(CATCH_SCOPE), | 165 scope_type_(CATCH_SCOPE), |
152 function_kind_(kNormalFunction), | |
153 already_resolved_(true) { | 166 already_resolved_(true) { |
154 SetDefaults(); | 167 SetDefaults(); |
155 AddInnerScope(inner_scope); | 168 AddInnerScope(inner_scope); |
156 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; | 169 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; |
157 Variable* variable = variables_.Declare(this, | 170 Variable* variable = variables_.Declare(this, |
158 catch_variable_name, | 171 catch_variable_name, |
159 VAR, | 172 VAR, |
160 Variable::NORMAL, | 173 Variable::NORMAL, |
161 kCreatedInitialized); | 174 kCreatedInitialized); |
162 AllocateHeapSlot(variable); | 175 AllocateHeapSlot(variable); |
163 } | 176 } |
164 | 177 |
165 void Scope::SetDefaults() { | 178 void DeclarationScope::SetDefaults() { |
166 is_declaration_scope_ = | 179 is_declaration_scope_ = true; |
167 is_eval_scope() || is_function_scope() || | |
168 is_module_scope() || is_script_scope(); | |
169 inner_scope_ = nullptr; | |
170 sibling_ = nullptr; | |
171 unresolved_ = nullptr; | |
172 #ifdef DEBUG | |
173 scope_name_ = nullptr; | |
174 #endif | |
175 dynamics_ = nullptr; | |
176 receiver_ = nullptr; | 180 receiver_ = nullptr; |
177 new_target_ = nullptr; | 181 new_target_ = nullptr; |
178 function_ = nullptr; | 182 function_ = nullptr; |
179 arguments_ = nullptr; | 183 arguments_ = nullptr; |
180 this_function_ = nullptr; | 184 this_function_ = nullptr; |
185 arity_ = 0; | |
186 has_simple_parameters_ = true; | |
187 rest_parameter_ = NULL; | |
188 rest_index_ = -1; | |
189 } | |
190 | |
191 void Scope::SetDefaults() { | |
192 #ifdef DEBUG | |
193 scope_name_ = nullptr; | |
194 #endif | |
195 is_declaration_scope_ = false; | |
196 inner_scope_ = nullptr; | |
197 sibling_ = nullptr; | |
198 unresolved_ = nullptr; | |
199 dynamics_ = nullptr; | |
181 scope_inside_with_ = false; | 200 scope_inside_with_ = false; |
182 scope_calls_eval_ = false; | 201 scope_calls_eval_ = false; |
183 has_arguments_parameter_ = false; | 202 has_arguments_parameter_ = false; |
184 scope_uses_super_property_ = false; | 203 scope_uses_super_property_ = false; |
185 asm_module_ = false; | 204 asm_module_ = false; |
186 asm_function_ = false; | 205 asm_function_ = false; |
187 language_mode_ = is_module_scope() ? STRICT : SLOPPY; | 206 language_mode_ = is_module_scope() ? STRICT : SLOPPY; |
188 outer_scope_calls_sloppy_eval_ = false; | 207 outer_scope_calls_sloppy_eval_ = false; |
189 inner_scope_calls_eval_ = false; | 208 inner_scope_calls_eval_ = false; |
190 scope_nonlinear_ = false; | 209 scope_nonlinear_ = false; |
191 force_eager_compilation_ = false; | 210 force_eager_compilation_ = false; |
192 force_context_allocation_ = false; | 211 force_context_allocation_ = false; |
193 num_stack_slots_ = 0; | 212 num_stack_slots_ = 0; |
194 num_heap_slots_ = 0; | 213 num_heap_slots_ = 0; |
195 num_global_slots_ = 0; | 214 num_global_slots_ = 0; |
196 arity_ = 0; | |
197 has_simple_parameters_ = true; | |
198 rest_parameter_ = NULL; | |
199 rest_index_ = -1; | |
200 start_position_ = kNoSourcePosition; | 215 start_position_ = kNoSourcePosition; |
201 end_position_ = kNoSourcePosition; | 216 end_position_ = kNoSourcePosition; |
202 is_hidden_ = false; | 217 is_hidden_ = false; |
203 } | 218 } |
204 | 219 |
220 bool Scope::HasSimpleParameters() { | |
221 DeclarationScope* scope = GetClosureScope(); | |
222 return !scope->is_function_scope() || scope->has_simple_parameters(); | |
223 } | |
224 | |
205 Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone, | 225 Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone, |
206 Context* context, Scope* script_scope, | 226 Context* context, Scope* script_scope, |
207 AstValueFactory* ast_value_factory) { | 227 AstValueFactory* ast_value_factory) { |
208 // Reconstruct the outer scope chain from a closure's context chain. | 228 // Reconstruct the outer scope chain from a closure's context chain. |
209 Scope* current_scope = NULL; | 229 Scope* current_scope = NULL; |
210 Scope* innermost_scope = NULL; | 230 Scope* innermost_scope = NULL; |
211 while (!context->IsNativeContext()) { | 231 while (!context->IsNativeContext()) { |
212 if (context->IsWithContext() || context->IsDebugEvaluateContext()) { | 232 if (context->IsWithContext() || context->IsDebugEvaluateContext()) { |
213 // For scope analysis, debug-evaluate is equivalent to a with scope. | 233 // For scope analysis, debug-evaluate is equivalent to a with scope. |
214 Scope* with_scope = new (zone) | 234 Scope* with_scope = new (zone) |
215 Scope(zone, current_scope, WITH_SCOPE, Handle<ScopeInfo>::null()); | 235 Scope(zone, current_scope, WITH_SCOPE, Handle<ScopeInfo>::null()); |
216 current_scope = with_scope; | 236 current_scope = with_scope; |
217 // All the inner scopes are inside a with. | 237 // All the inner scopes are inside a with. |
218 for (Scope* s = innermost_scope; s != NULL; s = s->outer_scope()) { | 238 for (Scope* s = innermost_scope; s != NULL; s = s->outer_scope()) { |
219 s->scope_inside_with_ = true; | 239 s->scope_inside_with_ = true; |
220 } | 240 } |
221 } else if (context->IsScriptContext()) { | 241 } else if (context->IsScriptContext()) { |
222 ScopeInfo* scope_info = context->scope_info(); | 242 ScopeInfo* scope_info = context->scope_info(); |
223 current_scope = new (zone) Scope(zone, current_scope, SCRIPT_SCOPE, | 243 current_scope = new (zone) DeclarationScope( |
224 Handle<ScopeInfo>(scope_info)); | 244 zone, current_scope, SCRIPT_SCOPE, Handle<ScopeInfo>(scope_info)); |
225 } else if (context->IsFunctionContext()) { | 245 } else if (context->IsFunctionContext()) { |
226 ScopeInfo* scope_info = context->closure()->shared()->scope_info(); | 246 ScopeInfo* scope_info = context->closure()->shared()->scope_info(); |
227 current_scope = new (zone) Scope(zone, current_scope, FUNCTION_SCOPE, | 247 current_scope = new (zone) DeclarationScope( |
228 Handle<ScopeInfo>(scope_info)); | 248 zone, current_scope, FUNCTION_SCOPE, Handle<ScopeInfo>(scope_info)); |
229 if (scope_info->IsAsmFunction()) current_scope->asm_function_ = true; | 249 if (scope_info->IsAsmFunction()) current_scope->asm_function_ = true; |
230 if (scope_info->IsAsmModule()) current_scope->asm_module_ = true; | 250 if (scope_info->IsAsmModule()) current_scope->asm_module_ = true; |
231 } else if (context->IsBlockContext()) { | 251 } else if (context->IsBlockContext()) { |
232 ScopeInfo* scope_info = context->scope_info(); | 252 ScopeInfo* scope_info = context->scope_info(); |
233 current_scope = new (zone) Scope(zone, current_scope, BLOCK_SCOPE, | 253 if (scope_info->is_declaration_scope()) { |
234 Handle<ScopeInfo>(scope_info)); | 254 current_scope = new (zone) DeclarationScope( |
255 zone, current_scope, BLOCK_SCOPE, Handle<ScopeInfo>(scope_info)); | |
256 } else { | |
257 current_scope = new (zone) Scope(zone, current_scope, BLOCK_SCOPE, | |
258 Handle<ScopeInfo>(scope_info)); | |
259 } | |
235 } else { | 260 } else { |
236 DCHECK(context->IsCatchContext()); | 261 DCHECK(context->IsCatchContext()); |
237 String* name = context->catch_name(); | 262 String* name = context->catch_name(); |
238 current_scope = | 263 current_scope = |
239 new (zone) Scope(zone, current_scope, | 264 new (zone) Scope(zone, current_scope, |
240 ast_value_factory->GetString(handle(name, isolate))); | 265 ast_value_factory->GetString(handle(name, isolate))); |
241 } | 266 } |
242 if (innermost_scope == NULL) innermost_scope = current_scope; | 267 if (innermost_scope == NULL) innermost_scope = current_scope; |
243 context = context->previous(); | 268 context = context->previous(); |
244 } | 269 } |
245 | 270 |
246 script_scope->AddInnerScope(current_scope); | 271 script_scope->AddInnerScope(current_scope); |
247 script_scope->PropagateScopeInfo(false); | 272 script_scope->PropagateScopeInfo(false); |
248 return (innermost_scope == NULL) ? script_scope : innermost_scope; | 273 return (innermost_scope == NULL) ? script_scope : innermost_scope; |
249 } | 274 } |
250 | 275 |
276 DeclarationScope* Scope::AsDeclarationScope() { | |
277 DCHECK(is_declaration_scope()); | |
278 return static_cast<DeclarationScope*>(this); | |
279 } | |
280 | |
281 const DeclarationScope* Scope::AsDeclarationScope() const { | |
282 DCHECK(is_declaration_scope()); | |
283 return static_cast<const DeclarationScope*>(this); | |
284 } | |
285 | |
286 int Scope::num_parameters() const { | |
287 return is_declaration_scope() ? AsDeclarationScope()->num_parameters() : 0; | |
288 } | |
251 | 289 |
252 bool Scope::Analyze(ParseInfo* info) { | 290 bool Scope::Analyze(ParseInfo* info) { |
253 DCHECK(info->literal() != NULL); | 291 DCHECK(info->literal() != NULL); |
254 DCHECK(info->scope() == NULL); | 292 DCHECK(info->scope() == NULL); |
255 Scope* scope = info->literal()->scope(); | 293 DeclarationScope* scope = info->literal()->scope(); |
256 Scope* top = scope; | 294 DeclarationScope* top = scope; |
257 | 295 |
258 // Traverse the scope tree up to the first unresolved scope or the global | 296 // Traverse the scope tree up to the first unresolved scope or the global |
259 // scope and start scope resolution and variable allocation from that scope. | 297 // scope and start scope resolution and variable allocation from that scope. |
298 // Such a scope is always a closure-scope, so always skip to the next closure | |
299 // scope. | |
260 while (!top->is_script_scope() && | 300 while (!top->is_script_scope() && |
261 !top->outer_scope()->already_resolved()) { | 301 !top->outer_scope()->already_resolved()) { |
262 top = top->outer_scope(); | 302 top = top->outer_scope()->GetClosureScope(); |
263 } | 303 } |
264 | 304 |
265 // Allocate the variables. | 305 // Allocate the variables. |
266 { | 306 { |
267 AstNodeFactory ast_node_factory(info->ast_value_factory()); | 307 AstNodeFactory ast_node_factory(info->ast_value_factory()); |
268 if (!top->AllocateVariables(info, &ast_node_factory)) { | 308 if (!top->AllocateVariables(info, &ast_node_factory)) { |
269 DCHECK(top->pending_error_handler_.has_pending_error()); | 309 DCHECK(top->pending_error_handler_.has_pending_error()); |
270 top->pending_error_handler_.ThrowPendingError(info->isolate(), | 310 top->pending_error_handler_.ThrowPendingError(info->isolate(), |
271 info->script()); | 311 info->script()); |
272 return false; | 312 return false; |
273 } | 313 } |
274 } | 314 } |
275 | 315 |
276 #ifdef DEBUG | 316 #ifdef DEBUG |
277 if (info->script_is_native() ? FLAG_print_builtin_scopes | 317 if (info->script_is_native() ? FLAG_print_builtin_scopes |
278 : FLAG_print_scopes) { | 318 : FLAG_print_scopes) { |
279 scope->Print(); | 319 scope->Print(); |
280 } | 320 } |
281 scope->CheckScopePositions(); | 321 scope->CheckScopePositions(); |
282 scope->CheckZones(); | 322 scope->CheckZones(); |
283 #endif | 323 #endif |
284 | 324 |
285 info->set_scope(scope); | 325 info->set_scope(scope); |
286 return true; | 326 return true; |
287 } | 327 } |
288 | 328 |
289 void Scope::DeclareThis(AstValueFactory* ast_value_factory) { | 329 void DeclarationScope::DeclareThis(AstValueFactory* ast_value_factory) { |
290 DCHECK(!already_resolved()); | 330 DCHECK(!already_resolved()); |
291 DCHECK(is_declaration_scope()); | 331 DCHECK(is_declaration_scope()); |
292 DCHECK(has_this_declaration()); | 332 DCHECK(has_this_declaration()); |
293 | 333 |
294 bool subclass_constructor = IsSubclassConstructor(function_kind_); | 334 bool subclass_constructor = IsSubclassConstructor(function_kind_); |
295 Variable* var = variables_.Declare( | 335 Variable* var = variables_.Declare( |
296 this, ast_value_factory->this_string(), | 336 this, ast_value_factory->this_string(), |
297 subclass_constructor ? CONST : VAR, Variable::THIS, | 337 subclass_constructor ? CONST : VAR, Variable::THIS, |
298 subclass_constructor ? kNeedsInitialization : kCreatedInitialized); | 338 subclass_constructor ? kNeedsInitialization : kCreatedInitialized); |
299 receiver_ = var; | 339 receiver_ = var; |
300 } | 340 } |
301 | 341 |
302 void Scope::DeclareDefaultFunctionVariables( | 342 void DeclarationScope::DeclareDefaultFunctionVariables( |
303 AstValueFactory* ast_value_factory) { | 343 AstValueFactory* ast_value_factory) { |
304 DCHECK(is_function_scope()); | 344 DCHECK(is_function_scope()); |
305 DCHECK(!is_arrow_scope()); | 345 DCHECK(!is_arrow_scope()); |
306 // Declare 'arguments' variable which exists in all non arrow functions. | 346 // Declare 'arguments' variable which exists in all non arrow functions. |
307 // Note that it might never be accessed, in which case it won't be | 347 // Note that it might never be accessed, in which case it won't be |
308 // allocated during variable allocation. | 348 // allocated during variable allocation. |
309 arguments_ = | 349 arguments_ = |
310 variables_.Declare(this, ast_value_factory->arguments_string(), VAR, | 350 variables_.Declare(this, ast_value_factory->arguments_string(), VAR, |
311 Variable::ARGUMENTS, kCreatedInitialized); | 351 Variable::ARGUMENTS, kCreatedInitialized); |
312 | 352 |
313 new_target_ = | 353 new_target_ = |
314 variables_.Declare(this, ast_value_factory->new_target_string(), CONST, | 354 variables_.Declare(this, ast_value_factory->new_target_string(), CONST, |
315 Variable::NORMAL, kCreatedInitialized); | 355 Variable::NORMAL, kCreatedInitialized); |
316 | 356 |
317 if (IsConciseMethod(function_kind_) || IsClassConstructor(function_kind_) || | 357 if (IsConciseMethod(function_kind_) || IsClassConstructor(function_kind_) || |
318 IsAccessorFunction(function_kind_)) { | 358 IsAccessorFunction(function_kind_)) { |
319 this_function_ = | 359 this_function_ = |
320 variables_.Declare(this, ast_value_factory->this_function_string(), | 360 variables_.Declare(this, ast_value_factory->this_function_string(), |
321 CONST, Variable::NORMAL, kCreatedInitialized); | 361 CONST, Variable::NORMAL, kCreatedInitialized); |
322 } | 362 } |
323 } | 363 } |
324 | 364 |
325 | 365 |
326 Scope* Scope::FinalizeBlockScope() { | 366 Scope* Scope::FinalizeBlockScope() { |
327 DCHECK(is_block_scope()); | 367 DCHECK(is_block_scope()); |
328 DCHECK(temps_.is_empty()); | |
329 DCHECK(params_.is_empty()); | |
330 | 368 |
331 if (variables_.occupancy() > 0 || | 369 if (variables_.occupancy() > 0 || |
332 (is_declaration_scope() && calls_sloppy_eval())) { | 370 (is_declaration_scope() && calls_sloppy_eval())) { |
333 return this; | 371 return this; |
334 } | 372 } |
335 | 373 |
336 // Remove this scope from outer scope. | 374 // Remove this scope from outer scope. |
337 outer_scope()->RemoveInnerScope(this); | 375 outer_scope()->RemoveInnerScope(this); |
338 | 376 |
339 // Reparent inner scopes. | 377 // Reparent inner scopes. |
(...skipping 20 matching lines...) Expand all Loading... | |
360 } | 398 } |
361 outer_scope()->unresolved_ = unresolved_; | 399 outer_scope()->unresolved_ = unresolved_; |
362 unresolved_ = nullptr; | 400 unresolved_ = nullptr; |
363 } | 401 } |
364 | 402 |
365 PropagateUsageFlagsToScope(outer_scope_); | 403 PropagateUsageFlagsToScope(outer_scope_); |
366 | 404 |
367 return NULL; | 405 return NULL; |
368 } | 406 } |
369 | 407 |
370 void Scope::Snapshot::Reparent(Scope* new_parent) const { | 408 void Scope::Snapshot::Reparent(DeclarationScope* new_parent) const { |
371 DCHECK_EQ(new_parent, outer_scope_->inner_scope_); | 409 DCHECK_EQ(new_parent, outer_scope_->inner_scope_); |
372 DCHECK_EQ(new_parent->outer_scope_, outer_scope_); | 410 DCHECK_EQ(new_parent->outer_scope_, outer_scope_); |
373 DCHECK_EQ(new_parent, new_parent->ClosureScope()); | 411 DCHECK_EQ(new_parent, new_parent->GetClosureScope()); |
374 DCHECK_NULL(new_parent->inner_scope_); | 412 DCHECK_NULL(new_parent->inner_scope_); |
375 DCHECK_NULL(new_parent->unresolved_); | 413 DCHECK_NULL(new_parent->unresolved_); |
376 DCHECK_EQ(0, new_parent->temps_.length()); | 414 DCHECK_EQ(0, new_parent->temps()->length()); |
377 Scope* inner_scope = new_parent->sibling_; | 415 Scope* inner_scope = new_parent->sibling_; |
378 if (inner_scope != top_inner_scope_) { | 416 if (inner_scope != top_inner_scope_) { |
379 for (; inner_scope->sibling() != top_inner_scope_; | 417 for (; inner_scope->sibling() != top_inner_scope_; |
380 inner_scope = inner_scope->sibling()) { | 418 inner_scope = inner_scope->sibling()) { |
381 inner_scope->outer_scope_ = new_parent; | 419 inner_scope->outer_scope_ = new_parent; |
382 DCHECK_NE(inner_scope, new_parent); | 420 DCHECK_NE(inner_scope, new_parent); |
383 } | 421 } |
384 inner_scope->outer_scope_ = new_parent; | 422 inner_scope->outer_scope_ = new_parent; |
385 | 423 |
386 new_parent->inner_scope_ = new_parent->sibling_; | 424 new_parent->inner_scope_ = new_parent->sibling_; |
387 inner_scope->sibling_ = nullptr; | 425 inner_scope->sibling_ = nullptr; |
388 // Reset the sibling rather than the inner_scope_ since we | 426 // Reset the sibling rather than the inner_scope_ since we |
389 // want to keep new_parent there. | 427 // want to keep new_parent there. |
390 new_parent->sibling_ = top_inner_scope_; | 428 new_parent->sibling_ = top_inner_scope_; |
391 } | 429 } |
392 | 430 |
393 if (outer_scope_->unresolved_ != top_unresolved_) { | 431 if (outer_scope_->unresolved_ != top_unresolved_) { |
394 VariableProxy* last = outer_scope_->unresolved_; | 432 VariableProxy* last = outer_scope_->unresolved_; |
395 while (last->next_unresolved() != top_unresolved_) { | 433 while (last->next_unresolved() != top_unresolved_) { |
396 last = last->next_unresolved(); | 434 last = last->next_unresolved(); |
397 } | 435 } |
398 last->set_next_unresolved(nullptr); | 436 last->set_next_unresolved(nullptr); |
399 new_parent->unresolved_ = outer_scope_->unresolved_; | 437 new_parent->unresolved_ = outer_scope_->unresolved_; |
400 outer_scope_->unresolved_ = top_unresolved_; | 438 outer_scope_->unresolved_ = top_unresolved_; |
401 } | 439 } |
402 | 440 |
403 if (outer_scope_->ClosureScope()->temps_.length() != top_temp_) { | 441 if (outer_scope_->GetClosureScope()->temps()->length() != top_temp_) { |
404 ZoneList<Variable*>* temps = &outer_scope_->ClosureScope()->temps_; | 442 ZoneList<Variable*>* temps = outer_scope_->GetClosureScope()->temps(); |
405 for (int i = top_temp_; i < temps->length(); i++) { | 443 for (int i = top_temp_; i < temps->length(); i++) { |
406 Variable* temp = temps->at(i); | 444 Variable* temp = temps->at(i); |
407 DCHECK_EQ(temp->scope(), temp->scope()->ClosureScope()); | 445 DCHECK_EQ(temp->scope(), temp->scope()->GetClosureScope()); |
408 DCHECK_NE(temp->scope(), new_parent); | 446 DCHECK_NE(temp->scope(), new_parent); |
409 temp->set_scope(new_parent); | 447 temp->set_scope(new_parent); |
410 new_parent->AddTemporary(temp); | 448 new_parent->AddTemporary(temp); |
411 } | 449 } |
412 temps->Rewind(top_temp_); | 450 temps->Rewind(top_temp_); |
413 } | 451 } |
414 } | 452 } |
415 | 453 |
416 void Scope::ReplaceOuterScope(Scope* outer) { | 454 void Scope::ReplaceOuterScope(Scope* outer) { |
417 DCHECK_NOT_NULL(outer); | 455 DCHECK_NOT_NULL(outer); |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
484 } | 522 } |
485 // TODO(marja, rossberg): Correctly declare FUNCTION, CLASS, NEW_TARGET, and | 523 // TODO(marja, rossberg): Correctly declare FUNCTION, CLASS, NEW_TARGET, and |
486 // ARGUMENTS bindings as their corresponding Variable::Kind. | 524 // ARGUMENTS bindings as their corresponding Variable::Kind. |
487 | 525 |
488 Variable* var = variables_.Declare(this, name, mode, kind, init_flag, | 526 Variable* var = variables_.Declare(this, name, mode, kind, init_flag, |
489 maybe_assigned_flag); | 527 maybe_assigned_flag); |
490 var->AllocateTo(location, index); | 528 var->AllocateTo(location, index); |
491 return var; | 529 return var; |
492 } | 530 } |
493 | 531 |
494 | 532 Variable* DeclarationScope::LookupFunctionVar(const AstRawString* name, |
495 Variable* Scope::LookupFunctionVar(const AstRawString* name, | 533 AstNodeFactory* factory) { |
496 AstNodeFactory* factory) { | |
497 if (function_ != NULL && function_->proxy()->raw_name() == name) { | 534 if (function_ != NULL && function_->proxy()->raw_name() == name) { |
498 return function_->proxy()->var(); | 535 return function_->proxy()->var(); |
499 } else if (!scope_info_.is_null()) { | 536 } else if (!scope_info_.is_null()) { |
500 // If we are backed by a scope info, try to lookup the variable there. | 537 // If we are backed by a scope info, try to lookup the variable there. |
501 VariableMode mode; | 538 VariableMode mode; |
502 int index = scope_info_->FunctionContextSlotIndex(*(name->string()), &mode); | 539 int index = scope_info_->FunctionContextSlotIndex(*(name->string()), &mode); |
503 if (index < 0) return NULL; | 540 if (index < 0) return NULL; |
504 Variable* var = new (zone()) | 541 Variable* var = new (zone()) |
505 Variable(this, name, mode, Variable::NORMAL, kCreatedInitialized); | 542 Variable(this, name, mode, Variable::NORMAL, kCreatedInitialized); |
506 DCHECK_NOT_NULL(factory); | 543 DCHECK_NOT_NULL(factory); |
(...skipping 13 matching lines...) Expand all Loading... | |
520 Variable* Scope::Lookup(const AstRawString* name) { | 557 Variable* Scope::Lookup(const AstRawString* name) { |
521 for (Scope* scope = this; | 558 for (Scope* scope = this; |
522 scope != NULL; | 559 scope != NULL; |
523 scope = scope->outer_scope()) { | 560 scope = scope->outer_scope()) { |
524 Variable* var = scope->LookupLocal(name); | 561 Variable* var = scope->LookupLocal(name); |
525 if (var != NULL) return var; | 562 if (var != NULL) return var; |
526 } | 563 } |
527 return NULL; | 564 return NULL; |
528 } | 565 } |
529 | 566 |
530 Variable* Scope::DeclareParameter(const AstRawString* name, VariableMode mode, | 567 Variable* DeclarationScope::DeclareParameter( |
531 bool is_optional, bool is_rest, | 568 const AstRawString* name, VariableMode mode, bool is_optional, bool is_rest, |
532 bool* is_duplicate, | 569 bool* is_duplicate, AstValueFactory* ast_value_factory) { |
533 AstValueFactory* ast_value_factory) { | |
534 DCHECK(!already_resolved()); | 570 DCHECK(!already_resolved()); |
535 DCHECK(is_function_scope()); | 571 DCHECK(is_function_scope()); |
536 DCHECK(!is_optional || !is_rest); | 572 DCHECK(!is_optional || !is_rest); |
537 Variable* var; | 573 Variable* var; |
538 if (mode == TEMPORARY) { | 574 if (mode == TEMPORARY) { |
539 var = NewTemporary(name); | 575 var = NewTemporary(name); |
540 } else { | 576 } else { |
541 var = variables_.Declare(this, name, mode, Variable::NORMAL, | 577 var = variables_.Declare(this, name, mode, Variable::NORMAL, |
542 kCreatedInitialized); | 578 kCreatedInitialized); |
543 // TODO(wingo): Avoid O(n^2) check. | 579 // TODO(wingo): Avoid O(n^2) check. |
(...skipping 19 matching lines...) Expand all Loading... | |
563 MaybeAssignedFlag maybe_assigned_flag) { | 599 MaybeAssignedFlag maybe_assigned_flag) { |
564 DCHECK(!already_resolved()); | 600 DCHECK(!already_resolved()); |
565 // This function handles VAR, LET, and CONST modes. DYNAMIC variables are | 601 // This function handles VAR, LET, and CONST modes. DYNAMIC variables are |
566 // introduced during variable allocation, and TEMPORARY variables are | 602 // introduced during variable allocation, and TEMPORARY variables are |
567 // allocated via NewTemporary(). | 603 // allocated via NewTemporary(). |
568 DCHECK(IsDeclaredVariableMode(mode)); | 604 DCHECK(IsDeclaredVariableMode(mode)); |
569 return variables_.Declare(this, name, mode, kind, init_flag, | 605 return variables_.Declare(this, name, mode, kind, init_flag, |
570 maybe_assigned_flag); | 606 maybe_assigned_flag); |
571 } | 607 } |
572 | 608 |
573 | 609 Variable* DeclarationScope::DeclareDynamicGlobal(const AstRawString* name) { |
574 Variable* Scope::DeclareDynamicGlobal(const AstRawString* name) { | |
575 DCHECK(is_script_scope()); | 610 DCHECK(is_script_scope()); |
576 return variables_.Declare(this, | 611 return variables_.Declare(this, |
577 name, | 612 name, |
578 DYNAMIC_GLOBAL, | 613 DYNAMIC_GLOBAL, |
579 Variable::NORMAL, | 614 Variable::NORMAL, |
580 kCreatedInitialized); | 615 kCreatedInitialized); |
581 } | 616 } |
582 | 617 |
583 | 618 |
584 bool Scope::RemoveUnresolved(VariableProxy* var) { | 619 bool Scope::RemoveUnresolved(VariableProxy* var) { |
(...skipping 11 matching lines...) Expand all Loading... | |
596 return true; | 631 return true; |
597 } | 632 } |
598 current = next; | 633 current = next; |
599 } | 634 } |
600 return false; | 635 return false; |
601 } | 636 } |
602 | 637 |
603 | 638 |
604 Variable* Scope::NewTemporary(const AstRawString* name) { | 639 Variable* Scope::NewTemporary(const AstRawString* name) { |
605 DCHECK(!already_resolved()); | 640 DCHECK(!already_resolved()); |
606 Scope* scope = this->ClosureScope(); | 641 DeclarationScope* scope = GetClosureScope(); |
607 Variable* var = new(zone()) Variable(scope, | 642 Variable* var = new(zone()) Variable(scope, |
608 name, | 643 name, |
609 TEMPORARY, | 644 TEMPORARY, |
610 Variable::NORMAL, | 645 Variable::NORMAL, |
611 kCreatedInitialized); | 646 kCreatedInitialized); |
612 scope->AddTemporary(var); | 647 scope->AddTemporary(var); |
613 return var; | 648 return var; |
614 } | 649 } |
615 | 650 |
616 int Scope::RemoveTemporary(Variable* var) { | 651 int DeclarationScope::RemoveTemporary(Variable* var) { |
617 DCHECK_NOT_NULL(var); | 652 DCHECK_NOT_NULL(var); |
618 // Temporaries are only placed in ClosureScopes. | 653 // Temporaries are only placed in ClosureScopes. |
619 DCHECK_EQ(ClosureScope(), this); | 654 DCHECK_EQ(GetClosureScope(), this); |
620 DCHECK_EQ(var->scope()->ClosureScope(), var->scope()); | 655 DCHECK_EQ(var->scope()->GetClosureScope(), var->scope()); |
621 // If the temporary is not here, return quickly. | 656 // If the temporary is not here, return quickly. |
622 if (var->scope() != this) return -1; | 657 if (var->scope() != this) return -1; |
623 // Most likely (always?) any temporary variable we want to remove | 658 // Most likely (always?) any temporary variable we want to remove |
624 // was just added before, so we search backwards. | 659 // was just added before, so we search backwards. |
625 for (int i = temps_.length(); i-- > 0;) { | 660 for (int i = temps_.length(); i-- > 0;) { |
626 if (temps_[i] == var) { | 661 if (temps_[i] == var) { |
627 // Don't shrink temps_, as callers of this method expect | 662 // Don't shrink temps_, as callers of this method expect |
628 // the returned indices to be unique per-scope. | 663 // the returned indices to be unique per-scope. |
629 temps_[i] = nullptr; | 664 temps_[i] = nullptr; |
630 return i; | 665 return i; |
631 } | 666 } |
632 } | 667 } |
633 return -1; | 668 return -1; |
634 } | 669 } |
635 | 670 |
636 | 671 |
637 void Scope::AddDeclaration(Declaration* declaration) { | 672 void Scope::AddDeclaration(Declaration* declaration) { |
638 decls_.Add(declaration, zone()); | 673 decls_.Add(declaration, zone()); |
639 } | 674 } |
640 | 675 |
641 | 676 |
642 Declaration* Scope::CheckConflictingVarDeclarations() { | 677 Declaration* Scope::CheckConflictingVarDeclarations() { |
643 int length = decls_.length(); | 678 int length = decls_.length(); |
644 for (int i = 0; i < length; i++) { | 679 for (int i = 0; i < length; i++) { |
645 Declaration* decl = decls_[i]; | 680 Declaration* decl = decls_[i]; |
646 // We don't create a separate scope to hold the function name of a function | 681 // We don't create a separate scope to hold the function name of a function |
647 // expression, so we have to make sure not to consider it when checking for | 682 // expression, so we have to make sure not to consider it when checking for |
648 // conflicts (since it's conceptually "outside" the declaration scope). | 683 // conflicts (since it's conceptually "outside" the declaration scope). |
649 if (is_function_scope() && decl == function()) continue; | 684 if (is_function_scope() && decl == AsDeclarationScope()->function()) |
685 continue; | |
650 if (IsLexicalVariableMode(decl->mode()) && !is_block_scope()) continue; | 686 if (IsLexicalVariableMode(decl->mode()) && !is_block_scope()) continue; |
651 const AstRawString* name = decl->proxy()->raw_name(); | 687 const AstRawString* name = decl->proxy()->raw_name(); |
652 | 688 |
653 // Iterate through all scopes until and including the declaration scope. | 689 // Iterate through all scopes until and including the declaration scope. |
654 Scope* previous = NULL; | 690 Scope* previous = NULL; |
655 Scope* current = decl->scope(); | 691 Scope* current = decl->scope(); |
656 // Lexical vs lexical conflicts within the same scope have already been | 692 // Lexical vs lexical conflicts within the same scope have already been |
657 // captured in Parser::Declare. The only conflicts we still need to check | 693 // captured in Parser::Declare. The only conflicts we still need to check |
658 // are lexical vs VAR, or any declarations within a declaration block scope | 694 // are lexical vs VAR, or any declarations within a declaration block scope |
659 // vs lexical declarations in its surrounding (function) scope. | 695 // vs lexical declarations in its surrounding (function) scope. |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
707 | 743 |
708 void Scope::CollectStackAndContextLocals(ZoneList<Variable*>* stack_locals, | 744 void Scope::CollectStackAndContextLocals(ZoneList<Variable*>* stack_locals, |
709 ZoneList<Variable*>* context_locals, | 745 ZoneList<Variable*>* context_locals, |
710 ZoneList<Variable*>* context_globals) { | 746 ZoneList<Variable*>* context_globals) { |
711 DCHECK(stack_locals != NULL); | 747 DCHECK(stack_locals != NULL); |
712 DCHECK(context_locals != NULL); | 748 DCHECK(context_locals != NULL); |
713 DCHECK(context_globals != NULL); | 749 DCHECK(context_globals != NULL); |
714 | 750 |
715 // Collect temporaries which are always allocated on the stack, unless the | 751 // Collect temporaries which are always allocated on the stack, unless the |
716 // context as a whole has forced context allocation. | 752 // context as a whole has forced context allocation. |
717 for (int i = 0; i < temps_.length(); i++) { | 753 if (is_declaration_scope()) { |
718 Variable* var = temps_[i]; | 754 ZoneList<Variable*>* temps = AsDeclarationScope()->temps(); |
719 if (var == nullptr) continue; | 755 for (int i = 0; i < temps->length(); i++) { |
720 if (var->is_used()) { | 756 Variable* var = (*temps)[i]; |
721 if (var->IsContextSlot()) { | 757 if (var == nullptr) continue; |
722 DCHECK(has_forced_context_allocation()); | 758 if (var->is_used()) { |
723 context_locals->Add(var, zone()); | 759 if (var->IsContextSlot()) { |
724 } else if (var->IsStackLocal()) { | 760 DCHECK(has_forced_context_allocation()); |
725 stack_locals->Add(var, zone()); | 761 context_locals->Add(var, zone()); |
726 } else { | 762 } else if (var->IsStackLocal()) { |
727 DCHECK(var->IsParameter()); | 763 stack_locals->Add(var, zone()); |
764 } else { | |
765 DCHECK(var->IsParameter()); | |
766 } | |
728 } | 767 } |
729 } | 768 } |
730 } | 769 } |
731 | 770 |
732 // Collect declared local variables. | 771 // Collect declared local variables. |
733 ZoneList<VarAndOrder> vars(variables_.occupancy(), zone()); | 772 ZoneList<VarAndOrder> vars(variables_.occupancy(), zone()); |
734 for (VariableMap::Entry* p = variables_.Start(); | 773 for (VariableMap::Entry* p = variables_.Start(); |
735 p != NULL; | 774 p != NULL; |
736 p = variables_.Next(p)) { | 775 p = variables_.Next(p)) { |
737 Variable* var = reinterpret_cast<Variable*>(p->value); | 776 Variable* var = reinterpret_cast<Variable*>(p->value); |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
832 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { | 871 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { |
833 max_context_chain_length = std::max(scope->MaxNestedContextChainLength(), | 872 max_context_chain_length = std::max(scope->MaxNestedContextChainLength(), |
834 max_context_chain_length); | 873 max_context_chain_length); |
835 } | 874 } |
836 if (NeedsContext()) { | 875 if (NeedsContext()) { |
837 max_context_chain_length += 1; | 876 max_context_chain_length += 1; |
838 } | 877 } |
839 return max_context_chain_length; | 878 return max_context_chain_length; |
840 } | 879 } |
841 | 880 |
842 | 881 DeclarationScope* Scope::GetDeclarationScope() { |
843 Scope* Scope::DeclarationScope() { | |
844 Scope* scope = this; | 882 Scope* scope = this; |
845 while (!scope->is_declaration_scope()) { | 883 while (!scope->is_declaration_scope()) { |
846 scope = scope->outer_scope(); | 884 scope = scope->outer_scope(); |
847 } | 885 } |
848 return scope; | 886 return scope->AsDeclarationScope(); |
849 } | 887 } |
850 | 888 |
851 | 889 DeclarationScope* Scope::GetClosureScope() { |
852 Scope* Scope::ClosureScope() { | |
853 Scope* scope = this; | 890 Scope* scope = this; |
854 while (!scope->is_declaration_scope() || scope->is_block_scope()) { | 891 while (!scope->is_declaration_scope() || scope->is_block_scope()) { |
855 scope = scope->outer_scope(); | 892 scope = scope->outer_scope(); |
856 } | 893 } |
857 return scope; | 894 return scope->AsDeclarationScope(); |
895 } | |
896 | |
897 DeclarationScope* Scope::GetReceiverScope() { | |
898 Scope* scope = this; | |
899 while (!scope->is_script_scope() && | |
900 (!scope->is_function_scope() || | |
901 scope->AsDeclarationScope()->is_arrow_scope())) { | |
902 scope = scope->outer_scope(); | |
903 } | |
904 return scope->AsDeclarationScope(); | |
858 } | 905 } |
859 | 906 |
860 | 907 |
861 Scope* Scope::ReceiverScope() { | |
862 Scope* scope = this; | |
863 while (!scope->is_script_scope() && | |
864 (!scope->is_function_scope() || scope->is_arrow_scope())) { | |
865 scope = scope->outer_scope(); | |
866 } | |
867 return scope; | |
868 } | |
869 | |
870 | |
871 | 908 |
872 Handle<ScopeInfo> Scope::GetScopeInfo(Isolate* isolate) { | 909 Handle<ScopeInfo> Scope::GetScopeInfo(Isolate* isolate) { |
873 if (scope_info_.is_null()) { | 910 if (scope_info_.is_null()) { |
874 scope_info_ = ScopeInfo::Create(isolate, zone(), this); | 911 scope_info_ = ScopeInfo::Create(isolate, zone(), this); |
875 } | 912 } |
876 return scope_info_; | 913 return scope_info_; |
877 } | 914 } |
878 | 915 |
879 Handle<StringSet> Scope::CollectNonLocals(Handle<StringSet> non_locals) { | 916 Handle<StringSet> Scope::CollectNonLocals(Handle<StringSet> non_locals) { |
880 // Collect non-local variables referenced in the scope. | 917 // Collect non-local variables referenced in the scope. |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1012 for (VariableMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) { | 1049 for (VariableMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) { |
1013 Variable* var = reinterpret_cast<Variable*>(p->value); | 1050 Variable* var = reinterpret_cast<Variable*>(p->value); |
1014 if (var == NULL) { | 1051 if (var == NULL) { |
1015 Indent(indent, "<?>\n"); | 1052 Indent(indent, "<?>\n"); |
1016 } else { | 1053 } else { |
1017 PrintVar(indent, var); | 1054 PrintVar(indent, var); |
1018 } | 1055 } |
1019 } | 1056 } |
1020 } | 1057 } |
1021 | 1058 |
1059 void DeclarationScope::PrintParameters() { | |
1060 PrintF(" ("); | |
1061 for (int i = 0; i < params_.length(); i++) { | |
1062 if (i > 0) PrintF(", "); | |
1063 const AstRawString* name = params_[i]->raw_name(); | |
1064 if (name->IsEmpty()) | |
1065 PrintF(".%p", reinterpret_cast<void*>(params_[i])); | |
1066 else | |
1067 PrintName(name); | |
1068 } | |
1069 PrintF(")"); | |
1070 } | |
1022 | 1071 |
1023 void Scope::Print(int n) { | 1072 void Scope::Print(int n) { |
1024 int n0 = (n > 0 ? n : 0); | 1073 int n0 = (n > 0 ? n : 0); |
1025 int n1 = n0 + 2; // indentation | 1074 int n1 = n0 + 2; // indentation |
1026 | 1075 |
1027 // Print header. | 1076 // Print header. |
1028 Indent(n0, Header(scope_type_, function_kind_, is_declaration_scope())); | 1077 FunctionKind function_kind = is_function_scope() |
1078 ? AsDeclarationScope()->function_kind() | |
1079 : kNormalFunction; | |
marja
2016/08/05 07:00:38
It's slightly weird that we pass kNormalFunction i
| |
1080 Indent(n0, Header(scope_type_, function_kind, is_declaration_scope())); | |
1029 if (scope_name_ != nullptr && !scope_name_->IsEmpty()) { | 1081 if (scope_name_ != nullptr && !scope_name_->IsEmpty()) { |
1030 PrintF(" "); | 1082 PrintF(" "); |
1031 PrintName(scope_name_); | 1083 PrintName(scope_name_); |
1032 } | 1084 } |
1033 | 1085 |
1034 // Print parameters, if any. | 1086 // Print parameters, if any. |
1087 VariableDeclaration* function = nullptr; | |
1035 if (is_function_scope()) { | 1088 if (is_function_scope()) { |
1036 PrintF(" ("); | 1089 AsDeclarationScope()->PrintParameters(); |
1037 for (int i = 0; i < params_.length(); i++) { | 1090 function = AsDeclarationScope()->function(); |
1038 if (i > 0) PrintF(", "); | |
1039 const AstRawString* name = params_[i]->raw_name(); | |
1040 if (name->IsEmpty()) | |
1041 PrintF(".%p", reinterpret_cast<void*>(params_[i])); | |
1042 else | |
1043 PrintName(name); | |
1044 } | |
1045 PrintF(")"); | |
1046 } | 1091 } |
1047 | 1092 |
1048 PrintF(" { // (%d, %d)\n", start_position(), end_position()); | 1093 PrintF(" { // (%d, %d)\n", start_position(), end_position()); |
1049 | 1094 |
1050 // Function name, if any (named function literals, only). | 1095 // Function name, if any (named function literals, only). |
1051 if (function_ != NULL) { | 1096 if (function != nullptr) { |
1052 Indent(n1, "// (local) function name: "); | 1097 Indent(n1, "// (local) function name: "); |
1053 PrintName(function_->proxy()->raw_name()); | 1098 PrintName(function->proxy()->raw_name()); |
1054 PrintF("\n"); | 1099 PrintF("\n"); |
1055 } | 1100 } |
1056 | 1101 |
1057 // Scope info. | 1102 // Scope info. |
1058 if (HasTrivialOuterContext()) { | 1103 if (HasTrivialOuterContext()) { |
1059 Indent(n1, "// scope has trivial outer context\n"); | 1104 Indent(n1, "// scope has trivial outer context\n"); |
1060 } | 1105 } |
1061 if (is_strict(language_mode())) { | 1106 if (is_strict(language_mode())) { |
1062 Indent(n1, "// strict mode scope\n"); | 1107 Indent(n1, "// strict mode scope\n"); |
1063 } | 1108 } |
(...skipping 11 matching lines...) Expand all Loading... | |
1075 Indent(n1, "// "); | 1120 Indent(n1, "// "); |
1076 PrintF("%d stack slots\n", num_stack_slots_); | 1121 PrintF("%d stack slots\n", num_stack_slots_); |
1077 } | 1122 } |
1078 if (num_heap_slots_ > 0) { | 1123 if (num_heap_slots_ > 0) { |
1079 Indent(n1, "// "); | 1124 Indent(n1, "// "); |
1080 PrintF("%d heap slots (including %d global slots)\n", num_heap_slots_, | 1125 PrintF("%d heap slots (including %d global slots)\n", num_heap_slots_, |
1081 num_global_slots_); | 1126 num_global_slots_); |
1082 } | 1127 } |
1083 | 1128 |
1084 // Print locals. | 1129 // Print locals. |
1085 if (function_ != NULL) { | 1130 if (function != nullptr) { |
1086 Indent(n1, "// function var:\n"); | 1131 Indent(n1, "// function var:\n"); |
1087 PrintVar(n1, function_->proxy()->var()); | 1132 PrintVar(n1, function->proxy()->var()); |
1088 } | 1133 } |
1089 | 1134 |
1090 if (temps_.length() > 0) { | 1135 if (is_declaration_scope()) { |
1091 bool printed_header = false; | 1136 bool printed_header = false; |
1092 for (int i = 0; i < temps_.length(); i++) { | 1137 ZoneList<Variable*>* temps = AsDeclarationScope()->temps(); |
1093 if (temps_[i] != nullptr) { | 1138 for (int i = 0; i < temps->length(); i++) { |
1139 if ((*temps)[i] != nullptr) { | |
1094 if (!printed_header) { | 1140 if (!printed_header) { |
1095 printed_header = true; | 1141 printed_header = true; |
1096 Indent(n1, "// temporary vars:\n"); | 1142 Indent(n1, "// temporary vars:\n"); |
1097 } | 1143 } |
1098 PrintVar(n1, temps_[i]); | 1144 PrintVar(n1, (*temps)[i]); |
1099 } | 1145 } |
1100 } | 1146 } |
1101 } | 1147 } |
1102 | 1148 |
1103 if (variables_.Start() != NULL) { | 1149 if (variables_.Start() != NULL) { |
1104 Indent(n1, "// local vars:\n"); | 1150 Indent(n1, "// local vars:\n"); |
1105 PrintMap(n1, &variables_); | 1151 PrintMap(n1, &variables_); |
1106 } | 1152 } |
1107 | 1153 |
1108 if (dynamics_ != NULL) { | 1154 if (dynamics_ != NULL) { |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1179 Variable* var = LookupLocal(proxy->raw_name()); | 1225 Variable* var = LookupLocal(proxy->raw_name()); |
1180 | 1226 |
1181 // We found a variable and we are done. (Even if there is an 'eval' in | 1227 // We found a variable and we are done. (Even if there is an 'eval' in |
1182 // this scope which introduces the same variable again, the resulting | 1228 // this scope which introduces the same variable again, the resulting |
1183 // variable remains the same.) | 1229 // variable remains the same.) |
1184 if (var != NULL) { | 1230 if (var != NULL) { |
1185 *binding_kind = BOUND; | 1231 *binding_kind = BOUND; |
1186 return var; | 1232 return var; |
1187 } | 1233 } |
1188 | 1234 |
1189 // We did not find a variable locally. Check against the function variable, | 1235 // We did not find a variable locally. Check against the function variable, if |
1190 // if any. We can do this for all scopes, since the function variable is | 1236 // any. |
1191 // only present - if at all - for function scopes. | |
1192 *binding_kind = UNBOUND; | 1237 *binding_kind = UNBOUND; |
1193 var = LookupFunctionVar(proxy->raw_name(), factory); | 1238 var = |
1239 is_function_scope() | |
1240 ? AsDeclarationScope()->LookupFunctionVar(proxy->raw_name(), factory) | |
1241 : nullptr; | |
1194 if (var != NULL) { | 1242 if (var != NULL) { |
1195 *binding_kind = BOUND; | 1243 *binding_kind = BOUND; |
1196 } else if (outer_scope_ != nullptr && this != max_outer_scope) { | 1244 } else if (outer_scope_ != nullptr && this != max_outer_scope) { |
1197 var = outer_scope_->LookupRecursive(proxy, binding_kind, factory, | 1245 var = outer_scope_->LookupRecursive(proxy, binding_kind, factory, |
1198 max_outer_scope); | 1246 max_outer_scope); |
1199 if (*binding_kind == BOUND && (is_function_scope() || is_with_scope())) { | 1247 if (*binding_kind == BOUND && (is_function_scope() || is_with_scope())) { |
1200 var->ForceContextAllocation(); | 1248 var->ForceContextAllocation(); |
1201 } | 1249 } |
1202 } else { | 1250 } else { |
1203 DCHECK(is_script_scope() || this == max_outer_scope); | 1251 DCHECK(is_script_scope() || this == max_outer_scope); |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1406 if (var->mode() == TEMPORARY) return false; | 1454 if (var->mode() == TEMPORARY) return false; |
1407 if (is_catch_scope() || is_module_scope()) return true; | 1455 if (is_catch_scope() || is_module_scope()) return true; |
1408 if (is_script_scope() && IsLexicalVariableMode(var->mode())) return true; | 1456 if (is_script_scope() && IsLexicalVariableMode(var->mode())) return true; |
1409 return var->has_forced_context_allocation() || scope_calls_eval_ || | 1457 return var->has_forced_context_allocation() || scope_calls_eval_ || |
1410 inner_scope_calls_eval_; | 1458 inner_scope_calls_eval_; |
1411 } | 1459 } |
1412 | 1460 |
1413 | 1461 |
1414 void Scope::AllocateStackSlot(Variable* var) { | 1462 void Scope::AllocateStackSlot(Variable* var) { |
1415 if (is_block_scope()) { | 1463 if (is_block_scope()) { |
1416 outer_scope()->DeclarationScope()->AllocateStackSlot(var); | 1464 outer_scope()->GetDeclarationScope()->AllocateStackSlot(var); |
1417 } else { | 1465 } else { |
1418 var->AllocateTo(VariableLocation::LOCAL, num_stack_slots_++); | 1466 var->AllocateTo(VariableLocation::LOCAL, num_stack_slots_++); |
1419 } | 1467 } |
1420 } | 1468 } |
1421 | 1469 |
1422 | 1470 |
1423 void Scope::AllocateHeapSlot(Variable* var) { | 1471 void Scope::AllocateHeapSlot(Variable* var) { |
1424 var->AllocateTo(VariableLocation::CONTEXT, num_heap_slots_++); | 1472 var->AllocateTo(VariableLocation::CONTEXT, num_heap_slots_++); |
1425 } | 1473 } |
1426 | 1474 |
1427 void Scope::AllocateParameterLocals() { | 1475 void DeclarationScope::AllocateParameterLocals() { |
1428 DCHECK(is_function_scope()); | 1476 DCHECK(is_function_scope()); |
1429 | 1477 |
1430 bool uses_sloppy_arguments = false; | 1478 bool uses_sloppy_arguments = false; |
1431 | 1479 |
1432 // Functions have 'arguments' declared implicitly in all non arrow functions. | 1480 // Functions have 'arguments' declared implicitly in all non arrow functions. |
1433 if (arguments_ != nullptr) { | 1481 if (arguments_ != nullptr) { |
1434 // 'arguments' is used. Unless there is also a parameter called | 1482 // 'arguments' is used. Unless there is also a parameter called |
1435 // 'arguments', we must be conservative and allocate all parameters to | 1483 // 'arguments', we must be conservative and allocate all parameters to |
1436 // the context assuming they will be captured by the arguments object. | 1484 // the context assuming they will be captured by the arguments object. |
1437 // If we have a parameter named 'arguments', a (new) value is always | 1485 // If we have a parameter named 'arguments', a (new) value is always |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1470 | 1518 |
1471 DCHECK(var->scope() == this); | 1519 DCHECK(var->scope() == this); |
1472 if (uses_sloppy_arguments || has_forced_context_allocation()) { | 1520 if (uses_sloppy_arguments || has_forced_context_allocation()) { |
1473 // Force context allocation of the parameter. | 1521 // Force context allocation of the parameter. |
1474 var->ForceContextAllocation(); | 1522 var->ForceContextAllocation(); |
1475 } | 1523 } |
1476 AllocateParameter(var, i); | 1524 AllocateParameter(var, i); |
1477 } | 1525 } |
1478 } | 1526 } |
1479 | 1527 |
1480 | 1528 void DeclarationScope::AllocateParameter(Variable* var, int index) { |
1481 void Scope::AllocateParameter(Variable* var, int index) { | |
1482 if (MustAllocate(var)) { | 1529 if (MustAllocate(var)) { |
1483 if (MustAllocateInContext(var)) { | 1530 if (MustAllocateInContext(var)) { |
1484 DCHECK(var->IsUnallocated() || var->IsContextSlot()); | 1531 DCHECK(var->IsUnallocated() || var->IsContextSlot()); |
1485 if (var->IsUnallocated()) { | 1532 if (var->IsUnallocated()) { |
1486 AllocateHeapSlot(var); | 1533 AllocateHeapSlot(var); |
1487 } | 1534 } |
1488 } else { | 1535 } else { |
1489 DCHECK(var->IsUnallocated() || var->IsParameter()); | 1536 DCHECK(var->IsUnallocated() || var->IsParameter()); |
1490 if (var->IsUnallocated()) { | 1537 if (var->IsUnallocated()) { |
1491 var->AllocateTo(VariableLocation::PARAMETER, index); | 1538 var->AllocateTo(VariableLocation::PARAMETER, index); |
1492 } | 1539 } |
1493 } | 1540 } |
1494 } else { | 1541 } else { |
1495 DCHECK(!var->IsGlobalSlot()); | 1542 DCHECK(!var->IsGlobalSlot()); |
1496 } | 1543 } |
1497 } | 1544 } |
1498 | 1545 |
1499 | 1546 void DeclarationScope::AllocateReceiver() { |
1500 void Scope::AllocateReceiver() { | 1547 if (!has_this_declaration()) return; |
1501 DCHECK_NOT_NULL(receiver()); | 1548 DCHECK_NOT_NULL(receiver()); |
1502 DCHECK_EQ(receiver()->scope(), this); | 1549 DCHECK_EQ(receiver()->scope(), this); |
1503 | 1550 |
1504 if (has_forced_context_allocation()) { | 1551 if (has_forced_context_allocation()) { |
1505 // Force context allocation of the receiver. | 1552 // Force context allocation of the receiver. |
1506 receiver()->ForceContextAllocation(); | 1553 receiver()->ForceContextAllocation(); |
1507 } | 1554 } |
1508 AllocateParameter(receiver(), -1); | 1555 AllocateParameter(receiver(), -1); |
1509 } | 1556 } |
1510 | 1557 |
(...skipping 25 matching lines...) Expand all Loading... | |
1536 } else { | 1583 } else { |
1537 // There must be only DYNAMIC_GLOBAL in the script scope. | 1584 // There must be only DYNAMIC_GLOBAL in the script scope. |
1538 DCHECK(!is_script_scope() || DYNAMIC_GLOBAL == var->mode()); | 1585 DCHECK(!is_script_scope() || DYNAMIC_GLOBAL == var->mode()); |
1539 } | 1586 } |
1540 } | 1587 } |
1541 } | 1588 } |
1542 | 1589 |
1543 void Scope::AllocateNonParameterLocalsAndDeclaredGlobals( | 1590 void Scope::AllocateNonParameterLocalsAndDeclaredGlobals( |
1544 AstValueFactory* ast_value_factory) { | 1591 AstValueFactory* ast_value_factory) { |
1545 // All variables that have no rewrite yet are non-parameter locals. | 1592 // All variables that have no rewrite yet are non-parameter locals. |
1546 for (int i = 0; i < temps_.length(); i++) { | 1593 if (is_declaration_scope()) { |
1547 if (temps_[i] == nullptr) continue; | 1594 ZoneList<Variable*>* temps = AsDeclarationScope()->temps(); |
1548 AllocateNonParameterLocal(temps_[i], ast_value_factory); | 1595 for (int i = 0; i < temps->length(); i++) { |
1596 if ((*temps)[i] == nullptr) continue; | |
1597 AllocateNonParameterLocal((*temps)[i], ast_value_factory); | |
1598 } | |
1549 } | 1599 } |
1550 | 1600 |
1551 ZoneList<VarAndOrder> vars(variables_.occupancy(), zone()); | 1601 ZoneList<VarAndOrder> vars(variables_.occupancy(), zone()); |
1552 for (VariableMap::Entry* p = variables_.Start(); | 1602 for (VariableMap::Entry* p = variables_.Start(); |
1553 p != NULL; | 1603 p != NULL; |
1554 p = variables_.Next(p)) { | 1604 p = variables_.Next(p)) { |
1555 Variable* var = reinterpret_cast<Variable*>(p->value); | 1605 Variable* var = reinterpret_cast<Variable*>(p->value); |
1556 vars.Add(VarAndOrder(var, p->order), zone()); | 1606 vars.Add(VarAndOrder(var, p->order), zone()); |
1557 } | 1607 } |
1558 vars.Sort(VarAndOrder::Compare); | 1608 vars.Sort(VarAndOrder::Compare); |
1559 int var_count = vars.length(); | 1609 int var_count = vars.length(); |
1560 for (int i = 0; i < var_count; i++) { | 1610 for (int i = 0; i < var_count; i++) { |
1561 AllocateNonParameterLocal(vars[i].var(), ast_value_factory); | 1611 AllocateNonParameterLocal(vars[i].var(), ast_value_factory); |
1562 } | 1612 } |
1563 | 1613 |
1564 if (FLAG_global_var_shortcuts) { | 1614 if (FLAG_global_var_shortcuts) { |
1565 for (int i = 0; i < var_count; i++) { | 1615 for (int i = 0; i < var_count; i++) { |
1566 AllocateDeclaredGlobal(vars[i].var(), ast_value_factory); | 1616 AllocateDeclaredGlobal(vars[i].var(), ast_value_factory); |
1567 } | 1617 } |
1568 } | 1618 } |
1569 | 1619 |
1620 if (is_declaration_scope()) { | |
1621 AsDeclarationScope()->AllocateLocals(ast_value_factory); | |
1622 } | |
1623 } | |
1624 | |
1625 void DeclarationScope::AllocateLocals(AstValueFactory* ast_value_factory) { | |
1570 // For now, function_ must be allocated at the very end. If it gets | 1626 // For now, function_ must be allocated at the very end. If it gets |
1571 // allocated in the context, it must be the last slot in the context, | 1627 // allocated in the context, it must be the last slot in the context, |
1572 // because of the current ScopeInfo implementation (see | 1628 // because of the current ScopeInfo implementation (see |
1573 // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor). | 1629 // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor). |
1574 if (function_ != nullptr) { | 1630 if (function_ != nullptr) { |
1575 AllocateNonParameterLocal(function_->proxy()->var(), ast_value_factory); | 1631 AllocateNonParameterLocal(function_->proxy()->var(), ast_value_factory); |
1576 } | 1632 } |
1577 | 1633 |
1578 if (rest_parameter_ != nullptr) { | 1634 if (rest_parameter_ != nullptr) { |
1579 AllocateNonParameterLocal(rest_parameter_, ast_value_factory); | 1635 AllocateNonParameterLocal(rest_parameter_, ast_value_factory); |
(...skipping 18 matching lines...) Expand all Loading... | |
1598 } | 1654 } |
1599 | 1655 |
1600 // If scope is already resolved, we still need to allocate | 1656 // If scope is already resolved, we still need to allocate |
1601 // variables in inner scopes which might not have been resolved yet. | 1657 // variables in inner scopes which might not have been resolved yet. |
1602 if (already_resolved()) return; | 1658 if (already_resolved()) return; |
1603 // The number of slots required for variables. | 1659 // The number of slots required for variables. |
1604 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; | 1660 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; |
1605 | 1661 |
1606 // Allocate variables for this scope. | 1662 // Allocate variables for this scope. |
1607 // Parameters must be allocated first, if any. | 1663 // Parameters must be allocated first, if any. |
1608 if (is_function_scope()) AllocateParameterLocals(); | 1664 if (is_declaration_scope()) { |
1609 if (has_this_declaration()) AllocateReceiver(); | 1665 if (is_function_scope()) AsDeclarationScope()->AllocateParameterLocals(); |
1666 AsDeclarationScope()->AllocateReceiver(); | |
1667 } | |
1610 AllocateNonParameterLocalsAndDeclaredGlobals(ast_value_factory); | 1668 AllocateNonParameterLocalsAndDeclaredGlobals(ast_value_factory); |
1611 | 1669 |
1612 // Force allocation of a context for this scope if necessary. For a 'with' | 1670 // Force allocation of a context for this scope if necessary. For a 'with' |
1613 // scope and for a function scope that makes an 'eval' call we need a context, | 1671 // scope and for a function scope that makes an 'eval' call we need a context, |
1614 // even if no local variables were statically allocated in the scope. | 1672 // even if no local variables were statically allocated in the scope. |
1615 // Likewise for modules. | 1673 // Likewise for modules. |
1616 bool must_have_context = | 1674 bool must_have_context = |
1617 is_with_scope() || is_module_scope() || | 1675 is_with_scope() || is_module_scope() || |
1618 (is_function_scope() && calls_sloppy_eval()) || | 1676 (is_function_scope() && calls_sloppy_eval()) || |
1619 (is_block_scope() && is_declaration_scope() && calls_sloppy_eval()); | 1677 (is_block_scope() && is_declaration_scope() && calls_sloppy_eval()); |
1620 | 1678 |
1621 // If we didn't allocate any locals in the local context, then we only | 1679 // If we didn't allocate any locals in the local context, then we only |
1622 // need the minimal number of slots if we must have a context. | 1680 // need the minimal number of slots if we must have a context. |
1623 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && !must_have_context) { | 1681 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && !must_have_context) { |
1624 num_heap_slots_ = 0; | 1682 num_heap_slots_ = 0; |
1625 } | 1683 } |
1626 | 1684 |
1627 // Allocation done. | 1685 // Allocation done. |
1628 DCHECK(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); | 1686 DCHECK(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); |
1629 } | 1687 } |
1630 | 1688 |
1631 | 1689 |
1632 int Scope::StackLocalCount() const { | 1690 int Scope::StackLocalCount() const { |
1691 VariableDeclaration* function = | |
1692 is_function_scope() ? AsDeclarationScope()->function() : nullptr; | |
1633 return num_stack_slots() - | 1693 return num_stack_slots() - |
1634 (function_ != NULL && function_->proxy()->var()->IsStackLocal() ? 1 : 0); | 1694 (function != NULL && function->proxy()->var()->IsStackLocal() ? 1 : 0); |
1635 } | 1695 } |
1636 | 1696 |
1637 | 1697 |
1638 int Scope::ContextLocalCount() const { | 1698 int Scope::ContextLocalCount() const { |
1639 if (num_heap_slots() == 0) return 0; | 1699 if (num_heap_slots() == 0) return 0; |
1700 VariableDeclaration* function = | |
1701 is_function_scope() ? AsDeclarationScope()->function() : nullptr; | |
1640 bool is_function_var_in_context = | 1702 bool is_function_var_in_context = |
1641 function_ != NULL && function_->proxy()->var()->IsContextSlot(); | 1703 function != NULL && function->proxy()->var()->IsContextSlot(); |
1642 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - | 1704 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - |
1643 (is_function_var_in_context ? 1 : 0); | 1705 (is_function_var_in_context ? 1 : 0); |
1644 } | 1706 } |
1645 | 1707 |
1646 | 1708 |
1647 int Scope::ContextGlobalCount() const { return num_global_slots(); } | 1709 int Scope::ContextGlobalCount() const { return num_global_slots(); } |
1648 | 1710 |
1649 } // namespace internal | 1711 } // namespace internal |
1650 } // namespace v8 | 1712 } // namespace v8 |
OLD | NEW |