pub fn generate_block(
        &mut self,
        abstract_state_in: AbstractState,
        abstract_state_out: AbstractState,
        module: CompiledModuleMut,
    ) -> Vec<Bytecode> {
        let mut bytecode: Vec<Bytecode> = Vec::new();
        let mut state = abstract_state_in.clone();
        // Generate block body
        loop {
            let candidates = self.candidate_instructions(
                state.clone(),
                abstract_state_in.get_locals().len(),
                module.clone(),
            );
            if candidates.is_empty() {
                warn!("No candidates found for state: [{:?}]", state);
                break;
            }
            match self.select_candidate(0, &state, &candidates) {
                Ok(next_instruction) => {
                    state = self.apply_instruction(state, &mut bytecode, next_instruction);
                    if state.is_final() {
                        break;
                    }
                }
                Err(err) => {
                    // Could not complete the bytecode sequence; reset to empty
                    error!("{}", err);
                    return Vec::new();
                }
            }
        }
        // Fix local availability
        for (i, (abstract_value, target_availability)) in abstract_state_out.get_locals().iter() {
            if let Some((_, current_availability)) = state.local_get(*i) {
                if *target_availability == BorrowState::Available
                    && *current_availability == BorrowState::Unavailable
                {
                    let next_instruction = match abstract_value.token {
                        SignatureToken::String => Bytecode::LdStr(UserStringIndex::new(0)),
                        SignatureToken::Address => Bytecode::LdAddr(AddressPoolIndex::new(0)),
                        SignatureToken::U64 => Bytecode::LdConst(0),
                        SignatureToken::Bool => Bytecode::LdFalse,
                        SignatureToken::ByteArray => {
                            Bytecode::LdByteArray(ByteArrayPoolIndex::new(0))
                        }
                        _ => unimplemented!("Unsupported return type: {:#?}", abstract_value.token),
                    };
                    state = self.apply_instruction(state, &mut bytecode, next_instruction);
                    state = self.apply_instruction(state, &mut bytecode, Bytecode::StLoc(*i as u8));
                } else if *target_availability == BorrowState::Unavailable
                    && *current_availability == BorrowState::Available
                {
                    state =
                        self.apply_instruction(state, &mut bytecode, Bytecode::MoveLoc(*i as u8));
                    state = self.apply_instruction(state, &mut bytecode, Bytecode::Pop);
                }
            } else {
                unreachable!("Target locals out contains new local");
            }
        }
        bytecode
    }
/// Given a valid starting state `abstract_state_in`, generate a valid sequence of
/// bytecode instructions such that `abstract_state_out` is reached.
Given a valid starting state `abstract_state_in`, generate a valid sequence of
bytecode instructions such that `abstract_state_out` is reached.
Given a valid starting state ` abstract_state_in ` generate a valid sequence of bytecode instructions such that ` abstract_state_out ` is reached .
pub fn generate_block(
        &mut self,
        abstract_state_in: AbstractState,
        abstract_state_out: AbstractState,
        module: CompiledModuleMut,
    ) -> Vec<Bytecode> {
        let mut bytecode: Vec<Bytecode> = Vec::new();
        let mut state = abstract_state_in.clone();
        // Generate block body
        loop {
            let candidates = self.candidate_instructions(
                state.clone(),
                abstract_state_in.get_locals().len(),
                module.clone(),
            );
            if candidates.is_empty() {
                warn!("No candidates found for state: [{:?}]", state);
                break;
            }
            match self.select_candidate(0, &state, &candidates) {
                Ok(next_instruction) => {
                    state = self.apply_instruction(state, &mut bytecode, next_instruction);
                    if state.is_final() {
                        break;
                    }
                }
                Err(err) => {
                    // Could not complete the bytecode sequence; reset to empty
                    error!("{}", err);
                    return Vec::new();
                }
            }
        }
        // Fix local availability
        for (i, (abstract_value, target_availability)) in abstract_state_out.get_locals().iter() {
            if let Some((_, current_availability)) = state.local_get(*i) {
                if *target_availability == BorrowState::Available
                    && *current_availability == BorrowState::Unavailable
                {
                    let next_instruction = match abstract_value.token {
                        SignatureToken::String => Bytecode::LdStr(UserStringIndex::new(0)),
                        SignatureToken::Address => Bytecode::LdAddr(AddressPoolIndex::new(0)),
                        SignatureToken::U64 => Bytecode::LdConst(0),
                        SignatureToken::Bool => Bytecode::LdFalse,
                        SignatureToken::ByteArray => {
                            Bytecode::LdByteArray(ByteArrayPoolIndex::new(0))
                        }
                        _ => unimplemented!("Unsupported return type: {:#?}", abstract_value.token),
                    };
                    state = self.apply_instruction(state, &mut bytecode, next_instruction);
                    state = self.apply_instruction(state, &mut bytecode, Bytecode::StLoc(*i as u8));
                } else if *target_availability == BorrowState::Unavailable
                    && *current_availability == BorrowState::Available
                {
                    state =
                        self.apply_instruction(state, &mut bytecode, Bytecode::MoveLoc(*i as u8));
                    state = self.apply_instruction(state, &mut bytecode, Bytecode::Pop);
                }
            } else {
                unreachable!("Target locals out contains new local");
            }
        }
        bytecode
    }
