//! The runtime code function. use std::marker::PhantomData; use crate::polkavm::context::code_type::CodeType; use crate::polkavm::context::function::runtime; use crate::polkavm::context::Context; use crate::polkavm::Dependency; use crate::polkavm::WriteLLVM; /// The runtime code function. /// Is a special function that is only used by the front-end generated code. #[derive(Debug)] pub struct RuntimeCode where B: WriteLLVM, D: Dependency + Clone, { /// The runtime code AST representation. inner: B, /// The `D` phantom data. _pd: PhantomData, } impl RuntimeCode where B: WriteLLVM, D: Dependency + Clone, { /// A shortcut constructor. pub fn new(inner: B) -> Self { Self { inner, _pd: PhantomData, } } } impl WriteLLVM for RuntimeCode where B: WriteLLVM, D: Dependency + Clone, { fn declare(&mut self, context: &mut Context) -> anyhow::Result<()> { let function_type = context.function_type::(vec![], 0, false); context.add_function( runtime::FUNCTION_RUNTIME_CODE, function_type, 0, Some(inkwell::module::Linkage::External), )?; self.inner.declare(context) } fn into_llvm(self, context: &mut Context) -> anyhow::Result<()> { context.set_current_function(runtime::FUNCTION_RUNTIME_CODE)?; context.set_basic_block(context.current_function().borrow().entry_block()); context.set_code_type(CodeType::Runtime); self.inner.into_llvm(context)?; 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_unreachable(); Ok(()) } }