OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/scopes.h" | 7 #include "src/scopes.h" |
8 | 8 |
9 #include "src/accessors.h" | 9 #include "src/accessors.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
71 AstValueFactory* ast_value_factory, Zone* zone) | 71 AstValueFactory* ast_value_factory, Zone* zone) |
72 : isolate_(zone->isolate()), | 72 : isolate_(zone->isolate()), |
73 inner_scopes_(4, zone), | 73 inner_scopes_(4, zone), |
74 variables_(zone), | 74 variables_(zone), |
75 internals_(4, zone), | 75 internals_(4, zone), |
76 temps_(4, zone), | 76 temps_(4, zone), |
77 params_(4, zone), | 77 params_(4, zone), |
78 unresolved_(16, zone), | 78 unresolved_(16, zone), |
79 decls_(4, zone), | 79 decls_(4, zone), |
80 interface_(FLAG_harmony_modules && | 80 interface_(FLAG_harmony_modules && |
81 (scope_type == MODULE_SCOPE || scope_type == GLOBAL_SCOPE) | 81 (scope_type == MODULE_SCOPE || scope_type == SCRIPT_SCOPE) |
82 ? Interface::NewModule(zone) : NULL), | 82 ? Interface::NewModule(zone) : NULL), |
83 already_resolved_(false), | 83 already_resolved_(false), |
84 ast_value_factory_(ast_value_factory), | 84 ast_value_factory_(ast_value_factory), |
85 zone_(zone) { | 85 zone_(zone) { |
86 SetDefaults(scope_type, outer_scope, Handle<ScopeInfo>::null()); | 86 SetDefaults(scope_type, outer_scope, Handle<ScopeInfo>::null()); |
87 // The outermost scope must be a global scope. | 87 // The outermost scope must be a script scope. |
88 DCHECK(scope_type == GLOBAL_SCOPE || outer_scope != NULL); | 88 DCHECK(scope_type == SCRIPT_SCOPE || outer_scope != NULL); |
89 DCHECK(!HasIllegalRedeclaration()); | 89 DCHECK(!HasIllegalRedeclaration()); |
90 } | 90 } |
91 | 91 |
92 | 92 |
93 Scope::Scope(Scope* inner_scope, | 93 Scope::Scope(Scope* inner_scope, |
94 ScopeType scope_type, | 94 ScopeType scope_type, |
95 Handle<ScopeInfo> scope_info, | 95 Handle<ScopeInfo> scope_info, |
96 AstValueFactory* value_factory, | 96 AstValueFactory* value_factory, |
97 Zone* zone) | 97 Zone* zone) |
98 : isolate_(zone->isolate()), | 98 : isolate_(zone->isolate()), |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
181 scope_info_ = scope_info; | 181 scope_info_ = scope_info; |
182 start_position_ = RelocInfo::kNoPosition; | 182 start_position_ = RelocInfo::kNoPosition; |
183 end_position_ = RelocInfo::kNoPosition; | 183 end_position_ = RelocInfo::kNoPosition; |
184 if (!scope_info.is_null()) { | 184 if (!scope_info.is_null()) { |
185 scope_calls_eval_ = scope_info->CallsEval(); | 185 scope_calls_eval_ = scope_info->CallsEval(); |
186 strict_mode_ = scope_info->strict_mode(); | 186 strict_mode_ = scope_info->strict_mode(); |
187 } | 187 } |
188 } | 188 } |
189 | 189 |
190 | 190 |
191 Scope* Scope::DeserializeScopeChain(Context* context, Scope* global_scope, | 191 Scope* Scope::DeserializeScopeChain(Context* context, Scope* script_scope, |
192 Zone* zone) { | 192 Zone* zone) { |
193 // Reconstruct the outer scope chain from a closure's context chain. | 193 // Reconstruct the outer scope chain from a closure's context chain. |
194 Scope* current_scope = NULL; | 194 Scope* current_scope = NULL; |
195 Scope* innermost_scope = NULL; | 195 Scope* innermost_scope = NULL; |
196 bool contains_with = false; | 196 bool contains_with = false; |
197 while (!context->IsNativeContext()) { | 197 while (!context->IsNativeContext()) { |
198 if (context->IsWithContext()) { | 198 if (context->IsWithContext()) { |
199 Scope* with_scope = new(zone) Scope(current_scope, | 199 Scope* with_scope = new(zone) Scope(current_scope, |
200 WITH_SCOPE, | 200 WITH_SCOPE, |
201 Handle<ScopeInfo>::null(), | 201 Handle<ScopeInfo>::null(), |
202 global_scope->ast_value_factory_, | 202 script_scope->ast_value_factory_, |
203 zone); | 203 zone); |
204 current_scope = with_scope; | 204 current_scope = with_scope; |
205 // All the inner scopes are inside a with. | 205 // All the inner scopes are inside a with. |
206 contains_with = true; | 206 contains_with = true; |
207 for (Scope* s = innermost_scope; s != NULL; s = s->outer_scope()) { | 207 for (Scope* s = innermost_scope; s != NULL; s = s->outer_scope()) { |
208 s->scope_inside_with_ = true; | 208 s->scope_inside_with_ = true; |
209 } | 209 } |
210 } else if (context->IsGlobalContext()) { | 210 } else if (context->IsScriptContext()) { |
211 ScopeInfo* scope_info = ScopeInfo::cast(context->extension()); | 211 ScopeInfo* scope_info = ScopeInfo::cast(context->extension()); |
212 current_scope = new(zone) Scope(current_scope, | 212 current_scope = new(zone) Scope(current_scope, |
213 GLOBAL_SCOPE, | 213 SCRIPT_SCOPE, |
214 Handle<ScopeInfo>(scope_info), | 214 Handle<ScopeInfo>(scope_info), |
215 global_scope->ast_value_factory_, | 215 script_scope->ast_value_factory_, |
216 zone); | 216 zone); |
217 } else if (context->IsModuleContext()) { | 217 } else if (context->IsModuleContext()) { |
218 ScopeInfo* scope_info = ScopeInfo::cast(context->module()->scope_info()); | 218 ScopeInfo* scope_info = ScopeInfo::cast(context->module()->scope_info()); |
219 current_scope = new(zone) Scope(current_scope, | 219 current_scope = new(zone) Scope(current_scope, |
220 MODULE_SCOPE, | 220 MODULE_SCOPE, |
221 Handle<ScopeInfo>(scope_info), | 221 Handle<ScopeInfo>(scope_info), |
222 global_scope->ast_value_factory_, | 222 script_scope->ast_value_factory_, |
223 zone); | 223 zone); |
224 } else if (context->IsFunctionContext()) { | 224 } else if (context->IsFunctionContext()) { |
225 ScopeInfo* scope_info = context->closure()->shared()->scope_info(); | 225 ScopeInfo* scope_info = context->closure()->shared()->scope_info(); |
226 current_scope = new(zone) Scope(current_scope, | 226 current_scope = new(zone) Scope(current_scope, |
227 FUNCTION_SCOPE, | 227 FUNCTION_SCOPE, |
228 Handle<ScopeInfo>(scope_info), | 228 Handle<ScopeInfo>(scope_info), |
229 global_scope->ast_value_factory_, | 229 script_scope->ast_value_factory_, |
230 zone); | 230 zone); |
231 if (scope_info->IsAsmFunction()) current_scope->asm_function_ = true; | 231 if (scope_info->IsAsmFunction()) current_scope->asm_function_ = true; |
232 if (scope_info->IsAsmModule()) current_scope->asm_module_ = true; | 232 if (scope_info->IsAsmModule()) current_scope->asm_module_ = true; |
233 } else if (context->IsBlockContext()) { | 233 } else if (context->IsBlockContext()) { |
234 ScopeInfo* scope_info = ScopeInfo::cast(context->extension()); | 234 ScopeInfo* scope_info = ScopeInfo::cast(context->extension()); |
235 current_scope = new(zone) Scope(current_scope, | 235 current_scope = new(zone) Scope(current_scope, |
236 BLOCK_SCOPE, | 236 BLOCK_SCOPE, |
237 Handle<ScopeInfo>(scope_info), | 237 Handle<ScopeInfo>(scope_info), |
238 global_scope->ast_value_factory_, | 238 script_scope->ast_value_factory_, |
239 zone); | 239 zone); |
240 } else { | 240 } else { |
241 DCHECK(context->IsCatchContext()); | 241 DCHECK(context->IsCatchContext()); |
242 String* name = String::cast(context->extension()); | 242 String* name = String::cast(context->extension()); |
243 current_scope = new (zone) Scope( | 243 current_scope = new (zone) Scope( |
244 current_scope, | 244 current_scope, |
245 global_scope->ast_value_factory_->GetString(Handle<String>(name)), | 245 script_scope->ast_value_factory_->GetString(Handle<String>(name)), |
246 global_scope->ast_value_factory_, zone); | 246 script_scope->ast_value_factory_, zone); |
247 } | 247 } |
248 if (contains_with) current_scope->RecordWithStatement(); | 248 if (contains_with) current_scope->RecordWithStatement(); |
249 if (innermost_scope == NULL) innermost_scope = current_scope; | 249 if (innermost_scope == NULL) innermost_scope = current_scope; |
250 | 250 |
251 // Forget about a with when we move to a context for a different function. | 251 // Forget about a with when we move to a context for a different function. |
252 if (context->previous()->closure() != context->closure()) { | 252 if (context->previous()->closure() != context->closure()) { |
253 contains_with = false; | 253 contains_with = false; |
254 } | 254 } |
255 context = context->previous(); | 255 context = context->previous(); |
256 } | 256 } |
257 | 257 |
258 global_scope->AddInnerScope(current_scope); | 258 script_scope->AddInnerScope(current_scope); |
259 global_scope->PropagateScopeInfo(false); | 259 script_scope->PropagateScopeInfo(false); |
260 return (innermost_scope == NULL) ? global_scope : innermost_scope; | 260 return (innermost_scope == NULL) ? script_scope : innermost_scope; |
261 } | 261 } |
262 | 262 |
263 | 263 |
264 bool Scope::Analyze(CompilationInfo* info) { | 264 bool Scope::Analyze(CompilationInfo* info) { |
265 DCHECK(info->function() != NULL); | 265 DCHECK(info->function() != NULL); |
266 Scope* scope = info->function()->scope(); | 266 Scope* scope = info->function()->scope(); |
267 Scope* top = scope; | 267 Scope* top = scope; |
268 | 268 |
269 // Traverse the scope tree up to the first unresolved scope or the global | 269 // Traverse the scope tree up to the first unresolved scope or the global |
270 // scope and start scope resolution and variable allocation from that scope. | 270 // scope and start scope resolution and variable allocation from that scope. |
271 while (!top->is_global_scope() && | 271 while (!top->is_script_scope() && |
272 !top->outer_scope()->already_resolved()) { | 272 !top->outer_scope()->already_resolved()) { |
273 top = top->outer_scope(); | 273 top = top->outer_scope(); |
274 } | 274 } |
275 | 275 |
276 // Allocate the variables. | 276 // Allocate the variables. |
277 { | 277 { |
278 AstNodeFactory<AstNullVisitor> ast_node_factory(info->ast_value_factory()); | 278 AstNodeFactory<AstNullVisitor> ast_node_factory(info->ast_value_factory()); |
279 if (!top->AllocateVariables(info, &ast_node_factory)) return false; | 279 if (!top->AllocateVariables(info, &ast_node_factory)) return false; |
280 } | 280 } |
281 | 281 |
282 #ifdef DEBUG | 282 #ifdef DEBUG |
283 if (info->isolate()->bootstrapper()->IsActive() | 283 if (info->isolate()->bootstrapper()->IsActive() |
284 ? FLAG_print_builtin_scopes | 284 ? FLAG_print_builtin_scopes |
285 : FLAG_print_scopes) { | 285 : FLAG_print_scopes) { |
286 scope->Print(); | 286 scope->Print(); |
287 } | 287 } |
288 | 288 |
289 if (FLAG_harmony_modules && FLAG_print_interfaces && top->is_global_scope()) { | 289 if (FLAG_harmony_modules && FLAG_print_interfaces && top->is_script_scope()) { |
290 PrintF("global : "); | 290 PrintF("global : "); |
291 top->interface()->Print(); | 291 top->interface()->Print(); |
292 } | 292 } |
293 #endif | 293 #endif |
294 | 294 |
295 info->PrepareForCompilation(scope); | 295 info->PrepareForCompilation(scope); |
296 return true; | 296 return true; |
297 } | 297 } |
298 | 298 |
299 | 299 |
300 void Scope::Initialize() { | 300 void Scope::Initialize() { |
301 DCHECK(!already_resolved()); | 301 DCHECK(!already_resolved()); |
302 | 302 |
303 // Add this scope as a new inner scope of the outer scope. | 303 // Add this scope as a new inner scope of the outer scope. |
304 if (outer_scope_ != NULL) { | 304 if (outer_scope_ != NULL) { |
305 outer_scope_->inner_scopes_.Add(this, zone()); | 305 outer_scope_->inner_scopes_.Add(this, zone()); |
306 scope_inside_with_ = outer_scope_->scope_inside_with_ || is_with_scope(); | 306 scope_inside_with_ = outer_scope_->scope_inside_with_ || is_with_scope(); |
307 } else { | 307 } else { |
308 scope_inside_with_ = is_with_scope(); | 308 scope_inside_with_ = is_with_scope(); |
309 } | 309 } |
310 | 310 |
311 // Declare convenience variables. | 311 // Declare convenience variables. |
312 // Declare and allocate receiver (even for the global scope, and even | 312 // Declare and allocate receiver (even for the script scope, and even |
313 // if naccesses_ == 0). | 313 // if naccesses_ == 0). |
314 // NOTE: When loading parameters in the global scope, we must take | 314 // NOTE: When loading parameters in the script scope, we must take |
315 // care not to access them as properties of the global object, but | 315 // care not to access them as properties of the global object, but |
316 // instead load them directly from the stack. Currently, the only | 316 // instead load them directly from the stack. Currently, the only |
317 // such parameter is 'this' which is passed on the stack when | 317 // such parameter is 'this' which is passed on the stack when |
318 // invoking scripts | 318 // invoking scripts |
319 if (is_declaration_scope()) { | 319 if (is_declaration_scope()) { |
320 Variable* var = | 320 Variable* var = |
321 variables_.Declare(this, | 321 variables_.Declare(this, |
322 ast_value_factory_->this_string(), | 322 ast_value_factory_->this_string(), |
323 VAR, | 323 VAR, |
324 false, | 324 false, |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
470 // introduces during variable allocation, INTERNAL variables are allocated | 470 // introduces during variable allocation, INTERNAL variables are allocated |
471 // explicitly, and TEMPORARY variables are allocated via NewTemporary(). | 471 // explicitly, and TEMPORARY variables are allocated via NewTemporary(). |
472 DCHECK(IsDeclaredVariableMode(mode)); | 472 DCHECK(IsDeclaredVariableMode(mode)); |
473 ++num_var_or_const_; | 473 ++num_var_or_const_; |
474 return variables_.Declare(this, name, mode, true, Variable::NORMAL, init_flag, | 474 return variables_.Declare(this, name, mode, true, Variable::NORMAL, init_flag, |
475 maybe_assigned_flag, interface); | 475 maybe_assigned_flag, interface); |
476 } | 476 } |
477 | 477 |
478 | 478 |
479 Variable* Scope::DeclareDynamicGlobal(const AstRawString* name) { | 479 Variable* Scope::DeclareDynamicGlobal(const AstRawString* name) { |
480 DCHECK(is_global_scope()); | 480 DCHECK(is_script_scope()); |
481 return variables_.Declare(this, | 481 return variables_.Declare(this, |
482 name, | 482 name, |
483 DYNAMIC_GLOBAL, | 483 DYNAMIC_GLOBAL, |
484 true, | 484 true, |
485 Variable::NORMAL, | 485 Variable::NORMAL, |
486 kCreatedInitialized); | 486 kCreatedInitialized); |
487 } | 487 } |
488 | 488 |
489 | 489 |
490 void Scope::RemoveUnresolved(VariableProxy* var) { | 490 void Scope::RemoveUnresolved(VariableProxy* var) { |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
641 // 1) Propagate scope information. | 641 // 1) Propagate scope information. |
642 bool outer_scope_calls_sloppy_eval = false; | 642 bool outer_scope_calls_sloppy_eval = false; |
643 if (outer_scope_ != NULL) { | 643 if (outer_scope_ != NULL) { |
644 outer_scope_calls_sloppy_eval = | 644 outer_scope_calls_sloppy_eval = |
645 outer_scope_->outer_scope_calls_sloppy_eval() | | 645 outer_scope_->outer_scope_calls_sloppy_eval() | |
646 outer_scope_->calls_sloppy_eval(); | 646 outer_scope_->calls_sloppy_eval(); |
647 } | 647 } |
648 PropagateScopeInfo(outer_scope_calls_sloppy_eval); | 648 PropagateScopeInfo(outer_scope_calls_sloppy_eval); |
649 | 649 |
650 // 2) Allocate module instances. | 650 // 2) Allocate module instances. |
651 if (FLAG_harmony_modules && (is_global_scope() || is_module_scope())) { | 651 if (FLAG_harmony_modules && (is_script_scope() || is_module_scope())) { |
652 DCHECK(num_modules_ == 0); | 652 DCHECK(num_modules_ == 0); |
653 AllocateModulesRecursively(this); | 653 AllocateModulesRecursively(this); |
654 } | 654 } |
655 | 655 |
656 // 3) Resolve variables. | 656 // 3) Resolve variables. |
657 if (!ResolveVariablesRecursively(info, factory)) return false; | 657 if (!ResolveVariablesRecursively(info, factory)) return false; |
658 | 658 |
659 // 4) Allocate variables. | 659 // 4) Allocate variables. |
660 AllocateVariablesRecursively(); | 660 AllocateVariablesRecursively(); |
661 | 661 |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
721 DCHECK(s != NULL); // scope must be in the scope chain | 721 DCHECK(s != NULL); // scope must be in the scope chain |
722 if (s->is_with_scope() || s->num_heap_slots() > 0) n++; | 722 if (s->is_with_scope() || s->num_heap_slots() > 0) n++; |
723 // Catch and module scopes always have heap slots. | 723 // Catch and module scopes always have heap slots. |
724 DCHECK(!s->is_catch_scope() || s->num_heap_slots() > 0); | 724 DCHECK(!s->is_catch_scope() || s->num_heap_slots() > 0); |
725 DCHECK(!s->is_module_scope() || s->num_heap_slots() > 0); | 725 DCHECK(!s->is_module_scope() || s->num_heap_slots() > 0); |
726 } | 726 } |
727 return n; | 727 return n; |
728 } | 728 } |
729 | 729 |
730 | 730 |
731 Scope* Scope::GlobalScope() { | 731 Scope* Scope::ScriptScope() { |
732 Scope* scope = this; | 732 Scope* scope = this; |
733 while (!scope->is_global_scope()) { | 733 while (!scope->is_script_scope()) { |
rossberg
2014/11/12 09:49:27
This loop should no longer be needed. (Is this met
Dmitry Lomov (no reviews)
2014/11/12 10:16:26
The loop is needed and the method is needed for mo
| |
734 scope = scope->outer_scope(); | 734 scope = scope->outer_scope(); |
735 } | 735 } |
736 return scope; | 736 return scope; |
737 } | 737 } |
738 | 738 |
739 | 739 |
740 Scope* Scope::DeclarationScope() { | 740 Scope* Scope::DeclarationScope() { |
741 Scope* scope = this; | 741 Scope* scope = this; |
742 while (!scope->is_declaration_scope()) { | 742 while (!scope->is_declaration_scope()) { |
743 scope = scope->outer_scope(); | 743 scope = scope->outer_scope(); |
(...skipping 27 matching lines...) Expand all Loading... | |
771 } | 771 } |
772 } | 772 } |
773 | 773 |
774 | 774 |
775 #ifdef DEBUG | 775 #ifdef DEBUG |
776 static const char* Header(ScopeType scope_type) { | 776 static const char* Header(ScopeType scope_type) { |
777 switch (scope_type) { | 777 switch (scope_type) { |
778 case EVAL_SCOPE: return "eval"; | 778 case EVAL_SCOPE: return "eval"; |
779 case FUNCTION_SCOPE: return "function"; | 779 case FUNCTION_SCOPE: return "function"; |
780 case MODULE_SCOPE: return "module"; | 780 case MODULE_SCOPE: return "module"; |
781 case GLOBAL_SCOPE: return "global"; | 781 case SCRIPT_SCOPE: return "global"; |
782 case CATCH_SCOPE: return "catch"; | 782 case CATCH_SCOPE: return "catch"; |
783 case BLOCK_SCOPE: return "block"; | 783 case BLOCK_SCOPE: return "block"; |
784 case WITH_SCOPE: return "with"; | 784 case WITH_SCOPE: return "with"; |
785 case ARROW_SCOPE: return "arrow"; | 785 case ARROW_SCOPE: return "arrow"; |
786 } | 786 } |
787 UNREACHABLE(); | 787 UNREACHABLE(); |
788 return NULL; | 788 return NULL; |
789 } | 789 } |
790 | 790 |
791 | 791 |
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
998 *binding_kind = UNBOUND; | 998 *binding_kind = UNBOUND; |
999 var = LookupFunctionVar(proxy->raw_name(), factory); | 999 var = LookupFunctionVar(proxy->raw_name(), factory); |
1000 if (var != NULL) { | 1000 if (var != NULL) { |
1001 *binding_kind = BOUND; | 1001 *binding_kind = BOUND; |
1002 } else if (outer_scope_ != NULL) { | 1002 } else if (outer_scope_ != NULL) { |
1003 var = outer_scope_->LookupRecursive(proxy, binding_kind, factory); | 1003 var = outer_scope_->LookupRecursive(proxy, binding_kind, factory); |
1004 if (*binding_kind == BOUND && (is_function_scope() || is_with_scope())) { | 1004 if (*binding_kind == BOUND && (is_function_scope() || is_with_scope())) { |
1005 var->ForceContextAllocation(); | 1005 var->ForceContextAllocation(); |
1006 } | 1006 } |
1007 } else { | 1007 } else { |
1008 DCHECK(is_global_scope()); | 1008 DCHECK(is_script_scope()); |
1009 } | 1009 } |
1010 | 1010 |
1011 if (is_with_scope()) { | 1011 if (is_with_scope()) { |
1012 DCHECK(!already_resolved()); | 1012 DCHECK(!already_resolved()); |
1013 // The current scope is a with scope, so the variable binding can not be | 1013 // The current scope is a with scope, so the variable binding can not be |
1014 // statically resolved. However, note that it was necessary to do a lookup | 1014 // statically resolved. However, note that it was necessary to do a lookup |
1015 // in the outer scope anyway, because if a binding exists in an outer scope, | 1015 // in the outer scope anyway, because if a binding exists in an outer scope, |
1016 // the associated variable has to be marked as potentially being accessed | 1016 // the associated variable has to be marked as potentially being accessed |
1017 // from inside of an inner with scope (the property may not be in the 'with' | 1017 // from inside of an inner with scope (the property may not be in the 'with' |
1018 // object). | 1018 // object). |
(...skipping 11 matching lines...) Expand all Loading... | |
1030 *binding_kind = UNBOUND_EVAL_SHADOWED; | 1030 *binding_kind = UNBOUND_EVAL_SHADOWED; |
1031 } | 1031 } |
1032 } | 1032 } |
1033 return var; | 1033 return var; |
1034 } | 1034 } |
1035 | 1035 |
1036 | 1036 |
1037 bool Scope::ResolveVariable(CompilationInfo* info, | 1037 bool Scope::ResolveVariable(CompilationInfo* info, |
1038 VariableProxy* proxy, | 1038 VariableProxy* proxy, |
1039 AstNodeFactory<AstNullVisitor>* factory) { | 1039 AstNodeFactory<AstNullVisitor>* factory) { |
1040 DCHECK(info->global_scope()->is_global_scope()); | 1040 DCHECK(info->script_scope()->is_script_scope()); |
1041 | 1041 |
1042 // If the proxy is already resolved there's nothing to do | 1042 // If the proxy is already resolved there's nothing to do |
1043 // (functions and consts may be resolved by the parser). | 1043 // (functions and consts may be resolved by the parser). |
1044 if (proxy->is_resolved()) return true; | 1044 if (proxy->is_resolved()) return true; |
1045 | 1045 |
1046 // Otherwise, try to resolve the variable. | 1046 // Otherwise, try to resolve the variable. |
1047 BindingKind binding_kind; | 1047 BindingKind binding_kind; |
1048 Variable* var = LookupRecursive(proxy, &binding_kind, factory); | 1048 Variable* var = LookupRecursive(proxy, &binding_kind, factory); |
1049 switch (binding_kind) { | 1049 switch (binding_kind) { |
1050 case BOUND: | 1050 case BOUND: |
(...skipping 11 matching lines...) Expand all Loading... | |
1062 var = NonLocal(proxy->raw_name(), DYNAMIC); | 1062 var = NonLocal(proxy->raw_name(), DYNAMIC); |
1063 } else { | 1063 } else { |
1064 Variable* invalidated = var; | 1064 Variable* invalidated = var; |
1065 var = NonLocal(proxy->raw_name(), DYNAMIC_LOCAL); | 1065 var = NonLocal(proxy->raw_name(), DYNAMIC_LOCAL); |
1066 var->set_local_if_not_shadowed(invalidated); | 1066 var->set_local_if_not_shadowed(invalidated); |
1067 } | 1067 } |
1068 break; | 1068 break; |
1069 | 1069 |
1070 case UNBOUND: | 1070 case UNBOUND: |
1071 // No binding has been found. Declare a variable on the global object. | 1071 // No binding has been found. Declare a variable on the global object. |
1072 var = info->global_scope()->DeclareDynamicGlobal(proxy->raw_name()); | 1072 var = info->script_scope()->DeclareDynamicGlobal(proxy->raw_name()); |
1073 break; | 1073 break; |
1074 | 1074 |
1075 case UNBOUND_EVAL_SHADOWED: | 1075 case UNBOUND_EVAL_SHADOWED: |
1076 // No binding has been found. But some scope makes a sloppy 'eval' call. | 1076 // No binding has been found. But some scope makes a sloppy 'eval' call. |
1077 var = NonLocal(proxy->raw_name(), DYNAMIC_GLOBAL); | 1077 var = NonLocal(proxy->raw_name(), DYNAMIC_GLOBAL); |
1078 break; | 1078 break; |
1079 | 1079 |
1080 case DYNAMIC_LOOKUP: | 1080 case DYNAMIC_LOOKUP: |
1081 // The variable could not be resolved statically. | 1081 // The variable could not be resolved statically. |
1082 var = NonLocal(proxy->raw_name(), DYNAMIC); | 1082 var = NonLocal(proxy->raw_name(), DYNAMIC); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1139 | 1139 |
1140 proxy->BindTo(var); | 1140 proxy->BindTo(var); |
1141 | 1141 |
1142 return true; | 1142 return true; |
1143 } | 1143 } |
1144 | 1144 |
1145 | 1145 |
1146 bool Scope::ResolveVariablesRecursively( | 1146 bool Scope::ResolveVariablesRecursively( |
1147 CompilationInfo* info, | 1147 CompilationInfo* info, |
1148 AstNodeFactory<AstNullVisitor>* factory) { | 1148 AstNodeFactory<AstNullVisitor>* factory) { |
1149 DCHECK(info->global_scope()->is_global_scope()); | 1149 DCHECK(info->script_scope()->is_script_scope()); |
1150 | 1150 |
1151 // Resolve unresolved variables for this scope. | 1151 // Resolve unresolved variables for this scope. |
1152 for (int i = 0; i < unresolved_.length(); i++) { | 1152 for (int i = 0; i < unresolved_.length(); i++) { |
1153 if (!ResolveVariable(info, unresolved_[i], factory)) return false; | 1153 if (!ResolveVariable(info, unresolved_[i], factory)) return false; |
1154 } | 1154 } |
1155 | 1155 |
1156 // Resolve unresolved variables for inner scopes. | 1156 // Resolve unresolved variables for inner scopes. |
1157 for (int i = 0; i < inner_scopes_.length(); i++) { | 1157 for (int i = 0; i < inner_scopes_.length(); i++) { |
1158 if (!inner_scopes_[i]->ResolveVariablesRecursively(info, factory)) | 1158 if (!inner_scopes_[i]->ResolveVariablesRecursively(info, factory)) |
1159 return false; | 1159 return false; |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1202 // via an eval() call. This is only possible if the variable has a | 1202 // via an eval() call. This is only possible if the variable has a |
1203 // visible name. | 1203 // visible name. |
1204 if ((var->is_this() || !var->raw_name()->IsEmpty()) && | 1204 if ((var->is_this() || !var->raw_name()->IsEmpty()) && |
1205 (var->has_forced_context_allocation() || | 1205 (var->has_forced_context_allocation() || |
1206 scope_calls_eval_ || | 1206 scope_calls_eval_ || |
1207 inner_scope_calls_eval_ || | 1207 inner_scope_calls_eval_ || |
1208 scope_contains_with_ || | 1208 scope_contains_with_ || |
1209 is_catch_scope() || | 1209 is_catch_scope() || |
1210 is_block_scope() || | 1210 is_block_scope() || |
1211 is_module_scope() || | 1211 is_module_scope() || |
1212 is_global_scope())) { | 1212 is_script_scope())) { |
1213 var->set_is_used(); | 1213 var->set_is_used(); |
1214 if (scope_calls_eval_ || inner_scope_calls_eval_) var->set_maybe_assigned(); | 1214 if (scope_calls_eval_ || inner_scope_calls_eval_) var->set_maybe_assigned(); |
1215 } | 1215 } |
1216 // Global variables do not need to be allocated. | 1216 // Global variables do not need to be allocated. |
1217 return !var->IsGlobalObjectProperty() && var->is_used(); | 1217 return !var->IsGlobalObjectProperty() && var->is_used(); |
1218 } | 1218 } |
1219 | 1219 |
1220 | 1220 |
1221 bool Scope::MustAllocateInContext(Variable* var) { | 1221 bool Scope::MustAllocateInContext(Variable* var) { |
1222 // If var is accessed from an inner scope, or if there is a possibility | 1222 // If var is accessed from an inner scope, or if there is a possibility |
1223 // that it might be accessed from the current or an inner scope (through | 1223 // that it might be accessed from the current or an inner scope (through |
1224 // an eval() call or a runtime with lookup), it must be allocated in the | 1224 // an eval() call or a runtime with lookup), it must be allocated in the |
1225 // context. | 1225 // context. |
1226 // | 1226 // |
1227 // Exceptions: If the scope as a whole has forced context allocation, all | 1227 // Exceptions: If the scope as a whole has forced context allocation, all |
1228 // variables will have context allocation, even temporaries. Otherwise | 1228 // variables will have context allocation, even temporaries. Otherwise |
1229 // temporary variables are always stack-allocated. Catch-bound variables are | 1229 // temporary variables are always stack-allocated. Catch-bound variables are |
1230 // always context-allocated. | 1230 // always context-allocated. |
1231 if (has_forced_context_allocation()) return true; | 1231 if (has_forced_context_allocation()) return true; |
1232 if (var->mode() == TEMPORARY) return false; | 1232 if (var->mode() == TEMPORARY) return false; |
1233 if (var->mode() == INTERNAL) return true; | 1233 if (var->mode() == INTERNAL) return true; |
1234 if (is_catch_scope() || is_block_scope() || is_module_scope()) return true; | 1234 if (is_catch_scope() || is_block_scope() || is_module_scope()) return true; |
1235 if (is_global_scope() && IsLexicalVariableMode(var->mode())) return true; | 1235 if (is_script_scope() && IsLexicalVariableMode(var->mode())) return true; |
1236 return var->has_forced_context_allocation() || | 1236 return var->has_forced_context_allocation() || |
1237 scope_calls_eval_ || | 1237 scope_calls_eval_ || |
1238 inner_scope_calls_eval_ || | 1238 inner_scope_calls_eval_ || |
1239 scope_contains_with_; | 1239 scope_contains_with_; |
1240 } | 1240 } |
1241 | 1241 |
1242 | 1242 |
1243 bool Scope::HasArgumentsParameter() { | 1243 bool Scope::HasArgumentsParameter() { |
1244 for (int i = 0; i < params_.length(); i++) { | 1244 for (int i = 0; i < params_.length(); i++) { |
1245 if (params_[i]->name().is_identical_to( | 1245 if (params_[i]->name().is_identical_to( |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1423 } | 1423 } |
1424 | 1424 |
1425 | 1425 |
1426 int Scope::ContextLocalCount() const { | 1426 int Scope::ContextLocalCount() const { |
1427 if (num_heap_slots() == 0) return 0; | 1427 if (num_heap_slots() == 0) return 0; |
1428 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - | 1428 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - |
1429 (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0); | 1429 (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0); |
1430 } | 1430 } |
1431 | 1431 |
1432 } } // namespace v8::internal | 1432 } } // namespace v8::internal |
OLD | NEW |