| 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 |