| 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/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/scopes.h" | 7 #include "src/scopes.h" |
| 8 | 8 |
| 9 #include "src/accessors.h" | 9 #include "src/accessors.h" |
| 10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 163 function_ = NULL; | 163 function_ = NULL; |
| 164 arguments_ = NULL; | 164 arguments_ = NULL; |
| 165 illegal_redecl_ = NULL; | 165 illegal_redecl_ = NULL; |
| 166 scope_inside_with_ = false; | 166 scope_inside_with_ = false; |
| 167 scope_contains_with_ = false; | 167 scope_contains_with_ = false; |
| 168 scope_calls_eval_ = false; | 168 scope_calls_eval_ = false; |
| 169 // Inherit the strict mode from the parent scope. | 169 // Inherit the strict mode from the parent scope. |
| 170 strict_mode_ = outer_scope != NULL ? outer_scope->strict_mode_ : SLOPPY; | 170 strict_mode_ = outer_scope != NULL ? outer_scope->strict_mode_ : SLOPPY; |
| 171 outer_scope_calls_sloppy_eval_ = false; | 171 outer_scope_calls_sloppy_eval_ = false; |
| 172 inner_scope_calls_eval_ = false; | 172 inner_scope_calls_eval_ = false; |
| 173 inner_scope_contains_with_ = false; | |
| 174 force_eager_compilation_ = false; | 173 force_eager_compilation_ = false; |
| 175 force_context_allocation_ = (outer_scope != NULL && !is_function_scope()) | 174 force_context_allocation_ = (outer_scope != NULL && !is_function_scope()) |
| 176 ? outer_scope->has_forced_context_allocation() : false; | 175 ? outer_scope->has_forced_context_allocation() : false; |
| 177 num_var_or_const_ = 0; | 176 num_var_or_const_ = 0; |
| 178 num_stack_slots_ = 0; | 177 num_stack_slots_ = 0; |
| 179 num_heap_slots_ = 0; | 178 num_heap_slots_ = 0; |
| 180 num_modules_ = 0; | 179 num_modules_ = 0; |
| 181 module_var_ = NULL, | 180 module_var_ = NULL, |
| 182 scope_info_ = scope_info; | 181 scope_info_ = scope_info; |
| 183 start_position_ = RelocInfo::kNoPosition; | 182 start_position_ = RelocInfo::kNoPosition; |
| 184 end_position_ = RelocInfo::kNoPosition; | 183 end_position_ = RelocInfo::kNoPosition; |
| 185 if (!scope_info.is_null()) { | 184 if (!scope_info.is_null()) { |
| 186 scope_calls_eval_ = scope_info->CallsEval(); | 185 scope_calls_eval_ = scope_info->CallsEval(); |
| 187 strict_mode_ = scope_info->strict_mode(); | 186 strict_mode_ = scope_info->strict_mode(); |
| 188 } | 187 } |
| 189 } | 188 } |
| 190 | 189 |
| 191 | 190 |
| 192 Scope* Scope::DeserializeScopeChain(Context* context, Scope* global_scope, | 191 Scope* Scope::DeserializeScopeChain(Context* context, Scope* global_scope, |
| 193 Zone* zone) { | 192 Zone* zone) { |
| 194 // Reconstruct the outer scope chain from a closure's context chain. | 193 // Reconstruct the outer scope chain from a closure's context chain. |
| 195 Scope* current_scope = NULL; | 194 Scope* current_scope = NULL; |
| 196 Scope* innermost_scope = NULL; | 195 Scope* innermost_scope = NULL; |
| 197 bool contains_with = false; | 196 bool contains_with = false; |
| 198 bool inner_contains_with = false; | |
| 199 while (!context->IsNativeContext()) { | 197 while (!context->IsNativeContext()) { |
| 200 if (context->IsWithContext()) { | 198 if (context->IsWithContext()) { |
| 201 Scope* with_scope = new(zone) Scope(current_scope, | 199 Scope* with_scope = new(zone) Scope(current_scope, |
| 202 WITH_SCOPE, | 200 WITH_SCOPE, |
| 203 Handle<ScopeInfo>::null(), | 201 Handle<ScopeInfo>::null(), |
| 204 global_scope->ast_value_factory_, | 202 global_scope->ast_value_factory_, |
| 205 zone); | 203 zone); |
| 206 current_scope = with_scope; | 204 current_scope = with_scope; |
| 207 // All the inner scopes are inside a with. | 205 // All the inner scopes are inside a with. |
| 208 contains_with = true; | 206 contains_with = true; |
| (...skipping 29 matching lines...) Expand all Loading... |
| 238 global_scope->ast_value_factory_, | 236 global_scope->ast_value_factory_, |
| 239 zone); | 237 zone); |
| 240 } else { | 238 } else { |
| 241 ASSERT(context->IsCatchContext()); | 239 ASSERT(context->IsCatchContext()); |
| 242 String* name = String::cast(context->extension()); | 240 String* name = String::cast(context->extension()); |
| 243 current_scope = new (zone) Scope( | 241 current_scope = new (zone) Scope( |
| 244 current_scope, | 242 current_scope, |
| 245 global_scope->ast_value_factory_->GetString(Handle<String>(name)), | 243 global_scope->ast_value_factory_->GetString(Handle<String>(name)), |
| 246 global_scope->ast_value_factory_, zone); | 244 global_scope->ast_value_factory_, zone); |
| 247 } | 245 } |
| 248 if (inner_contains_with) current_scope->inner_scope_contains_with_ = true; | 246 if (contains_with) current_scope->RecordWithStatement(); |
| 249 if (contains_with) { | |
| 250 current_scope->RecordWithStatement(); | |
| 251 inner_contains_with = true; | |
| 252 } | |
| 253 if (innermost_scope == NULL) innermost_scope = current_scope; | 247 if (innermost_scope == NULL) innermost_scope = current_scope; |
| 254 | 248 |
| 255 // Forget about a with when we move to a context for a different function. | 249 // Forget about a with when we move to a context for a different function. |
| 256 if (context->previous()->closure() != context->closure()) { | 250 if (context->previous()->closure() != context->closure()) { |
| 257 contains_with = false; | 251 contains_with = false; |
| 258 } | 252 } |
| 259 context = context->previous(); | 253 context = context->previous(); |
| 260 } | 254 } |
| 261 | 255 |
| 262 global_scope->AddInnerScope(current_scope); | 256 global_scope->AddInnerScope(current_scope); |
| (...skipping 555 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 818 } | 812 } |
| 819 | 813 |
| 820 | 814 |
| 821 static void PrintVar(int indent, Variable* var) { | 815 static void PrintVar(int indent, Variable* var) { |
| 822 if (var->is_used() || !var->IsUnallocated()) { | 816 if (var->is_used() || !var->IsUnallocated()) { |
| 823 Indent(indent, Variable::Mode2String(var->mode())); | 817 Indent(indent, Variable::Mode2String(var->mode())); |
| 824 PrintF(" "); | 818 PrintF(" "); |
| 825 PrintName(var->raw_name()); | 819 PrintName(var->raw_name()); |
| 826 PrintF("; // "); | 820 PrintF("; // "); |
| 827 PrintLocation(var); | 821 PrintLocation(var); |
| 828 bool comma = !var->IsUnallocated(); | |
| 829 if (var->has_forced_context_allocation()) { | 822 if (var->has_forced_context_allocation()) { |
| 830 if (comma) PrintF(", "); | 823 if (!var->IsUnallocated()) PrintF(", "); |
| 831 PrintF("forced context allocation"); | 824 PrintF("forced context allocation"); |
| 832 comma = true; | |
| 833 } | |
| 834 if (var->maybe_assigned()) { | |
| 835 if (comma) PrintF(", "); | |
| 836 PrintF("maybe assigned"); | |
| 837 } | 825 } |
| 838 PrintF("\n"); | 826 PrintF("\n"); |
| 839 } | 827 } |
| 840 } | 828 } |
| 841 | 829 |
| 842 | 830 |
| 843 static void PrintMap(int indent, VariableMap* map) { | 831 static void PrintMap(int indent, VariableMap* map) { |
| 844 for (VariableMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) { | 832 for (VariableMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) { |
| 845 Variable* var = reinterpret_cast<Variable*>(p->value); | 833 Variable* var = reinterpret_cast<Variable*>(p->value); |
| 846 PrintVar(indent, var); | 834 PrintVar(indent, var); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 880 | 868 |
| 881 // Scope info. | 869 // Scope info. |
| 882 if (HasTrivialOuterContext()) { | 870 if (HasTrivialOuterContext()) { |
| 883 Indent(n1, "// scope has trivial outer context\n"); | 871 Indent(n1, "// scope has trivial outer context\n"); |
| 884 } | 872 } |
| 885 if (strict_mode() == STRICT) { | 873 if (strict_mode() == STRICT) { |
| 886 Indent(n1, "// strict mode scope\n"); | 874 Indent(n1, "// strict mode scope\n"); |
| 887 } | 875 } |
| 888 if (scope_inside_with_) Indent(n1, "// scope inside 'with'\n"); | 876 if (scope_inside_with_) Indent(n1, "// scope inside 'with'\n"); |
| 889 if (scope_contains_with_) Indent(n1, "// scope contains 'with'\n"); | 877 if (scope_contains_with_) Indent(n1, "// scope contains 'with'\n"); |
| 890 if (inner_scope_contains_with_) { | |
| 891 Indent(n1, "// inner scope contains 'with'\n"); | |
| 892 } | |
| 893 if (scope_calls_eval_) Indent(n1, "// scope calls 'eval'\n"); | 878 if (scope_calls_eval_) Indent(n1, "// scope calls 'eval'\n"); |
| 894 if (outer_scope_calls_sloppy_eval_) { | 879 if (outer_scope_calls_sloppy_eval_) { |
| 895 Indent(n1, "// outer scope calls 'eval' in sloppy context\n"); | 880 Indent(n1, "// outer scope calls 'eval' in sloppy context\n"); |
| 896 } | 881 } |
| 897 if (inner_scope_calls_eval_) Indent(n1, "// inner scope calls 'eval'\n"); | 882 if (inner_scope_calls_eval_) Indent(n1, "// inner scope calls 'eval'\n"); |
| 898 if (num_stack_slots_ > 0) { Indent(n1, "// "); | 883 if (num_stack_slots_ > 0) { Indent(n1, "// "); |
| 899 PrintF("%d stack slots\n", num_stack_slots_); } | 884 PrintF("%d stack slots\n", num_stack_slots_); } |
| 900 if (num_heap_slots_ > 0) { Indent(n1, "// "); | 885 if (num_heap_slots_ > 0) { Indent(n1, "// "); |
| 901 PrintF("%d heap slots\n", num_heap_slots_); } | 886 PrintF("%d heap slots\n", num_heap_slots_); } |
| 902 | 887 |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 959 true, | 944 true, |
| 960 Variable::NORMAL, | 945 Variable::NORMAL, |
| 961 init_flag); | 946 init_flag); |
| 962 // Allocate it by giving it a dynamic lookup. | 947 // Allocate it by giving it a dynamic lookup. |
| 963 var->AllocateTo(Variable::LOOKUP, -1); | 948 var->AllocateTo(Variable::LOOKUP, -1); |
| 964 } | 949 } |
| 965 return var; | 950 return var; |
| 966 } | 951 } |
| 967 | 952 |
| 968 | 953 |
| 969 Variable* Scope::LookupRecursive(VariableProxy* proxy, | 954 Variable* Scope::LookupRecursive(const AstRawString* name, |
| 970 BindingKind* binding_kind, | 955 BindingKind* binding_kind, |
| 971 AstNodeFactory<AstNullVisitor>* factory) { | 956 AstNodeFactory<AstNullVisitor>* factory) { |
| 972 ASSERT(binding_kind != NULL); | 957 ASSERT(binding_kind != NULL); |
| 973 if (already_resolved() && is_with_scope()) { | 958 if (already_resolved() && is_with_scope()) { |
| 974 // Short-cut: if the scope is deserialized from a scope info, variable | 959 // Short-cut: if the scope is deserialized from a scope info, variable |
| 975 // allocation is already fixed. We can simply return with dynamic lookup. | 960 // allocation is already fixed. We can simply return with dynamic lookup. |
| 976 *binding_kind = DYNAMIC_LOOKUP; | 961 *binding_kind = DYNAMIC_LOOKUP; |
| 977 return NULL; | 962 return NULL; |
| 978 } | 963 } |
| 979 | 964 |
| 980 // Try to find the variable in this scope. | 965 // Try to find the variable in this scope. |
| 981 Variable* var = LookupLocal(proxy->raw_name()); | 966 Variable* var = LookupLocal(name); |
| 982 | 967 |
| 983 // We found a variable and we are done. (Even if there is an 'eval' in | 968 // We found a variable and we are done. (Even if there is an 'eval' in |
| 984 // this scope which introduces the same variable again, the resulting | 969 // this scope which introduces the same variable again, the resulting |
| 985 // variable remains the same.) | 970 // variable remains the same.) |
| 986 if (var != NULL) { | 971 if (var != NULL) { |
| 987 *binding_kind = BOUND; | 972 *binding_kind = BOUND; |
| 988 return var; | 973 return var; |
| 989 } | 974 } |
| 990 | 975 |
| 991 // We did not find a variable locally. Check against the function variable, | 976 // We did not find a variable locally. Check against the function variable, |
| 992 // if any. We can do this for all scopes, since the function variable is | 977 // if any. We can do this for all scopes, since the function variable is |
| 993 // only present - if at all - for function scopes. | 978 // only present - if at all - for function scopes. |
| 994 *binding_kind = UNBOUND; | 979 *binding_kind = UNBOUND; |
| 995 var = LookupFunctionVar(proxy->raw_name(), factory); | 980 var = LookupFunctionVar(name, factory); |
| 996 if (var != NULL) { | 981 if (var != NULL) { |
| 997 *binding_kind = BOUND; | 982 *binding_kind = BOUND; |
| 998 } else if (outer_scope_ != NULL) { | 983 } else if (outer_scope_ != NULL) { |
| 999 var = outer_scope_->LookupRecursive(proxy, binding_kind, factory); | 984 var = outer_scope_->LookupRecursive(name, binding_kind, factory); |
| 1000 if (*binding_kind == BOUND && (is_function_scope() || is_with_scope())) { | 985 if (*binding_kind == BOUND && (is_function_scope() || is_with_scope())) { |
| 1001 var->ForceContextAllocation(); | 986 var->ForceContextAllocation(); |
| 1002 } | 987 } |
| 1003 } else { | 988 } else { |
| 1004 ASSERT(is_global_scope()); | 989 ASSERT(is_global_scope()); |
| 1005 } | 990 } |
| 1006 | 991 |
| 1007 if (is_with_scope()) { | 992 if (is_with_scope()) { |
| 1008 ASSERT(!already_resolved()); | 993 ASSERT(!already_resolved()); |
| 1009 // The current scope is a with scope, so the variable binding can not be | 994 // The current scope is a with scope, so the variable binding can not be |
| 1010 // statically resolved. However, note that it was necessary to do a lookup | 995 // statically resolved. However, note that it was necessary to do a lookup |
| 1011 // in the outer scope anyway, because if a binding exists in an outer scope, | 996 // in the outer scope anyway, because if a binding exists in an outer scope, |
| 1012 // the associated variable has to be marked as potentially being accessed | 997 // the associated variable has to be marked as potentially being accessed |
| 1013 // from inside of an inner with scope (the property may not be in the 'with' | 998 // from inside of an inner with scope (the property may not be in the 'with' |
| 1014 // object). | 999 // object). |
| 1015 if (var != NULL && proxy->is_assigned()) var->set_maybe_assigned(); | |
| 1016 *binding_kind = DYNAMIC_LOOKUP; | 1000 *binding_kind = DYNAMIC_LOOKUP; |
| 1017 return NULL; | 1001 return NULL; |
| 1018 } else if (calls_sloppy_eval()) { | 1002 } else if (calls_sloppy_eval()) { |
| 1019 // A variable binding may have been found in an outer scope, but the current | 1003 // A variable binding may have been found in an outer scope, but the current |
| 1020 // scope makes a sloppy 'eval' call, so the found variable may not be | 1004 // scope makes a sloppy 'eval' call, so the found variable may not be |
| 1021 // the correct one (the 'eval' may introduce a binding with the same name). | 1005 // the correct one (the 'eval' may introduce a binding with the same name). |
| 1022 // In that case, change the lookup result to reflect this situation. | 1006 // In that case, change the lookup result to reflect this situation. |
| 1023 if (*binding_kind == BOUND) { | 1007 if (*binding_kind == BOUND) { |
| 1024 *binding_kind = BOUND_EVAL_SHADOWED; | 1008 *binding_kind = BOUND_EVAL_SHADOWED; |
| 1025 } else if (*binding_kind == UNBOUND) { | 1009 } else if (*binding_kind == UNBOUND) { |
| 1026 *binding_kind = UNBOUND_EVAL_SHADOWED; | 1010 *binding_kind = UNBOUND_EVAL_SHADOWED; |
| 1027 } | 1011 } |
| 1028 } | 1012 } |
| 1029 return var; | 1013 return var; |
| 1030 } | 1014 } |
| 1031 | 1015 |
| 1032 | 1016 |
| 1033 bool Scope::ResolveVariable(CompilationInfo* info, | 1017 bool Scope::ResolveVariable(CompilationInfo* info, |
| 1034 VariableProxy* proxy, | 1018 VariableProxy* proxy, |
| 1035 AstNodeFactory<AstNullVisitor>* factory) { | 1019 AstNodeFactory<AstNullVisitor>* factory) { |
| 1036 ASSERT(info->global_scope()->is_global_scope()); | 1020 ASSERT(info->global_scope()->is_global_scope()); |
| 1037 | 1021 |
| 1038 // If the proxy is already resolved there's nothing to do | 1022 // If the proxy is already resolved there's nothing to do |
| 1039 // (functions and consts may be resolved by the parser). | 1023 // (functions and consts may be resolved by the parser). |
| 1040 if (proxy->var() != NULL) return true; | 1024 if (proxy->var() != NULL) return true; |
| 1041 | 1025 |
| 1042 // Otherwise, try to resolve the variable. | 1026 // Otherwise, try to resolve the variable. |
| 1043 BindingKind binding_kind; | 1027 BindingKind binding_kind; |
| 1044 Variable* var = LookupRecursive(proxy, &binding_kind, factory); | 1028 Variable* var = LookupRecursive(proxy->raw_name(), &binding_kind, factory); |
| 1045 switch (binding_kind) { | 1029 switch (binding_kind) { |
| 1046 case BOUND: | 1030 case BOUND: |
| 1047 // We found a variable binding. | 1031 // We found a variable binding. |
| 1048 break; | 1032 break; |
| 1049 | 1033 |
| 1050 case BOUND_EVAL_SHADOWED: | 1034 case BOUND_EVAL_SHADOWED: |
| 1051 // We either found a variable binding that might be shadowed by eval or | 1035 // We either found a variable binding that might be shadowed by eval or |
| 1052 // gave up on it (e.g. by encountering a local with the same in the outer | 1036 // gave up on it (e.g. by encountering a local with the same in the outer |
| 1053 // scope which was not promoted to a context, this can happen if we use | 1037 // scope which was not promoted to a context, this can happen if we use |
| 1054 // debugger to evaluate arbitrary expressions at a break point). | 1038 // debugger to evaluate arbitrary expressions at a break point). |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1073 var = NonLocal(proxy->raw_name(), DYNAMIC_GLOBAL); | 1057 var = NonLocal(proxy->raw_name(), DYNAMIC_GLOBAL); |
| 1074 break; | 1058 break; |
| 1075 | 1059 |
| 1076 case DYNAMIC_LOOKUP: | 1060 case DYNAMIC_LOOKUP: |
| 1077 // The variable could not be resolved statically. | 1061 // The variable could not be resolved statically. |
| 1078 var = NonLocal(proxy->raw_name(), DYNAMIC); | 1062 var = NonLocal(proxy->raw_name(), DYNAMIC); |
| 1079 break; | 1063 break; |
| 1080 } | 1064 } |
| 1081 | 1065 |
| 1082 ASSERT(var != NULL); | 1066 ASSERT(var != NULL); |
| 1083 if (proxy->is_assigned()) var->set_maybe_assigned(); | |
| 1084 | 1067 |
| 1085 if (FLAG_harmony_scoping && strict_mode() == STRICT && | 1068 if (FLAG_harmony_scoping && strict_mode() == STRICT && |
| 1086 var->is_const_mode() && proxy->is_assigned()) { | 1069 var->is_const_mode() && proxy->IsLValue()) { |
| 1087 // Assignment to const. Throw a syntax error. | 1070 // Assignment to const. Throw a syntax error. |
| 1088 MessageLocation location( | 1071 MessageLocation location( |
| 1089 info->script(), proxy->position(), proxy->position()); | 1072 info->script(), proxy->position(), proxy->position()); |
| 1090 Isolate* isolate = info->isolate(); | 1073 Isolate* isolate = info->isolate(); |
| 1091 Factory* factory = isolate->factory(); | 1074 Factory* factory = isolate->factory(); |
| 1092 Handle<JSArray> array = factory->NewJSArray(0); | 1075 Handle<JSArray> array = factory->NewJSArray(0); |
| 1093 Handle<Object> result = | 1076 Handle<Object> result = |
| 1094 factory->NewSyntaxError("harmony_const_assign", array); | 1077 factory->NewSyntaxError("harmony_const_assign", array); |
| 1095 isolate->Throw(*result, &location); | 1078 isolate->Throw(*result, &location); |
| 1096 return false; | 1079 return false; |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1150 // Resolve unresolved variables for inner scopes. | 1133 // Resolve unresolved variables for inner scopes. |
| 1151 for (int i = 0; i < inner_scopes_.length(); i++) { | 1134 for (int i = 0; i < inner_scopes_.length(); i++) { |
| 1152 if (!inner_scopes_[i]->ResolveVariablesRecursively(info, factory)) | 1135 if (!inner_scopes_[i]->ResolveVariablesRecursively(info, factory)) |
| 1153 return false; | 1136 return false; |
| 1154 } | 1137 } |
| 1155 | 1138 |
| 1156 return true; | 1139 return true; |
| 1157 } | 1140 } |
| 1158 | 1141 |
| 1159 | 1142 |
| 1160 void Scope::PropagateScopeInfo(bool outer_scope_calls_sloppy_eval ) { | 1143 bool Scope::PropagateScopeInfo(bool outer_scope_calls_sloppy_eval ) { |
| 1161 if (outer_scope_calls_sloppy_eval) { | 1144 if (outer_scope_calls_sloppy_eval) { |
| 1162 outer_scope_calls_sloppy_eval_ = true; | 1145 outer_scope_calls_sloppy_eval_ = true; |
| 1163 } | 1146 } |
| 1164 | 1147 |
| 1165 bool calls_sloppy_eval = | 1148 bool calls_sloppy_eval = |
| 1166 this->calls_sloppy_eval() || outer_scope_calls_sloppy_eval_; | 1149 this->calls_sloppy_eval() || outer_scope_calls_sloppy_eval_; |
| 1167 for (int i = 0; i < inner_scopes_.length(); i++) { | 1150 for (int i = 0; i < inner_scopes_.length(); i++) { |
| 1168 Scope* inner = inner_scopes_[i]; | 1151 Scope* inner_scope = inner_scopes_[i]; |
| 1169 inner->PropagateScopeInfo(calls_sloppy_eval); | 1152 if (inner_scope->PropagateScopeInfo(calls_sloppy_eval)) { |
| 1170 if (inner->scope_calls_eval_ || inner->inner_scope_calls_eval_) { | |
| 1171 inner_scope_calls_eval_ = true; | 1153 inner_scope_calls_eval_ = true; |
| 1172 } | 1154 } |
| 1173 if (inner->scope_contains_with_ || inner->inner_scope_contains_with_) { | 1155 if (inner_scope->force_eager_compilation_) { |
| 1174 inner_scope_contains_with_ = true; | |
| 1175 } | |
| 1176 if (inner->force_eager_compilation_) { | |
| 1177 force_eager_compilation_ = true; | 1156 force_eager_compilation_ = true; |
| 1178 } | 1157 } |
| 1179 } | 1158 } |
| 1159 |
| 1160 return scope_calls_eval_ || inner_scope_calls_eval_; |
| 1180 } | 1161 } |
| 1181 | 1162 |
| 1182 | 1163 |
| 1183 bool Scope::MustAllocate(Variable* var) { | 1164 bool Scope::MustAllocate(Variable* var) { |
| 1184 // Give var a read/write use if there is a chance it might be accessed | 1165 // Give var a read/write use if there is a chance it might be accessed |
| 1185 // via an eval() call. This is only possible if the variable has a | 1166 // via an eval() call. This is only possible if the variable has a |
| 1186 // visible name. | 1167 // visible name. |
| 1187 if ((var->is_this() || !var->raw_name()->IsEmpty()) && | 1168 if ((var->is_this() || !var->raw_name()->IsEmpty()) && |
| 1188 (var->has_forced_context_allocation() || | 1169 (var->has_forced_context_allocation() || |
| 1189 scope_calls_eval_ || | 1170 scope_calls_eval_ || |
| 1190 inner_scope_calls_eval_ || | 1171 inner_scope_calls_eval_ || |
| 1191 scope_contains_with_ || | 1172 scope_contains_with_ || |
| 1192 is_catch_scope() || | 1173 is_catch_scope() || |
| 1193 is_block_scope() || | 1174 is_block_scope() || |
| 1194 is_module_scope() || | 1175 is_module_scope() || |
| 1195 is_global_scope())) { | 1176 is_global_scope())) { |
| 1196 var->set_is_used(); | 1177 var->set_is_used(true); |
| 1197 if (scope_calls_eval_ || inner_scope_calls_eval_) var->set_maybe_assigned(); | |
| 1198 } | 1178 } |
| 1199 // Global variables do not need to be allocated. | 1179 // Global variables do not need to be allocated. |
| 1200 return !var->IsGlobalObjectProperty() && var->is_used(); | 1180 return !var->IsGlobalObjectProperty() && var->is_used(); |
| 1201 } | 1181 } |
| 1202 | 1182 |
| 1203 | 1183 |
| 1204 bool Scope::MustAllocateInContext(Variable* var) { | 1184 bool Scope::MustAllocateInContext(Variable* var) { |
| 1205 // If var is accessed from an inner scope, or if there is a possibility | 1185 // If var is accessed from an inner scope, or if there is a possibility |
| 1206 // that it might be accessed from the current or an inner scope (through | 1186 // that it might be accessed from the current or an inner scope (through |
| 1207 // an eval() call or a runtime with lookup), it must be allocated in the | 1187 // an eval() call or a runtime with lookup), it must be allocated in the |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1406 } | 1386 } |
| 1407 | 1387 |
| 1408 | 1388 |
| 1409 int Scope::ContextLocalCount() const { | 1389 int Scope::ContextLocalCount() const { |
| 1410 if (num_heap_slots() == 0) return 0; | 1390 if (num_heap_slots() == 0) return 0; |
| 1411 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - | 1391 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - |
| 1412 (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0); | 1392 (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0); |
| 1413 } | 1393 } |
| 1414 | 1394 |
| 1415 } } // namespace v8::internal | 1395 } } // namespace v8::internal |
| OLD | NEW |