pub fn generate_block ( & mut self , abstract_state_in : AbstractState , abstract_state_out : AbstractState , module : CompiledModuleMut , ) -> Vec < Bytecode > { let mut bytecode : Vec < Bytecode > = Vec :: new ( ) ; let mut state = abstract_state_in . clone ( ) ; // Generate block body loop { let candidates = self . candidate_instructions ( state . clone ( ) , abstract_state_in . get_locals ( ) . len ( ) , module . clone ( ) , ) ; if candidates . is_empty ( ) { warn ! ( " " state ) ; break ; } match self . select_candidate ( 0 , & state , & candidates ) { Ok ( next_instruction ) => { state = self . apply_instruction ( state , & mut bytecode , next_instruction ) ; if state . is_final ( ) { break ; } } Err ( err ) => { // Could not complete the bytecode sequence; reset to empty error ! ( " " err ) ; return Vec :: new ( ) ; } } } // Fix local availability for ( i , ( abstract_value , target_availability ) ) in abstract_state_out . get_locals ( ) . iter ( ) { if let Some ( ( _ , current_availability ) ) = state . local_get ( * i ) { if * target_availability == BorrowState :: Available && * current_availability == BorrowState :: Unavailable { let next_instruction = match abstract_value . token { SignatureToken :: String => Bytecode :: LdStr ( UserStringIndex :: new ( 0 ) ) , SignatureToken :: Address => Bytecode :: LdAddr ( AddressPoolIndex :: new ( 0 ) ) , SignatureToken :: U64 => Bytecode :: LdConst ( 0 ) , SignatureToken :: Bool => Bytecode :: LdFalse , SignatureToken :: ByteArray => { Bytecode :: LdByteArray ( ByteArrayPoolIndex :: new ( 0 ) ) } _ => unimplemented ! ( " " abstract_value token ) , } ; state = self . apply_instruction ( state , & mut bytecode , next_instruction ) ; state = self . apply_instruction ( state , & mut bytecode , Bytecode :: StLoc ( * i as u8 ) ) ; } else if * target_availability == BorrowState :: Unavailable && * current_availability == BorrowState :: Available { state = self . apply_instruction ( state , & mut bytecode , Bytecode :: MoveLoc ( * i as u8 ) ) ; state = self . apply_instruction ( state , & mut bytecode , Bytecode :: Pop ) ; } } else { unreachable ! ( " " ) ; } } bytecode }
Given a valid starting state `abstract_state_in`, generate a valid sequence of
bytecode instructions such that `abstract_state_out` is reached.
Given a valid starting state ` abstract_state_in ` generate a valid sequence of bytecode instructions such that ` abstract_state_out ` is reached .
&mut self
abstract_state_in
AbstractState
abstract_state_out
AbstractState
module
CompiledModuleMut