| 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 #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 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 336 AstNodeFactory factory(ast_value_factory); | 336 AstNodeFactory factory(ast_value_factory); |
| 337 Handle<String> name_handle(scope_info_->FunctionName(), isolate); | 337 Handle<String> name_handle(scope_info_->FunctionName(), isolate); |
| 338 const AstRawString* name = ast_value_factory->GetString(name_handle); | 338 const AstRawString* name = ast_value_factory->GetString(name_handle); |
| 339 VariableMode mode; | 339 VariableMode mode; |
| 340 int index = scope_info_->FunctionContextSlotIndex(*name_handle, &mode); | 340 int index = scope_info_->FunctionContextSlotIndex(*name_handle, &mode); |
| 341 if (index >= 0) { | 341 if (index >= 0) { |
| 342 Variable* result = new (zone()) | 342 Variable* result = new (zone()) |
| 343 Variable(this, name, mode, Variable::NORMAL, kCreatedInitialized); | 343 Variable(this, name, mode, Variable::NORMAL, kCreatedInitialized); |
| 344 VariableProxy* proxy = factory.NewVariableProxy(result); | 344 VariableProxy* proxy = factory.NewVariableProxy(result); |
| 345 VariableDeclaration* declaration = | 345 VariableDeclaration* declaration = |
| 346 factory.NewVariableDeclaration(proxy, mode, this, kNoSourcePosition); | 346 factory.NewVariableDeclaration(proxy, this, kNoSourcePosition); |
| 347 AsDeclarationScope()->DeclareFunctionVar(declaration); | 347 AsDeclarationScope()->DeclareFunctionVar(declaration); |
| 348 result->AllocateTo(VariableLocation::CONTEXT, index); | 348 result->AllocateTo(VariableLocation::CONTEXT, index); |
| 349 } | 349 } |
| 350 } | 350 } |
| 351 | 351 |
| 352 scope_info_ = Handle<ScopeInfo>::null(); | 352 scope_info_ = Handle<ScopeInfo>::null(); |
| 353 } | 353 } |
| 354 | 354 |
| 355 DeclarationScope* Scope::AsDeclarationScope() { | 355 DeclarationScope* Scope::AsDeclarationScope() { |
| 356 DCHECK(is_declaration_scope()); | 356 DCHECK(is_declaration_scope()); |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 604 } else if (!scope_info_.is_null()) { | 604 } else if (!scope_info_.is_null()) { |
| 605 // If we are backed by a scope info, try to lookup the variable there. | 605 // If we are backed by a scope info, try to lookup the variable there. |
| 606 VariableMode mode; | 606 VariableMode mode; |
| 607 int index = scope_info_->FunctionContextSlotIndex(*(name->string()), &mode); | 607 int index = scope_info_->FunctionContextSlotIndex(*(name->string()), &mode); |
| 608 if (index < 0) return NULL; | 608 if (index < 0) return NULL; |
| 609 Variable* var = new (zone()) | 609 Variable* var = new (zone()) |
| 610 Variable(this, name, mode, Variable::NORMAL, kCreatedInitialized); | 610 Variable(this, name, mode, Variable::NORMAL, kCreatedInitialized); |
| 611 DCHECK_NOT_NULL(factory); | 611 DCHECK_NOT_NULL(factory); |
| 612 VariableProxy* proxy = factory->NewVariableProxy(var); | 612 VariableProxy* proxy = factory->NewVariableProxy(var); |
| 613 VariableDeclaration* declaration = | 613 VariableDeclaration* declaration = |
| 614 factory->NewVariableDeclaration(proxy, mode, this, kNoSourcePosition); | 614 factory->NewVariableDeclaration(proxy, this, kNoSourcePosition); |
| 615 DCHECK_EQ(factory->zone(), zone()); | 615 DCHECK_EQ(factory->zone(), zone()); |
| 616 DeclareFunctionVar(declaration); | 616 DeclareFunctionVar(declaration); |
| 617 var->AllocateTo(VariableLocation::CONTEXT, index); | 617 var->AllocateTo(VariableLocation::CONTEXT, index); |
| 618 return var; | 618 return var; |
| 619 } else { | 619 } else { |
| 620 return NULL; | 620 return NULL; |
| 621 } | 621 } |
| 622 } | 622 } |
| 623 | 623 |
| 624 | 624 |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 737 void Scope::AddDeclaration(Declaration* declaration) { | 737 void Scope::AddDeclaration(Declaration* declaration) { |
| 738 DCHECK(!already_resolved()); | 738 DCHECK(!already_resolved()); |
| 739 decls_.Add(declaration, zone()); | 739 decls_.Add(declaration, zone()); |
| 740 } | 740 } |
| 741 | 741 |
| 742 | 742 |
| 743 Declaration* Scope::CheckConflictingVarDeclarations() { | 743 Declaration* Scope::CheckConflictingVarDeclarations() { |
| 744 int length = decls_.length(); | 744 int length = decls_.length(); |
| 745 for (int i = 0; i < length; i++) { | 745 for (int i = 0; i < length; i++) { |
| 746 Declaration* decl = decls_[i]; | 746 Declaration* decl = decls_[i]; |
| 747 VariableMode mode = decl->proxy()->var()->mode(); |
| 747 // We don't create a separate scope to hold the function name of a function | 748 // We don't create a separate scope to hold the function name of a function |
| 748 // expression, so we have to make sure not to consider it when checking for | 749 // expression, so we have to make sure not to consider it when checking for |
| 749 // conflicts (since it's conceptually "outside" the declaration scope). | 750 // conflicts (since it's conceptually "outside" the declaration scope). |
| 750 if (is_function_scope() && decl == AsDeclarationScope()->function()) | 751 if (is_function_scope() && decl == AsDeclarationScope()->function()) |
| 751 continue; | 752 continue; |
| 752 if (IsLexicalVariableMode(decl->mode()) && !is_block_scope()) continue; | 753 if (IsLexicalVariableMode(mode) && !is_block_scope()) continue; |
| 753 const AstRawString* name = decl->proxy()->raw_name(); | |
| 754 | 754 |
| 755 // Iterate through all scopes until and including the declaration scope. | 755 // Iterate through all scopes until and including the declaration scope. |
| 756 Scope* previous = NULL; | 756 Scope* previous = NULL; |
| 757 Scope* current = decl->scope(); | 757 Scope* current = decl->scope(); |
| 758 // Lexical vs lexical conflicts within the same scope have already been | 758 // Lexical vs lexical conflicts within the same scope have already been |
| 759 // captured in Parser::Declare. The only conflicts we still need to check | 759 // captured in Parser::Declare. The only conflicts we still need to check |
| 760 // are lexical vs VAR, or any declarations within a declaration block scope | 760 // are lexical vs VAR, or any declarations within a declaration block scope |
| 761 // vs lexical declarations in its surrounding (function) scope. | 761 // vs lexical declarations in its surrounding (function) scope. |
| 762 if (IsLexicalVariableMode(decl->mode())) current = current->outer_scope_; | 762 if (IsLexicalVariableMode(mode)) current = current->outer_scope_; |
| 763 do { | 763 do { |
| 764 // There is a conflict if there exists a non-VAR binding. | 764 // There is a conflict if there exists a non-VAR binding. |
| 765 Variable* other_var = current->variables_.Lookup(name); | 765 Variable* other_var = |
| 766 current->variables_.Lookup(decl->proxy()->raw_name()); |
| 766 if (other_var != NULL && IsLexicalVariableMode(other_var->mode())) { | 767 if (other_var != NULL && IsLexicalVariableMode(other_var->mode())) { |
| 767 return decl; | 768 return decl; |
| 768 } | 769 } |
| 769 previous = current; | 770 previous = current; |
| 770 current = current->outer_scope_; | 771 current = current->outer_scope_; |
| 771 } while (!previous->is_declaration_scope()); | 772 } while (!previous->is_declaration_scope()); |
| 772 } | 773 } |
| 773 return NULL; | 774 return NULL; |
| 774 } | 775 } |
| 775 | 776 |
| (...skipping 1002 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1778 function != NULL && function->proxy()->var()->IsContextSlot(); | 1779 function != NULL && function->proxy()->var()->IsContextSlot(); |
| 1779 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - | 1780 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - |
| 1780 (is_function_var_in_context ? 1 : 0); | 1781 (is_function_var_in_context ? 1 : 0); |
| 1781 } | 1782 } |
| 1782 | 1783 |
| 1783 | 1784 |
| 1784 int Scope::ContextGlobalCount() const { return num_global_slots(); } | 1785 int Scope::ContextGlobalCount() const { return num_global_slots(); } |
| 1785 | 1786 |
| 1786 } // namespace internal | 1787 } // namespace internal |
| 1787 } // namespace v8 | 1788 } // namespace v8 |
| OLD | NEW |