use crate::{module, store::Stored, AsContextMut};
use alloc::sync::Arc;
use wasmi_arena::ArenaIndex;
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct DataSegmentIdx(u32);
impl ArenaIndex for DataSegmentIdx {
fn into_usize(self) -> usize {
self.0 as usize
}
fn from_usize(value: usize) -> Self {
let value = value.try_into().unwrap_or_else(|error| {
panic!("index {value} is out of bounds as data segment index: {error}")
});
Self(value)
}
}
#[derive(Debug, Copy, Clone)]
#[repr(transparent)]
pub struct DataSegment(Stored<DataSegmentIdx>);
impl DataSegment {
pub fn from_inner(stored: Stored<DataSegmentIdx>) -> Self {
Self(stored)
}
pub fn as_inner(&self) -> &Stored<DataSegmentIdx> {
&self.0
}
pub fn new(mut ctx: impl AsContextMut, segment: &module::DataSegment) -> Self {
let entity = DataSegmentEntity::from(segment);
ctx.as_context_mut().store.inner.alloc_data_segment(entity)
}
}
#[derive(Debug)]
pub struct DataSegmentEntity {
bytes: Option<Arc<[u8]>>,
}
impl From<&'_ module::DataSegment> for DataSegmentEntity {
fn from(segment: &'_ module::DataSegment) -> Self {
match segment.kind() {
module::DataSegmentKind::Passive => Self {
bytes: Some(segment.clone_bytes()),
},
module::DataSegmentKind::Active(_) => Self::empty(),
}
}
}
impl DataSegmentEntity {
fn empty() -> Self {
Self { bytes: None }
}
pub fn bytes(&self) -> &[u8] {
self.bytes
.as_ref()
.map(|bytes| &bytes[..])
.unwrap_or_else(|| &[])
}
pub fn drop_bytes(&mut self) {
self.bytes = None;
}
}