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