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

Side by Side Diff: src/scopes.cc

Issue 7885027: Merge revision 9281 to the 3.5 branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/3.5/
Patch Set: '' Created 9 years, 3 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | src/variables.h » ('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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 602 matching lines...) Expand 10 before | Expand all | Expand 10 after
613 613
614 614
615 static void PrintVar(PrettyPrinter* printer, int indent, Variable* var) { 615 static void PrintVar(PrettyPrinter* printer, int indent, Variable* var) {
616 if (var->is_used() || var->rewrite() != NULL) { 616 if (var->is_used() || var->rewrite() != NULL) {
617 Indent(indent, Variable::Mode2String(var->mode())); 617 Indent(indent, Variable::Mode2String(var->mode()));
618 PrintF(" "); 618 PrintF(" ");
619 PrintName(var->name()); 619 PrintName(var->name());
620 PrintF("; // "); 620 PrintF("; // ");
621 if (var->rewrite() != NULL) { 621 if (var->rewrite() != NULL) {
622 PrintF("%s, ", printer->Print(var->rewrite())); 622 PrintF("%s, ", printer->Print(var->rewrite()));
623 if (var->is_accessed_from_inner_function_scope()) PrintF(", "); 623 if (var->is_accessed_from_inner_scope()) PrintF(", ");
624 } 624 }
625 if (var->is_accessed_from_inner_function_scope()) { 625 if (var->is_accessed_from_inner_scope()) {
626 PrintF("inner scope access"); 626 PrintF("inner scope access");
627 } 627 }
628 PrintF("\n"); 628 PrintF("\n");
629 } 629 }
630 } 630 }
631 631
632 632
633 static void PrintMap(PrettyPrinter* printer, int indent, VariableMap* map) { 633 static void PrintMap(PrettyPrinter* printer, int indent, VariableMap* map) {
634 for (VariableMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) { 634 for (VariableMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) {
635 Variable* var = reinterpret_cast<Variable*>(p->value); 635 Variable* var = reinterpret_cast<Variable*>(p->value);
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
738 } 738 }
739 739
740 740
741 // Lookup a variable starting with this scope. The result is either 741 // Lookup a variable starting with this scope. The result is either
742 // the statically resolved variable belonging to an outer scope, or 742 // the statically resolved variable belonging to an outer scope, or
743 // NULL. It may be NULL because a) we couldn't find a variable, or b) 743 // NULL. It may be NULL because a) we couldn't find a variable, or b)
744 // because the variable is just a guess (and may be shadowed by 744 // because the variable is just a guess (and may be shadowed by
745 // another variable that is introduced dynamically via an 'eval' call 745 // another variable that is introduced dynamically via an 'eval' call
746 // or a 'with' statement). 746 // or a 'with' statement).
747 Variable* Scope::LookupRecursive(Handle<String> name, 747 Variable* Scope::LookupRecursive(Handle<String> name,
748 bool from_inner_function, 748 bool from_inner_scope,
749 Variable** invalidated_local) { 749 Variable** invalidated_local) {
750 // If we find a variable, but the current scope calls 'eval', the found 750 // If we find a variable, but the current scope calls 'eval', the found
751 // variable may not be the correct one (the 'eval' may introduce a 751 // variable may not be the correct one (the 'eval' may introduce a
752 // property with the same name). In that case, remember that the variable 752 // property with the same name). In that case, remember that the variable
753 // found is just a guess. 753 // found is just a guess.
754 bool guess = scope_calls_eval_; 754 bool guess = scope_calls_eval_;
755 755
756 // Try to find the variable in this scope. 756 // Try to find the variable in this scope.
757 Variable* var = LocalLookup(name); 757 Variable* var = LocalLookup(name);
758 758
759 if (var != NULL) { 759 if (var != NULL) {
760 // We found a variable. If this is not an inner lookup, we are done. 760 // We found a variable. If this is not an inner lookup, we are done.
761 // (Even if there is an 'eval' in this scope which introduces the 761 // (Even if there is an 'eval' in this scope which introduces the
762 // same variable again, the resulting variable remains the same. 762 // same variable again, the resulting variable remains the same.
763 // Note that enclosing 'with' statements are handled at the call site.) 763 // Note that enclosing 'with' statements are handled at the call site.)
764 if (!from_inner_function) 764 if (!from_inner_scope)
765 return var; 765 return var;
766 766
767 } else { 767 } else {
768 // We did not find a variable locally. Check against the function variable, 768 // We did not find a variable locally. Check against the function variable,
769 // if any. We can do this for all scopes, since the function variable is 769 // if any. We can do this for all scopes, since the function variable is
770 // only present - if at all - for function scopes. 770 // only present - if at all - for function scopes.
771 // 771 //
772 // This lookup corresponds to a lookup in the "intermediate" scope sitting 772 // This lookup corresponds to a lookup in the "intermediate" scope sitting
773 // between this scope and the outer scope. (ECMA-262, 3rd., requires that 773 // between this scope and the outer scope. (ECMA-262, 3rd., requires that
774 // the name of named function literal is kept in an intermediate scope 774 // the name of named function literal is kept in an intermediate scope
775 // in between this scope and the next outer scope.) 775 // in between this scope and the next outer scope.)
776 if (function_ != NULL && function_->name().is_identical_to(name)) { 776 if (function_ != NULL && function_->name().is_identical_to(name)) {
777 var = function_; 777 var = function_;
778 778
779 } else if (outer_scope_ != NULL) { 779 } else if (outer_scope_ != NULL) {
780 var = outer_scope_->LookupRecursive( 780 var = outer_scope_->LookupRecursive(name, true, invalidated_local);
781 name,
782 is_function_scope() || from_inner_function,
783 invalidated_local);
784 // We may have found a variable in an outer scope. However, if 781 // We may have found a variable in an outer scope. However, if
785 // the current scope is inside a 'with', the actual variable may 782 // the current scope is inside a 'with', the actual variable may
786 // be a property introduced via the 'with' statement. Then, the 783 // be a property introduced via the 'with' statement. Then, the
787 // variable we may have found is just a guess. 784 // variable we may have found is just a guess.
788 if (scope_inside_with_) 785 if (scope_inside_with_)
789 guess = true; 786 guess = true;
790 } 787 }
791 788
792 // If we did not find a variable, we are done. 789 // If we did not find a variable, we are done.
793 if (var == NULL) 790 if (var == NULL)
794 return NULL; 791 return NULL;
795 } 792 }
796 793
797 ASSERT(var != NULL); 794 ASSERT(var != NULL);
798 795
799 // If this is a lookup from an inner scope, mark the variable. 796 // If this is a lookup from an inner scope, mark the variable.
800 if (from_inner_function) { 797 if (from_inner_scope) {
801 var->MarkAsAccessedFromInnerFunctionScope(); 798 var->MarkAsAccessedFromInnerScope();
802 } 799 }
803 800
804 // If the variable we have found is just a guess, invalidate the 801 // If the variable we have found is just a guess, invalidate the
805 // result. If the found variable is local, record that fact so we 802 // result. If the found variable is local, record that fact so we
806 // can generate fast code to get it if it is not shadowed by eval. 803 // can generate fast code to get it if it is not shadowed by eval.
807 if (guess) { 804 if (guess) {
808 if (!var->is_global()) *invalidated_local = var; 805 if (!var->is_global()) *invalidated_local = var;
809 var = NULL; 806 var = NULL;
810 } 807 }
811 808
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
942 939
943 return scope_calls_eval_ || inner_scope_calls_eval_; 940 return scope_calls_eval_ || inner_scope_calls_eval_;
944 } 941 }
945 942
946 943
947 bool Scope::MustAllocate(Variable* var) { 944 bool Scope::MustAllocate(Variable* var) {
948 // Give var a read/write use if there is a chance it might be accessed 945 // Give var a read/write use if there is a chance it might be accessed
949 // via an eval() call. This is only possible if the variable has a 946 // via an eval() call. This is only possible if the variable has a
950 // visible name. 947 // visible name.
951 if ((var->is_this() || var->name()->length() > 0) && 948 if ((var->is_this() || var->name()->length() > 0) &&
952 (var->is_accessed_from_inner_function_scope() || 949 (var->is_accessed_from_inner_scope() ||
953 scope_calls_eval_ || 950 scope_calls_eval_ ||
954 inner_scope_calls_eval_ || 951 inner_scope_calls_eval_ ||
955 scope_contains_with_ || 952 scope_contains_with_ ||
956 is_catch_scope() || 953 is_catch_scope() ||
957 is_block_scope())) { 954 is_block_scope())) {
958 var->set_is_used(true); 955 var->set_is_used(true);
959 } 956 }
960 // Global variables do not need to be allocated. 957 // Global variables do not need to be allocated.
961 return !var->is_global() && var->is_used(); 958 return !var->is_global() && var->is_used();
962 } 959 }
963 960
964 961
965 bool Scope::MustAllocateInContext(Variable* var) { 962 bool Scope::MustAllocateInContext(Variable* var) {
966 // If var is accessed from an inner scope, or if there is a possibility 963 // If var is accessed from an inner scope, or if there is a possibility
967 // that it might be accessed from the current or an inner scope (through 964 // that it might be accessed from the current or an inner scope (through
968 // an eval() call or a runtime with lookup), it must be allocated in the 965 // an eval() call or a runtime with lookup), it must be allocated in the
969 // context. 966 // context.
970 // 967 //
971 // Exceptions: temporary variables are never allocated in a context; 968 // Exceptions: temporary variables are never allocated in a context;
972 // catch-bound variables are always allocated in a context. 969 // catch-bound variables are always allocated in a context.
973 if (var->mode() == Variable::TEMPORARY) return false; 970 if (var->mode() == Variable::TEMPORARY) return false;
974 if (is_catch_scope() || is_block_scope()) return true; 971 if (is_catch_scope() || is_block_scope()) return true;
975 return var->is_accessed_from_inner_function_scope() || 972 return var->is_accessed_from_inner_scope() ||
976 scope_calls_eval_ || 973 scope_calls_eval_ ||
977 inner_scope_calls_eval_ || 974 inner_scope_calls_eval_ ||
978 scope_contains_with_ || 975 scope_contains_with_ ||
979 var->is_global(); 976 var->is_global();
980 } 977 }
981 978
982 979
983 bool Scope::HasArgumentsParameter() { 980 bool Scope::HasArgumentsParameter() {
984 for (int i = 0; i < params_.length(); i++) { 981 for (int i = 0; i < params_.length(); i++) {
985 if (params_[i]->name().is_identical_to( 982 if (params_[i]->name().is_identical_to(
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1031 // The same parameter may occur multiple times in the parameters_ list. 1028 // The same parameter may occur multiple times in the parameters_ list.
1032 // If it does, and if it is not copied into the context object, it must 1029 // If it does, and if it is not copied into the context object, it must
1033 // receive the highest parameter index for that parameter; thus iteration 1030 // receive the highest parameter index for that parameter; thus iteration
1034 // order is relevant! 1031 // order is relevant!
1035 for (int i = params_.length() - 1; i >= 0; --i) { 1032 for (int i = params_.length() - 1; i >= 0; --i) {
1036 Variable* var = params_[i]; 1033 Variable* var = params_[i];
1037 ASSERT(var->scope() == this); 1034 ASSERT(var->scope() == this);
1038 if (uses_nonstrict_arguments) { 1035 if (uses_nonstrict_arguments) {
1039 // Give the parameter a use from an inner scope, to force allocation 1036 // Give the parameter a use from an inner scope, to force allocation
1040 // to the context. 1037 // to the context.
1041 var->MarkAsAccessedFromInnerFunctionScope(); 1038 var->MarkAsAccessedFromInnerScope();
1042 } 1039 }
1043 1040
1044 if (MustAllocate(var)) { 1041 if (MustAllocate(var)) {
1045 if (MustAllocateInContext(var)) { 1042 if (MustAllocateInContext(var)) {
1046 ASSERT(var->rewrite() == NULL || var->IsContextSlot()); 1043 ASSERT(var->rewrite() == NULL || var->IsContextSlot());
1047 if (var->rewrite() == NULL) { 1044 if (var->rewrite() == NULL) {
1048 AllocateHeapSlot(var); 1045 AllocateHeapSlot(var);
1049 } 1046 }
1050 } else { 1047 } else {
1051 ASSERT(var->rewrite() == NULL || var->IsParameter()); 1048 ASSERT(var->rewrite() == NULL || var->IsParameter());
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1131 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && 1128 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS &&
1132 !must_have_local_context) { 1129 !must_have_local_context) {
1133 num_heap_slots_ = 0; 1130 num_heap_slots_ = 0;
1134 } 1131 }
1135 1132
1136 // Allocation done. 1133 // Allocation done.
1137 ASSERT(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); 1134 ASSERT(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS);
1138 } 1135 }
1139 1136
1140 } } // namespace v8::internal 1137 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/variables.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698