| 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 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 225 #endif | 225 #endif |
| 226 inner_scope_ = nullptr; | 226 inner_scope_ = nullptr; |
| 227 sibling_ = nullptr; | 227 sibling_ = nullptr; |
| 228 unresolved_ = nullptr; | 228 unresolved_ = nullptr; |
| 229 | 229 |
| 230 start_position_ = kNoSourcePosition; | 230 start_position_ = kNoSourcePosition; |
| 231 end_position_ = kNoSourcePosition; | 231 end_position_ = kNoSourcePosition; |
| 232 | 232 |
| 233 num_stack_slots_ = 0; | 233 num_stack_slots_ = 0; |
| 234 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; | 234 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; |
| 235 num_global_slots_ = 0; | |
| 236 | 235 |
| 237 set_language_mode(SLOPPY); | 236 set_language_mode(SLOPPY); |
| 238 | 237 |
| 239 scope_calls_eval_ = false; | 238 scope_calls_eval_ = false; |
| 240 scope_nonlinear_ = false; | 239 scope_nonlinear_ = false; |
| 241 is_hidden_ = false; | 240 is_hidden_ = false; |
| 242 is_debug_evaluate_scope_ = false; | 241 is_debug_evaluate_scope_ = false; |
| 243 | 242 |
| 244 inner_scope_calls_eval_ = false; | 243 inner_scope_calls_eval_ = false; |
| 245 force_context_allocation_ = false; | 244 force_context_allocation_ = false; |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 333 script_scope->PropagateScopeInfo(); | 332 script_scope->PropagateScopeInfo(); |
| 334 return innermost_scope; | 333 return innermost_scope; |
| 335 } | 334 } |
| 336 | 335 |
| 337 void Scope::DeserializeScopeInfo(Isolate* isolate, | 336 void Scope::DeserializeScopeInfo(Isolate* isolate, |
| 338 AstValueFactory* ast_value_factory) { | 337 AstValueFactory* ast_value_factory) { |
| 339 if (scope_info_.is_null()) return; | 338 if (scope_info_.is_null()) return; |
| 340 | 339 |
| 341 DCHECK(ThreadId::Current().Equals(isolate->thread_id())); | 340 DCHECK(ThreadId::Current().Equals(isolate->thread_id())); |
| 342 | 341 |
| 343 // Internalize context local & globals variables. | 342 // Internalize context local variables. |
| 344 for (int var = 0; var < scope_info_->ContextLocalCount() + | 343 for (int var = 0; var < scope_info_->ContextLocalCount(); ++var) { |
| 345 scope_info_->ContextGlobalCount(); | |
| 346 ++var) { | |
| 347 Handle<String> name_handle(scope_info_->ContextLocalName(var), isolate); | 344 Handle<String> name_handle(scope_info_->ContextLocalName(var), isolate); |
| 348 const AstRawString* name = ast_value_factory->GetString(name_handle); | 345 const AstRawString* name = ast_value_factory->GetString(name_handle); |
| 349 int index = Context::MIN_CONTEXT_SLOTS + var; | 346 int index = Context::MIN_CONTEXT_SLOTS + var; |
| 350 VariableMode mode = scope_info_->ContextLocalMode(var); | 347 VariableMode mode = scope_info_->ContextLocalMode(var); |
| 351 InitializationFlag init_flag = scope_info_->ContextLocalInitFlag(var); | 348 InitializationFlag init_flag = scope_info_->ContextLocalInitFlag(var); |
| 352 MaybeAssignedFlag maybe_assigned_flag = | 349 MaybeAssignedFlag maybe_assigned_flag = |
| 353 scope_info_->ContextLocalMaybeAssignedFlag(var); | 350 scope_info_->ContextLocalMaybeAssignedFlag(var); |
| 354 VariableLocation location = var < scope_info_->ContextLocalCount() | 351 VariableLocation location = VariableLocation::CONTEXT; |
| 355 ? VariableLocation::CONTEXT | |
| 356 : VariableLocation::GLOBAL; | |
| 357 Variable::Kind kind = Variable::NORMAL; | 352 Variable::Kind kind = Variable::NORMAL; |
| 358 if (index == scope_info_->ReceiverContextSlotIndex()) { | 353 if (index == scope_info_->ReceiverContextSlotIndex()) { |
| 359 kind = Variable::THIS; | 354 kind = Variable::THIS; |
| 360 } | 355 } |
| 361 | 356 |
| 362 Variable* result = variables_.Declare(zone(), this, name, mode, kind, | 357 Variable* result = variables_.Declare(zone(), this, name, mode, kind, |
| 363 init_flag, maybe_assigned_flag); | 358 init_flag, maybe_assigned_flag); |
| 364 result->AllocateTo(location, index); | 359 result->AllocateTo(location, index); |
| 365 } | 360 } |
| 366 | 361 |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 596 // There should be no local slot with the given name. | 591 // There should be no local slot with the given name. |
| 597 DCHECK_LT(scope_info_->StackSlotIndex(*name_handle), 0); | 592 DCHECK_LT(scope_info_->StackSlotIndex(*name_handle), 0); |
| 598 | 593 |
| 599 VariableMode mode; | 594 VariableMode mode; |
| 600 InitializationFlag init_flag; | 595 InitializationFlag init_flag; |
| 601 MaybeAssignedFlag maybe_assigned_flag; | 596 MaybeAssignedFlag maybe_assigned_flag; |
| 602 | 597 |
| 603 VariableLocation location = VariableLocation::CONTEXT; | 598 VariableLocation location = VariableLocation::CONTEXT; |
| 604 int index = ScopeInfo::ContextSlotIndex(scope_info_, name_handle, &mode, | 599 int index = ScopeInfo::ContextSlotIndex(scope_info_, name_handle, &mode, |
| 605 &init_flag, &maybe_assigned_flag); | 600 &init_flag, &maybe_assigned_flag); |
| 606 if (index < 0) { | |
| 607 location = VariableLocation::GLOBAL; | |
| 608 index = ScopeInfo::ContextGlobalSlotIndex(scope_info_, name_handle, &mode, | |
| 609 &init_flag, &maybe_assigned_flag); | |
| 610 DCHECK(index < 0 || (is_script_scope() && mode == VAR)); | |
| 611 } | |
| 612 if (index < 0 && scope_type() == MODULE_SCOPE) { | 601 if (index < 0 && scope_type() == MODULE_SCOPE) { |
| 613 location = VariableLocation::MODULE; | 602 location = VariableLocation::MODULE; |
| 614 index = -1; // TODO(neis): Find module variables in scope info. | 603 index = -1; // TODO(neis): Find module variables in scope info. |
| 615 } | 604 } |
| 616 if (index < 0) return nullptr; // Nowhere found. | 605 if (index < 0) return nullptr; // Nowhere found. |
| 617 | 606 |
| 618 Variable::Kind kind = Variable::NORMAL; | 607 Variable::Kind kind = Variable::NORMAL; |
| 619 if (location == VariableLocation::CONTEXT && | 608 if (location == VariableLocation::CONTEXT && |
| 620 index == scope_info_->ReceiverContextSlotIndex()) { | 609 index == scope_info_->ReceiverContextSlotIndex()) { |
| 621 kind = Variable::THIS; | 610 kind = Variable::THIS; |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 783 if (decls_[j]->proxy()->raw_name() == name) { | 772 if (decls_[j]->proxy()->raw_name() == name) { |
| 784 return decls_[j]; | 773 return decls_[j]; |
| 785 } | 774 } |
| 786 } | 775 } |
| 787 DCHECK(false); | 776 DCHECK(false); |
| 788 } | 777 } |
| 789 } | 778 } |
| 790 return nullptr; | 779 return nullptr; |
| 791 } | 780 } |
| 792 | 781 |
| 793 void Scope::CollectVariables(ZoneList<Variable*>* stack_locals, | |
| 794 ZoneList<Variable*>* context_locals, | |
| 795 ZoneList<Variable*>* context_globals) { | |
| 796 // TODO(verwaest): Just pass out locals_ directly and walk it? | |
| 797 DCHECK_NOT_NULL(stack_locals); | |
| 798 DCHECK_NOT_NULL(context_locals); | |
| 799 DCHECK_NOT_NULL(context_globals); | |
| 800 | |
| 801 for (int i = 0; i < locals_.length(); i++) { | |
| 802 Variable* var = locals_[i]; | |
| 803 if (var->IsStackLocal()) { | |
| 804 stack_locals->Add(var, zone()); | |
| 805 } else if (var->IsContextSlot()) { | |
| 806 context_locals->Add(var, zone()); | |
| 807 } else if (var->IsGlobalSlot()) { | |
| 808 context_globals->Add(var, zone()); | |
| 809 } | |
| 810 } | |
| 811 } | |
| 812 | |
| 813 void DeclarationScope::AllocateVariables(ParseInfo* info) { | 782 void DeclarationScope::AllocateVariables(ParseInfo* info) { |
| 814 // 1) Propagate scope information. | 783 // 1) Propagate scope information. |
| 815 PropagateScopeInfo(); | 784 PropagateScopeInfo(); |
| 816 | 785 |
| 817 // 2) Resolve variables. | 786 // 2) Resolve variables. |
| 818 ResolveVariablesRecursively(info); | 787 ResolveVariablesRecursively(info); |
| 819 | 788 |
| 820 // 3) Allocate variables. | 789 // 3) Allocate variables. |
| 821 AllocateVariablesRecursively(); | 790 AllocateVariablesRecursively(); |
| 822 } | 791 } |
| (...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1109 if (is_declaration_scope() && AsDeclarationScope()->uses_super_property()) { | 1078 if (is_declaration_scope() && AsDeclarationScope()->uses_super_property()) { |
| 1110 Indent(n1, "// scope uses 'super' property\n"); | 1079 Indent(n1, "// scope uses 'super' property\n"); |
| 1111 } | 1080 } |
| 1112 if (inner_scope_calls_eval_) Indent(n1, "// inner scope calls 'eval'\n"); | 1081 if (inner_scope_calls_eval_) Indent(n1, "// inner scope calls 'eval'\n"); |
| 1113 if (num_stack_slots_ > 0) { | 1082 if (num_stack_slots_ > 0) { |
| 1114 Indent(n1, "// "); | 1083 Indent(n1, "// "); |
| 1115 PrintF("%d stack slots\n", num_stack_slots_); | 1084 PrintF("%d stack slots\n", num_stack_slots_); |
| 1116 } | 1085 } |
| 1117 if (num_heap_slots_ > 0) { | 1086 if (num_heap_slots_ > 0) { |
| 1118 Indent(n1, "// "); | 1087 Indent(n1, "// "); |
| 1119 PrintF("%d heap slots (including %d global slots)\n", num_heap_slots_, | 1088 PrintF("%d heap slots\n", num_heap_slots_); |
| 1120 num_global_slots_); | |
| 1121 } | 1089 } |
| 1122 | 1090 |
| 1123 // Print locals. | 1091 // Print locals. |
| 1124 if (function != nullptr) { | 1092 if (function != nullptr) { |
| 1125 Indent(n1, "// function var:\n"); | 1093 Indent(n1, "// function var:\n"); |
| 1126 PrintVar(n1, function); | 1094 PrintVar(n1, function); |
| 1127 } | 1095 } |
| 1128 | 1096 |
| 1129 if (variables_.Start() != NULL) { | 1097 if (variables_.Start() != NULL) { |
| 1130 Indent(n1, "// local vars:\n"); | 1098 Indent(n1, "// local vars:\n"); |
| (...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1461 DCHECK(var->IsUnallocated() || var->IsContextSlot()); | 1429 DCHECK(var->IsUnallocated() || var->IsContextSlot()); |
| 1462 if (var->IsUnallocated()) { | 1430 if (var->IsUnallocated()) { |
| 1463 AllocateHeapSlot(var); | 1431 AllocateHeapSlot(var); |
| 1464 } | 1432 } |
| 1465 } else { | 1433 } else { |
| 1466 DCHECK(var->IsUnallocated() || var->IsParameter()); | 1434 DCHECK(var->IsUnallocated() || var->IsParameter()); |
| 1467 if (var->IsUnallocated()) { | 1435 if (var->IsUnallocated()) { |
| 1468 var->AllocateTo(VariableLocation::PARAMETER, index); | 1436 var->AllocateTo(VariableLocation::PARAMETER, index); |
| 1469 } | 1437 } |
| 1470 } | 1438 } |
| 1471 } else { | |
| 1472 DCHECK(!var->IsGlobalSlot()); | |
| 1473 } | 1439 } |
| 1474 } | 1440 } |
| 1475 | 1441 |
| 1476 void DeclarationScope::AllocateReceiver() { | 1442 void DeclarationScope::AllocateReceiver() { |
| 1477 if (!has_this_declaration()) return; | 1443 if (!has_this_declaration()) return; |
| 1478 DCHECK_NOT_NULL(receiver()); | 1444 DCHECK_NOT_NULL(receiver()); |
| 1479 DCHECK_EQ(receiver()->scope(), this); | 1445 DCHECK_EQ(receiver()->scope(), this); |
| 1480 AllocateParameter(receiver(), -1); | 1446 AllocateParameter(receiver(), -1); |
| 1481 } | 1447 } |
| 1482 | 1448 |
| 1483 void Scope::AllocateNonParameterLocal(Variable* var) { | 1449 void Scope::AllocateNonParameterLocal(Variable* var) { |
| 1484 DCHECK(var->scope() == this); | 1450 DCHECK(var->scope() == this); |
| 1485 if (var->IsUnallocated() && MustAllocate(var)) { | 1451 if (var->IsUnallocated() && MustAllocate(var)) { |
| 1486 if (MustAllocateInContext(var)) { | 1452 if (MustAllocateInContext(var)) { |
| 1487 AllocateHeapSlot(var); | 1453 AllocateHeapSlot(var); |
| 1488 } else { | 1454 } else { |
| 1489 AllocateStackSlot(var); | 1455 AllocateStackSlot(var); |
| 1490 } | 1456 } |
| 1491 } | 1457 } |
| 1492 } | 1458 } |
| 1493 | 1459 |
| 1494 void Scope::AllocateDeclaredGlobal(Variable* var) { | |
| 1495 DCHECK(var->scope() == this); | |
| 1496 if (var->IsUnallocated()) { | |
| 1497 if (var->IsStaticGlobalObjectProperty()) { | |
| 1498 DCHECK_EQ(-1, var->index()); | |
| 1499 DCHECK(var->name()->IsString()); | |
| 1500 var->AllocateTo(VariableLocation::GLOBAL, num_heap_slots_++); | |
| 1501 num_global_slots_++; | |
| 1502 } else { | |
| 1503 // There must be only DYNAMIC_GLOBAL in the script scope. | |
| 1504 DCHECK(!is_script_scope() || DYNAMIC_GLOBAL == var->mode()); | |
| 1505 } | |
| 1506 } | |
| 1507 } | |
| 1508 | |
| 1509 void Scope::AllocateNonParameterLocalsAndDeclaredGlobals() { | 1460 void Scope::AllocateNonParameterLocalsAndDeclaredGlobals() { |
| 1510 for (int i = 0; i < locals_.length(); i++) { | 1461 for (int i = 0; i < locals_.length(); i++) { |
| 1511 AllocateNonParameterLocal(locals_[i]); | 1462 AllocateNonParameterLocal(locals_[i]); |
| 1512 } | 1463 } |
| 1513 | 1464 |
| 1514 if (FLAG_global_var_shortcuts) { | |
| 1515 for (int i = 0; i < locals_.length(); i++) { | |
| 1516 AllocateDeclaredGlobal(locals_[i]); | |
| 1517 } | |
| 1518 } | |
| 1519 | |
| 1520 if (is_declaration_scope()) { | 1465 if (is_declaration_scope()) { |
| 1521 AsDeclarationScope()->AllocateLocals(); | 1466 AsDeclarationScope()->AllocateLocals(); |
| 1522 } | 1467 } |
| 1523 } | 1468 } |
| 1524 | 1469 |
| 1525 void DeclarationScope::AllocateLocals() { | 1470 void DeclarationScope::AllocateLocals() { |
| 1526 // For now, function_ must be allocated at the very end. If it gets | 1471 // For now, function_ must be allocated at the very end. If it gets |
| 1527 // allocated in the context, it must be the last slot in the context, | 1472 // allocated in the context, it must be the last slot in the context, |
| 1528 // because of the current ScopeInfo implementation (see | 1473 // because of the current ScopeInfo implementation (see |
| 1529 // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor). | 1474 // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor). |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1607 (function != nullptr && function->IsStackLocal() ? 1 : 0); | 1552 (function != nullptr && function->IsStackLocal() ? 1 : 0); |
| 1608 } | 1553 } |
| 1609 | 1554 |
| 1610 | 1555 |
| 1611 int Scope::ContextLocalCount() const { | 1556 int Scope::ContextLocalCount() const { |
| 1612 if (num_heap_slots() == 0) return 0; | 1557 if (num_heap_slots() == 0) return 0; |
| 1613 Variable* function = | 1558 Variable* function = |
| 1614 is_function_scope() ? AsDeclarationScope()->function_var() : nullptr; | 1559 is_function_scope() ? AsDeclarationScope()->function_var() : nullptr; |
| 1615 bool is_function_var_in_context = | 1560 bool is_function_var_in_context = |
| 1616 function != nullptr && function->IsContextSlot(); | 1561 function != nullptr && function->IsContextSlot(); |
| 1617 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - | 1562 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - |
| 1618 (is_function_var_in_context ? 1 : 0); | 1563 (is_function_var_in_context ? 1 : 0); |
| 1619 } | 1564 } |
| 1620 | 1565 |
| 1621 | |
| 1622 int Scope::ContextGlobalCount() const { return num_global_slots(); } | |
| 1623 | |
| 1624 } // namespace internal | 1566 } // namespace internal |
| 1625 } // namespace v8 | 1567 } // namespace v8 |
| OLD | NEW |