OLD | NEW |
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 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
122 variables_(), | 122 variables_(), |
123 temps_(4), | 123 temps_(4), |
124 params_(4), | 124 params_(4), |
125 unresolved_(16), | 125 unresolved_(16), |
126 decls_(4), | 126 decls_(4), |
127 already_resolved_(false) { | 127 already_resolved_(false) { |
128 SetDefaults(type, outer_scope, Handle<ScopeInfo>::null()); | 128 SetDefaults(type, outer_scope, Handle<ScopeInfo>::null()); |
129 // At some point we might want to provide outer scopes to | 129 // At some point we might want to provide outer scopes to |
130 // eval scopes (by walking the stack and reading the scope info). | 130 // eval scopes (by walking the stack and reading the scope info). |
131 // In that case, the ASSERT below needs to be adjusted. | 131 // In that case, the ASSERT below needs to be adjusted. |
132 ASSERT((type == GLOBAL_SCOPE || type == EVAL_SCOPE) == (outer_scope == NULL)); | 132 ASSERT_EQ(type == GLOBAL_SCOPE, outer_scope == NULL); |
133 ASSERT(!HasIllegalRedeclaration()); | 133 ASSERT(!HasIllegalRedeclaration()); |
134 } | 134 } |
135 | 135 |
136 | 136 |
137 Scope::Scope(Scope* inner_scope, | 137 Scope::Scope(Scope* inner_scope, |
138 ScopeType type, | 138 ScopeType type, |
139 Handle<ScopeInfo> scope_info) | 139 Handle<ScopeInfo> scope_info) |
140 : isolate_(Isolate::Current()), | 140 : isolate_(Isolate::Current()), |
141 inner_scopes_(4), | 141 inner_scopes_(4), |
142 variables_(), | 142 variables_(), |
143 temps_(4), | 143 temps_(4), |
144 params_(4), | 144 params_(4), |
145 unresolved_(16), | 145 unresolved_(16), |
146 decls_(4), | 146 decls_(4), |
147 already_resolved_(true) { | 147 already_resolved_(true) { |
148 SetDefaults(type, NULL, scope_info); | 148 SetDefaults(type, NULL, scope_info); |
149 if (!scope_info.is_null()) { | 149 if (!scope_info.is_null()) { |
150 num_heap_slots_ = scope_info_->ContextLength(); | 150 num_heap_slots_ = scope_info_->ContextLength(); |
| 151 } else if (is_with_scope()) { |
| 152 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; |
151 } | 153 } |
152 AddInnerScope(inner_scope); | 154 AddInnerScope(inner_scope); |
153 } | 155 } |
154 | 156 |
155 | 157 |
156 Scope::Scope(Scope* inner_scope, Handle<String> catch_variable_name) | 158 Scope::Scope(Scope* inner_scope, Handle<String> catch_variable_name) |
157 : isolate_(Isolate::Current()), | 159 : isolate_(Isolate::Current()), |
158 inner_scopes_(1), | 160 inner_scopes_(1), |
159 variables_(), | 161 variables_(), |
160 temps_(0), | 162 temps_(0), |
161 params_(0), | 163 params_(0), |
162 unresolved_(0), | 164 unresolved_(0), |
163 decls_(0), | 165 decls_(0), |
164 already_resolved_(true) { | 166 already_resolved_(true) { |
165 SetDefaults(CATCH_SCOPE, NULL, Handle<ScopeInfo>::null()); | 167 SetDefaults(CATCH_SCOPE, NULL, Handle<ScopeInfo>::null()); |
166 AddInnerScope(inner_scope); | 168 AddInnerScope(inner_scope); |
167 ++num_var_or_const_; | 169 ++num_var_or_const_; |
| 170 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; |
168 Variable* variable = variables_.Declare(this, | 171 Variable* variable = variables_.Declare(this, |
169 catch_variable_name, | 172 catch_variable_name, |
170 VAR, | 173 VAR, |
171 true, // Valid left-hand side. | 174 true, // Valid left-hand side. |
172 Variable::NORMAL, | 175 Variable::NORMAL, |
173 kCreatedInitialized); | 176 kCreatedInitialized); |
174 AllocateHeapSlot(variable); | 177 AllocateHeapSlot(variable); |
175 } | 178 } |
176 | 179 |
177 | 180 |
(...skipping 16 matching lines...) Expand all Loading... |
194 ? outer_scope->strict_mode_flag_ : kNonStrictMode; | 197 ? outer_scope->strict_mode_flag_ : kNonStrictMode; |
195 outer_scope_calls_non_strict_eval_ = false; | 198 outer_scope_calls_non_strict_eval_ = false; |
196 inner_scope_calls_eval_ = false; | 199 inner_scope_calls_eval_ = false; |
197 force_eager_compilation_ = false; | 200 force_eager_compilation_ = false; |
198 num_var_or_const_ = 0; | 201 num_var_or_const_ = 0; |
199 num_stack_slots_ = 0; | 202 num_stack_slots_ = 0; |
200 num_heap_slots_ = 0; | 203 num_heap_slots_ = 0; |
201 scope_info_ = scope_info; | 204 scope_info_ = scope_info; |
202 start_position_ = RelocInfo::kNoPosition; | 205 start_position_ = RelocInfo::kNoPosition; |
203 end_position_ = RelocInfo::kNoPosition; | 206 end_position_ = RelocInfo::kNoPosition; |
| 207 if (!scope_info.is_null()) { |
| 208 scope_calls_eval_ = scope_info->CallsEval(); |
| 209 strict_mode_flag_ = |
| 210 scope_info->IsStrictMode() ? kStrictMode : kNonStrictMode; |
| 211 } |
204 } | 212 } |
205 | 213 |
206 | 214 |
207 Scope* Scope::DeserializeScopeChain(CompilationInfo* info, | 215 Scope* Scope::DeserializeScopeChain(Context* context, Scope* global_scope) { |
208 Scope* global_scope) { | |
209 // Reconstruct the outer scope chain from a closure's context chain. | 216 // Reconstruct the outer scope chain from a closure's context chain. |
210 ASSERT(!info->closure().is_null()); | |
211 Context* context = info->closure()->context(); | |
212 Scope* current_scope = NULL; | 217 Scope* current_scope = NULL; |
213 Scope* innermost_scope = NULL; | 218 Scope* innermost_scope = NULL; |
214 bool contains_with = false; | 219 bool contains_with = false; |
215 while (!context->IsGlobalContext()) { | 220 while (!context->IsGlobalContext()) { |
216 if (context->IsWithContext()) { | 221 if (context->IsWithContext()) { |
217 Scope* with_scope = new Scope(current_scope, | 222 Scope* with_scope = new Scope(current_scope, |
218 WITH_SCOPE, | 223 WITH_SCOPE, |
219 Handle<ScopeInfo>::null()); | 224 Handle<ScopeInfo>::null()); |
220 current_scope = with_scope; | 225 current_scope = with_scope; |
221 // All the inner scopes are inside a with. | 226 // All the inner scopes are inside a with. |
(...skipping 20 matching lines...) Expand all Loading... |
242 if (innermost_scope == NULL) innermost_scope = current_scope; | 247 if (innermost_scope == NULL) innermost_scope = current_scope; |
243 | 248 |
244 // 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. |
245 if (context->previous()->closure() != context->closure()) { | 250 if (context->previous()->closure() != context->closure()) { |
246 contains_with = false; | 251 contains_with = false; |
247 } | 252 } |
248 context = context->previous(); | 253 context = context->previous(); |
249 } | 254 } |
250 | 255 |
251 global_scope->AddInnerScope(current_scope); | 256 global_scope->AddInnerScope(current_scope); |
| 257 global_scope->PropagateScopeInfo(false); |
252 return (innermost_scope == NULL) ? global_scope : innermost_scope; | 258 return (innermost_scope == NULL) ? global_scope : innermost_scope; |
253 } | 259 } |
254 | 260 |
255 | 261 |
256 bool Scope::Analyze(CompilationInfo* info) { | 262 bool Scope::Analyze(CompilationInfo* info) { |
257 ASSERT(info->function() != NULL); | 263 ASSERT(info->function() != NULL); |
258 Scope* top = info->function()->scope(); | 264 Scope* scope = info->function()->scope(); |
| 265 Scope* top = scope; |
259 | 266 |
260 while (top->outer_scope() != NULL) top = top->outer_scope(); | 267 // When there are unresolved outer scopes, traverse the scope tree up and |
261 top->AllocateVariables(info->calling_context()); | 268 // start scope resolution and variable allocation from the first unresolved |
| 269 // ancestor. |
| 270 while (!top->is_global_scope() && |
| 271 !top->outer_scope()->already_resolved()) { |
| 272 top = top->outer_scope(); |
| 273 } |
| 274 |
| 275 // Allocated the variables. |
| 276 top->AllocateVariables(info->global_scope()); |
262 | 277 |
263 #ifdef DEBUG | 278 #ifdef DEBUG |
264 if (info->isolate()->bootstrapper()->IsActive() | 279 if (info->isolate()->bootstrapper()->IsActive() |
265 ? FLAG_print_builtin_scopes | 280 ? FLAG_print_builtin_scopes |
266 : FLAG_print_scopes) { | 281 : FLAG_print_scopes) { |
267 info->function()->scope()->Print(); | 282 scope->Print(); |
268 } | 283 } |
269 #endif | 284 #endif |
270 | 285 |
271 info->SetScope(info->function()->scope()); | 286 info->SetScope(scope); |
272 return true; // Can not fail. | 287 return true; // Can not fail. |
273 } | 288 } |
274 | 289 |
275 | 290 |
276 void Scope::Initialize() { | 291 void Scope::Initialize() { |
277 ASSERT(!already_resolved()); | 292 ASSERT(!already_resolved()); |
278 | 293 |
279 // Add this scope as a new inner scope of the outer scope. | 294 // Add this scope as a new inner scope of the outer scope. |
280 if (outer_scope_ != NULL) { | 295 if (outer_scope_ != NULL) { |
281 outer_scope_->inner_scopes_.Add(this); | 296 outer_scope_->inner_scopes_.Add(this); |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
349 return NULL; | 364 return NULL; |
350 } | 365 } |
351 | 366 |
352 | 367 |
353 Variable* Scope::LocalLookup(Handle<String> name) { | 368 Variable* Scope::LocalLookup(Handle<String> name) { |
354 Variable* result = variables_.Lookup(name); | 369 Variable* result = variables_.Lookup(name); |
355 if (result != NULL || scope_info_.is_null()) { | 370 if (result != NULL || scope_info_.is_null()) { |
356 return result; | 371 return result; |
357 } | 372 } |
358 // If we have a serialized scope info, we might find the variable there. | 373 // If we have a serialized scope info, we might find the variable there. |
359 // | |
360 // We should never lookup 'arguments' in this scope as it is implicitly | |
361 // present in every scope. | |
362 ASSERT(*name != *isolate_->factory()->arguments_symbol()); | |
363 // There should be no local slot with the given name. | 374 // There should be no local slot with the given name. |
364 ASSERT(scope_info_->StackSlotIndex(*name) < 0); | 375 ASSERT(scope_info_->StackSlotIndex(*name) < 0); |
365 | 376 |
366 // Check context slot lookup. | 377 // Check context slot lookup. |
367 VariableMode mode; | 378 VariableMode mode; |
368 InitializationFlag init_flag; | 379 InitializationFlag init_flag; |
369 int index = scope_info_->ContextSlotIndex(*name, &mode, &init_flag); | 380 int index = scope_info_->ContextSlotIndex(*name, &mode, &init_flag); |
370 if (index < 0) { | 381 if (index < 0) { |
371 // Check parameters. | 382 // Check parameters. |
372 mode = VAR; | 383 mode = VAR; |
373 init_flag = kCreatedInitialized; | 384 init_flag = kCreatedInitialized; |
374 index = scope_info_->ParameterIndex(*name); | 385 index = scope_info_->ParameterIndex(*name); |
375 if (index < 0) { | 386 if (index < 0) return NULL; |
376 // Check the function name. | |
377 index = scope_info_->FunctionContextSlotIndex(*name, &mode); | |
378 if (index < 0) return NULL; | |
379 } | |
380 } | 387 } |
381 | 388 |
382 Variable* var = | 389 Variable* var = |
383 variables_.Declare(this, | 390 variables_.Declare(this, |
384 name, | 391 name, |
385 mode, | 392 mode, |
386 true, | 393 true, |
387 Variable::NORMAL, | 394 Variable::NORMAL, |
388 init_flag); | 395 init_flag); |
389 var->AllocateTo(Variable::CONTEXT, index); | 396 var->AllocateTo(Variable::CONTEXT, index); |
390 return var; | 397 return var; |
391 } | 398 } |
392 | 399 |
393 | 400 |
| 401 Variable* Scope::LookupFunctionVar(Handle<String> name) { |
| 402 if (function_ != NULL && function_->name().is_identical_to(name)) { |
| 403 return function_->var(); |
| 404 } else if (!scope_info_.is_null()) { |
| 405 // If we are backed by a scope info, try to lookup the variable there. |
| 406 VariableMode mode; |
| 407 int index = scope_info_->FunctionContextSlotIndex(*name, &mode); |
| 408 if (index < 0) return NULL; |
| 409 Variable* var = DeclareFunctionVar(name, mode); |
| 410 var->AllocateTo(Variable::CONTEXT, index); |
| 411 return var; |
| 412 } else { |
| 413 return NULL; |
| 414 } |
| 415 } |
| 416 |
| 417 |
394 Variable* Scope::Lookup(Handle<String> name) { | 418 Variable* Scope::Lookup(Handle<String> name) { |
395 for (Scope* scope = this; | 419 for (Scope* scope = this; |
396 scope != NULL; | 420 scope != NULL; |
397 scope = scope->outer_scope()) { | 421 scope = scope->outer_scope()) { |
398 Variable* var = scope->LocalLookup(name); | 422 Variable* var = scope->LocalLookup(name); |
399 if (var != NULL) return var; | 423 if (var != NULL) return var; |
400 } | 424 } |
401 return NULL; | 425 return NULL; |
402 } | 426 } |
403 | 427 |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
552 if (var->IsStackLocal()) { | 576 if (var->IsStackLocal()) { |
553 stack_locals->Add(var); | 577 stack_locals->Add(var); |
554 } else if (var->IsContextSlot()) { | 578 } else if (var->IsContextSlot()) { |
555 context_locals->Add(var); | 579 context_locals->Add(var); |
556 } | 580 } |
557 } | 581 } |
558 } | 582 } |
559 } | 583 } |
560 | 584 |
561 | 585 |
562 void Scope::AllocateVariables(Handle<Context> context) { | 586 void Scope::AllocateVariables(Scope* global_scope) { |
563 ASSERT(outer_scope_ == NULL); // eval or global scopes only | |
564 | |
565 // 1) Propagate scope information. | 587 // 1) Propagate scope information. |
566 // If we are in an eval scope, we may have other outer scopes about | |
567 // which we don't know anything at this point. Thus we must be conservative | |
568 // and assume they may invoke eval themselves. Eventually we could capture | |
569 // this information in the ScopeInfo and then use it here (by traversing | |
570 // the call chain stack, at compile time). | |
571 | |
572 bool outer_scope_calls_non_strict_eval = false; | 588 bool outer_scope_calls_non_strict_eval = false; |
573 if (!is_global_scope()) { | 589 if (outer_scope_ != NULL) { |
574 context->ComputeEvalScopeInfo(&outer_scope_calls_non_strict_eval); | 590 outer_scope_calls_non_strict_eval = |
| 591 outer_scope_->outer_scope_calls_non_strict_eval() | |
| 592 outer_scope_->calls_non_strict_eval(); |
575 } | 593 } |
576 PropagateScopeInfo(outer_scope_calls_non_strict_eval); | 594 PropagateScopeInfo(outer_scope_calls_non_strict_eval); |
577 | 595 |
578 // 2) Resolve variables. | 596 // 2) Resolve variables. |
579 Scope* global_scope = NULL; | 597 ResolveVariablesRecursively(global_scope); |
580 if (is_global_scope()) global_scope = this; | |
581 ResolveVariablesRecursively(global_scope, context); | |
582 | 598 |
583 // 3) Allocate variables. | 599 // 3) Allocate variables. |
584 AllocateVariablesRecursively(); | 600 AllocateVariablesRecursively(); |
585 } | 601 } |
586 | 602 |
587 | 603 |
588 bool Scope::AllowsLazyCompilation() const { | 604 bool Scope::AllowsLazyCompilation() const { |
589 return !force_eager_compilation_ && HasTrivialOuterContext(); | 605 return !force_eager_compilation_ && HasTrivialOuterContext(); |
590 } | 606 } |
591 | 607 |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
825 Variable::NORMAL, | 841 Variable::NORMAL, |
826 init_flag); | 842 init_flag); |
827 // Allocate it by giving it a dynamic lookup. | 843 // Allocate it by giving it a dynamic lookup. |
828 var->AllocateTo(Variable::LOOKUP, -1); | 844 var->AllocateTo(Variable::LOOKUP, -1); |
829 } | 845 } |
830 return var; | 846 return var; |
831 } | 847 } |
832 | 848 |
833 | 849 |
834 Variable* Scope::LookupRecursive(Handle<String> name, | 850 Variable* Scope::LookupRecursive(Handle<String> name, |
835 Handle<Context> context, | |
836 BindingKind* binding_kind) { | 851 BindingKind* binding_kind) { |
837 ASSERT(binding_kind != NULL); | 852 ASSERT(binding_kind != NULL); |
838 // Try to find the variable in this scope. | 853 // Try to find the variable in this scope. |
839 Variable* var = LocalLookup(name); | 854 Variable* var = LocalLookup(name); |
840 | 855 |
841 // We found a variable and we are done. (Even if there is an 'eval' in | 856 // We found a variable and we are done. (Even if there is an 'eval' in |
842 // this scope which introduces the same variable again, the resulting | 857 // this scope which introduces the same variable again, the resulting |
843 // variable remains the same.) | 858 // variable remains the same.) |
844 if (var != NULL) { | 859 if (var != NULL) { |
845 *binding_kind = BOUND; | 860 *binding_kind = BOUND; |
846 return var; | 861 return var; |
847 } | 862 } |
848 | 863 |
849 // We did not find a variable locally. Check against the function variable, | 864 // We did not find a variable locally. Check against the function variable, |
850 // if any. We can do this for all scopes, since the function variable is | 865 // if any. We can do this for all scopes, since the function variable is |
851 // only present - if at all - for function scopes. | 866 // only present - if at all - for function scopes. |
852 // | |
853 // This lookup corresponds to a lookup in the "intermediate" scope sitting | |
854 // between this scope and the outer scope. (ECMA-262, 3rd., requires that | |
855 // the name of named function literal is kept in an intermediate scope | |
856 // in between this scope and the next outer scope.) | |
857 *binding_kind = UNBOUND; | 867 *binding_kind = UNBOUND; |
858 if (function_ != NULL && function_->name().is_identical_to(name)) { | 868 var = LookupFunctionVar(name); |
859 var = function_->var(); | 869 if (var != NULL) { |
860 *binding_kind = BOUND; | 870 *binding_kind = BOUND; |
861 } else if (outer_scope_ != NULL) { | 871 } else if (outer_scope_ != NULL) { |
862 var = outer_scope_->LookupRecursive(name, context, binding_kind); | 872 var = outer_scope_->LookupRecursive(name, binding_kind); |
863 if (*binding_kind == BOUND && (is_function_scope() || is_with_scope())) { | 873 if (*binding_kind == BOUND && (is_function_scope() || is_with_scope())) { |
864 var->ForceContextAllocation(); | 874 var->ForceContextAllocation(); |
865 } | 875 } |
| 876 } else { |
| 877 ASSERT(is_global_scope()); |
866 } | 878 } |
867 | 879 |
868 if (is_with_scope()) { | 880 if (is_with_scope()) { |
869 // The current scope is a with scope, so the variable binding can not be | 881 // The current scope is a with scope, so the variable binding can not be |
870 // statically resolved. However, note that it was necessary to do a lookup | 882 // statically resolved. However, note that it was necessary to do a lookup |
871 // in the outer scope anyway, because if a binding exists in an outer scope, | 883 // in the outer scope anyway, because if a binding exists in an outer scope, |
872 // the associated variable has to be marked as potentially being accessed | 884 // the associated variable has to be marked as potentially being accessed |
873 // from inside of an inner with scope (the property may not be in the 'with' | 885 // from inside of an inner with scope (the property may not be in the 'with' |
874 // object). | 886 // object). |
875 *binding_kind = DYNAMIC_LOOKUP; | 887 *binding_kind = DYNAMIC_LOOKUP; |
876 return NULL; | 888 return NULL; |
877 } else if (is_eval_scope()) { | |
878 // No local binding was found, no 'with' statements have been encountered | |
879 // and the code is executed as part of a call to 'eval'. The calling context | |
880 // contains scope information that we can use to determine if the variable | |
881 // is global, i.e. the calling context chain does not contain a binding and | |
882 // no 'with' contexts. | |
883 ASSERT(*binding_kind == UNBOUND); | |
884 *binding_kind = context->GlobalIfNotShadowedByEval(name) | |
885 ? UNBOUND_EVAL_SHADOWED : DYNAMIC_LOOKUP; | |
886 return NULL; | |
887 } else if (calls_non_strict_eval()) { | 889 } else if (calls_non_strict_eval()) { |
888 // A variable binding may have been found in an outer scope, but the current | 890 // A variable binding may have been found in an outer scope, but the current |
889 // scope makes a non-strict 'eval' call, so the found variable may not be | 891 // scope makes a non-strict 'eval' call, so the found variable may not be |
890 // the correct one (the 'eval' may introduce a binding with the same name). | 892 // the correct one (the 'eval' may introduce a binding with the same name). |
891 // In that case, change the lookup result to reflect this situation. | 893 // In that case, change the lookup result to reflect this situation. |
892 if (*binding_kind == BOUND) { | 894 if (*binding_kind == BOUND) { |
893 *binding_kind = BOUND_EVAL_SHADOWED; | 895 *binding_kind = BOUND_EVAL_SHADOWED; |
894 } else if (*binding_kind == UNBOUND) { | 896 } else if (*binding_kind == UNBOUND) { |
895 *binding_kind = UNBOUND_EVAL_SHADOWED; | 897 *binding_kind = UNBOUND_EVAL_SHADOWED; |
896 } | 898 } |
897 } | 899 } |
898 return var; | 900 return var; |
899 } | 901 } |
900 | 902 |
901 | 903 |
902 void Scope::ResolveVariable(Scope* global_scope, | 904 void Scope::ResolveVariable(Scope* global_scope, |
903 Handle<Context> context, | |
904 VariableProxy* proxy) { | 905 VariableProxy* proxy) { |
905 ASSERT(global_scope == NULL || global_scope->is_global_scope()); | 906 ASSERT(global_scope == NULL || global_scope->is_global_scope()); |
906 | 907 |
907 // If the proxy is already resolved there's nothing to do | 908 // If the proxy is already resolved there's nothing to do |
908 // (functions and consts may be resolved by the parser). | 909 // (functions and consts may be resolved by the parser). |
909 if (proxy->var() != NULL) return; | 910 if (proxy->var() != NULL) return; |
910 | 911 |
911 // Otherwise, try to resolve the variable. | 912 // Otherwise, try to resolve the variable. |
912 BindingKind binding_kind; | 913 BindingKind binding_kind; |
913 Variable* var = LookupRecursive(proxy->name(), context, &binding_kind); | 914 Variable* var = LookupRecursive(proxy->name(), &binding_kind); |
914 switch (binding_kind) { | 915 switch (binding_kind) { |
915 case BOUND: | 916 case BOUND: |
916 // We found a variable binding. | 917 // We found a variable binding. |
917 break; | 918 break; |
918 | 919 |
919 case BOUND_EVAL_SHADOWED: | 920 case BOUND_EVAL_SHADOWED: |
920 // We found a variable variable binding that might be shadowed | 921 // We found a variable variable binding that might be shadowed |
921 // by 'eval' introduced variable bindings. | 922 // by 'eval' introduced variable bindings. |
922 if (var->is_global()) { | 923 if (var->is_global()) { |
923 var = NonLocal(proxy->name(), DYNAMIC_GLOBAL); | 924 var = NonLocal(proxy->name(), DYNAMIC_GLOBAL); |
(...skipping 20 matching lines...) Expand all Loading... |
944 // The variable could not be resolved statically. | 945 // The variable could not be resolved statically. |
945 var = NonLocal(proxy->name(), DYNAMIC); | 946 var = NonLocal(proxy->name(), DYNAMIC); |
946 break; | 947 break; |
947 } | 948 } |
948 | 949 |
949 ASSERT(var != NULL); | 950 ASSERT(var != NULL); |
950 proxy->BindTo(var); | 951 proxy->BindTo(var); |
951 } | 952 } |
952 | 953 |
953 | 954 |
954 void Scope::ResolveVariablesRecursively(Scope* global_scope, | 955 void Scope::ResolveVariablesRecursively(Scope* global_scope) { |
955 Handle<Context> context) { | |
956 ASSERT(global_scope == NULL || global_scope->is_global_scope()); | 956 ASSERT(global_scope == NULL || global_scope->is_global_scope()); |
957 | 957 |
958 // Resolve unresolved variables for this scope. | 958 // Resolve unresolved variables for this scope. |
959 for (int i = 0; i < unresolved_.length(); i++) { | 959 for (int i = 0; i < unresolved_.length(); i++) { |
960 ResolveVariable(global_scope, context, unresolved_[i]); | 960 ResolveVariable(global_scope, unresolved_[i]); |
961 } | 961 } |
962 | 962 |
963 // Resolve unresolved variables for inner scopes. | 963 // Resolve unresolved variables for inner scopes. |
964 for (int i = 0; i < inner_scopes_.length(); i++) { | 964 for (int i = 0; i < inner_scopes_.length(); i++) { |
965 inner_scopes_[i]->ResolveVariablesRecursively(global_scope, context); | 965 inner_scopes_[i]->ResolveVariablesRecursively(global_scope); |
966 } | 966 } |
967 } | 967 } |
968 | 968 |
969 | 969 |
970 bool Scope::PropagateScopeInfo(bool outer_scope_calls_non_strict_eval ) { | 970 bool Scope::PropagateScopeInfo(bool outer_scope_calls_non_strict_eval ) { |
971 if (outer_scope_calls_non_strict_eval) { | 971 if (outer_scope_calls_non_strict_eval) { |
972 outer_scope_calls_non_strict_eval_ = true; | 972 outer_scope_calls_non_strict_eval_ = true; |
973 } | 973 } |
974 | 974 |
975 bool calls_non_strict_eval = | 975 bool calls_non_strict_eval = |
976 (scope_calls_eval_ && !is_strict_mode()) || | 976 this->calls_non_strict_eval() || outer_scope_calls_non_strict_eval_; |
977 outer_scope_calls_non_strict_eval_; | |
978 for (int i = 0; i < inner_scopes_.length(); i++) { | 977 for (int i = 0; i < inner_scopes_.length(); i++) { |
979 Scope* inner_scope = inner_scopes_[i]; | 978 Scope* inner_scope = inner_scopes_[i]; |
980 if (inner_scope->PropagateScopeInfo(calls_non_strict_eval)) { | 979 if (inner_scope->PropagateScopeInfo(calls_non_strict_eval)) { |
981 inner_scope_calls_eval_ = true; | 980 inner_scope_calls_eval_ = true; |
982 } | 981 } |
983 if (inner_scope->force_eager_compilation_) { | 982 if (inner_scope->force_eager_compilation_) { |
984 force_eager_compilation_ = true; | 983 force_eager_compilation_ = true; |
985 } | 984 } |
986 } | 985 } |
987 | 986 |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1180 } | 1179 } |
1181 | 1180 |
1182 | 1181 |
1183 int Scope::ContextLocalCount() const { | 1182 int Scope::ContextLocalCount() const { |
1184 if (num_heap_slots() == 0) return 0; | 1183 if (num_heap_slots() == 0) return 0; |
1185 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - | 1184 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - |
1186 (function_ != NULL && function_->var()->IsContextSlot() ? 1 : 0); | 1185 (function_ != NULL && function_->var()->IsContextSlot() ? 1 : 0); |
1187 } | 1186 } |
1188 | 1187 |
1189 } } // namespace v8::internal | 1188 } } // namespace v8::internal |
OLD | NEW |