diff --git a/CHANGELOG.md b/CHANGELOG.md index e8aced7e259..f9417379b7d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,8 +10,10 @@ Looking for changes that affect our C API? See the [C API Changelog](lib/c-api/C ## 2.0.0-rc2 - 2020/06/03 -### Changed +### Added +- [#2402](https://github.com/wasmerio/wasmer/pull/2402) Add more examples and more doctests for `wasmer-middlewares`. +### Changed - [#2399](https://github.com/wasmerio/wasmer/pull/2399) Add the Dart integration in the `README.md`. ### Fixed diff --git a/lib/middlewares/Cargo.toml b/lib/middlewares/Cargo.toml index 74eb3eaf661..4096b2f85f8 100644 --- a/lib/middlewares/Cargo.toml +++ b/lib/middlewares/Cargo.toml @@ -16,5 +16,8 @@ wasmer-types = { path = "../types", version = "2.0.0-rc2" } wasmer-vm = { path = "../vm", version = "2.0.0-rc2" } loupe = "0.1" +[dev-dependencies] +wasmer = { path = "../api", version = "2.0.0-rc2", features = ["compiler"] } + [badges] maintenance = { status = "actively-developed" } diff --git a/lib/middlewares/README.md b/lib/middlewares/README.md index 766c4cc4bdb..04fea2eeb2e 100644 --- a/lib/middlewares/README.md +++ b/lib/middlewares/README.md @@ -6,3 +6,7 @@ middlewares: - `metering`: A middleware for tracking how many operators are executed in total and putting a limit on the total number of operators executed. + + [See the `metering` + example](https://github.com/wasmerio/wasmer/blob/master/examples/metering.rs) + to get a concrete and complete example. diff --git a/lib/middlewares/src/lib.rs b/lib/middlewares/src/lib.rs index 561366c22c7..15ef8204d06 100644 --- a/lib/middlewares/src/lib.rs +++ b/lib/middlewares/src/lib.rs @@ -1,5 +1,6 @@ pub mod metering; -// The most commonly used symbol are exported at top level of the module. Others are available -// via modules, e.g. `wasmer_middlewares::metering::get_remaining_points` +// The most commonly used symbol are exported at top level of the +// module. Others are available via modules, +// e.g. `wasmer_middlewares::metering::get_remaining_points` pub use metering::Metering; diff --git a/lib/middlewares/src/metering.rs b/lib/middlewares/src/metering.rs index 4856c250d80..18be778b06f 100644 --- a/lib/middlewares/src/metering.rs +++ b/lib/middlewares/src/metering.rs @@ -1,5 +1,12 @@ -//! `metering` is a middleware for tracking how many operators are executed in total -//! and putting a limit on the total number of operators executed. +//! `metering` is a middleware for tracking how many operators are +//! executed in total and putting a limit on the total number of +//! operators executed. The WebAssemblt instance execution is stopped +//! when the limit is reached. +//! +//! # Example +//! +//! [See the `metering` detailed and complete +//! example](https://github.com/wasmerio/wasmer/blob/master/examples/metering.rs). use loupe::{MemoryUsage, MemoryUsageTracker}; use std::convert::TryInto; @@ -46,9 +53,36 @@ impl fmt::Debug for MeteringGlobalIndexes { /// /// # Panic /// -/// An instance of `Metering` should not be shared among different modules, since it tracks -/// module-specific information like the global index to store metering state. Attempts to use -/// a `Metering` instance from multiple modules will result in a panic. +/// An instance of `Metering` should _not_ be shared among different +/// modules, since it tracks module-specific information like the +/// global index to store metering state. Attempts to use a `Metering` +/// instance from multiple modules will result in a panic. +/// +/// # Example +/// +/// ```rust +/// use std::sync::Arc; +/// use wasmer::{wasmparser::Operator, CompilerConfig}; +/// use wasmer_middlewares::Metering; +/// +/// fn create_metering_middleware(compiler_config: &mut dyn CompilerConfig) { +/// // Let's define a dummy cost function, +/// // which counts 1 for all operators. +/// let cost_function = |_operator: &Operator| -> u64 { 1 }; +/// +/// // Let's define the initial limit. +/// let initial_limit = 10; +/// +/// // Let's creating the metering middleware. +/// let metering = Arc::new(Metering::new( +/// initial_limit, +/// cost_function +/// )); +/// +/// // Finally, let's push the middleware. +/// compiler_config.push_middleware(metering); +/// } +/// ``` pub struct Metering u64 + Send + Sync> { /// Initial limit of points. initial_limit: u64, @@ -72,13 +106,22 @@ pub struct FunctionMetering u64 + Send + Sync> { accumulated_cost: u64, } +/// Represents the type of the metering points, either `Remaining` or +/// `Exhausted`. +/// +/// # Example +/// +/// See the [`get_remaining_points`] function to get an example. #[derive(Debug, PartialEq)] pub enum MeteringPoints { /// The given number of metering points is left for the execution. - /// If the value is 0, all points are consumed but the execution was not terminated. + /// If the value is 0, all points are consumed but the execution + /// was not terminated. Remaining(u64), - /// The execution was terminated because the metering points were exhausted. - /// You can recover from this state by setting the points via `set_remaining_points` and restart the execution. + + /// The execution was terminated because the metering points were + /// exhausted. You can recover from this state by setting the + /// points via [`set_remaining_points`] and restart the execution. Exhausted, } @@ -225,15 +268,29 @@ impl u64 + Send + Sync> FunctionMiddleware for FunctionMeter } } -/// Get the remaining points in an `Instance`. +/// Get the remaining points in an [`Instance`][wasmer::Instance]. /// -/// This can be used in a headless engine after an ahead-of-time compilation -/// as all required state lives in the instance. +/// Note: This can be used in a headless engine after an ahead-of-time +/// compilation as all required state lives in the instance. /// /// # Panic /// -/// The instance Module must have been processed with the [`Metering`] middleware -/// at compile time, otherwise this will panic. +/// The [`Instance`][wasmer::Instance) must have been processed with +/// the [`Metering`] middleware at compile time, otherwise this will +/// panic. +/// +/// # Example +/// +/// ```rust +/// use wasmer::Instance; +/// use wasmer_middlewares::metering::{get_remaining_points, MeteringPoints}; +/// +/// /// Check whether the instance can continue to run based on the +/// /// number of remaining points. +/// fn can_continue_to_run(instance: &Instance) -> bool { +/// matches!(get_remaining_points(instance), MeteringPoints::Remaining(points) if points > 0) +/// } +/// ``` pub fn get_remaining_points(instance: &Instance) -> MeteringPoints { let exhausted: i32 = instance .exports @@ -258,15 +315,32 @@ pub fn get_remaining_points(instance: &Instance) -> MeteringPoints { MeteringPoints::Remaining(points) } -/// Set the provided remaining points in an `Instance`. +/// Set the new provided remaining points in an +/// [`Instance`][wasmer::Instance]. /// -/// This can be used in a headless engine after an ahead-of-time compilation -/// as all required state lives in the instance. +/// Note: This can be used in a headless engine after an ahead-of-time +/// compilation as all required state lives in the instance. /// /// # Panic /// -/// The instance Module must have been processed with the [`Metering`] middleware -/// at compile time, otherwise this will panic. +/// The given [`Instance`][wasmer::Instance] must have been processed +/// with the [`Metering`] middleware at compile time, otherwise this +/// will panic. +/// +/// # Example +/// +/// ```rust +/// use wasmer::Instance; +/// use wasmer_middlewares::metering::set_remaining_points; +/// +/// fn update_remaining_points(instance: &Instance) { +/// // The new limit. +/// let new_limit = 10; +/// +/// // Update the remaining points to the `new_limit`. +/// set_remaining_points(instance, new_limit); +/// } +/// ``` pub fn set_remaining_points(instance: &Instance, points: u64) { instance .exports