use std::sync::Mutex;
use chio_kernel::KernelError;
use crate::abi::{GuardRequest, GuardVerdict, WasmGuardAbi};
use crate::epoch::EpochId;
use crate::error::WasmGuardError;
pub struct LoadedModule {
epoch_id: EpochId,
backend: Mutex<Box<dyn WasmGuardAbi>>,
manifest_sha256: Option<String>,
}
impl LoadedModule {
#[must_use]
pub fn new(
backend: Box<dyn WasmGuardAbi>,
epoch_id: EpochId,
manifest_sha256: Option<String>,
) -> Self {
Self {
epoch_id,
backend: Mutex::new(backend),
manifest_sha256,
}
}
#[must_use]
pub fn epoch_id(&self) -> EpochId {
self.epoch_id
}
#[must_use]
pub fn manifest_sha256(&self) -> Option<&str> {
self.manifest_sha256.as_deref()
}
pub(crate) fn evaluate(
&self,
request: &GuardRequest,
) -> Result<(Result<GuardVerdict, WasmGuardError>, Option<u64>), KernelError> {
let mut backend = self
.backend
.lock()
.map_err(|e| KernelError::Internal(format!("WASM guard mutex poisoned: {e}")))?;
let result = backend.evaluate(request);
let fuel = backend.last_fuel_consumed();
Ok((result, fuel))
}
pub(crate) fn clear_instance_pre_cache(&self) {
let mut backend = match self.backend.lock() {
Ok(backend) => backend,
Err(poisoned) => poisoned.into_inner(),
};
backend.clear_instance_pre_cache();
}
}
impl std::fmt::Debug for LoadedModule {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("LoadedModule")
.field("epoch_id", &self.epoch_id)
.field("manifest_sha256", &self.manifest_sha256.as_deref())
.finish()
}
}