pub fn new(
        rng: &mut StdRng,
        locals: &[SignatureToken],
        parameters: &Signature,
        target_blocks: BlockIDSize,
    ) -> CFG {
        checked_precondition!(target_blocks > 0, "The CFG must haave at least one block");
        let mut basic_blocks: HashMap<BlockIDSize, BasicBlock> = HashMap::new();
        // Generate basic blocks
        for i in 0..target_blocks {
            basic_blocks.insert(i, BasicBlock::new());
        }
        // Generate control flow edges
        let mut edges: Vec<(BlockIDSize, BlockIDSize)> = Vec::new();
        let mut block_queue: VecDeque<BlockIDSize> = VecDeque::new();
        let mut current_block_id = 0;

        block_queue.push_back(current_block_id);
        current_block_id += 1;

        while current_block_id < target_blocks && !block_queue.is_empty() {
            let front_block = block_queue.pop_front();
            // `front_block` will be `Some` because the block queue is not empty
            assume!(front_block.is_some());
            let parent_block_id = front_block.unwrap();
            // The number of edges will be at most `2*target_blocks``
            // Since target blocks is at most a `u16`, this will not overflow even if
            // `usize` is a `u32`
            assume!(edges.len() < usize::max_value());
            edges.push((parent_block_id, current_block_id));
            block_queue.push_back(current_block_id);
            // `current_block_id` is bound by the max og `target_block_size`
            verify!(current_block_id < u16::max_value());
            current_block_id += 1;
            // Generate a second child edge with prob = 1/2
            if rng.gen_bool(0.5) && current_block_id < target_blocks {
                // The number of edges will be at most `2*target_blocks``
                // Since target blocks is at most a `u16`, this will not overflow even if
                // `usize` is a `u32`
                verify!(edges.len() < usize::max_value());
                edges.push((parent_block_id, current_block_id));
                block_queue.push_back(current_block_id);
                // `current_block_id` is bound by the max og `target_block_size`
                verify!(current_block_id < u16::max_value());
                current_block_id += 1;
            }
        }

        // Connect remaining blocks to return
        while !block_queue.is_empty() {
            let front_block = block_queue.pop_front();
            // `front_block` will be `Some` because the block queue is not empty
            assume!(front_block.is_some());
            let parent_block_id = front_block.unwrap();
            // By the precondition of the function
            assume!(target_blocks > 0);
            if parent_block_id != target_blocks - 1 {
                edges.push((parent_block_id, target_blocks - 1));
            }
        }
        debug!("Edges: {:?}", edges);

        // Build the CFG
        let mut cfg = CFG {
            basic_blocks,
            edges,
        };
        // Assign locals to basic blocks
        assume!(target_blocks == 0 || !cfg.basic_blocks.is_empty());
        CFG::add_locals(&mut cfg, rng, locals, parameters.0.len());
        cfg
    }
/// Construct a control flow graph that contains empty basic blocks with set incoming
/// and outgoing locals.
/// Currently the control flow graph is acyclic.
Construct a control flow graph that contains empty basic blocks with set incoming
and outgoing locals.
Currently the control flow graph is acyclic.
Construct a control flow graph that contains empty basic blocks with set incoming and outgoing locals . Currently the control flow graph is acyclic .
pub fn new(
        rng: &mut StdRng,
        locals: &[SignatureToken],
        parameters: &Signature,
        target_blocks: BlockIDSize,
    ) -> CFG {
        checked_precondition!(target_blocks > 0, "The CFG must haave at least one block");
        let mut basic_blocks: HashMap<BlockIDSize, BasicBlock> = HashMap::new();
        // Generate basic blocks
        for i in 0..target_blocks {
            basic_blocks.insert(i, BasicBlock::new());
        }
        // Generate control flow edges
        let mut edges: Vec<(BlockIDSize, BlockIDSize)> = Vec::new();
        let mut block_queue: VecDeque<BlockIDSize> = VecDeque::new();
        let mut current_block_id = 0;
        block_queue.push_back(current_block_id);
        current_block_id += 1;
        while current_block_id < target_blocks && !block_queue.is_empty() {
            let front_block = block_queue.pop_front();
            // `front_block` will be `Some` because the block queue is not empty
            assume!(front_block.is_some());
            let parent_block_id = front_block.unwrap();
            // The number of edges will be at most `2*target_blocks``
            // Since target blocks is at most a `u16`, this will not overflow even if
            // `usize` is a `u32`
            assume!(edges.len() < usize::max_value());
            edges.push((parent_block_id, current_block_id));
            block_queue.push_back(current_block_id);
            // `current_block_id` is bound by the max og `target_block_size`
            verify!(current_block_id < u16::max_value());
            current_block_id += 1;
            // Generate a second child edge with prob = 1/2
            if rng.gen_bool(0.5) && current_block_id < target_blocks {
                // The number of edges will be at most `2*target_blocks``
                // Since target blocks is at most a `u16`, this will not overflow even if
                // `usize` is a `u32`
                verify!(edges.len() < usize::max_value());
                edges.push((parent_block_id, current_block_id));
                block_queue.push_back(current_block_id);
                // `current_block_id` is bound by the max og `target_block_size`
                verify!(current_block_id < u16::max_value());
                current_block_id += 1;
            }
        }
        // Connect remaining blocks to return
        while !block_queue.is_empty() {
            let front_block = block_queue.pop_front();
            // `front_block` will be `Some` because the block queue is not empty
            assume!(front_block.is_some());
            let parent_block_id = front_block.unwrap();
            // By the precondition of the function
            assume!(target_blocks > 0);
            if parent_block_id != target_blocks - 1 {
                edges.push((parent_block_id, target_blocks - 1));
            }
        }
        debug!("Edges: {:?}", edges);
        // Build the CFG
        let mut cfg = CFG {
            basic_blocks,
            edges,
        };
        // Assign locals to basic blocks
        assume!(target_blocks == 0 || !cfg.basic_blocks.is_empty());
        CFG::add_locals(&mut cfg, rng, locals, parameters.0.len());
        cfg
    }
