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 1120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1131 // always allow referencing functions (for now). | 1131 // always allow referencing functions (for now). |
1132 | 1132 |
1133 // Allow referencing the class name from methods of that class, even though | 1133 // Allow referencing the class name from methods of that class, even though |
1134 // the initializer position for class names is only after the body. | 1134 // the initializer position for class names is only after the body. |
1135 Scope* scope = this; | 1135 Scope* scope = this; |
1136 while (scope) { | 1136 while (scope) { |
1137 if (scope->ClassVariableForMethod() == var) return true; | 1137 if (scope->ClassVariableForMethod() == var) return true; |
1138 scope = scope->outer_scope(); | 1138 scope = scope->outer_scope(); |
1139 } | 1139 } |
1140 | 1140 |
| 1141 // Allow references from methods to classes declared later, if we detect no |
| 1142 // problematic dependency cycles. |
| 1143 |
| 1144 if (ClassVariableForMethod() && var->is_class()) { |
| 1145 // A method is referring to some other class, possibly declared |
| 1146 // later. Referring to a class declared earlier is always OK and covered by |
| 1147 // the code outside this if. Here we only need to allow special cases for |
| 1148 // referring to a class which is declared later. |
| 1149 |
| 1150 // Referring to a class C declared later is OK under the following |
| 1151 // circumstances: |
| 1152 |
| 1153 // 1. The class declarations are in a consecutive group with no other |
| 1154 // declarations or statements in between, and |
| 1155 |
| 1156 // 2. There is no dependency cycle where the first edge is an initialization |
| 1157 // time dependency (computed property name or extends clause) from C to |
| 1158 // something that depends on this class directly or transitively. |
| 1159 |
| 1160 // TODO(marja,rossberg): implement these checks. Here we undershoot the |
| 1161 // target and allow referring to any class. |
| 1162 return true; |
| 1163 } |
| 1164 |
1141 // If both the use and the declaration are inside an eval scope (possibly | 1165 // If both the use and the declaration are inside an eval scope (possibly |
1142 // indirectly), or one of them is, we need to check whether they are inside | 1166 // indirectly), or one of them is, we need to check whether they are inside |
1143 // the same eval scope or different ones. | 1167 // the same eval scope or different ones. |
1144 | 1168 |
1145 // TODO(marja,rossberg): Detect errors across different evals (depends on the | 1169 // TODO(marja,rossberg): Detect errors across different evals (depends on the |
1146 // future of eval in strong mode). | 1170 // future of eval in strong mode). |
1147 const Scope* eval_for_use = NearestOuterEvalScope(); | 1171 const Scope* eval_for_use = NearestOuterEvalScope(); |
1148 const Scope* eval_for_declaration = var->scope()->NearestOuterEvalScope(); | 1172 const Scope* eval_for_declaration = var->scope()->NearestOuterEvalScope(); |
1149 | 1173 |
1150 if (proxy->position() != RelocInfo::kNoPosition && | 1174 if (proxy->position() != RelocInfo::kNoPosition && |
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1464 (function_ != NULL && function_->proxy()->var()->IsStackLocal() ? 1 : 0); | 1488 (function_ != NULL && function_->proxy()->var()->IsStackLocal() ? 1 : 0); |
1465 } | 1489 } |
1466 | 1490 |
1467 | 1491 |
1468 int Scope::ContextLocalCount() const { | 1492 int Scope::ContextLocalCount() const { |
1469 if (num_heap_slots() == 0) return 0; | 1493 if (num_heap_slots() == 0) return 0; |
1470 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - | 1494 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - |
1471 (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0); | 1495 (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0); |
1472 } | 1496 } |
1473 } } // namespace v8::internal | 1497 } } // namespace v8::internal |
OLD | NEW |