Chromium Code Reviews| 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/ast.h" | 7 #include "vm/ast.h" |
| 8 #include "vm/bit_vector.h" | 8 #include "vm/bit_vector.h" |
| 9 #include "vm/object.h" | 9 #include "vm/object.h" |
| 10 #include "vm/parser.h" | 10 #include "vm/parser.h" |
| 11 | 11 |
| 12 namespace dart { | 12 namespace dart { |
| 13 | 13 |
| 14 const char* SourceLabel::kDefaultLabelName = ":L"; | 14 const char* SourceLabel::kDefaultLabelName = ":L"; |
| 15 | 15 |
| 16 const char* LocalVariable::kSavedContextVarName = ":saved_entry_context_var"; | |
| 17 | |
| 16 | 18 |
| 17 int SourceLabel::FunctionLevel() const { | 19 int SourceLabel::FunctionLevel() const { |
| 18 ASSERT(owner() != NULL); | 20 ASSERT(owner() != NULL); |
| 19 return owner()->function_level(); | 21 return owner()->function_level(); |
| 20 } | 22 } |
| 21 | 23 |
| 22 | 24 |
| 23 LocalScope::LocalScope(LocalScope* parent, int function_level, int loop_level) | 25 LocalScope::LocalScope(LocalScope* parent, int function_level, int loop_level) |
| 24 : parent_(parent), | 26 : parent_(parent), |
| 25 child_(NULL), | 27 child_(NULL), |
| 26 sibling_(NULL), | 28 sibling_(NULL), |
| 27 function_level_(function_level), | 29 function_level_(function_level), |
| 28 loop_level_(loop_level), | 30 loop_level_(loop_level), |
| 29 context_level_(LocalScope::kUnitializedContextLevel), | 31 context_level_(LocalScope::kUnitializedContextLevel), |
| 30 num_context_variables_(0), | 32 num_context_variables_(0), |
| 33 begin_token_index_(0), | |
| 31 end_token_index_(0), | 34 end_token_index_(0), |
| 32 variables_(), | 35 variables_(), |
| 33 labels_() { | 36 labels_() { |
| 34 // Hook this node into the children of the parent, unless the parent has a | 37 // Hook this node into the children of the parent, unless the parent has a |
| 35 // different function_level, since the local scope of a nested function can | 38 // different function_level, since the local scope of a nested function can |
| 36 // be discarded after it has been parsed. | 39 // be discarded after it has been parsed. |
| 37 if ((parent != NULL) && (parent->function_level() == function_level)) { | 40 if ((parent != NULL) && (parent->function_level() == function_level)) { |
| 38 sibling_ = parent->child_; | 41 sibling_ = parent->child_; |
| 39 parent->child_ = this; | 42 parent->child_ = this; |
| 40 } | 43 } |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 173 if ((child_context_owner != *context_owner) && | 176 if ((child_context_owner != *context_owner) && |
| 174 (child_context_owner->loop_level() <= loop_owner->loop_level())) { | 177 (child_context_owner->loop_level() <= loop_owner->loop_level())) { |
| 175 *context_owner = child_context_owner; // Share context between siblings. | 178 *context_owner = child_context_owner; // Share context between siblings. |
| 176 } | 179 } |
| 177 child = child->sibling(); | 180 child = child->sibling(); |
| 178 } | 181 } |
| 179 return min_frame_index; | 182 return min_frame_index; |
| 180 } | 183 } |
| 181 | 184 |
| 182 | 185 |
| 183 RawLocalVarDescriptors* LocalScope::GetVarDescriptors() { | 186 RawLocalVarDescriptors* LocalScope::GetVarDescriptors(const Function& func) { |
| 184 GrowableArray<LocalVariable*> vars(8); | 187 GrowableArray<VarDesc> vars(8); |
| 185 // Variables of each scope are guaranteed to be consecutive elements | 188 // First enter all variables from scopes of outer functions. |
| 186 // in array vars. See CollectLocalVariables() below. The outermost | 189 const ContextScope& context_scope = |
| 187 // scope (containing the function parameters) has id 0. | 190 ContextScope::Handle(func.context_scope()); |
| 188 CollectLocalVariables(&vars); | 191 if (!context_scope.IsNull()) { |
| 192 ASSERT(func.IsLocalFunction()); | |
| 193 for (int i = 0; i < context_scope.num_variables(); i++) { | |
| 194 VarDesc desc; | |
| 195 desc.name = &String::Handle(context_scope.NameAt(i)); | |
| 196 desc.info.kind = RawLocalVarDescriptors::kContextVar; | |
| 197 desc.info.scope_id = context_scope.ContextLevelAt(i); | |
| 198 desc.info.begin_pos = begin_token_index(); | |
| 199 desc.info.end_pos = end_token_index(); | |
| 200 desc.info.index = context_scope.ContextIndexAt(i); | |
| 201 vars.Add(desc); | |
| 202 } | |
| 203 } | |
| 204 // Now collect all variables from local scopes. | |
| 205 int16_t scope_id = 0; | |
| 206 CollectLocalVariables(&vars, &scope_id); | |
| 207 | |
| 189 const LocalVarDescriptors& var_desc = | 208 const LocalVarDescriptors& var_desc = |
| 190 LocalVarDescriptors::Handle(LocalVarDescriptors::New(vars.length())); | 209 LocalVarDescriptors::Handle(LocalVarDescriptors::New(vars.length())); |
| 191 intptr_t scope_id = -1; | 210 for (int i = 0; i < vars.length(); i++) { |
| 192 LocalScope* current_scope = NULL; | 211 var_desc.SetVar(i, *(vars[i].name), &vars[i].info); |
| 193 for (int i = 0; i < vars.length(); i++) { | |
| 194 LocalVariable* var = vars[i]; | |
| 195 if (current_scope != var->owner()) { | |
| 196 current_scope = var->owner(); | |
| 197 scope_id += 1; | |
| 198 } | |
| 199 var_desc.SetVar(i, var->name(), var->index(), | |
| 200 scope_id, var->token_index(), var->owner()->end_token_index()); | |
| 201 } | 212 } |
| 202 return var_desc.raw(); | 213 return var_desc.raw(); |
| 203 } | 214 } |
| 204 | 215 |
| 205 | 216 |
| 206 // Add variables that are declared in this scope to vars, then collect | 217 // Add variables that are declared in this scope to vars, then collect |
| 207 // variables of children, followed by siblings. | 218 // variables of children, followed by siblings. |
| 208 void LocalScope::CollectLocalVariables(GrowableArray<LocalVariable*>* vars) { | 219 void LocalScope::CollectLocalVariables(GrowableArray<VarDesc>* vars, |
| 220 int16_t* scope_id) { | |
| 221 (*scope_id)++; | |
| 222 if (HasContextLevel() && | |
| 223 ((parent() == NULL) || | |
| 224 (!parent()->HasContextLevel()) || | |
|
regis
2012/06/19 18:14:41
No indentation needed.
hausner
2012/06/19 18:49:41
Ok. I try to indicate factors and terms by indenta
| |
| 225 (parent()->context_level() != context_level()))) { | |
| 226 // This is the outermost scope with a context level or this scope's | |
| 227 // context level differes from its parent's level. | |
| 228 VarDesc desc; | |
| 229 desc.name = &String::Handle(); // No name. | |
| 230 desc.info.kind = RawLocalVarDescriptors::kContextLevel; | |
| 231 desc.info.scope_id = *scope_id; | |
| 232 desc.info.begin_pos = begin_token_index(); | |
| 233 desc.info.end_pos = end_token_index(); | |
| 234 desc.info.index = context_level(); | |
| 235 vars->Add(desc); | |
| 236 } | |
| 209 for (int i = 0; i < this->variables_.length(); i++) { | 237 for (int i = 0; i < this->variables_.length(); i++) { |
| 210 LocalVariable* var = variables_[i]; | 238 LocalVariable* var = variables_[i]; |
| 211 // TODO(hausner): Remove the is_captured() condition once the debugger | 239 if (var->owner() == this) { |
| 212 // can handle getting values of captured variables. | 240 if (Scanner::IsIdent(var->name())) { |
| 213 if (!var->is_captured() && (var->owner() == this) && | 241 // This is a regular Dart variable, either stack-based or captured. |
| 214 Scanner::IsIdent(var->name())) { | 242 VarDesc desc; |
| 215 vars->Add(this->variables_[i]); | 243 desc.name = &var->name(); |
| 244 if (var->is_captured()) { | |
| 245 desc.info.kind = RawLocalVarDescriptors::kContextVar; | |
| 246 ASSERT(var->owner() != NULL); | |
| 247 ASSERT(var->owner()->context_level() >= 0); | |
| 248 desc.info.scope_id = var->owner()->context_level(); | |
| 249 } else { | |
| 250 desc.info.kind = RawLocalVarDescriptors::kStackVar; | |
| 251 desc.info.scope_id = *scope_id; | |
| 252 } | |
| 253 desc.info.begin_pos = var->token_index(); | |
| 254 desc.info.end_pos = var->owner()->end_token_index(); | |
| 255 desc.info.index = var->index(); | |
| 256 vars->Add(desc); | |
| 257 } else if (var->name().Equals(LocalVariable::kSavedContextVarName)) { | |
| 258 // This is the local variable in which the function saves the | |
| 259 // caller's chain of closure contexts (caller's CTX register). | |
| 260 VarDesc desc; | |
| 261 desc.name = &var->name(); | |
| 262 desc.info.kind = RawLocalVarDescriptors::kContextChain; | |
| 263 desc.info.scope_id = 0; | |
| 264 desc.info.begin_pos = 0; | |
| 265 desc.info.end_pos = 0; | |
| 266 desc.info.index = var->index(); | |
| 267 vars->Add(desc); | |
| 268 } | |
| 216 } | 269 } |
| 217 } | 270 } |
| 218 if (child() != NULL) { | 271 LocalScope* child = this->child(); |
| 219 child()->CollectLocalVariables(vars); | 272 while (child != NULL) { |
| 220 } | 273 child->CollectLocalVariables(vars, scope_id); |
| 221 if (sibling() != NULL) { | 274 child = child->sibling(); |
| 222 sibling()->CollectLocalVariables(vars); | |
| 223 } | 275 } |
| 224 } | 276 } |
| 225 | 277 |
| 226 | 278 |
| 227 SourceLabel* LocalScope::LocalLookupLabel(const String& name) const { | 279 SourceLabel* LocalScope::LocalLookupLabel(const String& name) const { |
| 228 for (intptr_t i = 0; i < labels_.length(); i++) { | 280 for (intptr_t i = 0; i < labels_.length(); i++) { |
| 229 SourceLabel* label = labels_[i]; | 281 SourceLabel* label = labels_[i]; |
| 230 if (label->name().Equals(name)) { | 282 if (label->name().Equals(name)) { |
| 231 return label; | 283 return label; |
| 232 } | 284 } |
| (...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 492 } else { | 544 } else { |
| 493 // Shift negative indexes so that the lowest one is 0 (they are still | 545 // Shift negative indexes so that the lowest one is 0 (they are still |
| 494 // non-positive) and index them backward from the end of the vector. | 546 // non-positive) and index them backward from the end of the vector. |
| 495 return (var_count - 1) + | 547 return (var_count - 1) + |
| 496 (index() - ParsedFunction::kFirstLocalSlotIndex); | 548 (index() - ParsedFunction::kFirstLocalSlotIndex); |
| 497 } | 549 } |
| 498 } | 550 } |
| 499 | 551 |
| 500 | 552 |
| 501 } // namespace dart | 553 } // namespace dart |
| OLD | NEW |