miden_core/mast/serialization/
mod.rs1use alloc::{
42 collections::BTreeMap,
43 string::{String, ToString},
44 sync::Arc,
45 vec::Vec,
46};
47
48use decorator::{DecoratorDataBuilder, DecoratorInfo};
49use string_table::StringTable;
50
51use super::{DecoratorId, MastForest, MastNode, MastNodeErrorContext, MastNodeId};
52use crate::{
53 AdviceMap,
54 mast::node::MastNodeExt,
55 utils::{ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable},
56};
57
58mod decorator;
59
60mod info;
61use info::MastNodeInfo;
62
63mod basic_blocks;
64use basic_blocks::{BasicBlockDataBuilder, BasicBlockDataDecoder};
65
66use crate::DecoratorList;
67
68mod string_table;
69
70#[cfg(test)]
71mod tests;
72
73type NodeDataOffset = u32;
78
79type DecoratorDataOffset = u32;
81
82type StringDataOffset = usize;
84
85type StringIndex = usize;
87
88const MAGIC: &[u8; 5] = b"MAST\0";
93
94const VERSION: [u8; 3] = [0, 0, 0];
100
101impl Serializable for MastForest {
105 fn write_into<W: ByteWriter>(&self, target: &mut W) {
106 let mut basic_block_data_builder = BasicBlockDataBuilder::new();
107
108 let mut before_enter_decorators: Vec<(usize, Vec<DecoratorId>)> = Vec::new();
110 let mut after_exit_decorators: Vec<(usize, Vec<DecoratorId>)> = Vec::new();
111
112 let mut basic_block_decorators: Vec<(usize, Vec<(usize, DecoratorId)>)> = Vec::new();
113
114 target.write_bytes(MAGIC);
116 target.write_bytes(&VERSION);
117
118 target.write_usize(self.nodes.len());
120 target.write_usize(self.decorators.len());
121
122 let roots: Vec<u32> = self.roots.iter().map(u32::from).collect();
124 roots.write_into(target);
125
126 let mast_node_infos: Vec<MastNodeInfo> = self
129 .nodes
130 .iter()
131 .enumerate()
132 .map(|(mast_node_id, mast_node)| {
133 if !mast_node.before_enter().is_empty() {
134 before_enter_decorators.push((mast_node_id, mast_node.before_enter().to_vec()));
135 }
136 if !mast_node.after_exit().is_empty() {
137 after_exit_decorators.push((mast_node_id, mast_node.after_exit().to_vec()));
138 }
139
140 let ops_offset = if let MastNode::Block(basic_block) = mast_node {
141 let ops_offset = basic_block_data_builder.encode_basic_block(basic_block);
142
143 basic_block_decorators
144 .push((mast_node_id, basic_block.decorators().collect::<Vec<_>>()));
145
146 ops_offset
147 } else {
148 0
149 };
150
151 MastNodeInfo::new(mast_node, ops_offset)
152 })
153 .collect();
154
155 let basic_block_data = basic_block_data_builder.finalize();
156 basic_block_data.write_into(target);
157
158 for mast_node_info in mast_node_infos {
160 mast_node_info.write_into(target);
161 }
162
163 self.advice_map.write_into(target);
164 let error_codes: BTreeMap<u64, String> =
165 self.error_codes.iter().map(|(k, v)| (*k, v.to_string())).collect();
166 error_codes.write_into(target);
167
168 let mut decorator_data_builder = DecoratorDataBuilder::new();
171 for decorator in &self.decorators {
172 decorator_data_builder.add_decorator(decorator)
173 }
174
175 let (decorator_data, decorator_infos, string_table) = decorator_data_builder.finalize();
176
177 decorator_data.write_into(target);
179 string_table.write_into(target);
180
181 for decorator_info in decorator_infos {
183 decorator_info.write_into(target);
184 }
185
186 basic_block_decorators.write_into(target);
187
188 before_enter_decorators.write_into(target);
190 after_exit_decorators.write_into(target);
191 }
192}
193
194impl Deserializable for MastForest {
195 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
196 read_and_validate_magic(source)?;
197 read_and_validate_version(source)?;
198
199 let node_count = source.read_usize()?;
201 let decorator_count = source.read_usize()?;
202
203 let roots: Vec<u32> = Deserializable::read_from(source)?;
205
206 let basic_block_data: Vec<u8> = Deserializable::read_from(source)?;
208 let mast_node_infos: Vec<MastNodeInfo> = node_infos_iter(source, node_count)
209 .collect::<Result<Vec<MastNodeInfo>, DeserializationError>>()?;
210
211 let advice_map = AdviceMap::read_from(source)?;
212
213 let error_codes: BTreeMap<u64, String> = Deserializable::read_from(source)?;
214 let error_codes: BTreeMap<u64, Arc<str>> =
215 error_codes.into_iter().map(|(k, v)| (k, Arc::from(v))).collect();
216
217 let decorator_data: Vec<u8> = Deserializable::read_from(source)?;
219 let string_table: StringTable = Deserializable::read_from(source)?;
220 let decorator_infos = decorator_infos_iter(source, decorator_count);
221
222 let mut mast_forest = {
224 let mut mast_forest = MastForest::new();
225
226 for decorator_info in decorator_infos {
227 let decorator_info = decorator_info?;
228 let decorator =
229 decorator_info.try_into_decorator(&string_table, &decorator_data)?;
230
231 mast_forest.add_decorator(decorator).map_err(|e| {
232 DeserializationError::InvalidValue(format!(
233 "failed to add decorator to MAST forest while deserializing: {e}",
234 ))
235 })?;
236 }
237
238 let basic_block_data_decoder = BasicBlockDataDecoder::new(&basic_block_data);
240 for mast_node_info in mast_node_infos {
241 let node =
242 mast_node_info.try_into_mast_node(node_count, &basic_block_data_decoder)?;
243
244 mast_forest.add_node(node).map_err(|e| {
245 DeserializationError::InvalidValue(format!(
246 "failed to add node to MAST forest while deserializing: {e}",
247 ))
248 })?;
249 }
250
251 for root in roots {
253 let root = MastNodeId::from_u32_safe(root, &mast_forest)?;
255 mast_forest.make_root(root);
256 }
257
258 mast_forest.advice_map = advice_map;
259
260 mast_forest
261 };
262
263 let basic_block_decorators: Vec<(usize, DecoratorList)> =
264 read_block_decorators(source, &mast_forest)?;
265 for (node_id, decorator_list) in basic_block_decorators {
266 let node_id = MastNodeId::from_usize_safe(node_id, &mast_forest)?;
267
268 match &mut mast_forest[node_id] {
269 MastNode::Block(basic_block) => {
270 basic_block.set_decorators(decorator_list);
271 },
272 other => {
273 return Err(DeserializationError::InvalidValue(format!(
274 "expected mast node with id {node_id} to be a basic block, found {other:?}"
275 )));
276 },
277 }
278 }
279
280 let before_enter_decorators: Vec<(usize, Vec<DecoratorId>)> =
282 read_before_after_decorators(source, &mast_forest)?;
283 for (node_id, decorator_ids) in before_enter_decorators {
284 let node_id = MastNodeId::from_usize_safe(node_id, &mast_forest)?;
285 mast_forest.append_before_enter(node_id, &decorator_ids);
286 }
287
288 let after_exit_decorators: Vec<(usize, Vec<DecoratorId>)> =
289 read_before_after_decorators(source, &mast_forest)?;
290 for (node_id, decorator_ids) in after_exit_decorators {
291 let node_id = MastNodeId::from_usize_safe(node_id, &mast_forest)?;
292 mast_forest.append_after_exit(node_id, &decorator_ids);
293 }
294
295 mast_forest.error_codes = error_codes;
296
297 Ok(mast_forest)
298 }
299}
300
301fn read_and_validate_magic<R: ByteReader>(source: &mut R) -> Result<[u8; 5], DeserializationError> {
302 let magic: [u8; 5] = source.read_array()?;
303 if magic != *MAGIC {
304 return Err(DeserializationError::InvalidValue(format!(
305 "Invalid magic bytes. Expected '{:?}', got '{:?}'",
306 *MAGIC, magic
307 )));
308 }
309 Ok(magic)
310}
311
312fn read_and_validate_version<R: ByteReader>(
313 source: &mut R,
314) -> Result<[u8; 3], DeserializationError> {
315 let version: [u8; 3] = source.read_array()?;
316 if version != VERSION {
317 return Err(DeserializationError::InvalidValue(format!(
318 "Unsupported version. Got '{version:?}', but only '{VERSION:?}' is supported",
319 )));
320 }
321 Ok(version)
322}
323
324fn read_block_decorators<R: ByteReader>(
325 source: &mut R,
326 mast_forest: &MastForest,
327) -> Result<Vec<(usize, DecoratorList)>, DeserializationError> {
328 let vec_len: usize = source.read()?;
329 let mut out_vec: Vec<_> = Vec::with_capacity(vec_len);
330
331 for _ in 0..vec_len {
332 let node_id: usize = source.read()?;
333
334 let decorator_vec_len: usize = source.read()?;
335 let mut inner_vec: Vec<(usize, DecoratorId)> = Vec::with_capacity(decorator_vec_len);
336 for _ in 0..decorator_vec_len {
337 let op_id: usize = source.read()?;
338 let decorator_id = DecoratorId::from_u32_safe(source.read()?, mast_forest)?;
339 inner_vec.push((op_id, decorator_id));
340 }
341
342 out_vec.push((node_id, inner_vec));
343 }
344
345 Ok(out_vec)
346}
347
348fn decorator_infos_iter<'a, R>(
349 source: &'a mut R,
350 decorator_count: usize,
351) -> impl Iterator<Item = Result<DecoratorInfo, DeserializationError>> + 'a
352where
353 R: ByteReader + 'a,
354{
355 let mut remaining = decorator_count;
356 core::iter::from_fn(move || {
357 if remaining == 0 {
358 return None;
359 }
360 remaining -= 1;
361 Some(DecoratorInfo::read_from(source))
362 })
363}
364
365fn node_infos_iter<'a, R>(
366 source: &'a mut R,
367 node_count: usize,
368) -> impl Iterator<Item = Result<MastNodeInfo, DeserializationError>> + 'a
369where
370 R: ByteReader + 'a,
371{
372 let mut remaining = node_count;
373 core::iter::from_fn(move || {
374 if remaining == 0 {
375 return None;
376 }
377 remaining -= 1;
378 Some(MastNodeInfo::read_from(source))
379 })
380}
381
382fn read_before_after_decorators<R: ByteReader>(
388 source: &mut R,
389 mast_forest: &MastForest,
390) -> Result<Vec<(usize, Vec<DecoratorId>)>, DeserializationError> {
391 let vec_len: usize = source.read()?;
392 let mut out_vec: Vec<_> = Vec::with_capacity(vec_len);
393
394 for _ in 0..vec_len {
395 let node_id: usize = source.read()?;
396
397 let inner_vec_len: usize = source.read()?;
398 let mut inner_vec: Vec<DecoratorId> = Vec::with_capacity(inner_vec_len);
399 for _ in 0..inner_vec_len {
400 let decorator_id = DecoratorId::from_u32_safe(source.read()?, mast_forest)?;
401 inner_vec.push(decorator_id);
402 }
403
404 out_vec.push((node_id, inner_vec));
405 }
406
407 Ok(out_vec)
408}