mica_language/value/
closures.rs1use std::cell::UnsafeCell;
2use std::marker::PhantomPinned;
3use std::pin::Pin;
4use std::rc::Rc;
5use std::{fmt, mem, ptr};
6
7use crate::bytecode::Opr24;
8
9use super::RawValue;
10
11pub struct Upvalue {
13 pub(crate) ptr: UnsafeCell<ptr::NonNull<RawValue>>,
15 closed: UnsafeCell<RawValue>,
17
18 _pinned: PhantomPinned,
19}
20
21impl fmt::Debug for Upvalue {
22 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
23 f.debug_struct("Upvalue")
24 .field("ptr", unsafe { self.ptr.get().as_ref() }.unwrap())
25 .field("closed", unsafe { self.closed.get().as_ref() }.unwrap())
26 .finish_non_exhaustive()
27 }
28}
29
30impl Upvalue {
31 pub(crate) fn new(var: ptr::NonNull<RawValue>) -> Pin<Rc<Upvalue>> {
33 Rc::pin(Upvalue {
34 ptr: UnsafeCell::new(var),
35 closed: UnsafeCell::new(RawValue::from(())),
36 _pinned: PhantomPinned,
37 })
38 }
39
40 pub(crate) unsafe fn close(&self) {
47 let ptr = &mut *self.ptr.get();
48 let closed = &mut *self.closed.get();
49 let value = mem::take(ptr.as_mut());
50 *closed = value;
51 *ptr = ptr::NonNull::new(closed).unwrap();
52 }
53
54 pub(crate) unsafe fn get(&self) -> RawValue {
60 *(*self.ptr.get()).as_ptr()
61 }
62
63 pub(crate) unsafe fn set(&self, value: RawValue) {
69 *(*self.ptr.get()).as_ptr() = value;
70 }
71}
72
73#[derive(Debug)]
75#[repr(align(8))]
76pub struct Closure {
77 pub function_id: Opr24,
78 pub captures: Vec<Pin<Rc<Upvalue>>>,
79}