| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/ast/scopes.h" | 5 #include "src/ast/scopes.h" |
| 6 | 6 |
| 7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
| 8 #include "src/ast/scopeinfo.h" | 8 #include "src/ast/scopeinfo.h" |
| 9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
| 10 #include "src/messages.h" | 10 #include "src/messages.h" |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 161 scope_name_ = nullptr; | 161 scope_name_ = nullptr; |
| 162 dynamics_ = nullptr; | 162 dynamics_ = nullptr; |
| 163 receiver_ = nullptr; | 163 receiver_ = nullptr; |
| 164 new_target_ = nullptr; | 164 new_target_ = nullptr; |
| 165 function_ = nullptr; | 165 function_ = nullptr; |
| 166 arguments_ = nullptr; | 166 arguments_ = nullptr; |
| 167 this_function_ = nullptr; | 167 this_function_ = nullptr; |
| 168 scope_inside_with_ = false; | 168 scope_inside_with_ = false; |
| 169 scope_calls_eval_ = false; | 169 scope_calls_eval_ = false; |
| 170 scope_uses_arguments_ = false; | 170 scope_uses_arguments_ = false; |
| 171 has_arguments_parameter_ = false; |
| 171 scope_uses_super_property_ = false; | 172 scope_uses_super_property_ = false; |
| 172 asm_module_ = false; | 173 asm_module_ = false; |
| 173 asm_function_ = outer_scope != NULL && outer_scope->asm_module_; | 174 asm_function_ = outer_scope != NULL && outer_scope->asm_module_; |
| 174 // Inherit the language mode from the parent scope. | 175 // Inherit the language mode from the parent scope. |
| 175 language_mode_ = | 176 language_mode_ = |
| 176 is_module_scope() | 177 is_module_scope() |
| 177 ? STRICT | 178 ? STRICT |
| 178 : (outer_scope != NULL ? outer_scope->language_mode_ : SLOPPY); | 179 : (outer_scope != NULL ? outer_scope->language_mode_ : SLOPPY); |
| 179 outer_scope_calls_sloppy_eval_ = false; | 180 outer_scope_calls_sloppy_eval_ = false; |
| 180 inner_scope_calls_eval_ = false; | 181 inner_scope_calls_eval_ = false; |
| (...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 474 Variable* Scope::Lookup(const AstRawString* name) { | 475 Variable* Scope::Lookup(const AstRawString* name) { |
| 475 for (Scope* scope = this; | 476 for (Scope* scope = this; |
| 476 scope != NULL; | 477 scope != NULL; |
| 477 scope = scope->outer_scope()) { | 478 scope = scope->outer_scope()) { |
| 478 Variable* var = scope->LookupLocal(name); | 479 Variable* var = scope->LookupLocal(name); |
| 479 if (var != NULL) return var; | 480 if (var != NULL) return var; |
| 480 } | 481 } |
| 481 return NULL; | 482 return NULL; |
| 482 } | 483 } |
| 483 | 484 |
| 484 | 485 Variable* Scope::DeclareParameter(const AstRawString* name, VariableMode mode, |
| 485 Variable* Scope::DeclareParameter( | 486 bool is_optional, bool is_rest, |
| 486 const AstRawString* name, VariableMode mode, | 487 bool* is_duplicate, |
| 487 bool is_optional, bool is_rest, bool* is_duplicate) { | 488 AstValueFactory* ast_value_factory) { |
| 488 DCHECK(!already_resolved()); | 489 DCHECK(!already_resolved()); |
| 489 DCHECK(is_function_scope()); | 490 DCHECK(is_function_scope()); |
| 490 DCHECK(!is_optional || !is_rest); | 491 DCHECK(!is_optional || !is_rest); |
| 491 Variable* var; | 492 Variable* var; |
| 492 if (mode == TEMPORARY) { | 493 if (mode == TEMPORARY) { |
| 493 var = NewTemporary(name); | 494 var = NewTemporary(name); |
| 494 } else { | 495 } else { |
| 495 var = variables_.Declare(this, name, mode, Variable::NORMAL, | 496 var = variables_.Declare(this, name, mode, Variable::NORMAL, |
| 496 kCreatedInitialized); | 497 kCreatedInitialized); |
| 497 // TODO(wingo): Avoid O(n^2) check. | 498 // TODO(wingo): Avoid O(n^2) check. |
| 498 *is_duplicate = IsDeclaredParameter(name); | 499 *is_duplicate = IsDeclaredParameter(name); |
| 499 } | 500 } |
| 500 if (!is_optional && !is_rest && arity_ == params_.length()) { | 501 if (!is_optional && !is_rest && arity_ == params_.length()) { |
| 501 ++arity_; | 502 ++arity_; |
| 502 } | 503 } |
| 503 if (is_rest) { | 504 if (is_rest) { |
| 504 DCHECK_NULL(rest_parameter_); | 505 DCHECK_NULL(rest_parameter_); |
| 505 rest_parameter_ = var; | 506 rest_parameter_ = var; |
| 506 rest_index_ = num_parameters(); | 507 rest_index_ = num_parameters(); |
| 507 } | 508 } |
| 508 params_.Add(var, zone()); | 509 params_.Add(var, zone()); |
| 510 if (name == ast_value_factory->arguments_string()) { |
| 511 has_arguments_parameter_ = true; |
| 512 } |
| 509 return var; | 513 return var; |
| 510 } | 514 } |
| 511 | 515 |
| 512 Variable* Scope::DeclareLocal(const AstRawString* name, VariableMode mode, | 516 Variable* Scope::DeclareLocal(const AstRawString* name, VariableMode mode, |
| 513 InitializationFlag init_flag, Variable::Kind kind, | 517 InitializationFlag init_flag, Variable::Kind kind, |
| 514 MaybeAssignedFlag maybe_assigned_flag) { | 518 MaybeAssignedFlag maybe_assigned_flag) { |
| 515 DCHECK(!already_resolved()); | 519 DCHECK(!already_resolved()); |
| 516 // This function handles VAR, LET, and CONST modes. DYNAMIC variables are | 520 // This function handles VAR, LET, and CONST modes. DYNAMIC variables are |
| 517 // introduced during variable allocation, and TEMPORARY variables are | 521 // introduced during variable allocation, and TEMPORARY variables are |
| 518 // allocated via NewTemporary(). | 522 // allocated via NewTemporary(). |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 698 if (var->IsStackLocal()) { | 702 if (var->IsStackLocal()) { |
| 699 stack_locals->Add(var, zone()); | 703 stack_locals->Add(var, zone()); |
| 700 } else if (var->IsContextSlot()) { | 704 } else if (var->IsContextSlot()) { |
| 701 context_locals->Add(var, zone()); | 705 context_locals->Add(var, zone()); |
| 702 } else if (var->IsGlobalSlot()) { | 706 } else if (var->IsGlobalSlot()) { |
| 703 context_globals->Add(var, zone()); | 707 context_globals->Add(var, zone()); |
| 704 } | 708 } |
| 705 } | 709 } |
| 706 } | 710 } |
| 707 | 711 |
| 708 | |
| 709 bool Scope::AllocateVariables(ParseInfo* info, AstNodeFactory* factory) { | 712 bool Scope::AllocateVariables(ParseInfo* info, AstNodeFactory* factory) { |
| 710 // 1) Propagate scope information. | 713 // 1) Propagate scope information. |
| 711 bool outer_scope_calls_sloppy_eval = false; | 714 bool outer_scope_calls_sloppy_eval = false; |
| 712 if (outer_scope_ != NULL) { | 715 if (outer_scope_ != NULL) { |
| 713 outer_scope_calls_sloppy_eval = | 716 outer_scope_calls_sloppy_eval = |
| 714 outer_scope_->outer_scope_calls_sloppy_eval() | | 717 outer_scope_->outer_scope_calls_sloppy_eval() | |
| 715 outer_scope_->calls_sloppy_eval(); | 718 outer_scope_->calls_sloppy_eval(); |
| 716 } | 719 } |
| 717 PropagateScopeInfo(outer_scope_calls_sloppy_eval); | 720 PropagateScopeInfo(outer_scope_calls_sloppy_eval); |
| 718 | 721 |
| 719 // 2) Resolve variables. | 722 // 2) Resolve variables. |
| 720 if (!ResolveVariablesRecursively(info, factory)) return false; | 723 if (!ResolveVariablesRecursively(info, factory)) return false; |
| 721 | 724 |
| 722 // 3) Allocate variables. | 725 // 3) Allocate variables. |
| 723 AllocateVariablesRecursively(info->isolate()); | 726 AllocateVariablesRecursively(info->ast_value_factory()); |
| 724 | 727 |
| 725 return true; | 728 return true; |
| 726 } | 729 } |
| 727 | 730 |
| 728 | 731 |
| 729 bool Scope::HasTrivialContext() const { | 732 bool Scope::HasTrivialContext() const { |
| 730 // A function scope has a trivial context if it always is the global | 733 // A function scope has a trivial context if it always is the global |
| 731 // context. We iteratively scan out the context chain to see if | 734 // context. We iteratively scan out the context chain to see if |
| 732 // there is anything that makes this scope non-trivial; otherwise we | 735 // there is anything that makes this scope non-trivial; otherwise we |
| 733 // return true. | 736 // return true. |
| (...skipping 562 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1296 // always context-allocated. | 1299 // always context-allocated. |
| 1297 if (has_forced_context_allocation()) return true; | 1300 if (has_forced_context_allocation()) return true; |
| 1298 if (var->mode() == TEMPORARY) return false; | 1301 if (var->mode() == TEMPORARY) return false; |
| 1299 if (is_catch_scope() || is_module_scope()) return true; | 1302 if (is_catch_scope() || is_module_scope()) return true; |
| 1300 if (is_script_scope() && IsLexicalVariableMode(var->mode())) return true; | 1303 if (is_script_scope() && IsLexicalVariableMode(var->mode())) return true; |
| 1301 return var->has_forced_context_allocation() || scope_calls_eval_ || | 1304 return var->has_forced_context_allocation() || scope_calls_eval_ || |
| 1302 inner_scope_calls_eval_; | 1305 inner_scope_calls_eval_; |
| 1303 } | 1306 } |
| 1304 | 1307 |
| 1305 | 1308 |
| 1306 bool Scope::HasArgumentsParameter(Isolate* isolate) { | |
| 1307 for (int i = 0; i < params_.length(); i++) { | |
| 1308 if (params_[i]->name().is_identical_to( | |
| 1309 isolate->factory()->arguments_string())) { | |
| 1310 return true; | |
| 1311 } | |
| 1312 } | |
| 1313 return false; | |
| 1314 } | |
| 1315 | |
| 1316 | |
| 1317 void Scope::AllocateStackSlot(Variable* var) { | 1309 void Scope::AllocateStackSlot(Variable* var) { |
| 1318 if (is_block_scope()) { | 1310 if (is_block_scope()) { |
| 1319 outer_scope()->DeclarationScope()->AllocateStackSlot(var); | 1311 outer_scope()->DeclarationScope()->AllocateStackSlot(var); |
| 1320 } else { | 1312 } else { |
| 1321 var->AllocateTo(VariableLocation::LOCAL, num_stack_slots_++); | 1313 var->AllocateTo(VariableLocation::LOCAL, num_stack_slots_++); |
| 1322 } | 1314 } |
| 1323 } | 1315 } |
| 1324 | 1316 |
| 1325 | 1317 |
| 1326 void Scope::AllocateHeapSlot(Variable* var) { | 1318 void Scope::AllocateHeapSlot(Variable* var) { |
| 1327 var->AllocateTo(VariableLocation::CONTEXT, num_heap_slots_++); | 1319 var->AllocateTo(VariableLocation::CONTEXT, num_heap_slots_++); |
| 1328 } | 1320 } |
| 1329 | 1321 |
| 1330 | 1322 void Scope::AllocateParameterLocals() { |
| 1331 void Scope::AllocateParameterLocals(Isolate* isolate) { | |
| 1332 DCHECK(is_function_scope()); | 1323 DCHECK(is_function_scope()); |
| 1333 | 1324 |
| 1334 bool uses_sloppy_arguments = false; | 1325 bool uses_sloppy_arguments = false; |
| 1335 | 1326 |
| 1336 // Functions have 'arguments' declared implicitly in all non arrow functions. | 1327 // Functions have 'arguments' declared implicitly in all non arrow functions. |
| 1337 if (arguments_ != nullptr) { | 1328 if (arguments_ != nullptr) { |
| 1338 // 'arguments' is used. Unless there is also a parameter called | 1329 // 'arguments' is used. Unless there is also a parameter called |
| 1339 // 'arguments', we must be conservative and allocate all parameters to | 1330 // 'arguments', we must be conservative and allocate all parameters to |
| 1340 // the context assuming they will be captured by the arguments object. | 1331 // the context assuming they will be captured by the arguments object. |
| 1341 // If we have a parameter named 'arguments', a (new) value is always | 1332 // If we have a parameter named 'arguments', a (new) value is always |
| 1342 // assigned to it via the function invocation. Then 'arguments' denotes | 1333 // assigned to it via the function invocation. Then 'arguments' denotes |
| 1343 // that specific parameter value and cannot be used to access the | 1334 // that specific parameter value and cannot be used to access the |
| 1344 // parameters, which is why we don't need to allocate an arguments | 1335 // parameters, which is why we don't need to allocate an arguments |
| 1345 // object in that case. | 1336 // object in that case. |
| 1346 if (MustAllocate(arguments_) && !HasArgumentsParameter(isolate)) { | 1337 if (MustAllocate(arguments_) && !has_arguments_parameter_) { |
| 1347 // In strict mode 'arguments' does not alias formal parameters. | 1338 // In strict mode 'arguments' does not alias formal parameters. |
| 1348 // Therefore in strict mode we allocate parameters as if 'arguments' | 1339 // Therefore in strict mode we allocate parameters as if 'arguments' |
| 1349 // were not used. | 1340 // were not used. |
| 1350 // If the parameter list is not simple, arguments isn't sloppy either. | 1341 // If the parameter list is not simple, arguments isn't sloppy either. |
| 1351 uses_sloppy_arguments = | 1342 uses_sloppy_arguments = |
| 1352 is_sloppy(language_mode()) && has_simple_parameters(); | 1343 is_sloppy(language_mode()) && has_simple_parameters(); |
| 1353 } else { | 1344 } else { |
| 1354 // 'arguments' is unused. Tell the code generator that it does not need to | 1345 // 'arguments' is unused. Tell the code generator that it does not need to |
| 1355 // allocate the arguments object by nulling out arguments_. | 1346 // allocate the arguments object by nulling out arguments_. |
| 1356 arguments_ = nullptr; | 1347 arguments_ = nullptr; |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1405 DCHECK_NOT_NULL(receiver()); | 1396 DCHECK_NOT_NULL(receiver()); |
| 1406 DCHECK_EQ(receiver()->scope(), this); | 1397 DCHECK_EQ(receiver()->scope(), this); |
| 1407 | 1398 |
| 1408 if (has_forced_context_allocation()) { | 1399 if (has_forced_context_allocation()) { |
| 1409 // Force context allocation of the receiver. | 1400 // Force context allocation of the receiver. |
| 1410 receiver()->ForceContextAllocation(); | 1401 receiver()->ForceContextAllocation(); |
| 1411 } | 1402 } |
| 1412 AllocateParameter(receiver(), -1); | 1403 AllocateParameter(receiver(), -1); |
| 1413 } | 1404 } |
| 1414 | 1405 |
| 1415 | 1406 void Scope::AllocateNonParameterLocal(Variable* var, |
| 1416 void Scope::AllocateNonParameterLocal(Isolate* isolate, Variable* var) { | 1407 AstValueFactory* ast_value_factory) { |
| 1417 DCHECK(var->scope() == this); | 1408 DCHECK(var->scope() == this); |
| 1418 DCHECK(!var->IsVariable(isolate->factory()->dot_result_string()) || | 1409 DCHECK(var->raw_name() != ast_value_factory->dot_result_string() || |
| 1419 !var->IsStackLocal()); | 1410 !var->IsStackLocal()); |
| 1420 if (var->IsUnallocated() && MustAllocate(var)) { | 1411 if (var->IsUnallocated() && MustAllocate(var)) { |
| 1421 if (MustAllocateInContext(var)) { | 1412 if (MustAllocateInContext(var)) { |
| 1422 AllocateHeapSlot(var); | 1413 AllocateHeapSlot(var); |
| 1423 } else { | 1414 } else { |
| 1424 AllocateStackSlot(var); | 1415 AllocateStackSlot(var); |
| 1425 } | 1416 } |
| 1426 } | 1417 } |
| 1427 } | 1418 } |
| 1428 | 1419 |
| 1429 | 1420 void Scope::AllocateDeclaredGlobal(Variable* var, |
| 1430 void Scope::AllocateDeclaredGlobal(Isolate* isolate, Variable* var) { | 1421 AstValueFactory* ast_value_factory) { |
| 1431 DCHECK(var->scope() == this); | 1422 DCHECK(var->scope() == this); |
| 1432 DCHECK(!var->IsVariable(isolate->factory()->dot_result_string()) || | 1423 DCHECK(var->raw_name() != ast_value_factory->dot_result_string() || |
| 1433 !var->IsStackLocal()); | 1424 !var->IsStackLocal()); |
| 1434 if (var->IsUnallocated()) { | 1425 if (var->IsUnallocated()) { |
| 1435 if (var->IsStaticGlobalObjectProperty()) { | 1426 if (var->IsStaticGlobalObjectProperty()) { |
| 1436 DCHECK_EQ(-1, var->index()); | 1427 DCHECK_EQ(-1, var->index()); |
| 1437 DCHECK(var->name()->IsString()); | 1428 DCHECK(var->name()->IsString()); |
| 1438 var->AllocateTo(VariableLocation::GLOBAL, num_heap_slots_++); | 1429 var->AllocateTo(VariableLocation::GLOBAL, num_heap_slots_++); |
| 1439 num_global_slots_++; | 1430 num_global_slots_++; |
| 1440 } else { | 1431 } else { |
| 1441 // There must be only DYNAMIC_GLOBAL in the script scope. | 1432 // There must be only DYNAMIC_GLOBAL in the script scope. |
| 1442 DCHECK(!is_script_scope() || DYNAMIC_GLOBAL == var->mode()); | 1433 DCHECK(!is_script_scope() || DYNAMIC_GLOBAL == var->mode()); |
| 1443 } | 1434 } |
| 1444 } | 1435 } |
| 1445 } | 1436 } |
| 1446 | 1437 |
| 1447 | 1438 void Scope::AllocateNonParameterLocalsAndDeclaredGlobals( |
| 1448 void Scope::AllocateNonParameterLocalsAndDeclaredGlobals(Isolate* isolate) { | 1439 AstValueFactory* ast_value_factory) { |
| 1449 // All variables that have no rewrite yet are non-parameter locals. | 1440 // All variables that have no rewrite yet are non-parameter locals. |
| 1450 for (int i = 0; i < temps_.length(); i++) { | 1441 for (int i = 0; i < temps_.length(); i++) { |
| 1451 if (temps_[i] == nullptr) continue; | 1442 if (temps_[i] == nullptr) continue; |
| 1452 AllocateNonParameterLocal(isolate, temps_[i]); | 1443 AllocateNonParameterLocal(temps_[i], ast_value_factory); |
| 1453 } | 1444 } |
| 1454 | 1445 |
| 1455 ZoneList<VarAndOrder> vars(variables_.occupancy(), zone()); | 1446 ZoneList<VarAndOrder> vars(variables_.occupancy(), zone()); |
| 1456 for (VariableMap::Entry* p = variables_.Start(); | 1447 for (VariableMap::Entry* p = variables_.Start(); |
| 1457 p != NULL; | 1448 p != NULL; |
| 1458 p = variables_.Next(p)) { | 1449 p = variables_.Next(p)) { |
| 1459 Variable* var = reinterpret_cast<Variable*>(p->value); | 1450 Variable* var = reinterpret_cast<Variable*>(p->value); |
| 1460 vars.Add(VarAndOrder(var, p->order), zone()); | 1451 vars.Add(VarAndOrder(var, p->order), zone()); |
| 1461 } | 1452 } |
| 1462 vars.Sort(VarAndOrder::Compare); | 1453 vars.Sort(VarAndOrder::Compare); |
| 1463 int var_count = vars.length(); | 1454 int var_count = vars.length(); |
| 1464 for (int i = 0; i < var_count; i++) { | 1455 for (int i = 0; i < var_count; i++) { |
| 1465 AllocateNonParameterLocal(isolate, vars[i].var()); | 1456 AllocateNonParameterLocal(vars[i].var(), ast_value_factory); |
| 1466 } | 1457 } |
| 1467 | 1458 |
| 1468 if (FLAG_global_var_shortcuts) { | 1459 if (FLAG_global_var_shortcuts) { |
| 1469 for (int i = 0; i < var_count; i++) { | 1460 for (int i = 0; i < var_count; i++) { |
| 1470 AllocateDeclaredGlobal(isolate, vars[i].var()); | 1461 AllocateDeclaredGlobal(vars[i].var(), ast_value_factory); |
| 1471 } | 1462 } |
| 1472 } | 1463 } |
| 1473 | 1464 |
| 1474 // For now, function_ must be allocated at the very end. If it gets | 1465 // For now, function_ must be allocated at the very end. If it gets |
| 1475 // allocated in the context, it must be the last slot in the context, | 1466 // allocated in the context, it must be the last slot in the context, |
| 1476 // because of the current ScopeInfo implementation (see | 1467 // because of the current ScopeInfo implementation (see |
| 1477 // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor). | 1468 // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor). |
| 1478 if (function_ != nullptr) { | 1469 if (function_ != nullptr) { |
| 1479 AllocateNonParameterLocal(isolate, function_->proxy()->var()); | 1470 AllocateNonParameterLocal(function_->proxy()->var(), ast_value_factory); |
| 1480 } | 1471 } |
| 1481 | 1472 |
| 1482 if (rest_parameter_ != nullptr) { | 1473 if (rest_parameter_ != nullptr) { |
| 1483 AllocateNonParameterLocal(isolate, rest_parameter_); | 1474 AllocateNonParameterLocal(rest_parameter_, ast_value_factory); |
| 1484 } | 1475 } |
| 1485 | 1476 |
| 1486 if (new_target_ != nullptr && !MustAllocate(new_target_)) { | 1477 if (new_target_ != nullptr && !MustAllocate(new_target_)) { |
| 1487 new_target_ = nullptr; | 1478 new_target_ = nullptr; |
| 1488 } | 1479 } |
| 1489 | 1480 |
| 1490 if (this_function_ != nullptr && !MustAllocate(this_function_)) { | 1481 if (this_function_ != nullptr && !MustAllocate(this_function_)) { |
| 1491 this_function_ = nullptr; | 1482 this_function_ = nullptr; |
| 1492 } | 1483 } |
| 1493 } | 1484 } |
| 1494 | 1485 |
| 1495 | 1486 void Scope::AllocateVariablesRecursively(AstValueFactory* ast_value_factory) { |
| 1496 void Scope::AllocateVariablesRecursively(Isolate* isolate) { | |
| 1497 if (!already_resolved()) { | 1487 if (!already_resolved()) { |
| 1498 num_stack_slots_ = 0; | 1488 num_stack_slots_ = 0; |
| 1499 } | 1489 } |
| 1500 // Allocate variables for inner scopes. | 1490 // Allocate variables for inner scopes. |
| 1501 for (int i = 0; i < inner_scopes_.length(); i++) { | 1491 for (int i = 0; i < inner_scopes_.length(); i++) { |
| 1502 inner_scopes_[i]->AllocateVariablesRecursively(isolate); | 1492 inner_scopes_[i]->AllocateVariablesRecursively(ast_value_factory); |
| 1503 } | 1493 } |
| 1504 | 1494 |
| 1505 // If scope is already resolved, we still need to allocate | 1495 // If scope is already resolved, we still need to allocate |
| 1506 // variables in inner scopes which might not have been resolved yet. | 1496 // variables in inner scopes which might not have been resolved yet. |
| 1507 if (already_resolved()) return; | 1497 if (already_resolved()) return; |
| 1508 // The number of slots required for variables. | 1498 // The number of slots required for variables. |
| 1509 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; | 1499 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; |
| 1510 | 1500 |
| 1511 // Allocate variables for this scope. | 1501 // Allocate variables for this scope. |
| 1512 // Parameters must be allocated first, if any. | 1502 // Parameters must be allocated first, if any. |
| 1513 if (is_function_scope()) AllocateParameterLocals(isolate); | 1503 if (is_function_scope()) AllocateParameterLocals(); |
| 1514 if (has_this_declaration()) AllocateReceiver(); | 1504 if (has_this_declaration()) AllocateReceiver(); |
| 1515 AllocateNonParameterLocalsAndDeclaredGlobals(isolate); | 1505 AllocateNonParameterLocalsAndDeclaredGlobals(ast_value_factory); |
| 1516 | 1506 |
| 1517 // Force allocation of a context for this scope if necessary. For a 'with' | 1507 // Force allocation of a context for this scope if necessary. For a 'with' |
| 1518 // scope and for a function scope that makes an 'eval' call we need a context, | 1508 // scope and for a function scope that makes an 'eval' call we need a context, |
| 1519 // even if no local variables were statically allocated in the scope. | 1509 // even if no local variables were statically allocated in the scope. |
| 1520 // Likewise for modules. | 1510 // Likewise for modules. |
| 1521 bool must_have_context = | 1511 bool must_have_context = |
| 1522 is_with_scope() || is_module_scope() || | 1512 is_with_scope() || is_module_scope() || |
| 1523 (is_function_scope() && calls_sloppy_eval()) || | 1513 (is_function_scope() && calls_sloppy_eval()) || |
| 1524 (is_block_scope() && is_declaration_scope() && calls_sloppy_eval()); | 1514 (is_block_scope() && is_declaration_scope() && calls_sloppy_eval()); |
| 1525 | 1515 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1546 function_ != NULL && function_->proxy()->var()->IsContextSlot(); | 1536 function_ != NULL && function_->proxy()->var()->IsContextSlot(); |
| 1547 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - | 1537 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - |
| 1548 (is_function_var_in_context ? 1 : 0); | 1538 (is_function_var_in_context ? 1 : 0); |
| 1549 } | 1539 } |
| 1550 | 1540 |
| 1551 | 1541 |
| 1552 int Scope::ContextGlobalCount() const { return num_global_slots(); } | 1542 int Scope::ContextGlobalCount() const { return num_global_slots(); } |
| 1553 | 1543 |
| 1554 } // namespace internal | 1544 } // namespace internal |
| 1555 } // namespace v8 | 1545 } // namespace v8 |
| OLD | NEW |