diff --git a/crates/c-api/include/wasmtime/store.h b/crates/c-api/include/wasmtime/store.h index 55c9f680bd..ba1d74a943 100644 --- a/crates/c-api/include/wasmtime/store.h +++ b/crates/c-api/include/wasmtime/store.h @@ -79,6 +79,44 @@ WASM_API_EXTERN wasmtime_store_t *wasmtime_store_new( */ WASM_API_EXTERN wasmtime_context_t *wasmtime_store_context(wasmtime_store_t *store); +/** + * \brief Provides limits for a store. Used by hosts to limit resource + * consumption of instances. Use negative value to keep the default value + * for the limit. + * + * \param store store where the limits should be set. + * \param memory_size the maximum number of bytes a linear memory can grow to. + * Growing a linear memory beyond this limit will fail. By default, + * linear memory will not be limited. + * \param table_elements the maximum number of elements in a table. + * Growing a table beyond this limit will fail. By default, table elements + * will not be limited. + * \param instances the maximum number of instances that can be created + * for a Store. Module instantiation will fail if this limit is exceeded. + * This value defaults to 10,000. + * \param tables the maximum number of tables that can be created for a Store. + * Module instantiation will fail if this limit is exceeded. This value + * defaults to 10,000. + * \param memories the maximum number of linear memories that can be created + * for a Store. Instantiation will fail with an error if this limit is exceeded. + * This value defaults to 10,000. + * + * Use any negative value for the parameters that should be kept on + * the default values. + * + * Note that the limits are only used to limit the creation/growth of + * resources in the future, this does not retroactively attempt to apply + * limits to the store. + */ +WASM_API_EXTERN void wasmtime_store_limiter( + wasmtime_store_t *store, + int64_t memory_size, + int64_t table_elements, + int64_t instances, + int64_t tables, + int64_t memories +); + /** * \brief Deletes a store. */ diff --git a/crates/c-api/src/store.rs b/crates/c-api/src/store.rs index cac07b0ca3..3949d46b0e 100644 --- a/crates/c-api/src/store.rs +++ b/crates/c-api/src/store.rs @@ -2,7 +2,10 @@ use crate::{wasm_engine_t, wasmtime_error_t, wasmtime_val_t, ForeignData}; use std::cell::UnsafeCell; use std::ffi::c_void; use std::sync::Arc; -use wasmtime::{AsContext, AsContextMut, Store, StoreContext, StoreContextMut, Val}; +use wasmtime::{ + AsContext, AsContextMut, Store, StoreContext, StoreContextMut, StoreLimits, StoreLimitsBuilder, + Val, +}; /// This representation of a `Store` is used to implement the `wasm.h` API. /// @@ -77,6 +80,9 @@ pub struct StoreData { /// Temporary storage for usage during host->wasm calls, same as above but /// for a different direction. pub wasm_val_storage: Vec, + + /// Limits for the store. + pub store_limits: StoreLimits, } #[no_mangle] @@ -94,6 +100,7 @@ pub extern "C" fn wasmtime_store_new( wasi: None, hostcall_val_storage: Vec::new(), wasm_val_storage: Vec::new(), + store_limits: StoreLimits::default(), }, ), }) @@ -104,6 +111,35 @@ pub extern "C" fn wasmtime_store_context(store: &mut wasmtime_store_t) -> CStore store.store.as_context_mut() } +#[no_mangle] +pub extern "C" fn wasmtime_store_limiter( + store: &mut wasmtime_store_t, + memory_size: i64, + table_elements: i64, + instances: i64, + tables: i64, + memories: i64, +) { + let mut limiter = StoreLimitsBuilder::new(); + if memory_size >= 0 { + limiter = limiter.memory_size(memory_size as usize); + } + if table_elements >= 0 { + limiter = limiter.table_elements(table_elements as u32); + } + if instances >= 0 { + limiter = limiter.instances(instances as usize); + } + if tables >= 0 { + limiter = limiter.tables(tables as usize); + } + if memories >= 0 { + limiter = limiter.memories(memories as usize); + } + store.store.data_mut().store_limits = limiter.build(); + store.store.limiter(|data| &mut data.store_limits); +} + #[no_mangle] pub extern "C" fn wasmtime_context_get_data(store: CStoreContext<'_>) -> *mut c_void { store.data().foreign.data