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::{DecoratedOpLink, DecoratorId, MastForest, MastNode, 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<DecoratedOpLink>)> = 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().copied().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.push((
144 mast_node_id,
145 basic_block.indexed_decorator_iter().collect::<Vec<_>>(),
146 ));
147
148 ops_offset
149 } else {
150 0
151 };
152
153 MastNodeInfo::new(mast_node, ops_offset)
154 })
155 .collect();
156
157 let basic_block_data = basic_block_data_builder.finalize();
158 basic_block_data.write_into(target);
159
160 for mast_node_info in mast_node_infos {
162 mast_node_info.write_into(target);
163 }
164
165 self.advice_map.write_into(target);
166 let error_codes: BTreeMap<u64, String> =
167 self.error_codes.iter().map(|(k, v)| (*k, v.to_string())).collect();
168 error_codes.write_into(target);
169
170 let mut decorator_data_builder = DecoratorDataBuilder::new();
173 for decorator in &self.decorators {
174 decorator_data_builder.add_decorator(decorator)
175 }
176
177 let (decorator_data, decorator_infos, string_table) = decorator_data_builder.finalize();
178
179 decorator_data.write_into(target);
181 string_table.write_into(target);
182
183 for decorator_info in decorator_infos {
185 decorator_info.write_into(target);
186 }
187
188 basic_block_decorators.write_into(target);
189
190 before_enter_decorators.write_into(target);
192 after_exit_decorators.write_into(target);
193 }
194}
195
196impl Deserializable for MastForest {
197 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
198 read_and_validate_magic(source)?;
199 read_and_validate_version(source)?;
200
201 let node_count = source.read_usize()?;
203 let decorator_count = source.read_usize()?;
204
205 let roots: Vec<u32> = Deserializable::read_from(source)?;
207
208 let basic_block_data: Vec<u8> = Deserializable::read_from(source)?;
210 let mast_node_infos: Vec<MastNodeInfo> = node_infos_iter(source, node_count)
211 .collect::<Result<Vec<MastNodeInfo>, DeserializationError>>()?;
212
213 let advice_map = AdviceMap::read_from(source)?;
214
215 let error_codes: BTreeMap<u64, String> = Deserializable::read_from(source)?;
216 let error_codes: BTreeMap<u64, Arc<str>> =
217 error_codes.into_iter().map(|(k, v)| (k, Arc::from(v))).collect();
218
219 let decorator_data: Vec<u8> = Deserializable::read_from(source)?;
221 let string_table: StringTable = Deserializable::read_from(source)?;
222 let decorator_infos = decorator_infos_iter(source, decorator_count);
223
224 let mut mast_forest = {
226 let mut mast_forest = MastForest::new();
227
228 for decorator_info in decorator_infos {
229 let decorator_info = decorator_info?;
230 let decorator =
231 decorator_info.try_into_decorator(&string_table, &decorator_data)?;
232
233 mast_forest.add_decorator(decorator).map_err(|e| {
234 DeserializationError::InvalidValue(format!(
235 "failed to add decorator to MAST forest while deserializing: {e}",
236 ))
237 })?;
238 }
239
240 let basic_block_data_decoder = BasicBlockDataDecoder::new(&basic_block_data);
242 for mast_node_info in mast_node_infos {
243 let node =
244 mast_node_info.try_into_mast_node(node_count, &basic_block_data_decoder)?;
245
246 mast_forest.add_node(node).map_err(|e| {
247 DeserializationError::InvalidValue(format!(
248 "failed to add node to MAST forest while deserializing: {e}",
249 ))
250 })?;
251 }
252
253 for root in roots {
255 let root = MastNodeId::from_u32_safe(root, &mast_forest)?;
257 mast_forest.make_root(root);
258 }
259
260 mast_forest.advice_map = advice_map;
261
262 mast_forest
263 };
264
265 let basic_block_decorators: Vec<(usize, DecoratorList)> =
266 read_block_decorators(source, &mast_forest)?;
267 for (node_id, decorator_list) in basic_block_decorators {
268 let node_id = MastNodeId::from_usize_safe(node_id, &mast_forest)?;
269
270 match &mut mast_forest[node_id] {
271 MastNode::Block(basic_block) => {
272 basic_block.set_decorators(decorator_list);
273 },
274 other => {
275 return Err(DeserializationError::InvalidValue(format!(
276 "expected mast node with id {node_id} to be a basic block, found {other:?}"
277 )));
278 },
279 }
280 }
281
282 let before_enter_decorators: Vec<(usize, Vec<DecoratorId>)> =
284 read_before_after_decorators(source, &mast_forest)?;
285 for (node_id, decorator_ids) in before_enter_decorators {
286 let node_id = MastNodeId::from_usize_safe(node_id, &mast_forest)?;
287 mast_forest.append_before_enter(node_id, &decorator_ids);
288 }
289
290 let after_exit_decorators: Vec<(usize, Vec<DecoratorId>)> =
291 read_before_after_decorators(source, &mast_forest)?;
292 for (node_id, decorator_ids) in after_exit_decorators {
293 let node_id = MastNodeId::from_usize_safe(node_id, &mast_forest)?;
294 mast_forest.append_after_exit(node_id, &decorator_ids);
295 }
296
297 mast_forest.error_codes = error_codes;
298
299 Ok(mast_forest)
300 }
301}
302
303fn read_and_validate_magic<R: ByteReader>(source: &mut R) -> Result<[u8; 5], DeserializationError> {
304 let magic: [u8; 5] = source.read_array()?;
305 if magic != *MAGIC {
306 return Err(DeserializationError::InvalidValue(format!(
307 "Invalid magic bytes. Expected '{:?}', got '{:?}'",
308 *MAGIC, magic
309 )));
310 }
311 Ok(magic)
312}
313
314fn read_and_validate_version<R: ByteReader>(
315 source: &mut R,
316) -> Result<[u8; 3], DeserializationError> {
317 let version: [u8; 3] = source.read_array()?;
318 if version != VERSION {
319 return Err(DeserializationError::InvalidValue(format!(
320 "Unsupported version. Got '{version:?}', but only '{VERSION:?}' is supported",
321 )));
322 }
323 Ok(version)
324}
325
326fn read_block_decorators<R: ByteReader>(
327 source: &mut R,
328 mast_forest: &MastForest,
329) -> Result<Vec<(usize, DecoratorList)>, DeserializationError> {
330 let vec_len: usize = source.read()?;
331 let mut out_vec: Vec<_> = Vec::with_capacity(vec_len);
332
333 for _ in 0..vec_len {
334 let node_id: usize = source.read()?;
335
336 let decorator_vec_len: usize = source.read()?;
337 let mut inner_vec: Vec<DecoratedOpLink> = Vec::with_capacity(decorator_vec_len);
338 for _ in 0..decorator_vec_len {
339 let op_id: usize = source.read()?;
340 let decorator_id = DecoratorId::from_u32_safe(source.read()?, mast_forest)?;
341 inner_vec.push((op_id, decorator_id));
342 }
343
344 out_vec.push((node_id, inner_vec));
345 }
346
347 Ok(out_vec)
348}
349
350fn decorator_infos_iter<'a, R>(
351 source: &'a mut R,
352 decorator_count: usize,
353) -> impl Iterator<Item = Result<DecoratorInfo, DeserializationError>> + 'a
354where
355 R: ByteReader + 'a,
356{
357 let mut remaining = decorator_count;
358 core::iter::from_fn(move || {
359 if remaining == 0 {
360 return None;
361 }
362 remaining -= 1;
363 Some(DecoratorInfo::read_from(source))
364 })
365}
366
367fn node_infos_iter<'a, R>(
368 source: &'a mut R,
369 node_count: usize,
370) -> impl Iterator<Item = Result<MastNodeInfo, DeserializationError>> + 'a
371where
372 R: ByteReader + 'a,
373{
374 let mut remaining = node_count;
375 core::iter::from_fn(move || {
376 if remaining == 0 {
377 return None;
378 }
379 remaining -= 1;
380 Some(MastNodeInfo::read_from(source))
381 })
382}
383
384fn read_before_after_decorators<R: ByteReader>(
390 source: &mut R,
391 mast_forest: &MastForest,
392) -> Result<Vec<(usize, Vec<DecoratorId>)>, DeserializationError> {
393 let vec_len: usize = source.read()?;
394 let mut out_vec: Vec<_> = Vec::with_capacity(vec_len);
395
396 for _ in 0..vec_len {
397 let node_id: usize = source.read()?;
398
399 let inner_vec_len: usize = source.read()?;
400 let mut inner_vec: Vec<DecoratorId> = Vec::with_capacity(inner_vec_len);
401 for _ in 0..inner_vec_len {
402 let decorator_id = DecoratorId::from_u32_safe(source.read()?, mast_forest)?;
403 inner_vec.push(decorator_id);
404 }
405
406 out_vec.push((node_id, inner_vec));
407 }
408
409 Ok(out_vec)
410}