fuel-vm 0.66.3

FuelVM interpreter.
Documentation
use fuel_asm::{
    RegId,
    Word,
};
use fuel_tx::PanicReason;
use fuel_types::BlobId;

use crate::{
    error::IoResult,
    interpreter::{
        contract::blob_size,
        memory::copy_from_storage_zero_fill,
    },
    storage::{
        BlobData,
        InterpreterStorage,
    },
};

use super::{
    GetRegMut,
    Interpreter,
    Memory,
    SystemRegisters,
    WriteRegKey,
    internal::inc_pc,
    split_registers,
};

impl<M, S, Tx, Ecal, V> Interpreter<M, S, Tx, Ecal, V>
where
    M: Memory,
    S: InterpreterStorage,
    <S as InterpreterStorage>::DataError: From<S::DataError>,
{
    pub(crate) fn blob_size(
        &mut self,
        dst: RegId,
        blob_id_ptr: Word,
    ) -> IoResult<(), S::DataError> {
        let gas_cost = self
            .interpreter_params
            .gas_costs
            .bsiz()
            .map_err(PanicReason::from)?;
        self.gas_charge(gas_cost.base())?;

        let blob_id = BlobId::from(self.memory.as_ref().read_bytes(blob_id_ptr)?);

        let size = blob_size(&self.storage, &blob_id)?;

        self.dependent_gas_charge_without_base(gas_cost, size as Word)?;
        let (SystemRegisters { pc, .. }, mut w) = split_registers(&mut self.registers);
        let result = &mut w[WriteRegKey::try_from(dst)?];
        *result = size as Word;
        inc_pc(pc);
        Ok(())
    }

    pub(crate) fn blob_load_data(
        &mut self,
        dst_ptr: Word,
        blob_id_ptr: Word,
        blob_offset: Word,
        len: Word,
    ) -> IoResult<(), S::DataError> {
        let gas_cost = self
            .interpreter_params
            .gas_costs
            .bldd()
            .map_err(PanicReason::from)?;
        self.gas_charge(gas_cost.base())?;

        let blob_id = BlobId::from(self.memory.as_ref().read_bytes(blob_id_ptr)?);
        let owner = self.ownership_registers();

        let blob_len = blob_size(&self.storage, &blob_id)?;
        let charge_len = len.max(blob_len as Word);
        self.dependent_gas_charge_without_base(gas_cost, charge_len)?;

        copy_from_storage_zero_fill::<BlobData, _>(
            self.memory.as_mut(),
            owner,
            &self.storage,
            dst_ptr,
            len,
            &blob_id,
            blob_offset,
            blob_len,
            PanicReason::BlobNotFound,
        )?;

        inc_pc(self.registers.pc_mut());
        Ok(())
    }
}