1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
// Copyright (C) 2019-2022 Aleo Systems Inc.
// This file is part of the snarkVM library.
// The snarkVM library is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// The snarkVM library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with the snarkVM library. If not, see <https://www.gnu.org/licenses/>.
use super::*;
impl<N: Network> FinalizeRegisters<N> {
/// Assigns the given literal to the given register, assuming the register is not already assigned.
///
/// # Errors
/// This method will halt if the given register is a register member.
/// This method will halt if the given register is an input register.
/// This method will halt if the register is already used.
#[inline]
pub fn store_literal(&mut self, stack: &Stack<N>, register: &Register<N>, literal: Literal<N>) -> Result<()> {
self.store(stack, register, Value::Plaintext(Plaintext::from(literal)))
}
/// Assigns the given value to the given register, assuming the register is not already assigned.
///
/// # Errors
/// This method will halt if the given register is a register member.
/// This method will halt if the given register is an input register.
/// This method will halt if the register is already used.
#[inline]
pub fn store(&mut self, stack: &Stack<N>, register: &Register<N>, stack_value: Value<N>) -> Result<()> {
match register {
Register::Locator(locator) => {
// Ensure the register assignments are monotonically increasing.
let expected_locator = self.registers.len() as u64;
ensure!(expected_locator == *locator, "Out-of-order write operation at '{register}'");
// Ensure the register does not already exist.
ensure!(!self.registers.contains_key(locator), "Cannot write to occupied register '{register}'");
// Ensure the register type is valid.
match self.finalize_types.get_type(stack, register) {
// Ensure the stack value matches the register type.
Ok(register_type) => stack.matches_register_type(&stack_value, ®ister_type)?,
// Ensure the register is defined.
Err(error) => bail!("Register '{register}' is missing a type definition: {error}"),
};
// Store the stack value.
match self.registers.insert(*locator, stack_value) {
// Ensure the register has not been previously stored.
Some(..) => bail!("Attempted to write to register '{register}' again"),
// Return on success.
None => Ok(()),
}
}
// Ensure the register is not a register member.
Register::Member(..) => bail!("Cannot store to a register member: '{register}'"),
}
}
}