Chromium Code Reviews| Index: runtime/vm/scopes.cc |
| diff --git a/runtime/vm/scopes.cc b/runtime/vm/scopes.cc |
| index c972b0f7a43c6d4d154102ea66a136146f5739a2..f148286c6294599ab649c3a96833432ab2c6ba53 100644 |
| --- a/runtime/vm/scopes.cc |
| +++ b/runtime/vm/scopes.cc |
| @@ -284,8 +284,40 @@ static bool IsFilteredIdentifier(const String& str) { |
| } |
| -RawLocalVarDescriptors* LocalScope::GetVarDescriptors(const Function& func) { |
| +RawLocalVarDescriptors* LocalScope::GetVarDescriptors( |
| + const Function& func, |
| + ZoneGrowableArray<intptr_t>* context_level_array) { |
| GrowableArray<VarDesc> vars(8); |
| + |
| + // Record deopt-id -> context-level mappings, using ranges of deopt-ids with |
| + // the same context-level. |
| + for (intptr_t start = 0; start < context_level_array->length();) { |
|
Vyacheslav Egorov (Google)
2017/05/31 14:29:51
Maybe context_level_array tuples need to be sorted
rmacnak
2017/05/31 18:03:17
We don't depend on the order the AST is processed
Vyacheslav Egorov (Google)
2017/06/01 12:32:41
Yeah, I am not sure what I was thinking. GetNextDe
|
| + intptr_t start_deopt_id = (*context_level_array)[start]; |
| + intptr_t start_context_level = (*context_level_array)[start + 1]; |
| + intptr_t end = start; |
| + intptr_t end_deopt_id = start_deopt_id; |
| + for (intptr_t peek = start + 2; peek < context_level_array->length(); |
| + peek += 2) { |
| + intptr_t peek_deopt_id = (*context_level_array)[peek]; |
| + intptr_t peek_context_level = (*context_level_array)[peek + 1]; |
| + ASSERT(peek_deopt_id > end_deopt_id); |
| + if (peek_context_level != start_context_level) break; |
| + end = peek; |
| + end_deopt_id = peek_deopt_id; |
| + } |
| + |
| + VarDesc desc; |
| + desc.name = &Symbols::Empty(); // No name. |
| + desc.info.set_kind(RawLocalVarDescriptors::kContextLevel); |
| + desc.info.scope_id = 0; |
| + desc.info.begin_pos = TokenPosition(start_deopt_id); |
| + desc.info.end_pos = TokenPosition(end_deopt_id); |
| + desc.info.set_index(start_context_level); |
| + vars.Add(desc); |
| + |
| + start = end + 2; |
| + } |
| + |
| // First enter all variables from scopes of outer functions. |
| const ContextScope& context_scope = |
| ContextScope::Handle(func.context_scope()); |
| @@ -333,16 +365,6 @@ RawLocalVarDescriptors* LocalScope::GetVarDescriptors(const Function& func) { |
| void LocalScope::CollectLocalVariables(GrowableArray<VarDesc>* vars, |
| int16_t* scope_id) { |
| (*scope_id)++; |
| - if (num_context_variables() > 0) { |
| - VarDesc desc; |
| - desc.name = &Symbols::Empty(); // No name. |
| - desc.info.set_kind(RawLocalVarDescriptors::kContextLevel); |
| - desc.info.scope_id = *scope_id; |
| - desc.info.begin_pos = begin_token_pos(); |
| - desc.info.end_pos = end_token_pos(); |
| - desc.info.set_index(context_level()); |
| - vars->Add(desc); |
| - } |
| for (int i = 0; i < this->variables_.length(); i++) { |
| LocalVariable* var = variables_[i]; |
| if ((var->owner() == this) && !var->is_invisible()) { |