| 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...) Expand 10 before | Expand all | Expand 10 after  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...) Expand 10 before | Expand all | Expand 10 after  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...) Expand 10 before | Expand all | Expand 10 after  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...) Expand all  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...) Expand 10 before | Expand all | Expand 10 after  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...) Expand 10 before | Expand all | Expand 10 after  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 | 
|---|