Index: runtime/vm/scopes.cc |
=================================================================== |
--- runtime/vm/scopes.cc (revision 44591) |
+++ runtime/vm/scopes.cc (working copy) |
@@ -139,25 +139,32 @@ |
void LocalScope::AllocateContextVariable(LocalVariable* variable, |
LocalScope** context_owner) { |
ASSERT(variable->is_captured()); |
- ASSERT(variable->owner()->loop_level() == loop_level()); |
- if (num_context_variables_ == 0) { |
+ ASSERT(variable->owner() == this); |
+ // The context level in the owner scope of a captured variable indicates at |
+ // code generation time how far to walk up the context chain in order to |
+ // access the variable from the current context level. |
+ if ((*context_owner) == NULL) { |
+ ASSERT(num_context_variables_ == 0); |
+ // This scope becomes the current context owner. |
+ set_context_level(1); |
+ *context_owner = this; |
+ } else if ((*context_owner)->loop_level() < loop_level()) { |
+ // The captured variable is at a deeper loop level than the current context. |
// This scope will allocate and chain a new context. |
- int new_context_level = ((*context_owner) == NULL) ? |
- 1 : (*context_owner)->context_level() + 1; |
+ ASSERT(num_context_variables_ == 0); |
// This scope becomes the current context owner. |
+ set_context_level((*context_owner)->context_level() + 1); |
*context_owner = this; |
- set_context_level(new_context_level); |
- } |
- // The context level in the owner scope of a captured variable indicates at |
- // code generation time how far to walk up the context chain in order to |
- // access the variable from the current context level. |
- if (!variable->owner()->HasContextLevel()) { |
- ASSERT(variable->owner() != this); |
- variable->owner()->set_context_level(context_level()); |
} else { |
- ASSERT(variable->owner()->context_level() == context_level()); |
+ // Allocate the captured variable in the current context. |
+ if (!HasContextLevel()) { |
+ ASSERT(variable->owner() != *context_owner); |
+ set_context_level((*context_owner)->context_level()); |
+ } else { |
+ ASSERT(context_level() == (*context_owner)->context_level()); |
+ } |
} |
- variable->set_index(num_context_variables_++); |
+ variable->set_index((*context_owner)->num_context_variables_++); |
} |
@@ -164,19 +171,12 @@ |
int LocalScope::AllocateVariables(int first_parameter_index, |
int num_parameters, |
int first_frame_index, |
- LocalScope* loop_owner, |
- LocalScope** context_owner, |
+ LocalScope* context_owner, |
bool* found_captured_variables) { |
// We should not allocate variables of nested functions while compiling an |
// enclosing function. |
ASSERT(function_level() == 0); |
ASSERT(num_parameters >= 0); |
- |
- // Keep track of the current loop owner scope, that is of the highest parent |
- // scope at the same loop level as this scope. |
- if (loop_level() > loop_owner->loop_level()) { |
- loop_owner = this; |
- } |
// Parameters must be listed first and must all appear in the top scope. |
ASSERT(num_parameters <= num_variables()); |
int pos = 0; // Current variable position. |
@@ -194,7 +194,7 @@ |
// context, where it gets copied to. The parameter index reflects the |
// context allocation index. |
frame_index--; |
- loop_owner->AllocateContextVariable(parameter, context_owner); |
+ AllocateContextVariable(parameter, &context_owner); |
*found_captured_variables = true; |
} else { |
parameter->set_index(frame_index--); |
@@ -208,7 +208,7 @@ |
pos++; |
if (variable->owner() == this) { |
if (variable->is_captured()) { |
- loop_owner->AllocateContextVariable(variable, context_owner); |
+ AllocateContextVariable(variable, &context_owner); |
*found_captured_variables = true; |
} else { |
variable->set_index(frame_index--); |
@@ -216,27 +216,19 @@ |
} |
} |
// Allocate variables of all children. |
- int min_frame_index = frame_index; |
+ int min_frame_index = frame_index; // Frame index decreases with allocations. |
LocalScope* child = this->child(); |
while (child != NULL) { |
- LocalScope* child_context_owner = *context_owner; |
int const dummy_parameter_index = 0; // Ignored, since no parameters. |
int const num_parameters_in_child = 0; // No parameters in children scopes. |
int child_frame_index = child->AllocateVariables(dummy_parameter_index, |
num_parameters_in_child, |
frame_index, |
- loop_owner, |
- &child_context_owner, |
+ context_owner, |
found_captured_variables); |
if (child_frame_index < min_frame_index) { |
min_frame_index = child_frame_index; |
} |
- // A context allocated at a deeper loop level than the current loop level is |
- // not shared between children. |
- if ((child_context_owner != *context_owner) && |
- (child_context_owner->loop_level() <= loop_owner->loop_level())) { |
- *context_owner = child_context_owner; // Share context between siblings. |
- } |
child = child->sibling(); |
} |
return min_frame_index; |