use std::{cell::UnsafeCell, fmt, marker::PhantomPinned, mem, pin::Pin, ptr, rc::Rc};
use super::RawValue;
use crate::ll::bytecode::FunctionIndex;
pub struct Upvalue {
pub(crate) ptr: UnsafeCell<ptr::NonNull<RawValue>>,
closed: UnsafeCell<RawValue>,
_pinned: PhantomPinned,
}
impl fmt::Debug for Upvalue {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Upvalue")
.field("ptr", unsafe { self.ptr.get().as_ref() }.unwrap())
.field("closed", unsafe { self.closed.get().as_ref() }.unwrap())
.finish_non_exhaustive()
}
}
impl Upvalue {
pub(crate) fn new(var: ptr::NonNull<RawValue>) -> Pin<Rc<Upvalue>> {
Rc::pin(Upvalue {
ptr: UnsafeCell::new(var),
closed: UnsafeCell::new(RawValue::from(())),
_pinned: PhantomPinned,
})
}
pub(crate) unsafe fn close(&self) {
let ptr = &mut *self.ptr.get();
let closed = &mut *self.closed.get();
let value = mem::take(ptr.as_mut());
*closed = value;
*ptr = ptr::NonNull::new(closed).unwrap();
}
pub(crate) unsafe fn get(&self) -> RawValue {
*(*self.ptr.get()).as_ptr()
}
pub(crate) unsafe fn set(&self, value: RawValue) {
*(*self.ptr.get()).as_ptr() = value;
}
}
#[derive(Debug)]
#[repr(align(8))]
pub struct Closure {
pub name: Rc<str>,
pub function_id: FunctionIndex,
pub captures: Vec<Pin<Rc<Upvalue>>>,
}