use crate::polkavm::context::function::runtime;
use crate::polkavm::context::Context;
use crate::polkavm::WriteLLVM;
#[derive(Debug)]
pub struct DeployCode<B>
where
B: WriteLLVM,
{
inner: B,
}
impl<B> DeployCode<B>
where
B: WriteLLVM,
{
pub fn new(inner: B) -> Self {
Self { inner }
}
}
impl<B> WriteLLVM for DeployCode<B>
where
B: WriteLLVM,
{
fn declare(&mut self, context: &mut Context) -> anyhow::Result<()> {
let function_type = context.function_type::<inkwell::types::BasicTypeEnum>(vec![], 0);
context.add_function(
runtime::FUNCTION_DEPLOY_CODE,
function_type,
0,
Some(inkwell::module::Linkage::Private),
None,
false,
)?;
self.inner.declare(context)
}
fn into_llvm(self, context: &mut Context) -> anyhow::Result<()> {
context.set_current_function(runtime::FUNCTION_DEPLOY_CODE, None, false)?;
context.set_basic_block(context.current_function().borrow().entry_block());
self.inner.into_llvm(context)?;
context.set_debug_location(0, 0, None)?;
match context
.basic_block()
.get_last_instruction()
.map(|instruction| instruction.get_opcode())
{
Some(inkwell::values::InstructionOpcode::Br) => {}
Some(inkwell::values::InstructionOpcode::Switch) => {}
_ => context
.build_unconditional_branch(context.current_function().borrow().return_block()),
}
context.set_basic_block(context.current_function().borrow().return_block());
context.build_return(None);
context.pop_debug_scope();
Ok(())
}
}