pub fn serialize(&mut self) -> Vec<Bytecode> {
        checked_precondition!(
            !self.basic_blocks.is_empty(),
            "Error: CFG has no basic blocks"
        );
        let cfg_copy = self.clone();
        let mut bytecode: Vec<Bytecode> = Vec::new();
        let block_order = self.serialize_block_order();
        for block_id in &block_order {
            let block = self.basic_blocks.get_mut(block_id);
            // The generated block order contains every block
            assume!(block.is_some());
            let block = block.unwrap();
            // All basic blocks should have instructions filled in at this point
            checked_assume!(
                !block.instructions.is_empty(),
                "Error: block created with no instructions",
            );
            let last_instruction_index = block.instructions.len() - 1;
            let child_ids = cfg_copy.get_children_ids(*block_id);
            if child_ids.len() == 2 {
                // The left child (fallthrough) is serialized before the right (jump)
                let offset = CFG::get_block_offset(&cfg_copy, &block_order, child_ids[1]);
                match block.instructions.last() {
                    Some(Bytecode::BrTrue(_)) => {
                        block.instructions[last_instruction_index] =
                            Bytecode::BrTrue(offset as u16);
                    }
                    Some(Bytecode::BrFalse(_)) => {
                        block.instructions[last_instruction_index] =
                            Bytecode::BrFalse(offset as u16);
                    }
                    _ => unreachable!(
                        "Error: unsupported two target jump instruction, {:#?}",
                        block.instructions.last()
                    ),
                };
            } else if child_ids.len() == 1 {
                let offset = CFG::get_block_offset(&cfg_copy, &block_order, child_ids[0]);
                match block.instructions.last() {
                    Some(Bytecode::Branch(_)) => {
                        block.instructions[last_instruction_index] = Bytecode::Branch(offset);
                    }
                    _ => unreachable!(
                        "Error: unsupported one target jump instruction, {:#?}",
                        block.instructions.last()
                    ),
                }
            }
            bytecode.extend(block.instructions.clone());
        }
        debug!("Final bytecode: {:#?}", bytecode);
        bytecode
    }
/// Serialize the control flow graph into a sequence of instructions. Set the offsets of branch
/// instructions appropriately.
Serialize the control flow graph into a sequence of instructions. Set the offsets of branch
instructions appropriately.
Serialize the control flow graph into a sequence of instructions . Set the offsets of branch instructions appropriately .
pub fn serialize(&mut self) -> Vec<Bytecode> {
        checked_precondition!(
            !self.basic_blocks.is_empty(),
            "Error: CFG has no basic blocks"
        );
        let cfg_copy = self.clone();
        let mut bytecode: Vec<Bytecode> = Vec::new();
        let block_order = self.serialize_block_order();
        for block_id in &block_order {
            let block = self.basic_blocks.get_mut(block_id);
            // The generated block order contains every block
            assume!(block.is_some());
            let block = block.unwrap();
            // All basic blocks should have instructions filled in at this point
            checked_assume!(
                !block.instructions.is_empty(),
                "Error: block created with no instructions",
            );
            let last_instruction_index = block.instructions.len() - 1;
            let child_ids = cfg_copy.get_children_ids(*block_id);
            if child_ids.len() == 2 {
                // The left child (fallthrough) is serialized before the right (jump)
                let offset = CFG::get_block_offset(&cfg_copy, &block_order, child_ids[1]);
                match block.instructions.last() {
                    Some(Bytecode::BrTrue(_)) => {
                        block.instructions[last_instruction_index] =
                            Bytecode::BrTrue(offset as u16);
                    }
                    Some(Bytecode::BrFalse(_)) => {
                        block.instructions[last_instruction_index] =
                            Bytecode::BrFalse(offset as u16);
                    }
                    _ => unreachable!(
                        "Error: unsupported two target jump instruction, {:#?}",
                        block.instructions.last()
                    ),
                };
            } else if child_ids.len() == 1 {
                let offset = CFG::get_block_offset(&cfg_copy, &block_order, child_ids[0]);
                match block.instructions.last() {
                    Some(Bytecode::Branch(_)) => {
                        block.instructions[last_instruction_index] = Bytecode::Branch(offset);
                    }
                    _ => unreachable!(
                        "Error: unsupported one target jump instruction, {:#?}",
                        block.instructions.last()
                    ),
                }
            }
            bytecode.extend(block.instructions.clone());
        }
        debug!("Final bytecode: {:#?}", bytecode);
        bytecode
    }
pub fn serialize ( & mut self ) -> Vec < Bytecode > { checked_precondition ! ( self basic_blocks is_empty ( ) " " ) ; let cfg_copy = self . clone ( ) ; let mut bytecode : Vec < Bytecode > = Vec :: new ( ) ; let block_order = self . serialize_block_order ( ) ; for block_id in & block_order { let block = self . basic_blocks . get_mut ( block_id ) ; // The generated block order contains every block assume ! ( block is_some ( ) ) ; let block = block . unwrap ( ) ; // All basic blocks should have instructions filled in at this point checked_assume ! ( block instructions is_empty ( ) " " ) ; let last_instruction_index = block . instructions . len ( ) - 1 ; let child_ids = cfg_copy . get_children_ids ( * block_id ) ; if child_ids . len ( ) == 2 { // The left child (fallthrough) is serialized before the right (jump) let offset = CFG :: get_block_offset ( & cfg_copy , & block_order , child_ids [ 1 ] ) ; match block . instructions . last ( ) { Some ( Bytecode :: BrTrue ( _ ) ) => { block . instructions [ last_instruction_index ] = Bytecode :: BrTrue ( offset as u16 ) ; } Some ( Bytecode :: BrFalse ( _ ) ) => { block . instructions [ last_instruction_index ] = Bytecode :: BrFalse ( offset as u16 ) ; } _ => unreachable ! ( " " block instructions last ( ) ) , } ; } else if child_ids . len ( ) == 1 { let offset = CFG :: get_block_offset ( & cfg_copy , & block_order , child_ids [ 0 ] ) ; match block . instructions . last ( ) { Some ( Bytecode :: Branch ( _ ) ) => { block . instructions [ last_instruction_index ] = Bytecode :: Branch ( offset ) ; } _ => unreachable ! ( " " block instructions last ( ) ) , } } bytecode . extend ( block . instructions . clone ( ) ) ; } debug ! ( " " bytecode ) ; bytecode }
Serialize the control flow graph into a sequence of instructions.
Serialize the control flow graph into a sequence of instructions .
&mut self