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

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_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
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 // 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
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
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
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
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
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
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