|
@@ -2214,16 +2214,21 @@ auto Interpreter::StepDestroy() -> ErrorOr<Success> {
|
|
|
auto Interpreter::StepCleanUp() -> ErrorOr<Success> {
|
|
auto Interpreter::StepCleanUp() -> ErrorOr<Success> {
|
|
|
const Action& act = todo_.CurrentAction();
|
|
const Action& act = todo_.CurrentAction();
|
|
|
const auto& cleanup = cast<CleanUpAction>(act);
|
|
const auto& cleanup = cast<CleanUpAction>(act);
|
|
|
- if (act.pos() < cleanup.allocations_count()) {
|
|
|
|
|
- auto allocation =
|
|
|
|
|
- act.scope()->allocations()[cleanup.allocations_count() - act.pos() - 1];
|
|
|
|
|
- const auto* lvalue = arena_->New<LValue>(Address(allocation));
|
|
|
|
|
- SourceLocation source_loc("destructor", 1);
|
|
|
|
|
- auto value = heap_.Read(lvalue->address(), source_loc);
|
|
|
|
|
- // Step over uninitialized values
|
|
|
|
|
- if (value.ok()) {
|
|
|
|
|
- return todo_.Spawn(std::make_unique<DestroyAction>(lvalue, *value));
|
|
|
|
|
|
|
+ if (act.pos() < cleanup.allocations_count() * 2) {
|
|
|
|
|
+ const size_t alloc_index = cleanup.allocations_count() - act.pos() / 2 - 1;
|
|
|
|
|
+ auto allocation = act.scope()->allocations()[alloc_index];
|
|
|
|
|
+ if (act.pos() % 2 == 0) {
|
|
|
|
|
+ auto* lvalue = arena_->New<LValue>(Address(allocation));
|
|
|
|
|
+ auto value =
|
|
|
|
|
+ heap_.Read(lvalue->address(), SourceLocation("destructor", 1));
|
|
|
|
|
+ // Step over uninitialized values.
|
|
|
|
|
+ if (value.ok()) {
|
|
|
|
|
+ return todo_.Spawn(std::make_unique<DestroyAction>(lvalue, *value));
|
|
|
|
|
+ } else {
|
|
|
|
|
+ return todo_.RunAgain();
|
|
|
|
|
+ }
|
|
|
} else {
|
|
} else {
|
|
|
|
|
+ heap_.Deallocate(allocation);
|
|
|
return todo_.RunAgain();
|
|
return todo_.RunAgain();
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|