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 |
11 namespace dart { | 11 namespace dart { |
12 | 12 |
13 DEFINE_FLAG(bool, share_enclosing_context, true, | 13 DEFINE_FLAG(bool, |
| 14 share_enclosing_context, |
| 15 true, |
14 "Allocate captured variables in the existing context of an " | 16 "Allocate captured variables in the existing context of an " |
15 "enclosing scope (up to innermost loop) and spare the allocation " | 17 "enclosing scope (up to innermost loop) and spare the allocation " |
16 "of a local context."); | 18 "of a local context."); |
17 | 19 |
18 int SourceLabel::FunctionLevel() const { | 20 int SourceLabel::FunctionLevel() const { |
19 ASSERT(owner() != NULL); | 21 ASSERT(owner() != NULL); |
20 return owner()->function_level(); | 22 return owner()->function_level(); |
21 } | 23 } |
22 | 24 |
23 | 25 |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
194 int num_parameters, | 196 int num_parameters, |
195 int first_frame_index, | 197 int first_frame_index, |
196 LocalScope* context_owner, | 198 LocalScope* context_owner, |
197 bool* found_captured_variables) { | 199 bool* found_captured_variables) { |
198 // We should not allocate variables of nested functions while compiling an | 200 // We should not allocate variables of nested functions while compiling an |
199 // enclosing function. | 201 // enclosing function. |
200 ASSERT(function_level() == 0); | 202 ASSERT(function_level() == 0); |
201 ASSERT(num_parameters >= 0); | 203 ASSERT(num_parameters >= 0); |
202 // Parameters must be listed first and must all appear in the top scope. | 204 // Parameters must be listed first and must all appear in the top scope. |
203 ASSERT(num_parameters <= num_variables()); | 205 ASSERT(num_parameters <= num_variables()); |
204 int pos = 0; // Current variable position. | 206 int pos = 0; // Current variable position. |
205 int frame_index = first_parameter_index; // Current free frame index. | 207 int frame_index = first_parameter_index; // Current free frame index. |
206 while (pos < num_parameters) { | 208 while (pos < num_parameters) { |
207 LocalVariable* parameter = VariableAt(pos); | 209 LocalVariable* parameter = VariableAt(pos); |
208 pos++; | 210 pos++; |
209 // Parsing formal parameter default values may add local variable aliases | 211 // Parsing formal parameter default values may add local variable aliases |
210 // to the local scope before the formal parameters are added. However, | 212 // to the local scope before the formal parameters are added. However, |
211 // the parameters get inserted in front of the aliases, therefore, no | 213 // the parameters get inserted in front of the aliases, therefore, no |
212 // aliases can be encountered among the first num_parameters variables. | 214 // aliases can be encountered among the first num_parameters variables. |
213 ASSERT(parameter->owner() == this); | 215 ASSERT(parameter->owner() == this); |
214 if (parameter->is_captured()) { | 216 if (parameter->is_captured()) { |
(...skipping 19 matching lines...) Expand all Loading... |
234 *found_captured_variables = true; | 236 *found_captured_variables = true; |
235 } else { | 237 } else { |
236 variable->set_index(frame_index--); | 238 variable->set_index(frame_index--); |
237 } | 239 } |
238 } | 240 } |
239 } | 241 } |
240 // Allocate variables of all children. | 242 // Allocate variables of all children. |
241 int min_frame_index = frame_index; // Frame index decreases with allocations. | 243 int min_frame_index = frame_index; // Frame index decreases with allocations. |
242 LocalScope* child = this->child(); | 244 LocalScope* child = this->child(); |
243 while (child != NULL) { | 245 while (child != NULL) { |
244 int const dummy_parameter_index = 0; // Ignored, since no parameters. | 246 int const dummy_parameter_index = 0; // Ignored, since no parameters. |
245 int const num_parameters_in_child = 0; // No parameters in children scopes. | 247 int const num_parameters_in_child = 0; // No parameters in children scopes. |
246 int child_frame_index = child->AllocateVariables(dummy_parameter_index, | 248 int child_frame_index = child->AllocateVariables( |
247 num_parameters_in_child, | 249 dummy_parameter_index, num_parameters_in_child, frame_index, |
248 frame_index, | 250 context_owner, found_captured_variables); |
249 context_owner, | |
250 found_captured_variables); | |
251 if (child_frame_index < min_frame_index) { | 251 if (child_frame_index < min_frame_index) { |
252 min_frame_index = child_frame_index; | 252 min_frame_index = child_frame_index; |
253 } | 253 } |
254 child = child->sibling(); | 254 child = child->sibling(); |
255 } | 255 } |
256 return min_frame_index; | 256 return min_frame_index; |
257 } | 257 } |
258 | 258 |
259 | 259 |
260 // The parser creates internal variables that start with ":" | 260 // The parser creates internal variables that start with ":" |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
455 SourceLabel* LocalScope::LookupInnermostLabel(Token::Kind jump_kind) { | 455 SourceLabel* LocalScope::LookupInnermostLabel(Token::Kind jump_kind) { |
456 ASSERT((jump_kind == Token::kCONTINUE) || (jump_kind == Token::kBREAK)); | 456 ASSERT((jump_kind == Token::kCONTINUE) || (jump_kind == Token::kBREAK)); |
457 LocalScope* current_scope = this; | 457 LocalScope* current_scope = this; |
458 while (current_scope != NULL) { | 458 while (current_scope != NULL) { |
459 for (intptr_t i = 0; i < current_scope->labels_.length(); i++) { | 459 for (intptr_t i = 0; i < current_scope->labels_.length(); i++) { |
460 SourceLabel* label = current_scope->labels_[i]; | 460 SourceLabel* label = current_scope->labels_[i]; |
461 if ((label->kind() == SourceLabel::kWhile) || | 461 if ((label->kind() == SourceLabel::kWhile) || |
462 (label->kind() == SourceLabel::kFor) || | 462 (label->kind() == SourceLabel::kFor) || |
463 (label->kind() == SourceLabel::kDoWhile) || | 463 (label->kind() == SourceLabel::kDoWhile) || |
464 ((jump_kind == Token::kBREAK) && | 464 ((jump_kind == Token::kBREAK) && |
465 (label->kind() == SourceLabel::kSwitch))) { | 465 (label->kind() == SourceLabel::kSwitch))) { |
466 return label; | 466 return label; |
467 } | 467 } |
468 } | 468 } |
469 current_scope = current_scope->parent(); | 469 current_scope = current_scope->parent(); |
470 } | 470 } |
471 return NULL; | 471 return NULL; |
472 } | 472 } |
473 | 473 |
474 | 474 |
475 LocalScope* LocalScope::LookupSwitchScope() { | 475 LocalScope* LocalScope::LookupSwitchScope() { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
526 if (variable->owner()->function_level() != 1) { | 526 if (variable->owner()->function_level() != 1) { |
527 ASSERT(variable->is_captured()); | 527 ASSERT(variable->is_captured()); |
528 ASSERT(variable->owner()->function_level() == 0); | 528 ASSERT(variable->owner()->function_level() == 0); |
529 num_captured++; | 529 num_captured++; |
530 } | 530 } |
531 } | 531 } |
532 return num_captured; | 532 return num_captured; |
533 } | 533 } |
534 | 534 |
535 | 535 |
536 RawContextScope* LocalScope::PreserveOuterScope(int current_context_level) | 536 RawContextScope* LocalScope::PreserveOuterScope( |
537 const { | 537 int current_context_level) const { |
538 // Since code generation for nested functions is postponed until first | 538 // Since code generation for nested functions is postponed until first |
539 // invocation, the function level of the closure scope can only be 1. | 539 // invocation, the function level of the closure scope can only be 1. |
540 ASSERT(function_level() == 1); | 540 ASSERT(function_level() == 1); |
541 | 541 |
542 // Count the number of referenced captured variables. | 542 // Count the number of referenced captured variables. |
543 intptr_t num_captured_vars = NumCapturedVariables(); | 543 intptr_t num_captured_vars = NumCapturedVariables(); |
544 | 544 |
545 // Create a ContextScope with space for num_captured_vars descriptors. | 545 // Create a ContextScope with space for num_captured_vars descriptors. |
546 const ContextScope& context_scope = | 546 const ContextScope& context_scope = |
547 ContextScope::Handle(ContextScope::New(num_captured_vars, false)); | 547 ContextScope::Handle(ContextScope::New(num_captured_vars, false)); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
580 | 580 |
581 | 581 |
582 LocalScope* LocalScope::RestoreOuterScope(const ContextScope& context_scope) { | 582 LocalScope* LocalScope::RestoreOuterScope(const ContextScope& context_scope) { |
583 // The function level of the outer scope is one less than the function level | 583 // The function level of the outer scope is one less than the function level |
584 // of the current function, which is 0. | 584 // of the current function, which is 0. |
585 LocalScope* outer_scope = new LocalScope(NULL, -1, 0); | 585 LocalScope* outer_scope = new LocalScope(NULL, -1, 0); |
586 // Add all variables as aliases to the outer scope. | 586 // Add all variables as aliases to the outer scope. |
587 for (int i = 0; i < context_scope.num_variables(); i++) { | 587 for (int i = 0; i < context_scope.num_variables(); i++) { |
588 LocalVariable* variable; | 588 LocalVariable* variable; |
589 if (context_scope.IsConstAt(i)) { | 589 if (context_scope.IsConstAt(i)) { |
590 variable = new LocalVariable( | 590 variable = new LocalVariable(context_scope.DeclarationTokenIndexAt(i), |
591 context_scope.DeclarationTokenIndexAt(i), | 591 context_scope.TokenIndexAt(i), |
592 context_scope.TokenIndexAt(i), | 592 String::ZoneHandle(context_scope.NameAt(i)), |
593 String::ZoneHandle(context_scope.NameAt(i)), | 593 Object::dynamic_type()); |
594 Object::dynamic_type()); | |
595 variable->SetConstValue( | 594 variable->SetConstValue( |
596 Instance::ZoneHandle(context_scope.ConstValueAt(i))); | 595 Instance::ZoneHandle(context_scope.ConstValueAt(i))); |
597 } else { | 596 } else { |
598 variable = new LocalVariable( | 597 variable = |
599 context_scope.DeclarationTokenIndexAt(i), | 598 new LocalVariable(context_scope.DeclarationTokenIndexAt(i), |
600 context_scope.TokenIndexAt(i), | 599 context_scope.TokenIndexAt(i), |
601 String::ZoneHandle(context_scope.NameAt(i)), | 600 String::ZoneHandle(context_scope.NameAt(i)), |
602 AbstractType::ZoneHandle(context_scope.TypeAt(i))); | 601 AbstractType::ZoneHandle(context_scope.TypeAt(i))); |
603 } | 602 } |
604 variable->set_is_captured(); | 603 variable->set_is_captured(); |
605 variable->set_index(context_scope.ContextIndexAt(i)); | 604 variable->set_index(context_scope.ContextIndexAt(i)); |
606 if (context_scope.IsFinalAt(i)) { | 605 if (context_scope.IsFinalAt(i)) { |
607 variable->set_is_final(); | 606 variable->set_is_final(); |
608 } | 607 } |
609 // Create a fake owner scope describing the index and context level of the | 608 // Create a fake owner scope describing the index and context level of the |
610 // variable. Function level and loop level are unused (set to 0), since | 609 // variable. Function level and loop level are unused (set to 0), since |
611 // context level has already been assigned. | 610 // context level has already been assigned. |
612 LocalScope* owner_scope = new LocalScope(NULL, 0, 0); | 611 LocalScope* owner_scope = new LocalScope(NULL, 0, 0); |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
687 return fixed_parameter_count - (index() - kParamEndSlotFromFp); | 686 return fixed_parameter_count - (index() - kParamEndSlotFromFp); |
688 } else { | 687 } else { |
689 // Shift negative indexes so that the lowest one is 0 (they are still | 688 // Shift negative indexes so that the lowest one is 0 (they are still |
690 // non-positive). | 689 // non-positive). |
691 return fixed_parameter_count - (index() - kFirstLocalSlotFromFp); | 690 return fixed_parameter_count - (index() - kFirstLocalSlotFromFp); |
692 } | 691 } |
693 } | 692 } |
694 | 693 |
695 | 694 |
696 } // namespace dart | 695 } // namespace dart |
OLD | NEW |