use super::*;
impl<N: Network> FinalizeRegisters<N> {
#[inline]
pub fn load_literal(&self, stack: &Stack<N>, operand: &Operand<N>) -> Result<Literal<N>> {
match self.load(stack, operand)? {
Value::Plaintext(Plaintext::Literal(literal, ..)) => Ok(literal),
Value::Plaintext(Plaintext::Interface(..)) => bail!("Operand must be a literal"),
Value::Record(..) => bail!("Operand must be a literal"),
}
}
#[inline]
pub fn load_plaintext(&self, stack: &Stack<N>, operand: &Operand<N>) -> Result<Plaintext<N>> {
match self.load(stack, operand)? {
Value::Plaintext(plaintext) => Ok(plaintext),
Value::Record(..) => bail!("Operand must be a plaintext"),
}
}
#[inline]
pub fn load(&self, stack: &Stack<N>, operand: &Operand<N>) -> Result<Value<N>> {
let register = match operand {
Operand::Literal(literal) => return Ok(Value::Plaintext(Plaintext::from(literal))),
Operand::Register(register) => register,
Operand::ProgramID(program_id) => {
return Ok(Value::Plaintext(Plaintext::from(Literal::Address(program_id.to_address()?))));
}
Operand::Caller => bail!("Forbidden operation: Cannot use 'self.caller' in 'finalize'"),
};
let stack_value =
self.registers.get(®ister.locator()).ok_or_else(|| anyhow!("'{register}' does not exist"))?;
let stack_value = match register {
Register::Locator(..) => stack_value.clone(),
Register::Member(_, ref path) => {
match stack_value {
Value::Plaintext(plaintext) => Value::Plaintext(plaintext.find(path)?),
Value::Record(record) => match record.find(path)? {
Entry::Constant(plaintext) | Entry::Public(plaintext) | Entry::Private(plaintext) => {
Value::Plaintext(plaintext)
}
},
}
}
};
match self.finalize_types.get_type(stack, register) {
Ok(register_type) => stack.matches_register_type(&stack_value, ®ister_type)?,
Err(error) => bail!("Register '{register}' is not a member of the function: {error}"),
};
Ok(stack_value)
}
}