---
date: 2024-09-22 21:15
---

Reference Countにする場合、Dropをどう実装するか

drop_array()、drop_closure()をプリミティブ命令として用意する？

プリミティブな値の配列ならそのまま開放してよし、オブジェクトを含む（配列の配列とか、クロージャの配列）なら再帰的にdropする必要あり

drop命令をどのタイミングで挿入するか
mirgenでletの生存期間を調べるしかない
bindsでArgumentの区別はされてるから、環境参照してArgument以外を全部dropする、みたいな感じでええのか

```rust

enum UpvalueKind{
 Open{base_ptr:u64,offset:u64},
 Closed(ObjectIdx)
}
struct Upvalue{
	data:UpvalueKind,
	ty: ObjType,
}

type SharedUpValue = Rc<RefCell<Upvalue>>
struct Closure{
 pub fnproto_i: u64,
 pub base_ptr: u64, //base pointer to current closure, to calculate open upvalue
 pub is_closed: bool,
 pub upvalues: Vec<SharedUpValue>,
 pub state_storage:StateStorage,
}
struct Array{
 pub d_size:TypeSize,
 pub raw_data: Vec<RawVal>,
}
union HeapObject{
  clousre: Closure,
  array: Array,
  primitive: Vec<RawVal>,
}
struct RcObject{
  refcount:u64,
  data: HeapObject
}
type = ObjectStorage=SlotMap<DefaultKey, RcObject>;
type = ObjectIdx = DefaultKey;

impl Machine{
...
  fn drop_closure(&mut self, objectid:ObjectIdx){
	let obj = self.get_object_mut(objectid);
	obj.refcount-=1;
	if obj.refcount==0{
      let cls = unsafe{ &obj.data.closure };
      cls.upvalue.iter().for_each(|upv|{
	      upv
      })
      self.object_storage.remove(objectid)
	}
  }
}

```