Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(260)

Side by Side Diff: src/scopes.cc

Issue 1218783005: Support for global var shortcuts in script contexts. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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"
11 #include "src/scopeinfo.h" 11 #include "src/scopeinfo.h"
12 #include "src/scopes.h" 12 #include "src/scopes.h"
13 13
14 namespace v8 { 14 namespace v8 {
15 namespace internal { 15 namespace internal {
16 16
17 // TODO(ishell): remove this once compiler support is landed.
18 bool enable_context_globals = false;
19
17 // ---------------------------------------------------------------------------- 20 // ----------------------------------------------------------------------------
18 // Implementation of LocalsMap 21 // Implementation of LocalsMap
19 // 22 //
20 // Note: We are storing the handle locations as key values in the hash map. 23 // Note: We are storing the handle locations as key values in the hash map.
21 // When inserting a new variable via Declare(), we rely on the fact that 24 // When inserting a new variable via Declare(), we rely on the fact that
22 // the handle location remains alive for the duration of that variable 25 // the handle location remains alive for the duration of that variable
23 // use. Because a Variable holding a handle with the same location exists 26 // use. Because a Variable holding a handle with the same location exists
24 // this is ensured. 27 // this is ensured.
25 28
26 VariableMap::VariableMap(Zone* zone) 29 VariableMap::VariableMap(Zone* zone)
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 language_mode_ = outer_scope != NULL ? outer_scope->language_mode_ : SLOPPY; 175 language_mode_ = outer_scope != NULL ? outer_scope->language_mode_ : SLOPPY;
173 outer_scope_calls_sloppy_eval_ = false; 176 outer_scope_calls_sloppy_eval_ = false;
174 inner_scope_calls_eval_ = false; 177 inner_scope_calls_eval_ = false;
175 inner_scope_uses_arguments_ = false; 178 inner_scope_uses_arguments_ = false;
176 force_eager_compilation_ = false; 179 force_eager_compilation_ = false;
177 force_context_allocation_ = (outer_scope != NULL && !is_function_scope()) 180 force_context_allocation_ = (outer_scope != NULL && !is_function_scope())
178 ? outer_scope->has_forced_context_allocation() : false; 181 ? outer_scope->has_forced_context_allocation() : false;
179 num_var_or_const_ = 0; 182 num_var_or_const_ = 0;
180 num_stack_slots_ = 0; 183 num_stack_slots_ = 0;
181 num_heap_slots_ = 0; 184 num_heap_slots_ = 0;
185 num_global_slots_ = 0;
182 num_modules_ = 0; 186 num_modules_ = 0;
183 module_var_ = NULL, 187 module_var_ = NULL,
184 rest_parameter_ = NULL; 188 rest_parameter_ = NULL;
185 rest_index_ = -1; 189 rest_index_ = -1;
186 scope_info_ = scope_info; 190 scope_info_ = scope_info;
187 start_position_ = RelocInfo::kNoPosition; 191 start_position_ = RelocInfo::kNoPosition;
188 end_position_ = RelocInfo::kNoPosition; 192 end_position_ = RelocInfo::kNoPosition;
189 if (!scope_info.is_null()) { 193 if (!scope_info.is_null()) {
190 scope_calls_eval_ = scope_info->CallsEval(); 194 scope_calls_eval_ = scope_info->CallsEval();
191 language_mode_ = scope_info->language_mode(); 195 language_mode_ = scope_info->language_mode();
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 Handle<String> name_handle = name->string(); 387 Handle<String> name_handle = name->string();
384 // The Scope is backed up by ScopeInfo. This means it cannot operate in a 388 // The Scope is backed up by ScopeInfo. This means it cannot operate in a
385 // heap-independent mode, and all strings must be internalized immediately. So 389 // heap-independent mode, and all strings must be internalized immediately. So
386 // it's ok to get the Handle<String> here. 390 // it's ok to get the Handle<String> here.
387 // If we have a serialized scope info, we might find the variable there. 391 // If we have a serialized scope info, we might find the variable there.
388 // There should be no local slot with the given name. 392 // There should be no local slot with the given name.
389 DCHECK(scope_info_->StackSlotIndex(*name_handle) < 0 || is_block_scope()); 393 DCHECK(scope_info_->StackSlotIndex(*name_handle) < 0 || is_block_scope());
390 394
391 // Check context slot lookup. 395 // Check context slot lookup.
392 VariableMode mode; 396 VariableMode mode;
397 ContextSlotKindFlag slot_kind;
393 Variable::Location location = Variable::CONTEXT; 398 Variable::Location location = Variable::CONTEXT;
394 InitializationFlag init_flag; 399 InitializationFlag init_flag;
395 MaybeAssignedFlag maybe_assigned_flag; 400 MaybeAssignedFlag maybe_assigned_flag;
396 int index = ScopeInfo::ContextSlotIndex(scope_info_, name_handle, &mode, 401 int index =
397 &init_flag, &maybe_assigned_flag); 402 ScopeInfo::ContextSlotIndex(scope_info_, name_handle, &mode, &slot_kind,
403 &init_flag, &maybe_assigned_flag);
398 if (index < 0) { 404 if (index < 0) {
399 // Check parameters. 405 // Check parameters.
400 index = scope_info_->ParameterIndex(*name_handle); 406 index = scope_info_->ParameterIndex(*name_handle);
401 if (index < 0) return NULL; 407 if (index < 0) return NULL;
402 408
403 mode = DYNAMIC; 409 mode = DYNAMIC;
404 location = Variable::LOOKUP; 410 location = Variable::LOOKUP;
405 init_flag = kCreatedInitialized; 411 init_flag = kCreatedInitialized;
406 // Be conservative and flag parameters as maybe assigned. Better information 412 // Be conservative and flag parameters as maybe assigned. Better information
407 // would require ScopeInfo to serialize the maybe_assigned bit also for 413 // would require ScopeInfo to serialize the maybe_assigned bit also for
408 // parameters. 414 // parameters.
409 maybe_assigned_flag = kMaybeAssigned; 415 maybe_assigned_flag = kMaybeAssigned;
416
417 } else if (slot_kind == ContextSlotKindFlag::kGlobal) {
418 DCHECK(is_script_scope());
419 DCHECK(IsDeclaredVariableMode(mode) && !IsLexicalVariableMode(mode));
420 location = Variable::UNALLOCATED;
410 } 421 }
411 422
412 Variable::Kind kind = Variable::NORMAL; 423 Variable::Kind kind = Variable::NORMAL;
413 if (location == Variable::CONTEXT && 424 if (location == Variable::CONTEXT &&
414 index == scope_info_->ReceiverContextSlotIndex()) { 425 index == scope_info_->ReceiverContextSlotIndex()) {
415 kind = Variable::THIS; 426 kind = Variable::THIS;
416 } 427 }
417 // TODO(marja, rossberg): Correctly declare FUNCTION, CLASS, NEW_TARGET, and 428 // TODO(marja, rossberg): Correctly declare FUNCTION, CLASS, NEW_TARGET, and
418 // ARGUMENTS bindings as their corresponding Variable::Kind. 429 // ARGUMENTS bindings as their corresponding Variable::Kind.
419 430
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
598 } 609 }
599 610
600 private: 611 private:
601 Variable* var_; 612 Variable* var_;
602 int order_; 613 int order_;
603 }; 614 };
604 615
605 616
606 void Scope::CollectStackAndContextLocals( 617 void Scope::CollectStackAndContextLocals(
607 ZoneList<Variable*>* stack_locals, ZoneList<Variable*>* context_locals, 618 ZoneList<Variable*>* stack_locals, ZoneList<Variable*>* context_locals,
619 ZoneList<Variable*>* context_globals,
608 ZoneList<Variable*>* strong_mode_free_variables) { 620 ZoneList<Variable*>* strong_mode_free_variables) {
609 DCHECK(stack_locals != NULL); 621 DCHECK(stack_locals != NULL);
610 DCHECK(context_locals != NULL); 622 DCHECK(context_locals != NULL);
623 DCHECK(context_globals != NULL);
611 624
612 // Collect internals which are always allocated on the heap. 625 // Collect internals which are always allocated on the heap.
613 for (int i = 0; i < internals_.length(); i++) { 626 for (int i = 0; i < internals_.length(); i++) {
614 Variable* var = internals_[i]; 627 Variable* var = internals_[i];
615 if (var->is_used()) { 628 if (var->is_used()) {
616 DCHECK(var->IsContextSlot()); 629 DCHECK(var->IsContextSlot());
617 context_locals->Add(var, zone()); 630 context_locals->Add(var, zone());
618 } 631 }
619 } 632 }
620 633
(...skipping 28 matching lines...) Expand all
649 } 662 }
650 } 663 }
651 vars.Sort(VarAndOrder::Compare); 664 vars.Sort(VarAndOrder::Compare);
652 int var_count = vars.length(); 665 int var_count = vars.length();
653 for (int i = 0; i < var_count; i++) { 666 for (int i = 0; i < var_count; i++) {
654 Variable* var = vars[i].var(); 667 Variable* var = vars[i].var();
655 if (var->IsStackLocal()) { 668 if (var->IsStackLocal()) {
656 stack_locals->Add(var, zone()); 669 stack_locals->Add(var, zone());
657 } else if (var->IsContextSlot()) { 670 } else if (var->IsContextSlot()) {
658 context_locals->Add(var, zone()); 671 context_locals->Add(var, zone());
672 } else if (enable_context_globals && var->IsStaticGlobalObjectProperty()) {
673 context_globals->Add(var, zone());
659 } 674 }
660 } 675 }
661 } 676 }
662 677
663 678
664 bool Scope::AllocateVariables(ParseInfo* info, AstNodeFactory* factory) { 679 bool Scope::AllocateVariables(ParseInfo* info, AstNodeFactory* factory) {
665 // 1) Propagate scope information. 680 // 1) Propagate scope information.
666 bool outer_scope_calls_sloppy_eval = false; 681 bool outer_scope_calls_sloppy_eval = false;
667 if (outer_scope_ != NULL) { 682 if (outer_scope_ != NULL) {
668 outer_scope_calls_sloppy_eval = 683 outer_scope_calls_sloppy_eval =
(...skipping 19 matching lines...) Expand all
688 703
689 704
690 bool Scope::HasTrivialContext() const { 705 bool Scope::HasTrivialContext() const {
691 // A function scope has a trivial context if it always is the global 706 // A function scope has a trivial context if it always is the global
692 // context. We iteratively scan out the context chain to see if 707 // context. We iteratively scan out the context chain to see if
693 // there is anything that makes this scope non-trivial; otherwise we 708 // there is anything that makes this scope non-trivial; otherwise we
694 // return true. 709 // return true.
695 for (const Scope* scope = this; scope != NULL; scope = scope->outer_scope_) { 710 for (const Scope* scope = this; scope != NULL; scope = scope->outer_scope_) {
696 if (scope->is_eval_scope()) return false; 711 if (scope->is_eval_scope()) return false;
697 if (scope->scope_inside_with_) return false; 712 if (scope->scope_inside_with_) return false;
698 if (scope->num_heap_slots_ > 0) return false; 713 if (scope->ContextLocalCount() > 0) return false;
699 } 714 }
700 return true; 715 return true;
701 } 716 }
702 717
703 718
704 bool Scope::HasTrivialOuterContext() const { 719 bool Scope::HasTrivialOuterContext() const {
705 Scope* outer = outer_scope_; 720 Scope* outer = outer_scope_;
706 if (outer == NULL) return true; 721 if (outer == NULL) return true;
707 // Note that the outer context may be trivial in general, but the current 722 // Note that the outer context may be trivial in general, but the current
708 // scope may be inside a 'with' statement in which case the outer context 723 // scope may be inside a 'with' statement in which case the outer context
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
824 839
825 840
826 static void PrintName(const AstRawString* name) { 841 static void PrintName(const AstRawString* name) {
827 PrintF("%.*s", name->length(), name->raw_data()); 842 PrintF("%.*s", name->length(), name->raw_data());
828 } 843 }
829 844
830 845
831 static void PrintLocation(Variable* var) { 846 static void PrintLocation(Variable* var) {
832 switch (var->location()) { 847 switch (var->location()) {
833 case Variable::UNALLOCATED: 848 case Variable::UNALLOCATED:
849 if (var->IsStaticGlobalObjectProperty()) {
850 PrintF("global[%d]", var->index());
851 }
834 break; 852 break;
835 case Variable::PARAMETER: 853 case Variable::PARAMETER:
836 PrintF("parameter[%d]", var->index()); 854 PrintF("parameter[%d]", var->index());
837 break; 855 break;
838 case Variable::LOCAL: 856 case Variable::LOCAL:
839 PrintF("local[%d]", var->index()); 857 PrintF("local[%d]", var->index());
840 break; 858 break;
841 case Variable::CONTEXT: 859 case Variable::CONTEXT:
842 PrintF("context[%d]", var->index()); 860 PrintF("context[%d]", var->index());
843 break; 861 break;
844 case Variable::LOOKUP: 862 case Variable::LOOKUP:
845 PrintF("lookup"); 863 PrintF("lookup");
846 break; 864 break;
847 } 865 }
848 } 866 }
849 867
850 868
851 static void PrintVar(int indent, Variable* var) { 869 static void PrintVar(int indent, Variable* var) {
852 if (var->is_used() || !var->IsUnallocated()) { 870 if (var->is_used() || !var->IsUnallocated() ||
871 var->IsStaticGlobalObjectProperty()) {
853 Indent(indent, Variable::Mode2String(var->mode())); 872 Indent(indent, Variable::Mode2String(var->mode()));
854 PrintF(" "); 873 PrintF(" ");
855 PrintName(var->raw_name()); 874 PrintName(var->raw_name());
856 PrintF("; // "); 875 PrintF("; // ");
857 PrintLocation(var); 876 PrintLocation(var);
858 bool comma = !var->IsUnallocated(); 877 bool comma = !var->IsUnallocated() || var->IsStaticGlobalObjectProperty();
859 if (var->has_forced_context_allocation()) { 878 if (var->has_forced_context_allocation()) {
860 if (comma) PrintF(", "); 879 if (comma) PrintF(", ");
861 PrintF("forced context allocation"); 880 PrintF("forced context allocation");
862 comma = true; 881 comma = true;
863 } 882 }
864 if (var->maybe_assigned() == kMaybeAssigned) { 883 if (var->maybe_assigned() == kMaybeAssigned) {
865 if (comma) PrintF(", "); 884 if (comma) PrintF(", ");
866 PrintF("maybe assigned"); 885 PrintF("maybe assigned");
867 } 886 }
868 PrintF("\n"); 887 PrintF("\n");
869 } 888 }
870 } 889 }
871 890
872 891
873 static void PrintMap(int indent, VariableMap* map) { 892 static void PrintMap(int indent, VariableMap* map) {
874 for (VariableMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) { 893 for (VariableMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) {
875 Variable* var = reinterpret_cast<Variable*>(p->value); 894 Variable* var = reinterpret_cast<Variable*>(p->value);
876 PrintVar(indent, var); 895 if (var == NULL) {
896 Indent(indent, "<?>\n");
897 } else {
898 PrintVar(indent, var);
899 }
877 } 900 }
878 } 901 }
879 902
880 903
881 void Scope::Print(int n) { 904 void Scope::Print(int n) {
882 int n0 = (n > 0 ? n : 0); 905 int n0 = (n > 0 ? n : 0);
883 int n1 = n0 + 2; // indentation 906 int n1 = n0 + 2; // indentation
884 907
885 // Print header. 908 // Print header.
886 Indent(n0, Header(scope_type_)); 909 Indent(n0, Header(scope_type_));
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
923 if (scope_uses_arguments_) Indent(n1, "// scope uses 'arguments'\n"); 946 if (scope_uses_arguments_) Indent(n1, "// scope uses 'arguments'\n");
924 if (scope_uses_super_property_) 947 if (scope_uses_super_property_)
925 Indent(n1, "// scope uses 'super' property\n"); 948 Indent(n1, "// scope uses 'super' property\n");
926 if (inner_scope_uses_arguments_) { 949 if (inner_scope_uses_arguments_) {
927 Indent(n1, "// inner scope uses 'arguments'\n"); 950 Indent(n1, "// inner scope uses 'arguments'\n");
928 } 951 }
929 if (outer_scope_calls_sloppy_eval_) { 952 if (outer_scope_calls_sloppy_eval_) {
930 Indent(n1, "// outer scope calls 'eval' in sloppy context\n"); 953 Indent(n1, "// outer scope calls 'eval' in sloppy context\n");
931 } 954 }
932 if (inner_scope_calls_eval_) Indent(n1, "// inner scope calls 'eval'\n"); 955 if (inner_scope_calls_eval_) Indent(n1, "// inner scope calls 'eval'\n");
933 if (num_stack_slots_ > 0) { Indent(n1, "// "); 956 if (num_stack_slots_ > 0) {
934 PrintF("%d stack slots\n", num_stack_slots_); } 957 Indent(n1, "// ");
935 if (num_heap_slots_ > 0) { Indent(n1, "// "); 958 PrintF("%d stack slots\n", num_stack_slots_);
936 PrintF("%d heap slots\n", num_heap_slots_); } 959 }
960 if (num_heap_slots_ > 0) {
961 Indent(n1, "// ");
962 PrintF("%d heap slots (including %d global slots)\n", num_heap_slots_,
963 num_global_slots_);
964 }
937 965
938 // Print locals. 966 // Print locals.
939 if (function_ != NULL) { 967 if (function_ != NULL) {
940 Indent(n1, "// function var:\n"); 968 Indent(n1, "// function var:\n");
941 PrintVar(n1, function_->proxy()->var()); 969 PrintVar(n1, function_->proxy()->var());
942 } 970 }
943 971
944 if (temps_.length() > 0) { 972 if (temps_.length() > 0) {
945 Indent(n1, "// temporary vars:\n"); 973 Indent(n1, "// temporary vars:\n");
946 for (int i = 0; i < temps_.length(); i++) { 974 for (int i = 0; i < temps_.length(); i++) {
(...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after
1413 DCHECK(var->IsUnallocated() || var->IsContextSlot()); 1441 DCHECK(var->IsUnallocated() || var->IsContextSlot());
1414 if (var->IsUnallocated()) { 1442 if (var->IsUnallocated()) {
1415 AllocateHeapSlot(var); 1443 AllocateHeapSlot(var);
1416 } 1444 }
1417 } else { 1445 } else {
1418 DCHECK(var->IsUnallocated() || var->IsParameter()); 1446 DCHECK(var->IsUnallocated() || var->IsParameter());
1419 if (var->IsUnallocated()) { 1447 if (var->IsUnallocated()) {
1420 var->AllocateTo(Variable::PARAMETER, index); 1448 var->AllocateTo(Variable::PARAMETER, index);
1421 } 1449 }
1422 } 1450 }
1451 } else {
1452 DCHECK(!var->IsStaticGlobalObjectProperty());
1423 } 1453 }
1424 } 1454 }
1425 1455
1426 1456
1427 void Scope::AllocateReceiver() { 1457 void Scope::AllocateReceiver() {
1428 DCHECK_NOT_NULL(receiver()); 1458 DCHECK_NOT_NULL(receiver());
1429 DCHECK_EQ(receiver()->scope(), this); 1459 DCHECK_EQ(receiver()->scope(), this);
1430 1460
1431 if (has_forced_context_allocation()) { 1461 if (has_forced_context_allocation()) {
1432 // Force context allocation of the receiver. 1462 // Force context allocation of the receiver.
(...skipping 10 matching lines...) Expand all
1443 if (var->IsUnallocated() && MustAllocate(var)) { 1473 if (var->IsUnallocated() && MustAllocate(var)) {
1444 if (MustAllocateInContext(var)) { 1474 if (MustAllocateInContext(var)) {
1445 AllocateHeapSlot(var); 1475 AllocateHeapSlot(var);
1446 } else { 1476 } else {
1447 AllocateStackSlot(var); 1477 AllocateStackSlot(var);
1448 } 1478 }
1449 } 1479 }
1450 } 1480 }
1451 1481
1452 1482
1453 void Scope::AllocateNonParameterLocals(Isolate* isolate) { 1483 void Scope::AllocateDeclaredGlobal(Isolate* isolate, Variable* var) {
1484 DCHECK(var->scope() == this);
1485 DCHECK(!var->IsVariable(isolate->factory()->dot_result_string()) ||
1486 !var->IsStackLocal());
1487 if (var->IsUnallocated() && var->IsStaticGlobalObjectProperty()) {
1488 DCHECK_EQ(-1, var->index());
1489 DCHECK(var->name()->IsString());
1490 var->AllocateTo(Variable::UNALLOCATED, num_heap_slots_);
1491 num_global_slots_++;
1492 // Each global variable occupies two slots in the context: for reads
1493 // and writes.
1494 num_heap_slots_ += 2;
1495 }
1496 }
1497
1498
1499 void Scope::AllocateNonParameterLocalsAndDeclaredGlobals(Isolate* isolate) {
1454 // All variables that have no rewrite yet are non-parameter locals. 1500 // All variables that have no rewrite yet are non-parameter locals.
1455 for (int i = 0; i < temps_.length(); i++) { 1501 for (int i = 0; i < temps_.length(); i++) {
1456 AllocateNonParameterLocal(isolate, temps_[i]); 1502 AllocateNonParameterLocal(isolate, temps_[i]);
1457 } 1503 }
1458 1504
1459 for (int i = 0; i < internals_.length(); i++) { 1505 for (int i = 0; i < internals_.length(); i++) {
1460 AllocateNonParameterLocal(isolate, internals_[i]); 1506 AllocateNonParameterLocal(isolate, internals_[i]);
1461 } 1507 }
1462 1508
1463 ZoneList<VarAndOrder> vars(variables_.occupancy(), zone()); 1509 ZoneList<VarAndOrder> vars(variables_.occupancy(), zone());
1464 for (VariableMap::Entry* p = variables_.Start(); 1510 for (VariableMap::Entry* p = variables_.Start();
1465 p != NULL; 1511 p != NULL;
1466 p = variables_.Next(p)) { 1512 p = variables_.Next(p)) {
1467 Variable* var = reinterpret_cast<Variable*>(p->value); 1513 Variable* var = reinterpret_cast<Variable*>(p->value);
1468 vars.Add(VarAndOrder(var, p->order), zone()); 1514 vars.Add(VarAndOrder(var, p->order), zone());
1469 } 1515 }
1470 vars.Sort(VarAndOrder::Compare); 1516 vars.Sort(VarAndOrder::Compare);
1471 int var_count = vars.length(); 1517 int var_count = vars.length();
1472 for (int i = 0; i < var_count; i++) { 1518 for (int i = 0; i < var_count; i++) {
1473 AllocateNonParameterLocal(isolate, vars[i].var()); 1519 AllocateNonParameterLocal(isolate, vars[i].var());
1474 } 1520 }
1475 1521
1522 if (enable_context_globals) {
1523 for (int i = 0; i < var_count; i++) {
1524 AllocateDeclaredGlobal(isolate, vars[i].var());
1525 }
1526 }
1527
1476 // For now, function_ must be allocated at the very end. If it gets 1528 // For now, function_ must be allocated at the very end. If it gets
1477 // allocated in the context, it must be the last slot in the context, 1529 // allocated in the context, it must be the last slot in the context,
1478 // because of the current ScopeInfo implementation (see 1530 // because of the current ScopeInfo implementation (see
1479 // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor). 1531 // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor).
1480 if (function_ != nullptr) { 1532 if (function_ != nullptr) {
1481 AllocateNonParameterLocal(isolate, function_->proxy()->var()); 1533 AllocateNonParameterLocal(isolate, function_->proxy()->var());
1482 } 1534 }
1483 1535
1484 if (rest_parameter_ != nullptr) { 1536 if (rest_parameter_ != nullptr) {
1485 AllocateNonParameterLocal(isolate, rest_parameter_); 1537 AllocateNonParameterLocal(isolate, rest_parameter_);
(...skipping 25 matching lines...) Expand all
1511 // If scope is already resolved, we still need to allocate 1563 // If scope is already resolved, we still need to allocate
1512 // variables in inner scopes which might not had been resolved yet. 1564 // variables in inner scopes which might not had been resolved yet.
1513 if (already_resolved()) return; 1565 if (already_resolved()) return;
1514 // The number of slots required for variables. 1566 // The number of slots required for variables.
1515 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; 1567 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS;
1516 1568
1517 // Allocate variables for this scope. 1569 // Allocate variables for this scope.
1518 // Parameters must be allocated first, if any. 1570 // Parameters must be allocated first, if any.
1519 if (is_function_scope()) AllocateParameterLocals(isolate); 1571 if (is_function_scope()) AllocateParameterLocals(isolate);
1520 if (has_this_declaration()) AllocateReceiver(); 1572 if (has_this_declaration()) AllocateReceiver();
1521 AllocateNonParameterLocals(isolate); 1573 AllocateNonParameterLocalsAndDeclaredGlobals(isolate);
1522 1574
1523 // Force allocation of a context for this scope if necessary. For a 'with' 1575 // Force allocation of a context for this scope if necessary. For a 'with'
1524 // scope and for a function scope that makes an 'eval' call we need a context, 1576 // scope and for a function scope that makes an 'eval' call we need a context,
1525 // even if no local variables were statically allocated in the scope. 1577 // even if no local variables were statically allocated in the scope.
1526 // Likewise for modules. 1578 // Likewise for modules.
1527 bool must_have_context = is_with_scope() || is_module_scope() || 1579 bool must_have_context = is_with_scope() || is_module_scope() ||
1528 (is_function_scope() && calls_sloppy_eval()); 1580 (is_function_scope() && calls_sloppy_eval());
1529 1581
1530 // If we didn't allocate any locals in the local context, then we only 1582 // If we didn't allocate any locals in the local context, then we only
1531 // need the minimal number of slots if we must have a context. 1583 // need the minimal number of slots if we must have a context.
(...skipping 23 matching lines...) Expand all
1555 1607
1556 1608
1557 int Scope::StackLocalCount() const { 1609 int Scope::StackLocalCount() const {
1558 return num_stack_slots() - 1610 return num_stack_slots() -
1559 (function_ != NULL && function_->proxy()->var()->IsStackLocal() ? 1 : 0); 1611 (function_ != NULL && function_->proxy()->var()->IsStackLocal() ? 1 : 0);
1560 } 1612 }
1561 1613
1562 1614
1563 int Scope::ContextLocalCount() const { 1615 int Scope::ContextLocalCount() const {
1564 if (num_heap_slots() == 0) return 0; 1616 if (num_heap_slots() == 0) return 0;
1617 bool is_function_var_in_context =
1618 function_ != NULL && function_->proxy()->var()->IsContextSlot();
1565 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - 1619 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS -
1566 (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0); 1620 2 * num_global_slots() - (is_function_var_in_context ? 1 : 0);
1567 } 1621 }
1622
1623
1624 int Scope::ContextGlobalCount() const { return num_global_slots(); }
1568 } // namespace internal 1625 } // namespace internal
1569 } // namespace v8 1626 } // namespace v8
OLDNEW
« src/runtime/runtime-scopes.cc ('K') | « src/scopes.h ('k') | src/typing.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698