| 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" |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 | 23 |
| 24 | 24 |
| 25 LocalScope::LocalScope(LocalScope* parent, int function_level, int loop_level) | 25 LocalScope::LocalScope(LocalScope* parent, int function_level, int loop_level) |
| 26 : parent_(parent), | 26 : parent_(parent), |
| 27 child_(NULL), | 27 child_(NULL), |
| 28 sibling_(NULL), | 28 sibling_(NULL), |
| 29 function_level_(function_level), | 29 function_level_(function_level), |
| 30 loop_level_(loop_level), | 30 loop_level_(loop_level), |
| 31 context_level_(LocalScope::kUnitializedContextLevel), | 31 context_level_(LocalScope::kUnitializedContextLevel), |
| 32 num_context_variables_(0), | 32 num_context_variables_(0), |
| 33 begin_token_index_(0), | 33 begin_token_pos_(0), |
| 34 end_token_index_(0), | 34 end_token_pos_(0), |
| 35 variables_(), | 35 variables_(), |
| 36 labels_() { | 36 labels_() { |
| 37 // 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 |
| 38 // 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 |
| 39 // be discarded after it has been parsed. | 39 // be discarded after it has been parsed. |
| 40 if ((parent != NULL) && (parent->function_level() == function_level)) { | 40 if ((parent != NULL) && (parent->function_level() == function_level)) { |
| 41 sibling_ = parent->child_; | 41 sibling_ = parent->child_; |
| 42 parent->child_ = this; | 42 parent->child_ = this; |
| 43 } | 43 } |
| 44 } | 44 } |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 188 // First enter all variables from scopes of outer functions. | 188 // First enter all variables from scopes of outer functions. |
| 189 const ContextScope& context_scope = | 189 const ContextScope& context_scope = |
| 190 ContextScope::Handle(func.context_scope()); | 190 ContextScope::Handle(func.context_scope()); |
| 191 if (!context_scope.IsNull()) { | 191 if (!context_scope.IsNull()) { |
| 192 ASSERT(func.IsLocalFunction()); | 192 ASSERT(func.IsLocalFunction()); |
| 193 for (int i = 0; i < context_scope.num_variables(); i++) { | 193 for (int i = 0; i < context_scope.num_variables(); i++) { |
| 194 VarDesc desc; | 194 VarDesc desc; |
| 195 desc.name = &String::Handle(context_scope.NameAt(i)); | 195 desc.name = &String::Handle(context_scope.NameAt(i)); |
| 196 desc.info.kind = RawLocalVarDescriptors::kContextVar; | 196 desc.info.kind = RawLocalVarDescriptors::kContextVar; |
| 197 desc.info.scope_id = context_scope.ContextLevelAt(i); | 197 desc.info.scope_id = context_scope.ContextLevelAt(i); |
| 198 desc.info.begin_pos = begin_token_index(); | 198 desc.info.begin_pos = begin_token_pos(); |
| 199 desc.info.end_pos = end_token_index(); | 199 desc.info.end_pos = end_token_pos(); |
| 200 desc.info.index = context_scope.ContextIndexAt(i); | 200 desc.info.index = context_scope.ContextIndexAt(i); |
| 201 vars.Add(desc); | 201 vars.Add(desc); |
| 202 } | 202 } |
| 203 } | 203 } |
| 204 // Now collect all variables from local scopes. | 204 // Now collect all variables from local scopes. |
| 205 int16_t scope_id = 0; | 205 int16_t scope_id = 0; |
| 206 CollectLocalVariables(&vars, &scope_id); | 206 CollectLocalVariables(&vars, &scope_id); |
| 207 | 207 |
| 208 const LocalVarDescriptors& var_desc = | 208 const LocalVarDescriptors& var_desc = |
| 209 LocalVarDescriptors::Handle(LocalVarDescriptors::New(vars.length())); | 209 LocalVarDescriptors::Handle(LocalVarDescriptors::New(vars.length())); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 222 if (HasContextLevel() && | 222 if (HasContextLevel() && |
| 223 ((parent() == NULL) || | 223 ((parent() == NULL) || |
| 224 (!parent()->HasContextLevel()) || | 224 (!parent()->HasContextLevel()) || |
| 225 (parent()->context_level() != context_level()))) { | 225 (parent()->context_level() != context_level()))) { |
| 226 // This is the outermost scope with a context level or this scope's | 226 // This is the outermost scope with a context level or this scope's |
| 227 // context level differes from its parent's level. | 227 // context level differes from its parent's level. |
| 228 VarDesc desc; | 228 VarDesc desc; |
| 229 desc.name = &String::Handle(); // No name. | 229 desc.name = &String::Handle(); // No name. |
| 230 desc.info.kind = RawLocalVarDescriptors::kContextLevel; | 230 desc.info.kind = RawLocalVarDescriptors::kContextLevel; |
| 231 desc.info.scope_id = *scope_id; | 231 desc.info.scope_id = *scope_id; |
| 232 desc.info.begin_pos = begin_token_index(); | 232 desc.info.begin_pos = begin_token_pos(); |
| 233 desc.info.end_pos = end_token_index(); | 233 desc.info.end_pos = end_token_pos(); |
| 234 desc.info.index = context_level(); | 234 desc.info.index = context_level(); |
| 235 vars->Add(desc); | 235 vars->Add(desc); |
| 236 } | 236 } |
| 237 for (int i = 0; i < this->variables_.length(); i++) { | 237 for (int i = 0; i < this->variables_.length(); i++) { |
| 238 LocalVariable* var = variables_[i]; | 238 LocalVariable* var = variables_[i]; |
| 239 if (var->owner() == this) { | 239 if (var->owner() == this) { |
| 240 if (Scanner::IsIdent(var->name())) { | 240 if (Scanner::IsIdent(var->name())) { |
| 241 // This is a regular Dart variable, either stack-based or captured. | 241 // This is a regular Dart variable, either stack-based or captured. |
| 242 VarDesc desc; | 242 VarDesc desc; |
| 243 desc.name = &var->name(); | 243 desc.name = &var->name(); |
| 244 if (var->is_captured()) { | 244 if (var->is_captured()) { |
| 245 desc.info.kind = RawLocalVarDescriptors::kContextVar; | 245 desc.info.kind = RawLocalVarDescriptors::kContextVar; |
| 246 ASSERT(var->owner() != NULL); | 246 ASSERT(var->owner() != NULL); |
| 247 ASSERT(var->owner()->context_level() >= 0); | 247 ASSERT(var->owner()->context_level() >= 0); |
| 248 desc.info.scope_id = var->owner()->context_level(); | 248 desc.info.scope_id = var->owner()->context_level(); |
| 249 } else { | 249 } else { |
| 250 desc.info.kind = RawLocalVarDescriptors::kStackVar; | 250 desc.info.kind = RawLocalVarDescriptors::kStackVar; |
| 251 desc.info.scope_id = *scope_id; | 251 desc.info.scope_id = *scope_id; |
| 252 } | 252 } |
| 253 desc.info.begin_pos = var->token_index(); | 253 desc.info.begin_pos = var->token_pos(); |
| 254 desc.info.end_pos = var->owner()->end_token_index(); | 254 desc.info.end_pos = var->owner()->end_token_pos(); |
| 255 desc.info.index = var->index(); | 255 desc.info.index = var->index(); |
| 256 vars->Add(desc); | 256 vars->Add(desc); |
| 257 } else if (var->name().Equals(LocalVariable::kSavedContextVarName)) { | 257 } else if (var->name().Equals(LocalVariable::kSavedContextVarName)) { |
| 258 // This is the local variable in which the function saves the | 258 // This is the local variable in which the function saves the |
| 259 // caller's chain of closure contexts (caller's CTX register). | 259 // caller's chain of closure contexts (caller's CTX register). |
| 260 VarDesc desc; | 260 VarDesc desc; |
| 261 desc.name = &var->name(); | 261 desc.name = &var->name(); |
| 262 desc.info.kind = RawLocalVarDescriptors::kContextChain; | 262 desc.info.kind = RawLocalVarDescriptors::kContextChain; |
| 263 desc.info.scope_id = 0; | 263 desc.info.scope_id = 0; |
| 264 desc.info.begin_pos = 0; | 264 desc.info.begin_pos = 0; |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 444 const ContextScope& context_scope = | 444 const ContextScope& context_scope = |
| 445 ContextScope::Handle(ContextScope::New(num_captured_vars)); | 445 ContextScope::Handle(ContextScope::New(num_captured_vars)); |
| 446 | 446 |
| 447 // Create a descriptor for each referenced captured variable of enclosing | 447 // Create a descriptor for each referenced captured variable of enclosing |
| 448 // functions to preserve its name and its context allocation information. | 448 // functions to preserve its name and its context allocation information. |
| 449 int captured_idx = 0; | 449 int captured_idx = 0; |
| 450 for (int i = 0; i < num_variables(); i++) { | 450 for (int i = 0; i < num_variables(); i++) { |
| 451 LocalVariable* variable = VariableAt(i); | 451 LocalVariable* variable = VariableAt(i); |
| 452 // Preserve the aliases of captured variables belonging to outer scopes. | 452 // Preserve the aliases of captured variables belonging to outer scopes. |
| 453 if (variable->owner()->function_level() != 1) { | 453 if (variable->owner()->function_level() != 1) { |
| 454 context_scope.SetTokenIndexAt(captured_idx, variable->token_index()); | 454 context_scope.SetTokenIndexAt(captured_idx, variable->token_pos()); |
| 455 context_scope.SetNameAt(captured_idx, variable->name()); | 455 context_scope.SetNameAt(captured_idx, variable->name()); |
| 456 context_scope.SetIsFinalAt(captured_idx, variable->is_final()); | 456 context_scope.SetIsFinalAt(captured_idx, variable->is_final()); |
| 457 context_scope.SetTypeAt(captured_idx, variable->type()); | 457 context_scope.SetTypeAt(captured_idx, variable->type()); |
| 458 context_scope.SetContextIndexAt(captured_idx, variable->index()); | 458 context_scope.SetContextIndexAt(captured_idx, variable->index()); |
| 459 // Adjust the context level relative to the current context level, | 459 // Adjust the context level relative to the current context level, |
| 460 // since the context of the current scope will be at level 0 when | 460 // since the context of the current scope will be at level 0 when |
| 461 // compiling the nested function. | 461 // compiling the nested function. |
| 462 int adjusted_context_level = | 462 int adjusted_context_level = |
| 463 variable->owner()->context_level() - current_context_level; | 463 variable->owner()->context_level() - current_context_level; |
| 464 context_scope.SetContextLevelAt(captured_idx, adjusted_context_level); | 464 context_scope.SetContextLevelAt(captured_idx, adjusted_context_level); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 498 | 498 |
| 499 RawContextScope* LocalScope::CreateImplicitClosureScope(const Function& func) { | 499 RawContextScope* LocalScope::CreateImplicitClosureScope(const Function& func) { |
| 500 static const intptr_t kNumCapturedVars = 1; | 500 static const intptr_t kNumCapturedVars = 1; |
| 501 | 501 |
| 502 // Create a ContextScope with space for kNumCapturedVars descriptors. | 502 // Create a ContextScope with space for kNumCapturedVars descriptors. |
| 503 const ContextScope& context_scope = | 503 const ContextScope& context_scope = |
| 504 ContextScope::Handle(ContextScope::New(kNumCapturedVars)); | 504 ContextScope::Handle(ContextScope::New(kNumCapturedVars)); |
| 505 | 505 |
| 506 // Create a descriptor for 'this' variable. | 506 // Create a descriptor for 'this' variable. |
| 507 const String& name = String::Handle(String::NewSymbol("this")); | 507 const String& name = String::Handle(String::NewSymbol("this")); |
| 508 context_scope.SetTokenIndexAt(0, func.token_index()); | 508 context_scope.SetTokenIndexAt(0, func.token_pos()); |
| 509 context_scope.SetNameAt(0, name); | 509 context_scope.SetNameAt(0, name); |
| 510 context_scope.SetIsFinalAt(0, true); | 510 context_scope.SetIsFinalAt(0, true); |
| 511 const AbstractType& type = AbstractType::Handle(func.ParameterTypeAt(0)); | 511 const AbstractType& type = AbstractType::Handle(func.ParameterTypeAt(0)); |
| 512 context_scope.SetTypeAt(0, type); | 512 context_scope.SetTypeAt(0, type); |
| 513 context_scope.SetContextIndexAt(0, 0); | 513 context_scope.SetContextIndexAt(0, 0); |
| 514 context_scope.SetContextLevelAt(0, 0); | 514 context_scope.SetContextLevelAt(0, 0); |
| 515 ASSERT(context_scope.num_variables() == kNumCapturedVars); // Verify count. | 515 ASSERT(context_scope.num_variables() == kNumCapturedVars); // Verify count. |
| 516 return context_scope.raw(); | 516 return context_scope.raw(); |
| 517 } | 517 } |
| 518 | 518 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 544 } else { | 544 } else { |
| 545 // 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 |
| 546 // 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. |
| 547 return (var_count - 1) + | 547 return (var_count - 1) + |
| 548 (index() - ParsedFunction::kFirstLocalSlotIndex); | 548 (index() - ParsedFunction::kFirstLocalSlotIndex); |
| 549 } | 549 } |
| 550 } | 550 } |
| 551 | 551 |
| 552 | 552 |
| 553 } // namespace dart | 553 } // namespace dart |
| OLD | NEW |