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 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
76 p->value = new (zone_->New(sizeof(Vector))) Vector(zone_); | 76 p->value = new (zone_->New(sizeof(Vector))) Vector(zone_); |
77 } | 77 } |
78 Vector* delegates = static_cast<Vector*>(p->value); | 78 Vector* delegates = static_cast<Vector*>(p->value); |
79 delegates->push_back(stmt); | 79 delegates->push_back(stmt); |
80 } | 80 } |
81 | 81 |
82 | 82 |
83 // ---------------------------------------------------------------------------- | 83 // ---------------------------------------------------------------------------- |
84 // Implementation of Scope | 84 // Implementation of Scope |
85 | 85 |
86 Scope::Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type) | 86 Scope::Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type, |
| 87 FunctionKind function_kind) |
87 : outer_scope_(outer_scope), | 88 : outer_scope_(outer_scope), |
88 variables_(zone), | 89 variables_(zone), |
| 90 temps_(4, zone), |
| 91 params_(4, zone), |
89 decls_(4, zone), | 92 decls_(4, zone), |
| 93 module_descriptor_(scope_type == MODULE_SCOPE ? new (zone) |
| 94 ModuleDescriptor(zone) |
| 95 : NULL), |
| 96 sloppy_block_function_map_(zone), |
90 scope_type_(scope_type), | 97 scope_type_(scope_type), |
| 98 function_kind_(function_kind), |
91 already_resolved_(false) { | 99 already_resolved_(false) { |
92 SetDefaults(); | 100 SetDefaults(); |
93 if (outer_scope == nullptr) { | 101 if (outer_scope == nullptr) { |
94 // If the outer scope is null, this cannot be a with scope. The outermost | 102 // If the outer scope is null, this cannot be a with scope. The outermost |
95 // scope must be a script scope. | 103 // scope must be a script scope. |
96 DCHECK_EQ(SCRIPT_SCOPE, scope_type); | 104 DCHECK_EQ(SCRIPT_SCOPE, scope_type); |
97 } else { | 105 } else { |
98 asm_function_ = outer_scope_->asm_module_; | 106 asm_function_ = outer_scope_->asm_module_; |
99 // Inherit the language mode from the parent scope unless we're a module | 107 // Inherit the language mode from the parent scope unless we're a module |
100 // scope. | 108 // scope. |
101 if (!is_module_scope()) language_mode_ = outer_scope->language_mode_; | 109 if (!is_module_scope()) language_mode_ = outer_scope->language_mode_; |
102 force_context_allocation_ = | 110 force_context_allocation_ = |
103 !is_function_scope() && outer_scope->has_forced_context_allocation(); | 111 !is_function_scope() && outer_scope->has_forced_context_allocation(); |
104 outer_scope_->AddInnerScope(this); | 112 outer_scope_->AddInnerScope(this); |
105 scope_inside_with_ = outer_scope_->scope_inside_with_ || is_with_scope(); | 113 scope_inside_with_ = outer_scope_->scope_inside_with_ || is_with_scope(); |
106 } | 114 } |
107 } | 115 } |
108 | 116 |
109 Scope::Snapshot::Snapshot(Scope* scope) | |
110 : outer_scope_(scope), | |
111 top_inner_scope_(scope->inner_scope_), | |
112 top_unresolved_(scope->unresolved_), | |
113 top_temp_(scope->GetClosureScope()->temps()->length()) {} | |
114 | |
115 DeclarationScope::DeclarationScope(Zone* zone, Scope* outer_scope, | |
116 ScopeType scope_type, | |
117 FunctionKind function_kind) | |
118 : Scope(zone, outer_scope, scope_type), | |
119 function_kind_(function_kind), | |
120 temps_(4, zone), | |
121 params_(4, zone), | |
122 sloppy_block_function_map_(zone), | |
123 module_descriptor_(scope_type == MODULE_SCOPE ? new (zone) | |
124 ModuleDescriptor(zone) | |
125 : NULL) { | |
126 SetDefaults(); | |
127 } | |
128 | |
129 Scope::Scope(Zone* zone, Scope* inner_scope, ScopeType scope_type, | 117 Scope::Scope(Zone* zone, Scope* inner_scope, ScopeType scope_type, |
130 Handle<ScopeInfo> scope_info) | 118 Handle<ScopeInfo> scope_info) |
131 : outer_scope_(nullptr), | 119 : outer_scope_(nullptr), |
132 variables_(zone), | 120 variables_(zone), |
| 121 temps_(4, zone), |
| 122 params_(4, zone), |
133 decls_(4, zone), | 123 decls_(4, zone), |
134 scope_info_(scope_info), | 124 module_descriptor_(nullptr), |
| 125 sloppy_block_function_map_(zone), |
135 scope_type_(scope_type), | 126 scope_type_(scope_type), |
136 already_resolved_(true) { | 127 function_kind_(scope_info.is_null() ? kNormalFunction |
| 128 : scope_info->function_kind()), |
| 129 already_resolved_(true), |
| 130 scope_info_(scope_info) { |
137 SetDefaults(); | 131 SetDefaults(); |
138 if (!scope_info.is_null()) { | 132 if (!scope_info.is_null()) { |
139 scope_calls_eval_ = scope_info->CallsEval(); | 133 scope_calls_eval_ = scope_info->CallsEval(); |
140 language_mode_ = scope_info->language_mode(); | 134 language_mode_ = scope_info->language_mode(); |
| 135 is_declaration_scope_ = scope_info->is_declaration_scope(); |
141 num_heap_slots_ = scope_info_->ContextLength(); | 136 num_heap_slots_ = scope_info_->ContextLength(); |
142 } | 137 } |
143 // Ensure at least MIN_CONTEXT_SLOTS to indicate a materialized context. | 138 // Ensure at least MIN_CONTEXT_SLOTS to indicate a materialized context. |
144 num_heap_slots_ = Max(num_heap_slots_, | 139 num_heap_slots_ = Max(num_heap_slots_, |
145 static_cast<int>(Context::MIN_CONTEXT_SLOTS)); | 140 static_cast<int>(Context::MIN_CONTEXT_SLOTS)); |
146 AddInnerScope(inner_scope); | 141 AddInnerScope(inner_scope); |
147 } | 142 } |
148 | 143 |
149 DeclarationScope::DeclarationScope(Zone* zone, Scope* inner_scope, | |
150 ScopeType scope_type, | |
151 Handle<ScopeInfo> scope_info) | |
152 : Scope(zone, inner_scope, scope_type, scope_info), | |
153 function_kind_(scope_info.is_null() ? kNormalFunction | |
154 : scope_info->function_kind()), | |
155 temps_(4, zone), | |
156 params_(4, zone), | |
157 sloppy_block_function_map_(zone), | |
158 module_descriptor_(nullptr) { | |
159 SetDefaults(); | |
160 } | |
161 | |
162 Scope::Scope(Zone* zone, Scope* inner_scope, | 144 Scope::Scope(Zone* zone, Scope* inner_scope, |
163 const AstRawString* catch_variable_name) | 145 const AstRawString* catch_variable_name) |
164 : outer_scope_(nullptr), | 146 : outer_scope_(nullptr), |
165 variables_(zone), | 147 variables_(zone), |
| 148 temps_(0, zone), |
| 149 params_(0, zone), |
166 decls_(0, zone), | 150 decls_(0, zone), |
| 151 module_descriptor_(nullptr), |
| 152 sloppy_block_function_map_(zone), |
167 scope_type_(CATCH_SCOPE), | 153 scope_type_(CATCH_SCOPE), |
| 154 function_kind_(kNormalFunction), |
168 already_resolved_(true) { | 155 already_resolved_(true) { |
169 SetDefaults(); | 156 SetDefaults(); |
170 AddInnerScope(inner_scope); | 157 AddInnerScope(inner_scope); |
171 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; | 158 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; |
172 Variable* variable = variables_.Declare(this, | 159 Variable* variable = variables_.Declare(this, |
173 catch_variable_name, | 160 catch_variable_name, |
174 VAR, | 161 VAR, |
175 Variable::NORMAL, | 162 Variable::NORMAL, |
176 kCreatedInitialized); | 163 kCreatedInitialized); |
177 AllocateHeapSlot(variable); | 164 AllocateHeapSlot(variable); |
178 } | 165 } |
179 | 166 |
180 void DeclarationScope::SetDefaults() { | 167 void Scope::SetDefaults() { |
181 is_declaration_scope_ = true; | 168 is_declaration_scope_ = |
| 169 is_eval_scope() || is_function_scope() || |
| 170 is_module_scope() || is_script_scope(); |
| 171 inner_scope_ = nullptr; |
| 172 sibling_ = nullptr; |
| 173 unresolved_ = nullptr; |
| 174 #ifdef DEBUG |
| 175 scope_name_ = nullptr; |
| 176 #endif |
| 177 dynamics_ = nullptr; |
182 receiver_ = nullptr; | 178 receiver_ = nullptr; |
183 new_target_ = nullptr; | 179 new_target_ = nullptr; |
184 function_ = nullptr; | 180 function_ = nullptr; |
185 arguments_ = nullptr; | 181 arguments_ = nullptr; |
186 this_function_ = nullptr; | 182 this_function_ = nullptr; |
187 arity_ = 0; | |
188 has_simple_parameters_ = true; | |
189 rest_parameter_ = NULL; | |
190 rest_index_ = -1; | |
191 } | |
192 | |
193 void Scope::SetDefaults() { | |
194 #ifdef DEBUG | |
195 scope_name_ = nullptr; | |
196 #endif | |
197 is_declaration_scope_ = false; | |
198 inner_scope_ = nullptr; | |
199 sibling_ = nullptr; | |
200 unresolved_ = nullptr; | |
201 dynamics_ = nullptr; | |
202 scope_inside_with_ = false; | 183 scope_inside_with_ = false; |
203 scope_calls_eval_ = false; | 184 scope_calls_eval_ = false; |
204 has_arguments_parameter_ = false; | 185 has_arguments_parameter_ = false; |
205 scope_uses_super_property_ = false; | 186 scope_uses_super_property_ = false; |
206 asm_module_ = false; | 187 asm_module_ = false; |
207 asm_function_ = false; | 188 asm_function_ = false; |
208 language_mode_ = is_module_scope() ? STRICT : SLOPPY; | 189 language_mode_ = is_module_scope() ? STRICT : SLOPPY; |
209 outer_scope_calls_sloppy_eval_ = false; | 190 outer_scope_calls_sloppy_eval_ = false; |
210 inner_scope_calls_eval_ = false; | 191 inner_scope_calls_eval_ = false; |
211 scope_nonlinear_ = false; | 192 scope_nonlinear_ = false; |
212 force_eager_compilation_ = false; | 193 force_eager_compilation_ = false; |
213 force_context_allocation_ = false; | 194 force_context_allocation_ = false; |
214 num_stack_slots_ = 0; | 195 num_stack_slots_ = 0; |
215 num_heap_slots_ = 0; | 196 num_heap_slots_ = 0; |
216 num_global_slots_ = 0; | 197 num_global_slots_ = 0; |
| 198 arity_ = 0; |
| 199 has_simple_parameters_ = true; |
| 200 rest_parameter_ = NULL; |
| 201 rest_index_ = -1; |
217 start_position_ = kNoSourcePosition; | 202 start_position_ = kNoSourcePosition; |
218 end_position_ = kNoSourcePosition; | 203 end_position_ = kNoSourcePosition; |
219 is_hidden_ = false; | 204 is_hidden_ = false; |
220 } | 205 } |
221 | 206 |
222 bool Scope::HasSimpleParameters() { | |
223 DeclarationScope* scope = GetClosureScope(); | |
224 return !scope->is_function_scope() || scope->has_simple_parameters(); | |
225 } | |
226 | |
227 Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone, | 207 Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone, |
228 Context* context, Scope* script_scope, | 208 Context* context, Scope* script_scope, |
229 AstValueFactory* ast_value_factory, | 209 AstValueFactory* ast_value_factory, |
230 DeserializationMode deserialization_mode) { | 210 DeserializationMode deserialization_mode) { |
231 // Reconstruct the outer scope chain from a closure's context chain. | 211 // Reconstruct the outer scope chain from a closure's context chain. |
232 Scope* current_scope = NULL; | 212 Scope* current_scope = NULL; |
233 Scope* innermost_scope = NULL; | 213 Scope* innermost_scope = NULL; |
234 while (!context->IsNativeContext()) { | 214 while (!context->IsNativeContext()) { |
235 if (context->IsWithContext() || context->IsDebugEvaluateContext()) { | 215 if (context->IsWithContext() || context->IsDebugEvaluateContext()) { |
236 // For scope analysis, debug-evaluate is equivalent to a with scope. | 216 // For scope analysis, debug-evaluate is equivalent to a with scope. |
237 Scope* with_scope = new (zone) | 217 Scope* with_scope = new (zone) |
238 Scope(zone, current_scope, WITH_SCOPE, Handle<ScopeInfo>::null()); | 218 Scope(zone, current_scope, WITH_SCOPE, Handle<ScopeInfo>::null()); |
239 current_scope = with_scope; | 219 current_scope = with_scope; |
240 // All the inner scopes are inside a with. | 220 // All the inner scopes are inside a with. |
241 for (Scope* s = innermost_scope; s != NULL; s = s->outer_scope()) { | 221 for (Scope* s = innermost_scope; s != NULL; s = s->outer_scope()) { |
242 s->scope_inside_with_ = true; | 222 s->scope_inside_with_ = true; |
243 } | 223 } |
244 } else if (context->IsScriptContext()) { | 224 } else if (context->IsScriptContext()) { |
245 ScopeInfo* scope_info = context->scope_info(); | 225 ScopeInfo* scope_info = context->scope_info(); |
246 current_scope = new (zone) DeclarationScope( | 226 current_scope = new (zone) Scope(zone, current_scope, SCRIPT_SCOPE, |
247 zone, current_scope, SCRIPT_SCOPE, Handle<ScopeInfo>(scope_info)); | 227 Handle<ScopeInfo>(scope_info)); |
248 } else if (context->IsFunctionContext()) { | 228 } else if (context->IsFunctionContext()) { |
249 ScopeInfo* scope_info = context->closure()->shared()->scope_info(); | 229 ScopeInfo* scope_info = context->closure()->shared()->scope_info(); |
250 current_scope = new (zone) DeclarationScope( | 230 current_scope = new (zone) Scope(zone, current_scope, FUNCTION_SCOPE, |
251 zone, current_scope, FUNCTION_SCOPE, Handle<ScopeInfo>(scope_info)); | 231 Handle<ScopeInfo>(scope_info)); |
252 if (scope_info->IsAsmFunction()) current_scope->asm_function_ = true; | 232 if (scope_info->IsAsmFunction()) current_scope->asm_function_ = true; |
253 if (scope_info->IsAsmModule()) current_scope->asm_module_ = true; | 233 if (scope_info->IsAsmModule()) current_scope->asm_module_ = true; |
254 } else if (context->IsBlockContext()) { | 234 } else if (context->IsBlockContext()) { |
255 ScopeInfo* scope_info = context->scope_info(); | 235 ScopeInfo* scope_info = context->scope_info(); |
256 if (scope_info->is_declaration_scope()) { | 236 current_scope = new (zone) Scope(zone, current_scope, BLOCK_SCOPE, |
257 current_scope = new (zone) DeclarationScope( | 237 Handle<ScopeInfo>(scope_info)); |
258 zone, current_scope, BLOCK_SCOPE, Handle<ScopeInfo>(scope_info)); | |
259 } else { | |
260 current_scope = new (zone) Scope(zone, current_scope, BLOCK_SCOPE, | |
261 Handle<ScopeInfo>(scope_info)); | |
262 } | |
263 } else { | 238 } else { |
264 DCHECK(context->IsCatchContext()); | 239 DCHECK(context->IsCatchContext()); |
265 String* name = context->catch_name(); | 240 String* name = context->catch_name(); |
266 current_scope = | 241 current_scope = |
267 new (zone) Scope(zone, current_scope, | 242 new (zone) Scope(zone, current_scope, |
268 ast_value_factory->GetString(handle(name, isolate))); | 243 ast_value_factory->GetString(handle(name, isolate))); |
269 } | 244 } |
270 if (deserialization_mode == DeserializationMode::kDeserializeOffHeap) { | 245 if (deserialization_mode == DeserializationMode::kDeserializeOffHeap) { |
271 current_scope->DeserializeScopeInfo(isolate, ast_value_factory); | 246 current_scope->DeserializeScopeInfo(isolate, ast_value_factory); |
272 } | 247 } |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
337 Handle<String> name_handle(scope_info_->FunctionName(), isolate); | 312 Handle<String> name_handle(scope_info_->FunctionName(), isolate); |
338 const AstRawString* name = ast_value_factory->GetString(name_handle); | 313 const AstRawString* name = ast_value_factory->GetString(name_handle); |
339 VariableMode mode; | 314 VariableMode mode; |
340 int index = scope_info_->FunctionContextSlotIndex(*name_handle, &mode); | 315 int index = scope_info_->FunctionContextSlotIndex(*name_handle, &mode); |
341 if (index >= 0) { | 316 if (index >= 0) { |
342 Variable* result = new (zone()) | 317 Variable* result = new (zone()) |
343 Variable(this, name, mode, Variable::NORMAL, kCreatedInitialized); | 318 Variable(this, name, mode, Variable::NORMAL, kCreatedInitialized); |
344 VariableProxy* proxy = factory.NewVariableProxy(result); | 319 VariableProxy* proxy = factory.NewVariableProxy(result); |
345 VariableDeclaration* declaration = | 320 VariableDeclaration* declaration = |
346 factory.NewVariableDeclaration(proxy, mode, this, kNoSourcePosition); | 321 factory.NewVariableDeclaration(proxy, mode, this, kNoSourcePosition); |
347 AsDeclarationScope()->DeclareFunctionVar(declaration); | 322 DeclareFunctionVar(declaration); |
348 result->AllocateTo(VariableLocation::CONTEXT, index); | 323 result->AllocateTo(VariableLocation::CONTEXT, index); |
349 } | 324 } |
350 } | 325 } |
351 | 326 |
352 scope_info_ = Handle<ScopeInfo>::null(); | 327 scope_info_ = Handle<ScopeInfo>::null(); |
353 } | 328 } |
354 | 329 |
355 DeclarationScope* Scope::AsDeclarationScope() { | |
356 DCHECK(is_declaration_scope()); | |
357 return static_cast<DeclarationScope*>(this); | |
358 } | |
359 | |
360 const DeclarationScope* Scope::AsDeclarationScope() const { | |
361 DCHECK(is_declaration_scope()); | |
362 return static_cast<const DeclarationScope*>(this); | |
363 } | |
364 | |
365 int Scope::num_parameters() const { | |
366 return is_declaration_scope() ? AsDeclarationScope()->num_parameters() : 0; | |
367 } | |
368 | |
369 bool Scope::Analyze(ParseInfo* info) { | 330 bool Scope::Analyze(ParseInfo* info) { |
370 DCHECK(info->literal() != NULL); | 331 DCHECK(info->literal() != NULL); |
371 DCHECK(info->scope() == NULL); | 332 DCHECK(info->scope() == NULL); |
372 DeclarationScope* scope = info->literal()->scope(); | 333 Scope* scope = info->literal()->scope(); |
373 DeclarationScope* top = scope; | 334 Scope* top = scope; |
374 | 335 |
375 // Traverse the scope tree up to the first unresolved scope or the global | 336 // Traverse the scope tree up to the first unresolved scope or the global |
376 // scope and start scope resolution and variable allocation from that scope. | 337 // scope and start scope resolution and variable allocation from that scope. |
377 // Such a scope is always a closure-scope, so always skip to the next closure | |
378 // scope. | |
379 while (!top->is_script_scope() && | 338 while (!top->is_script_scope() && |
380 !top->outer_scope()->already_resolved()) { | 339 !top->outer_scope()->already_resolved()) { |
381 top = top->outer_scope()->GetClosureScope(); | 340 top = top->outer_scope(); |
382 } | 341 } |
383 | 342 |
384 // Allocate the variables. | 343 // Allocate the variables. |
385 { | 344 { |
386 AstNodeFactory ast_node_factory(info->ast_value_factory()); | 345 AstNodeFactory ast_node_factory(info->ast_value_factory()); |
387 if (!top->AllocateVariables(info, &ast_node_factory)) return false; | 346 if (!top->AllocateVariables(info, &ast_node_factory)) { |
| 347 DCHECK(top->pending_error_handler_.has_pending_error()); |
| 348 top->pending_error_handler_.ThrowPendingError(info->isolate(), |
| 349 info->script()); |
| 350 return false; |
| 351 } |
388 } | 352 } |
389 | 353 |
390 #ifdef DEBUG | 354 #ifdef DEBUG |
391 if (info->script_is_native() ? FLAG_print_builtin_scopes | 355 if (info->script_is_native() ? FLAG_print_builtin_scopes |
392 : FLAG_print_scopes) { | 356 : FLAG_print_scopes) { |
393 scope->Print(); | 357 scope->Print(); |
394 } | 358 } |
395 scope->CheckScopePositions(); | 359 scope->CheckScopePositions(); |
396 scope->CheckZones(); | 360 scope->CheckZones(); |
397 #endif | 361 #endif |
398 | 362 |
399 info->set_scope(scope); | 363 info->set_scope(scope); |
400 return true; | 364 return true; |
401 } | 365 } |
402 | 366 |
403 void DeclarationScope::DeclareThis(AstValueFactory* ast_value_factory) { | 367 void Scope::DeclareThis(AstValueFactory* ast_value_factory) { |
404 DCHECK(!already_resolved()); | 368 DCHECK(!already_resolved()); |
405 DCHECK(is_declaration_scope()); | 369 DCHECK(is_declaration_scope()); |
406 DCHECK(has_this_declaration()); | 370 DCHECK(has_this_declaration()); |
407 | 371 |
408 bool subclass_constructor = IsSubclassConstructor(function_kind_); | 372 bool subclass_constructor = IsSubclassConstructor(function_kind_); |
409 Variable* var = variables_.Declare( | 373 Variable* var = variables_.Declare( |
410 this, ast_value_factory->this_string(), | 374 this, ast_value_factory->this_string(), |
411 subclass_constructor ? CONST : VAR, Variable::THIS, | 375 subclass_constructor ? CONST : VAR, Variable::THIS, |
412 subclass_constructor ? kNeedsInitialization : kCreatedInitialized); | 376 subclass_constructor ? kNeedsInitialization : kCreatedInitialized); |
413 receiver_ = var; | 377 receiver_ = var; |
414 } | 378 } |
415 | 379 |
416 void DeclarationScope::DeclareDefaultFunctionVariables( | 380 void Scope::DeclareDefaultFunctionVariables( |
417 AstValueFactory* ast_value_factory) { | 381 AstValueFactory* ast_value_factory) { |
418 DCHECK(is_function_scope()); | 382 DCHECK(is_function_scope()); |
419 DCHECK(!is_arrow_scope()); | 383 DCHECK(!is_arrow_scope()); |
420 // Declare 'arguments' variable which exists in all non arrow functions. | 384 // Declare 'arguments' variable which exists in all non arrow functions. |
421 // Note that it might never be accessed, in which case it won't be | 385 // Note that it might never be accessed, in which case it won't be |
422 // allocated during variable allocation. | 386 // allocated during variable allocation. |
423 arguments_ = | 387 arguments_ = |
424 variables_.Declare(this, ast_value_factory->arguments_string(), VAR, | 388 variables_.Declare(this, ast_value_factory->arguments_string(), VAR, |
425 Variable::ARGUMENTS, kCreatedInitialized); | 389 Variable::ARGUMENTS, kCreatedInitialized); |
426 | 390 |
427 new_target_ = | 391 new_target_ = |
428 variables_.Declare(this, ast_value_factory->new_target_string(), CONST, | 392 variables_.Declare(this, ast_value_factory->new_target_string(), CONST, |
429 Variable::NORMAL, kCreatedInitialized); | 393 Variable::NORMAL, kCreatedInitialized); |
430 | 394 |
431 if (IsConciseMethod(function_kind_) || IsClassConstructor(function_kind_) || | 395 if (IsConciseMethod(function_kind_) || IsClassConstructor(function_kind_) || |
432 IsAccessorFunction(function_kind_)) { | 396 IsAccessorFunction(function_kind_)) { |
433 this_function_ = | 397 this_function_ = |
434 variables_.Declare(this, ast_value_factory->this_function_string(), | 398 variables_.Declare(this, ast_value_factory->this_function_string(), |
435 CONST, Variable::NORMAL, kCreatedInitialized); | 399 CONST, Variable::NORMAL, kCreatedInitialized); |
436 } | 400 } |
437 } | 401 } |
438 | 402 |
439 | 403 |
440 Scope* Scope::FinalizeBlockScope() { | 404 Scope* Scope::FinalizeBlockScope() { |
441 DCHECK(is_block_scope()); | 405 DCHECK(is_block_scope()); |
| 406 DCHECK(temps_.is_empty()); |
| 407 DCHECK(params_.is_empty()); |
442 | 408 |
443 if (variables_.occupancy() > 0 || | 409 if (variables_.occupancy() > 0 || |
444 (is_declaration_scope() && calls_sloppy_eval())) { | 410 (is_declaration_scope() && calls_sloppy_eval())) { |
445 return this; | 411 return this; |
446 } | 412 } |
447 | 413 |
448 // Remove this scope from outer scope. | 414 // Remove this scope from outer scope. |
449 outer_scope()->RemoveInnerScope(this); | 415 outer_scope()->RemoveInnerScope(this); |
450 | 416 |
451 // Reparent inner scopes. | 417 // Reparent inner scopes. |
(...skipping 20 matching lines...) Expand all Loading... |
472 } | 438 } |
473 outer_scope()->unresolved_ = unresolved_; | 439 outer_scope()->unresolved_ = unresolved_; |
474 unresolved_ = nullptr; | 440 unresolved_ = nullptr; |
475 } | 441 } |
476 | 442 |
477 PropagateUsageFlagsToScope(outer_scope_); | 443 PropagateUsageFlagsToScope(outer_scope_); |
478 | 444 |
479 return NULL; | 445 return NULL; |
480 } | 446 } |
481 | 447 |
482 void Scope::Snapshot::Reparent(DeclarationScope* new_parent) const { | 448 void Scope::Snapshot::Reparent(Scope* new_parent) const { |
483 DCHECK_EQ(new_parent, outer_scope_->inner_scope_); | 449 DCHECK_EQ(new_parent, outer_scope_->inner_scope_); |
484 DCHECK_EQ(new_parent->outer_scope_, outer_scope_); | 450 DCHECK_EQ(new_parent->outer_scope_, outer_scope_); |
485 DCHECK_EQ(new_parent, new_parent->GetClosureScope()); | 451 DCHECK_EQ(new_parent, new_parent->ClosureScope()); |
486 DCHECK_NULL(new_parent->inner_scope_); | 452 DCHECK_NULL(new_parent->inner_scope_); |
487 DCHECK_NULL(new_parent->unresolved_); | 453 DCHECK_NULL(new_parent->unresolved_); |
488 DCHECK_EQ(0, new_parent->temps()->length()); | 454 DCHECK_EQ(0, new_parent->temps_.length()); |
489 Scope* inner_scope = new_parent->sibling_; | 455 Scope* inner_scope = new_parent->sibling_; |
490 if (inner_scope != top_inner_scope_) { | 456 if (inner_scope != top_inner_scope_) { |
491 for (; inner_scope->sibling() != top_inner_scope_; | 457 for (; inner_scope->sibling() != top_inner_scope_; |
492 inner_scope = inner_scope->sibling()) { | 458 inner_scope = inner_scope->sibling()) { |
493 inner_scope->outer_scope_ = new_parent; | 459 inner_scope->outer_scope_ = new_parent; |
494 DCHECK_NE(inner_scope, new_parent); | 460 DCHECK_NE(inner_scope, new_parent); |
495 } | 461 } |
496 inner_scope->outer_scope_ = new_parent; | 462 inner_scope->outer_scope_ = new_parent; |
497 | 463 |
498 new_parent->inner_scope_ = new_parent->sibling_; | 464 new_parent->inner_scope_ = new_parent->sibling_; |
499 inner_scope->sibling_ = nullptr; | 465 inner_scope->sibling_ = nullptr; |
500 // Reset the sibling rather than the inner_scope_ since we | 466 // Reset the sibling rather than the inner_scope_ since we |
501 // want to keep new_parent there. | 467 // want to keep new_parent there. |
502 new_parent->sibling_ = top_inner_scope_; | 468 new_parent->sibling_ = top_inner_scope_; |
503 } | 469 } |
504 | 470 |
505 if (outer_scope_->unresolved_ != top_unresolved_) { | 471 if (outer_scope_->unresolved_ != top_unresolved_) { |
506 VariableProxy* last = outer_scope_->unresolved_; | 472 VariableProxy* last = outer_scope_->unresolved_; |
507 while (last->next_unresolved() != top_unresolved_) { | 473 while (last->next_unresolved() != top_unresolved_) { |
508 last = last->next_unresolved(); | 474 last = last->next_unresolved(); |
509 } | 475 } |
510 last->set_next_unresolved(nullptr); | 476 last->set_next_unresolved(nullptr); |
511 new_parent->unresolved_ = outer_scope_->unresolved_; | 477 new_parent->unresolved_ = outer_scope_->unresolved_; |
512 outer_scope_->unresolved_ = top_unresolved_; | 478 outer_scope_->unresolved_ = top_unresolved_; |
513 } | 479 } |
514 | 480 |
515 if (outer_scope_->GetClosureScope()->temps()->length() != top_temp_) { | 481 if (outer_scope_->ClosureScope()->temps_.length() != top_temp_) { |
516 ZoneList<Variable*>* temps = outer_scope_->GetClosureScope()->temps(); | 482 ZoneList<Variable*>* temps = &outer_scope_->ClosureScope()->temps_; |
517 for (int i = top_temp_; i < temps->length(); i++) { | 483 for (int i = top_temp_; i < temps->length(); i++) { |
518 Variable* temp = temps->at(i); | 484 Variable* temp = temps->at(i); |
519 DCHECK_EQ(temp->scope(), temp->scope()->GetClosureScope()); | 485 DCHECK_EQ(temp->scope(), temp->scope()->ClosureScope()); |
520 DCHECK_NE(temp->scope(), new_parent); | 486 DCHECK_NE(temp->scope(), new_parent); |
521 temp->set_scope(new_parent); | 487 temp->set_scope(new_parent); |
522 new_parent->AddTemporary(temp); | 488 new_parent->AddTemporary(temp); |
523 } | 489 } |
524 temps->Rewind(top_temp_); | 490 temps->Rewind(top_temp_); |
525 } | 491 } |
526 } | 492 } |
527 | 493 |
528 void Scope::ReplaceOuterScope(Scope* outer) { | 494 void Scope::ReplaceOuterScope(Scope* outer) { |
529 DCHECK_NOT_NULL(outer); | 495 DCHECK_NOT_NULL(outer); |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
596 } | 562 } |
597 // TODO(marja, rossberg): Correctly declare FUNCTION, CLASS, NEW_TARGET, and | 563 // TODO(marja, rossberg): Correctly declare FUNCTION, CLASS, NEW_TARGET, and |
598 // ARGUMENTS bindings as their corresponding Variable::Kind. | 564 // ARGUMENTS bindings as their corresponding Variable::Kind. |
599 | 565 |
600 Variable* var = variables_.Declare(this, name, mode, kind, init_flag, | 566 Variable* var = variables_.Declare(this, name, mode, kind, init_flag, |
601 maybe_assigned_flag); | 567 maybe_assigned_flag); |
602 var->AllocateTo(location, index); | 568 var->AllocateTo(location, index); |
603 return var; | 569 return var; |
604 } | 570 } |
605 | 571 |
606 Variable* DeclarationScope::LookupFunctionVar(const AstRawString* name, | 572 |
607 AstNodeFactory* factory) { | 573 Variable* Scope::LookupFunctionVar(const AstRawString* name, |
| 574 AstNodeFactory* factory) { |
608 if (function_ != NULL && function_->proxy()->raw_name() == name) { | 575 if (function_ != NULL && function_->proxy()->raw_name() == name) { |
609 return function_->proxy()->var(); | 576 return function_->proxy()->var(); |
610 } else if (!scope_info_.is_null()) { | 577 } else if (!scope_info_.is_null()) { |
611 // If we are backed by a scope info, try to lookup the variable there. | 578 // If we are backed by a scope info, try to lookup the variable there. |
612 VariableMode mode; | 579 VariableMode mode; |
613 int index = scope_info_->FunctionContextSlotIndex(*(name->string()), &mode); | 580 int index = scope_info_->FunctionContextSlotIndex(*(name->string()), &mode); |
614 if (index < 0) return NULL; | 581 if (index < 0) return NULL; |
615 Variable* var = new (zone()) | 582 Variable* var = new (zone()) |
616 Variable(this, name, mode, Variable::NORMAL, kCreatedInitialized); | 583 Variable(this, name, mode, Variable::NORMAL, kCreatedInitialized); |
617 DCHECK_NOT_NULL(factory); | 584 DCHECK_NOT_NULL(factory); |
(...skipping 13 matching lines...) Expand all Loading... |
631 Variable* Scope::Lookup(const AstRawString* name) { | 598 Variable* Scope::Lookup(const AstRawString* name) { |
632 for (Scope* scope = this; | 599 for (Scope* scope = this; |
633 scope != NULL; | 600 scope != NULL; |
634 scope = scope->outer_scope()) { | 601 scope = scope->outer_scope()) { |
635 Variable* var = scope->LookupLocal(name); | 602 Variable* var = scope->LookupLocal(name); |
636 if (var != NULL) return var; | 603 if (var != NULL) return var; |
637 } | 604 } |
638 return NULL; | 605 return NULL; |
639 } | 606 } |
640 | 607 |
641 Variable* DeclarationScope::DeclareParameter( | 608 Variable* Scope::DeclareParameter(const AstRawString* name, VariableMode mode, |
642 const AstRawString* name, VariableMode mode, bool is_optional, bool is_rest, | 609 bool is_optional, bool is_rest, |
643 bool* is_duplicate, AstValueFactory* ast_value_factory) { | 610 bool* is_duplicate, |
| 611 AstValueFactory* ast_value_factory) { |
644 DCHECK(!already_resolved()); | 612 DCHECK(!already_resolved()); |
645 DCHECK(is_function_scope()); | 613 DCHECK(is_function_scope()); |
646 DCHECK(!is_optional || !is_rest); | 614 DCHECK(!is_optional || !is_rest); |
647 Variable* var; | 615 Variable* var; |
648 if (mode == TEMPORARY) { | 616 if (mode == TEMPORARY) { |
649 var = NewTemporary(name); | 617 var = NewTemporary(name); |
650 } else { | 618 } else { |
651 var = variables_.Declare(this, name, mode, Variable::NORMAL, | 619 var = variables_.Declare(this, name, mode, Variable::NORMAL, |
652 kCreatedInitialized); | 620 kCreatedInitialized); |
653 // TODO(wingo): Avoid O(n^2) check. | 621 // TODO(wingo): Avoid O(n^2) check. |
(...skipping 19 matching lines...) Expand all Loading... |
673 MaybeAssignedFlag maybe_assigned_flag) { | 641 MaybeAssignedFlag maybe_assigned_flag) { |
674 DCHECK(!already_resolved()); | 642 DCHECK(!already_resolved()); |
675 // This function handles VAR, LET, and CONST modes. DYNAMIC variables are | 643 // This function handles VAR, LET, and CONST modes. DYNAMIC variables are |
676 // introduced during variable allocation, and TEMPORARY variables are | 644 // introduced during variable allocation, and TEMPORARY variables are |
677 // allocated via NewTemporary(). | 645 // allocated via NewTemporary(). |
678 DCHECK(IsDeclaredVariableMode(mode)); | 646 DCHECK(IsDeclaredVariableMode(mode)); |
679 return variables_.Declare(this, name, mode, kind, init_flag, | 647 return variables_.Declare(this, name, mode, kind, init_flag, |
680 maybe_assigned_flag); | 648 maybe_assigned_flag); |
681 } | 649 } |
682 | 650 |
683 Variable* DeclarationScope::DeclareDynamicGlobal(const AstRawString* name) { | 651 |
| 652 Variable* Scope::DeclareDynamicGlobal(const AstRawString* name) { |
684 DCHECK(is_script_scope()); | 653 DCHECK(is_script_scope()); |
685 return variables_.Declare(this, | 654 return variables_.Declare(this, |
686 name, | 655 name, |
687 DYNAMIC_GLOBAL, | 656 DYNAMIC_GLOBAL, |
688 Variable::NORMAL, | 657 Variable::NORMAL, |
689 kCreatedInitialized); | 658 kCreatedInitialized); |
690 } | 659 } |
691 | 660 |
692 | 661 |
693 bool Scope::RemoveUnresolved(VariableProxy* var) { | 662 bool Scope::RemoveUnresolved(VariableProxy* var) { |
(...skipping 11 matching lines...) Expand all Loading... |
705 return true; | 674 return true; |
706 } | 675 } |
707 current = next; | 676 current = next; |
708 } | 677 } |
709 return false; | 678 return false; |
710 } | 679 } |
711 | 680 |
712 | 681 |
713 Variable* Scope::NewTemporary(const AstRawString* name) { | 682 Variable* Scope::NewTemporary(const AstRawString* name) { |
714 DCHECK(!already_resolved()); | 683 DCHECK(!already_resolved()); |
715 DeclarationScope* scope = GetClosureScope(); | 684 Scope* scope = this->ClosureScope(); |
716 Variable* var = new(zone()) Variable(scope, | 685 Variable* var = new(zone()) Variable(scope, |
717 name, | 686 name, |
718 TEMPORARY, | 687 TEMPORARY, |
719 Variable::NORMAL, | 688 Variable::NORMAL, |
720 kCreatedInitialized); | 689 kCreatedInitialized); |
721 scope->AddTemporary(var); | 690 scope->AddTemporary(var); |
722 return var; | 691 return var; |
723 } | 692 } |
724 | 693 |
725 int DeclarationScope::RemoveTemporary(Variable* var) { | 694 int Scope::RemoveTemporary(Variable* var) { |
726 DCHECK_NOT_NULL(var); | 695 DCHECK_NOT_NULL(var); |
727 // Temporaries are only placed in ClosureScopes. | 696 // Temporaries are only placed in ClosureScopes. |
728 DCHECK_EQ(GetClosureScope(), this); | 697 DCHECK_EQ(ClosureScope(), this); |
729 DCHECK_EQ(var->scope()->GetClosureScope(), var->scope()); | 698 DCHECK_EQ(var->scope()->ClosureScope(), var->scope()); |
730 // If the temporary is not here, return quickly. | 699 // If the temporary is not here, return quickly. |
731 if (var->scope() != this) return -1; | 700 if (var->scope() != this) return -1; |
732 // Most likely (always?) any temporary variable we want to remove | 701 // Most likely (always?) any temporary variable we want to remove |
733 // was just added before, so we search backwards. | 702 // was just added before, so we search backwards. |
734 for (int i = temps_.length(); i-- > 0;) { | 703 for (int i = temps_.length(); i-- > 0;) { |
735 if (temps_[i] == var) { | 704 if (temps_[i] == var) { |
736 // Don't shrink temps_, as callers of this method expect | 705 // Don't shrink temps_, as callers of this method expect |
737 // the returned indices to be unique per-scope. | 706 // the returned indices to be unique per-scope. |
738 temps_[i] = nullptr; | 707 temps_[i] = nullptr; |
739 return i; | 708 return i; |
740 } | 709 } |
741 } | 710 } |
742 return -1; | 711 return -1; |
743 } | 712 } |
744 | 713 |
745 | 714 |
746 void Scope::AddDeclaration(Declaration* declaration) { | 715 void Scope::AddDeclaration(Declaration* declaration) { |
747 decls_.Add(declaration, zone()); | 716 decls_.Add(declaration, zone()); |
748 } | 717 } |
749 | 718 |
750 | 719 |
751 Declaration* Scope::CheckConflictingVarDeclarations() { | 720 Declaration* Scope::CheckConflictingVarDeclarations() { |
752 int length = decls_.length(); | 721 int length = decls_.length(); |
753 for (int i = 0; i < length; i++) { | 722 for (int i = 0; i < length; i++) { |
754 Declaration* decl = decls_[i]; | 723 Declaration* decl = decls_[i]; |
755 // We don't create a separate scope to hold the function name of a function | 724 // We don't create a separate scope to hold the function name of a function |
756 // expression, so we have to make sure not to consider it when checking for | 725 // expression, so we have to make sure not to consider it when checking for |
757 // conflicts (since it's conceptually "outside" the declaration scope). | 726 // conflicts (since it's conceptually "outside" the declaration scope). |
758 if (is_function_scope() && decl == AsDeclarationScope()->function()) | 727 if (is_function_scope() && decl == function()) continue; |
759 continue; | |
760 if (IsLexicalVariableMode(decl->mode()) && !is_block_scope()) continue; | 728 if (IsLexicalVariableMode(decl->mode()) && !is_block_scope()) continue; |
761 const AstRawString* name = decl->proxy()->raw_name(); | 729 const AstRawString* name = decl->proxy()->raw_name(); |
762 | 730 |
763 // Iterate through all scopes until and including the declaration scope. | 731 // Iterate through all scopes until and including the declaration scope. |
764 Scope* previous = NULL; | 732 Scope* previous = NULL; |
765 Scope* current = decl->scope(); | 733 Scope* current = decl->scope(); |
766 // Lexical vs lexical conflicts within the same scope have already been | 734 // Lexical vs lexical conflicts within the same scope have already been |
767 // captured in Parser::Declare. The only conflicts we still need to check | 735 // captured in Parser::Declare. The only conflicts we still need to check |
768 // are lexical vs VAR, or any declarations within a declaration block scope | 736 // are lexical vs VAR, or any declarations within a declaration block scope |
769 // vs lexical declarations in its surrounding (function) scope. | 737 // vs lexical declarations in its surrounding (function) scope. |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
817 | 785 |
818 void Scope::CollectStackAndContextLocals(ZoneList<Variable*>* stack_locals, | 786 void Scope::CollectStackAndContextLocals(ZoneList<Variable*>* stack_locals, |
819 ZoneList<Variable*>* context_locals, | 787 ZoneList<Variable*>* context_locals, |
820 ZoneList<Variable*>* context_globals) { | 788 ZoneList<Variable*>* context_globals) { |
821 DCHECK(stack_locals != NULL); | 789 DCHECK(stack_locals != NULL); |
822 DCHECK(context_locals != NULL); | 790 DCHECK(context_locals != NULL); |
823 DCHECK(context_globals != NULL); | 791 DCHECK(context_globals != NULL); |
824 | 792 |
825 // Collect temporaries which are always allocated on the stack, unless the | 793 // Collect temporaries which are always allocated on the stack, unless the |
826 // context as a whole has forced context allocation. | 794 // context as a whole has forced context allocation. |
827 if (is_declaration_scope()) { | 795 for (int i = 0; i < temps_.length(); i++) { |
828 ZoneList<Variable*>* temps = AsDeclarationScope()->temps(); | 796 Variable* var = temps_[i]; |
829 for (int i = 0; i < temps->length(); i++) { | 797 if (var == nullptr) continue; |
830 Variable* var = (*temps)[i]; | 798 if (var->is_used()) { |
831 if (var == nullptr) continue; | 799 if (var->IsContextSlot()) { |
832 if (var->is_used()) { | 800 DCHECK(has_forced_context_allocation()); |
833 if (var->IsContextSlot()) { | 801 context_locals->Add(var, zone()); |
834 DCHECK(has_forced_context_allocation()); | 802 } else if (var->IsStackLocal()) { |
835 context_locals->Add(var, zone()); | 803 stack_locals->Add(var, zone()); |
836 } else if (var->IsStackLocal()) { | 804 } else { |
837 stack_locals->Add(var, zone()); | 805 DCHECK(var->IsParameter()); |
838 } else { | |
839 DCHECK(var->IsParameter()); | |
840 } | |
841 } | 806 } |
842 } | 807 } |
843 } | 808 } |
844 | 809 |
845 // Collect declared local variables. | 810 // Collect declared local variables. |
846 ZoneList<VarAndOrder> vars(variables_.occupancy(), zone()); | 811 ZoneList<VarAndOrder> vars(variables_.occupancy(), zone()); |
847 for (VariableMap::Entry* p = variables_.Start(); | 812 for (VariableMap::Entry* p = variables_.Start(); |
848 p != NULL; | 813 p != NULL; |
849 p = variables_.Next(p)) { | 814 p = variables_.Next(p)) { |
850 Variable* var = reinterpret_cast<Variable*>(p->value); | 815 Variable* var = reinterpret_cast<Variable*>(p->value); |
851 if (var->is_used()) { | 816 if (var->is_used()) { |
852 vars.Add(VarAndOrder(var, p->order), zone()); | 817 vars.Add(VarAndOrder(var, p->order), zone()); |
853 } | 818 } |
854 } | 819 } |
855 vars.Sort(VarAndOrder::Compare); | 820 vars.Sort(VarAndOrder::Compare); |
856 int var_count = vars.length(); | 821 int var_count = vars.length(); |
857 for (int i = 0; i < var_count; i++) { | 822 for (int i = 0; i < var_count; i++) { |
858 Variable* var = vars[i].var(); | 823 Variable* var = vars[i].var(); |
859 if (var->IsStackLocal()) { | 824 if (var->IsStackLocal()) { |
860 stack_locals->Add(var, zone()); | 825 stack_locals->Add(var, zone()); |
861 } else if (var->IsContextSlot()) { | 826 } else if (var->IsContextSlot()) { |
862 context_locals->Add(var, zone()); | 827 context_locals->Add(var, zone()); |
863 } else if (var->IsGlobalSlot()) { | 828 } else if (var->IsGlobalSlot()) { |
864 context_globals->Add(var, zone()); | 829 context_globals->Add(var, zone()); |
865 } | 830 } |
866 } | 831 } |
867 } | 832 } |
868 | 833 |
869 bool DeclarationScope::AllocateVariables(ParseInfo* info, | 834 bool Scope::AllocateVariables(ParseInfo* info, AstNodeFactory* factory) { |
870 AstNodeFactory* factory) { | |
871 // 1) Propagate scope information. | 835 // 1) Propagate scope information. |
872 bool outer_scope_calls_sloppy_eval = false; | 836 bool outer_scope_calls_sloppy_eval = false; |
873 if (outer_scope_ != NULL) { | 837 if (outer_scope_ != NULL) { |
874 outer_scope_calls_sloppy_eval = | 838 outer_scope_calls_sloppy_eval = |
875 outer_scope_->outer_scope_calls_sloppy_eval() | | 839 outer_scope_->outer_scope_calls_sloppy_eval() | |
876 outer_scope_->calls_sloppy_eval(); | 840 outer_scope_->calls_sloppy_eval(); |
877 } | 841 } |
878 PropagateScopeInfo(outer_scope_calls_sloppy_eval); | 842 PropagateScopeInfo(outer_scope_calls_sloppy_eval); |
879 | 843 |
880 // 2) Resolve variables. | 844 // 2) Resolve variables. |
881 if (!ResolveVariablesRecursively(info, factory)) { | 845 if (!ResolveVariablesRecursively(info, factory)) return false; |
882 DCHECK(pending_error_handler_.has_pending_error()); | |
883 pending_error_handler_.ThrowPendingError(info->isolate(), info->script()); | |
884 return false; | |
885 } | |
886 | 846 |
887 // 3) Allocate variables. | 847 // 3) Allocate variables. |
888 AllocateVariablesRecursively(info->ast_value_factory()); | 848 AllocateVariablesRecursively(info->ast_value_factory()); |
889 | 849 |
890 return true; | 850 return true; |
891 } | 851 } |
892 | 852 |
893 | 853 |
894 bool Scope::HasTrivialContext() const { | 854 bool Scope::HasTrivialContext() const { |
895 // A function scope has a trivial context if it always is the global | 855 // A function scope has a trivial context if it always is the global |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
950 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { | 910 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { |
951 max_context_chain_length = std::max(scope->MaxNestedContextChainLength(), | 911 max_context_chain_length = std::max(scope->MaxNestedContextChainLength(), |
952 max_context_chain_length); | 912 max_context_chain_length); |
953 } | 913 } |
954 if (NeedsContext()) { | 914 if (NeedsContext()) { |
955 max_context_chain_length += 1; | 915 max_context_chain_length += 1; |
956 } | 916 } |
957 return max_context_chain_length; | 917 return max_context_chain_length; |
958 } | 918 } |
959 | 919 |
960 DeclarationScope* Scope::GetDeclarationScope() { | 920 |
| 921 Scope* Scope::DeclarationScope() { |
961 Scope* scope = this; | 922 Scope* scope = this; |
962 while (!scope->is_declaration_scope()) { | 923 while (!scope->is_declaration_scope()) { |
963 scope = scope->outer_scope(); | 924 scope = scope->outer_scope(); |
964 } | 925 } |
965 return scope->AsDeclarationScope(); | 926 return scope; |
966 } | 927 } |
967 | 928 |
968 DeclarationScope* Scope::GetClosureScope() { | 929 |
| 930 Scope* Scope::ClosureScope() { |
969 Scope* scope = this; | 931 Scope* scope = this; |
970 while (!scope->is_declaration_scope() || scope->is_block_scope()) { | 932 while (!scope->is_declaration_scope() || scope->is_block_scope()) { |
971 scope = scope->outer_scope(); | 933 scope = scope->outer_scope(); |
972 } | 934 } |
973 return scope->AsDeclarationScope(); | 935 return scope; |
974 } | |
975 | |
976 DeclarationScope* Scope::GetReceiverScope() { | |
977 Scope* scope = this; | |
978 while (!scope->is_script_scope() && | |
979 (!scope->is_function_scope() || | |
980 scope->AsDeclarationScope()->is_arrow_scope())) { | |
981 scope = scope->outer_scope(); | |
982 } | |
983 return scope->AsDeclarationScope(); | |
984 } | 936 } |
985 | 937 |
986 | 938 |
| 939 Scope* Scope::ReceiverScope() { |
| 940 Scope* scope = this; |
| 941 while (!scope->is_script_scope() && |
| 942 (!scope->is_function_scope() || scope->is_arrow_scope())) { |
| 943 scope = scope->outer_scope(); |
| 944 } |
| 945 return scope; |
| 946 } |
| 947 |
| 948 |
987 | 949 |
988 Handle<ScopeInfo> Scope::GetScopeInfo(Isolate* isolate) { | 950 Handle<ScopeInfo> Scope::GetScopeInfo(Isolate* isolate) { |
989 if (scope_info_.is_null()) { | 951 if (scope_info_.is_null()) { |
990 scope_info_ = ScopeInfo::Create(isolate, zone(), this); | 952 scope_info_ = ScopeInfo::Create(isolate, zone(), this); |
991 } | 953 } |
992 return scope_info_; | 954 return scope_info_; |
993 } | 955 } |
994 | 956 |
995 Handle<StringSet> Scope::CollectNonLocals(Handle<StringSet> non_locals) { | 957 Handle<StringSet> Scope::CollectNonLocals(Handle<StringSet> non_locals) { |
996 // Collect non-local variables referenced in the scope. | 958 // Collect non-local variables referenced in the scope. |
997 // TODO(yangguo): store non-local variables explicitly if we can no longer | 959 // TODO(yangguo): store non-local variables explicitly if we can no longer |
998 // rely on unresolved_ to find them. | 960 // rely on unresolved_ to find them. |
999 for (VariableProxy* proxy = unresolved_; proxy != nullptr; | 961 for (VariableProxy* proxy = unresolved_; proxy != nullptr; |
1000 proxy = proxy->next_unresolved()) { | 962 proxy = proxy->next_unresolved()) { |
1001 if (proxy->is_resolved() && proxy->var()->IsStackAllocated()) continue; | 963 if (proxy->is_resolved() && proxy->var()->IsStackAllocated()) continue; |
1002 Handle<String> name = proxy->name(); | 964 Handle<String> name = proxy->name(); |
1003 non_locals = StringSet::Add(non_locals, name); | 965 non_locals = StringSet::Add(non_locals, name); |
1004 } | 966 } |
1005 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { | 967 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { |
1006 non_locals = scope->CollectNonLocals(non_locals); | 968 non_locals = scope->CollectNonLocals(non_locals); |
1007 } | 969 } |
1008 return non_locals; | 970 return non_locals; |
1009 } | 971 } |
1010 | 972 |
1011 void DeclarationScope::AnalyzePartially(DeclarationScope* migrate_to, | 973 void Scope::AnalyzePartially(Scope* migrate_to, |
1012 AstNodeFactory* ast_node_factory) { | 974 AstNodeFactory* ast_node_factory) { |
1013 // Gather info from inner scopes. | 975 // Gather info from inner scopes. |
1014 PropagateScopeInfo(false); | 976 PropagateScopeInfo(false); |
1015 | 977 |
1016 // Try to resolve unresolved variables for this Scope and migrate those which | 978 // Try to resolve unresolved variables for this Scope and migrate those which |
1017 // cannot be resolved inside. It doesn't make sense to try to resolve them in | 979 // cannot be resolved inside. It doesn't make sense to try to resolve them in |
1018 // the outer Scopes here, because they are incomplete. | 980 // the outer Scopes here, because they are incomplete. |
1019 MigrateUnresolvableLocals(migrate_to, ast_node_factory, this); | 981 MigrateUnresolvableLocals(migrate_to, ast_node_factory, this); |
1020 | 982 |
1021 // Push scope data up to migrate_to. Note that migrate_to and this Scope | 983 // Push scope data up to migrate_to. Note that migrate_to and this Scope |
1022 // describe the same Scope, just in different Zones. | 984 // describe the same Scope, just in different Zones. |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1122 for (VariableMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) { | 1084 for (VariableMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) { |
1123 Variable* var = reinterpret_cast<Variable*>(p->value); | 1085 Variable* var = reinterpret_cast<Variable*>(p->value); |
1124 if (var == NULL) { | 1086 if (var == NULL) { |
1125 Indent(indent, "<?>\n"); | 1087 Indent(indent, "<?>\n"); |
1126 } else { | 1088 } else { |
1127 PrintVar(indent, var); | 1089 PrintVar(indent, var); |
1128 } | 1090 } |
1129 } | 1091 } |
1130 } | 1092 } |
1131 | 1093 |
1132 void DeclarationScope::PrintParameters() { | |
1133 PrintF(" ("); | |
1134 for (int i = 0; i < params_.length(); i++) { | |
1135 if (i > 0) PrintF(", "); | |
1136 const AstRawString* name = params_[i]->raw_name(); | |
1137 if (name->IsEmpty()) | |
1138 PrintF(".%p", reinterpret_cast<void*>(params_[i])); | |
1139 else | |
1140 PrintName(name); | |
1141 } | |
1142 PrintF(")"); | |
1143 } | |
1144 | 1094 |
1145 void Scope::Print(int n) { | 1095 void Scope::Print(int n) { |
1146 int n0 = (n > 0 ? n : 0); | 1096 int n0 = (n > 0 ? n : 0); |
1147 int n1 = n0 + 2; // indentation | 1097 int n1 = n0 + 2; // indentation |
1148 | 1098 |
1149 // Print header. | 1099 // Print header. |
1150 FunctionKind function_kind = is_function_scope() | 1100 Indent(n0, Header(scope_type_, function_kind_, is_declaration_scope())); |
1151 ? AsDeclarationScope()->function_kind() | |
1152 : kNormalFunction; | |
1153 Indent(n0, Header(scope_type_, function_kind, is_declaration_scope())); | |
1154 if (scope_name_ != nullptr && !scope_name_->IsEmpty()) { | 1101 if (scope_name_ != nullptr && !scope_name_->IsEmpty()) { |
1155 PrintF(" "); | 1102 PrintF(" "); |
1156 PrintName(scope_name_); | 1103 PrintName(scope_name_); |
1157 } | 1104 } |
1158 | 1105 |
1159 // Print parameters, if any. | 1106 // Print parameters, if any. |
1160 VariableDeclaration* function = nullptr; | |
1161 if (is_function_scope()) { | 1107 if (is_function_scope()) { |
1162 AsDeclarationScope()->PrintParameters(); | 1108 PrintF(" ("); |
1163 function = AsDeclarationScope()->function(); | 1109 for (int i = 0; i < params_.length(); i++) { |
| 1110 if (i > 0) PrintF(", "); |
| 1111 const AstRawString* name = params_[i]->raw_name(); |
| 1112 if (name->IsEmpty()) |
| 1113 PrintF(".%p", reinterpret_cast<void*>(params_[i])); |
| 1114 else |
| 1115 PrintName(name); |
| 1116 } |
| 1117 PrintF(")"); |
1164 } | 1118 } |
1165 | 1119 |
1166 PrintF(" { // (%d, %d)\n", start_position(), end_position()); | 1120 PrintF(" { // (%d, %d)\n", start_position(), end_position()); |
1167 | 1121 |
1168 // Function name, if any (named function literals, only). | 1122 // Function name, if any (named function literals, only). |
1169 if (function != nullptr) { | 1123 if (function_ != NULL) { |
1170 Indent(n1, "// (local) function name: "); | 1124 Indent(n1, "// (local) function name: "); |
1171 PrintName(function->proxy()->raw_name()); | 1125 PrintName(function_->proxy()->raw_name()); |
1172 PrintF("\n"); | 1126 PrintF("\n"); |
1173 } | 1127 } |
1174 | 1128 |
1175 // Scope info. | 1129 // Scope info. |
1176 if (HasTrivialOuterContext()) { | 1130 if (HasTrivialOuterContext()) { |
1177 Indent(n1, "// scope has trivial outer context\n"); | 1131 Indent(n1, "// scope has trivial outer context\n"); |
1178 } | 1132 } |
1179 if (is_strict(language_mode())) { | 1133 if (is_strict(language_mode())) { |
1180 Indent(n1, "// strict mode scope\n"); | 1134 Indent(n1, "// strict mode scope\n"); |
1181 } | 1135 } |
(...skipping 11 matching lines...) Expand all Loading... |
1193 Indent(n1, "// "); | 1147 Indent(n1, "// "); |
1194 PrintF("%d stack slots\n", num_stack_slots_); | 1148 PrintF("%d stack slots\n", num_stack_slots_); |
1195 } | 1149 } |
1196 if (num_heap_slots_ > 0) { | 1150 if (num_heap_slots_ > 0) { |
1197 Indent(n1, "// "); | 1151 Indent(n1, "// "); |
1198 PrintF("%d heap slots (including %d global slots)\n", num_heap_slots_, | 1152 PrintF("%d heap slots (including %d global slots)\n", num_heap_slots_, |
1199 num_global_slots_); | 1153 num_global_slots_); |
1200 } | 1154 } |
1201 | 1155 |
1202 // Print locals. | 1156 // Print locals. |
1203 if (function != nullptr) { | 1157 if (function_ != NULL) { |
1204 Indent(n1, "// function var:\n"); | 1158 Indent(n1, "// function var:\n"); |
1205 PrintVar(n1, function->proxy()->var()); | 1159 PrintVar(n1, function_->proxy()->var()); |
1206 } | 1160 } |
1207 | 1161 |
1208 if (is_declaration_scope()) { | 1162 if (temps_.length() > 0) { |
1209 bool printed_header = false; | 1163 bool printed_header = false; |
1210 ZoneList<Variable*>* temps = AsDeclarationScope()->temps(); | 1164 for (int i = 0; i < temps_.length(); i++) { |
1211 for (int i = 0; i < temps->length(); i++) { | 1165 if (temps_[i] != nullptr) { |
1212 if ((*temps)[i] != nullptr) { | |
1213 if (!printed_header) { | 1166 if (!printed_header) { |
1214 printed_header = true; | 1167 printed_header = true; |
1215 Indent(n1, "// temporary vars:\n"); | 1168 Indent(n1, "// temporary vars:\n"); |
1216 } | 1169 } |
1217 PrintVar(n1, (*temps)[i]); | 1170 PrintVar(n1, temps_[i]); |
1218 } | 1171 } |
1219 } | 1172 } |
1220 } | 1173 } |
1221 | 1174 |
1222 if (variables_.Start() != NULL) { | 1175 if (variables_.Start() != NULL) { |
1223 Indent(n1, "// local vars:\n"); | 1176 Indent(n1, "// local vars:\n"); |
1224 PrintMap(n1, &variables_); | 1177 PrintMap(n1, &variables_); |
1225 } | 1178 } |
1226 | 1179 |
1227 if (dynamics_ != NULL) { | 1180 if (dynamics_ != NULL) { |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1298 Variable* var = LookupLocal(proxy->raw_name()); | 1251 Variable* var = LookupLocal(proxy->raw_name()); |
1299 | 1252 |
1300 // We found a variable and we are done. (Even if there is an 'eval' in | 1253 // We found a variable and we are done. (Even if there is an 'eval' in |
1301 // this scope which introduces the same variable again, the resulting | 1254 // this scope which introduces the same variable again, the resulting |
1302 // variable remains the same.) | 1255 // variable remains the same.) |
1303 if (var != NULL) { | 1256 if (var != NULL) { |
1304 *binding_kind = BOUND; | 1257 *binding_kind = BOUND; |
1305 return var; | 1258 return var; |
1306 } | 1259 } |
1307 | 1260 |
1308 // We did not find a variable locally. Check against the function variable, if | 1261 // We did not find a variable locally. Check against the function variable, |
1309 // any. | 1262 // if any. We can do this for all scopes, since the function variable is |
| 1263 // only present - if at all - for function scopes. |
1310 *binding_kind = UNBOUND; | 1264 *binding_kind = UNBOUND; |
1311 var = | 1265 var = LookupFunctionVar(proxy->raw_name(), factory); |
1312 is_function_scope() | |
1313 ? AsDeclarationScope()->LookupFunctionVar(proxy->raw_name(), factory) | |
1314 : nullptr; | |
1315 if (var != NULL) { | 1266 if (var != NULL) { |
1316 *binding_kind = BOUND; | 1267 *binding_kind = BOUND; |
1317 } else if (outer_scope_ != nullptr && this != max_outer_scope) { | 1268 } else if (outer_scope_ != nullptr && this != max_outer_scope) { |
1318 var = outer_scope_->LookupRecursive(proxy, binding_kind, factory, | 1269 var = outer_scope_->LookupRecursive(proxy, binding_kind, factory, |
1319 max_outer_scope); | 1270 max_outer_scope); |
1320 if (*binding_kind == BOUND && (is_function_scope() || is_with_scope())) { | 1271 if (*binding_kind == BOUND && (is_function_scope() || is_with_scope())) { |
1321 var->ForceContextAllocation(); | 1272 var->ForceContextAllocation(); |
1322 } | 1273 } |
1323 } else { | 1274 } else { |
1324 DCHECK(is_script_scope() || this == max_outer_scope); | 1275 DCHECK(is_script_scope() || this == max_outer_scope); |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1447 } | 1398 } |
1448 | 1399 |
1449 // Resolve unresolved variables for inner scopes. | 1400 // Resolve unresolved variables for inner scopes. |
1450 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { | 1401 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { |
1451 if (!scope->ResolveVariablesRecursively(info, factory)) return false; | 1402 if (!scope->ResolveVariablesRecursively(info, factory)) return false; |
1452 } | 1403 } |
1453 | 1404 |
1454 return true; | 1405 return true; |
1455 } | 1406 } |
1456 | 1407 |
1457 void Scope::MigrateUnresolvableLocals(DeclarationScope* migrate_to, | 1408 void Scope::MigrateUnresolvableLocals(Scope* migrate_to, |
1458 AstNodeFactory* ast_node_factory, | 1409 AstNodeFactory* ast_node_factory, |
1459 DeclarationScope* max_outer_scope) { | 1410 Scope* max_outer_scope) { |
1460 BindingKind binding_kind; | 1411 BindingKind binding_kind; |
1461 for (VariableProxy *proxy = unresolved_, *next = nullptr; proxy != nullptr; | 1412 for (VariableProxy *proxy = unresolved_, *next = nullptr; proxy != nullptr; |
1462 proxy = next) { | 1413 proxy = next) { |
1463 next = proxy->next_unresolved(); | 1414 next = proxy->next_unresolved(); |
1464 // Note that we pass nullptr as AstNodeFactory: this phase should not create | 1415 // Note that we pass nullptr as AstNodeFactory: this phase should not create |
1465 // any new AstNodes, since none of the Scopes involved are backed up by | 1416 // any new AstNodes, since none of the Scopes involved are backed up by |
1466 // ScopeInfo. | 1417 // ScopeInfo. |
1467 if (LookupRecursive(proxy, &binding_kind, nullptr, max_outer_scope) == | 1418 if (LookupRecursive(proxy, &binding_kind, nullptr, max_outer_scope) == |
1468 nullptr) { | 1419 nullptr) { |
1469 // Re-create the VariableProxies in the right Zone and insert them into | 1420 // Re-create the VariableProxies in the right Zone and insert them into |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1532 if (var->mode() == TEMPORARY) return false; | 1483 if (var->mode() == TEMPORARY) return false; |
1533 if (is_catch_scope() || is_module_scope()) return true; | 1484 if (is_catch_scope() || is_module_scope()) return true; |
1534 if (is_script_scope() && IsLexicalVariableMode(var->mode())) return true; | 1485 if (is_script_scope() && IsLexicalVariableMode(var->mode())) return true; |
1535 return var->has_forced_context_allocation() || scope_calls_eval_ || | 1486 return var->has_forced_context_allocation() || scope_calls_eval_ || |
1536 inner_scope_calls_eval_; | 1487 inner_scope_calls_eval_; |
1537 } | 1488 } |
1538 | 1489 |
1539 | 1490 |
1540 void Scope::AllocateStackSlot(Variable* var) { | 1491 void Scope::AllocateStackSlot(Variable* var) { |
1541 if (is_block_scope()) { | 1492 if (is_block_scope()) { |
1542 outer_scope()->GetDeclarationScope()->AllocateStackSlot(var); | 1493 outer_scope()->DeclarationScope()->AllocateStackSlot(var); |
1543 } else { | 1494 } else { |
1544 var->AllocateTo(VariableLocation::LOCAL, num_stack_slots_++); | 1495 var->AllocateTo(VariableLocation::LOCAL, num_stack_slots_++); |
1545 } | 1496 } |
1546 } | 1497 } |
1547 | 1498 |
1548 | 1499 |
1549 void Scope::AllocateHeapSlot(Variable* var) { | 1500 void Scope::AllocateHeapSlot(Variable* var) { |
1550 var->AllocateTo(VariableLocation::CONTEXT, num_heap_slots_++); | 1501 var->AllocateTo(VariableLocation::CONTEXT, num_heap_slots_++); |
1551 } | 1502 } |
1552 | 1503 |
1553 void DeclarationScope::AllocateParameterLocals() { | 1504 void Scope::AllocateParameterLocals() { |
1554 DCHECK(is_function_scope()); | 1505 DCHECK(is_function_scope()); |
1555 | 1506 |
1556 bool uses_sloppy_arguments = false; | 1507 bool uses_sloppy_arguments = false; |
1557 | 1508 |
1558 // Functions have 'arguments' declared implicitly in all non arrow functions. | 1509 // Functions have 'arguments' declared implicitly in all non arrow functions. |
1559 if (arguments_ != nullptr) { | 1510 if (arguments_ != nullptr) { |
1560 // 'arguments' is used. Unless there is also a parameter called | 1511 // 'arguments' is used. Unless there is also a parameter called |
1561 // 'arguments', we must be conservative and allocate all parameters to | 1512 // 'arguments', we must be conservative and allocate all parameters to |
1562 // the context assuming they will be captured by the arguments object. | 1513 // the context assuming they will be captured by the arguments object. |
1563 // If we have a parameter named 'arguments', a (new) value is always | 1514 // 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... |
1596 | 1547 |
1597 DCHECK(var->scope() == this); | 1548 DCHECK(var->scope() == this); |
1598 if (uses_sloppy_arguments || has_forced_context_allocation()) { | 1549 if (uses_sloppy_arguments || has_forced_context_allocation()) { |
1599 // Force context allocation of the parameter. | 1550 // Force context allocation of the parameter. |
1600 var->ForceContextAllocation(); | 1551 var->ForceContextAllocation(); |
1601 } | 1552 } |
1602 AllocateParameter(var, i); | 1553 AllocateParameter(var, i); |
1603 } | 1554 } |
1604 } | 1555 } |
1605 | 1556 |
1606 void DeclarationScope::AllocateParameter(Variable* var, int index) { | 1557 |
| 1558 void Scope::AllocateParameter(Variable* var, int index) { |
1607 if (MustAllocate(var)) { | 1559 if (MustAllocate(var)) { |
1608 if (MustAllocateInContext(var)) { | 1560 if (MustAllocateInContext(var)) { |
1609 DCHECK(var->IsUnallocated() || var->IsContextSlot()); | 1561 DCHECK(var->IsUnallocated() || var->IsContextSlot()); |
1610 if (var->IsUnallocated()) { | 1562 if (var->IsUnallocated()) { |
1611 AllocateHeapSlot(var); | 1563 AllocateHeapSlot(var); |
1612 } | 1564 } |
1613 } else { | 1565 } else { |
1614 DCHECK(var->IsUnallocated() || var->IsParameter()); | 1566 DCHECK(var->IsUnallocated() || var->IsParameter()); |
1615 if (var->IsUnallocated()) { | 1567 if (var->IsUnallocated()) { |
1616 var->AllocateTo(VariableLocation::PARAMETER, index); | 1568 var->AllocateTo(VariableLocation::PARAMETER, index); |
1617 } | 1569 } |
1618 } | 1570 } |
1619 } else { | 1571 } else { |
1620 DCHECK(!var->IsGlobalSlot()); | 1572 DCHECK(!var->IsGlobalSlot()); |
1621 } | 1573 } |
1622 } | 1574 } |
1623 | 1575 |
1624 void DeclarationScope::AllocateReceiver() { | 1576 |
1625 if (!has_this_declaration()) return; | 1577 void Scope::AllocateReceiver() { |
1626 DCHECK_NOT_NULL(receiver()); | 1578 DCHECK_NOT_NULL(receiver()); |
1627 DCHECK_EQ(receiver()->scope(), this); | 1579 DCHECK_EQ(receiver()->scope(), this); |
1628 | 1580 |
1629 if (has_forced_context_allocation()) { | 1581 if (has_forced_context_allocation()) { |
1630 // Force context allocation of the receiver. | 1582 // Force context allocation of the receiver. |
1631 receiver()->ForceContextAllocation(); | 1583 receiver()->ForceContextAllocation(); |
1632 } | 1584 } |
1633 AllocateParameter(receiver(), -1); | 1585 AllocateParameter(receiver(), -1); |
1634 } | 1586 } |
1635 | 1587 |
(...skipping 25 matching lines...) Expand all Loading... |
1661 } else { | 1613 } else { |
1662 // There must be only DYNAMIC_GLOBAL in the script scope. | 1614 // There must be only DYNAMIC_GLOBAL in the script scope. |
1663 DCHECK(!is_script_scope() || DYNAMIC_GLOBAL == var->mode()); | 1615 DCHECK(!is_script_scope() || DYNAMIC_GLOBAL == var->mode()); |
1664 } | 1616 } |
1665 } | 1617 } |
1666 } | 1618 } |
1667 | 1619 |
1668 void Scope::AllocateNonParameterLocalsAndDeclaredGlobals( | 1620 void Scope::AllocateNonParameterLocalsAndDeclaredGlobals( |
1669 AstValueFactory* ast_value_factory) { | 1621 AstValueFactory* ast_value_factory) { |
1670 // All variables that have no rewrite yet are non-parameter locals. | 1622 // All variables that have no rewrite yet are non-parameter locals. |
1671 if (is_declaration_scope()) { | 1623 for (int i = 0; i < temps_.length(); i++) { |
1672 ZoneList<Variable*>* temps = AsDeclarationScope()->temps(); | 1624 if (temps_[i] == nullptr) continue; |
1673 for (int i = 0; i < temps->length(); i++) { | 1625 AllocateNonParameterLocal(temps_[i], ast_value_factory); |
1674 if ((*temps)[i] == nullptr) continue; | |
1675 AllocateNonParameterLocal((*temps)[i], ast_value_factory); | |
1676 } | |
1677 } | 1626 } |
1678 | 1627 |
1679 ZoneList<VarAndOrder> vars(variables_.occupancy(), zone()); | 1628 ZoneList<VarAndOrder> vars(variables_.occupancy(), zone()); |
1680 for (VariableMap::Entry* p = variables_.Start(); | 1629 for (VariableMap::Entry* p = variables_.Start(); |
1681 p != NULL; | 1630 p != NULL; |
1682 p = variables_.Next(p)) { | 1631 p = variables_.Next(p)) { |
1683 Variable* var = reinterpret_cast<Variable*>(p->value); | 1632 Variable* var = reinterpret_cast<Variable*>(p->value); |
1684 vars.Add(VarAndOrder(var, p->order), zone()); | 1633 vars.Add(VarAndOrder(var, p->order), zone()); |
1685 } | 1634 } |
1686 vars.Sort(VarAndOrder::Compare); | 1635 vars.Sort(VarAndOrder::Compare); |
1687 int var_count = vars.length(); | 1636 int var_count = vars.length(); |
1688 for (int i = 0; i < var_count; i++) { | 1637 for (int i = 0; i < var_count; i++) { |
1689 AllocateNonParameterLocal(vars[i].var(), ast_value_factory); | 1638 AllocateNonParameterLocal(vars[i].var(), ast_value_factory); |
1690 } | 1639 } |
1691 | 1640 |
1692 if (FLAG_global_var_shortcuts) { | 1641 if (FLAG_global_var_shortcuts) { |
1693 for (int i = 0; i < var_count; i++) { | 1642 for (int i = 0; i < var_count; i++) { |
1694 AllocateDeclaredGlobal(vars[i].var(), ast_value_factory); | 1643 AllocateDeclaredGlobal(vars[i].var(), ast_value_factory); |
1695 } | 1644 } |
1696 } | 1645 } |
1697 | 1646 |
1698 if (is_declaration_scope()) { | |
1699 AsDeclarationScope()->AllocateLocals(ast_value_factory); | |
1700 } | |
1701 } | |
1702 | |
1703 void DeclarationScope::AllocateLocals(AstValueFactory* ast_value_factory) { | |
1704 // For now, function_ must be allocated at the very end. If it gets | 1647 // For now, function_ must be allocated at the very end. If it gets |
1705 // allocated in the context, it must be the last slot in the context, | 1648 // allocated in the context, it must be the last slot in the context, |
1706 // because of the current ScopeInfo implementation (see | 1649 // because of the current ScopeInfo implementation (see |
1707 // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor). | 1650 // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor). |
1708 if (function_ != nullptr) { | 1651 if (function_ != nullptr) { |
1709 AllocateNonParameterLocal(function_->proxy()->var(), ast_value_factory); | 1652 AllocateNonParameterLocal(function_->proxy()->var(), ast_value_factory); |
1710 } | 1653 } |
1711 | 1654 |
1712 if (rest_parameter_ != nullptr) { | 1655 if (rest_parameter_ != nullptr) { |
1713 AllocateNonParameterLocal(rest_parameter_, ast_value_factory); | 1656 AllocateNonParameterLocal(rest_parameter_, ast_value_factory); |
(...skipping 18 matching lines...) Expand all Loading... |
1732 } | 1675 } |
1733 | 1676 |
1734 // If scope is already resolved, we still need to allocate | 1677 // If scope is already resolved, we still need to allocate |
1735 // variables in inner scopes which might not have been resolved yet. | 1678 // variables in inner scopes which might not have been resolved yet. |
1736 if (already_resolved()) return; | 1679 if (already_resolved()) return; |
1737 // The number of slots required for variables. | 1680 // The number of slots required for variables. |
1738 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; | 1681 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; |
1739 | 1682 |
1740 // Allocate variables for this scope. | 1683 // Allocate variables for this scope. |
1741 // Parameters must be allocated first, if any. | 1684 // Parameters must be allocated first, if any. |
1742 if (is_declaration_scope()) { | 1685 if (is_function_scope()) AllocateParameterLocals(); |
1743 if (is_function_scope()) AsDeclarationScope()->AllocateParameterLocals(); | 1686 if (has_this_declaration()) AllocateReceiver(); |
1744 AsDeclarationScope()->AllocateReceiver(); | |
1745 } | |
1746 AllocateNonParameterLocalsAndDeclaredGlobals(ast_value_factory); | 1687 AllocateNonParameterLocalsAndDeclaredGlobals(ast_value_factory); |
1747 | 1688 |
1748 // Force allocation of a context for this scope if necessary. For a 'with' | 1689 // Force allocation of a context for this scope if necessary. For a 'with' |
1749 // scope and for a function scope that makes an 'eval' call we need a context, | 1690 // scope and for a function scope that makes an 'eval' call we need a context, |
1750 // even if no local variables were statically allocated in the scope. | 1691 // even if no local variables were statically allocated in the scope. |
1751 // Likewise for modules. | 1692 // Likewise for modules. |
1752 bool must_have_context = | 1693 bool must_have_context = |
1753 is_with_scope() || is_module_scope() || | 1694 is_with_scope() || is_module_scope() || |
1754 (is_function_scope() && calls_sloppy_eval()) || | 1695 (is_function_scope() && calls_sloppy_eval()) || |
1755 (is_block_scope() && is_declaration_scope() && calls_sloppy_eval()); | 1696 (is_block_scope() && is_declaration_scope() && calls_sloppy_eval()); |
1756 | 1697 |
1757 // If we didn't allocate any locals in the local context, then we only | 1698 // If we didn't allocate any locals in the local context, then we only |
1758 // need the minimal number of slots if we must have a context. | 1699 // need the minimal number of slots if we must have a context. |
1759 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && !must_have_context) { | 1700 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && !must_have_context) { |
1760 num_heap_slots_ = 0; | 1701 num_heap_slots_ = 0; |
1761 } | 1702 } |
1762 | 1703 |
1763 // Allocation done. | 1704 // Allocation done. |
1764 DCHECK(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); | 1705 DCHECK(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); |
1765 } | 1706 } |
1766 | 1707 |
1767 | 1708 |
1768 int Scope::StackLocalCount() const { | 1709 int Scope::StackLocalCount() const { |
1769 VariableDeclaration* function = | |
1770 is_function_scope() ? AsDeclarationScope()->function() : nullptr; | |
1771 return num_stack_slots() - | 1710 return num_stack_slots() - |
1772 (function != NULL && function->proxy()->var()->IsStackLocal() ? 1 : 0); | 1711 (function_ != NULL && function_->proxy()->var()->IsStackLocal() ? 1 : 0); |
1773 } | 1712 } |
1774 | 1713 |
1775 | 1714 |
1776 int Scope::ContextLocalCount() const { | 1715 int Scope::ContextLocalCount() const { |
1777 if (num_heap_slots() == 0) return 0; | 1716 if (num_heap_slots() == 0) return 0; |
1778 VariableDeclaration* function = | |
1779 is_function_scope() ? AsDeclarationScope()->function() : nullptr; | |
1780 bool is_function_var_in_context = | 1717 bool is_function_var_in_context = |
1781 function != NULL && function->proxy()->var()->IsContextSlot(); | 1718 function_ != NULL && function_->proxy()->var()->IsContextSlot(); |
1782 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - | 1719 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - |
1783 (is_function_var_in_context ? 1 : 0); | 1720 (is_function_var_in_context ? 1 : 0); |
1784 } | 1721 } |
1785 | 1722 |
1786 | 1723 |
1787 int Scope::ContextGlobalCount() const { return num_global_slots(); } | 1724 int Scope::ContextGlobalCount() const { return num_global_slots(); } |
1788 | 1725 |
1789 } // namespace internal | 1726 } // namespace internal |
1790 } // namespace v8 | 1727 } // namespace v8 |
OLD | NEW |