Kaynağa Gözat

Explorer: move deallocation to `StepCleanUp` (#2547)

Move deallocation logic to `StepCleanUp` to have all necessary cleanup actions in the same place. Currently this means `DestroyAction` and `heap_.Deallocate`.
Adrien Leravat 3 yıl önce
ebeveyn
işleme
7222f349d6

+ 0 - 7
explorer/interpreter/action.cpp

@@ -35,13 +35,6 @@ auto RuntimeScope::operator=(RuntimeScope&& rhs) noexcept -> RuntimeScope& {
   return *this;
 }
 
-RuntimeScope::~RuntimeScope() {
-  for (auto allocation : allocations_) {
-    // TODO: move this into StepCleanUp
-    heap_->Deallocate(allocation);
-  }
-}
-
 void RuntimeScope::Print(llvm::raw_ostream& out) const {
   out << "{";
   llvm::ListSeparator sep;

+ 0 - 3
explorer/interpreter/action.h

@@ -42,9 +42,6 @@ class RuntimeScope {
   RuntimeScope(RuntimeScope&&) noexcept;
   auto operator=(RuntimeScope&&) noexcept -> RuntimeScope&;
 
-  // Deallocates any allocations in this scope from `heap`.
-  ~RuntimeScope();
-
   void Print(llvm::raw_ostream& out) const;
   LLVM_DUMP_METHOD void Dump() const { Print(llvm::errs()); }
 

+ 14 - 9
explorer/interpreter/interpreter.cpp

@@ -2214,16 +2214,21 @@ auto Interpreter::StepDestroy() -> ErrorOr<Success> {
 auto Interpreter::StepCleanUp() -> ErrorOr<Success> {
   const Action& act = todo_.CurrentAction();
   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 {
+      heap_.Deallocate(allocation);
       return todo_.RunAgain();
     }
   }