mica_language/value/
structs.rs1use std::cell::{Cell, UnsafeCell};
2
3use crate::bytecode::DispatchTable;
4use crate::common::ErrorKind;
5use crate::gc::GcRaw;
6
7use super::RawValue;
8
9#[repr(align(8))]
14pub struct Struct {
15 pub(crate) dtable: UnsafeCell<GcRaw<DispatchTable>>,
18 sealed: Cell<bool>,
19 fields: UnsafeCell<Vec<RawValue>>,
20}
21
22impl Struct {
23 pub fn new_type(dtable: GcRaw<DispatchTable>) -> Self {
25 Self {
26 dtable: UnsafeCell::new(dtable),
27 sealed: Cell::new(false),
28 fields: UnsafeCell::new(Vec::new()),
29 }
30 }
31
32 pub(crate) unsafe fn new_instance(&self, field_count: usize) -> Self {
34 Self {
35 dtable: UnsafeCell::new(self.dtable().instance.unwrap_unchecked()),
36 sealed: Cell::new(true),
37 fields: UnsafeCell::new(std::iter::repeat(RawValue::from(())).take(field_count).collect()),
38 }
39 }
40
41 pub unsafe fn dtable<'a>(&self) -> &'a DispatchTable {
51 self.dtable.get().as_ref().unwrap_unchecked().get()
52 }
53
54 pub(crate) fn implement(&self, dtable: GcRaw<DispatchTable>) -> Result<(), ErrorKind> {
56 if self.sealed.get() {
57 return Err(ErrorKind::StructAlreadyImplemented);
58 }
59 unsafe { *self.dtable.get() = dtable }
60 self.sealed.set(true);
61 Ok(())
62 }
63
64 pub(crate) unsafe fn get_field(&self, index: usize) -> RawValue {
69 *(*self.fields.get()).get_unchecked(index)
70 }
71
72 pub(crate) unsafe fn set_field(&self, index: usize, value: RawValue) {
77 *(*self.fields.get()).get_unchecked_mut(index) = value;
78 }
79
80 pub(crate) unsafe fn fields(&self) -> impl Iterator<Item = RawValue> + '_ {
81 (*self.fields.get()).iter().copied()
82 }
83}