use bitflags::bitflags;
pub(crate) type SlotIndex = u32;
bitflags! {
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub(crate) struct SlotAttributes: u8 {
const WRITABLE = 0b0000_0001;
const ENUMERABLE = 0b0000_0010;
const CONFIGURABLE = 0b0000_0100;
const GET = 0b0000_1000;
const SET = 0b0001_0000;
const INLINE_CACHE_BITS = 0b1110_0000;
const PROTOTYPE = 0b0010_0000;
const FOUND = 0b0100_0000;
const NOT_CACHABLE = 0b1000_0000;
}
}
impl SlotAttributes {
pub(crate) const fn is_accessor_descriptor(self) -> bool {
self.contains(Self::GET) || self.contains(Self::SET)
}
pub(crate) const fn has_get(self) -> bool {
self.contains(Self::GET)
}
pub(crate) const fn has_set(self) -> bool {
self.contains(Self::SET)
}
pub(crate) const fn width_match(self, other: Self) -> bool {
self.is_accessor_descriptor() == other.is_accessor_descriptor()
}
pub(crate) fn width(self) -> u32 {
1 + u32::from(self.is_accessor_descriptor())
}
pub(crate) const fn is_cachable(self) -> bool {
!self.contains(Self::NOT_CACHABLE) && self.contains(Self::FOUND)
}
#[cfg(test)]
pub(crate) const fn in_prototype(self) -> bool {
self.contains(Self::PROTOTYPE)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) struct Slot {
pub(crate) index: SlotIndex,
pub(crate) attributes: SlotAttributes,
}
impl Slot {
pub(crate) const fn new() -> Self {
Self {
index: 0,
attributes: SlotAttributes::empty(),
}
}
pub(crate) const fn is_cachable(self) -> bool {
self.attributes.is_cachable()
}
#[cfg(test)]
pub(crate) const fn in_prototype(self) -> bool {
self.attributes.in_prototype()
}
pub(crate) fn width(self) -> u32 {
self.attributes.width()
}
pub(crate) fn from_previous(
previous_slot: Option<Self>,
new_attributes: SlotAttributes,
) -> Self {
let Some(previous_slot) = previous_slot else {
return Self {
index: 0,
attributes: new_attributes,
};
};
Self {
index: previous_slot.index + previous_slot.width(),
attributes: new_attributes,
}
}
pub(crate) fn set_not_cachable_if_already_prototype(&mut self) {
self.attributes |= SlotAttributes::from_bits_retain(
(self.attributes.bits() & SlotAttributes::PROTOTYPE.bits()) << 2,
);
}
}