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/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/bootstrapper.h" | 8 #include "src/bootstrapper.h" |
9 #include "src/messages.h" | 9 #include "src/messages.h" |
10 #include "src/parser.h" | 10 #include "src/parser.h" |
(...skipping 1150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1161 | 1161 |
1162 // Allow references from methods to classes declared later, if we detect no | 1162 // Allow references from methods to classes declared later, if we detect no |
1163 // problematic dependency cycles. Note that we can be inside multiple methods | 1163 // problematic dependency cycles. Note that we can be inside multiple methods |
1164 // at the same time, and it's enough if we find one where the reference is | 1164 // at the same time, and it's enough if we find one where the reference is |
1165 // allowed. | 1165 // allowed. |
1166 if (var->is_class() && | 1166 if (var->is_class() && |
1167 var->AsClassVariable()->declaration_group_start() >= 0) { | 1167 var->AsClassVariable()->declaration_group_start() >= 0) { |
1168 for (scope = this; scope && scope != var->scope(); | 1168 for (scope = this; scope && scope != var->scope(); |
1169 scope = scope->outer_scope()) { | 1169 scope = scope->outer_scope()) { |
1170 ClassVariable* class_var = scope->ClassVariableForMethod(); | 1170 ClassVariable* class_var = scope->ClassVariableForMethod(); |
1171 if (class_var) { | 1171 // A method is referring to some other class, possibly declared |
1172 // A method is referring to some other class, possibly declared | 1172 // later. Referring to a class declared earlier is always OK and covered |
1173 // later. Referring to a class declared earlier is always OK and covered | 1173 // by the code outside this if. Here we only need to allow special cases |
1174 // by the code outside this if. Here we only need to allow special cases | 1174 // for referring to a class which is declared later. |
1175 // for referring to a class which is declared later. | |
1176 | 1175 |
1177 // Referring to a class C declared later is OK under the following | 1176 // Referring to a class C declared later is OK under the following |
1178 // circumstances: | 1177 // circumstances: |
1179 | 1178 |
1180 // 1. The class declarations are in a consecutive group with no other | 1179 // 1. The class declarations are in a consecutive group with no other |
1181 // declarations or statements in between, and | 1180 // declarations or statements in between, and |
1182 | 1181 |
1183 // 2. There is no dependency cycle where the first edge is an | 1182 // 2. There is no dependency cycle where the first edge is an |
1184 // initialization time dependency (computed property name or extends | 1183 // initialization time dependency (computed property name or extends |
1185 // clause) from C to something that depends on this class directly or | 1184 // clause) from C to something that depends on this class directly or |
1186 // transitively. | 1185 // transitively. |
| 1186 if (class_var && |
| 1187 class_var->declaration_group_start() == |
| 1188 var->AsClassVariable()->declaration_group_start()) { |
| 1189 return true; |
| 1190 } |
1187 | 1191 |
1188 // This is needed because a class ("class Name { }") creates two | 1192 // TODO(marja,rossberg): implement the dependency cycle detection. Here we |
1189 // bindings (one in the outer scope, and one in the class scope). The | 1193 // undershoot the target and allow referring to any class in the same |
1190 // method is a function scope inside the inner scope (class scope). The | 1194 // consectuive declaration group. |
1191 // consecutive class declarations are in the outer scope. | |
1192 class_var = class_var->corresponding_outer_class_variable(); | |
1193 if (class_var && | |
1194 class_var->declaration_group_start() == | |
1195 var->AsClassVariable()->declaration_group_start()) { | |
1196 return true; | |
1197 } | |
1198 | 1195 |
1199 // TODO(marja,rossberg): implement the dependency cycle detection. Here | 1196 // The cycle detection can work roughly like this: 1) detect init-time |
1200 // we undershoot the target and allow referring to any class in the same | 1197 // references here (they are free variables which are inside the class |
1201 // consectuive declaration group. | 1198 // scope but not inside a method scope - no parser changes needed to |
1202 | 1199 // detect them) 2) if we encounter an init-time reference here, allow it, |
1203 // The cycle detection can work roughly like this: 1) detect init-time | 1200 // but record it for a later dependency cycle check 3) also record |
1204 // references here (they are free variables which are inside the class | 1201 // non-init-time references here 4) after scope analysis is done, analyse |
1205 // scope but not inside a method scope - no parser changes needed to | 1202 // the dependency cycles: an illegal cycle is one starting with an |
1206 // detect them) 2) if we encounter an init-time reference here, allow | 1203 // init-time reference and leading back to the starting point with either |
1207 // it, but record it for a later dependency cycle check 3) also record | 1204 // non-init-time and init-time references. |
1208 // non-init-time references here 4) after scope analysis is done, | |
1209 // analyse the dependency cycles: an illegal cycle is one starting with | |
1210 // an init-time reference and leading back to the starting point with | |
1211 // either non-init-time and init-time references. | |
1212 } | |
1213 } | 1205 } |
1214 } | 1206 } |
1215 | 1207 |
1216 // If both the use and the declaration are inside an eval scope (possibly | 1208 // If both the use and the declaration are inside an eval scope (possibly |
1217 // indirectly), or one of them is, we need to check whether they are inside | 1209 // indirectly), or one of them is, we need to check whether they are inside |
1218 // the same eval scope or different ones. | 1210 // the same eval scope or different ones. |
1219 | 1211 |
1220 // TODO(marja,rossberg): Detect errors across different evals (depends on the | 1212 // TODO(marja,rossberg): Detect errors across different evals (depends on the |
1221 // future of eval in strong mode). | 1213 // future of eval in strong mode). |
1222 const Scope* eval_for_use = NearestOuterEvalScope(); | 1214 const Scope* eval_for_use = NearestOuterEvalScope(); |
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1551 (function_ != NULL && function_->proxy()->var()->IsStackLocal() ? 1 : 0); | 1543 (function_ != NULL && function_->proxy()->var()->IsStackLocal() ? 1 : 0); |
1552 } | 1544 } |
1553 | 1545 |
1554 | 1546 |
1555 int Scope::ContextLocalCount() const { | 1547 int Scope::ContextLocalCount() const { |
1556 if (num_heap_slots() == 0) return 0; | 1548 if (num_heap_slots() == 0) return 0; |
1557 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - | 1549 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - |
1558 (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0); | 1550 (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0); |
1559 } | 1551 } |
1560 } } // namespace v8::internal | 1552 } } // namespace v8::internal |
OLD | NEW |