use crate::errors::ContractPrecompilatonResult;
use crate::logic::errors::{CacheError, CompilationError, VMRunnerError};
use crate::logic::types::PromiseResult;
use crate::logic::{CompiledContractCache, External, VMContext, VMOutcome};
use crate::ContractCode;
use unc_parameters::vm::{Config, VMKind};
use unc_parameters::RuntimeFeesConfig;
pub(crate) type VMResult<T = VMOutcome> = Result<T, VMRunnerError>;
pub fn run(
code: &ContractCode,
method_name: &str,
ext: &mut dyn External,
context: VMContext,
wasm_config: &Config,
fees_config: &RuntimeFeesConfig,
promise_results: &[PromiseResult],
cache: Option<&dyn CompiledContractCache>,
) -> VMResult {
let vm_kind = wasm_config.vm_kind;
let span = tracing::debug_span!(
target: "vm",
"run",
"code.len" = code.code().len(),
%method_name,
?vm_kind,
burnt_gas = tracing::field::Empty,
)
.entered();
let runtime = vm_kind
.runtime(wasm_config.clone())
.unwrap_or_else(|| panic!("the {vm_kind:?} runtime has not been enabled at compile time"));
let outcome =
runtime.run(code, method_name, ext, context, fees_config, promise_results, cache)?;
span.record("burnt_gas", &outcome.burnt_gas);
Ok(outcome)
}
pub trait VM {
fn run(
&self,
code: &ContractCode,
method_name: &str,
ext: &mut dyn External,
context: VMContext,
fees_config: &RuntimeFeesConfig,
promise_results: &[PromiseResult],
cache: Option<&dyn CompiledContractCache>,
) -> VMResult;
fn precompile(
&self,
code: &ContractCode,
cache: &dyn CompiledContractCache,
) -> Result<Result<ContractPrecompilatonResult, CompilationError>, CacheError>;
}
pub trait VMKindExt {
fn runtime(&self, config: Config) -> Option<Box<dyn VM>>;
}
impl VMKindExt for VMKind {
#[allow(unused_variables)]
fn runtime(&self, config: Config) -> Option<Box<dyn VM>> {
match self {
#[cfg(all(feature = "wasmer0_vm", target_arch = "x86_64"))]
Self::Wasmer0 => Some(Box::new(crate::wasmer_runner::Wasmer0VM::new(config))),
#[cfg(feature = "wasmtime_vm")]
Self::Wasmtime => Some(Box::new(crate::wasmtime_runner::WasmtimeVM::new(config))),
#[cfg(all(feature = "wasmer2_vm", target_arch = "x86_64"))]
Self::Wasmer2 => Some(Box::new(crate::wasmer2_runner::Wasmer2VM::new(config))),
#[cfg(all(feature = "unc_vm", target_arch = "x86_64"))]
Self::UncVm => Some(Box::new(crate::unc_vm_runner::UncVM::new(config))),
#[allow(unreachable_patterns)] _ => None,
}
}
}