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

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

Issue 2280033002: Move Parser::Declare to Scope. (Closed)
Patch Set: code review (verwaest@) 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
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"
(...skipping 678 matching lines...) Expand 10 before | Expand all | Expand 10 after
689 MaybeAssignedFlag maybe_assigned_flag) { 689 MaybeAssignedFlag maybe_assigned_flag) {
690 DCHECK(!already_resolved_); 690 DCHECK(!already_resolved_);
691 // This function handles VAR, LET, and CONST modes. DYNAMIC variables are 691 // This function handles VAR, LET, and CONST modes. DYNAMIC variables are
692 // introduced during variable allocation, and TEMPORARY variables are 692 // introduced during variable allocation, and TEMPORARY variables are
693 // allocated via NewTemporary(). 693 // allocated via NewTemporary().
694 DCHECK(IsDeclaredVariableMode(mode)); 694 DCHECK(IsDeclaredVariableMode(mode));
695 return Declare(zone(), this, name, mode, kind, init_flag, 695 return Declare(zone(), this, name, mode, kind, init_flag,
696 maybe_assigned_flag); 696 maybe_assigned_flag);
697 } 697 }
698 698
699 Variable* Scope::DeclareVariable(
700 Declaration* declaration, VariableMode mode, InitializationFlag init,
701 bool allow_harmony_restrictive_generators,
702 bool* sloppy_mode_block_scope_function_redefinition, bool* ok) {
703 DCHECK(IsDeclaredVariableMode(mode) && mode != CONST_LEGACY);
704 DCHECK(!already_resolved_);
705
706 if (mode == VAR && !is_declaration_scope()) {
707 return GetDeclarationScope()->DeclareVariable(
708 declaration, mode, init, allow_harmony_restrictive_generators,
709 sloppy_mode_block_scope_function_redefinition, ok);
710 }
711 DCHECK(!is_catch_scope());
712 DCHECK(!is_with_scope());
713 DCHECK(is_declaration_scope() ||
714 (IsLexicalVariableMode(mode) && is_block_scope()));
715
716 VariableProxy* proxy = declaration->proxy();
717 DCHECK(proxy->raw_name() != NULL);
718 const AstRawString* name = proxy->raw_name();
719 bool is_function_declaration = declaration->IsFunctionDeclaration();
720
721 Variable* var = nullptr;
722 if (is_eval_scope() && is_sloppy(language_mode()) && mode == VAR) {
723 // In a var binding in a sloppy direct eval, pollute the enclosing scope
724 // with this new binding by doing the following:
725 // The proxy is bound to a lookup variable to force a dynamic declaration
726 // using the DeclareEvalVar or DeclareEvalFunction runtime functions.
727 Variable::Kind kind = Variable::NORMAL;
728 // TODO(sigurds) figure out if kNotAssigned is OK here
729 var = new (zone()) Variable(this, name, mode, kind, init, kNotAssigned);
730 var->AllocateTo(VariableLocation::LOOKUP, -1);
731 } else {
732 // Declare the variable in the declaration scope.
733 var = LookupLocal(name);
734 if (var == NULL) {
735 // Declare the name.
736 Variable::Kind kind = Variable::NORMAL;
737 if (is_function_declaration) {
738 kind = Variable::FUNCTION;
739 }
740 var = DeclareLocal(name, mode, init, kind, kNotAssigned);
741 } else if (IsLexicalVariableMode(mode) ||
742 IsLexicalVariableMode(var->mode())) {
743 // Allow duplicate function decls for web compat, see bug 4693.
744 bool duplicate_allowed = false;
745 if (is_sloppy(language_mode()) && is_function_declaration &&
746 var->is_function()) {
747 DCHECK(IsLexicalVariableMode(mode) &&
748 IsLexicalVariableMode(var->mode()));
749 // If the duplication is allowed, then the var will show up
750 // in the SloppyBlockFunctionMap and the new FunctionKind
751 // will be a permitted duplicate.
752 FunctionKind function_kind =
753 declaration->AsFunctionDeclaration()->fun()->kind();
754 duplicate_allowed =
755 GetDeclarationScope()->sloppy_block_function_map()->Lookup(
756 const_cast<AstRawString*>(name), name->hash()) != nullptr &&
757 !IsAsyncFunction(function_kind) &&
758 !(allow_harmony_restrictive_generators &&
759 IsGeneratorFunction(function_kind));
760 }
761 if (duplicate_allowed) {
762 *sloppy_mode_block_scope_function_redefinition = true;
763 } else {
764 // The name was declared in this scope before; check for conflicting
adamk 2016/08/30 18:58:32 This comment seems out of place and out of date. M
marja 2016/08/31 07:44:53 Ok, then I won't do anything for it..
765 // re-declarations. We have a conflict if either of the declarations
766 // is not a var (in script scope, we also have to ignore legacy const
767 // for compatibility). There is similar code in runtime.cc in the
768 // Declare functions. The function CheckConflictingVarDeclarations
769 // checks for var and let bindings from different scopes whereas this
770 // is a check for conflicting declarations within the same scope. This
771 // check also covers the special case
772 //
773 // function () { let x; { var x; } }
774 //
775 // because the var declaration is hoisted to the function scope where
776 // 'x' is already bound.
777 DCHECK(IsDeclaredVariableMode(var->mode()));
778 // In harmony we treat re-declarations as early errors. See
adamk 2016/08/30 18:58:32 This comment is now out of place (it belongs in th
marja 2016/08/31 07:44:53 Hmm, but the decision to set *ok = false is done h
adamk 2016/08/31 18:10:34 Ah, I hadn't thought about it that way. I was thin
779 // ES5 16 for a definition of early errors.
780 *ok = false;
781 return nullptr;
782 }
783 } else if (mode == VAR) {
784 var->set_maybe_assigned();
785 }
786 }
787 DCHECK_NOT_NULL(var);
788
789 // We add a declaration node for every declaration. The compiler
790 // will only generate code if necessary. In particular, declarations
791 // for inner local variables that do not represent functions won't
792 // result in any generated code.
793 //
794 // This will lead to multiple declaration nodes for the
795 // same variable if it is declared several times. This is not a
796 // semantic issue, but it may be a performance issue since it may
797 // lead to repeated DeclareEvalVar or DeclareEvalFunction calls.
798 decls_.Add(declaration, zone());
799 proxy->BindTo(var);
800 return var;
801 }
802
699 Variable* DeclarationScope::DeclareDynamicGlobal(const AstRawString* name, 803 Variable* DeclarationScope::DeclareDynamicGlobal(const AstRawString* name,
700 Variable::Kind kind) { 804 Variable::Kind kind) {
701 DCHECK(is_script_scope()); 805 DCHECK(is_script_scope());
702 return variables_.Declare(zone(), this, name, DYNAMIC_GLOBAL, kind, 806 return variables_.Declare(zone(), this, name, DYNAMIC_GLOBAL, kind,
703 kCreatedInitialized); 807 kCreatedInitialized);
704 } 808 }
705 809
706 810
707 bool Scope::RemoveUnresolved(VariableProxy* var) { 811 bool Scope::RemoveUnresolved(VariableProxy* var) {
708 if (unresolved_ == var) { 812 if (unresolved_ == var) {
(...skipping 19 matching lines...) Expand all
728 DeclarationScope* scope = GetClosureScope(); 832 DeclarationScope* scope = GetClosureScope();
729 Variable* var = new(zone()) Variable(scope, 833 Variable* var = new(zone()) Variable(scope,
730 name, 834 name,
731 TEMPORARY, 835 TEMPORARY,
732 Variable::NORMAL, 836 Variable::NORMAL,
733 kCreatedInitialized); 837 kCreatedInitialized);
734 scope->AddLocal(var); 838 scope->AddLocal(var);
735 return var; 839 return var;
736 } 840 }
737 841
738 void Scope::AddDeclaration(Declaration* declaration) {
739 DCHECK(!already_resolved_);
740 decls_.Add(declaration, zone());
741 }
742
743
744 Declaration* Scope::CheckConflictingVarDeclarations() { 842 Declaration* Scope::CheckConflictingVarDeclarations() {
745 int length = decls_.length(); 843 int length = decls_.length();
746 for (int i = 0; i < length; i++) { 844 for (int i = 0; i < length; i++) {
747 Declaration* decl = decls_[i]; 845 Declaration* decl = decls_[i];
748 VariableMode mode = decl->proxy()->var()->mode(); 846 VariableMode mode = decl->proxy()->var()->mode();
749 if (IsLexicalVariableMode(mode) && !is_block_scope()) continue; 847 if (IsLexicalVariableMode(mode) && !is_block_scope()) continue;
750 848
751 // Iterate through all scopes until and including the declaration scope. 849 // Iterate through all scopes until and including the declaration scope.
752 Scope* previous = NULL; 850 Scope* previous = NULL;
753 Scope* current = decl->scope(); 851 Scope* current = decl->scope();
(...skipping 862 matching lines...) Expand 10 before | Expand all | Expand 10 after
1616 function != nullptr && function->IsContextSlot(); 1714 function != nullptr && function->IsContextSlot();
1617 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - 1715 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() -
1618 (is_function_var_in_context ? 1 : 0); 1716 (is_function_var_in_context ? 1 : 0);
1619 } 1717 }
1620 1718
1621 1719
1622 int Scope::ContextGlobalCount() const { return num_global_slots(); } 1720 int Scope::ContextGlobalCount() const { return num_global_slots(); }
1623 1721
1624 } // namespace internal 1722 } // namespace internal
1625 } // namespace v8 1723 } // namespace v8
OLDNEW
« no previous file with comments | « src/ast/scopes.h ('k') | src/parsing/parser.cc » ('j') | src/parsing/parser.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698