//! Translates the jump operations. /// Translates the unconditional jump. pub fn unconditional( context: &mut revive_llvm_context::PolkaVMContext, destination: num::BigUint, stack_hash: md5::Digest, ) -> anyhow::Result<()> where D: revive_llvm_context::PolkaVMDependency + Clone, { let code_type = context .code_type() .ok_or_else(|| anyhow::anyhow!("The contract code part type is undefined"))?; let block_key = revive_llvm_context::PolkaVMFunctionBlockKey::new(code_type, destination); let block = context .current_function() .borrow() .evmla() .find_block(&block_key, &stack_hash)?; context.build_unconditional_branch(block.inner()); Ok(()) } /// Translates the conditional jump. pub fn conditional( context: &mut revive_llvm_context::PolkaVMContext, destination: num::BigUint, stack_hash: md5::Digest, stack_height: usize, ) -> anyhow::Result<()> where D: revive_llvm_context::PolkaVMDependency + Clone, { let code_type = context .code_type() .ok_or_else(|| anyhow::anyhow!("The contract code part type is undefined"))?; let block_key = revive_llvm_context::PolkaVMFunctionBlockKey::new(code_type, destination); let condition_pointer = context.evmla().stack[stack_height] .to_llvm() .into_pointer_value(); let condition = context.build_load( revive_llvm_context::PolkaVMPointer::new_stack_field(context, condition_pointer), format!("conditional_{block_key}_condition").as_str(), )?; let condition = context.builder().build_int_compare( inkwell::IntPredicate::NE, condition.into_int_value(), context.word_const(0), format!("conditional_{block_key}_condition_compared").as_str(), )?; let then_block = context .current_function() .borrow() .evmla() .find_block(&block_key, &stack_hash)?; let join_block = context.append_basic_block(format!("conditional_{block_key}_join_block").as_str()); context.build_conditional_branch(condition, then_block.inner(), join_block)?; context.set_basic_block(join_block); Ok(()) }