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

Side by Side Diff: src/scopes.cc

Issue 7904008: Introduce with scope and rework variable resolution. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
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
« src/scopes.h ('K') | « src/scopes.h ('k') | no next file » | 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 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 Scope* Scope::DeserializeScopeChain(CompilationInfo* info, 217 Scope* Scope::DeserializeScopeChain(CompilationInfo* info,
218 Scope* global_scope) { 218 Scope* global_scope) {
219 // Reconstruct the outer scope chain from a closure's context chain. 219 // Reconstruct the outer scope chain from a closure's context chain.
220 ASSERT(!info->closure().is_null()); 220 ASSERT(!info->closure().is_null());
221 Context* context = info->closure()->context(); 221 Context* context = info->closure()->context();
222 Scope* current_scope = NULL; 222 Scope* current_scope = NULL;
223 Scope* innermost_scope = NULL; 223 Scope* innermost_scope = NULL;
224 bool contains_with = false; 224 bool contains_with = false;
225 while (!context->IsGlobalContext()) { 225 while (!context->IsGlobalContext()) {
226 if (context->IsWithContext()) { 226 if (context->IsWithContext()) {
227 Scope* with_scope = new Scope(WITH_SCOPE);
Kevin Millikin (Chromium) 2011/09/15 09:38:13 Make the constructor take the current scope and ca
Steven 2011/09/15 19:54:06 There's already such a constructor that is used du
228 with_scope->AddInnerScope(current_scope);
229 current_scope = with_scope;
227 // All the inner scopes are inside a with. 230 // All the inner scopes are inside a with.
228 contains_with = true; 231 contains_with = true;
229 for (Scope* s = innermost_scope; s != NULL; s = s->outer_scope()) { 232 for (Scope* s = innermost_scope; s != NULL; s = s->outer_scope()) {
230 s->scope_inside_with_ = true; 233 s->scope_inside_with_ = true;
231 } 234 }
235 } else if (context->IsFunctionContext()) {
236 SerializedScopeInfo* scope_info =
237 context->closure()->shared()->scope_info();
238 current_scope = new Scope(current_scope, FUNCTION_SCOPE,
239 Handle<SerializedScopeInfo>(scope_info));
240 } else if (context->IsBlockContext()) {
241 SerializedScopeInfo* scope_info =
242 SerializedScopeInfo::cast(context->extension());
243 current_scope = new Scope(current_scope, BLOCK_SCOPE,
244 Handle<SerializedScopeInfo>(scope_info));
232 } else { 245 } else {
233 if (context->IsFunctionContext()) { 246 ASSERT(context->IsCatchContext());
234 SerializedScopeInfo* scope_info = 247 String* name = String::cast(context->extension());
235 context->closure()->shared()->scope_info(); 248 current_scope = new Scope(current_scope, Handle<String>(name));
236 current_scope = new Scope(current_scope, FUNCTION_SCOPE,
237 Handle<SerializedScopeInfo>(scope_info));
238 } else if (context->IsBlockContext()) {
239 SerializedScopeInfo* scope_info =
240 SerializedScopeInfo::cast(context->extension());
241 current_scope = new Scope(current_scope, BLOCK_SCOPE,
242 Handle<SerializedScopeInfo>(scope_info));
243 } else {
244 ASSERT(context->IsCatchContext());
245 String* name = String::cast(context->extension());
246 current_scope = new Scope(current_scope, Handle<String>(name));
247 }
248 if (contains_with) current_scope->RecordWithStatement();
249 if (innermost_scope == NULL) innermost_scope = current_scope;
250 } 249 }
250 if (contains_with) current_scope->RecordWithStatement();
251 if (innermost_scope == NULL) innermost_scope = current_scope;
251 252
252 // Forget about a with when we move to a context for a different function. 253 // Forget about a with when we move to a context for a different function.
253 if (context->previous()->closure() != context->closure()) { 254 if (context->previous()->closure() != context->closure()) {
254 contains_with = false; 255 contains_with = false;
255 } 256 }
256 context = context->previous(); 257 context = context->previous();
257 } 258 }
258 259
259 global_scope->AddInnerScope(current_scope); 260 global_scope->AddInnerScope(current_scope);
260 return (innermost_scope == NULL) ? global_scope : innermost_scope; 261 return (innermost_scope == NULL) ? global_scope : innermost_scope;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
293 } 294 }
294 295
295 // Declare convenience variables. 296 // Declare convenience variables.
296 // Declare and allocate receiver (even for the global scope, and even 297 // Declare and allocate receiver (even for the global scope, and even
297 // if naccesses_ == 0). 298 // if naccesses_ == 0).
298 // NOTE: When loading parameters in the global scope, we must take 299 // NOTE: When loading parameters in the global scope, we must take
299 // care not to access them as properties of the global object, but 300 // care not to access them as properties of the global object, but
300 // instead load them directly from the stack. Currently, the only 301 // instead load them directly from the stack. Currently, the only
301 // such parameter is 'this' which is passed on the stack when 302 // such parameter is 'this' which is passed on the stack when
302 // invoking scripts 303 // invoking scripts
303 if (is_catch_scope() || is_block_scope()) { 304 if (is_catch_scope() || is_block_scope() || is_with_scope()) {
Kevin Millikin (Chromium) 2011/09/15 09:38:13 Flip the condition and use: if (is_declaration_sc
Steven 2011/09/15 19:54:06 Done.
304 ASSERT(outer_scope() != NULL); 305 ASSERT(outer_scope() != NULL);
305 receiver_ = outer_scope()->receiver(); 306 receiver_ = outer_scope()->receiver();
306 } else { 307 } else {
307 ASSERT(is_function_scope() || 308 ASSERT(is_function_scope() ||
308 is_global_scope() || 309 is_global_scope() ||
309 is_eval_scope()); 310 is_eval_scope());
310 Variable* var = 311 Variable* var =
311 variables_.Declare(this, 312 variables_.Declare(this,
312 isolate_->factory()->this_symbol(), 313 isolate_->factory()->this_symbol(),
313 Variable::VAR, 314 Variable::VAR,
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
501 } 502 }
502 503
503 504
504 Declaration* Scope::CheckConflictingVarDeclarations() { 505 Declaration* Scope::CheckConflictingVarDeclarations() {
505 int length = decls_.length(); 506 int length = decls_.length();
506 for (int i = 0; i < length; i++) { 507 for (int i = 0; i < length; i++) {
507 Declaration* decl = decls_[i]; 508 Declaration* decl = decls_[i];
508 if (decl->mode() != Variable::VAR) continue; 509 if (decl->mode() != Variable::VAR) continue;
509 Handle<String> name = decl->proxy()->name(); 510 Handle<String> name = decl->proxy()->name();
510 bool cond = true; 511 bool cond = true;
511 for (Scope* scope = decl->scope(); cond ; scope = scope->outer_scope_) { 512 for (Scope* scope = decl->scope(); cond ; scope = scope->outer_scope_) {
Kevin Millikin (Chromium) 2011/09/15 09:38:13 I found the logic of this loop too complicated. Y
Steven 2011/09/15 19:54:06 Done.
512 // There is a conflict if there exists a non-VAR binding. 513 // There is a conflict if there exists a non-VAR binding.
513 Variable* other_var = scope->variables_.Lookup(name); 514 Variable* other_var = scope->variables_.Lookup(name);
514 if (other_var != NULL && other_var->mode() != Variable::VAR) { 515 if (other_var != NULL && other_var->mode() != Variable::VAR) {
515 return decl; 516 return decl;
516 } 517 }
517 518
518 // Include declaration scope in the iteration but stop after. 519 // Include declaration scope in the iteration but stop after.
519 if (!scope->is_block_scope() && !scope->is_catch_scope()) cond = false; 520 if (scope->is_declaration_scope()) cond = false;
520 } 521 }
521 } 522 }
522 return NULL; 523 return NULL;
523 } 524 }
524 525
525 526
526 template<class Allocator> 527 template<class Allocator>
527 void Scope::CollectUsedVariables(List<Variable*, Allocator>* locals) { 528 void Scope::CollectUsedVariables(List<Variable*, Allocator>* locals) {
528 // Collect variables in this scope. 529 // Collect variables in this scope.
529 // Note that the function_ variable - if present - is not 530 // Note that the function_ variable - if present - is not
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
620 for (Scope* s = this; s != scope; s = s->outer_scope_) { 621 for (Scope* s = this; s != scope; s = s->outer_scope_) {
621 ASSERT(s != NULL); // scope must be in the scope chain 622 ASSERT(s != NULL); // scope must be in the scope chain
622 if (s->num_heap_slots() > 0) n++; 623 if (s->num_heap_slots() > 0) n++;
623 } 624 }
624 return n; 625 return n;
625 } 626 }
626 627
627 628
628 Scope* Scope::DeclarationScope() { 629 Scope* Scope::DeclarationScope() {
629 Scope* scope = this; 630 Scope* scope = this;
630 while (scope->is_catch_scope() || 631 while (!scope->is_declaration_scope()) {
631 scope->is_block_scope()) {
632 scope = scope->outer_scope(); 632 scope = scope->outer_scope();
633 } 633 }
634 return scope; 634 return scope;
635 } 635 }
636 636
637 637
638 Handle<SerializedScopeInfo> Scope::GetSerializedScopeInfo() { 638 Handle<SerializedScopeInfo> Scope::GetSerializedScopeInfo() {
639 if (scope_info_.is_null()) { 639 if (scope_info_.is_null()) {
640 scope_info_ = SerializedScopeInfo::Create(this); 640 scope_info_ = SerializedScopeInfo::Create(this);
641 } 641 }
642 return scope_info_; 642 return scope_info_;
643 } 643 }
644 644
645 645
646 #ifdef DEBUG 646 #ifdef DEBUG
647 static const char* Header(Scope::Type type) { 647 static const char* Header(Scope::Type type) {
648 switch (type) { 648 switch (type) {
649 case Scope::EVAL_SCOPE: return "eval"; 649 case Scope::EVAL_SCOPE: return "eval";
650 case Scope::FUNCTION_SCOPE: return "function"; 650 case Scope::FUNCTION_SCOPE: return "function";
651 case Scope::GLOBAL_SCOPE: return "global"; 651 case Scope::GLOBAL_SCOPE: return "global";
652 case Scope::CATCH_SCOPE: return "catch"; 652 case Scope::CATCH_SCOPE: return "catch";
653 case Scope::BLOCK_SCOPE: return "block"; 653 case Scope::BLOCK_SCOPE: return "block";
654 case Scope::WITH_SCOPE: return "with";
654 } 655 }
655 UNREACHABLE(); 656 UNREACHABLE();
656 return NULL; 657 return NULL;
657 } 658 }
658 659
659 660
660 static void Indent(int n, const char* str) { 661 static void Indent(int n, const char* str) {
661 PrintF("%*s%s", n, "", str); 662 PrintF("%*s%s", n, "", str);
662 } 663 }
663 664
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
804 if (var == NULL) { 805 if (var == NULL) {
805 // Declare a new non-local. 806 // Declare a new non-local.
806 var = map->Declare(NULL, name, mode, true, Variable::NORMAL); 807 var = map->Declare(NULL, name, mode, true, Variable::NORMAL);
807 // Allocate it by giving it a dynamic lookup. 808 // Allocate it by giving it a dynamic lookup.
808 var->AllocateTo(Variable::LOOKUP, -1); 809 var->AllocateTo(Variable::LOOKUP, -1);
809 } 810 }
810 return var; 811 return var;
811 } 812 }
812 813
813 814
814 // Lookup a variable starting with this scope. The result is either 815 Scope::LookupResult Scope::LookupRecursive(Handle<String> name,
815 // the statically resolved variable belonging to an outer scope, or 816 bool from_inner_scope,
816 // NULL. It may be NULL because a) we couldn't find a variable, or b) 817 Variable** var) {
817 // because the variable is just a guess (and may be shadowed by 818 // Try to find the variable in this scope.
818 // another variable that is introduced dynamically via an 'eval' call 819 *var = LocalLookup(name);
819 // or a 'with' statement).
820 Variable* Scope::LookupRecursive(Handle<String> name,
821 bool from_inner_scope,
822 Variable** invalidated_local) {
823 // If we find a variable, but the current scope calls 'eval', the found
824 // variable may not be the correct one (the 'eval' may introduce a
825 // property with the same name). In that case, remember that the variable
826 // found is just a guess.
827 bool guess = scope_calls_eval_;
828 820
829 // Try to find the variable in this scope. 821 if (*var != NULL) {
830 Variable* var = LocalLookup(name); 822 // We found a variable and we are done. (Even if there is an 'eval' in this
823 // scope which introduces the same variable again, the resulting variable
824 // remains the same.)
831 825
832 if (var != NULL) { 826 // If this is a lookup from an inner scope, mark the variable.
833 // We found a variable. If this is not an inner lookup, we are done. 827 if (from_inner_scope) {
834 // (Even if there is an 'eval' in this scope which introduces the 828 (*var)->MarkAsAccessedFromInnerScope();
Kevin Millikin (Chromium) 2011/09/16 05:23:21 This is annoying to check here. Isn't it possible
Steven 2011/09/16 10:48:14 Sure, done. On 2011/09/16 05:23:21, Kevin Millikin
835 // same variable again, the resulting variable remains the same.
836 // Note that enclosing 'with' statements are handled at the call site.)
837 if (!from_inner_scope)
838 return var;
839
840 } else {
841 // We did not find a variable locally. Check against the function variable,
842 // if any. We can do this for all scopes, since the function variable is
843 // only present - if at all - for function scopes.
844 //
845 // This lookup corresponds to a lookup in the "intermediate" scope sitting
846 // between this scope and the outer scope. (ECMA-262, 3rd., requires that
847 // the name of named function literal is kept in an intermediate scope
848 // in between this scope and the next outer scope.)
849 if (function_ != NULL && function_->name().is_identical_to(name)) {
850 var = function_->var();
851
852 } else if (outer_scope_ != NULL) {
853 var = outer_scope_->LookupRecursive(name, true, invalidated_local);
854 // We may have found a variable in an outer scope. However, if
855 // the current scope is inside a 'with', the actual variable may
856 // be a property introduced via the 'with' statement. Then, the
857 // variable we may have found is just a guess.
858 if (scope_inside_with_)
859 guess = true;
860 } 829 }
861 830
862 // If we did not find a variable, we are done. 831 if (is_global_scope()) return GLOBAL;
Kevin Millikin (Chromium) 2011/09/15 09:38:13 return is_global_scope() ? GLOBAL : FOUND; Though
Steven 2011/09/15 19:54:06 We need to distinguish locally bound variables fro
Kevin Millikin (Chromium) 2011/09/16 05:23:21 That's what I'm asking about. The old code will r
Steven 2011/09/16 10:48:14 Yes, I'm sorry you're right. The old code only thr
863 if (var == NULL) 832 return FOUND;
864 return NULL;
865 } 833 }
866 834
867 ASSERT(var != NULL); 835 // We did not find a variable locally. Check against the function variable,
868 836 // if any. We can do this for all scopes, since the function variable is
869 // If this is a lookup from an inner scope, mark the variable. 837 // only present - if at all - for function scopes.
870 if (from_inner_scope) { 838 //
871 var->MarkAsAccessedFromInnerScope(); 839 // This lookup corresponds to a lookup in the "intermediate" scope sitting
840 // between this scope and the outer scope. (ECMA-262, 3rd., requires that
841 // the name of named function literal is kept in an intermediate scope
842 // in between this scope and the next outer scope.)
843 LookupResult result = GLOBAL;
844 if (function_ != NULL && function_->name().is_identical_to(name)) {
845 *var = function_->var();
846 if (from_inner_scope) {
847 (*var)->MarkAsAccessedFromInnerScope();
848 }
849 result = FOUND;
850 } else if (outer_scope_ != NULL) {
851 result = outer_scope_->LookupRecursive(name, true, var);
872 } 852 }
873 853
874 // If the variable we have found is just a guess, invalidate the 854 // We may have found a variable in an outer scope. However, if the current
875 // result. If the found variable is local, record that fact so we 855 // scope is a 'with' scope, the actual variable may be a property introduced
876 // can generate fast code to get it if it is not shadowed by eval. 856 // via the 'with' statement. Then, the variable we may have found is just a
877 if (guess) { 857 // guess.
878 if (!var->is_global()) *invalidated_local = var; 858 // Note that we must do a lookup in the outer scope anyway, because if we find
879 var = NULL; 859 // one, we must mark that variable as potentially accessed from inside of an
880 } 860 // inner with scope (the property may not be in the 'with' object).
861 if (is_with_scope()) return FOUND_WITH;
881 862
882 return var; 863 // If we have found a variable in an outer scope, but the current scope calls
864 // 'eval', the found variable may not be the correct one (the 'eval' may
865 // introduce a property with the same name). In that case, remember that the
866 // variable found is just a guess.
867 if (result == FOUND && scope_calls_eval_) return FOUND_EVAL;
868
869 return result;
883 } 870 }
884 871
885 872
886 void Scope::ResolveVariable(Scope* global_scope, 873 void Scope::ResolveVariable(Scope* global_scope,
887 Handle<Context> context, 874 Handle<Context> context,
888 VariableProxy* proxy) { 875 VariableProxy* proxy) {
889 ASSERT(global_scope == NULL || global_scope->is_global_scope()); 876 ASSERT(global_scope == NULL || global_scope->is_global_scope());
890 877
891 // If the proxy is already resolved there's nothing to do 878 // If the proxy is already resolved there's nothing to do
892 // (functions and consts may be resolved by the parser). 879 // (functions and consts may be resolved by the parser).
893 if (proxy->var() != NULL) return; 880 if (proxy->var() != NULL) return;
894 881
895 // Otherwise, try to resolve the variable. 882 // Otherwise, try to resolve the variable.
896 Variable* invalidated_local = NULL; 883 Variable* var = NULL;
897 Variable* var = LookupRecursive(proxy->name(), false, &invalidated_local); 884 LookupResult result = LookupRecursive(proxy->name(), false, &var);
898 885
899 if (proxy->inside_with()) { 886 switch (result) {
900 // If we are inside a local 'with' statement, all bets are off 887 case FOUND:
901 // and we cannot resolve the proxy to a local variable even if 888 break;
902 // we found an outer matching variable.
903 // Note that we must do a lookup anyway, because if we find one,
904 // we must mark that variable as potentially accessed from this
905 // inner scope (the property may not be in the 'with' object).
906 var = NonLocal(proxy->name(), Variable::DYNAMIC);
907 889
908 } else { 890 case FOUND_WITH:
909 // We are not inside a local 'with' statement. 891 // If we are inside a local 'with' statement, all bets are off
Kevin Millikin (Chromium) 2011/09/15 09:38:13 I lot of these comments are confusing and should b
Steven 2011/09/15 19:54:06 I cleaned them up. PTAL. On 2011/09/15 09:38:13, K
892 // and we cannot resolve the proxy to a local variable even if
893 // we found an outer matching variable.
894 var = NonLocal(proxy->name(), Variable::DYNAMIC);
895 break;
910 896
911 if (var == NULL) { 897 case FOUND_EVAL: {
898 // No with statements are involved and we found a local variable
899 // that might be shadowed by eval introduced variables.
900 Variable* invalidated_local = var;
901 var = NonLocal(proxy->name(), Variable::DYNAMIC_LOCAL);
902 var->set_local_if_not_shadowed(invalidated_local);
903 break;
904 }
905
906 case GLOBAL:
912 // We did not find the variable. We have a global variable 907 // We did not find the variable. We have a global variable
Kevin Millikin (Chromium) 2011/09/15 09:38:13 Or we did find it, and it was in the global scope.
Steven 2011/09/15 19:54:06 Eval in the global scope can't introduce shadowed
Kevin Millikin (Chromium) 2011/09/16 05:23:21 Yes, I know. Perhaps the names are a just bit off
Steven 2011/09/16 10:48:14 For BOUND it does indeed not matter much if the va
913 // if we are in the global scope (we know already that we 908 // if we are in the global scope (we know already that we
914 // are outside a 'with' statement) or if there is no way 909 // are outside a 'with' statement) or if there is no way
915 // that the variable might be introduced dynamically (through 910 // that the variable might be introduced dynamically (through
916 // a local or outer eval() call, or an outer 'with' statement), 911 // a local or outer eval() call, or an outer 'with' statement),
917 // or we don't know about the outer scope (because we are 912 // or we don't know about the outer scope (because we are
918 // in an eval scope). 913 // in an eval scope).
919 if (is_global_scope() || 914 if (is_global_scope() ||
920 !(scope_inside_with_ || outer_scope_is_eval_scope_ || 915 !(scope_inside_with_ || outer_scope_is_eval_scope_ ||
Kevin Millikin (Chromium) 2011/09/15 09:38:13 Is all this junk still necessary? If we got GLOBA
Steven 2011/09/15 19:54:06 Not necessary anymore. On 2011/09/15 09:38:13, Kev
921 scope_calls_eval_ || outer_scope_calls_eval_)) { 916 scope_calls_eval_ || outer_scope_calls_eval_)) {
922 // We must have a global variable. 917 // We must have a global variable.
923 ASSERT(global_scope != NULL); 918 ASSERT(global_scope != NULL);
924 var = global_scope->DeclareGlobal(proxy->name()); 919 var = global_scope->DeclareGlobal(proxy->name());
Kevin Millikin (Chromium) 2011/09/15 09:38:13 Is it right to (re)declare this variable even in t
Steven 2011/09/15 19:54:06 I think it matched the old behaviour, but now I av
925 920
926 } else if (scope_inside_with_) { 921 } else if (scope_inside_with_) {
927 // If we are inside a with statement we give up and look up 922 // If we are inside a with statement we give up and look up
928 // the variable at runtime. 923 // the variable at runtime.
924 ASSERT(false);
Kevin Millikin (Chromium) 2011/09/15 09:38:13 Just get rid of this case completely and assert !s
Steven 2011/09/15 19:54:06 Sorry, this is dead code I forgot to delete. On 20
929 var = NonLocal(proxy->name(), Variable::DYNAMIC); 925 var = NonLocal(proxy->name(), Variable::DYNAMIC);
930 926
931 } else if (invalidated_local != NULL) {
932 // No with statements are involved and we found a local
933 // variable that might be shadowed by eval introduced
934 // variables.
935 var = NonLocal(proxy->name(), Variable::DYNAMIC_LOCAL);
936 var->set_local_if_not_shadowed(invalidated_local);
937
938 } else if (outer_scope_is_eval_scope_) { 927 } else if (outer_scope_is_eval_scope_) {
Kevin Millikin (Chromium) 2011/09/15 09:38:13 It would be great if we could get rid of this flag
Steven 2011/09/15 19:54:06 Got rid of the flag, but still need the propagate
939 // No with statements and we did not find a local and the code 928 // No with statements and we did not find a local and the code
940 // is executed with a call to eval. The context contains 929 // is executed with a call to eval. The context contains
941 // scope information that we can use to determine if the 930 // scope information that we can use to determine if the
942 // variable is global if it is not shadowed by eval-introduced 931 // variable is global if it is not shadowed by eval-introduced
943 // variables. 932 // variables.
944 if (context->GlobalIfNotShadowedByEval(proxy->name())) { 933 if (context->GlobalIfNotShadowedByEval(proxy->name())) {
945 var = NonLocal(proxy->name(), Variable::DYNAMIC_GLOBAL); 934 var = NonLocal(proxy->name(), Variable::DYNAMIC_GLOBAL);
946
947 } else { 935 } else {
948 var = NonLocal(proxy->name(), Variable::DYNAMIC); 936 var = NonLocal(proxy->name(), Variable::DYNAMIC);
949 } 937 }
950 938
951 } else { 939 } else {
952 // No with statements and we did not find a local and the code 940 // No with statements and we did not find a local and the code
953 // is not executed with a call to eval. We know that this 941 // is not executed with a call to eval. We know that this
954 // variable is global unless it is shadowed by eval-introduced 942 // variable is global unless it is shadowed by eval-introduced
955 // variables. 943 // variables.
956 var = NonLocal(proxy->name(), Variable::DYNAMIC_GLOBAL); 944 var = NonLocal(proxy->name(), Variable::DYNAMIC_GLOBAL);
957 } 945 }
958 } 946 break;
959 } 947 }
960 948
949 ASSERT(var != NULL);
961 proxy->BindTo(var); 950 proxy->BindTo(var);
962 } 951 }
963 952
964 953
965 void Scope::ResolveVariablesRecursively(Scope* global_scope, 954 void Scope::ResolveVariablesRecursively(Scope* global_scope,
966 Handle<Context> context) { 955 Handle<Context> context) {
967 ASSERT(global_scope == NULL || global_scope->is_global_scope()); 956 ASSERT(global_scope == NULL || global_scope->is_global_scope());
968 957
969 // Resolve unresolved variables for this scope. 958 // Resolve unresolved variables for this scope.
970 for (int i = 0; i < unresolved_.length(); i++) { 959 for (int i = 0; i < unresolved_.length(); i++) {
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
1199 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && 1188 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS &&
1200 !must_have_local_context) { 1189 !must_have_local_context) {
1201 num_heap_slots_ = 0; 1190 num_heap_slots_ = 0;
1202 } 1191 }
1203 1192
1204 // Allocation done. 1193 // Allocation done.
1205 ASSERT(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); 1194 ASSERT(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS);
1206 } 1195 }
1207 1196
1208 } } // namespace v8::internal 1197 } } // namespace v8::internal
OLDNEW
« src/scopes.h ('K') | « src/scopes.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698