#[derive(Debug, Clone)]
pub struct Argument<'ctx> {
pub value: Value<'ctx>,
pub original: Option<String>,
pub constant: Option<num::BigUint>,
}
#[derive(Clone, Debug)]
pub enum Value<'ctx> {
Register(inkwell::values::BasicValueEnum<'ctx>),
Pointer {
pointer: crate::polkavm::context::Pointer<'ctx>,
id: String,
},
}
impl<'ctx> Argument<'ctx> {
pub fn value(value: inkwell::values::BasicValueEnum<'ctx>) -> Self {
Self {
value: Value::Register(value),
original: None,
constant: None,
}
}
pub fn pointer(pointer: crate::polkavm::context::Pointer<'ctx>, id: String) -> Self {
Self {
value: Value::Pointer { pointer, id },
original: None,
constant: None,
}
}
pub fn with_original(mut self, original: String) -> Self {
self.original = Some(original);
self
}
pub fn with_constant(mut self, constant: num::BigUint) -> Self {
self.constant = Some(constant);
self
}
pub fn _to_llvm_value(&self) -> inkwell::values::BasicValueEnum<'ctx> {
match &self.value {
Value::Register(value) => *value,
Value::Pointer { .. } => unreachable!("invalid register value access"),
}
}
pub fn access(
&self,
context: &crate::polkavm::context::Context<'ctx>,
) -> anyhow::Result<inkwell::values::BasicValueEnum<'ctx>> {
match &self.value {
Value::Register(value) => Ok(*value),
Value::Pointer { pointer, id } => context.build_load(*pointer, id),
}
}
pub fn as_pointer(
&self,
context: &crate::polkavm::context::Context<'ctx>,
) -> anyhow::Result<crate::polkavm::context::Pointer<'ctx>> {
match &self.value {
Value::Register(value) => {
let pointer = context.build_alloca_at_entry(context.word_type(), "pvm_arg");
context.build_store(pointer, *value)?;
Ok(pointer)
}
Value::Pointer { pointer, .. } => Ok(*pointer),
}
}
}
impl<'ctx> From<inkwell::values::BasicValueEnum<'ctx>> for Argument<'ctx> {
fn from(value: inkwell::values::BasicValueEnum<'ctx>) -> Self {
Self::value(value)
}
}