lucet_module_data/
module_data.rs1use crate::{
2 functions::{
3 ExportFunction, FunctionIndex, FunctionMetadata, ImportFunction, OwnedFunctionMetadata,
4 },
5 globals::GlobalSpec,
6 linear_memory::{HeapSpec, LinearMemorySpec, SparseData},
7 types::Signature,
8 Error,
9};
10use minisign::SignatureBones;
11use serde::{Deserialize, Serialize};
12
13#[derive(Debug, Serialize, Deserialize)]
22pub struct ModuleData<'a> {
23 #[serde(borrow)]
24 linear_memory: Option<LinearMemorySpec<'a>>,
25 #[serde(borrow)]
26 globals_spec: Vec<GlobalSpec<'a>>,
27 #[serde(borrow)]
28 function_info: Vec<FunctionMetadata<'a>>,
29 #[serde(borrow)]
30 import_functions: Vec<ImportFunction<'a>>,
31 #[serde(borrow)]
32 export_functions: Vec<ExportFunction<'a>>,
33 signatures: Vec<Signature>,
34 module_signature: Vec<u8>,
35}
36
37impl<'a> ModuleData<'a> {
38 pub fn new(
39 linear_memory: Option<LinearMemorySpec<'a>>,
40 globals_spec: Vec<GlobalSpec<'a>>,
41 function_info: Vec<FunctionMetadata<'a>>,
42 import_functions: Vec<ImportFunction<'a>>,
43 export_functions: Vec<ExportFunction<'a>>,
44 signatures: Vec<Signature>,
45 ) -> Self {
46 let module_signature = vec![0u8; SignatureBones::BYTES];
47 Self {
48 linear_memory,
49 globals_spec,
50 function_info,
51 import_functions,
52 export_functions,
53 signatures,
54 module_signature,
55 }
56 }
57
58 pub fn heap_spec(&self) -> Option<&HeapSpec> {
59 if let Some(ref linear_memory) = self.linear_memory {
60 Some(&linear_memory.heap)
61 } else {
62 None
63 }
64 }
65
66 pub fn sparse_data(&self) -> Option<&SparseData<'a>> {
67 if let Some(ref linear_memory) = self.linear_memory {
68 Some(&linear_memory.initializer)
69 } else {
70 None
71 }
72 }
73
74 pub fn globals_spec(&self) -> &[GlobalSpec<'a>] {
75 &self.globals_spec
76 }
77
78 pub fn function_info(&self) -> &[FunctionMetadata<'a>] {
79 &self.function_info
80 }
81
82 pub fn import_functions(&self) -> &[ImportFunction<'_>] {
83 &self.import_functions
84 }
85
86 pub fn export_functions(&self) -> &[ExportFunction<'_>] {
87 &self.export_functions
88 }
89
90 pub fn get_signature(&self, fn_id: FunctionIndex) -> &Signature {
95 let sig_idx = self.function_info[fn_id.as_u32() as usize].signature;
96 &self.signatures[sig_idx.as_u32() as usize]
97 }
98
99 pub fn get_export_func_id(&self, name: &str) -> Option<FunctionIndex> {
100 self.export_functions
101 .iter()
102 .find(|export| export.names.contains(&name))
103 .map(|export| export.fn_idx)
104 }
105
106 pub fn signatures(&self) -> &[Signature] {
107 &self.signatures
108 }
109
110 pub fn get_module_signature(&self) -> &[u8] {
111 &self.module_signature
112 }
113
114 pub fn patch_module_signature(
115 module_data_bin: &'a [u8],
116 module_signature: &[u8],
117 ) -> Result<Vec<u8>, Error> {
118 assert_eq!(module_signature.len(), SignatureBones::BYTES);
119 let mut module_data = Self::deserialize(module_data_bin)?;
120 module_data
121 .module_signature
122 .copy_from_slice(module_signature);
123 let patched_module_data_bin = module_data.serialize()?;
124 assert_eq!(patched_module_data_bin.len(), module_data_bin.len());
125 Ok(patched_module_data_bin)
126 }
127
128 pub fn clear_module_signature(module_data_bin: &'a [u8]) -> Result<Vec<u8>, Error> {
129 let module_signature = vec![0u8; SignatureBones::BYTES];
130 Self::patch_module_signature(module_data_bin, &module_signature)
131 }
132
133 pub fn serialize(&self) -> Result<Vec<u8>, Error> {
135 bincode::serialize(self).map_err(Error::SerializationError)
136 }
137
138 pub fn deserialize(buf: &'a [u8]) -> Result<ModuleData<'a>, Error> {
140 bincode::deserialize(buf).map_err(Error::DeserializationError)
141 }
142}
143
144use crate::{
145 functions::{OwnedExportFunction, OwnedImportFunction},
146 globals::OwnedGlobalSpec,
147 linear_memory::{OwnedLinearMemorySpec, OwnedSparseData},
148};
149
150pub struct OwnedModuleData {
156 linear_memory: Option<OwnedLinearMemorySpec>,
157 globals_spec: Vec<OwnedGlobalSpec>,
158 function_info: Vec<OwnedFunctionMetadata>,
159 imports: Vec<OwnedImportFunction>,
160 exports: Vec<OwnedExportFunction>,
161 signatures: Vec<Signature>,
162}
163
164impl OwnedModuleData {
165 pub fn new(
166 linear_memory: Option<OwnedLinearMemorySpec>,
167 globals_spec: Vec<OwnedGlobalSpec>,
168 function_info: Vec<OwnedFunctionMetadata>,
169 imports: Vec<OwnedImportFunction>,
170 exports: Vec<OwnedExportFunction>,
171 signatures: Vec<Signature>,
172 ) -> Self {
173 Self {
174 linear_memory,
175 globals_spec,
176 function_info,
177 imports,
178 exports,
179 signatures,
180 }
181 }
182
183 pub fn to_ref<'a>(&'a self) -> ModuleData<'a> {
186 ModuleData::new(
187 if let Some(ref owned_linear_memory) = self.linear_memory {
188 Some(owned_linear_memory.to_ref())
189 } else {
190 None
191 },
192 self.globals_spec.iter().map(|gs| gs.to_ref()).collect(),
193 self.function_info
194 .iter()
195 .map(|info| info.to_ref())
196 .collect(),
197 self.imports.iter().map(|imp| imp.to_ref()).collect(),
198 self.exports.iter().map(|exp| exp.to_ref()).collect(),
199 self.signatures.clone(),
200 )
201 }
202
203 pub fn empty() -> Self {
204 Self::new(None, vec![], vec![], vec![], vec![], vec![])
205 }
206
207 pub fn with_heap_spec(mut self, heap_spec: HeapSpec) -> Self {
208 if let Some(ref mut linear_memory) = self.linear_memory {
209 linear_memory.heap = heap_spec;
210 } else {
211 self.linear_memory = Some(OwnedLinearMemorySpec {
212 heap: heap_spec,
213 initializer: OwnedSparseData::new(vec![]).unwrap(),
214 });
215 }
216 self
217 }
218}
219
220impl Default for OwnedModuleData {
221 fn default() -> Self {
222 OwnedModuleData::empty()
223 }
224}