pub fn new ( rng : & mut StdRng , locals : & [ SignatureToken ] , parameters : & Signature , target_blocks : BlockIDSize , ) -> CFG { checked_precondition ! ( target_blocks 0 " " ) ; let mut basic_blocks : HashMap < BlockIDSize , BasicBlock > = HashMap :: new ( ) ; // Generate basic blocks for i in 0 .. target_blocks { basic_blocks . insert ( i , BasicBlock :: new ( ) ) ; } // Generate control flow edges let mut edges : Vec < ( BlockIDSize , BlockIDSize ) > = Vec :: new ( ) ; let mut block_queue : VecDeque < BlockIDSize > = VecDeque :: new ( ) ; let mut current_block_id = 0 ; block_queue . push_back ( current_block_id ) ; current_block_id += 1 ; while current_block_id < target_blocks && ! block_queue . is_empty ( ) { let front_block = block_queue . pop_front ( ) ; // `front_block` will be `Some` because the block queue is not empty assume ! ( front_block is_some ( ) ) ; let parent_block_id = front_block . unwrap ( ) ; // The number of edges will be at most `2*target_blocks`` // Since target blocks is at most a `u16`, this will not overflow even if // `usize` is a `u32` assume ! ( edges len ( ) usize max_value ( ) ) ; edges . push ( ( parent_block_id , current_block_id ) ) ; block_queue . push_back ( current_block_id ) ; // `current_block_id` is bound by the max og `target_block_size` verify ! ( current_block_id u16 max_value ( ) ) ; current_block_id += 1 ; // Generate a second child edge with prob = 1/2 if rng . gen_bool ( 0.5 ) && current_block_id < target_blocks { // The number of edges will be at most `2*target_blocks`` // Since target blocks is at most a `u16`, this will not overflow even if // `usize` is a `u32` verify ! ( edges len ( ) usize max_value ( ) ) ; edges . push ( ( parent_block_id , current_block_id ) ) ; block_queue . push_back ( current_block_id ) ; // `current_block_id` is bound by the max og `target_block_size` verify ! ( current_block_id u16 max_value ( ) ) ; current_block_id += 1 ; } } // Connect remaining blocks to return while ! block_queue . is_empty ( ) { let front_block = block_queue . pop_front ( ) ; // `front_block` will be `Some` because the block queue is not empty assume ! ( front_block is_some ( ) ) ; let parent_block_id = front_block . unwrap ( ) ; // By the precondition of the function assume ! ( target_blocks 0 ) ; if parent_block_id != target_blocks - 1 { edges . push ( ( parent_block_id , target_blocks - 1 ) ) ; } } debug ! ( " " edges ) ; // Build the CFG let mut cfg = CFG { basic_blocks , edges , } ; // Assign locals to basic blocks assume ! ( target_blocks 0 cfg basic_blocks is_empty ( ) ) ; CFG :: add_locals ( & mut cfg , rng , locals , parameters . 0 . len ( ) ) ; cfg }
Construct a control flow graph that contains empty basic blocks with set incoming
and outgoing locals.
Construct a control flow graph that contains empty basic blocks with set incoming and outgoing locals .
rng
&mut StdRng
locals
&[SignatureToken]
parameters
&Signature
target_blocks
BlockIDSize