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

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

Issue 2232633002: Function name variable does not need a VariableDeclaration (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebased Created 4 years, 4 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/parser.cc » ('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"
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after
326 VariableLocation location = VariableLocation::LOOKUP; 326 VariableLocation location = VariableLocation::LOOKUP;
327 Variable::Kind kind = Variable::NORMAL; 327 Variable::Kind kind = Variable::NORMAL;
328 328
329 Variable* result = variables_.Declare(zone(), this, name, mode, kind, 329 Variable* result = variables_.Declare(zone(), this, name, mode, kind,
330 init_flag, maybe_assigned_flag); 330 init_flag, maybe_assigned_flag);
331 result->AllocateTo(location, index); 331 result->AllocateTo(location, index);
332 } 332 }
333 333
334 // Internalize function proxy for this scope. 334 // Internalize function proxy for this scope.
335 if (scope_info_->HasFunctionName()) { 335 if (scope_info_->HasFunctionName()) {
336 AstNodeFactory factory(ast_value_factory);
337 Handle<String> name_handle(scope_info_->FunctionName(), isolate); 336 Handle<String> name_handle(scope_info_->FunctionName(), isolate);
338 const AstRawString* name = ast_value_factory->GetString(name_handle); 337 const AstRawString* name = ast_value_factory->GetString(name_handle);
339 VariableMode mode; 338 VariableMode mode;
340 int index = scope_info_->FunctionContextSlotIndex(*name_handle, &mode); 339 int index = scope_info_->FunctionContextSlotIndex(*name_handle, &mode);
341 if (index >= 0) { 340 if (index >= 0) {
342 Variable* result = new (zone()) 341 Variable* result = AsDeclarationScope()->DeclareFunctionVar(name);
343 Variable(this, name, mode, Variable::NORMAL, kCreatedInitialized); 342 DCHECK_EQ(mode, result->mode());
344 VariableProxy* proxy = factory.NewVariableProxy(result);
345 VariableDeclaration* declaration =
346 factory.NewVariableDeclaration(proxy, this, kNoSourcePosition);
347 AsDeclarationScope()->DeclareFunctionVar(declaration);
348 result->AllocateTo(VariableLocation::CONTEXT, index); 343 result->AllocateTo(VariableLocation::CONTEXT, index);
349 } 344 }
350 } 345 }
351 346
352 scope_info_ = Handle<ScopeInfo>::null(); 347 scope_info_ = Handle<ScopeInfo>::null();
353 } 348 }
354 349
355 DeclarationScope* Scope::AsDeclarationScope() { 350 DeclarationScope* Scope::AsDeclarationScope() {
356 DCHECK(is_declaration_scope()); 351 DCHECK(is_declaration_scope());
357 return static_cast<DeclarationScope*>(this); 352 return static_cast<DeclarationScope*>(this);
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 CONST, Variable::NORMAL, kCreatedInitialized); 418 CONST, Variable::NORMAL, kCreatedInitialized);
424 419
425 if (IsConciseMethod(function_kind_) || IsClassConstructor(function_kind_) || 420 if (IsConciseMethod(function_kind_) || IsClassConstructor(function_kind_) ||
426 IsAccessorFunction(function_kind_)) { 421 IsAccessorFunction(function_kind_)) {
427 this_function_ = variables_.Declare( 422 this_function_ = variables_.Declare(
428 zone(), this, ast_value_factory->this_function_string(), CONST, 423 zone(), this, ast_value_factory->this_function_string(), CONST,
429 Variable::NORMAL, kCreatedInitialized); 424 Variable::NORMAL, kCreatedInitialized);
430 } 425 }
431 } 426 }
432 427
428 Variable* DeclarationScope::DeclareFunctionVar(const AstRawString* name) {
429 DCHECK(is_function_scope());
430 DCHECK_NULL(function_);
431 VariableMode mode = is_strict(language_mode()) ? CONST : CONST_LEGACY;
432 function_ = new (zone())
433 Variable(this, name, mode, Variable::NORMAL, kCreatedInitialized);
434 return function_;
435 }
433 436
434 Scope* Scope::FinalizeBlockScope() { 437 Scope* Scope::FinalizeBlockScope() {
435 DCHECK(is_block_scope()); 438 DCHECK(is_block_scope());
436 439
437 if (variables_.occupancy() > 0 || 440 if (variables_.occupancy() > 0 ||
438 (is_declaration_scope() && calls_sloppy_eval())) { 441 (is_declaration_scope() && calls_sloppy_eval())) {
439 return this; 442 return this;
440 } 443 }
441 444
442 // Remove this scope from outer scope. 445 // Remove this scope from outer scope.
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
590 } 593 }
591 // TODO(marja, rossberg): Correctly declare FUNCTION, CLASS, NEW_TARGET, and 594 // TODO(marja, rossberg): Correctly declare FUNCTION, CLASS, NEW_TARGET, and
592 // ARGUMENTS bindings as their corresponding Variable::Kind. 595 // ARGUMENTS bindings as their corresponding Variable::Kind.
593 596
594 Variable* var = variables_.Declare(zone(), this, name, mode, kind, init_flag, 597 Variable* var = variables_.Declare(zone(), this, name, mode, kind, init_flag,
595 maybe_assigned_flag); 598 maybe_assigned_flag);
596 var->AllocateTo(location, index); 599 var->AllocateTo(location, index);
597 return var; 600 return var;
598 } 601 }
599 602
600 Variable* DeclarationScope::LookupFunctionVar(const AstRawString* name, 603 Variable* DeclarationScope::LookupFunctionVar(const AstRawString* name) {
601 AstNodeFactory* factory) { 604 if (function_ != nullptr && function_->raw_name() == name) {
602 if (function_ != NULL && function_->proxy()->raw_name() == name) { 605 return function_;
603 return function_->proxy()->var();
604 } else if (!scope_info_.is_null()) { 606 } else if (!scope_info_.is_null()) {
605 // If we are backed by a scope info, try to lookup the variable there. 607 // If we are backed by a scope info, try to lookup the variable there.
606 VariableMode mode; 608 VariableMode mode;
607 int index = scope_info_->FunctionContextSlotIndex(*(name->string()), &mode); 609 int index = scope_info_->FunctionContextSlotIndex(*(name->string()), &mode);
608 if (index < 0) return NULL; 610 if (index < 0) return nullptr;
609 Variable* var = new (zone()) 611 Variable* var = DeclareFunctionVar(name);
610 Variable(this, name, mode, Variable::NORMAL, kCreatedInitialized); 612 DCHECK_EQ(mode, var->mode());
611 DCHECK_NOT_NULL(factory);
612 VariableProxy* proxy = factory->NewVariableProxy(var);
613 VariableDeclaration* declaration =
614 factory->NewVariableDeclaration(proxy, this, kNoSourcePosition);
615 DCHECK_EQ(factory->zone(), zone());
616 DeclareFunctionVar(declaration);
617 var->AllocateTo(VariableLocation::CONTEXT, index); 613 var->AllocateTo(VariableLocation::CONTEXT, index);
618 return var; 614 return var;
619 } else { 615 } else {
620 return NULL; 616 return nullptr;
621 } 617 }
622 } 618 }
623 619
624 620
625 Variable* Scope::Lookup(const AstRawString* name) { 621 Variable* Scope::Lookup(const AstRawString* name) {
626 for (Scope* scope = this; 622 for (Scope* scope = this;
627 scope != NULL; 623 scope != NULL;
628 scope = scope->outer_scope()) { 624 scope = scope->outer_scope()) {
629 Variable* var = scope->LookupLocal(name); 625 Variable* var = scope->LookupLocal(name);
630 if (var != NULL) return var; 626 if (var != NULL) return var;
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
738 DCHECK(!already_resolved()); 734 DCHECK(!already_resolved());
739 decls_.Add(declaration, zone()); 735 decls_.Add(declaration, zone());
740 } 736 }
741 737
742 738
743 Declaration* Scope::CheckConflictingVarDeclarations() { 739 Declaration* Scope::CheckConflictingVarDeclarations() {
744 int length = decls_.length(); 740 int length = decls_.length();
745 for (int i = 0; i < length; i++) { 741 for (int i = 0; i < length; i++) {
746 Declaration* decl = decls_[i]; 742 Declaration* decl = decls_[i];
747 VariableMode mode = decl->proxy()->var()->mode(); 743 VariableMode mode = decl->proxy()->var()->mode();
748 // We don't create a separate scope to hold the function name of a function
749 // expression, so we have to make sure not to consider it when checking for
750 // conflicts (since it's conceptually "outside" the declaration scope).
751 if (is_function_scope() && decl == AsDeclarationScope()->function())
752 continue;
753 if (IsLexicalVariableMode(mode) && !is_block_scope()) continue; 744 if (IsLexicalVariableMode(mode) && !is_block_scope()) continue;
754 745
755 // Iterate through all scopes until and including the declaration scope. 746 // Iterate through all scopes until and including the declaration scope.
756 Scope* previous = NULL; 747 Scope* previous = NULL;
757 Scope* current = decl->scope(); 748 Scope* current = decl->scope();
758 // Lexical vs lexical conflicts within the same scope have already been 749 // Lexical vs lexical conflicts within the same scope have already been
759 // captured in Parser::Declare. The only conflicts we still need to check 750 // 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 751 // are lexical vs VAR, or any declarations within a declaration block scope
761 // vs lexical declarations in its surrounding (function) scope. 752 // vs lexical declarations in its surrounding (function) scope.
762 if (IsLexicalVariableMode(mode)) current = current->outer_scope_; 753 if (IsLexicalVariableMode(mode)) current = current->outer_scope_;
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after
1139 FunctionKind function_kind = is_function_scope() 1130 FunctionKind function_kind = is_function_scope()
1140 ? AsDeclarationScope()->function_kind() 1131 ? AsDeclarationScope()->function_kind()
1141 : kNormalFunction; 1132 : kNormalFunction;
1142 Indent(n0, Header(scope_type_, function_kind, is_declaration_scope())); 1133 Indent(n0, Header(scope_type_, function_kind, is_declaration_scope()));
1143 if (scope_name_ != nullptr && !scope_name_->IsEmpty()) { 1134 if (scope_name_ != nullptr && !scope_name_->IsEmpty()) {
1144 PrintF(" "); 1135 PrintF(" ");
1145 PrintName(scope_name_); 1136 PrintName(scope_name_);
1146 } 1137 }
1147 1138
1148 // Print parameters, if any. 1139 // Print parameters, if any.
1149 VariableDeclaration* function = nullptr; 1140 Variable* function = nullptr;
1150 if (is_function_scope()) { 1141 if (is_function_scope()) {
1151 AsDeclarationScope()->PrintParameters(); 1142 AsDeclarationScope()->PrintParameters();
1152 function = AsDeclarationScope()->function(); 1143 function = AsDeclarationScope()->function_var();
1153 } 1144 }
1154 1145
1155 PrintF(" { // (%d, %d)\n", start_position(), end_position()); 1146 PrintF(" { // (%d, %d)\n", start_position(), end_position());
1156 1147
1157 // Function name, if any (named function literals, only). 1148 // Function name, if any (named function literals, only).
1158 if (function != nullptr) { 1149 if (function != nullptr) {
1159 Indent(n1, "// (local) function name: "); 1150 Indent(n1, "// (local) function name: ");
1160 PrintName(function->proxy()->raw_name()); 1151 PrintName(function->raw_name());
1161 PrintF("\n"); 1152 PrintF("\n");
1162 } 1153 }
1163 1154
1164 // Scope info. 1155 // Scope info.
1165 if (HasTrivialOuterContext()) { 1156 if (HasTrivialOuterContext()) {
1166 Indent(n1, "// scope has trivial outer context\n"); 1157 Indent(n1, "// scope has trivial outer context\n");
1167 } 1158 }
1168 if (is_strict(language_mode())) { 1159 if (is_strict(language_mode())) {
1169 Indent(n1, "// strict mode scope\n"); 1160 Indent(n1, "// strict mode scope\n");
1170 } 1161 }
(...skipping 13 matching lines...) Expand all
1184 } 1175 }
1185 if (num_heap_slots_ > 0) { 1176 if (num_heap_slots_ > 0) {
1186 Indent(n1, "// "); 1177 Indent(n1, "// ");
1187 PrintF("%d heap slots (including %d global slots)\n", num_heap_slots_, 1178 PrintF("%d heap slots (including %d global slots)\n", num_heap_slots_,
1188 num_global_slots_); 1179 num_global_slots_);
1189 } 1180 }
1190 1181
1191 // Print locals. 1182 // Print locals.
1192 if (function != nullptr) { 1183 if (function != nullptr) {
1193 Indent(n1, "// function var:\n"); 1184 Indent(n1, "// function var:\n");
1194 PrintVar(n1, function->proxy()->var()); 1185 PrintVar(n1, function);
1195 } 1186 }
1196 1187
1197 if (is_declaration_scope()) { 1188 if (is_declaration_scope()) {
1198 bool printed_header = false; 1189 bool printed_header = false;
1199 ZoneList<Variable*>* temps = AsDeclarationScope()->temps(); 1190 ZoneList<Variable*>* temps = AsDeclarationScope()->temps();
1200 for (int i = 0; i < temps->length(); i++) { 1191 for (int i = 0; i < temps->length(); i++) {
1201 if ((*temps)[i] != nullptr) { 1192 if ((*temps)[i] != nullptr) {
1202 if (!printed_header) { 1193 if (!printed_header) {
1203 printed_header = true; 1194 printed_header = true;
1204 Indent(n1, "// temporary vars:\n"); 1195 Indent(n1, "// temporary vars:\n");
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
1286 // this scope which introduces the same variable again, the resulting 1277 // this scope which introduces the same variable again, the resulting
1287 // variable remains the same.) 1278 // variable remains the same.)
1288 if (var != NULL) { 1279 if (var != NULL) {
1289 *binding_kind = BOUND; 1280 *binding_kind = BOUND;
1290 return var; 1281 return var;
1291 } 1282 }
1292 1283
1293 // We did not find a variable locally. Check against the function variable, if 1284 // We did not find a variable locally. Check against the function variable, if
1294 // any. 1285 // any.
1295 *binding_kind = UNBOUND; 1286 *binding_kind = UNBOUND;
1296 var = 1287 var = is_function_scope()
1297 is_function_scope() 1288 ? AsDeclarationScope()->LookupFunctionVar(proxy->raw_name())
1298 ? AsDeclarationScope()->LookupFunctionVar(proxy->raw_name(), factory) 1289 : nullptr;
1299 : nullptr;
1300 if (var != NULL) { 1290 if (var != NULL) {
1301 *binding_kind = BOUND; 1291 *binding_kind = BOUND;
1302 } else if (outer_scope_ != nullptr && this != max_outer_scope) { 1292 } else if (outer_scope_ != nullptr && this != max_outer_scope) {
1303 var = outer_scope_->LookupRecursive(proxy, binding_kind, factory, 1293 var = outer_scope_->LookupRecursive(proxy, binding_kind, factory,
1304 max_outer_scope); 1294 max_outer_scope);
1305 if (*binding_kind == BOUND && is_function_scope()) { 1295 if (*binding_kind == BOUND && is_function_scope()) {
1306 var->ForceContextAllocation(); 1296 var->ForceContextAllocation();
1307 } 1297 }
1308 } else { 1298 } else {
1309 DCHECK(is_script_scope() || this == max_outer_scope); 1299 DCHECK(is_script_scope() || this == max_outer_scope);
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after
1690 AsDeclarationScope()->AllocateLocals(ast_value_factory); 1680 AsDeclarationScope()->AllocateLocals(ast_value_factory);
1691 } 1681 }
1692 } 1682 }
1693 1683
1694 void DeclarationScope::AllocateLocals(AstValueFactory* ast_value_factory) { 1684 void DeclarationScope::AllocateLocals(AstValueFactory* ast_value_factory) {
1695 // For now, function_ must be allocated at the very end. If it gets 1685 // For now, function_ must be allocated at the very end. If it gets
1696 // allocated in the context, it must be the last slot in the context, 1686 // allocated in the context, it must be the last slot in the context,
1697 // because of the current ScopeInfo implementation (see 1687 // because of the current ScopeInfo implementation (see
1698 // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor). 1688 // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor).
1699 if (function_ != nullptr) { 1689 if (function_ != nullptr) {
1700 AllocateNonParameterLocal(function_->proxy()->var(), ast_value_factory); 1690 AllocateNonParameterLocal(function_, ast_value_factory);
1701 } 1691 }
1702 1692
1703 if (rest_parameter_ != nullptr) { 1693 if (rest_parameter_ != nullptr) {
1704 AllocateNonParameterLocal(rest_parameter_, ast_value_factory); 1694 AllocateNonParameterLocal(rest_parameter_, ast_value_factory);
1705 } 1695 }
1706 1696
1707 if (new_target_ != nullptr && !MustAllocate(new_target_)) { 1697 if (new_target_ != nullptr && !MustAllocate(new_target_)) {
1708 new_target_ = nullptr; 1698 new_target_ = nullptr;
1709 } 1699 }
1710 1700
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1769 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && !must_have_context) { 1759 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && !must_have_context) {
1770 num_heap_slots_ = 0; 1760 num_heap_slots_ = 0;
1771 } 1761 }
1772 1762
1773 // Allocation done. 1763 // Allocation done.
1774 DCHECK(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); 1764 DCHECK(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS);
1775 } 1765 }
1776 1766
1777 1767
1778 int Scope::StackLocalCount() const { 1768 int Scope::StackLocalCount() const {
1779 VariableDeclaration* function = 1769 Variable* function =
1780 is_function_scope() ? AsDeclarationScope()->function() : nullptr; 1770 is_function_scope() ? AsDeclarationScope()->function_var() : nullptr;
1781 return num_stack_slots() - 1771 return num_stack_slots() -
1782 (function != NULL && function->proxy()->var()->IsStackLocal() ? 1 : 0); 1772 (function != nullptr && function->IsStackLocal() ? 1 : 0);
1783 } 1773 }
1784 1774
1785 1775
1786 int Scope::ContextLocalCount() const { 1776 int Scope::ContextLocalCount() const {
1787 if (num_heap_slots() == 0) return 0; 1777 if (num_heap_slots() == 0) return 0;
1788 VariableDeclaration* function = 1778 Variable* function =
1789 is_function_scope() ? AsDeclarationScope()->function() : nullptr; 1779 is_function_scope() ? AsDeclarationScope()->function_var() : nullptr;
1790 bool is_function_var_in_context = 1780 bool is_function_var_in_context =
1791 function != NULL && function->proxy()->var()->IsContextSlot(); 1781 function != nullptr && function->IsContextSlot();
1792 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - 1782 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() -
1793 (is_function_var_in_context ? 1 : 0); 1783 (is_function_var_in_context ? 1 : 0);
1794 } 1784 }
1795 1785
1796 1786
1797 int Scope::ContextGlobalCount() const { return num_global_slots(); } 1787 int Scope::ContextGlobalCount() const { return num_global_slots(); }
1798 1788
1799 } // namespace internal 1789 } // namespace internal
1800 } // namespace v8 1790 } // namespace v8
OLDNEW
« no previous file with comments | « src/ast/scopes.h ('k') | src/parsing/parser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698