From a1527ea363b55e3f6ab91361c0b71b987e991903 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 7 Jun 2021 14:57:29 +0200 Subject: [PATCH 1/3] doc(middlewares) Add more examples and more doctests. The idea of this patch is to improve the documentation of the `wasmer-middlewares` crate by doing the following: * Link to the fully detailed existing `metering` example, * Give an overview of how to push a middleware on a compiler, * Give one example per type and function: `Metering`, `MeteringPoints`, `get_remaining_points` and `set_remaining_points`. --- lib/middlewares/README.md | 4 ++ lib/middlewares/src/lib.rs | 5 +- lib/middlewares/src/metering.rs | 110 ++++++++++++++++++++++++++------ 3 files changed, 99 insertions(+), 20 deletions(-) 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 From 3b5f89ec192839686b09b406eb99013b8b1d588e Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 7 Jun 2021 15:09:29 +0200 Subject: [PATCH 2/3] test(middlewares) Enable more features on `wasmer` when testing. --- lib/middlewares/Cargo.toml | 3 +++ 1 file changed, 3 insertions(+) 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" } From 6fc39d3efc962af013fd3e9235482b388332538a Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 7 Jun 2021 15:15:32 +0200 Subject: [PATCH 3/3] doc(changelog) Add #2402. --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9120d182bce..b52741f8a4e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,9 @@ Looking for changes that affect our C API? See the [C API Changelog](lib/c-api/C ## 2.0.0-rc2 - 2020/06/03 +### Added +- [#2402](https://github.com/wasmerio/wasmer/pull/2402) Add more examples and more doctests for `wasmer-middlewares`. + ### Fixed - [#2383](https://github.com/wasmerio/wasmer/pull/2383) Fix bugs in the Wasmer CLI tool with the way `--version` and the name of the CLI tool itself were printed.