pub const DEFAULT_INSTANCE_LIMIT: usize = 10000;
pub const DEFAULT_TABLE_LIMIT: usize = 10000;
pub const DEFAULT_MEMORY_LIMIT: usize = 10000;
pub trait ResourceLimiter {
fn memory_growing(&mut self, current: usize, desired: usize, maximum: Option<usize>) -> bool;
fn memory_grow_failed(&mut self, _error: &anyhow::Error) {}
fn table_growing(&mut self, current: u32, desired: u32, maximum: Option<u32>) -> bool;
fn table_grow_failed(&mut self, _error: &anyhow::Error) {}
fn instances(&self) -> usize {
DEFAULT_INSTANCE_LIMIT
}
fn tables(&self) -> usize {
DEFAULT_TABLE_LIMIT
}
fn memories(&self) -> usize {
DEFAULT_MEMORY_LIMIT
}
}
#[cfg(feature = "async")]
#[async_trait::async_trait]
pub trait ResourceLimiterAsync {
async fn memory_growing(
&mut self,
current: usize,
desired: usize,
maximum: Option<usize>,
) -> bool;
fn memory_grow_failed(&mut self, _error: &anyhow::Error) {}
async fn table_growing(&mut self, current: u32, desired: u32, maximum: Option<u32>) -> bool;
fn table_grow_failed(&mut self, _error: &anyhow::Error) {}
fn instances(&self) -> usize {
DEFAULT_INSTANCE_LIMIT
}
fn tables(&self) -> usize {
DEFAULT_TABLE_LIMIT
}
fn memories(&self) -> usize {
DEFAULT_MEMORY_LIMIT
}
}
pub struct StoreLimitsBuilder(StoreLimits);
impl StoreLimitsBuilder {
pub fn new() -> Self {
Self(StoreLimits::default())
}
pub fn memory_size(mut self, limit: usize) -> Self {
self.0.memory_size = Some(limit);
self
}
pub fn table_elements(mut self, limit: u32) -> Self {
self.0.table_elements = Some(limit);
self
}
pub fn instances(mut self, limit: usize) -> Self {
self.0.instances = limit;
self
}
pub fn tables(mut self, tables: usize) -> Self {
self.0.tables = tables;
self
}
pub fn memories(mut self, memories: usize) -> Self {
self.0.memories = memories;
self
}
pub fn build(self) -> StoreLimits {
self.0
}
}
pub struct StoreLimits {
memory_size: Option<usize>,
table_elements: Option<u32>,
instances: usize,
tables: usize,
memories: usize,
}
impl Default for StoreLimits {
fn default() -> Self {
Self {
memory_size: None,
table_elements: None,
instances: DEFAULT_INSTANCE_LIMIT,
tables: DEFAULT_TABLE_LIMIT,
memories: DEFAULT_MEMORY_LIMIT,
}
}
}
impl ResourceLimiter for StoreLimits {
fn memory_growing(&mut self, _current: usize, desired: usize, _maximum: Option<usize>) -> bool {
match self.memory_size {
Some(limit) if desired > limit => false,
_ => true,
}
}
fn table_growing(&mut self, _current: u32, desired: u32, _maximum: Option<u32>) -> bool {
match self.table_elements {
Some(limit) if desired > limit => false,
_ => true,
}
}
fn instances(&self) -> usize {
self.instances
}
fn tables(&self) -> usize {
self.tables
}
fn memories(&self) -> usize {
self.memories
}
}