wasmer_types/
initializers.rs

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