use std::convert::TryFrom;
use std::sync::Arc;
use wasmer::{BaseTunables, CompilerConfig, Pages, Store, Target, WASM_PAGE_SIZE};
use wasmer_compiler_singlepass::Singlepass;
use wasmer_engine_universal::Universal;
use wasmer_middlewares::Metering;
use super::custom_tunables::CustomTunables;
use crate::gas::wasm_opcode_gas_schedule;
use crate::wasmer::non_determinism_filter::NonDeterminismFilter;
pub fn instantiate_store(gas_limit: u64, memory_limit: Option<usize>) -> Store {
let nd_filter = Arc::new(NonDeterminismFilter::default());
let metering = Arc::new(Metering::new(gas_limit, wasm_opcode_gas_schedule));
let mut compiler_config = Singlepass::new();
compiler_config.push_middleware(nd_filter);
compiler_config.push_middleware(metering);
let engine = Universal::new(compiler_config).engine();
match memory_limit {
Some(limit) => {
let base_tunables = BaseTunables::for_target(&Target::default());
let custom_tunables = CustomTunables::new(base_tunables, limit_pages(limit));
Store::new_with_tunables(&engine, custom_tunables)
}
None => Store::new(&engine),
}
}
fn limit_pages(limit: usize) -> Pages {
const MAX_PAGES_AVAILABLE: u32 = 65536;
let capped_size = match u32::try_from(limit / WASM_PAGE_SIZE) {
Ok(x) => std::cmp::min(x, MAX_PAGES_AVAILABLE),
Err(_too_large) => MAX_PAGES_AVAILABLE,
};
Pages(capped_size)
}