Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(94)

Side by Side Diff: src/ast/scopes.cc

Issue 2280033002: Move Parser::Declare to Scope. (Closed)
Patch Set: beautification Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/ast/scopes.h ('k') | src/parsing/declaration-descriptor.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/ast/scopes.h" 5 #include "src/ast/scopes.h"
6 6
7 #include <set> 7 #include <set>
8 8
9 #include "src/accessors.h" 9 #include "src/accessors.h"
10 #include "src/bootstrapper.h" 10 #include "src/bootstrapper.h"
11 #include "src/isolate.h"
11 #include "src/messages.h" 12 #include "src/messages.h"
12 #include "src/parsing/parse-info.h" 13 #include "src/parsing/parse-info.h"
13 14
14 namespace v8 { 15 namespace v8 {
15 namespace internal { 16 namespace internal {
16 17
17 // ---------------------------------------------------------------------------- 18 // ----------------------------------------------------------------------------
18 // Implementation of LocalsMap 19 // Implementation of LocalsMap
19 // 20 //
20 // Note: We are storing the handle locations as key values in the hash map. 21 // Note: We are storing the handle locations as key values in the hash map.
(...skipping 668 matching lines...) Expand 10 before | Expand all | Expand 10 after
689 MaybeAssignedFlag maybe_assigned_flag) { 690 MaybeAssignedFlag maybe_assigned_flag) {
690 DCHECK(!already_resolved_); 691 DCHECK(!already_resolved_);
691 // This function handles VAR, LET, and CONST modes. DYNAMIC variables are 692 // This function handles VAR, LET, and CONST modes. DYNAMIC variables are
692 // introduced during variable allocation, and TEMPORARY variables are 693 // introduced during variable allocation, and TEMPORARY variables are
693 // allocated via NewTemporary(). 694 // allocated via NewTemporary().
694 DCHECK(IsDeclaredVariableMode(mode)); 695 DCHECK(IsDeclaredVariableMode(mode));
695 return Declare(zone(), this, name, mode, kind, init_flag, 696 return Declare(zone(), this, name, mode, kind, init_flag,
696 maybe_assigned_flag); 697 maybe_assigned_flag);
697 } 698 }
698 699
700 Variable* Scope::DeclareVariableOrParameter(
701 Declaration* declaration, DeclarationDescriptor::Kind declaration_kind,
702 VariableMode mode, InitializationFlag init,
703 bool allow_harmony_restrictive_generators,
704 PendingCompilationErrorHandler* error_handler_, int* use_counts, bool* ok) {
705 DCHECK(IsDeclaredVariableMode(mode) && mode != CONST_LEGACY);
706 DCHECK(!already_resolved_);
707
708 if (mode == VAR && !is_declaration_scope()) {
709 return GetDeclarationScope()->DeclareVariableOrParameter(
710 declaration, declaration_kind, mode, init,
711 allow_harmony_restrictive_generators, error_handler_, use_counts, ok);
712 }
713 DCHECK(!is_catch_scope());
714 DCHECK(!is_with_scope());
715 DCHECK(is_declaration_scope() ||
716 (IsLexicalVariableMode(mode) && is_block_scope()));
717
718 VariableProxy* proxy = declaration->proxy();
719 DCHECK(proxy->raw_name() != NULL);
720 const AstRawString* name = proxy->raw_name();
721 bool is_function_declaration = declaration->IsFunctionDeclaration();
722
723 Variable* var = NULL;
724 if (is_eval_scope() && is_sloppy(language_mode()) && mode == VAR) {
725 // In a var binding in a sloppy direct eval, pollute the enclosing scope
726 // with this new binding by doing the following:
727 // The proxy is bound to a lookup variable to force a dynamic declaration
728 // using the DeclareEvalVar or DeclareEvalFunction runtime functions.
729 Variable::Kind kind = Variable::NORMAL;
730 // TODO(sigurds) figure out if kNotAssigned is OK here
731 var = new (zone()) Variable(this, name, mode, kind, init, kNotAssigned);
732 var->AllocateTo(VariableLocation::LOOKUP, -1);
733 } else {
734 // Declare the variable in the declaration scope.
735 var = LookupLocal(name);
736 if (var == NULL) {
737 // Declare the name.
738 Variable::Kind kind = Variable::NORMAL;
739 if (is_function_declaration) {
740 kind = Variable::FUNCTION;
741 }
742 var = DeclareLocal(name, mode, init, kind, kNotAssigned);
743 } else if (IsLexicalVariableMode(mode) ||
744 IsLexicalVariableMode(var->mode())) {
745 // Allow duplicate function decls for web compat, see bug 4693.
746 bool duplicate_allowed = false;
747 if (is_sloppy(language_mode()) && is_function_declaration &&
748 var->is_function()) {
749 DCHECK(IsLexicalVariableMode(mode) &&
750 IsLexicalVariableMode(var->mode()));
751 // If the duplication is allowed, then the var will show up
752 // in the SloppyBlockFunctionMap and the new FunctionKind
753 // will be a permitted duplicate.
754 FunctionKind function_kind =
755 declaration->AsFunctionDeclaration()->fun()->kind();
756 duplicate_allowed =
757 GetDeclarationScope()->sloppy_block_function_map()->Lookup(
758 const_cast<AstRawString*>(name), name->hash()) != nullptr &&
759 !IsAsyncFunction(function_kind) &&
760 !(allow_harmony_restrictive_generators &&
761 IsGeneratorFunction(function_kind));
762 }
763 if (duplicate_allowed) {
764 ++use_counts[v8::Isolate::kSloppyModeBlockScopedFunctionRedefinition];
765 } else {
766 // The name was declared in this scope before; check for conflicting
767 // re-declarations. We have a conflict if either of the declarations
768 // is not a var (in script scope, we also have to ignore legacy const
769 // for compatibility). There is similar code in runtime.cc in the
770 // Declare functions. The function CheckConflictingVarDeclarations
771 // checks for var and let bindings from different scopes whereas this
772 // is a check for conflicting declarations within the same scope. This
773 // check also covers the special case
774 //
775 // function () { let x; { var x; } }
776 //
777 // because the var declaration is hoisted to the function scope where
778 // 'x' is already bound.
779 DCHECK(IsDeclaredVariableMode(var->mode()));
780 // In harmony we treat re-declarations as early errors. See
781 // ES5 16 for a definition of early errors.
782 if (declaration_kind == DeclarationDescriptor::NORMAL) {
783 error_handler_->ReportMessageAt(
784 declaration->position(), declaration->proxy()->end_position(),
marja 2016/08/29 08:31:44 Here the positions are different than they used to
785 MessageTemplate::kVarRedeclaration, name);
786 } else {
787 error_handler_->ReportMessageAt(declaration->position(),
788 declaration->proxy()->end_position(),
789 MessageTemplate::kParamDupe);
790 }
791 *ok = false;
792 return nullptr;
793 }
794 } else if (mode == VAR) {
795 var->set_maybe_assigned();
796 }
797 }
798 DCHECK_NOT_NULL(var);
799
800 // We add a declaration node for every declaration. The compiler
801 // will only generate code if necessary. In particular, declarations
802 // for inner local variables that do not represent functions won't
803 // result in any generated code.
804 //
805 // This will lead to multiple declaration nodes for the
806 // same variable if it is declared several times. This is not a
807 // semantic issue, but it may be a performance issue since it may
808 // lead to repeated DeclareEvalVar or DeclareEvalFunction calls.
809 decls_.Add(declaration, zone());
marja 2016/08/29 08:31:44 Inlined Scope::AddDeclaration here.
810 proxy->BindTo(var);
811 return var;
812 }
813
699 Variable* DeclarationScope::DeclareDynamicGlobal(const AstRawString* name, 814 Variable* DeclarationScope::DeclareDynamicGlobal(const AstRawString* name,
700 Variable::Kind kind) { 815 Variable::Kind kind) {
701 DCHECK(is_script_scope()); 816 DCHECK(is_script_scope());
702 return variables_.Declare(zone(), this, name, DYNAMIC_GLOBAL, kind, 817 return variables_.Declare(zone(), this, name, DYNAMIC_GLOBAL, kind,
703 kCreatedInitialized); 818 kCreatedInitialized);
704 } 819 }
705 820
706 821
707 bool Scope::RemoveUnresolved(VariableProxy* var) { 822 bool Scope::RemoveUnresolved(VariableProxy* var) {
708 if (unresolved_ == var) { 823 if (unresolved_ == var) {
(...skipping 19 matching lines...) Expand all
728 DeclarationScope* scope = GetClosureScope(); 843 DeclarationScope* scope = GetClosureScope();
729 Variable* var = new(zone()) Variable(scope, 844 Variable* var = new(zone()) Variable(scope,
730 name, 845 name,
731 TEMPORARY, 846 TEMPORARY,
732 Variable::NORMAL, 847 Variable::NORMAL,
733 kCreatedInitialized); 848 kCreatedInitialized);
734 scope->AddLocal(var); 849 scope->AddLocal(var);
735 return var; 850 return var;
736 } 851 }
737 852
738 void Scope::AddDeclaration(Declaration* declaration) {
739 DCHECK(!already_resolved_);
740 decls_.Add(declaration, zone());
741 }
742
743
744 Declaration* Scope::CheckConflictingVarDeclarations() { 853 Declaration* Scope::CheckConflictingVarDeclarations() {
745 int length = decls_.length(); 854 int length = decls_.length();
746 for (int i = 0; i < length; i++) { 855 for (int i = 0; i < length; i++) {
747 Declaration* decl = decls_[i]; 856 Declaration* decl = decls_[i];
748 VariableMode mode = decl->proxy()->var()->mode(); 857 VariableMode mode = decl->proxy()->var()->mode();
749 if (IsLexicalVariableMode(mode) && !is_block_scope()) continue; 858 if (IsLexicalVariableMode(mode) && !is_block_scope()) continue;
750 859
751 // Iterate through all scopes until and including the declaration scope. 860 // Iterate through all scopes until and including the declaration scope.
752 Scope* previous = NULL; 861 Scope* previous = NULL;
753 Scope* current = decl->scope(); 862 Scope* current = decl->scope();
(...skipping 862 matching lines...) Expand 10 before | Expand all | Expand 10 after
1616 function != nullptr && function->IsContextSlot(); 1725 function != nullptr && function->IsContextSlot();
1617 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - 1726 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() -
1618 (is_function_var_in_context ? 1 : 0); 1727 (is_function_var_in_context ? 1 : 0);
1619 } 1728 }
1620 1729
1621 1730
1622 int Scope::ContextGlobalCount() const { return num_global_slots(); } 1731 int Scope::ContextGlobalCount() const { return num_global_slots(); }
1623 1732
1624 } // namespace internal 1733 } // namespace internal
1625 } // namespace v8 1734 } // namespace v8
OLDNEW
« no previous file with comments | « src/ast/scopes.h ('k') | src/parsing/declaration-descriptor.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698