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/scopes.h" | |
8 | |
9 #include "src/accessors.h" | 7 #include "src/accessors.h" |
10 #include "src/bootstrapper.h" | 8 #include "src/bootstrapper.h" |
11 #include "src/compiler.h" | |
12 #include "src/messages.h" | 9 #include "src/messages.h" |
| 10 #include "src/parser.h" |
13 #include "src/scopeinfo.h" | 11 #include "src/scopeinfo.h" |
| 12 #include "src/scopes.h" |
14 | 13 |
15 namespace v8 { | 14 namespace v8 { |
16 namespace internal { | 15 namespace internal { |
17 | 16 |
18 // ---------------------------------------------------------------------------- | 17 // ---------------------------------------------------------------------------- |
19 // Implementation of LocalsMap | 18 // Implementation of LocalsMap |
20 // | 19 // |
21 // Note: We are storing the handle locations as key values in the hash map. | 20 // Note: We are storing the handle locations as key values in the hash map. |
22 // When inserting a new variable via Declare(), we rely on the fact that | 21 // When inserting a new variable via Declare(), we rely on the fact that |
23 // the handle location remains alive for the duration of that variable | 22 // the handle location remains alive for the duration of that variable |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
241 } | 240 } |
242 context = context->previous(); | 241 context = context->previous(); |
243 } | 242 } |
244 | 243 |
245 script_scope->AddInnerScope(current_scope); | 244 script_scope->AddInnerScope(current_scope); |
246 script_scope->PropagateScopeInfo(false); | 245 script_scope->PropagateScopeInfo(false); |
247 return (innermost_scope == NULL) ? script_scope : innermost_scope; | 246 return (innermost_scope == NULL) ? script_scope : innermost_scope; |
248 } | 247 } |
249 | 248 |
250 | 249 |
251 bool Scope::Analyze(CompilationInfo* info) { | 250 bool Scope::Analyze(ParseInfo* info) { |
252 DCHECK(info->function() != NULL); | 251 DCHECK(info->function() != NULL); |
| 252 DCHECK(info->scope() == NULL); |
253 Scope* scope = info->function()->scope(); | 253 Scope* scope = info->function()->scope(); |
254 Scope* top = scope; | 254 Scope* top = scope; |
255 | 255 |
256 // Traverse the scope tree up to the first unresolved scope or the global | 256 // Traverse the scope tree up to the first unresolved scope or the global |
257 // scope and start scope resolution and variable allocation from that scope. | 257 // scope and start scope resolution and variable allocation from that scope. |
258 while (!top->is_script_scope() && | 258 while (!top->is_script_scope() && |
259 !top->outer_scope()->already_resolved()) { | 259 !top->outer_scope()->already_resolved()) { |
260 top = top->outer_scope(); | 260 top = top->outer_scope(); |
261 } | 261 } |
262 | 262 |
263 // Allocate the variables. | 263 // Allocate the variables. |
264 { | 264 { |
265 AstNodeFactory ast_node_factory(info->ast_value_factory()); | 265 AstNodeFactory ast_node_factory(info->ast_value_factory()); |
266 if (!top->AllocateVariables(info, &ast_node_factory)) { | 266 if (!top->AllocateVariables(info, &ast_node_factory)) { |
267 DCHECK(top->pending_error_handler_.has_pending_error()); | 267 DCHECK(top->pending_error_handler_.has_pending_error()); |
268 top->pending_error_handler_.ThrowPendingError(info->isolate(), | 268 top->pending_error_handler_.ThrowPendingError(info->isolate(), |
269 info->script()); | 269 info->script()); |
270 return false; | 270 return false; |
271 } | 271 } |
272 } | 272 } |
273 | 273 |
274 #ifdef DEBUG | 274 #ifdef DEBUG |
275 if (info->isolate()->bootstrapper()->IsActive() | 275 if (info->isolate()->bootstrapper()->IsActive() |
276 ? FLAG_print_builtin_scopes | 276 ? FLAG_print_builtin_scopes |
277 : FLAG_print_scopes) { | 277 : FLAG_print_scopes) { |
278 scope->Print(); | 278 scope->Print(); |
279 } | 279 } |
280 #endif | 280 #endif |
281 | 281 |
282 info->PrepareForCompilation(scope); | 282 info->set_scope(scope); |
283 return true; | 283 return true; |
284 } | 284 } |
285 | 285 |
286 | 286 |
287 void Scope::Initialize(bool subclass_constructor) { | 287 void Scope::Initialize(bool subclass_constructor) { |
288 DCHECK(!already_resolved()); | 288 DCHECK(!already_resolved()); |
289 | 289 |
290 // Add this scope as a new inner scope of the outer scope. | 290 // Add this scope as a new inner scope of the outer scope. |
291 if (outer_scope_ != NULL) { | 291 if (outer_scope_ != NULL) { |
292 outer_scope_->inner_scopes_.Add(this, zone()); | 292 outer_scope_->inner_scopes_.Add(this, zone()); |
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
632 Variable* var = vars[i].var(); | 632 Variable* var = vars[i].var(); |
633 if (var->IsStackLocal()) { | 633 if (var->IsStackLocal()) { |
634 stack_locals->Add(var, zone()); | 634 stack_locals->Add(var, zone()); |
635 } else if (var->IsContextSlot()) { | 635 } else if (var->IsContextSlot()) { |
636 context_locals->Add(var, zone()); | 636 context_locals->Add(var, zone()); |
637 } | 637 } |
638 } | 638 } |
639 } | 639 } |
640 | 640 |
641 | 641 |
642 bool Scope::AllocateVariables(CompilationInfo* info, AstNodeFactory* factory) { | 642 bool Scope::AllocateVariables(ParseInfo* info, AstNodeFactory* factory) { |
643 // 1) Propagate scope information. | 643 // 1) Propagate scope information. |
644 bool outer_scope_calls_sloppy_eval = false; | 644 bool outer_scope_calls_sloppy_eval = false; |
645 if (outer_scope_ != NULL) { | 645 if (outer_scope_ != NULL) { |
646 outer_scope_calls_sloppy_eval = | 646 outer_scope_calls_sloppy_eval = |
647 outer_scope_->outer_scope_calls_sloppy_eval() | | 647 outer_scope_->outer_scope_calls_sloppy_eval() | |
648 outer_scope_->calls_sloppy_eval(); | 648 outer_scope_->calls_sloppy_eval(); |
649 } | 649 } |
650 PropagateScopeInfo(outer_scope_calls_sloppy_eval); | 650 PropagateScopeInfo(outer_scope_calls_sloppy_eval); |
651 | 651 |
652 // 2) Allocate module instances. | 652 // 2) Allocate module instances. |
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1048 if (*binding_kind == BOUND) { | 1048 if (*binding_kind == BOUND) { |
1049 *binding_kind = BOUND_EVAL_SHADOWED; | 1049 *binding_kind = BOUND_EVAL_SHADOWED; |
1050 } else if (*binding_kind == UNBOUND) { | 1050 } else if (*binding_kind == UNBOUND) { |
1051 *binding_kind = UNBOUND_EVAL_SHADOWED; | 1051 *binding_kind = UNBOUND_EVAL_SHADOWED; |
1052 } | 1052 } |
1053 } | 1053 } |
1054 return var; | 1054 return var; |
1055 } | 1055 } |
1056 | 1056 |
1057 | 1057 |
1058 bool Scope::ResolveVariable(CompilationInfo* info, VariableProxy* proxy, | 1058 bool Scope::ResolveVariable(ParseInfo* info, VariableProxy* proxy, |
1059 AstNodeFactory* factory) { | 1059 AstNodeFactory* factory) { |
1060 DCHECK(info->script_scope()->is_script_scope()); | 1060 DCHECK(info->script_scope()->is_script_scope()); |
1061 | 1061 |
1062 // If the proxy is already resolved there's nothing to do | 1062 // If the proxy is already resolved there's nothing to do |
1063 // (functions and consts may be resolved by the parser). | 1063 // (functions and consts may be resolved by the parser). |
1064 if (proxy->is_resolved()) return true; | 1064 if (proxy->is_resolved()) return true; |
1065 | 1065 |
1066 // Otherwise, try to resolve the variable. | 1066 // Otherwise, try to resolve the variable. |
1067 BindingKind binding_kind; | 1067 BindingKind binding_kind; |
1068 Variable* var = LookupRecursive(proxy, &binding_kind, factory); | 1068 Variable* var = LookupRecursive(proxy, &binding_kind, factory); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1130 | 1130 |
1131 DCHECK(var != NULL); | 1131 DCHECK(var != NULL); |
1132 if (proxy->is_assigned()) var->set_maybe_assigned(); | 1132 if (proxy->is_assigned()) var->set_maybe_assigned(); |
1133 | 1133 |
1134 proxy->BindTo(var); | 1134 proxy->BindTo(var); |
1135 | 1135 |
1136 return true; | 1136 return true; |
1137 } | 1137 } |
1138 | 1138 |
1139 | 1139 |
1140 bool Scope::ResolveVariablesRecursively(CompilationInfo* info, | 1140 bool Scope::ResolveVariablesRecursively(ParseInfo* info, |
1141 AstNodeFactory* factory) { | 1141 AstNodeFactory* factory) { |
1142 DCHECK(info->script_scope()->is_script_scope()); | 1142 DCHECK(info->script_scope()->is_script_scope()); |
1143 | 1143 |
1144 // Resolve unresolved variables for this scope. | 1144 // Resolve unresolved variables for this scope. |
1145 for (int i = 0; i < unresolved_.length(); i++) { | 1145 for (int i = 0; i < unresolved_.length(); i++) { |
1146 if (!ResolveVariable(info, unresolved_[i], factory)) return false; | 1146 if (!ResolveVariable(info, unresolved_[i], factory)) return false; |
1147 } | 1147 } |
1148 | 1148 |
1149 // Resolve unresolved variables for inner scopes. | 1149 // Resolve unresolved variables for inner scopes. |
1150 for (int i = 0; i < inner_scopes_.length(); i++) { | 1150 for (int i = 0; i < inner_scopes_.length(); i++) { |
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1425 } | 1425 } |
1426 | 1426 |
1427 | 1427 |
1428 int Scope::ContextLocalCount() const { | 1428 int Scope::ContextLocalCount() const { |
1429 if (num_heap_slots() == 0) return 0; | 1429 if (num_heap_slots() == 0) return 0; |
1430 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - | 1430 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - |
1431 (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0); | 1431 (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0); |
1432 } | 1432 } |
1433 | 1433 |
1434 } } // namespace v8::internal | 1434 } } // namespace v8::internal |
OLD | NEW |