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 |