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 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
453 // Create a descriptor for each referenced captured variable of enclosing | 453 // Create a descriptor for each referenced captured variable of enclosing |
454 // functions to preserve its name and its context allocation information. | 454 // functions to preserve its name and its context allocation information. |
455 int captured_idx = 0; | 455 int captured_idx = 0; |
456 for (int i = 0; i < num_variables(); i++) { | 456 for (int i = 0; i < num_variables(); i++) { |
457 LocalVariable* variable = VariableAt(i); | 457 LocalVariable* variable = VariableAt(i); |
458 // Preserve the aliases of captured variables belonging to outer scopes. | 458 // Preserve the aliases of captured variables belonging to outer scopes. |
459 if (variable->owner()->function_level() != 1) { | 459 if (variable->owner()->function_level() != 1) { |
460 context_scope.SetTokenIndexAt(captured_idx, variable->token_pos()); | 460 context_scope.SetTokenIndexAt(captured_idx, variable->token_pos()); |
461 context_scope.SetNameAt(captured_idx, variable->name()); | 461 context_scope.SetNameAt(captured_idx, variable->name()); |
462 context_scope.SetIsFinalAt(captured_idx, variable->is_final()); | 462 context_scope.SetIsFinalAt(captured_idx, variable->is_final()); |
463 context_scope.SetTypeAt(captured_idx, variable->type()); | 463 context_scope.SetIsConstAt(captured_idx, variable->IsConst()); |
| 464 if (variable->IsConst()) { |
| 465 context_scope.SetConstValueAt(captured_idx, *variable->ConstValue()); |
| 466 } else { |
| 467 context_scope.SetTypeAt(captured_idx, variable->type()); |
| 468 } |
464 context_scope.SetContextIndexAt(captured_idx, variable->index()); | 469 context_scope.SetContextIndexAt(captured_idx, variable->index()); |
465 // Adjust the context level relative to the current context level, | 470 // Adjust the context level relative to the current context level, |
466 // since the context of the current scope will be at level 0 when | 471 // since the context of the current scope will be at level 0 when |
467 // compiling the nested function. | 472 // compiling the nested function. |
468 int adjusted_context_level = | 473 int adjusted_context_level = |
469 variable->owner()->context_level() - current_context_level; | 474 variable->owner()->context_level() - current_context_level; |
470 context_scope.SetContextLevelAt(captured_idx, adjusted_context_level); | 475 context_scope.SetContextLevelAt(captured_idx, adjusted_context_level); |
471 captured_idx++; | 476 captured_idx++; |
472 } | 477 } |
473 } | 478 } |
474 ASSERT(context_scope.num_variables() == captured_idx); // Verify count. | 479 ASSERT(context_scope.num_variables() == captured_idx); // Verify count. |
475 return context_scope.raw(); | 480 return context_scope.raw(); |
476 } | 481 } |
477 | 482 |
478 | 483 |
479 LocalScope* LocalScope::RestoreOuterScope(const ContextScope& context_scope) { | 484 LocalScope* LocalScope::RestoreOuterScope(const ContextScope& context_scope) { |
480 // The function level of the outer scope is one less than the function level | 485 // The function level of the outer scope is one less than the function level |
481 // of the current function, which is 0. | 486 // of the current function, which is 0. |
482 LocalScope* outer_scope = new LocalScope(NULL, -1, 0); | 487 LocalScope* outer_scope = new LocalScope(NULL, -1, 0); |
483 // Add all variables as aliases to the outer scope. | 488 // Add all variables as aliases to the outer scope. |
484 for (int i = 0; i < context_scope.num_variables(); i++) { | 489 for (int i = 0; i < context_scope.num_variables(); i++) { |
485 LocalVariable* variable = | 490 LocalVariable* variable; |
486 new LocalVariable(context_scope.TokenIndexAt(i), | 491 if (context_scope.IsConstAt(i)) { |
487 String::ZoneHandle(context_scope.NameAt(i)), | 492 variable = new LocalVariable(context_scope.TokenIndexAt(i), |
488 AbstractType::ZoneHandle(context_scope.TypeAt(i))); | 493 String::ZoneHandle(context_scope.NameAt(i)), |
| 494 AbstractType::ZoneHandle(Type::DynamicType())); |
| 495 variable->SetConstValue( |
| 496 Instance::ZoneHandle(context_scope.ConstValueAt(i))); |
| 497 } else { |
| 498 variable = new LocalVariable(context_scope.TokenIndexAt(i), |
| 499 String::ZoneHandle(context_scope.NameAt(i)), |
| 500 AbstractType::ZoneHandle(context_scope.TypeAt(i))); |
| 501 } |
489 variable->set_is_captured(); | 502 variable->set_is_captured(); |
490 variable->set_index(context_scope.ContextIndexAt(i)); | 503 variable->set_index(context_scope.ContextIndexAt(i)); |
491 if (context_scope.IsFinalAt(i)) { | 504 if (context_scope.IsFinalAt(i)) { |
492 variable->set_is_final(); | 505 variable->set_is_final(); |
493 } | 506 } |
494 // Create a fake owner scope describing the index and context level of the | 507 // Create a fake owner scope describing the index and context level of the |
495 // variable. Function level and loop level are unused (set to 0), since | 508 // variable. Function level and loop level are unused (set to 0), since |
496 // context level has already been assigned. | 509 // context level has already been assigned. |
497 LocalScope* owner_scope = new LocalScope(NULL, 0, 0); | 510 LocalScope* owner_scope = new LocalScope(NULL, 0, 0); |
498 owner_scope->set_context_level(context_scope.ContextLevelAt(i)); | 511 owner_scope->set_context_level(context_scope.ContextLevelAt(i)); |
(...skipping 10 matching lines...) Expand all Loading... |
509 | 522 |
510 // Create a ContextScope with space for kNumCapturedVars descriptors. | 523 // Create a ContextScope with space for kNumCapturedVars descriptors. |
511 const ContextScope& context_scope = | 524 const ContextScope& context_scope = |
512 ContextScope::Handle(ContextScope::New(kNumCapturedVars)); | 525 ContextScope::Handle(ContextScope::New(kNumCapturedVars)); |
513 | 526 |
514 // Create a descriptor for 'this' variable. | 527 // Create a descriptor for 'this' variable. |
515 const String& name = String::Handle(Symbols::This()); | 528 const String& name = String::Handle(Symbols::This()); |
516 context_scope.SetTokenIndexAt(0, func.token_pos()); | 529 context_scope.SetTokenIndexAt(0, func.token_pos()); |
517 context_scope.SetNameAt(0, name); | 530 context_scope.SetNameAt(0, name); |
518 context_scope.SetIsFinalAt(0, true); | 531 context_scope.SetIsFinalAt(0, true); |
| 532 context_scope.SetIsConstAt(0, false); |
519 const AbstractType& type = AbstractType::Handle(func.ParameterTypeAt(0)); | 533 const AbstractType& type = AbstractType::Handle(func.ParameterTypeAt(0)); |
520 context_scope.SetTypeAt(0, type); | 534 context_scope.SetTypeAt(0, type); |
521 context_scope.SetContextIndexAt(0, 0); | 535 context_scope.SetContextIndexAt(0, 0); |
522 context_scope.SetContextLevelAt(0, 0); | 536 context_scope.SetContextLevelAt(0, 0); |
523 ASSERT(context_scope.num_variables() == kNumCapturedVars); // Verify count. | 537 ASSERT(context_scope.num_variables() == kNumCapturedVars); // Verify count. |
524 return context_scope.raw(); | 538 return context_scope.raw(); |
525 } | 539 } |
526 | 540 |
527 | 541 |
528 bool LocalVariable::Equals(const LocalVariable& other) const { | 542 bool LocalVariable::Equals(const LocalVariable& other) const { |
(...skipping 22 matching lines...) Expand all Loading... |
551 } else { | 565 } else { |
552 // Shift negative indexes so that the lowest one is 0 (they are still | 566 // Shift negative indexes so that the lowest one is 0 (they are still |
553 // non-positive). | 567 // non-positive). |
554 return fixed_parameter_count - | 568 return fixed_parameter_count - |
555 (index() - ParsedFunction::kFirstLocalSlotIndex); | 569 (index() - ParsedFunction::kFirstLocalSlotIndex); |
556 } | 570 } |
557 } | 571 } |
558 | 572 |
559 | 573 |
560 } // namespace dart | 574 } // namespace dart |
OLD | NEW |