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/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/bootstrapper.h" | 8 #include "src/bootstrapper.h" |
9 #include "src/messages.h" | 9 #include "src/messages.h" |
10 #include "src/parser.h" | 10 #include "src/parser.h" |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 scope_type_ = scope_type; | 153 scope_type_ = scope_type; |
154 function_kind_ = function_kind; | 154 function_kind_ = function_kind; |
155 block_scope_is_class_scope_ = false; | 155 block_scope_is_class_scope_ = false; |
156 scope_name_ = ast_value_factory_->empty_string(); | 156 scope_name_ = ast_value_factory_->empty_string(); |
157 dynamics_ = nullptr; | 157 dynamics_ = nullptr; |
158 receiver_ = nullptr; | 158 receiver_ = nullptr; |
159 new_target_ = nullptr; | 159 new_target_ = nullptr; |
160 function_ = nullptr; | 160 function_ = nullptr; |
161 arguments_ = nullptr; | 161 arguments_ = nullptr; |
162 home_object_ = nullptr; | 162 home_object_ = nullptr; |
163 this_function_ = nullptr; | |
164 illegal_redecl_ = nullptr; | 163 illegal_redecl_ = nullptr; |
165 scope_inside_with_ = false; | 164 scope_inside_with_ = false; |
166 scope_contains_with_ = false; | 165 scope_contains_with_ = false; |
167 scope_calls_eval_ = false; | 166 scope_calls_eval_ = false; |
168 scope_uses_arguments_ = false; | 167 scope_uses_arguments_ = false; |
169 scope_uses_super_property_ = false; | 168 scope_uses_super_property_ = false; |
170 asm_module_ = false; | 169 asm_module_ = false; |
171 asm_function_ = outer_scope != NULL && outer_scope->asm_module_; | 170 asm_function_ = outer_scope != NULL && outer_scope->asm_module_; |
172 // Inherit the language mode from the parent scope. | 171 // Inherit the language mode from the parent scope. |
173 language_mode_ = outer_scope != NULL ? outer_scope->language_mode_ : SLOPPY; | 172 language_mode_ = outer_scope != NULL ? outer_scope->language_mode_ : SLOPPY; |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
302 | 301 |
303 // Add this scope as a new inner scope of the outer scope. | 302 // Add this scope as a new inner scope of the outer scope. |
304 if (outer_scope_ != NULL) { | 303 if (outer_scope_ != NULL) { |
305 outer_scope_->inner_scopes_.Add(this, zone()); | 304 outer_scope_->inner_scopes_.Add(this, zone()); |
306 scope_inside_with_ = outer_scope_->scope_inside_with_ || is_with_scope(); | 305 scope_inside_with_ = outer_scope_->scope_inside_with_ || is_with_scope(); |
307 } else { | 306 } else { |
308 scope_inside_with_ = is_with_scope(); | 307 scope_inside_with_ = is_with_scope(); |
309 } | 308 } |
310 | 309 |
311 // Declare convenience variables and the receiver. | 310 // Declare convenience variables and the receiver. |
312 if (is_declaration_scope() && has_this_declaration()) { | 311 if (is_declaration_scope()) { |
313 Variable* var = variables_.Declare( | 312 DCHECK(!subclass_constructor || is_function_scope()); |
314 this, ast_value_factory_->this_string(), | 313 if (has_this_declaration()) { |
315 subclass_constructor ? CONST : VAR, Variable::THIS, | 314 Variable* var = variables_.Declare( |
316 subclass_constructor ? kNeedsInitialization : kCreatedInitialized); | 315 this, ast_value_factory_->this_string(), |
317 receiver_ = var; | 316 subclass_constructor ? CONST : VAR, Variable::THIS, |
318 } | 317 subclass_constructor ? kNeedsInitialization : kCreatedInitialized); |
319 | 318 receiver_ = var; |
320 if (is_function_scope()) { | |
321 if (!is_arrow_scope()) { | |
322 // Declare 'arguments' variable which exists in all non arrow functions. | |
323 // Note that it might never be accessed, in which case it won't be | |
324 // allocated during variable allocation. | |
325 variables_.Declare(this, ast_value_factory_->arguments_string(), VAR, | |
326 Variable::ARGUMENTS, kCreatedInitialized); | |
327 } | 319 } |
328 | 320 |
329 if (subclass_constructor) { | 321 if (subclass_constructor) { |
330 DCHECK(!is_arrow_scope()); | 322 new_target_ = |
331 variables_.Declare(this, ast_value_factory_->new_target_string(), CONST, | 323 variables_.Declare(this, ast_value_factory_->new_target_string(), |
332 Variable::NORMAL, kCreatedInitialized); | 324 CONST, Variable::NEW_TARGET, kCreatedInitialized); |
| 325 new_target_->AllocateTo(Variable::PARAMETER, -2); |
| 326 new_target_->set_is_used(); |
333 } | 327 } |
| 328 } |
334 | 329 |
335 if (IsConciseMethod(function_kind_) || IsConstructor(function_kind_) || | 330 if (is_function_scope() && !is_arrow_scope()) { |
336 IsAccessorFunction(function_kind_)) { | 331 // Declare 'arguments' variable which exists in all non arrow functions. |
337 DCHECK(!is_arrow_scope()); | 332 // Note that it might never be accessed, in which case it won't be |
338 // Declare '.home_object' variable which exists in all methods. | 333 // allocated during variable allocation. |
339 // Note that it might never be accessed, in which case it won't be | 334 variables_.Declare(this, |
340 // allocated during variable allocation. | 335 ast_value_factory_->arguments_string(), |
341 variables_.Declare(this, ast_value_factory_->home_object_string(), CONST, | 336 VAR, |
342 Variable::NORMAL, kCreatedInitialized); | 337 Variable::ARGUMENTS, |
343 } | 338 kCreatedInitialized); |
| 339 } |
344 | 340 |
345 if (IsSubclassConstructor(function_kind_)) { | 341 if (is_function_scope() && |
346 DCHECK(!is_arrow_scope()); | 342 (IsConciseMethod(function_kind_) || IsConstructor(function_kind_) || |
347 variables_.Declare(this, ast_value_factory_->this_function_string(), | 343 IsAccessorFunction(function_kind_))) { |
348 CONST, Variable::NORMAL, kCreatedInitialized); | 344 DCHECK(!is_arrow_scope()); |
349 } | 345 // Declare '.home_object' variable which exists in all methods. |
| 346 // Note that it might never be accessed, in which case it won't be |
| 347 // allocated during variable allocation. |
| 348 variables_.Declare(this, ast_value_factory_->home_object_string(), VAR, |
| 349 Variable::NORMAL, kCreatedInitialized); |
350 } | 350 } |
351 } | 351 } |
352 | 352 |
353 | 353 |
354 Scope* Scope::FinalizeBlockScope() { | 354 Scope* Scope::FinalizeBlockScope() { |
355 DCHECK(is_block_scope()); | 355 DCHECK(is_block_scope()); |
356 DCHECK(internals_.is_empty()); | 356 DCHECK(internals_.is_empty()); |
357 DCHECK(temps_.is_empty()); | 357 DCHECK(temps_.is_empty()); |
358 DCHECK(params_.is_empty()); | 358 DCHECK(params_.is_empty()); |
359 | 359 |
(...skipping 944 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1304 inner->asm_function_ = true; | 1304 inner->asm_function_ = true; |
1305 } | 1305 } |
1306 } | 1306 } |
1307 } | 1307 } |
1308 | 1308 |
1309 | 1309 |
1310 bool Scope::MustAllocate(Variable* var) { | 1310 bool Scope::MustAllocate(Variable* var) { |
1311 // Give var a read/write use if there is a chance it might be accessed | 1311 // Give var a read/write use if there is a chance it might be accessed |
1312 // via an eval() call. This is only possible if the variable has a | 1312 // via an eval() call. This is only possible if the variable has a |
1313 // visible name. | 1313 // visible name. |
1314 if ((var->is_this() || !var->raw_name()->IsEmpty()) && | 1314 if ((var->is_this() || var->is_new_target() || !var->raw_name()->IsEmpty()) && |
1315 (var->has_forced_context_allocation() || scope_calls_eval_ || | 1315 (var->has_forced_context_allocation() || scope_calls_eval_ || |
1316 inner_scope_calls_eval_ || scope_contains_with_ || is_catch_scope() || | 1316 inner_scope_calls_eval_ || scope_contains_with_ || is_catch_scope() || |
1317 is_block_scope() || is_module_scope() || is_script_scope())) { | 1317 is_block_scope() || is_module_scope() || is_script_scope())) { |
1318 var->set_is_used(); | 1318 var->set_is_used(); |
1319 if (scope_calls_eval_ || inner_scope_calls_eval_) var->set_maybe_assigned(); | 1319 if (scope_calls_eval_ || inner_scope_calls_eval_) var->set_maybe_assigned(); |
1320 } | 1320 } |
1321 // Global variables do not need to be allocated. | 1321 // Global variables do not need to be allocated. |
1322 return !var->IsGlobalObjectProperty() && var->is_used(); | 1322 return !var->IsGlobalObjectProperty() && var->is_used(); |
1323 } | 1323 } |
1324 | 1324 |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1396 // In strict mode 'arguments' does not alias formal parameters. | 1396 // In strict mode 'arguments' does not alias formal parameters. |
1397 // Therefore in strict mode we allocate parameters as if 'arguments' | 1397 // Therefore in strict mode we allocate parameters as if 'arguments' |
1398 // were not used. | 1398 // were not used. |
1399 uses_sloppy_arguments = is_sloppy(language_mode()); | 1399 uses_sloppy_arguments = is_sloppy(language_mode()); |
1400 } | 1400 } |
1401 | 1401 |
1402 if (rest_parameter_ && !MustAllocate(rest_parameter_)) { | 1402 if (rest_parameter_ && !MustAllocate(rest_parameter_)) { |
1403 rest_parameter_ = NULL; | 1403 rest_parameter_ = NULL; |
1404 } | 1404 } |
1405 | 1405 |
| 1406 Variable* home_object_var = |
| 1407 LookupLocal(ast_value_factory_->home_object_string()); |
| 1408 if (home_object_var != nullptr && uses_super_property() && |
| 1409 MustAllocate(home_object_var)) { |
| 1410 // TODO(arv): super() uses a SuperReference so it generates a VariableProxy |
| 1411 // for the .home_object which makes it look like we need to allocate the |
| 1412 // home_object_var. |
| 1413 // Consider splitting the AST node into 2 different nodes since the |
| 1414 // semantics is just so different. |
| 1415 home_object_ = home_object_var; |
| 1416 } |
| 1417 |
1406 // The same parameter may occur multiple times in the parameters_ list. | 1418 // The same parameter may occur multiple times in the parameters_ list. |
1407 // If it does, and if it is not copied into the context object, it must | 1419 // If it does, and if it is not copied into the context object, it must |
1408 // receive the highest parameter index for that parameter; thus iteration | 1420 // receive the highest parameter index for that parameter; thus iteration |
1409 // order is relevant! | 1421 // order is relevant! |
1410 for (int i = params_.length() - 1; i >= 0; --i) { | 1422 for (int i = params_.length() - 1; i >= 0; --i) { |
1411 Variable* var = params_[i]; | 1423 Variable* var = params_[i]; |
1412 if (var == rest_parameter_) continue; | 1424 if (var == rest_parameter_) continue; |
1413 | 1425 |
1414 DCHECK(var->scope() == this); | 1426 DCHECK(var->scope() == this); |
1415 if (uses_sloppy_arguments || has_forced_context_allocation()) { | 1427 if (uses_sloppy_arguments || has_forced_context_allocation()) { |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1484 vars.Sort(VarAndOrder::Compare); | 1496 vars.Sort(VarAndOrder::Compare); |
1485 int var_count = vars.length(); | 1497 int var_count = vars.length(); |
1486 for (int i = 0; i < var_count; i++) { | 1498 for (int i = 0; i < var_count; i++) { |
1487 AllocateNonParameterLocal(isolate, vars[i].var()); | 1499 AllocateNonParameterLocal(isolate, vars[i].var()); |
1488 } | 1500 } |
1489 | 1501 |
1490 // For now, function_ must be allocated at the very end. If it gets | 1502 // For now, function_ must be allocated at the very end. If it gets |
1491 // allocated in the context, it must be the last slot in the context, | 1503 // allocated in the context, it must be the last slot in the context, |
1492 // because of the current ScopeInfo implementation (see | 1504 // because of the current ScopeInfo implementation (see |
1493 // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor). | 1505 // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor). |
1494 if (function_ != nullptr) { | 1506 if (function_ != NULL) { |
1495 AllocateNonParameterLocal(isolate, function_->proxy()->var()); | 1507 AllocateNonParameterLocal(isolate, function_->proxy()->var()); |
1496 } | 1508 } |
1497 | 1509 |
1498 if (rest_parameter_ != nullptr) { | 1510 if (rest_parameter_) { |
1499 AllocateNonParameterLocal(isolate, rest_parameter_); | 1511 AllocateNonParameterLocal(isolate, rest_parameter_); |
1500 } | 1512 } |
1501 | |
1502 Variable* home_object_var = | |
1503 LookupLocal(ast_value_factory_->home_object_string()); | |
1504 if (home_object_var != nullptr && MustAllocate(home_object_var)) { | |
1505 home_object_ = home_object_var; | |
1506 } | |
1507 | |
1508 Variable* new_target_var = | |
1509 LookupLocal(ast_value_factory_->new_target_string()); | |
1510 if (new_target_var != nullptr && MustAllocate(new_target_var)) { | |
1511 new_target_ = new_target_var; | |
1512 } | |
1513 | |
1514 Variable* this_function_var = | |
1515 LookupLocal(ast_value_factory_->this_function_string()); | |
1516 if (this_function_var != nullptr && MustAllocate(this_function_var)) { | |
1517 this_function_ = this_function_var; | |
1518 } | |
1519 } | 1513 } |
1520 | 1514 |
1521 | 1515 |
1522 void Scope::AllocateVariablesRecursively(Isolate* isolate) { | 1516 void Scope::AllocateVariablesRecursively(Isolate* isolate) { |
1523 if (!already_resolved()) { | 1517 if (!already_resolved()) { |
1524 num_stack_slots_ = 0; | 1518 num_stack_slots_ = 0; |
1525 } | 1519 } |
1526 // Allocate variables for inner scopes. | 1520 // Allocate variables for inner scopes. |
1527 for (int i = 0; i < inner_scopes_.length(); i++) { | 1521 for (int i = 0; i < inner_scopes_.length(); i++) { |
1528 inner_scopes_[i]->AllocateVariablesRecursively(isolate); | 1522 inner_scopes_[i]->AllocateVariablesRecursively(isolate); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1579 (function_ != NULL && function_->proxy()->var()->IsStackLocal() ? 1 : 0); | 1573 (function_ != NULL && function_->proxy()->var()->IsStackLocal() ? 1 : 0); |
1580 } | 1574 } |
1581 | 1575 |
1582 | 1576 |
1583 int Scope::ContextLocalCount() const { | 1577 int Scope::ContextLocalCount() const { |
1584 if (num_heap_slots() == 0) return 0; | 1578 if (num_heap_slots() == 0) return 0; |
1585 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - | 1579 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - |
1586 (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0); | 1580 (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0); |
1587 } | 1581 } |
1588 } } // namespace v8::internal | 1582 } } // namespace v8::internal |
OLD | NEW |