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