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 #ifndef V8_AST_SCOPES_H_ | 5 #ifndef V8_AST_SCOPES_H_ |
6 #define V8_AST_SCOPES_H_ | 6 #define V8_AST_SCOPES_H_ |
7 | 7 |
8 #include "src/ast/ast.h" | 8 #include "src/ast/ast.h" |
9 #include "src/base/hashmap.h" | 9 #include "src/base/hashmap.h" |
10 #include "src/globals.h" | 10 #include "src/globals.h" |
(...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
523 bool force_context_allocation_ : 1; | 523 bool force_context_allocation_ : 1; |
524 | 524 |
525 // True if it holds 'var' declarations. | 525 // True if it holds 'var' declarations. |
526 bool is_declaration_scope_ : 1; | 526 bool is_declaration_scope_ : 1; |
527 | 527 |
528 // Create a non-local variable with a given name. | 528 // Create a non-local variable with a given name. |
529 // These variables are looked up dynamically at runtime. | 529 // These variables are looked up dynamically at runtime. |
530 Variable* NonLocal(const AstRawString* name, VariableMode mode); | 530 Variable* NonLocal(const AstRawString* name, VariableMode mode); |
531 | 531 |
532 // Variable resolution. | 532 // Variable resolution. |
533 // Possible results of a recursive variable lookup telling if and how a | |
534 // variable is bound. These are returned in the output parameter *binding_kind | |
535 // of the LookupRecursive function. | |
536 enum BindingKind { | |
537 // The variable reference could be statically resolved to a variable binding | |
538 // which is returned. There is no 'with' statement between the reference and | |
539 // the binding and no scope between the reference scope (inclusive) and | |
540 // binding scope (exclusive) makes a sloppy 'eval' call. | |
541 BOUND, | |
542 | |
543 // The variable reference could be statically resolved to a variable binding | |
544 // which is returned. There is no 'with' statement between the reference and | |
545 // the binding, but some scope between the reference scope (inclusive) and | |
546 // binding scope (exclusive) makes a sloppy 'eval' call, that might | |
547 // possibly introduce variable bindings shadowing the found one. Thus the | |
548 // found variable binding is just a guess. | |
549 BOUND_EVAL_SHADOWED, | |
550 | |
551 // The variable reference could not be statically resolved to any binding | |
552 // and thus should be considered referencing a global variable. NULL is | |
553 // returned. The variable reference is not inside any 'with' statement and | |
554 // no scope between the reference scope (inclusive) and script scope | |
555 // (exclusive) makes a sloppy 'eval' call. | |
556 UNBOUND, | |
557 | |
558 // The variable reference could not be statically resolved to any binding | |
559 // NULL is returned. The variable reference is not inside any 'with' | |
560 // statement, but some scope between the reference scope (inclusive) and | |
561 // script scope (exclusive) makes a sloppy 'eval' call, that might | |
562 // possibly introduce a variable binding. Thus the reference should be | |
563 // considered referencing a global variable unless it is shadowed by an | |
564 // 'eval' introduced binding. | |
565 UNBOUND_EVAL_SHADOWED, | |
566 | |
567 // The variable could not be statically resolved and needs to be looked up | |
568 // dynamically. NULL is returned. There are two possible reasons: | |
569 // * A 'with' statement has been encountered and there is no variable | |
570 // binding for the name between the variable reference and the 'with'. | |
571 // The variable potentially references a property of the 'with' object. | |
572 // * The code is being executed as part of a call to 'eval' and the calling | |
573 // context chain contains either a variable binding for the name or it | |
574 // contains a 'with' context. | |
575 DYNAMIC_LOOKUP | |
576 }; | |
577 | |
578 // Lookup a variable reference given by name recursively starting with this | 533 // Lookup a variable reference given by name recursively starting with this |
579 // scope, and stopping when reaching the outer_scope_end scope. If the code is | 534 // scope, and stopping when reaching the outer_scope_end scope. If the code is |
580 // executed because of a call to 'eval', the context parameter should be set | 535 // executed because of a call to 'eval', the context parameter should be set |
581 // to the calling context of 'eval'. | 536 // to the calling context of 'eval'. |
582 Variable* LookupRecursive(VariableProxy* proxy, BindingKind* binding_kind, | 537 // {declare_free} indicates whether nullptr should be returned for free |
583 AstNodeFactory* factory, | 538 // variables when falling off outer_scope_end, or whether they should be |
584 Scope* outer_scope_end = nullptr); | 539 // declared automatically as non-locals. |
585 void ResolveTo(ParseInfo* info, BindingKind binding_kind, | 540 Variable* LookupRecursive(VariableProxy* proxy, bool declare_free, |
586 VariableProxy* proxy, Variable* var); | 541 Scope* outer_scope_end); |
587 void ResolveVariable(ParseInfo* info, VariableProxy* proxy, | 542 void ResolveTo(ParseInfo* info, VariableProxy* proxy, Variable* var); |
588 AstNodeFactory* factory); | 543 void ResolveVariable(ParseInfo* info, VariableProxy* proxy); |
589 void ResolveVariablesRecursively(ParseInfo* info, AstNodeFactory* factory); | 544 void ResolveVariablesRecursively(ParseInfo* info); |
590 | 545 |
591 // Finds free variables of this scope. This mutates the unresolved variables | 546 // Finds free variables of this scope. This mutates the unresolved variables |
592 // list along the way, so full resolution cannot be done afterwards. | 547 // list along the way, so full resolution cannot be done afterwards. |
593 // If a ParseInfo* is passed, non-free variables will be resolved. | 548 // If a ParseInfo* is passed, non-free variables will be resolved. |
594 VariableProxy* FetchFreeVariables(DeclarationScope* max_outer_scope, | 549 VariableProxy* FetchFreeVariables(DeclarationScope* max_outer_scope, |
595 ParseInfo* info = nullptr, | 550 ParseInfo* info = nullptr, |
596 VariableProxy* stack = nullptr); | 551 VariableProxy* stack = nullptr); |
597 | 552 |
598 // Scope analysis. | 553 // Scope analysis. |
599 void PropagateScopeInfo(); | 554 void PropagateScopeInfo(); |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
674 // Does this scope access "super" property (super.foo). | 629 // Does this scope access "super" property (super.foo). |
675 bool uses_super_property() const { return scope_uses_super_property_; } | 630 bool uses_super_property() const { return scope_uses_super_property_; } |
676 | 631 |
677 bool NeedsHomeObject() const { | 632 bool NeedsHomeObject() const { |
678 return scope_uses_super_property_ || | 633 return scope_uses_super_property_ || |
679 (inner_scope_calls_eval_ && (IsConciseMethod(function_kind()) || | 634 (inner_scope_calls_eval_ && (IsConciseMethod(function_kind()) || |
680 IsAccessorFunction(function_kind()) || | 635 IsAccessorFunction(function_kind()) || |
681 IsClassConstructor(function_kind()))); | 636 IsClassConstructor(function_kind()))); |
682 } | 637 } |
683 | 638 |
| 639 void SetScriptScopeInfo(Handle<ScopeInfo> scope_info) { |
| 640 DCHECK(is_script_scope()); |
| 641 DCHECK(scope_info_.is_null()); |
| 642 scope_info_ = scope_info; |
| 643 } |
| 644 |
684 bool asm_module() const { return asm_module_; } | 645 bool asm_module() const { return asm_module_; } |
685 void set_asm_module() { asm_module_ = true; } | 646 void set_asm_module() { asm_module_ = true; } |
686 bool asm_function() const { return asm_function_; } | 647 bool asm_function() const { return asm_function_; } |
687 void set_asm_function() { asm_module_ = true; } | 648 void set_asm_function() { asm_module_ = true; } |
688 | 649 |
689 void DeclareThis(AstValueFactory* ast_value_factory); | 650 void DeclareThis(AstValueFactory* ast_value_factory); |
690 void DeclareDefaultFunctionVariables(AstValueFactory* ast_value_factory); | 651 void DeclareDefaultFunctionVariables(AstValueFactory* ast_value_factory); |
691 | 652 |
692 // This lookup corresponds to a lookup in the "intermediate" scope sitting | 653 // This lookup corresponds to a lookup in the "intermediate" scope sitting |
693 // between this scope and the outer scope. (ECMA-262, 3rd., requires that | 654 // between this scope and the outer scope. (ECMA-262, 3rd., requires that |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
825 } | 786 } |
826 | 787 |
827 // Resolve and fill in the allocation information for all variables | 788 // Resolve and fill in the allocation information for all variables |
828 // in this scopes. Must be called *after* all scopes have been | 789 // in this scopes. Must be called *after* all scopes have been |
829 // processed (parsed) to ensure that unresolved variables can be | 790 // processed (parsed) to ensure that unresolved variables can be |
830 // resolved properly. | 791 // resolved properly. |
831 // | 792 // |
832 // In the case of code compiled and run using 'eval', the context | 793 // In the case of code compiled and run using 'eval', the context |
833 // parameter is the context in which eval was called. In all other | 794 // parameter is the context in which eval was called. In all other |
834 // cases the context parameter is an empty handle. | 795 // cases the context parameter is an empty handle. |
835 void AllocateVariables(ParseInfo* info, AstNodeFactory* factory); | 796 void AllocateVariables(ParseInfo* info); |
836 | 797 |
837 // To be called during parsing. Do just enough scope analysis that we can | 798 // To be called during parsing. Do just enough scope analysis that we can |
838 // discard the Scope for lazily compiled functions. In particular, this | 799 // discard the Scope for lazily compiled functions. In particular, this |
839 // records variables which cannot be resolved inside the Scope (we don't yet | 800 // records variables which cannot be resolved inside the Scope (we don't yet |
840 // know what they will resolve to since the outer Scopes are incomplete) and | 801 // know what they will resolve to since the outer Scopes are incomplete) and |
841 // migrates them into migrate_to. | 802 // migrates them into migrate_to. |
842 void AnalyzePartially(DeclarationScope* migrate_to, | 803 void AnalyzePartially(DeclarationScope* migrate_to, |
843 AstNodeFactory* ast_node_factory); | 804 AstNodeFactory* ast_node_factory); |
844 | 805 |
845 Handle<StringSet> CollectNonLocals(ParseInfo* info, | 806 Handle<StringSet> CollectNonLocals(ParseInfo* info, |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
923 void AllocateModuleVariables(); | 884 void AllocateModuleVariables(); |
924 | 885 |
925 private: | 886 private: |
926 ModuleDescriptor* module_descriptor_; | 887 ModuleDescriptor* module_descriptor_; |
927 }; | 888 }; |
928 | 889 |
929 } // namespace internal | 890 } // namespace internal |
930 } // namespace v8 | 891 } // namespace v8 |
931 | 892 |
932 #endif // V8_AST_SCOPES_H_ | 893 #endif // V8_AST_SCOPES_H_ |
OLD | NEW |