diff --git a/core/src/mast/node/basic_block_node/mod.rs b/core/src/mast/node/basic_block_node/mod.rs index 66cc659998..e9bec6d0c0 100644 --- a/core/src/mast/node/basic_block_node/mod.rs +++ b/core/src/mast/node/basic_block_node/mod.rs @@ -223,7 +223,7 @@ impl fmt::Display for BasicBlockNode { // OPERATION OR DECORATOR // ================================================================================================ -// TODOP: Document +/// Encodes either an [`Operation`] or a [`Decorator`]. #[derive(Clone, Debug, Eq, PartialEq)] pub enum OperationOrDecorator<'a> { Operation(&'a Operation), diff --git a/core/src/mast/serialization/basic_block_data_builder.rs b/core/src/mast/serialization/basic_block_data_builder.rs index 886f1a09d9..3ca9ece182 100644 --- a/core/src/mast/serialization/basic_block_data_builder.rs +++ b/core/src/mast/serialization/basic_block_data_builder.rs @@ -9,7 +9,7 @@ use crate::{ use super::{decorator::EncodedDecoratorVariant, DataOffset, StringIndex, StringRef}; -/// TODOP: Document +/// Builds the `data` section of a serialized [`crate::mast::MastForest`]. #[derive(Debug, Default)] pub struct BasicBlockDataBuilder { data: Vec, @@ -25,7 +25,9 @@ impl BasicBlockDataBuilder { /// Accessors impl BasicBlockDataBuilder { - pub fn current_data_offset(&self) -> DataOffset { + /// Returns the offset in the serialized [`crate::mast::MastForest`] data field that the next + /// [`super::MastNodeInfo`] representing a [`BasicBlockNode`] will take. + pub fn next_data_offset(&self) -> DataOffset { self.data .len() .try_into() @@ -35,6 +37,7 @@ impl BasicBlockDataBuilder { /// Mutators impl BasicBlockDataBuilder { + /// Encodes a [`BasicBlockNode`] into the serialized [`crate::mast::MastForest`] data field. pub fn encode_basic_block(&mut self, basic_block: &BasicBlockNode) { // 2nd part of `mast_node_to_info()` (inside the match) for op_or_decorator in basic_block.iter() { @@ -45,6 +48,7 @@ impl BasicBlockDataBuilder { } } + /// Returns the serialized [`crate::mast::MastForest`] data field, as well as the string table. pub fn into_parts(mut self) -> (Vec, Vec) { let string_table = self.string_table_builder.into_table(&mut self.data); (self.data, string_table) diff --git a/core/src/mast/serialization/decorator.rs b/core/src/mast/serialization/decorator.rs index 3cb509a039..22024397ca 100644 --- a/core/src/mast/serialization/decorator.rs +++ b/core/src/mast/serialization/decorator.rs @@ -3,7 +3,10 @@ use num_traits::{FromPrimitive, ToPrimitive}; use crate::{AdviceInjector, DebugOptions, Decorator}; -/// TODOP: Document +/// Stores all the possible [`Decorator`] variants, without any associated data. +/// +/// This is effectively equivalent to a set of constants, and designed to convert between variant +/// discriminant and enum variant conveniently. #[derive(FromPrimitive, ToPrimitive)] #[repr(u8)] pub enum EncodedDecoratorVariant { diff --git a/core/src/mast/serialization/info.rs b/core/src/mast/serialization/info.rs index 63ffb216c9..1dec494aac 100644 --- a/core/src/mast/serialization/info.rs +++ b/core/src/mast/serialization/info.rs @@ -8,6 +8,15 @@ use super::{basic_block_data_decoder::BasicBlockDataDecoder, DataOffset}; // MAST NODE INFO // =============================================================================================== +/// Represents a serialized [`MastNode`], with some data inlined in its [`MastNodeType`]. +/// +/// In the case of [`crate::mast::BasicBlockNode`], all its operation- and decorator-related data is +/// stored in the serialized [`MastForest`]'s `data` field at offset represented by the `offset` +/// field. For all other variants of [`MastNode`], the `offset` field is guaranteed to be 0. +/// +/// The serialized representation of [`MastNodeInfo`] is guaranteed to be fixed width, so that the +/// nodes stored in the `nodes` table of the serialzied [`MastForest`] can be accessed quickly by +/// index. #[derive(Debug)] pub struct MastNodeInfo { ty: MastNodeType, @@ -125,7 +134,12 @@ const SYSCALL: u8 = 5; const DYN: u8 = 6; const EXTERNAL: u8 = 7; -/// TODOP: Document the fact that encoded representation is always 8 bytes +/// Represents the variant of a [`MastNode`], as well as any additional data. For example, for more +/// efficient decoding, and because of the frequency with which these node types appear, we directly +/// represent the child indices for `Join`, `Split`, and `Loop`, `Call` and `SysCall` inline. +/// +/// The serialized representation of the MAST node type is guaranteed to be 8 bytes, so that +/// [`MastNodeInfo`] (which contains it) can be of fixed width. #[derive(Debug)] #[repr(u8)] pub enum MastNodeType { @@ -156,6 +170,7 @@ pub enum MastNodeType { /// Constructors impl MastNodeType { + /// Constructs a new [`MastNodeType`] from a [`MastNode`]. pub fn new(mast_node: &MastNode) -> Self { use MastNode::*; @@ -199,9 +214,9 @@ impl Serializable for MastNodeType { let mut serialized_bytes = self.inline_data_to_bytes(); // Tag is always placed in the first four bytes - let tag = self.tag(); - assert!(tag <= 0b1111); - serialized_bytes[0] |= tag << 4; + let discriminant = self.discriminant(); + assert!(discriminant <= 0b1111); + serialized_bytes[0] |= discriminant << 4; serialized_bytes }; @@ -212,7 +227,7 @@ impl Serializable for MastNodeType { /// Serialization helpers impl MastNodeType { - fn tag(&self) -> u8 { + fn discriminant(&self) -> u8 { // SAFETY: This is safe because we have given this enum a primitive representation with // #[repr(u8)], with the first field of the underlying union-of-structs the discriminant. // @@ -240,7 +255,6 @@ impl MastNodeType { } } - // TODOP: Make a diagram of how the bits are split fn encode_join_or_split(left_child_id: u32, right_child_id: u32) -> [u8; 8] { assert!(left_child_id < 2_u32.pow(30)); assert!(right_child_id < 2_u32.pow(30)); diff --git a/core/src/mast/serialization/mod.rs b/core/src/mast/serialization/mod.rs index 0caaf2f96e..b08b58bdda 100644 --- a/core/src/mast/serialization/mod.rs +++ b/core/src/mast/serialization/mod.rs @@ -90,7 +90,7 @@ impl Serializable for MastForest { // MAST node infos for mast_node in &self.nodes { let mast_node_info = - MastNodeInfo::new(mast_node, basic_block_data_builder.current_data_offset()); + MastNodeInfo::new(mast_node, basic_block_data_builder.next_data_offset()); if let MastNode::Block(basic_block) = mast_node { basic_block_data_builder.encode_basic_block(basic_block); diff --git a/core/src/operations/mod.rs b/core/src/operations/mod.rs index ab201933bd..078abaf72c 100644 --- a/core/src/operations/mod.rs +++ b/core/src/operations/mod.rs @@ -451,7 +451,7 @@ pub enum OperationData { /// Constructors impl Operation { - // TODOP: document + /// Builds an operation from its opcode and inline data (if any). pub fn with_opcode_and_data( opcode: u8, data: OperationData,