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

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: Fixing builds 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
« no previous file with comments | « src/scopes.h ('k') | src/typing.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
171 language_mode_ = outer_scope != NULL ? outer_scope->language_mode_ : SLOPPY; 174 language_mode_ = outer_scope != NULL ? outer_scope->language_mode_ : SLOPPY;
172 outer_scope_calls_sloppy_eval_ = false; 175 outer_scope_calls_sloppy_eval_ = false;
173 inner_scope_calls_eval_ = false; 176 inner_scope_calls_eval_ = false;
174 inner_scope_uses_arguments_ = false; 177 inner_scope_uses_arguments_ = false;
175 force_eager_compilation_ = false; 178 force_eager_compilation_ = false;
176 force_context_allocation_ = (outer_scope != NULL && !is_function_scope()) 179 force_context_allocation_ = (outer_scope != NULL && !is_function_scope())
177 ? outer_scope->has_forced_context_allocation() : false; 180 ? outer_scope->has_forced_context_allocation() : false;
178 num_var_or_const_ = 0; 181 num_var_or_const_ = 0;
179 num_stack_slots_ = 0; 182 num_stack_slots_ = 0;
180 num_heap_slots_ = 0; 183 num_heap_slots_ = 0;
184 num_global_slots_ = 0;
181 num_modules_ = 0; 185 num_modules_ = 0;
182 module_var_ = NULL, 186 module_var_ = NULL,
183 rest_parameter_ = NULL; 187 rest_parameter_ = NULL;
184 rest_index_ = -1; 188 rest_index_ = -1;
185 scope_info_ = scope_info; 189 scope_info_ = scope_info;
186 start_position_ = RelocInfo::kNoPosition; 190 start_position_ = RelocInfo::kNoPosition;
187 end_position_ = RelocInfo::kNoPosition; 191 end_position_ = RelocInfo::kNoPosition;
188 if (!scope_info.is_null()) { 192 if (!scope_info.is_null()) {
189 scope_calls_eval_ = scope_info->CallsEval(); 193 scope_calls_eval_ = scope_info->CallsEval();
190 language_mode_ = scope_info->language_mode(); 194 language_mode_ = scope_info->language_mode();
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
381 Handle<String> name_handle = name->string(); 385 Handle<String> name_handle = name->string();
382 // The Scope is backed up by ScopeInfo. This means it cannot operate in a 386 // The Scope is backed up by ScopeInfo. This means it cannot operate in a
383 // heap-independent mode, and all strings must be internalized immediately. So 387 // heap-independent mode, and all strings must be internalized immediately. So
384 // it's ok to get the Handle<String> here. 388 // it's ok to get the Handle<String> here.
385 // If we have a serialized scope info, we might find the variable there. 389 // If we have a serialized scope info, we might find the variable there.
386 // There should be no local slot with the given name. 390 // There should be no local slot with the given name.
387 DCHECK(scope_info_->StackSlotIndex(*name_handle) < 0 || is_block_scope()); 391 DCHECK(scope_info_->StackSlotIndex(*name_handle) < 0 || is_block_scope());
388 392
389 // Check context slot lookup. 393 // Check context slot lookup.
390 VariableMode mode; 394 VariableMode mode;
391 Variable::Location location = Variable::CONTEXT; 395 VariableLocation location;
392 InitializationFlag init_flag; 396 InitializationFlag init_flag;
393 MaybeAssignedFlag maybe_assigned_flag; 397 MaybeAssignedFlag maybe_assigned_flag;
394 int index = ScopeInfo::ContextSlotIndex(scope_info_, name_handle, &mode, 398 int index =
395 &init_flag, &maybe_assigned_flag); 399 ScopeInfo::ContextSlotIndex(scope_info_, name_handle, &mode, &location,
400 &init_flag, &maybe_assigned_flag);
396 if (index < 0) { 401 if (index < 0) {
397 // Check parameters. 402 // Check parameters.
398 index = scope_info_->ParameterIndex(*name_handle); 403 index = scope_info_->ParameterIndex(*name_handle);
399 if (index < 0) return NULL; 404 if (index < 0) return NULL;
400 405
401 mode = DYNAMIC; 406 mode = DYNAMIC;
402 location = Variable::LOOKUP; 407 location = VariableLocation::LOOKUP;
403 init_flag = kCreatedInitialized; 408 init_flag = kCreatedInitialized;
404 // Be conservative and flag parameters as maybe assigned. Better information 409 // Be conservative and flag parameters as maybe assigned. Better information
405 // would require ScopeInfo to serialize the maybe_assigned bit also for 410 // would require ScopeInfo to serialize the maybe_assigned bit also for
406 // parameters. 411 // parameters.
407 maybe_assigned_flag = kMaybeAssigned; 412 maybe_assigned_flag = kMaybeAssigned;
413 } else {
414 DCHECK(location != VariableLocation::GLOBAL ||
415 (is_script_scope() && IsDeclaredVariableMode(mode) &&
416 !IsLexicalVariableMode(mode)));
408 } 417 }
409 418
410 Variable::Kind kind = Variable::NORMAL; 419 Variable::Kind kind = Variable::NORMAL;
411 if (location == Variable::CONTEXT && 420 if (location == VariableLocation::CONTEXT &&
412 index == scope_info_->ReceiverContextSlotIndex()) { 421 index == scope_info_->ReceiverContextSlotIndex()) {
413 kind = Variable::THIS; 422 kind = Variable::THIS;
414 } 423 }
415 // TODO(marja, rossberg): Correctly declare FUNCTION, CLASS, NEW_TARGET, and 424 // TODO(marja, rossberg): Correctly declare FUNCTION, CLASS, NEW_TARGET, and
416 // ARGUMENTS bindings as their corresponding Variable::Kind. 425 // ARGUMENTS bindings as their corresponding Variable::Kind.
417 426
418 Variable* var = variables_.Declare(this, name, mode, kind, init_flag, 427 Variable* var = variables_.Declare(this, name, mode, kind, init_flag,
419 maybe_assigned_flag); 428 maybe_assigned_flag);
420 var->AllocateTo(location, index); 429 var->AllocateTo(location, index);
421 return var; 430 return var;
422 } 431 }
423 432
424 433
425 Variable* Scope::LookupFunctionVar(const AstRawString* name, 434 Variable* Scope::LookupFunctionVar(const AstRawString* name,
426 AstNodeFactory* factory) { 435 AstNodeFactory* factory) {
427 if (function_ != NULL && function_->proxy()->raw_name() == name) { 436 if (function_ != NULL && function_->proxy()->raw_name() == name) {
428 return function_->proxy()->var(); 437 return function_->proxy()->var();
429 } else if (!scope_info_.is_null()) { 438 } else if (!scope_info_.is_null()) {
430 // If we are backed by a scope info, try to lookup the variable there. 439 // If we are backed by a scope info, try to lookup the variable there.
431 VariableMode mode; 440 VariableMode mode;
432 int index = scope_info_->FunctionContextSlotIndex(*(name->string()), &mode); 441 int index = scope_info_->FunctionContextSlotIndex(*(name->string()), &mode);
433 if (index < 0) return NULL; 442 if (index < 0) return NULL;
434 Variable* var = new (zone()) 443 Variable* var = new (zone())
435 Variable(this, name, mode, Variable::NORMAL, kCreatedInitialized); 444 Variable(this, name, mode, Variable::NORMAL, kCreatedInitialized);
436 VariableProxy* proxy = factory->NewVariableProxy(var); 445 VariableProxy* proxy = factory->NewVariableProxy(var);
437 VariableDeclaration* declaration = factory->NewVariableDeclaration( 446 VariableDeclaration* declaration = factory->NewVariableDeclaration(
438 proxy, mode, this, RelocInfo::kNoPosition); 447 proxy, mode, this, RelocInfo::kNoPosition);
439 DeclareFunctionVar(declaration); 448 DeclareFunctionVar(declaration);
440 var->AllocateTo(Variable::CONTEXT, index); 449 var->AllocateTo(VariableLocation::CONTEXT, index);
441 return var; 450 return var;
442 } else { 451 } else {
443 return NULL; 452 return NULL;
444 } 453 }
445 } 454 }
446 455
447 456
448 Variable* Scope::Lookup(const AstRawString* name) { 457 Variable* Scope::Lookup(const AstRawString* name) {
449 for (Scope* scope = this; 458 for (Scope* scope = this;
450 scope != NULL; 459 scope != NULL;
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
596 } 605 }
597 606
598 private: 607 private:
599 Variable* var_; 608 Variable* var_;
600 int order_; 609 int order_;
601 }; 610 };
602 611
603 612
604 void Scope::CollectStackAndContextLocals( 613 void Scope::CollectStackAndContextLocals(
605 ZoneList<Variable*>* stack_locals, ZoneList<Variable*>* context_locals, 614 ZoneList<Variable*>* stack_locals, ZoneList<Variable*>* context_locals,
615 ZoneList<Variable*>* context_globals,
606 ZoneList<Variable*>* strong_mode_free_variables) { 616 ZoneList<Variable*>* strong_mode_free_variables) {
607 DCHECK(stack_locals != NULL); 617 DCHECK(stack_locals != NULL);
608 DCHECK(context_locals != NULL); 618 DCHECK(context_locals != NULL);
619 DCHECK(context_globals != NULL);
609 620
610 // Collect internals which are always allocated on the heap. 621 // Collect internals which are always allocated on the heap.
611 for (int i = 0; i < internals_.length(); i++) { 622 for (int i = 0; i < internals_.length(); i++) {
612 Variable* var = internals_[i]; 623 Variable* var = internals_[i];
613 if (var->is_used()) { 624 if (var->is_used()) {
614 DCHECK(var->IsContextSlot()); 625 DCHECK(var->IsContextSlot());
615 context_locals->Add(var, zone()); 626 context_locals->Add(var, zone());
616 } 627 }
617 } 628 }
618 629
(...skipping 28 matching lines...) Expand all
647 } 658 }
648 } 659 }
649 vars.Sort(VarAndOrder::Compare); 660 vars.Sort(VarAndOrder::Compare);
650 int var_count = vars.length(); 661 int var_count = vars.length();
651 for (int i = 0; i < var_count; i++) { 662 for (int i = 0; i < var_count; i++) {
652 Variable* var = vars[i].var(); 663 Variable* var = vars[i].var();
653 if (var->IsStackLocal()) { 664 if (var->IsStackLocal()) {
654 stack_locals->Add(var, zone()); 665 stack_locals->Add(var, zone());
655 } else if (var->IsContextSlot()) { 666 } else if (var->IsContextSlot()) {
656 context_locals->Add(var, zone()); 667 context_locals->Add(var, zone());
668 } else if (var->IsGlobalSlot()) {
669 context_globals->Add(var, zone());
657 } 670 }
658 } 671 }
659 } 672 }
660 673
661 674
662 bool Scope::AllocateVariables(ParseInfo* info, AstNodeFactory* factory) { 675 bool Scope::AllocateVariables(ParseInfo* info, AstNodeFactory* factory) {
663 // 1) Propagate scope information. 676 // 1) Propagate scope information.
664 bool outer_scope_calls_sloppy_eval = false; 677 bool outer_scope_calls_sloppy_eval = false;
665 if (outer_scope_ != NULL) { 678 if (outer_scope_ != NULL) {
666 outer_scope_calls_sloppy_eval = 679 outer_scope_calls_sloppy_eval =
(...skipping 19 matching lines...) Expand all
686 699
687 700
688 bool Scope::HasTrivialContext() const { 701 bool Scope::HasTrivialContext() const {
689 // A function scope has a trivial context if it always is the global 702 // A function scope has a trivial context if it always is the global
690 // context. We iteratively scan out the context chain to see if 703 // context. We iteratively scan out the context chain to see if
691 // there is anything that makes this scope non-trivial; otherwise we 704 // there is anything that makes this scope non-trivial; otherwise we
692 // return true. 705 // return true.
693 for (const Scope* scope = this; scope != NULL; scope = scope->outer_scope_) { 706 for (const Scope* scope = this; scope != NULL; scope = scope->outer_scope_) {
694 if (scope->is_eval_scope()) return false; 707 if (scope->is_eval_scope()) return false;
695 if (scope->scope_inside_with_) return false; 708 if (scope->scope_inside_with_) return false;
696 if (scope->num_heap_slots_ > 0) return false; 709 if (scope->ContextLocalCount() > 0) return false;
697 } 710 }
698 return true; 711 return true;
699 } 712 }
700 713
701 714
702 bool Scope::HasTrivialOuterContext() const { 715 bool Scope::HasTrivialOuterContext() const {
703 Scope* outer = outer_scope_; 716 Scope* outer = outer_scope_;
704 if (outer == NULL) return true; 717 if (outer == NULL) return true;
705 // Note that the outer context may be trivial in general, but the current 718 // Note that the outer context may be trivial in general, but the current
706 // scope may be inside a 'with' statement in which case the outer context 719 // scope may be inside a 'with' statement in which case the outer context
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
821 } 834 }
822 835
823 836
824 static void PrintName(const AstRawString* name) { 837 static void PrintName(const AstRawString* name) {
825 PrintF("%.*s", name->length(), name->raw_data()); 838 PrintF("%.*s", name->length(), name->raw_data());
826 } 839 }
827 840
828 841
829 static void PrintLocation(Variable* var) { 842 static void PrintLocation(Variable* var) {
830 switch (var->location()) { 843 switch (var->location()) {
831 case Variable::UNALLOCATED: 844 case VariableLocation::UNALLOCATED:
832 break; 845 break;
833 case Variable::PARAMETER: 846 case VariableLocation::PARAMETER:
834 PrintF("parameter[%d]", var->index()); 847 PrintF("parameter[%d]", var->index());
835 break; 848 break;
836 case Variable::LOCAL: 849 case VariableLocation::LOCAL:
837 PrintF("local[%d]", var->index()); 850 PrintF("local[%d]", var->index());
838 break; 851 break;
839 case Variable::CONTEXT: 852 case VariableLocation::CONTEXT:
840 PrintF("context[%d]", var->index()); 853 PrintF("context[%d]", var->index());
841 break; 854 break;
842 case Variable::LOOKUP: 855 case VariableLocation::GLOBAL:
856 PrintF("global[%d]", var->index());
857 break;
858 case VariableLocation::LOOKUP:
843 PrintF("lookup"); 859 PrintF("lookup");
844 break; 860 break;
845 } 861 }
846 } 862 }
847 863
848 864
849 static void PrintVar(int indent, Variable* var) { 865 static void PrintVar(int indent, Variable* var) {
850 if (var->is_used() || !var->IsUnallocated()) { 866 if (var->is_used() || !var->IsUnallocated()) {
851 Indent(indent, Variable::Mode2String(var->mode())); 867 Indent(indent, Variable::Mode2String(var->mode()));
852 PrintF(" "); 868 PrintF(" ");
(...skipping 11 matching lines...) Expand all
864 PrintF("maybe assigned"); 880 PrintF("maybe assigned");
865 } 881 }
866 PrintF("\n"); 882 PrintF("\n");
867 } 883 }
868 } 884 }
869 885
870 886
871 static void PrintMap(int indent, VariableMap* map) { 887 static void PrintMap(int indent, VariableMap* map) {
872 for (VariableMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) { 888 for (VariableMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) {
873 Variable* var = reinterpret_cast<Variable*>(p->value); 889 Variable* var = reinterpret_cast<Variable*>(p->value);
874 PrintVar(indent, var); 890 if (var == NULL) {
891 Indent(indent, "<?>\n");
892 } else {
893 PrintVar(indent, var);
894 }
875 } 895 }
876 } 896 }
877 897
878 898
879 void Scope::Print(int n) { 899 void Scope::Print(int n) {
880 int n0 = (n > 0 ? n : 0); 900 int n0 = (n > 0 ? n : 0);
881 int n1 = n0 + 2; // indentation 901 int n1 = n0 + 2; // indentation
882 902
883 // Print header. 903 // Print header.
884 Indent(n0, Header(scope_type_)); 904 Indent(n0, Header(scope_type_));
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
921 if (scope_uses_arguments_) Indent(n1, "// scope uses 'arguments'\n"); 941 if (scope_uses_arguments_) Indent(n1, "// scope uses 'arguments'\n");
922 if (scope_uses_super_property_) 942 if (scope_uses_super_property_)
923 Indent(n1, "// scope uses 'super' property\n"); 943 Indent(n1, "// scope uses 'super' property\n");
924 if (inner_scope_uses_arguments_) { 944 if (inner_scope_uses_arguments_) {
925 Indent(n1, "// inner scope uses 'arguments'\n"); 945 Indent(n1, "// inner scope uses 'arguments'\n");
926 } 946 }
927 if (outer_scope_calls_sloppy_eval_) { 947 if (outer_scope_calls_sloppy_eval_) {
928 Indent(n1, "// outer scope calls 'eval' in sloppy context\n"); 948 Indent(n1, "// outer scope calls 'eval' in sloppy context\n");
929 } 949 }
930 if (inner_scope_calls_eval_) Indent(n1, "// inner scope calls 'eval'\n"); 950 if (inner_scope_calls_eval_) Indent(n1, "// inner scope calls 'eval'\n");
931 if (num_stack_slots_ > 0) { Indent(n1, "// "); 951 if (num_stack_slots_ > 0) {
932 PrintF("%d stack slots\n", num_stack_slots_); } 952 Indent(n1, "// ");
933 if (num_heap_slots_ > 0) { Indent(n1, "// "); 953 PrintF("%d stack slots\n", num_stack_slots_);
934 PrintF("%d heap slots\n", num_heap_slots_); } 954 }
955 if (num_heap_slots_ > 0) {
956 Indent(n1, "// ");
957 PrintF("%d heap slots (including %d global slots)\n", num_heap_slots_,
958 num_global_slots_);
959 }
935 960
936 // Print locals. 961 // Print locals.
937 if (function_ != NULL) { 962 if (function_ != NULL) {
938 Indent(n1, "// function var:\n"); 963 Indent(n1, "// function var:\n");
939 PrintVar(n1, function_->proxy()->var()); 964 PrintVar(n1, function_->proxy()->var());
940 } 965 }
941 966
942 if (temps_.length() > 0) { 967 if (temps_.length() > 0) {
943 Indent(n1, "// temporary vars:\n"); 968 Indent(n1, "// temporary vars:\n");
944 for (int i = 0; i < temps_.length(); i++) { 969 for (int i = 0; i < temps_.length(); i++) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
985 if (var == NULL) { 1010 if (var == NULL) {
986 // Declare a new non-local. 1011 // Declare a new non-local.
987 InitializationFlag init_flag = (mode == VAR) 1012 InitializationFlag init_flag = (mode == VAR)
988 ? kCreatedInitialized : kNeedsInitialization; 1013 ? kCreatedInitialized : kNeedsInitialization;
989 var = map->Declare(NULL, 1014 var = map->Declare(NULL,
990 name, 1015 name,
991 mode, 1016 mode,
992 Variable::NORMAL, 1017 Variable::NORMAL,
993 init_flag); 1018 init_flag);
994 // Allocate it by giving it a dynamic lookup. 1019 // Allocate it by giving it a dynamic lookup.
995 var->AllocateTo(Variable::LOOKUP, -1); 1020 var->AllocateTo(VariableLocation::LOOKUP, -1);
996 } 1021 }
997 return var; 1022 return var;
998 } 1023 }
999 1024
1000 1025
1001 Variable* Scope::LookupRecursive(VariableProxy* proxy, 1026 Variable* Scope::LookupRecursive(VariableProxy* proxy,
1002 BindingKind* binding_kind, 1027 BindingKind* binding_kind,
1003 AstNodeFactory* factory) { 1028 AstNodeFactory* factory) {
1004 DCHECK(binding_kind != NULL); 1029 DCHECK(binding_kind != NULL);
1005 if (already_resolved() && is_with_scope()) { 1030 if (already_resolved() && is_with_scope()) {
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after
1336 } 1361 }
1337 } 1362 }
1338 return false; 1363 return false;
1339 } 1364 }
1340 1365
1341 1366
1342 void Scope::AllocateStackSlot(Variable* var) { 1367 void Scope::AllocateStackSlot(Variable* var) {
1343 if (is_block_scope()) { 1368 if (is_block_scope()) {
1344 DeclarationScope()->AllocateStackSlot(var); 1369 DeclarationScope()->AllocateStackSlot(var);
1345 } else { 1370 } else {
1346 var->AllocateTo(Variable::LOCAL, num_stack_slots_++); 1371 var->AllocateTo(VariableLocation::LOCAL, num_stack_slots_++);
1347 } 1372 }
1348 } 1373 }
1349 1374
1350 1375
1351 void Scope::AllocateHeapSlot(Variable* var) { 1376 void Scope::AllocateHeapSlot(Variable* var) {
1352 var->AllocateTo(Variable::CONTEXT, num_heap_slots_++); 1377 var->AllocateTo(VariableLocation::CONTEXT, num_heap_slots_++);
1353 } 1378 }
1354 1379
1355 1380
1356 void Scope::AllocateParameterLocals(Isolate* isolate) { 1381 void Scope::AllocateParameterLocals(Isolate* isolate) {
1357 DCHECK(is_function_scope()); 1382 DCHECK(is_function_scope());
1358 Variable* arguments = LookupLocal(ast_value_factory_->arguments_string()); 1383 Variable* arguments = LookupLocal(ast_value_factory_->arguments_string());
1359 // Functions have 'arguments' declared implicitly in all non arrow functions. 1384 // Functions have 'arguments' declared implicitly in all non arrow functions.
1360 DCHECK(arguments != nullptr || is_arrow_scope()); 1385 DCHECK(arguments != nullptr || is_arrow_scope());
1361 1386
1362 bool uses_sloppy_arguments = false; 1387 bool uses_sloppy_arguments = false;
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1407 void Scope::AllocateParameter(Variable* var, int index) { 1432 void Scope::AllocateParameter(Variable* var, int index) {
1408 if (MustAllocate(var)) { 1433 if (MustAllocate(var)) {
1409 if (MustAllocateInContext(var)) { 1434 if (MustAllocateInContext(var)) {
1410 DCHECK(var->IsUnallocated() || var->IsContextSlot()); 1435 DCHECK(var->IsUnallocated() || var->IsContextSlot());
1411 if (var->IsUnallocated()) { 1436 if (var->IsUnallocated()) {
1412 AllocateHeapSlot(var); 1437 AllocateHeapSlot(var);
1413 } 1438 }
1414 } else { 1439 } else {
1415 DCHECK(var->IsUnallocated() || var->IsParameter()); 1440 DCHECK(var->IsUnallocated() || var->IsParameter());
1416 if (var->IsUnallocated()) { 1441 if (var->IsUnallocated()) {
1417 var->AllocateTo(Variable::PARAMETER, index); 1442 var->AllocateTo(VariableLocation::PARAMETER, index);
1418 } 1443 }
1419 } 1444 }
1445 } else {
1446 DCHECK(!var->IsGlobalSlot());
1420 } 1447 }
1421 } 1448 }
1422 1449
1423 1450
1424 void Scope::AllocateReceiver() { 1451 void Scope::AllocateReceiver() {
1425 DCHECK_NOT_NULL(receiver()); 1452 DCHECK_NOT_NULL(receiver());
1426 DCHECK_EQ(receiver()->scope(), this); 1453 DCHECK_EQ(receiver()->scope(), this);
1427 1454
1428 if (has_forced_context_allocation()) { 1455 if (has_forced_context_allocation()) {
1429 // Force context allocation of the receiver. 1456 // Force context allocation of the receiver.
(...skipping 10 matching lines...) Expand all
1440 if (var->IsUnallocated() && MustAllocate(var)) { 1467 if (var->IsUnallocated() && MustAllocate(var)) {
1441 if (MustAllocateInContext(var)) { 1468 if (MustAllocateInContext(var)) {
1442 AllocateHeapSlot(var); 1469 AllocateHeapSlot(var);
1443 } else { 1470 } else {
1444 AllocateStackSlot(var); 1471 AllocateStackSlot(var);
1445 } 1472 }
1446 } 1473 }
1447 } 1474 }
1448 1475
1449 1476
1450 void Scope::AllocateNonParameterLocals(Isolate* isolate) { 1477 void Scope::AllocateDeclaredGlobal(Isolate* isolate, Variable* var) {
1478 DCHECK(var->scope() == this);
1479 DCHECK(!var->IsVariable(isolate->factory()->dot_result_string()) ||
1480 !var->IsStackLocal());
1481 if (var->IsUnallocated() && var->IsStaticGlobalObjectProperty()) {
1482 DCHECK_EQ(-1, var->index());
1483 DCHECK(var->name()->IsString());
1484 var->AllocateTo(VariableLocation::GLOBAL, num_heap_slots_);
1485 num_global_slots_++;
1486 // Each global variable occupies two slots in the context: for reads
1487 // and writes.
1488 num_heap_slots_ += 2;
1489 }
1490 }
1491
1492
1493 void Scope::AllocateNonParameterLocalsAndDeclaredGlobals(Isolate* isolate) {
1451 // All variables that have no rewrite yet are non-parameter locals. 1494 // All variables that have no rewrite yet are non-parameter locals.
1452 for (int i = 0; i < temps_.length(); i++) { 1495 for (int i = 0; i < temps_.length(); i++) {
1453 AllocateNonParameterLocal(isolate, temps_[i]); 1496 AllocateNonParameterLocal(isolate, temps_[i]);
1454 } 1497 }
1455 1498
1456 for (int i = 0; i < internals_.length(); i++) { 1499 for (int i = 0; i < internals_.length(); i++) {
1457 AllocateNonParameterLocal(isolate, internals_[i]); 1500 AllocateNonParameterLocal(isolate, internals_[i]);
1458 } 1501 }
1459 1502
1460 ZoneList<VarAndOrder> vars(variables_.occupancy(), zone()); 1503 ZoneList<VarAndOrder> vars(variables_.occupancy(), zone());
1461 for (VariableMap::Entry* p = variables_.Start(); 1504 for (VariableMap::Entry* p = variables_.Start();
1462 p != NULL; 1505 p != NULL;
1463 p = variables_.Next(p)) { 1506 p = variables_.Next(p)) {
1464 Variable* var = reinterpret_cast<Variable*>(p->value); 1507 Variable* var = reinterpret_cast<Variable*>(p->value);
1465 vars.Add(VarAndOrder(var, p->order), zone()); 1508 vars.Add(VarAndOrder(var, p->order), zone());
1466 } 1509 }
1467 vars.Sort(VarAndOrder::Compare); 1510 vars.Sort(VarAndOrder::Compare);
1468 int var_count = vars.length(); 1511 int var_count = vars.length();
1469 for (int i = 0; i < var_count; i++) { 1512 for (int i = 0; i < var_count; i++) {
1470 AllocateNonParameterLocal(isolate, vars[i].var()); 1513 AllocateNonParameterLocal(isolate, vars[i].var());
1471 } 1514 }
1472 1515
1516 if (enable_context_globals) {
1517 for (int i = 0; i < var_count; i++) {
1518 AllocateDeclaredGlobal(isolate, vars[i].var());
1519 }
1520 }
1521
1473 // For now, function_ must be allocated at the very end. If it gets 1522 // For now, function_ must be allocated at the very end. If it gets
1474 // allocated in the context, it must be the last slot in the context, 1523 // allocated in the context, it must be the last slot in the context,
1475 // because of the current ScopeInfo implementation (see 1524 // because of the current ScopeInfo implementation (see
1476 // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor). 1525 // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor).
1477 if (function_ != nullptr) { 1526 if (function_ != nullptr) {
1478 AllocateNonParameterLocal(isolate, function_->proxy()->var()); 1527 AllocateNonParameterLocal(isolate, function_->proxy()->var());
1479 } 1528 }
1480 1529
1481 if (rest_parameter_ != nullptr) { 1530 if (rest_parameter_ != nullptr) {
1482 AllocateNonParameterLocal(isolate, rest_parameter_); 1531 AllocateNonParameterLocal(isolate, rest_parameter_);
(...skipping 25 matching lines...) Expand all
1508 // If scope is already resolved, we still need to allocate 1557 // If scope is already resolved, we still need to allocate
1509 // variables in inner scopes which might not had been resolved yet. 1558 // variables in inner scopes which might not had been resolved yet.
1510 if (already_resolved()) return; 1559 if (already_resolved()) return;
1511 // The number of slots required for variables. 1560 // The number of slots required for variables.
1512 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; 1561 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS;
1513 1562
1514 // Allocate variables for this scope. 1563 // Allocate variables for this scope.
1515 // Parameters must be allocated first, if any. 1564 // Parameters must be allocated first, if any.
1516 if (is_function_scope()) AllocateParameterLocals(isolate); 1565 if (is_function_scope()) AllocateParameterLocals(isolate);
1517 if (has_this_declaration()) AllocateReceiver(); 1566 if (has_this_declaration()) AllocateReceiver();
1518 AllocateNonParameterLocals(isolate); 1567 AllocateNonParameterLocalsAndDeclaredGlobals(isolate);
1519 1568
1520 // Force allocation of a context for this scope if necessary. For a 'with' 1569 // Force allocation of a context for this scope if necessary. For a 'with'
1521 // scope and for a function scope that makes an 'eval' call we need a context, 1570 // scope and for a function scope that makes an 'eval' call we need a context,
1522 // even if no local variables were statically allocated in the scope. 1571 // even if no local variables were statically allocated in the scope.
1523 // Likewise for modules. 1572 // Likewise for modules.
1524 bool must_have_context = is_with_scope() || is_module_scope() || 1573 bool must_have_context = is_with_scope() || is_module_scope() ||
1525 (is_function_scope() && calls_sloppy_eval()); 1574 (is_function_scope() && calls_sloppy_eval());
1526 1575
1527 // If we didn't allocate any locals in the local context, then we only 1576 // If we didn't allocate any locals in the local context, then we only
1528 // need the minimal number of slots if we must have a context. 1577 // need the minimal number of slots if we must have a context.
(...skipping 23 matching lines...) Expand all
1552 1601
1553 1602
1554 int Scope::StackLocalCount() const { 1603 int Scope::StackLocalCount() const {
1555 return num_stack_slots() - 1604 return num_stack_slots() -
1556 (function_ != NULL && function_->proxy()->var()->IsStackLocal() ? 1 : 0); 1605 (function_ != NULL && function_->proxy()->var()->IsStackLocal() ? 1 : 0);
1557 } 1606 }
1558 1607
1559 1608
1560 int Scope::ContextLocalCount() const { 1609 int Scope::ContextLocalCount() const {
1561 if (num_heap_slots() == 0) return 0; 1610 if (num_heap_slots() == 0) return 0;
1611 bool is_function_var_in_context =
1612 function_ != NULL && function_->proxy()->var()->IsContextSlot();
1562 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - 1613 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS -
1563 (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0); 1614 2 * num_global_slots() - (is_function_var_in_context ? 1 : 0);
1564 } 1615 }
1616
1617
1618 int Scope::ContextGlobalCount() const { return num_global_slots(); }
1565 } // namespace internal 1619 } // namespace internal
1566 } // namespace v8 1620 } // namespace v8
OLDNEW
« no previous file with comments | « src/scopes.h ('k') | src/typing.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698