OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/scopes.h" | 5 #include "vm/scopes.h" |
6 | 6 |
7 #include "vm/object.h" | 7 #include "vm/object.h" |
8 #include "vm/stack_frame.h" | 8 #include "vm/stack_frame.h" |
9 #include "vm/symbols.h" | 9 #include "vm/symbols.h" |
10 | 10 |
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
425 } | 425 } |
426 | 426 |
427 | 427 |
428 bool LocalScope::CaptureVariable(const String& name) { | 428 bool LocalScope::CaptureVariable(const String& name) { |
429 ASSERT(name.IsSymbol()); | 429 ASSERT(name.IsSymbol()); |
430 LocalScope* current_scope = this; | 430 LocalScope* current_scope = this; |
431 while (current_scope != NULL) { | 431 while (current_scope != NULL) { |
432 LocalVariable* var = current_scope->LocalLookupVariable(name); | 432 LocalVariable* var = current_scope->LocalLookupVariable(name); |
433 if (var != NULL) { | 433 if (var != NULL) { |
434 var->set_is_captured(); | 434 var->set_is_captured(); |
435 // Insert aliases of the variable in intermediate scopes. | 435 LocalScope* scope = this; |
436 LocalScope* intermediate_scope = this; | 436 while (var->owner()->function_level() != scope->function_level()) { |
437 while (intermediate_scope != current_scope) { | 437 // Insert an alias of the variable in the top scope of each function |
438 intermediate_scope->variables_.Add(var); | 438 // level so that the variable is found in the context. |
439 ASSERT(var->owner() != intermediate_scope); // Item is an alias. | 439 LocalScope* parent_scope = scope->parent(); |
440 intermediate_scope = intermediate_scope->parent(); | 440 while ((parent_scope != NULL) && |
| 441 (parent_scope->function_level() == scope->function_level())) { |
| 442 scope = parent_scope; |
| 443 parent_scope = scope->parent(); |
| 444 } |
| 445 scope->variables_.Add(var); |
| 446 ASSERT(var->owner() != scope); // Item is an alias. |
| 447 scope = parent_scope; |
441 } | 448 } |
442 return true; | 449 return true; |
443 } | 450 } |
444 current_scope = current_scope->parent(); | 451 current_scope = current_scope->parent(); |
445 } | 452 } |
446 return false; | 453 return false; |
447 } | 454 } |
448 | 455 |
449 | 456 |
450 SourceLabel* LocalScope::LookupLabel(const String& name) { | 457 SourceLabel* LocalScope::LookupLabel(const String& name) { |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
684 return fixed_parameter_count - (index() - kParamEndSlotFromFp); | 691 return fixed_parameter_count - (index() - kParamEndSlotFromFp); |
685 } else { | 692 } else { |
686 // Shift negative indexes so that the lowest one is 0 (they are still | 693 // Shift negative indexes so that the lowest one is 0 (they are still |
687 // non-positive). | 694 // non-positive). |
688 return fixed_parameter_count - (index() - kFirstLocalSlotFromFp); | 695 return fixed_parameter_count - (index() - kFirstLocalSlotFromFp); |
689 } | 696 } |
690 } | 697 } |
691 | 698 |
692 | 699 |
693 } // namespace dart | 700 } // namespace dart |
OLD | NEW |