OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 31 matching lines...) Loading... |
42 public: | 42 public: |
43 VariableMap(); | 43 VariableMap(); |
44 | 44 |
45 virtual ~VariableMap(); | 45 virtual ~VariableMap(); |
46 | 46 |
47 Variable* Declare(Scope* scope, | 47 Variable* Declare(Scope* scope, |
48 Handle<String> name, | 48 Handle<String> name, |
49 VariableMode mode, | 49 VariableMode mode, |
50 bool is_valid_lhs, | 50 bool is_valid_lhs, |
51 Variable::Kind kind, | 51 Variable::Kind kind, |
52 InitializationFlag initialization_flag); | 52 InitializationFlag initialization_flag, |
| 53 Interface* interface = Interface::NewValue()); |
53 | 54 |
54 Variable* Lookup(Handle<String> name); | 55 Variable* Lookup(Handle<String> name); |
55 }; | 56 }; |
56 | 57 |
57 | 58 |
58 // The dynamic scope part holds hash maps for the variables that will | 59 // The dynamic scope part holds hash maps for the variables that will |
59 // be looked up dynamically from within eval and with scopes. The objects | 60 // be looked up dynamically from within eval and with scopes. The objects |
60 // are allocated on-demand from Scope::NonLocal to avoid wasting memory | 61 // are allocated on-demand from Scope::NonLocal to avoid wasting memory |
61 // and setup time for scopes that don't need them. | 62 // and setup time for scopes that don't need them. |
62 class DynamicScopePart : public ZoneObject { | 63 class DynamicScopePart : public ZoneObject { |
(...skipping 75 matching lines...) Loading... |
138 | 139 |
139 // Declare a parameter in this scope. When there are duplicated | 140 // Declare a parameter in this scope. When there are duplicated |
140 // parameters the rightmost one 'wins'. However, the implementation | 141 // parameters the rightmost one 'wins'. However, the implementation |
141 // expects all parameters to be declared and from left to right. | 142 // expects all parameters to be declared and from left to right. |
142 void DeclareParameter(Handle<String> name, VariableMode mode); | 143 void DeclareParameter(Handle<String> name, VariableMode mode); |
143 | 144 |
144 // Declare a local variable in this scope. If the variable has been | 145 // Declare a local variable in this scope. If the variable has been |
145 // declared before, the previously declared variable is returned. | 146 // declared before, the previously declared variable is returned. |
146 Variable* DeclareLocal(Handle<String> name, | 147 Variable* DeclareLocal(Handle<String> name, |
147 VariableMode mode, | 148 VariableMode mode, |
148 InitializationFlag init_flag); | 149 InitializationFlag init_flag, |
| 150 Interface* interface = Interface::NewValue()); |
149 | 151 |
150 // Declare an implicit global variable in this scope which must be a | 152 // Declare an implicit global variable in this scope which must be a |
151 // global scope. The variable was introduced (possibly from an inner | 153 // global scope. The variable was introduced (possibly from an inner |
152 // scope) by a reference to an unresolved variable with no intervening | 154 // scope) by a reference to an unresolved variable with no intervening |
153 // with statements or eval calls. | 155 // with statements or eval calls. |
154 Variable* DeclareGlobal(Handle<String> name); | 156 Variable* DeclareGlobal(Handle<String> name); |
155 | 157 |
156 // Create a new unresolved variable. | 158 // Create a new unresolved variable. |
157 template<class Visitor> | 159 template<class Visitor> |
158 VariableProxy* NewUnresolved(AstNodeFactory<Visitor>* factory, | 160 VariableProxy* NewUnresolved(AstNodeFactory<Visitor>* factory, |
159 Handle<String> name, | 161 Handle<String> name, |
160 int position = RelocInfo::kNoPosition) { | 162 int position = RelocInfo::kNoPosition, |
| 163 Interface* interface = Interface::NewValue()) { |
161 // Note that we must not share the unresolved variables with | 164 // Note that we must not share the unresolved variables with |
162 // the same name because they may be removed selectively via | 165 // the same name because they may be removed selectively via |
163 // RemoveUnresolved(). | 166 // RemoveUnresolved(). |
164 ASSERT(!already_resolved()); | 167 ASSERT(!already_resolved()); |
165 VariableProxy* proxy = factory->NewVariableProxy(name, false, position); | 168 VariableProxy* proxy = |
| 169 factory->NewVariableProxy(name, false, position, interface); |
166 unresolved_.Add(proxy); | 170 unresolved_.Add(proxy); |
167 return proxy; | 171 return proxy; |
168 } | 172 } |
169 | 173 |
170 // Remove a unresolved variable. During parsing, an unresolved variable | 174 // Remove a unresolved variable. During parsing, an unresolved variable |
171 // may have been added optimistically, but then only the variable name | 175 // may have been added optimistically, but then only the variable name |
172 // was used (typically for labels). If the variable was not declared, the | 176 // was used (typically for labels). If the variable was not declared, the |
173 // addition introduced a new unresolved variable which may end up being | 177 // addition introduced a new unresolved variable which may end up being |
174 // allocated globally as a "ghost" variable. RemoveUnresolved removes | 178 // allocated globally as a "ghost" variable. RemoveUnresolved removes |
175 // such a variable again if it was added; otherwise this is a no-op. | 179 // such a variable again if it was added; otherwise this is a no-op. |
(...skipping 112 matching lines...) Loading... |
288 } | 292 } |
289 bool outer_scope_calls_non_strict_eval() const { | 293 bool outer_scope_calls_non_strict_eval() const { |
290 return outer_scope_calls_non_strict_eval_; | 294 return outer_scope_calls_non_strict_eval_; |
291 } | 295 } |
292 | 296 |
293 // Is this scope inside a with statement. | 297 // Is this scope inside a with statement. |
294 bool inside_with() const { return scope_inside_with_; } | 298 bool inside_with() const { return scope_inside_with_; } |
295 // Does this scope contain a with statement. | 299 // Does this scope contain a with statement. |
296 bool contains_with() const { return scope_contains_with_; } | 300 bool contains_with() const { return scope_contains_with_; } |
297 | 301 |
298 // The scope immediately surrounding this scope, or NULL. | |
299 Scope* outer_scope() const { return outer_scope_; } | |
300 | |
301 // --------------------------------------------------------------------------- | 302 // --------------------------------------------------------------------------- |
302 // Accessors. | 303 // Accessors. |
303 | 304 |
304 // The type of this scope. | 305 // The type of this scope. |
305 ScopeType type() const { return type_; } | 306 ScopeType type() const { return type_; } |
306 | 307 |
307 // The language mode of this scope. | 308 // The language mode of this scope. |
308 LanguageMode language_mode() const { return language_mode_; } | 309 LanguageMode language_mode() const { return language_mode_; } |
309 | 310 |
310 // The variable corresponding the 'this' value. | 311 // The variable corresponding the 'this' value. |
(...skipping 18 matching lines...) Loading... |
329 | 330 |
330 // The local variable 'arguments' if we need to allocate it; NULL otherwise. | 331 // The local variable 'arguments' if we need to allocate it; NULL otherwise. |
331 Variable* arguments() const { return arguments_; } | 332 Variable* arguments() const { return arguments_; } |
332 | 333 |
333 // Declarations list. | 334 // Declarations list. |
334 ZoneList<Declaration*>* declarations() { return &decls_; } | 335 ZoneList<Declaration*>* declarations() { return &decls_; } |
335 | 336 |
336 // Inner scope list. | 337 // Inner scope list. |
337 ZoneList<Scope*>* inner_scopes() { return &inner_scopes_; } | 338 ZoneList<Scope*>* inner_scopes() { return &inner_scopes_; } |
338 | 339 |
| 340 // The scope immediately surrounding this scope, or NULL. |
| 341 Scope* outer_scope() const { return outer_scope_; } |
| 342 |
| 343 // The interface as inferred so far; only for module scopes. |
| 344 Interface* interface() const { return interface_; } |
| 345 |
339 // --------------------------------------------------------------------------- | 346 // --------------------------------------------------------------------------- |
340 // Variable allocation. | 347 // Variable allocation. |
341 | 348 |
342 // Collect stack and context allocated local variables in this scope. Note | 349 // Collect stack and context allocated local variables in this scope. Note |
343 // that the function variable - if present - is not collected and should be | 350 // that the function variable - if present - is not collected and should be |
344 // handled separately. | 351 // handled separately. |
345 void CollectStackAndContextLocals(ZoneList<Variable*>* stack_locals, | 352 void CollectStackAndContextLocals(ZoneList<Variable*>* stack_locals, |
346 ZoneList<Variable*>* context_locals); | 353 ZoneList<Variable*>* context_locals); |
347 | 354 |
348 // Resolve and fill in the allocation information for all variables | |
349 // in this scopes. Must be called *after* all scopes have been | |
350 // processed (parsed) to ensure that unresolved variables can be | |
351 // resolved properly. | |
352 // | |
353 // In the case of code compiled and run using 'eval', the context | |
354 // parameter is the context in which eval was called. In all other | |
355 // cases the context parameter is an empty handle. | |
356 void AllocateVariables(Scope* global_scope, | |
357 AstNodeFactory<AstNullVisitor>* factory); | |
358 | |
359 // Current number of var or const locals. | 355 // Current number of var or const locals. |
360 int num_var_or_const() { return num_var_or_const_; } | 356 int num_var_or_const() { return num_var_or_const_; } |
361 | 357 |
362 // Result of variable allocation. | 358 // Result of variable allocation. |
363 int num_stack_slots() const { return num_stack_slots_; } | 359 int num_stack_slots() const { return num_stack_slots_; } |
364 int num_heap_slots() const { return num_heap_slots_; } | 360 int num_heap_slots() const { return num_heap_slots_; } |
365 | 361 |
366 int StackLocalCount() const; | 362 int StackLocalCount() const; |
367 int ContextLocalCount() const; | 363 int ContextLocalCount() const; |
368 | 364 |
(...skipping 77 matching lines...) Loading... |
446 // Unresolved variables referred to from this scope. | 442 // Unresolved variables referred to from this scope. |
447 ZoneList<VariableProxy*> unresolved_; | 443 ZoneList<VariableProxy*> unresolved_; |
448 // Declarations. | 444 // Declarations. |
449 ZoneList<Declaration*> decls_; | 445 ZoneList<Declaration*> decls_; |
450 // Convenience variable. | 446 // Convenience variable. |
451 Variable* receiver_; | 447 Variable* receiver_; |
452 // Function variable, if any; function scopes only. | 448 // Function variable, if any; function scopes only. |
453 VariableProxy* function_; | 449 VariableProxy* function_; |
454 // Convenience variable; function scopes only. | 450 // Convenience variable; function scopes only. |
455 Variable* arguments_; | 451 Variable* arguments_; |
| 452 // Interface; module scopes only. |
| 453 Interface* interface_; |
456 | 454 |
457 // Illegal redeclaration. | 455 // Illegal redeclaration. |
458 Expression* illegal_redecl_; | 456 Expression* illegal_redecl_; |
459 | 457 |
460 // Scope-specific information computed during parsing. | 458 // Scope-specific information computed during parsing. |
461 // | 459 // |
462 // This scope is inside a 'with' of some outer scope. | 460 // This scope is inside a 'with' of some outer scope. |
463 bool scope_inside_with_; | 461 bool scope_inside_with_; |
464 // This scope contains a 'with' statement. | 462 // This scope contains a 'with' statement. |
465 bool scope_contains_with_; | 463 bool scope_contains_with_; |
(...skipping 75 matching lines...) Loading... |
541 // contains a 'with' context. | 539 // contains a 'with' context. |
542 DYNAMIC_LOOKUP | 540 DYNAMIC_LOOKUP |
543 }; | 541 }; |
544 | 542 |
545 // Lookup a variable reference given by name recursively starting with this | 543 // Lookup a variable reference given by name recursively starting with this |
546 // scope. If the code is executed because of a call to 'eval', the context | 544 // scope. If the code is executed because of a call to 'eval', the context |
547 // parameter should be set to the calling context of 'eval'. | 545 // parameter should be set to the calling context of 'eval'. |
548 Variable* LookupRecursive(Handle<String> name, | 546 Variable* LookupRecursive(Handle<String> name, |
549 BindingKind* binding_kind, | 547 BindingKind* binding_kind, |
550 AstNodeFactory<AstNullVisitor>* factory); | 548 AstNodeFactory<AstNullVisitor>* factory); |
551 void ResolveVariable(Scope* global_scope, | 549 MUST_USE_RESULT |
| 550 bool ResolveVariable(CompilationInfo* info, |
552 VariableProxy* proxy, | 551 VariableProxy* proxy, |
553 AstNodeFactory<AstNullVisitor>* factory); | 552 AstNodeFactory<AstNullVisitor>* factory); |
554 void ResolveVariablesRecursively(Scope* global_scope, | 553 MUST_USE_RESULT |
| 554 bool ResolveVariablesRecursively(CompilationInfo* info, |
555 AstNodeFactory<AstNullVisitor>* factory); | 555 AstNodeFactory<AstNullVisitor>* factory); |
556 | 556 |
557 // Scope analysis. | 557 // Scope analysis. |
558 bool PropagateScopeInfo(bool outer_scope_calls_non_strict_eval); | 558 bool PropagateScopeInfo(bool outer_scope_calls_non_strict_eval); |
559 bool HasTrivialContext() const; | 559 bool HasTrivialContext() const; |
560 | 560 |
561 // Predicates. | 561 // Predicates. |
562 bool MustAllocate(Variable* var); | 562 bool MustAllocate(Variable* var); |
563 bool MustAllocateInContext(Variable* var); | 563 bool MustAllocateInContext(Variable* var); |
564 bool HasArgumentsParameter(); | 564 bool HasArgumentsParameter(); |
565 | 565 |
566 // Variable allocation. | 566 // Variable allocation. |
567 void AllocateStackSlot(Variable* var); | 567 void AllocateStackSlot(Variable* var); |
568 void AllocateHeapSlot(Variable* var); | 568 void AllocateHeapSlot(Variable* var); |
569 void AllocateParameterLocals(); | 569 void AllocateParameterLocals(); |
570 void AllocateNonParameterLocal(Variable* var); | 570 void AllocateNonParameterLocal(Variable* var); |
571 void AllocateNonParameterLocals(); | 571 void AllocateNonParameterLocals(); |
572 void AllocateVariablesRecursively(); | 572 void AllocateVariablesRecursively(); |
573 | 573 |
| 574 // Resolve and fill in the allocation information for all variables |
| 575 // in this scopes. Must be called *after* all scopes have been |
| 576 // processed (parsed) to ensure that unresolved variables can be |
| 577 // resolved properly. |
| 578 // |
| 579 // In the case of code compiled and run using 'eval', the context |
| 580 // parameter is the context in which eval was called. In all other |
| 581 // cases the context parameter is an empty handle. |
| 582 MUST_USE_RESULT |
| 583 bool AllocateVariables(CompilationInfo* info, |
| 584 AstNodeFactory<AstNullVisitor>* factory); |
| 585 |
574 private: | 586 private: |
575 // Construct a scope based on the scope info. | 587 // Construct a scope based on the scope info. |
576 Scope(Scope* inner_scope, ScopeType type, Handle<ScopeInfo> scope_info); | 588 Scope(Scope* inner_scope, ScopeType type, Handle<ScopeInfo> scope_info); |
577 | 589 |
578 // Construct a catch scope with a binding for the name. | 590 // Construct a catch scope with a binding for the name. |
579 Scope(Scope* inner_scope, Handle<String> catch_variable_name); | 591 Scope(Scope* inner_scope, Handle<String> catch_variable_name); |
580 | 592 |
581 void AddInnerScope(Scope* inner_scope) { | 593 void AddInnerScope(Scope* inner_scope) { |
582 if (inner_scope != NULL) { | 594 if (inner_scope != NULL) { |
583 inner_scopes_.Add(inner_scope); | 595 inner_scopes_.Add(inner_scope); |
584 inner_scope->outer_scope_ = this; | 596 inner_scope->outer_scope_ = this; |
585 } | 597 } |
586 } | 598 } |
587 | 599 |
588 void SetDefaults(ScopeType type, | 600 void SetDefaults(ScopeType type, |
589 Scope* outer_scope, | 601 Scope* outer_scope, |
590 Handle<ScopeInfo> scope_info); | 602 Handle<ScopeInfo> scope_info); |
591 }; | 603 }; |
592 | 604 |
593 } } // namespace v8::internal | 605 } } // namespace v8::internal |
594 | 606 |
595 #endif // V8_SCOPES_H_ | 607 #endif // V8_SCOPES_H_ |
OLD | NEW |