wasmer_types/
initializers.rs

1use crate::indexes::{FunctionIndex, GlobalIndex, MemoryIndex, TableIndex};
2use crate::lib::std::boxed::Box;
3
4use enumset::__internal::EnumSetTypeRepr;
5use rkyv::{Archive, CheckBytes, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize};
6#[cfg(feature = "enable-serde")]
7use serde::{Deserialize, Serialize};
8
9/// A WebAssembly table initializer.
10#[derive(Clone, Debug, Hash, PartialEq, Eq, RkyvSerialize, RkyvDeserialize, Archive)]
11#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
12#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))]
13#[archive_attr(derive(CheckBytes, Debug))]
14pub struct TableInitializer {
15    /// The index of a table to initialize.
16    pub table_index: TableIndex,
17    /// Optionally, a global variable giving a base index.
18    pub base: Option<GlobalIndex>,
19    /// The offset to add to the base.
20    pub offset: usize,
21    /// The values to write into the table elements.
22    pub elements: Box<[FunctionIndex]>,
23}
24
25/// A memory index and offset within that memory where a data initialization
26/// should be performed.
27#[derive(Clone, Debug, PartialEq, Eq, RkyvSerialize, RkyvDeserialize, Archive)]
28#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))]
29#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
30#[archive_attr(derive(CheckBytes, Debug))]
31pub struct DataInitializerLocation {
32    /// The index of the memory to initialize.
33    pub memory_index: MemoryIndex,
34
35    /// Optionally a Global variable base to initialize at.
36    pub base: Option<GlobalIndex>,
37
38    /// A constant offset to initialize at.
39    pub offset: usize,
40}
41
42/// Any struct that acts like a `DataInitializerLocation`.
43#[allow(missing_docs)]
44pub trait DataInitializerLocationLike {
45    fn memory_index(&self) -> MemoryIndex;
46    fn base(&self) -> Option<GlobalIndex>;
47    fn offset(&self) -> usize;
48}
49
50impl DataInitializerLocationLike for &DataInitializerLocation {
51    fn memory_index(&self) -> MemoryIndex {
52        self.memory_index
53    }
54
55    fn base(&self) -> Option<GlobalIndex> {
56        self.base
57    }
58
59    fn offset(&self) -> usize {
60        self.offset
61    }
62}
63
64impl DataInitializerLocationLike for &ArchivedDataInitializerLocation {
65    fn memory_index(&self) -> MemoryIndex {
66        MemoryIndex::from_u32(self.memory_index.as_u32())
67    }
68
69    fn base(&self) -> Option<GlobalIndex> {
70        match self.base {
71            rkyv::option::ArchivedOption::None => None,
72            rkyv::option::ArchivedOption::Some(base) => Some(GlobalIndex::from_u32(base.as_u32())),
73        }
74    }
75
76    fn offset(&self) -> usize {
77        self.offset.to_usize()
78    }
79}
80
81/// A data initializer for linear memory.
82#[derive(Debug)]
83#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
84pub struct DataInitializer<'data> {
85    /// The location where the initialization is to be performed.
86    pub location: DataInitializerLocation,
87
88    /// The initialization data.
89    pub data: &'data [u8],
90}
91
92/// As `DataInitializer` but owning the data rather than
93/// holding a reference to it
94#[derive(Debug, Clone, PartialEq, Eq, RkyvSerialize, RkyvDeserialize, Archive)]
95#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
96#[cfg_attr(feature = "artifact-size", derive(loupe::MemoryUsage))]
97#[archive_attr(derive(CheckBytes, Debug))]
98pub struct OwnedDataInitializer {
99    /// The location where the initialization is to be performed.
100    pub location: DataInitializerLocation,
101
102    /// The initialization owned data.
103    pub data: Box<[u8]>,
104}
105
106/// Any struct that acts like a `DataInitializer`.
107#[allow(missing_docs)]
108pub trait DataInitializerLike<'a> {
109    type Location: DataInitializerLocationLike + Copy + 'a;
110
111    fn location(&self) -> Self::Location;
112    fn data(&self) -> &'a [u8];
113}
114
115impl OwnedDataInitializer {
116    /// Creates a new `OwnedDataInitializer` from a `DataInitializer`.
117    pub fn new(borrowed: &DataInitializer<'_>) -> Self {
118        Self {
119            location: borrowed.location.clone(),
120            data: borrowed.data.to_vec().into_boxed_slice(),
121        }
122    }
123}
124
125impl<'a> DataInitializerLike<'a> for &'a OwnedDataInitializer {
126    type Location = &'a DataInitializerLocation;
127
128    fn location(&self) -> Self::Location {
129        &self.location
130    }
131
132    fn data(&self) -> &'a [u8] {
133        self.data.as_ref()
134    }
135}
136
137impl<'a> DataInitializerLike<'a> for &'a ArchivedOwnedDataInitializer {
138    type Location = &'a ArchivedDataInitializerLocation;
139
140    fn location(&self) -> Self::Location {
141        &self.location
142    }
143
144    fn data(&self) -> &'a [u8] {
145        self.data.as_ref()
146    }
147}