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

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

Issue 1704223002: Remove strong mode support from Scope and Variable (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Remove test-parsing test Created 4 years, 10 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/ast/variables.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 "src/accessors.h" 7 #include "src/accessors.h"
8 #include "src/ast/scopeinfo.h" 8 #include "src/ast/scopeinfo.h"
9 #include "src/bootstrapper.h" 9 #include "src/bootstrapper.h"
10 #include "src/messages.h" 10 #include "src/messages.h"
11 #include "src/parsing/parser.h" // for ParseInfo 11 #include "src/parsing/parser.h" // for ParseInfo
12 12
13 namespace v8 { 13 namespace v8 {
14 namespace internal { 14 namespace internal {
15 15
16 // ---------------------------------------------------------------------------- 16 // ----------------------------------------------------------------------------
17 // Implementation of LocalsMap 17 // Implementation of LocalsMap
18 // 18 //
19 // Note: We are storing the handle locations as key values in the hash map. 19 // Note: We are storing the handle locations as key values in the hash map.
20 // When inserting a new variable via Declare(), we rely on the fact that 20 // When inserting a new variable via Declare(), we rely on the fact that
21 // the handle location remains alive for the duration of that variable 21 // the handle location remains alive for the duration of that variable
22 // use. Because a Variable holding a handle with the same location exists 22 // use. Because a Variable holding a handle with the same location exists
23 // this is ensured. 23 // this is ensured.
24 24
25 VariableMap::VariableMap(Zone* zone) 25 VariableMap::VariableMap(Zone* zone)
26 : ZoneHashMap(ZoneHashMap::PointersMatch, 8, ZoneAllocationPolicy(zone)), 26 : ZoneHashMap(ZoneHashMap::PointersMatch, 8, ZoneAllocationPolicy(zone)),
27 zone_(zone) {} 27 zone_(zone) {}
28 VariableMap::~VariableMap() {} 28 VariableMap::~VariableMap() {}
29 29
30
31 Variable* VariableMap::Declare(Scope* scope, const AstRawString* name, 30 Variable* VariableMap::Declare(Scope* scope, const AstRawString* name,
32 VariableMode mode, Variable::Kind kind, 31 VariableMode mode, Variable::Kind kind,
33 InitializationFlag initialization_flag, 32 InitializationFlag initialization_flag,
34 MaybeAssignedFlag maybe_assigned_flag, 33 MaybeAssignedFlag maybe_assigned_flag) {
35 int declaration_group_start) {
36 // AstRawStrings are unambiguous, i.e., the same string is always represented 34 // AstRawStrings are unambiguous, i.e., the same string is always represented
37 // by the same AstRawString*. 35 // by the same AstRawString*.
38 // FIXME(marja): fix the type of Lookup. 36 // FIXME(marja): fix the type of Lookup.
39 Entry* p = 37 Entry* p =
40 ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->hash(), 38 ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->hash(),
41 ZoneAllocationPolicy(zone())); 39 ZoneAllocationPolicy(zone()));
42 if (p->value == NULL) { 40 if (p->value == NULL) {
43 // The variable has not been declared yet -> insert it. 41 // The variable has not been declared yet -> insert it.
44 DCHECK(p->key == name); 42 DCHECK(p->key == name);
45 if (kind == Variable::CLASS) { 43 p->value = new (zone()) Variable(scope, name, mode, kind,
46 p->value = new (zone()) 44 initialization_flag, maybe_assigned_flag);
47 ClassVariable(scope, name, mode, initialization_flag,
48 maybe_assigned_flag, declaration_group_start);
49 } else {
50 p->value = new (zone()) Variable(
51 scope, name, mode, kind, initialization_flag, maybe_assigned_flag);
52 }
53 } 45 }
54 return reinterpret_cast<Variable*>(p->value); 46 return reinterpret_cast<Variable*>(p->value);
55 } 47 }
56 48
57 49
58 Variable* VariableMap::Lookup(const AstRawString* name) { 50 Variable* VariableMap::Lookup(const AstRawString* name) {
59 Entry* p = ZoneHashMap::Lookup(const_cast<AstRawString*>(name), name->hash()); 51 Entry* p = ZoneHashMap::Lookup(const_cast<AstRawString*>(name), name->hash());
60 if (p != NULL) { 52 if (p != NULL) {
61 DCHECK(reinterpret_cast<const AstRawString*>(p->key) == name); 53 DCHECK(reinterpret_cast<const AstRawString*>(p->key) == name);
62 DCHECK(p->value != NULL); 54 DCHECK(p->value != NULL);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
96 variables_(zone), 88 variables_(zone),
97 temps_(4, zone), 89 temps_(4, zone),
98 params_(4, zone), 90 params_(4, zone),
99 unresolved_(16, zone), 91 unresolved_(16, zone),
100 decls_(4, zone), 92 decls_(4, zone),
101 module_descriptor_( 93 module_descriptor_(
102 scope_type == MODULE_SCOPE ? ModuleDescriptor::New(zone) : NULL), 94 scope_type == MODULE_SCOPE ? ModuleDescriptor::New(zone) : NULL),
103 sloppy_block_function_map_(zone), 95 sloppy_block_function_map_(zone),
104 already_resolved_(false), 96 already_resolved_(false),
105 ast_value_factory_(ast_value_factory), 97 ast_value_factory_(ast_value_factory),
106 zone_(zone), 98 zone_(zone) {
107 class_declaration_group_start_(-1) {
108 SetDefaults(scope_type, outer_scope, Handle<ScopeInfo>::null(), 99 SetDefaults(scope_type, outer_scope, Handle<ScopeInfo>::null(),
109 function_kind); 100 function_kind);
110 // The outermost scope must be a script scope. 101 // The outermost scope must be a script scope.
111 DCHECK(scope_type == SCRIPT_SCOPE || outer_scope != NULL); 102 DCHECK(scope_type == SCRIPT_SCOPE || outer_scope != NULL);
112 DCHECK(!HasIllegalRedeclaration()); 103 DCHECK(!HasIllegalRedeclaration());
113 } 104 }
114 105
115
116 Scope::Scope(Zone* zone, Scope* inner_scope, ScopeType scope_type, 106 Scope::Scope(Zone* zone, Scope* inner_scope, ScopeType scope_type,
117 Handle<ScopeInfo> scope_info, AstValueFactory* value_factory) 107 Handle<ScopeInfo> scope_info, AstValueFactory* value_factory)
118 : inner_scopes_(4, zone), 108 : inner_scopes_(4, zone),
119 variables_(zone), 109 variables_(zone),
120 temps_(4, zone), 110 temps_(4, zone),
121 params_(4, zone), 111 params_(4, zone),
122 unresolved_(16, zone), 112 unresolved_(16, zone),
123 decls_(4, zone), 113 decls_(4, zone),
124 module_descriptor_(NULL), 114 module_descriptor_(NULL),
125 sloppy_block_function_map_(zone), 115 sloppy_block_function_map_(zone),
126 already_resolved_(true), 116 already_resolved_(true),
127 ast_value_factory_(value_factory), 117 ast_value_factory_(value_factory),
128 zone_(zone), 118 zone_(zone) {
129 class_declaration_group_start_(-1) {
130 SetDefaults(scope_type, NULL, scope_info); 119 SetDefaults(scope_type, NULL, scope_info);
131 if (!scope_info.is_null()) { 120 if (!scope_info.is_null()) {
132 num_heap_slots_ = scope_info_->ContextLength(); 121 num_heap_slots_ = scope_info_->ContextLength();
133 } 122 }
134 // Ensure at least MIN_CONTEXT_SLOTS to indicate a materialized context. 123 // Ensure at least MIN_CONTEXT_SLOTS to indicate a materialized context.
135 num_heap_slots_ = Max(num_heap_slots_, 124 num_heap_slots_ = Max(num_heap_slots_,
136 static_cast<int>(Context::MIN_CONTEXT_SLOTS)); 125 static_cast<int>(Context::MIN_CONTEXT_SLOTS));
137 AddInnerScope(inner_scope); 126 AddInnerScope(inner_scope);
138 } 127 }
139 128
140
141 Scope::Scope(Zone* zone, Scope* inner_scope, 129 Scope::Scope(Zone* zone, Scope* inner_scope,
142 const AstRawString* catch_variable_name, 130 const AstRawString* catch_variable_name,
143 AstValueFactory* value_factory) 131 AstValueFactory* value_factory)
144 : inner_scopes_(1, zone), 132 : inner_scopes_(1, zone),
145 variables_(zone), 133 variables_(zone),
146 temps_(0, zone), 134 temps_(0, zone),
147 params_(0, zone), 135 params_(0, zone),
148 unresolved_(0, zone), 136 unresolved_(0, zone),
149 decls_(0, zone), 137 decls_(0, zone),
150 module_descriptor_(NULL), 138 module_descriptor_(NULL),
151 sloppy_block_function_map_(zone), 139 sloppy_block_function_map_(zone),
152 already_resolved_(true), 140 already_resolved_(true),
153 ast_value_factory_(value_factory), 141 ast_value_factory_(value_factory),
154 zone_(zone), 142 zone_(zone) {
155 class_declaration_group_start_(-1) {
156 SetDefaults(CATCH_SCOPE, NULL, Handle<ScopeInfo>::null()); 143 SetDefaults(CATCH_SCOPE, NULL, Handle<ScopeInfo>::null());
157 AddInnerScope(inner_scope); 144 AddInnerScope(inner_scope);
158 ++num_var_or_const_; 145 ++num_var_or_const_;
159 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; 146 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS;
160 Variable* variable = variables_.Declare(this, 147 Variable* variable = variables_.Declare(this,
161 catch_variable_name, 148 catch_variable_name,
162 VAR, 149 VAR,
163 Variable::NORMAL, 150 Variable::NORMAL,
164 kCreatedInitialized); 151 kCreatedInitialized);
165 AllocateHeapSlot(variable); 152 AllocateHeapSlot(variable);
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after
521 } 508 }
522 if (is_rest) { 509 if (is_rest) {
523 DCHECK_NULL(rest_parameter_); 510 DCHECK_NULL(rest_parameter_);
524 rest_parameter_ = var; 511 rest_parameter_ = var;
525 rest_index_ = num_parameters(); 512 rest_index_ = num_parameters();
526 } 513 }
527 params_.Add(var, zone()); 514 params_.Add(var, zone());
528 return var; 515 return var;
529 } 516 }
530 517
531
532 Variable* Scope::DeclareLocal(const AstRawString* name, VariableMode mode, 518 Variable* Scope::DeclareLocal(const AstRawString* name, VariableMode mode,
533 InitializationFlag init_flag, Variable::Kind kind, 519 InitializationFlag init_flag, Variable::Kind kind,
534 MaybeAssignedFlag maybe_assigned_flag, 520 MaybeAssignedFlag maybe_assigned_flag) {
535 int declaration_group_start) {
536 DCHECK(!already_resolved()); 521 DCHECK(!already_resolved());
537 // This function handles VAR, LET, and CONST modes. DYNAMIC variables are 522 // This function handles VAR, LET, and CONST modes. DYNAMIC variables are
538 // introduces during variable allocation, and TEMPORARY variables are 523 // introduces during variable allocation, and TEMPORARY variables are
539 // allocated via NewTemporary(). 524 // allocated via NewTemporary().
540 DCHECK(IsDeclaredVariableMode(mode)); 525 DCHECK(IsDeclaredVariableMode(mode));
541 ++num_var_or_const_; 526 ++num_var_or_const_;
542 return variables_.Declare(this, name, mode, kind, init_flag, 527 return variables_.Declare(this, name, mode, kind, init_flag,
543 maybe_assigned_flag, declaration_group_start); 528 maybe_assigned_flag);
544 } 529 }
545 530
546 531
547 Variable* Scope::DeclareDynamicGlobal(const AstRawString* name) { 532 Variable* Scope::DeclareDynamicGlobal(const AstRawString* name) {
548 DCHECK(is_script_scope()); 533 DCHECK(is_script_scope());
549 return variables_.Declare(this, 534 return variables_.Declare(this,
550 name, 535 name,
551 DYNAMIC_GLOBAL, 536 DYNAMIC_GLOBAL,
552 Variable::NORMAL, 537 Variable::NORMAL,
553 kCreatedInitialized); 538 kCreatedInitialized);
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
653 int order() const { return order_; } 638 int order() const { return order_; }
654 static int Compare(const VarAndOrder* a, const VarAndOrder* b) { 639 static int Compare(const VarAndOrder* a, const VarAndOrder* b) {
655 return a->order_ - b->order_; 640 return a->order_ - b->order_;
656 } 641 }
657 642
658 private: 643 private:
659 Variable* var_; 644 Variable* var_;
660 int order_; 645 int order_;
661 }; 646 };
662 647
663 648 void Scope::CollectStackAndContextLocals(ZoneList<Variable*>* stack_locals,
664 void Scope::CollectStackAndContextLocals( 649 ZoneList<Variable*>* context_locals,
665 ZoneList<Variable*>* stack_locals, ZoneList<Variable*>* context_locals, 650 ZoneList<Variable*>* context_globals) {
666 ZoneList<Variable*>* context_globals,
667 ZoneList<Variable*>* strong_mode_free_variables) {
668 DCHECK(stack_locals != NULL); 651 DCHECK(stack_locals != NULL);
669 DCHECK(context_locals != NULL); 652 DCHECK(context_locals != NULL);
670 DCHECK(context_globals != NULL); 653 DCHECK(context_globals != NULL);
671 654
672 // Collect temporaries which are always allocated on the stack, unless the 655 // Collect temporaries which are always allocated on the stack, unless the
673 // context as a whole has forced context allocation. 656 // context as a whole has forced context allocation.
674 for (int i = 0; i < temps_.length(); i++) { 657 for (int i = 0; i < temps_.length(); i++) {
675 Variable* var = temps_[i]; 658 Variable* var = temps_[i];
676 if (var->is_used()) { 659 if (var->is_used()) {
677 if (var->IsContextSlot()) { 660 if (var->IsContextSlot()) {
678 DCHECK(has_forced_context_allocation()); 661 DCHECK(has_forced_context_allocation());
679 context_locals->Add(var, zone()); 662 context_locals->Add(var, zone());
680 } else if (var->IsStackLocal()) { 663 } else if (var->IsStackLocal()) {
681 stack_locals->Add(var, zone()); 664 stack_locals->Add(var, zone());
682 } else { 665 } else {
683 DCHECK(var->IsParameter()); 666 DCHECK(var->IsParameter());
684 } 667 }
685 } 668 }
686 } 669 }
687 670
688 // Collect declared local variables. 671 // Collect declared local variables.
689 ZoneList<VarAndOrder> vars(variables_.occupancy(), zone()); 672 ZoneList<VarAndOrder> vars(variables_.occupancy(), zone());
690 for (VariableMap::Entry* p = variables_.Start(); 673 for (VariableMap::Entry* p = variables_.Start();
691 p != NULL; 674 p != NULL;
692 p = variables_.Next(p)) { 675 p = variables_.Next(p)) {
693 Variable* var = reinterpret_cast<Variable*>(p->value); 676 Variable* var = reinterpret_cast<Variable*>(p->value);
694 if (strong_mode_free_variables && var->has_strong_mode_reference() &&
695 var->mode() == DYNAMIC_GLOBAL) {
696 strong_mode_free_variables->Add(var, zone());
697 }
698
699 if (var->is_used()) { 677 if (var->is_used()) {
700 vars.Add(VarAndOrder(var, p->order), zone()); 678 vars.Add(VarAndOrder(var, p->order), zone());
701 } 679 }
702 } 680 }
703 vars.Sort(VarAndOrder::Compare); 681 vars.Sort(VarAndOrder::Compare);
704 int var_count = vars.length(); 682 int var_count = vars.length();
705 for (int i = 0; i < var_count; i++) { 683 for (int i = 0; i < var_count; i++) {
706 Variable* var = vars[i].var(); 684 Variable* var = vars[i].var();
707 if (var->IsStackLocal()) { 685 if (var->IsStackLocal()) {
708 stack_locals->Add(var, zone()); 686 stack_locals->Add(var, zone());
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after
1010 if (function_ != NULL) { 988 if (function_ != NULL) {
1011 Indent(n1, "// (local) function name: "); 989 Indent(n1, "// (local) function name: ");
1012 PrintName(function_->proxy()->raw_name()); 990 PrintName(function_->proxy()->raw_name());
1013 PrintF("\n"); 991 PrintF("\n");
1014 } 992 }
1015 993
1016 // Scope info. 994 // Scope info.
1017 if (HasTrivialOuterContext()) { 995 if (HasTrivialOuterContext()) {
1018 Indent(n1, "// scope has trivial outer context\n"); 996 Indent(n1, "// scope has trivial outer context\n");
1019 } 997 }
1020 if (is_strong(language_mode())) { 998 if (is_strict(language_mode())) {
1021 Indent(n1, "// strong mode scope\n");
1022 } else if (is_strict(language_mode())) {
1023 Indent(n1, "// strict mode scope\n"); 999 Indent(n1, "// strict mode scope\n");
1024 } 1000 }
1025 if (scope_inside_with_) Indent(n1, "// scope inside 'with'\n"); 1001 if (scope_inside_with_) Indent(n1, "// scope inside 'with'\n");
1026 if (scope_contains_with_) Indent(n1, "// scope contains 'with'\n"); 1002 if (scope_contains_with_) Indent(n1, "// scope contains 'with'\n");
1027 if (scope_calls_eval_) Indent(n1, "// scope calls 'eval'\n"); 1003 if (scope_calls_eval_) Indent(n1, "// scope calls 'eval'\n");
1028 if (scope_uses_arguments_) Indent(n1, "// scope uses 'arguments'\n"); 1004 if (scope_uses_arguments_) Indent(n1, "// scope uses 'arguments'\n");
1029 if (scope_uses_super_property_) 1005 if (scope_uses_super_property_)
1030 Indent(n1, "// scope uses 'super' property\n"); 1006 Indent(n1, "// scope uses 'super' property\n");
1031 if (outer_scope_calls_sloppy_eval_) { 1007 if (outer_scope_calls_sloppy_eval_) {
1032 Indent(n1, "// outer scope calls 'eval' in sloppy context\n"); 1008 Indent(n1, "// outer scope calls 'eval' in sloppy context\n");
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
1197 VariableLocation location = var->location(); 1173 VariableLocation location = var->location();
1198 CHECK(location == VariableLocation::LOCAL || 1174 CHECK(location == VariableLocation::LOCAL ||
1199 location == VariableLocation::CONTEXT || 1175 location == VariableLocation::CONTEXT ||
1200 location == VariableLocation::PARAMETER || 1176 location == VariableLocation::PARAMETER ||
1201 location == VariableLocation::UNALLOCATED); 1177 location == VariableLocation::UNALLOCATED);
1202 } 1178 }
1203 #endif 1179 #endif
1204 1180
1205 switch (binding_kind) { 1181 switch (binding_kind) {
1206 case BOUND: 1182 case BOUND:
1207 // We found a variable binding.
1208 if (is_strong(language_mode())) {
1209 if (!CheckStrongModeDeclaration(proxy, var)) return false;
1210 }
1211 break; 1183 break;
1212 1184
1213 case BOUND_EVAL_SHADOWED: 1185 case BOUND_EVAL_SHADOWED:
1214 // We either found a variable binding that might be shadowed by eval or 1186 // We either found a variable binding that might be shadowed by eval or
1215 // gave up on it (e.g. by encountering a local with the same in the outer 1187 // gave up on it (e.g. by encountering a local with the same in the outer
1216 // scope which was not promoted to a context, this can happen if we use 1188 // scope which was not promoted to a context, this can happen if we use
1217 // debugger to evaluate arbitrary expressions at a break point). 1189 // debugger to evaluate arbitrary expressions at a break point).
1218 if (var->IsGlobalObjectProperty()) { 1190 if (var->IsGlobalObjectProperty()) {
1219 var = NonLocal(proxy->raw_name(), DYNAMIC_GLOBAL); 1191 var = NonLocal(proxy->raw_name(), DYNAMIC_GLOBAL);
1220 } else if (var->is_dynamic()) { 1192 } else if (var->is_dynamic()) {
(...skipping 17 matching lines...) Expand all
1238 1210
1239 case DYNAMIC_LOOKUP: 1211 case DYNAMIC_LOOKUP:
1240 // The variable could not be resolved statically. 1212 // The variable could not be resolved statically.
1241 var = NonLocal(proxy->raw_name(), DYNAMIC); 1213 var = NonLocal(proxy->raw_name(), DYNAMIC);
1242 break; 1214 break;
1243 } 1215 }
1244 1216
1245 DCHECK(var != NULL); 1217 DCHECK(var != NULL);
1246 if (proxy->is_assigned()) var->set_maybe_assigned(); 1218 if (proxy->is_assigned()) var->set_maybe_assigned();
1247 1219
1248 if (is_strong(language_mode())) {
1249 // Record that the variable is referred to from strong mode. Also, record
1250 // the position.
1251 var->RecordStrongModeReference(proxy->position(), proxy->end_position());
1252 }
1253
1254 proxy->BindTo(var); 1220 proxy->BindTo(var);
1255 1221
1256 return true; 1222 return true;
1257 } 1223 }
1258 1224
1259 1225
1260 bool Scope::CheckStrongModeDeclaration(VariableProxy* proxy, Variable* var) {
1261 // Check for declaration-after use (for variables) in strong mode. Note that
1262 // we can only do this in the case where we have seen the declaration. And we
1263 // always allow referencing functions (for now).
1264
1265 // This might happen during lazy compilation; we don't keep track of
1266 // initializer positions for variables stored in ScopeInfo, so we cannot check
1267 // bindings against them. TODO(marja, rossberg): remove this hack.
1268 if (var->initializer_position() == RelocInfo::kNoPosition) return true;
1269
1270 // Allow referencing the class name from methods of that class, even though
1271 // the initializer position for class names is only after the body.
1272 Scope* scope = this;
1273 while (scope) {
1274 if (scope->ClassVariableForMethod() == var) return true;
1275 scope = scope->outer_scope();
1276 }
1277
1278 // Allow references from methods to classes declared later, if we detect no
1279 // problematic dependency cycles. Note that we can be inside multiple methods
1280 // at the same time, and it's enough if we find one where the reference is
1281 // allowed.
1282 if (var->is_class() &&
1283 var->AsClassVariable()->declaration_group_start() >= 0) {
1284 for (scope = this; scope && scope != var->scope();
1285 scope = scope->outer_scope()) {
1286 ClassVariable* class_var = scope->ClassVariableForMethod();
1287 // A method is referring to some other class, possibly declared
1288 // later. Referring to a class declared earlier is always OK and covered
1289 // by the code outside this if. Here we only need to allow special cases
1290 // for referring to a class which is declared later.
1291
1292 // Referring to a class C declared later is OK under the following
1293 // circumstances:
1294
1295 // 1. The class declarations are in a consecutive group with no other
1296 // declarations or statements in between, and
1297
1298 // 2. There is no dependency cycle where the first edge is an
1299 // initialization time dependency (computed property name or extends
1300 // clause) from C to something that depends on this class directly or
1301 // transitively.
1302 if (class_var &&
1303 class_var->declaration_group_start() ==
1304 var->AsClassVariable()->declaration_group_start()) {
1305 return true;
1306 }
1307
1308 // TODO(marja,rossberg): implement the dependency cycle detection. Here we
1309 // undershoot the target and allow referring to any class in the same
1310 // consectuive declaration group.
1311
1312 // The cycle detection can work roughly like this: 1) detect init-time
1313 // references here (they are free variables which are inside the class
1314 // scope but not inside a method scope - no parser changes needed to
1315 // detect them) 2) if we encounter an init-time reference here, allow it,
1316 // but record it for a later dependency cycle check 3) also record
1317 // non-init-time references here 4) after scope analysis is done, analyse
1318 // the dependency cycles: an illegal cycle is one starting with an
1319 // init-time reference and leading back to the starting point with either
1320 // non-init-time and init-time references.
1321 }
1322 }
1323
1324 // If both the use and the declaration are inside an eval scope (possibly
1325 // indirectly), or one of them is, we need to check whether they are inside
1326 // the same eval scope or different ones.
1327
1328 // TODO(marja,rossberg): Detect errors across different evals (depends on the
1329 // future of eval in strong mode).
1330 const Scope* eval_for_use = NearestOuterEvalScope();
1331 const Scope* eval_for_declaration = var->scope()->NearestOuterEvalScope();
1332
1333 if (proxy->position() != RelocInfo::kNoPosition &&
1334 proxy->position() < var->initializer_position() && !var->is_function() &&
1335 eval_for_use == eval_for_declaration) {
1336 DCHECK(proxy->end_position() != RelocInfo::kNoPosition);
1337 ReportMessage(proxy->position(), proxy->end_position(),
1338 MessageTemplate::kStrongUseBeforeDeclaration,
1339 proxy->raw_name());
1340 return false;
1341 }
1342 return true;
1343 }
1344
1345
1346 ClassVariable* Scope::ClassVariableForMethod() const {
1347 // TODO(marja, rossberg): This fails to find a class variable in the following
1348 // cases:
1349 // let A = class { ... }
1350 // It needs to be investigated whether this causes any practical problems.
1351 if (!is_function_scope()) return nullptr;
1352 if (IsInObjectLiteral(function_kind_)) return nullptr;
1353 if (!IsConciseMethod(function_kind_) && !IsClassConstructor(function_kind_) &&
1354 !IsAccessorFunction(function_kind_)) {
1355 return nullptr;
1356 }
1357 DCHECK_NOT_NULL(outer_scope_);
1358 // The class scope contains at most one variable, the class name.
1359 DCHECK(outer_scope_->variables_.occupancy() <= 1);
1360 if (outer_scope_->variables_.occupancy() == 0) return nullptr;
1361 VariableMap::Entry* p = outer_scope_->variables_.Start();
1362 Variable* var = reinterpret_cast<Variable*>(p->value);
1363 if (!var->is_class()) return nullptr;
1364 return var->AsClassVariable();
1365 }
1366
1367
1368 bool Scope::ResolveVariablesRecursively(ParseInfo* info, 1226 bool Scope::ResolveVariablesRecursively(ParseInfo* info,
1369 AstNodeFactory* factory) { 1227 AstNodeFactory* factory) {
1370 DCHECK(info->script_scope()->is_script_scope()); 1228 DCHECK(info->script_scope()->is_script_scope());
1371 1229
1372 // Resolve unresolved variables for this scope. 1230 // Resolve unresolved variables for this scope.
1373 for (int i = 0; i < unresolved_.length(); i++) { 1231 for (int i = 0; i < unresolved_.length(); i++) {
1374 if (!ResolveVariable(info, unresolved_[i], factory)) return false; 1232 if (!ResolveVariable(info, unresolved_[i], factory)) return false;
1375 } 1233 }
1376 1234
1377 // Resolve unresolved variables for inner scopes. 1235 // Resolve unresolved variables for inner scopes.
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after
1689 function_ != NULL && function_->proxy()->var()->IsContextSlot(); 1547 function_ != NULL && function_->proxy()->var()->IsContextSlot();
1690 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - 1548 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() -
1691 (is_function_var_in_context ? 1 : 0); 1549 (is_function_var_in_context ? 1 : 0);
1692 } 1550 }
1693 1551
1694 1552
1695 int Scope::ContextGlobalCount() const { return num_global_slots(); } 1553 int Scope::ContextGlobalCount() const { return num_global_slots(); }
1696 1554
1697 } // namespace internal 1555 } // namespace internal
1698 } // namespace v8 1556 } // namespace v8
OLDNEW
« no previous file with comments | « src/ast/scopes.h ('k') | src/ast/variables.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698