pub fn generate(
        &mut self,
        locals: &[SignatureToken],
        signature: &FunctionSignature,
        target_min: usize,
        target_max: usize,
    ) -> Vec<Bytecode> {
        let mut bytecode: Vec<Bytecode> = Vec::new();
        let mut state: AbstractState = AbstractState::new(&Vec::new());
        loop {
            debug!("Bytecode: [{:?}]", bytecode);
            debug!("AbstractState: [{:?}]", state);
            let candidates = self.candidate_instructions(state.clone(), locals.len());
            debug!("Candidates: [{:?}]", candidates);
            if candidates.is_empty() {
                warn!("No candidates found for state: [{:?}]", state);
                break;
            }
            let next_instruction = self.select_candidate(0, &state, &candidates);
            debug!("Next instr: {:?}", next_instruction);
            state = self.abstract_step(state, next_instruction.clone());
            debug!("New state: {:?}", state);
            bytecode.push(next_instruction);
            debug!("**********************");
            if bytecode.len() >= target_min && state.is_final() || bytecode.len() >= target_max {
                info!("Instructions generated: {}", bytecode.len());
                break;
            }
        }
        for return_type in signature.return_types.iter() {
            match return_type {
                SignatureToken::String => bytecode.push(Bytecode::LdStr(StringPoolIndex::new(0))),
                SignatureToken::Address => {
                    bytecode.push(Bytecode::LdAddr(AddressPoolIndex::new(0)))
                }
                SignatureToken::U64 => bytecode.push(Bytecode::LdConst(0)),
                SignatureToken::Bool => bytecode.push(Bytecode::LdFalse),
                SignatureToken::ByteArray => {
                    bytecode.push(Bytecode::LdByteArray(ByteArrayPoolIndex::new(0)))
                }
                _ => panic!("Unsupported return type: {:#?}", return_type),
            }
        }
        bytecode.push(Bytecode::Ret);
        bytecode
    }
/// Return a sequence of bytecode instructions given a set of `locals` and a target return
/// `signature`. The sequence should contain at least `target_min` and at most `target_max`
/// instructions.
Return a sequence of bytecode instructions given a set of `locals` and a target return
`signature`. The sequence should contain at least `target_min` and at most `target_max`
instructions.
Return a sequence of bytecode instructions given a set of ` locals ` and a target return ` signature ` . The sequence should contain at least ` target_min ` and at most ` target_max ` instructions .
pub fn generate(
        &mut self,
        locals: &[SignatureToken],
        signature: &FunctionSignature,
        target_min: usize,
        target_max: usize,
    ) -> Vec<Bytecode> {
        let mut bytecode: Vec<Bytecode> = Vec::new();
        let mut state: AbstractState = AbstractState::new(&Vec::new());
        loop {
            debug!("Bytecode: [{:?}]", bytecode);
            debug!("AbstractState: [{:?}]", state);
            let candidates = self.candidate_instructions(state.clone(), locals.len());
            debug!("Candidates: [{:?}]", candidates);
            if candidates.is_empty() {
                warn!("No candidates found for state: [{:?}]", state);
                break;
            }
            let next_instruction = self.select_candidate(0, &state, &candidates);
            debug!("Next instr: {:?}", next_instruction);
            state = self.abstract_step(state, next_instruction.clone());
            debug!("New state: {:?}", state);
            bytecode.push(next_instruction);
            debug!("**********************");
            if bytecode.len() >= target_min && state.is_final() || bytecode.len() >= target_max {
                info!("Instructions generated: {}", bytecode.len());
                break;
            }
        }
        for return_type in signature.return_types.iter() {
            match return_type {
                SignatureToken::String => bytecode.push(Bytecode::LdStr(StringPoolIndex::new(0))),
                SignatureToken::Address => {
                    bytecode.push(Bytecode::LdAddr(AddressPoolIndex::new(0)))
                }
                SignatureToken::U64 => bytecode.push(Bytecode::LdConst(0)),
                SignatureToken::Bool => bytecode.push(Bytecode::LdFalse),
                SignatureToken::ByteArray => {
                    bytecode.push(Bytecode::LdByteArray(ByteArrayPoolIndex::new(0)))
                }
                _ => panic!("Unsupported return type: {:#?}", return_type),
            }
        }
        bytecode.push(Bytecode::Ret);
        bytecode
    }
pub fn generate ( & mut self , locals : & [ SignatureToken ] , signature : & FunctionSignature , target_min : usize , target_max : usize , ) -> Vec < Bytecode > { let mut bytecode : Vec < Bytecode > = Vec :: new ( ) ; let mut state : AbstractState = AbstractState :: new ( & Vec :: new ( ) ) ; loop { debug ! ( " " bytecode ) ; debug ! ( " " state ) ; let candidates = self . candidate_instructions ( state . clone ( ) , locals . len ( ) ) ; debug ! ( " " candidates ) ; if candidates . is_empty ( ) { warn ! ( " " state ) ; break ; } let next_instruction = self . select_candidate ( 0 , & state , & candidates ) ; debug ! ( " " next_instruction ) ; state = self . abstract_step ( state , next_instruction . clone ( ) ) ; debug ! ( " " state ) ; bytecode . push ( next_instruction ) ; debug ! ( " " ) ; if bytecode . len ( ) >= target_min && state . is_final ( ) || bytecode . len ( ) >= target_max { info ! ( " " bytecode len ( ) ) ; break ; } } for return_type in signature . return_types . iter ( ) { match return_type { SignatureToken :: String => bytecode . push ( Bytecode :: LdStr ( StringPoolIndex :: new ( 0 ) ) ) , SignatureToken :: Address => { bytecode . push ( Bytecode :: LdAddr ( AddressPoolIndex :: new ( 0 ) ) ) } SignatureToken :: U64 => bytecode . push ( Bytecode :: LdConst ( 0 ) ) , SignatureToken :: Bool => bytecode . push ( Bytecode :: LdFalse ) , SignatureToken :: ByteArray => { bytecode . push ( Bytecode :: LdByteArray ( ByteArrayPoolIndex :: new ( 0 ) ) ) } _ => panic ! ( " " return_type ) , } } bytecode . push ( Bytecode :: Ret ) ; bytecode }
Return a sequence of bytecode instructions given a set of `locals` and a target return
`signature`.
Return a sequence of bytecode instructions given a set of ` locals ` and a target return ` signature ` .
&mut self
locals
&[SignatureToken]
signature
&FunctionSignature
target_min
usize
target_max
usize
&mut self
locals
&[SignatureToken]
signature
&FunctionSignature
target_min
usize
target_max
usize