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

Side by Side Diff: src/scopes.cc

Issue 8508052: Static resolution of outer variables in eval code. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comments. Created 9 years, 1 month 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 | « src/scopes.h ('k') | test/cctest/test-parsing.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 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
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((type == GLOBAL_SCOPE) == (outer_scope == NULL));
fschneider 2011/11/14 15:20:52 Use ASSERT_EQ instead, so that you get a better er
Steven 2011/11/15 11:53:23 Done.
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
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
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 // Traverse the scope tree up to the first unresolved scope.
261 top->AllocateVariables(info->calling_context()); 268 while (!top->is_global_scope() &&
269 !top->outer_scope()->already_resolved()) {
fschneider 2011/11/14 15:20:52 This loop condition seems inconsistent with the co
Steven 2011/11/15 11:53:23 I've updated the comment with a more thorough desc
fschneider 2011/11/15 12:06:46 Maybe say: Traverse until the first unresolved sco
Steven 2011/11/15 13:51:15 Done.
270 top = top->outer_scope();
271 }
272
273 // Allocated the variables.
274 top->AllocateVariables(info->global_scope());
262 275
263 #ifdef DEBUG 276 #ifdef DEBUG
264 if (info->isolate()->bootstrapper()->IsActive() 277 if (info->isolate()->bootstrapper()->IsActive()
265 ? FLAG_print_builtin_scopes 278 ? FLAG_print_builtin_scopes
266 : FLAG_print_scopes) { 279 : FLAG_print_scopes) {
267 info->function()->scope()->Print(); 280 scope->Print();
268 } 281 }
269 #endif 282 #endif
270 283
271 info->SetScope(info->function()->scope()); 284 info->SetScope(scope);
272 return true; // Can not fail. 285 return true; // Can not fail.
273 } 286 }
274 287
275 288
276 void Scope::Initialize() { 289 void Scope::Initialize() {
277 ASSERT(!already_resolved()); 290 ASSERT(!already_resolved());
278 291
279 // Add this scope as a new inner scope of the outer scope. 292 // Add this scope as a new inner scope of the outer scope.
280 if (outer_scope_ != NULL) { 293 if (outer_scope_ != NULL) {
281 outer_scope_->inner_scopes_.Add(this); 294 outer_scope_->inner_scopes_.Add(this);
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 return NULL; 362 return NULL;
350 } 363 }
351 364
352 365
353 Variable* Scope::LocalLookup(Handle<String> name) { 366 Variable* Scope::LocalLookup(Handle<String> name) {
354 Variable* result = variables_.Lookup(name); 367 Variable* result = variables_.Lookup(name);
355 if (result != NULL || scope_info_.is_null()) { 368 if (result != NULL || scope_info_.is_null()) {
356 return result; 369 return result;
357 } 370 }
358 // If we have a serialized scope info, we might find the variable there. 371 // 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. 372 // There should be no local slot with the given name.
364 ASSERT(scope_info_->StackSlotIndex(*name) < 0); 373 ASSERT(scope_info_->StackSlotIndex(*name) < 0);
365 374
366 // Check context slot lookup. 375 // Check context slot lookup.
367 VariableMode mode; 376 VariableMode mode;
368 InitializationFlag init_flag; 377 InitializationFlag init_flag;
369 int index = scope_info_->ContextSlotIndex(*name, &mode, &init_flag); 378 int index = scope_info_->ContextSlotIndex(*name, &mode, &init_flag);
370 if (index < 0) { 379 if (index < 0) {
371 // Check parameters. 380 // Check parameters.
372 mode = VAR; 381 mode = VAR;
373 init_flag = kCreatedInitialized; 382 init_flag = kCreatedInitialized;
374 index = scope_info_->ParameterIndex(*name); 383 index = scope_info_->ParameterIndex(*name);
375 if (index < 0) { 384 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 } 385 }
381 386
382 Variable* var = 387 Variable* var =
383 variables_.Declare(this, 388 variables_.Declare(this,
384 name, 389 name,
385 mode, 390 mode,
386 true, 391 true,
387 Variable::NORMAL, 392 Variable::NORMAL,
388 init_flag); 393 init_flag);
389 var->AllocateTo(Variable::CONTEXT, index); 394 var->AllocateTo(Variable::CONTEXT, index);
390 return var; 395 return var;
391 } 396 }
392 397
393 398
399 Variable* Scope::LookupFunctionVar(Handle<String> name) {
400 if (function_ != NULL && function_->name().is_identical_to(name)) {
401 return function_->var();
402 } else if (!scope_info_.is_null()) {
403 // If we are backed by a scope info, try to lookup the variable there.
404 VariableMode mode;
405 int index = scope_info_->FunctionContextSlotIndex(*name, &mode);
406 if (index < 0) return NULL;
407 Variable* var = DeclareFunctionVar(name, mode);
408 var->AllocateTo(Variable::CONTEXT, index);
409 return var;
410 } else {
411 return NULL;
412 }
413 }
414
415
394 Variable* Scope::Lookup(Handle<String> name) { 416 Variable* Scope::Lookup(Handle<String> name) {
395 for (Scope* scope = this; 417 for (Scope* scope = this;
396 scope != NULL; 418 scope != NULL;
397 scope = scope->outer_scope()) { 419 scope = scope->outer_scope()) {
398 Variable* var = scope->LocalLookup(name); 420 Variable* var = scope->LocalLookup(name);
399 if (var != NULL) return var; 421 if (var != NULL) return var;
400 } 422 }
401 return NULL; 423 return NULL;
402 } 424 }
403 425
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
552 if (var->IsStackLocal()) { 574 if (var->IsStackLocal()) {
553 stack_locals->Add(var); 575 stack_locals->Add(var);
554 } else if (var->IsContextSlot()) { 576 } else if (var->IsContextSlot()) {
555 context_locals->Add(var); 577 context_locals->Add(var);
556 } 578 }
557 } 579 }
558 } 580 }
559 } 581 }
560 582
561 583
562 void Scope::AllocateVariables(Handle<Context> context) { 584 void Scope::AllocateVariables(Scope* global_scope) {
563 ASSERT(outer_scope_ == NULL); // eval or global scopes only
564
565 // 1) Propagate scope information. 585 // 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; 586 bool outer_scope_calls_non_strict_eval = false;
573 if (!is_global_scope()) { 587 if (outer_scope_ != NULL) {
574 context->ComputeEvalScopeInfo(&outer_scope_calls_non_strict_eval); 588 outer_scope_calls_non_strict_eval =
589 outer_scope_->outer_scope_calls_non_strict_eval() |
590 outer_scope_->calls_non_strict_eval();
575 } 591 }
576 PropagateScopeInfo(outer_scope_calls_non_strict_eval); 592 PropagateScopeInfo(outer_scope_calls_non_strict_eval);
577 593
578 // 2) Resolve variables. 594 // 2) Resolve variables.
579 Scope* global_scope = NULL; 595 ResolveVariablesRecursively(global_scope);
580 if (is_global_scope()) global_scope = this;
581 ResolveVariablesRecursively(global_scope, context);
582 596
583 // 3) Allocate variables. 597 // 3) Allocate variables.
584 AllocateVariablesRecursively(); 598 AllocateVariablesRecursively();
585 } 599 }
586 600
587 601
588 bool Scope::AllowsLazyCompilation() const { 602 bool Scope::AllowsLazyCompilation() const {
589 return !force_eager_compilation_ && HasTrivialOuterContext(); 603 return !force_eager_compilation_ && HasTrivialOuterContext();
590 } 604 }
591 605
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
825 Variable::NORMAL, 839 Variable::NORMAL,
826 init_flag); 840 init_flag);
827 // Allocate it by giving it a dynamic lookup. 841 // Allocate it by giving it a dynamic lookup.
828 var->AllocateTo(Variable::LOOKUP, -1); 842 var->AllocateTo(Variable::LOOKUP, -1);
829 } 843 }
830 return var; 844 return var;
831 } 845 }
832 846
833 847
834 Variable* Scope::LookupRecursive(Handle<String> name, 848 Variable* Scope::LookupRecursive(Handle<String> name,
835 Handle<Context> context,
836 BindingKind* binding_kind) { 849 BindingKind* binding_kind) {
837 ASSERT(binding_kind != NULL); 850 ASSERT(binding_kind != NULL);
838 // Try to find the variable in this scope. 851 // Try to find the variable in this scope.
839 Variable* var = LocalLookup(name); 852 Variable* var = LocalLookup(name);
840 853
841 // We found a variable and we are done. (Even if there is an 'eval' in 854 // 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 855 // this scope which introduces the same variable again, the resulting
843 // variable remains the same.) 856 // variable remains the same.)
844 if (var != NULL) { 857 if (var != NULL) {
845 *binding_kind = BOUND; 858 *binding_kind = BOUND;
846 return var; 859 return var;
847 } 860 }
848 861
849 // We did not find a variable locally. Check against the function variable, 862 // 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 863 // if any. We can do this for all scopes, since the function variable is
851 // only present - if at all - for function scopes. 864 // 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; 865 *binding_kind = UNBOUND;
858 if (function_ != NULL && function_->name().is_identical_to(name)) { 866 var = LookupFunctionVar(name);
859 var = function_->var(); 867 if (var != NULL) {
860 *binding_kind = BOUND; 868 *binding_kind = BOUND;
861 } else if (outer_scope_ != NULL) { 869 } else if (outer_scope_ != NULL) {
862 var = outer_scope_->LookupRecursive(name, context, binding_kind); 870 var = outer_scope_->LookupRecursive(name, binding_kind);
863 if (*binding_kind == BOUND && (is_function_scope() || is_with_scope())) { 871 if (*binding_kind == BOUND && (is_function_scope() || is_with_scope())) {
864 var->ForceContextAllocation(); 872 var->ForceContextAllocation();
865 } 873 }
874 } else {
875 ASSERT(is_global_scope());
866 } 876 }
867 877
868 if (is_with_scope()) { 878 if (is_with_scope()) {
869 // The current scope is a with scope, so the variable binding can not be 879 // 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 880 // 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, 881 // 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 882 // 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' 883 // from inside of an inner with scope (the property may not be in the 'with'
874 // object). 884 // object).
875 *binding_kind = DYNAMIC_LOOKUP; 885 *binding_kind = DYNAMIC_LOOKUP;
876 return NULL; 886 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()) { 887 } else if (calls_non_strict_eval()) {
888 // A variable binding may have been found in an outer scope, but the current 888 // 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 889 // 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). 890 // 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. 891 // In that case, change the lookup result to reflect this situation.
892 if (*binding_kind == BOUND) { 892 if (*binding_kind == BOUND) {
893 *binding_kind = BOUND_EVAL_SHADOWED; 893 *binding_kind = BOUND_EVAL_SHADOWED;
894 } else if (*binding_kind == UNBOUND) { 894 } else if (*binding_kind == UNBOUND) {
895 *binding_kind = UNBOUND_EVAL_SHADOWED; 895 *binding_kind = UNBOUND_EVAL_SHADOWED;
896 } 896 }
897 } 897 }
898 return var; 898 return var;
899 } 899 }
900 900
901 901
902 void Scope::ResolveVariable(Scope* global_scope, 902 void Scope::ResolveVariable(Scope* global_scope,
903 Handle<Context> context,
904 VariableProxy* proxy) { 903 VariableProxy* proxy) {
905 ASSERT(global_scope == NULL || global_scope->is_global_scope()); 904 ASSERT(global_scope == NULL || global_scope->is_global_scope());
906 905
907 // If the proxy is already resolved there's nothing to do 906 // If the proxy is already resolved there's nothing to do
908 // (functions and consts may be resolved by the parser). 907 // (functions and consts may be resolved by the parser).
909 if (proxy->var() != NULL) return; 908 if (proxy->var() != NULL) return;
910 909
911 // Otherwise, try to resolve the variable. 910 // Otherwise, try to resolve the variable.
912 BindingKind binding_kind; 911 BindingKind binding_kind;
913 Variable* var = LookupRecursive(proxy->name(), context, &binding_kind); 912 Variable* var = LookupRecursive(proxy->name(), &binding_kind);
914 switch (binding_kind) { 913 switch (binding_kind) {
915 case BOUND: 914 case BOUND:
916 // We found a variable binding. 915 // We found a variable binding.
917 break; 916 break;
918 917
919 case BOUND_EVAL_SHADOWED: 918 case BOUND_EVAL_SHADOWED:
920 // We found a variable variable binding that might be shadowed 919 // We found a variable variable binding that might be shadowed
921 // by 'eval' introduced variable bindings. 920 // by 'eval' introduced variable bindings.
922 if (var->is_global()) { 921 if (var->is_global()) {
923 var = NonLocal(proxy->name(), DYNAMIC_GLOBAL); 922 var = NonLocal(proxy->name(), DYNAMIC_GLOBAL);
(...skipping 20 matching lines...) Expand all
944 // The variable could not be resolved statically. 943 // The variable could not be resolved statically.
945 var = NonLocal(proxy->name(), DYNAMIC); 944 var = NonLocal(proxy->name(), DYNAMIC);
946 break; 945 break;
947 } 946 }
948 947
949 ASSERT(var != NULL); 948 ASSERT(var != NULL);
950 proxy->BindTo(var); 949 proxy->BindTo(var);
951 } 950 }
952 951
953 952
954 void Scope::ResolveVariablesRecursively(Scope* global_scope, 953 void Scope::ResolveVariablesRecursively(Scope* global_scope) {
955 Handle<Context> context) {
956 ASSERT(global_scope == NULL || global_scope->is_global_scope()); 954 ASSERT(global_scope == NULL || global_scope->is_global_scope());
957 955
958 // Resolve unresolved variables for this scope. 956 // Resolve unresolved variables for this scope.
959 for (int i = 0; i < unresolved_.length(); i++) { 957 for (int i = 0; i < unresolved_.length(); i++) {
960 ResolveVariable(global_scope, context, unresolved_[i]); 958 ResolveVariable(global_scope, unresolved_[i]);
961 } 959 }
962 960
963 // Resolve unresolved variables for inner scopes. 961 // Resolve unresolved variables for inner scopes.
964 for (int i = 0; i < inner_scopes_.length(); i++) { 962 for (int i = 0; i < inner_scopes_.length(); i++) {
965 inner_scopes_[i]->ResolveVariablesRecursively(global_scope, context); 963 inner_scopes_[i]->ResolveVariablesRecursively(global_scope);
966 } 964 }
967 } 965 }
968 966
969 967
970 bool Scope::PropagateScopeInfo(bool outer_scope_calls_non_strict_eval ) { 968 bool Scope::PropagateScopeInfo(bool outer_scope_calls_non_strict_eval ) {
971 if (outer_scope_calls_non_strict_eval) { 969 if (outer_scope_calls_non_strict_eval) {
972 outer_scope_calls_non_strict_eval_ = true; 970 outer_scope_calls_non_strict_eval_ = true;
973 } 971 }
974 972
975 bool calls_non_strict_eval = 973 bool calls_non_strict_eval =
976 (scope_calls_eval_ && !is_strict_mode()) || 974 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++) { 975 for (int i = 0; i < inner_scopes_.length(); i++) {
979 Scope* inner_scope = inner_scopes_[i]; 976 Scope* inner_scope = inner_scopes_[i];
980 if (inner_scope->PropagateScopeInfo(calls_non_strict_eval)) { 977 if (inner_scope->PropagateScopeInfo(calls_non_strict_eval)) {
981 inner_scope_calls_eval_ = true; 978 inner_scope_calls_eval_ = true;
982 } 979 }
983 if (inner_scope->force_eager_compilation_) { 980 if (inner_scope->force_eager_compilation_) {
984 force_eager_compilation_ = true; 981 force_eager_compilation_ = true;
985 } 982 }
986 } 983 }
987 984
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
1180 } 1177 }
1181 1178
1182 1179
1183 int Scope::ContextLocalCount() const { 1180 int Scope::ContextLocalCount() const {
1184 if (num_heap_slots() == 0) return 0; 1181 if (num_heap_slots() == 0) return 0;
1185 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - 1182 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS -
1186 (function_ != NULL && function_->var()->IsContextSlot() ? 1 : 0); 1183 (function_ != NULL && function_->var()->IsContextSlot() ? 1 : 0);
1187 } 1184 }
1188 1185
1189 } } // namespace v8::internal 1186 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/scopes.h ('k') | test/cctest/test-parsing.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698