Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

c-api: wasmtime_store_limiter #5761

Merged
merged 1 commit into from
Feb 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions crates/c-api/include/wasmtime/store.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down
38 changes: 37 additions & 1 deletion crates/c-api/src/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
///
Expand Down Expand Up @@ -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<Val>,

/// Limits for the store.
pub store_limits: StoreLimits,
}

#[no_mangle]
Expand All @@ -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(),
},
),
})
Expand All @@ -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
Expand Down