use crate::v2::closure_layout::{CaptureKind, ClosureLayout, SharedCell, TypedClosureHeader};
use crate::v2::closure_raw::{
read_capture_as_value_bits, typed_closure_function_id, typed_closure_refcount,
typed_closure_type_id,
};
pub struct VmClosureHandle<'a> {
ptr: *const TypedClosureHeader,
layout: &'a ClosureLayout,
}
impl<'a> VmClosureHandle<'a> {
#[inline]
pub unsafe fn raw(ptr: *const TypedClosureHeader, layout: &'a ClosureLayout) -> Self {
VmClosureHandle { ptr, layout }
}
#[inline]
pub fn function_id(&self) -> u32 {
unsafe { typed_closure_function_id(self.ptr as *const u8) as u32 }
}
#[inline]
pub fn type_id(&self) -> u32 {
unsafe { typed_closure_type_id(self.ptr as *const u8) }
}
#[inline]
pub fn capture_count(&self) -> usize {
self.layout.capture_count()
}
#[inline]
pub fn capture_execution_bits(&self, i: usize) -> u64 {
match self.layout.capture_storage_kind(i) {
CaptureKind::Immutable => {
unsafe { read_capture_as_value_bits(self.ptr as *const u8, self.layout, i) }
}
CaptureKind::OwnedMutable => {
unsafe { owned_mutable_cell_ptr(self.ptr, self.layout, i) as u64 }
}
CaptureKind::Shared => {
unsafe { shared_cell_ptr(self.ptr, self.layout, i) as u64 }
}
}
}
#[inline]
pub fn capture_owned_mutable_ptr(&self, i: usize) -> Option<*mut u64> {
match self.layout.capture_storage_kind(i) {
CaptureKind::OwnedMutable => {
Some(unsafe { owned_mutable_cell_ptr(self.ptr, self.layout, i) })
}
_ => None,
}
}
#[inline]
pub fn capture_shared_cell_ptr(&self, i: usize) -> Option<*const SharedCell> {
match self.layout.capture_storage_kind(i) {
CaptureKind::Shared => Some(unsafe { shared_cell_ptr(self.ptr, self.layout, i) }),
_ => None,
}
}
#[inline]
pub fn refcount(&self) -> u32 {
unsafe { typed_closure_refcount(self.ptr as *const u8) }
}
}
#[inline]
unsafe fn owned_mutable_cell_ptr(
ptr: *const TypedClosureHeader,
layout: &ClosureLayout,
i: usize,
) -> *mut u64 {
let off = layout.heap_capture_offset(i);
unsafe { std::ptr::read((ptr as *const u8).add(off) as *const *mut u64) }
}
#[inline]
unsafe fn shared_cell_ptr(
ptr: *const TypedClosureHeader,
layout: &ClosureLayout,
i: usize,
) -> *const SharedCell {
let off = layout.heap_capture_offset(i);
unsafe { std::ptr::read((ptr as *const u8).add(off) as *const *const SharedCell) }
}