From 197d0f7a49796effe7811b90017ed4c783faa8c4 Mon Sep 17 00:00:00 2001 From: Nick Lewycky Date: Tue, 9 Feb 2021 01:20:34 -0800 Subject: [PATCH 01/34] Initial commit of C API for metering and middleware. --- Cargo.lock | 1 + Makefile | 26 +++++------ lib/c-api/Cargo.toml | 3 ++ lib/c-api/build.rs | 3 ++ lib/c-api/src/lib.rs | 2 + lib/c-api/src/metering.rs | 73 ++++++++++++++++++++++++++++++ lib/c-api/src/wasm_c_api/engine.rs | 38 +++++++++++++++- lib/c-api/wasmer.h | 14 ++++++ lib/c-api/wasmer.hh | 16 +++++++ lib/c-api/wasmer_wasm.h | 24 ++++++++-- 10 files changed, 183 insertions(+), 17 deletions(-) create mode 100644 lib/c-api/src/metering.rs diff --git a/Cargo.lock b/Cargo.lock index 2a33a74917f..9810c42fcab 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2340,6 +2340,7 @@ dependencies = [ "wasmer-engine-jit", "wasmer-engine-native", "wasmer-engine-object-file", + "wasmer-middlewares", "wasmer-types", "wasmer-wasi", ] diff --git a/Makefile b/Makefile index 07971764547..cc006065254 100644 --- a/Makefile +++ b/Makefile @@ -170,55 +170,55 @@ build-capi: build-capi-cranelift build-capi-singlepass: cargo build --manifest-path lib/c-api/Cargo.toml --release \ - --no-default-features --features deprecated,wat,jit,native,object-file,singlepass,wasi $(capi_default_features) + --no-default-features --features deprecated,wat,jit,native,object-file,singlepass,wasi,middlewares $(capi_default_features) build-capi-singlepass-jit: cargo build --manifest-path lib/c-api/Cargo.toml --release \ - --no-default-features --features deprecated,wat,jit,singlepass,wasi $(capi_default_features) + --no-default-features --features deprecated,wat,jit,singlepass,wasi,middlewares $(capi_default_features) build-capi-singlepass-native: cargo build --manifest-path lib/c-api/Cargo.toml --release \ - --no-default-features --features deprecated,wat,native,singlepass,wasi $(capi_default_features) + --no-default-features --features deprecated,wat,native,singlepass,wasi,middlewares $(capi_default_features) build-capi-singlepass-object-file: cargo build --manifest-path lib/c-api/Cargo.toml --release \ - --no-default-features --features deprecated,wat,object-file,singlepass,wasi $(capi_default_features) + --no-default-features --features deprecated,wat,object-file,singlepass,wasi,middlewares $(capi_default_features) build-capi-cranelift: cargo build --manifest-path lib/c-api/Cargo.toml --release \ - --no-default-features --features deprecated,wat,jit,native,object-file,cranelift,wasi $(capi_default_features) + --no-default-features --features deprecated,wat,jit,native,object-file,cranelift,wasi,middlewares $(capi_default_features) build-capi-cranelift-system-libffi: cargo build --manifest-path lib/c-api/Cargo.toml --release \ - --no-default-features --features deprecated,wat,jit,native,object-file,cranelift,wasi,system-libffi $(capi_default_features) + --no-default-features --features deprecated,wat,jit,native,object-file,cranelift,wasi,middlewares,system-libffi $(capi_default_features) build-capi-cranelift-jit: cargo build --manifest-path lib/c-api/Cargo.toml --release \ - --no-default-features --features deprecated,wat,jit,cranelift,wasi $(capi_default_features) + --no-default-features --features deprecated,wat,jit,cranelift,wasi,middlewares $(capi_default_features) build-capi-cranelift-native: cargo build --manifest-path lib/c-api/Cargo.toml --release \ - --no-default-features --features deprecated,wat,native,cranelift,wasi $(capi_default_features) + --no-default-features --features deprecated,wat,native,cranelift,wasi,middlewares $(capi_default_features) build-capi-cranelift-object-file: cargo build --manifest-path lib/c-api/Cargo.toml --release \ - --no-default-features --features deprecated,wat,native,object-file,cranelift,wasi $(capi_default_features) + --no-default-features --features deprecated,wat,native,object-file,cranelift,wasi,middlewares $(capi_default_features) build-capi-llvm: cargo build --manifest-path lib/c-api/Cargo.toml --release \ - --no-default-features --features deprecated,wat,jit,native,object-file,llvm,wasi $(capi_default_features) + --no-default-features --features deprecated,wat,jit,native,object-file,llvm,wasi,middlewares $(capi_default_features) build-capi-llvm-jit: cargo build --manifest-path lib/c-api/Cargo.toml --release \ - --no-default-features --features deprecated,wat,jit,llvm,wasi $(capi_default_features) + --no-default-features --features deprecated,wat,jit,llvm,wasi,middlewares $(capi_default_features) build-capi-llvm-native: cargo build --manifest-path lib/c-api/Cargo.toml --release \ - --no-default-features --features deprecated,wat,native,llvm,wasi $(capi_default_features) + --no-default-features --features deprecated,wat,native,llvm,wasi,middlewares $(capi_default_features) build-capi-llvm-object-file: cargo build --manifest-path lib/c-api/Cargo.toml --release \ - --no-default-features --features deprecated,wat,object-file,llvm,wasi $(capi_default_features) + --no-default-features --features deprecated,wat,object-file,llvm,wasi,middlewares $(capi_default_features) # Headless (we include the minimal to be able to run) diff --git a/lib/c-api/Cargo.toml b/lib/c-api/Cargo.toml index 000744350a2..db974040cb7 100644 --- a/lib/c-api/Cargo.toml +++ b/lib/c-api/Cargo.toml @@ -25,6 +25,7 @@ wasmer-engine = { version = "1.0.2", path = "../engine" } wasmer-engine-jit = { version = "1.0.2", path = "../engine-jit", optional = true } wasmer-engine-native = { version = "1.0.2", path = "../engine-native", optional = true } wasmer-engine-object-file = { version = "1.0.2", path = "../engine-object-file", optional = true } +wasmer-middlewares = { version = "1.0.2", path = "../middlewares", optional = true } wasmer-wasi = { version = "1.0.2", path = "../wasi", optional = true } wasmer-types = { version = "1.0.2", path = "../wasmer-types" } enumset = "1.0" @@ -50,10 +51,12 @@ default = [ "cranelift", "jit", "wasi", + "middlewares", ] wat = ["wasmer/wat"] wasi = ["wasmer-wasi", "typetag", "serde"] engine = [] +middlewares = ["wasmer-middlewares"] deprecated = ["libffi"] jit = [ "wasmer-engine-jit", diff --git a/lib/c-api/build.rs b/lib/c-api/build.rs index ab0683f5841..8a9c05e16a8 100644 --- a/lib/c-api/build.rs +++ b/lib/c-api/build.rs @@ -470,6 +470,7 @@ fn exclude_items_from_wasm_c_api(builder: Builder) -> Builder { .exclude_item("wasm_config_set_compiler") .exclude_item("wasm_config_set_engine") .exclude_item("wasm_config_set_target") + .exclude_item("wasm_config_push_middleware") .exclude_item("wasm_cpu_features_add") .exclude_item("wasm_cpu_features_delete") .exclude_item("wasm_cpu_features_new") @@ -494,6 +495,8 @@ fn exclude_items_from_wasm_c_api(builder: Builder) -> Builder { .exclude_item("wasm_triple_t") .exclude_item("wasmer_compiler_t") .exclude_item("wasmer_engine_t") + .exclude_item("wasmer_metering_get_remaining_points") + .exclude_item("wasmer_metering_set_remaining_points") .exclude_item("wat2wasm") } diff --git a/lib/c-api/src/lib.rs b/lib/c-api/src/lib.rs index 11432f3a24b..731cdeb9c32 100644 --- a/lib/c-api/src/lib.rs +++ b/lib/c-api/src/lib.rs @@ -41,5 +41,7 @@ #[cfg(feature = "deprecated")] pub mod deprecated; pub mod error; +#[cfg(feature = "middlewares")] +pub mod metering; mod ordered_resolver; pub mod wasm_c_api; diff --git a/lib/c-api/src/metering.rs b/lib/c-api/src/metering.rs new file mode 100644 index 00000000000..f54dd972cc2 --- /dev/null +++ b/lib/c-api/src/metering.rs @@ -0,0 +1,73 @@ +// C API for metering. + +use super::wasm_c_api::instance::wasm_instance_t; +use std::sync::Arc; +use wasmer::wasmparser::Operator; +use wasmer_middlewares::{ + metering::{get_remaining_points, set_remaining_points, MeteringPoints}, + Metering, +}; + +/// Opaque type representing a MeteringPoints. +#[allow(non_camel_case_types)] +pub struct wasmer_metering_points_t { + pub(crate) inner: MeteringPoints, +} + +#[no_mangle] +pub unsafe extern "C" fn wasmer_metering_points_value( + metering_points: &Box, + exhausted: u64, +) -> u64 { + match metering_points.inner { + MeteringPoints::Remaining(value) => value, + MeteringPoints::Exhausted => exhausted, + } +} + +#[no_mangle] +pub unsafe extern "C" fn wasmer_metering_points_is_exhausted( + metering_points: &Box, +) -> bool { + matches!(metering_points.inner, MeteringPoints::Exhausted) +} + +/// Opaque type representing a MeteringPoints. +#[allow(non_camel_case_types)] +pub struct wasmer_metering_t { + #[allow(dead_code)] + pub(crate) inner: Arc u64>>, +} + +#[no_mangle] +pub unsafe extern "C" fn wasmer_metering_new(initial_limit: u64) -> Box { + let cost_function = |operator: &Operator| -> u64 { + match operator { + Operator::I32Const { .. } + | Operator::I64Const { .. } + | Operator::F32Const { .. } + | Operator::F64Const { .. } => 0, + _ => 1, + } + }; + Box::new(wasmer_metering_t { + inner: Arc::new(Metering::new(initial_limit, cost_function)), + }) +} + +#[no_mangle] +pub unsafe extern "C" fn wasmer_metering_get_remaining_points( + instance: &wasm_instance_t, +) -> Box { + Box::new(wasmer_metering_points_t { + inner: get_remaining_points(&instance.inner), + }) +} + +#[no_mangle] +pub unsafe extern "C" fn wasmer_metering_set_remaining_points( + instance: &wasm_instance_t, + new_limit: u64, +) { + set_remaining_points(&instance.inner, new_limit); +} diff --git a/lib/c-api/src/wasm_c_api/engine.rs b/lib/c-api/src/wasm_c_api/engine.rs index bfc3e4f09d7..55c43273fb9 100644 --- a/lib/c-api/src/wasm_c_api/engine.rs +++ b/lib/c-api/src/wasm_c_api/engine.rs @@ -4,6 +4,8 @@ use crate::error::{update_last_error, CApiError}; use cfg_if::cfg_if; use std::sync::Arc; use wasmer::Engine; +#[cfg(feature = "middlewares")] +use wasmer_compiler::ModuleMiddleware; #[cfg(feature = "jit")] use wasmer_engine_jit::JIT; #[cfg(feature = "native")] @@ -11,6 +13,10 @@ use wasmer_engine_native::Native; #[cfg(feature = "object-file")] use wasmer_engine_object_file::ObjectFile; +#[cfg(feature = "middlewares")] +#[cfg(not(feature = "compiler"))] +compile_error!("middlewares features requires compilers feature"); + /// Kind of compilers that can be used by the engines. /// /// This is a Wasmer-specific type with Wasmer-specific functions for @@ -86,6 +92,16 @@ impl Default for wasmer_engine_t { } } +/// Opaque representing a middleware. +/// +#[cfg(feature = "middlewares")] +#[derive(Debug)] +#[repr(C)] +#[allow(non_camel_case_types)] +pub struct wasmer_module_middleware_t { + pub(super) inner: Arc, +} + /// A configuration holds the compiler and the engine used by the store. /// /// cbindgen:ignore @@ -96,6 +112,8 @@ pub struct wasm_config_t { #[cfg(feature = "compiler")] compiler: wasmer_compiler_t, pub(super) target: Option>, + #[cfg(feature = "middlewares")] + pub(super) middlewares: Vec, } /// Create a new default Wasmer configuration. @@ -246,6 +264,16 @@ pub extern "C" fn wasm_config_set_engine(config: &mut wasm_config_t, engine: was config.engine = engine; } +// TODO: documentation +#[cfg(feature = "middlewares")] +#[no_mangle] +pub extern "C" fn wasm_config_push_middleware( + config: &mut wasm_config_t, + middleware: Box, +) { + config.middlewares.push(*middleware); +} + /// An engine is used by the store to drive the compilation and the /// execution of a WebAssembly module. /// @@ -311,7 +339,7 @@ cfg_if! { /// cbindgen:ignore #[no_mangle] pub extern "C" fn wasm_engine_new() -> Box { - let mut compiler_config: Box = get_default_compiler_config(); + let compiler_config: Box = get_default_compiler_config(); let engine: Arc = Arc::new(Native::new(compiler_config).engine()); Box::new(wasm_engine_t { inner: engine }) } @@ -448,6 +476,14 @@ pub extern "C" fn wasm_engine_new_with_config( }, }; + cfg_if! { + if #[cfg(feature = "middlewares")] { + for middleware in config.middlewares { + compiler_config.push_middleware(middleware.inner); + } + } + } + let inner: Arc = match config.engine { wasmer_engine_t::JIT => { cfg_if! { diff --git a/lib/c-api/wasmer.h b/lib/c-api/wasmer.h index 79e3eb7e9ef..c43c9ec539d 100644 --- a/lib/c-api/wasmer.h +++ b/lib/c-api/wasmer.h @@ -166,6 +166,13 @@ enum wasmer_value_tag typedef uint32_t wasmer_value_tag; #endif // __cplusplus +typedef struct Box_wasmer_metering_points_t Box_wasmer_metering_points_t; + +/** + * Opaque type representing a MeteringPoints. + */ +typedef struct wasmer_metering_t wasmer_metering_t; + typedef struct { } wasmer_module_t; @@ -1296,6 +1303,13 @@ uint32_t wasmer_memory_length(const wasmer_memory_t *memory); */ wasmer_result_t wasmer_memory_new(wasmer_memory_t **memory, wasmer_limits_t limits); +wasmer_metering_t *wasmer_metering_new(uint64_t initial_limit); + +bool wasmer_metering_points_is_exhausted(const Box_wasmer_metering_points_t *metering_points); + +uint64_t wasmer_metering_points_value(const Box_wasmer_metering_points_t *metering_points, + uint64_t exhausted); + /** * Deserialize the given serialized module. * diff --git a/lib/c-api/wasmer.hh b/lib/c-api/wasmer.hh index 51e90260fd2..c1ad52ffbb2 100644 --- a/lib/c-api/wasmer.hh +++ b/lib/c-api/wasmer.hh @@ -112,6 +112,15 @@ enum class wasmer_value_tag : uint32_t { WASM_F64, }; +template +struct Box; + +/// Opaque type representing a MeteringPoints. +struct wasmer_metering_points_t; + +/// Opaque type representing a MeteringPoints. +struct wasmer_metering_t; + struct wasmer_module_t { }; @@ -1060,6 +1069,13 @@ uint32_t wasmer_memory_length(const wasmer_memory_t *memory); /// ``` wasmer_result_t wasmer_memory_new(wasmer_memory_t **memory, wasmer_limits_t limits); +Box wasmer_metering_new(uint64_t initial_limit); + +bool wasmer_metering_points_is_exhausted(const Box *metering_points); + +uint64_t wasmer_metering_points_value(const Box *metering_points, + uint64_t exhausted); + /// Deserialize the given serialized module. /// /// Returns `wasmer_result_t::WASMER_OK` upon success. diff --git a/lib/c-api/wasmer_wasm.h b/lib/c-api/wasmer_wasm.h index f13aab20953..1822d705495 100644 --- a/lib/c-api/wasmer_wasm.h +++ b/lib/c-api/wasmer_wasm.h @@ -62,9 +62,6 @@ # define DEPRECATED(message) __declspec(deprecated(message)) #endif -// The `jit` feature has been enabled for this build. -#define WASMER_JIT_ENABLED - // The `compiler` feature has been enabled for this build. #define WASMER_COMPILER_ENABLED @@ -126,6 +123,8 @@ typedef enum { OBJECT_FILE = 2, } wasmer_engine_t; +typedef struct Box_wasmer_metering_points_t Box_wasmer_metering_points_t; + #if defined(WASMER_WASI_ENABLED) typedef struct wasi_config_t wasi_config_t; #endif @@ -144,6 +143,12 @@ typedef struct wasm_target_t wasm_target_t; typedef struct wasm_triple_t wasm_triple_t; +typedef struct wasmer_metering_points_t wasmer_metering_points_t; + +typedef struct wasmer_metering_t wasmer_metering_t; + +typedef struct wasmer_module_middleware_t wasmer_module_middleware_t; + #if defined(WASMER_WASI_ENABLED) typedef struct { uintptr_t size; @@ -245,6 +250,8 @@ bool wasi_get_unordered_imports(const wasm_store_t *store, wasi_version_t wasi_get_wasi_version(const wasm_module_t *module); #endif +void wasm_config_push_middleware(wasm_config_t *config, wasmer_module_middleware_t *middleware); + #if defined(WASMER_COMPILER_ENABLED) void wasm_config_set_compiler(wasm_config_t *config, wasmer_compiler_t compiler); #endif @@ -312,6 +319,17 @@ int wasmer_last_error_length(void); int wasmer_last_error_message(char *buffer, int length); +wasmer_metering_points_t *wasmer_metering_get_remaining_points(const wasm_instance_t *instance); + +wasmer_metering_t *wasmer_metering_new(uint64_t initial_limit); + +bool wasmer_metering_points_is_exhausted(const Box_wasmer_metering_points_t *metering_points); + +uint64_t wasmer_metering_points_value(const Box_wasmer_metering_points_t *metering_points, + uint64_t exhausted); + +void wasmer_metering_set_remaining_points(const wasm_instance_t *instance, uint64_t new_limit); + const char *wasmer_version(void); uint8_t wasmer_version_major(void); From d660943b459e5cc3b56326a433a409cd283a26b8 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 1 Mar 2021 15:13:40 +0100 Subject: [PATCH 02/34] feat(c-api) Simplify `&Box` to `&T`. --- lib/c-api/src/metering.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/c-api/src/metering.rs b/lib/c-api/src/metering.rs index f54dd972cc2..2b3cf9d0409 100644 --- a/lib/c-api/src/metering.rs +++ b/lib/c-api/src/metering.rs @@ -16,7 +16,7 @@ pub struct wasmer_metering_points_t { #[no_mangle] pub unsafe extern "C" fn wasmer_metering_points_value( - metering_points: &Box, + metering_points: &wasmer_metering_points_t, exhausted: u64, ) -> u64 { match metering_points.inner { @@ -27,7 +27,7 @@ pub unsafe extern "C" fn wasmer_metering_points_value( #[no_mangle] pub unsafe extern "C" fn wasmer_metering_points_is_exhausted( - metering_points: &Box, + metering_points: &wasmer_metering_points_t, ) -> bool { matches!(metering_points.inner, MeteringPoints::Exhausted) } From 2bc502bd47f0ffcf5590a35c89a160ed3e859dab Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 1 Mar 2021 15:27:56 +0100 Subject: [PATCH 03/34] fix(c-api) Move the middleware API into the `unstable` module. --- lib/c-api/src/lib.rs | 2 -- lib/c-api/src/{ => wasm_c_api/unstable/middlewares}/metering.rs | 2 +- lib/c-api/src/wasm_c_api/unstable/middlewares/mod.rs | 1 + lib/c-api/src/wasm_c_api/unstable/mod.rs | 2 ++ 4 files changed, 4 insertions(+), 3 deletions(-) rename lib/c-api/src/{ => wasm_c_api/unstable/middlewares}/metering.rs (97%) create mode 100644 lib/c-api/src/wasm_c_api/unstable/middlewares/mod.rs diff --git a/lib/c-api/src/lib.rs b/lib/c-api/src/lib.rs index 731cdeb9c32..11432f3a24b 100644 --- a/lib/c-api/src/lib.rs +++ b/lib/c-api/src/lib.rs @@ -41,7 +41,5 @@ #[cfg(feature = "deprecated")] pub mod deprecated; pub mod error; -#[cfg(feature = "middlewares")] -pub mod metering; mod ordered_resolver; pub mod wasm_c_api; diff --git a/lib/c-api/src/metering.rs b/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs similarity index 97% rename from lib/c-api/src/metering.rs rename to lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs index 2b3cf9d0409..56d6ac608cf 100644 --- a/lib/c-api/src/metering.rs +++ b/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs @@ -1,6 +1,6 @@ // C API for metering. -use super::wasm_c_api::instance::wasm_instance_t; +use super::super::super::instance::wasm_instance_t; use std::sync::Arc; use wasmer::wasmparser::Operator; use wasmer_middlewares::{ diff --git a/lib/c-api/src/wasm_c_api/unstable/middlewares/mod.rs b/lib/c-api/src/wasm_c_api/unstable/middlewares/mod.rs new file mode 100644 index 00000000000..32e0ce27a59 --- /dev/null +++ b/lib/c-api/src/wasm_c_api/unstable/middlewares/mod.rs @@ -0,0 +1 @@ +pub mod metering; diff --git a/lib/c-api/src/wasm_c_api/unstable/mod.rs b/lib/c-api/src/wasm_c_api/unstable/mod.rs index 5b673aec6ec..41b795eda3c 100644 --- a/lib/c-api/src/wasm_c_api/unstable/mod.rs +++ b/lib/c-api/src/wasm_c_api/unstable/mod.rs @@ -1,3 +1,5 @@ pub mod engine; +#[cfg(feature = "middlewares")] +pub mod middlewares; pub mod module; pub mod target_lexicon; From fd5a9b50d6cfa95f447ba8d777dbc5f1a02a3076 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 1 Mar 2021 15:28:37 +0100 Subject: [PATCH 04/34] chore(c-api) Update headers. --- lib/c-api/wasmer.h | 9 ++++++--- lib/c-api/wasmer.hh | 4 ++-- lib/c-api/wasmer_wasm.h | 9 +++++---- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/lib/c-api/wasmer.h b/lib/c-api/wasmer.h index c43c9ec539d..2ce2aa87885 100644 --- a/lib/c-api/wasmer.h +++ b/lib/c-api/wasmer.h @@ -166,7 +166,10 @@ enum wasmer_value_tag typedef uint32_t wasmer_value_tag; #endif // __cplusplus -typedef struct Box_wasmer_metering_points_t Box_wasmer_metering_points_t; +/** + * Opaque type representing a MeteringPoints. + */ +typedef struct wasmer_metering_points_t wasmer_metering_points_t; /** * Opaque type representing a MeteringPoints. @@ -1305,9 +1308,9 @@ wasmer_result_t wasmer_memory_new(wasmer_memory_t **memory, wasmer_limits_t limi wasmer_metering_t *wasmer_metering_new(uint64_t initial_limit); -bool wasmer_metering_points_is_exhausted(const Box_wasmer_metering_points_t *metering_points); +bool wasmer_metering_points_is_exhausted(const wasmer_metering_points_t *metering_points); -uint64_t wasmer_metering_points_value(const Box_wasmer_metering_points_t *metering_points, +uint64_t wasmer_metering_points_value(const wasmer_metering_points_t *metering_points, uint64_t exhausted); /** diff --git a/lib/c-api/wasmer.hh b/lib/c-api/wasmer.hh index c1ad52ffbb2..b775e2bf8a2 100644 --- a/lib/c-api/wasmer.hh +++ b/lib/c-api/wasmer.hh @@ -1071,9 +1071,9 @@ wasmer_result_t wasmer_memory_new(wasmer_memory_t **memory, wasmer_limits_t limi Box wasmer_metering_new(uint64_t initial_limit); -bool wasmer_metering_points_is_exhausted(const Box *metering_points); +bool wasmer_metering_points_is_exhausted(const wasmer_metering_points_t *metering_points); -uint64_t wasmer_metering_points_value(const Box *metering_points, +uint64_t wasmer_metering_points_value(const wasmer_metering_points_t *metering_points, uint64_t exhausted); /// Deserialize the given serialized module. diff --git a/lib/c-api/wasmer_wasm.h b/lib/c-api/wasmer_wasm.h index 1822d705495..691297ca241 100644 --- a/lib/c-api/wasmer_wasm.h +++ b/lib/c-api/wasmer_wasm.h @@ -62,6 +62,9 @@ # define DEPRECATED(message) __declspec(deprecated(message)) #endif +// The `jit` feature has been enabled for this build. +#define WASMER_JIT_ENABLED + // The `compiler` feature has been enabled for this build. #define WASMER_COMPILER_ENABLED @@ -123,8 +126,6 @@ typedef enum { OBJECT_FILE = 2, } wasmer_engine_t; -typedef struct Box_wasmer_metering_points_t Box_wasmer_metering_points_t; - #if defined(WASMER_WASI_ENABLED) typedef struct wasi_config_t wasi_config_t; #endif @@ -323,9 +324,9 @@ wasmer_metering_points_t *wasmer_metering_get_remaining_points(const wasm_instan wasmer_metering_t *wasmer_metering_new(uint64_t initial_limit); -bool wasmer_metering_points_is_exhausted(const Box_wasmer_metering_points_t *metering_points); +bool wasmer_metering_points_is_exhausted(const wasmer_metering_points_t *metering_points); -uint64_t wasmer_metering_points_value(const Box_wasmer_metering_points_t *metering_points, +uint64_t wasmer_metering_points_value(const wasmer_metering_points_t *metering_points, uint64_t exhausted); void wasmer_metering_set_remaining_points(const wasm_instance_t *instance, uint64_t new_limit); From cbbdfdaefa781848fa08f2c497a93cb3ab7d597b Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 1 Mar 2021 16:41:44 +0100 Subject: [PATCH 05/34] temp --- .../unstable/middlewares/metering.rs | 71 ++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs b/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs index 56d6ac608cf..1944f85cd85 100644 --- a/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs +++ b/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs @@ -1,5 +1,63 @@ -// C API for metering. +//! Unstable non-standard Wasmer-specific API that contains everything +//! to create a the middleware metering API. +//! +//! # Example +//! +//! ```rust +//! # use inline_c::assert_c; +//! # fn main() { +//! # (assert_c! { +//! # #include "tests/wasmer_wasm.h" +//! # +//! int main() {//!//! +//! wasmer_metering_t* metering = wasmer_metering_new(10); +//! wasmer_module_middleware_t* middleware = wasmer_metering_as_middleware(metering); +//! +//! wasm_config_t* config = wasm_config_new(); +//! wasm_config_push_middleware(config, middleware); +//! +//! wasm_engine_t* engine = wasm_engin_new_with_config(config); +//! +//! wasm_store_t* store = wasm_store_new(engine); +//! +//! wasm_byte_vec_t wat; +//! wasmer_byte_vec_new_from_string( +//! &wat, +//! "(module\n" +//! " (type $add_t (func (param i32) (result i32)))\n" +//! " (func $add_one_f (type $add_t) (param $value i32) (result i32)\n" +//! " local.get $value\n" +//! " i32.const 1\n" +//! " i32.add)\n" +//! " (export "add_one" (func $add_one_f)))" +//! ); +//! wasm_byte_vec_t wasm; +//! wat2wasm(&wat, &wasm); +//! +//! wasm_module_t* module = wasm_module_new(store, &wasm); +//! assert(module); +//! +//! wasm_extern_vec_t imports = WASM_EMPTY_VEC; +//! wasm_trap_t* traps = NULL; +//! wasm_instance_t* instance = wasm_instance_new(store, module, &imports, &traps); +//! assert(instance); +//! +//! +//! +//! +//! wasm_instance_delete(instance); +//! wasm_module_delete(module); +//! wasm_store_delete(store); +//! wasm_engine_delete(engine); +//! +//! return 0; +//! } +//! # }) +//! # .success(); +//! # } +//! ``` +use super::super::super::engine::wasmer_module_middleware_t; use super::super::super::instance::wasm_instance_t; use std::sync::Arc; use wasmer::wasmparser::Operator; @@ -71,3 +129,14 @@ pub unsafe extern "C" fn wasmer_metering_set_remaining_points( ) { set_remaining_points(&instance.inner, new_limit); } + +#[no_mangle] +pub unsafe extern "C" fn wasmer_metering_as_middleware( + metering: Option>, +) -> Option> { + let metering = metering?; + + Some(Box::new(wasmer_module_middleware_t { + inner: metering.inner, + })) +} From db4286d57616bfb4c8a67011a904bc9e9c50b534 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 1 Mar 2021 16:44:04 +0100 Subject: [PATCH 06/34] fix(c-api) Fix merge conflict. --- lib/c-api/src/wasm_c_api/engine.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/c-api/src/wasm_c_api/engine.rs b/lib/c-api/src/wasm_c_api/engine.rs index ff959d8202f..887eeb27e68 100644 --- a/lib/c-api/src/wasm_c_api/engine.rs +++ b/lib/c-api/src/wasm_c_api/engine.rs @@ -113,7 +113,6 @@ pub struct wasm_config_t { engine: wasmer_engine_t, #[cfg(feature = "compiler")] compiler: wasmer_compiler_t, - pub(super) target: Option>, #[cfg(feature = "middlewares")] pub(super) middlewares: Vec, pub(super) target: Option>, From 8b30ae9d4114f7a4d2d85c76684d0089775302d3 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 1 Mar 2021 17:10:27 +0100 Subject: [PATCH 07/34] feat(c-api) Add `_delete` and rename `_value` to `wasmer_metering_points_unwrap_or`. --- lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs b/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs index 1944f85cd85..28acb0de7cc 100644 --- a/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs +++ b/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs @@ -73,7 +73,13 @@ pub struct wasmer_metering_points_t { } #[no_mangle] -pub unsafe extern "C" fn wasmer_metering_points_value( +pub unsafe extern "C" fn wasmer_metering_points_delete( + _metering_points: Option>, +) { +} + +#[no_mangle] +pub unsafe extern "C" fn wasmer_metering_points_unwrap_or( metering_points: &wasmer_metering_points_t, exhausted: u64, ) -> u64 { From cb02694abc2bed85d7868ded0efff6c28163f7b7 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 1 Mar 2021 17:11:09 +0100 Subject: [PATCH 08/34] test(c-api) Add tests for the `wasmer_metering_*` API. --- .../unstable/middlewares/metering.rs | 59 +++++++++++++++++-- 1 file changed, 53 insertions(+), 6 deletions(-) diff --git a/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs b/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs index 28acb0de7cc..0dfbc066713 100644 --- a/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs +++ b/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs @@ -9,14 +9,14 @@ //! # (assert_c! { //! # #include "tests/wasmer_wasm.h" //! # -//! int main() {//!//! +//! int main() { //! wasmer_metering_t* metering = wasmer_metering_new(10); //! wasmer_module_middleware_t* middleware = wasmer_metering_as_middleware(metering); //! //! wasm_config_t* config = wasm_config_new(); //! wasm_config_push_middleware(config, middleware); //! -//! wasm_engine_t* engine = wasm_engin_new_with_config(config); +//! wasm_engine_t* engine = wasm_engine_new_with_config(config); //! //! wasm_store_t* store = wasm_store_new(engine); //! @@ -25,11 +25,13 @@ //! &wat, //! "(module\n" //! " (type $add_t (func (param i32) (result i32)))\n" -//! " (func $add_one_f (type $add_t) (param $value i32) (result i32)\n" +//! " (func $add_two_f (type $add_t) (param $value i32) (result i32)\n" //! " local.get $value\n" //! " i32.const 1\n" +//! " i32.add\n" +//! " i32.const 1\n" //! " i32.add)\n" -//! " (export "add_one" (func $add_one_f)))" +//! " (export \"add_two\" (func $add_two_f)))" //! ); //! wasm_byte_vec_t wasm; //! wat2wasm(&wat, &wasm); @@ -42,8 +44,53 @@ //! wasm_instance_t* instance = wasm_instance_new(store, module, &imports, &traps); //! assert(instance); //! -//! -//! +//! wasm_extern_vec_t exports; +//! wasm_instance_exports(instance, &exports); +//! assert(exports.size >= 1); +//! assert(wasm_extern_kind(exports.data[0]) == WASM_EXTERN_FUNC); +//! +//! const wasm_func_t* add_two = wasm_extern_as_func(exports.data[0]); +//! assert(add_two); +//! +//! wasm_val_t arguments[1] = { WASM_I32_VAL(40) }; +//! wasm_val_t results[1] = { WASM_INIT_VAL }; +//! +//! wasm_val_vec_t arguments_as_array = WASM_ARRAY_VEC(arguments); +//! wasm_val_vec_t results_as_array = WASM_ARRAY_VEC(results); +//! +//! uint64_t exhausted_value = -1; +//! +//! { +//! wasm_trap_t* trap = wasm_func_call(add_two, &arguments_as_array, &results_as_array); +//! assert(trap == NULL); +//! assert(results[0].of.i32 == 42); +//! +//! wasmer_metering_points_t* metering_points = wasmer_metering_get_remaining_points(instance); +//! assert(wasmer_metering_points_unwrap_or(metering_points, exhausted_value) == 6); +//! assert(wasmer_metering_points_is_exhausted(metering_points) == false); +//! wasmer_metering_points_delete(metering_points); +//! } +//! +//! { +//! wasm_trap_t* trap = wasm_func_call(add_two, &arguments_as_array, &results_as_array); +//! assert(trap == NULL); +//! assert(results[0].of.i32 == 42); +//! +//! wasmer_metering_points_t* metering_points = wasmer_metering_get_remaining_points(instance); +//! assert(wasmer_metering_points_unwrap_or(metering_points, exhausted_value) == 2); +//! assert(wasmer_metering_points_is_exhausted(metering_points) == false); +//! wasmer_metering_points_delete(metering_points); +//! } +//! +//! { +//! wasm_trap_t* trap = wasm_func_call(add_two, &arguments_as_array, &results_as_array); +//! assert(trap != NULL); +//! +//! wasmer_metering_points_t* metering_points = wasmer_metering_get_remaining_points(instance); +//! assert(wasmer_metering_points_unwrap_or(metering_points, exhausted_value) == exhausted_value); +//! assert(wasmer_metering_points_is_exhausted(metering_points) == true); +//! wasmer_metering_points_delete(metering_points); +//! } //! //! wasm_instance_delete(instance); //! wasm_module_delete(module); From 3b0572fafeed1a9353c8be7bab90018c9038b652 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 1 Mar 2021 17:11:33 +0100 Subject: [PATCH 09/34] feat(makefile) Test the C API with the `middlewares` feature. --- Makefile | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 540c2e45aa8..6f0bf814cf6 100644 --- a/Makefile +++ b/Makefile @@ -526,27 +526,27 @@ test-capi: $(foreach compiler_engine,$(compilers_engines),test-capi-$(compiler_e test-capi-all: build-capi cargo test --manifest-path lib/c-api/Cargo.toml --release \ - --no-default-features --features deprecated,wat,jit,native,object-file,wasi $(capi_default_features) $(capi_compiler_features) -- --nocapture + --no-default-features --features deprecated,wat,jit,native,object-file,wasi,middlewares $(capi_default_features) $(capi_compiler_features) -- --nocapture test-capi-singlepass-jit: build-capi-singlepass-jit test-capi-tests cargo test --manifest-path lib/c-api/Cargo.toml --release \ - --no-default-features --features deprecated,wat,jit,singlepass,wasi $(capi_default_features) -- --nocapture + --no-default-features --features deprecated,wat,jit,singlepass,wasi,middlewares $(capi_default_features) -- --nocapture test-capi-cranelift-jit: build-capi-cranelift-jit test-capi-tests cargo test --manifest-path lib/c-api/Cargo.toml --release \ - --no-default-features --features deprecated,wat,jit,cranelift,wasi $(capi_default_features) -- --nocapture + --no-default-features --features deprecated,wat,jit,cranelift,wasi,middlewares $(capi_default_features) -- --nocapture test-capi-cranelift-native: build-capi-cranelift-native test-capi-tests cargo test --manifest-path lib/c-api/Cargo.toml --release \ - --no-default-features --features deprecated,wat,native,cranelift,wasi $(capi_default_features) -- --nocapture + --no-default-features --features deprecated,wat,native,cranelift,wasi,middlewares $(capi_default_features) -- --nocapture test-capi-llvm-jit: build-capi-llvm-jit test-capi-tests cargo test --manifest-path lib/c-api/Cargo.toml --release \ - --no-default-features --features deprecated,wat,jit,llvm,wasi $(capi_default_features) -- --nocapture + --no-default-features --features deprecated,wat,jit,llvm,wasi,middlewares $(capi_default_features) -- --nocapture test-capi-llvm-native: build-capi-llvm-native test-capi-tests cargo test --manifest-path lib/c-api/Cargo.toml --release \ - --no-default-features --features deprecated,wat,native,llvm,wasi $(capi_default_features) -- --nocapture + --no-default-features --features deprecated,wat,native,llvm,wasi,middlewares $(capi_default_features) -- --nocapture test-capi-tests: package-capi # Test the Wasmer C API tests for C From e67fd6acf6773d93592e24ed935271523cea8661 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 1 Mar 2021 17:21:43 +0100 Subject: [PATCH 10/34] feat(c-api) Update headers + add the `MIDDLEWARES_FEATURE_AS_C_DEFINE` constant. --- lib/c-api/build.rs | 19 +++++++++++++++--- lib/c-api/wasmer.h | 17 ---------------- lib/c-api/wasmer.hh | 16 --------------- lib/c-api/wasmer_wasm.h | 43 +++++++++++++++++++++++++---------------- 4 files changed, 42 insertions(+), 53 deletions(-) diff --git a/lib/c-api/build.rs b/lib/c-api/build.rs index 77a5c38bfc5..587c4026ab9 100644 --- a/lib/c-api/build.rs +++ b/lib/c-api/build.rs @@ -41,6 +41,9 @@ const COMPILER_FEATURE_AS_C_DEFINE: &'static str = "WASMER_COMPILER_ENABLED"; #[allow(unused)] const WASI_FEATURE_AS_C_DEFINE: &'static str = "WASMER_WASI_ENABLED"; +#[allow(unused)] +const MIDDLEWARES_FEATURE_AS_C_DEFINE: &'static str = "WASMER_MIDDLEWARES_ENABLED"; + #[allow(unused)] const EMSCRIPTEN_FEATURE_AS_C_DEFINE: &'static str = "WASMER_EMSCRIPTEN_ENABLED"; @@ -135,6 +138,7 @@ fn build_wasm_c_api_headers(crate_dir: &str, out_dir: &str) { map_feature_as_c_define!("jit", JIT_FEATURE_AS_C_DEFINE, pre_header); map_feature_as_c_define!("compiler", COMPILER_FEATURE_AS_C_DEFINE, pre_header); map_feature_as_c_define!("wasi", WASI_FEATURE_AS_C_DEFINE, pre_header); + map_feature_as_c_define!("middlewares", MIDDLEWARES_FEATURE_AS_C_DEFINE, pre_header); map_feature_as_c_define!("emscripten", EMSCRIPTEN_FEATURE_AS_C_DEFINE, pre_header); add_wasmer_version(&mut pre_header); @@ -467,10 +471,10 @@ fn exclude_items_from_wasm_c_api(builder: Builder) -> Builder { .exclude_item("wasi_get_unordered_imports") .exclude_item("wasi_get_wasi_version") .exclude_item("wasi_version_t") + .exclude_item("wasm_config_push_middleware") .exclude_item("wasm_config_set_compiler") .exclude_item("wasm_config_set_engine") .exclude_item("wasm_config_set_target") - .exclude_item("wasm_config_push_middleware") .exclude_item("wasm_cpu_features_add") .exclude_item("wasm_cpu_features_delete") .exclude_item("wasm_cpu_features_new") @@ -499,11 +503,20 @@ fn exclude_items_from_wasm_c_api(builder: Builder) -> Builder { .exclude_item("wasmer_cpu_features_new") .exclude_item("wasmer_cpu_features_t") .exclude_item("wasmer_engine_t") - .exclude_item("wasmer_metering_get_remaining_points") - .exclude_item("wasmer_metering_set_remaining_points") .exclude_item("wasmer_is_compiler_available") .exclude_item("wasmer_is_engine_available") .exclude_item("wasmer_is_headless") + .exclude_item("wasmer_metering_as_middleware") + .exclude_item("wasmer_metering_delete") + .exclude_item("wasmer_metering_get_remaining_points") + .exclude_item("wasmer_metering_new") + .exclude_item("wasmer_metering_points_delete") + .exclude_item("wasmer_metering_points_is_exhausted") + .exclude_item("wasmer_metering_points_t") + .exclude_item("wasmer_metering_points_unwrap_or") + .exclude_item("wasmer_metering_set_remaining_points") + .exclude_item("wasmer_metering_t") + .exclude_item("wasmer_module_middleware_t") .exclude_item("wasmer_module_name") .exclude_item("wasmer_module_set_name") .exclude_item("wasmer_named_extern_module") diff --git a/lib/c-api/wasmer.h b/lib/c-api/wasmer.h index 2ce2aa87885..79e3eb7e9ef 100644 --- a/lib/c-api/wasmer.h +++ b/lib/c-api/wasmer.h @@ -166,16 +166,6 @@ enum wasmer_value_tag typedef uint32_t wasmer_value_tag; #endif // __cplusplus -/** - * Opaque type representing a MeteringPoints. - */ -typedef struct wasmer_metering_points_t wasmer_metering_points_t; - -/** - * Opaque type representing a MeteringPoints. - */ -typedef struct wasmer_metering_t wasmer_metering_t; - typedef struct { } wasmer_module_t; @@ -1306,13 +1296,6 @@ uint32_t wasmer_memory_length(const wasmer_memory_t *memory); */ wasmer_result_t wasmer_memory_new(wasmer_memory_t **memory, wasmer_limits_t limits); -wasmer_metering_t *wasmer_metering_new(uint64_t initial_limit); - -bool wasmer_metering_points_is_exhausted(const wasmer_metering_points_t *metering_points); - -uint64_t wasmer_metering_points_value(const wasmer_metering_points_t *metering_points, - uint64_t exhausted); - /** * Deserialize the given serialized module. * diff --git a/lib/c-api/wasmer.hh b/lib/c-api/wasmer.hh index b775e2bf8a2..51e90260fd2 100644 --- a/lib/c-api/wasmer.hh +++ b/lib/c-api/wasmer.hh @@ -112,15 +112,6 @@ enum class wasmer_value_tag : uint32_t { WASM_F64, }; -template -struct Box; - -/// Opaque type representing a MeteringPoints. -struct wasmer_metering_points_t; - -/// Opaque type representing a MeteringPoints. -struct wasmer_metering_t; - struct wasmer_module_t { }; @@ -1069,13 +1060,6 @@ uint32_t wasmer_memory_length(const wasmer_memory_t *memory); /// ``` wasmer_result_t wasmer_memory_new(wasmer_memory_t **memory, wasmer_limits_t limits); -Box wasmer_metering_new(uint64_t initial_limit); - -bool wasmer_metering_points_is_exhausted(const wasmer_metering_points_t *metering_points); - -uint64_t wasmer_metering_points_value(const wasmer_metering_points_t *metering_points, - uint64_t exhausted); - /// Deserialize the given serialized module. /// /// Returns `wasmer_result_t::WASMER_OK` upon success. diff --git a/lib/c-api/wasmer_wasm.h b/lib/c-api/wasmer_wasm.h index e83e87ad825..4920e39c238 100644 --- a/lib/c-api/wasmer_wasm.h +++ b/lib/c-api/wasmer_wasm.h @@ -71,6 +71,9 @@ // The `wasi` feature has been enabled for this build. #define WASMER_WASI_ENABLED +// The `middlewares` feature has been enabled for this build. +#define WASMER_MIDDLEWARES_ENABLED + // This file corresponds to the following Wasmer version. #define WASMER_VERSION "1.0.2" #define WASMER_VERSION_MAJOR 1 @@ -136,6 +139,12 @@ typedef struct wasi_env_t wasi_env_t; typedef struct wasmer_cpu_features_t wasmer_cpu_features_t; +typedef struct wasmer_metering_points_t wasmer_metering_points_t; + +typedef struct wasmer_metering_t wasmer_metering_t; + +typedef struct wasmer_module_middleware_t wasmer_module_middleware_t; + #if defined(WASMER_WASI_ENABLED) typedef struct wasmer_named_extern_t wasmer_named_extern_t; #endif @@ -144,12 +153,6 @@ typedef struct wasmer_target_t wasmer_target_t; typedef struct wasmer_triple_t wasmer_triple_t; -typedef struct wasmer_metering_points_t wasmer_metering_points_t; - -typedef struct wasmer_metering_t wasmer_metering_t; - -typedef struct wasmer_module_middleware_t wasmer_module_middleware_t; - #if defined(WASMER_WASI_ENABLED) typedef struct { uintptr_t size; @@ -277,6 +280,23 @@ int wasmer_last_error_length(void); int wasmer_last_error_message(char *buffer, int length); +wasmer_module_middleware_t *wasmer_metering_as_middleware(wasmer_metering_t *metering); + +void wasmer_metering_delete(wasmer_metering_t *_metering); + +wasmer_metering_points_t *wasmer_metering_get_remaining_points(const wasm_instance_t *instance); + +wasmer_metering_t *wasmer_metering_new(uint64_t initial_limit); + +void wasmer_metering_points_delete(wasmer_metering_points_t *_metering_points); + +bool wasmer_metering_points_is_exhausted(const wasmer_metering_points_t *metering_points); + +uint64_t wasmer_metering_points_unwrap_or(const wasmer_metering_points_t *metering_points, + uint64_t exhausted); + +void wasmer_metering_set_remaining_points(const wasm_instance_t *instance, uint64_t new_limit); + void wasmer_module_name(const wasm_module_t *module, wasm_name_t *out); bool wasmer_module_set_name(wasm_module_t *module, const wasm_name_t *name); @@ -326,17 +346,6 @@ wasmer_triple_t *wasmer_triple_new(const wasm_name_t *triple); wasmer_triple_t *wasmer_triple_new_from_host(void); -wasmer_metering_points_t *wasmer_metering_get_remaining_points(const wasm_instance_t *instance); - -wasmer_metering_t *wasmer_metering_new(uint64_t initial_limit); - -bool wasmer_metering_points_is_exhausted(const wasmer_metering_points_t *metering_points); - -uint64_t wasmer_metering_points_value(const wasmer_metering_points_t *metering_points, - uint64_t exhausted); - -void wasmer_metering_set_remaining_points(const wasm_instance_t *instance, uint64_t new_limit); - const char *wasmer_version(void); uint8_t wasmer_version_major(void); From 8f1a4f3406da38fc4037e7804083e09d8ff24440 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 1 Mar 2021 17:31:04 +0100 Subject: [PATCH 11/34] feat(c-api) Add `wasmer_metering_delete`. --- lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs b/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs index 0dfbc066713..71dc2d84d5f 100644 --- a/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs +++ b/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs @@ -166,6 +166,9 @@ pub unsafe extern "C" fn wasmer_metering_new(initial_limit: u64) -> Box>) {} + #[no_mangle] pub unsafe extern "C" fn wasmer_metering_get_remaining_points( instance: &wasm_instance_t, From fb973b2af1dca1c227b9d3ad7c4bbc36354a65c3 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Tue, 2 Mar 2021 14:58:18 +0100 Subject: [PATCH 12/34] fix(c-api) `wasmer_module_middleware_t` is an opaque type. --- lib/c-api/src/wasm_c_api/engine.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/c-api/src/wasm_c_api/engine.rs b/lib/c-api/src/wasm_c_api/engine.rs index 887eeb27e68..d3e82136239 100644 --- a/lib/c-api/src/wasm_c_api/engine.rs +++ b/lib/c-api/src/wasm_c_api/engine.rs @@ -98,7 +98,6 @@ impl Default for wasmer_engine_t { /// #[cfg(feature = "middlewares")] #[derive(Debug)] -#[repr(C)] #[allow(non_camel_case_types)] pub struct wasmer_module_middleware_t { pub(super) inner: Arc, From 31669b8cdc12f9fa860cf890a6d193bf89a148f7 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Tue, 2 Mar 2021 15:20:23 +0100 Subject: [PATCH 13/34] feat(c-api) Rename `wasmer_module_middleware_t` to `wasmer_middleware_t`. Also, move it into the `unstable::middleware` module. --- lib/c-api/src/wasm_c_api/engine.rs | 31 +++---------------- .../unstable/middlewares/metering.rs | 6 ++-- .../wasm_c_api/unstable/middlewares/mod.rs | 22 +++++++++++++ 3 files changed, 30 insertions(+), 29 deletions(-) diff --git a/lib/c-api/src/wasm_c_api/engine.rs b/lib/c-api/src/wasm_c_api/engine.rs index d3e82136239..ca69590bf78 100644 --- a/lib/c-api/src/wasm_c_api/engine.rs +++ b/lib/c-api/src/wasm_c_api/engine.rs @@ -1,13 +1,15 @@ pub use super::unstable::engine::{ wasm_config_set_target, wasmer_is_compiler_available, wasmer_is_engine_available, }; +#[cfg(feature = "middlewares")] +pub use super::unstable::middlewares::wasm_config_push_middleware; +#[cfg(feature = "middlewares")] +use super::unstable::middlewares::wasmer_middleware_t; use super::unstable::target_lexicon::wasmer_target_t; use crate::error::{update_last_error, CApiError}; use cfg_if::cfg_if; use std::sync::Arc; use wasmer::Engine; -#[cfg(feature = "middlewares")] -use wasmer_compiler::ModuleMiddleware; #[cfg(feature = "jit")] use wasmer_engine_jit::JIT; #[cfg(feature = "native")] @@ -15,10 +17,6 @@ use wasmer_engine_native::Native; #[cfg(feature = "object-file")] use wasmer_engine_object_file::ObjectFile; -#[cfg(feature = "middlewares")] -#[cfg(not(feature = "compiler"))] -compile_error!("middlewares features requires compilers feature"); - /// Kind of compilers that can be used by the engines. /// /// This is a Wasmer-specific type with Wasmer-specific functions for @@ -94,15 +92,6 @@ impl Default for wasmer_engine_t { } } -/// Opaque representing a middleware. -/// -#[cfg(feature = "middlewares")] -#[derive(Debug)] -#[allow(non_camel_case_types)] -pub struct wasmer_module_middleware_t { - pub(super) inner: Arc, -} - /// A configuration holds the compiler and the engine used by the store. /// /// cbindgen:ignore @@ -113,7 +102,7 @@ pub struct wasm_config_t { #[cfg(feature = "compiler")] compiler: wasmer_compiler_t, #[cfg(feature = "middlewares")] - pub(super) middlewares: Vec, + pub(super) middlewares: Vec, pub(super) target: Option>, } @@ -283,16 +272,6 @@ pub extern "C" fn wasm_config_set_engine(config: &mut wasm_config_t, engine: was config.engine = engine; } -// TODO: documentation -#[cfg(feature = "middlewares")] -#[no_mangle] -pub extern "C" fn wasm_config_push_middleware( - config: &mut wasm_config_t, - middleware: Box, -) { - config.middlewares.push(*middleware); -} - /// An engine is used by the store to drive the compilation and the /// execution of a WebAssembly module. /// diff --git a/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs b/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs index 71dc2d84d5f..f434ad81654 100644 --- a/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs +++ b/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs @@ -104,8 +104,8 @@ //! # } //! ``` -use super::super::super::engine::wasmer_module_middleware_t; use super::super::super::instance::wasm_instance_t; +use super::wasmer_middleware_t; use std::sync::Arc; use wasmer::wasmparser::Operator; use wasmer_middlewares::{ @@ -189,10 +189,10 @@ pub unsafe extern "C" fn wasmer_metering_set_remaining_points( #[no_mangle] pub unsafe extern "C" fn wasmer_metering_as_middleware( metering: Option>, -) -> Option> { +) -> Option> { let metering = metering?; - Some(Box::new(wasmer_module_middleware_t { + Some(Box::new(wasmer_middleware_t { inner: metering.inner, })) } diff --git a/lib/c-api/src/wasm_c_api/unstable/middlewares/mod.rs b/lib/c-api/src/wasm_c_api/unstable/middlewares/mod.rs index 32e0ce27a59..930c8b69d04 100644 --- a/lib/c-api/src/wasm_c_api/unstable/middlewares/mod.rs +++ b/lib/c-api/src/wasm_c_api/unstable/middlewares/mod.rs @@ -1 +1,23 @@ pub mod metering; + +use super::super::engine::wasm_config_t; +use std::sync::Arc; +use wasmer_compiler::ModuleMiddleware; + +#[cfg(all(feature = "middlewares", not(feature = "compiler")))] +compile_error!("The `middlewares` feature requires the `compiler` feature to be turned on"); + +/// Opaque representing a middleware. +#[derive(Debug)] +#[allow(non_camel_case_types)] +pub struct wasmer_middleware_t { + pub(in crate::wasm_c_api) inner: Arc, +} + +#[no_mangle] +pub extern "C" fn wasm_config_push_middleware( + config: &mut wasm_config_t, + middleware: Box, +) { + config.middlewares.push(*middleware); +} From 798dd888c4439385586628fd9fa04cc68fdeaf1f Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Tue, 2 Mar 2021 15:24:48 +0100 Subject: [PATCH 14/34] feat(c-api) Simplify a compilation condition. --- lib/c-api/src/wasm_c_api/engine.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/lib/c-api/src/wasm_c_api/engine.rs b/lib/c-api/src/wasm_c_api/engine.rs index ca69590bf78..d83dfd28de8 100644 --- a/lib/c-api/src/wasm_c_api/engine.rs +++ b/lib/c-api/src/wasm_c_api/engine.rs @@ -474,12 +474,9 @@ pub extern "C" fn wasm_engine_new_with_config( }, }; - cfg_if! { - if #[cfg(feature = "middlewares")] { - for middleware in config.middlewares { - compiler_config.push_middleware(middleware.inner); - } - } + #[cfg(feature = "middlewares")] + for middleware in config.middlewares { + compiler_config.push_middleware(middleware.inner); } let inner: Arc = match config.engine { From e0148077f7de5dd0c33b2efb9ea352183128b39a Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Tue, 2 Mar 2021 16:11:23 +0100 Subject: [PATCH 15/34] doc(middlewares) Format. --- lib/middlewares/README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/middlewares/README.md b/lib/middlewares/README.md index 9f40322ea2a..766c4cc4bdb 100644 --- a/lib/middlewares/README.md +++ b/lib/middlewares/README.md @@ -1,5 +1,8 @@ # Wasmer Middlewares -The `wasmer-middlewares` crate is a collection of various useful middlewares: +The `wasmer-middlewares` crate is a collection of various useful +middlewares: -- `metering`: A middleware for tracking how many operators are executed in total and putting a limit on the total number of operators executed. +- `metering`: A middleware for tracking how many operators are + executed in total and putting a limit on the total number of + operators executed. From 19c04124b1bf3ccc2077caacb4b06b1fe8c62e12 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Tue, 2 Mar 2021 16:32:02 +0100 Subject: [PATCH 16/34] doc(c-api) Write more documentation and tests. --- .../unstable/middlewares/metering.rs | 169 +++++++++++++++++- .../wasm_c_api/unstable/middlewares/mod.rs | 19 +- 2 files changed, 179 insertions(+), 9 deletions(-) diff --git a/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs b/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs index f434ad81654..c258a39b167 100644 --- a/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs +++ b/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs @@ -1,6 +1,10 @@ //! Unstable non-standard Wasmer-specific API that contains everything //! to create a the middleware metering API. //! +//! The metering middleware is used for tracking how many operators +//! are executed in total and putting a limit on the total number of +//! operators executed. +//! //! # Example //! //! ```rust @@ -10,16 +14,21 @@ //! # #include "tests/wasmer_wasm.h" //! # //! int main() { +//! // Create a new metering middleware. //! wasmer_metering_t* metering = wasmer_metering_new(10); -//! wasmer_module_middleware_t* middleware = wasmer_metering_as_middleware(metering); +//! +//! // Consume `metering` to produce a generic `wasmer_middle_t` value. +//! wasmer_middleware_t* middleware = wasmer_metering_as_middleware(metering); //! +//! // Create a new configuration, and push the middleware in it. //! wasm_config_t* config = wasm_config_new(); //! wasm_config_push_middleware(config, middleware); //! +//! // Create the engine and the store based on the configuration. //! wasm_engine_t* engine = wasm_engine_new_with_config(config); -//! //! wasm_store_t* store = wasm_store_new(engine); //! +//! // Create the new WebAssembly module. //! wasm_byte_vec_t wat; //! wasmer_byte_vec_new_from_string( //! &wat, @@ -39,11 +48,14 @@ //! wasm_module_t* module = wasm_module_new(store, &wasm); //! assert(module); //! +//! // Instantiate the module. //! wasm_extern_vec_t imports = WASM_EMPTY_VEC; //! wasm_trap_t* traps = NULL; //! wasm_instance_t* instance = wasm_instance_new(store, module, &imports, &traps); //! assert(instance); //! +//! // Here we go. At this step, we will get the `add_two` exported function, and +//! // call it. //! wasm_extern_vec_t exports; //! wasm_instance_exports(instance, &exports); //! assert(exports.size >= 1); @@ -58,36 +70,44 @@ //! wasm_val_vec_t arguments_as_array = WASM_ARRAY_VEC(arguments); //! wasm_val_vec_t results_as_array = WASM_ARRAY_VEC(results); //! -//! uint64_t exhausted_value = -1; +//! // Let's define a value when points are exhausted. +//! uint64_t is_exhausted = -1; //! +//! // Let's call `add_two` for the first time! //! { //! wasm_trap_t* trap = wasm_func_call(add_two, &arguments_as_array, &results_as_array); //! assert(trap == NULL); //! assert(results[0].of.i32 == 42); //! +//! // There is 6 points left! //! wasmer_metering_points_t* metering_points = wasmer_metering_get_remaining_points(instance); -//! assert(wasmer_metering_points_unwrap_or(metering_points, exhausted_value) == 6); +//! assert(wasmer_metering_points_unwrap_or(metering_points, is_exhausted) == 6); //! assert(wasmer_metering_points_is_exhausted(metering_points) == false); //! wasmer_metering_points_delete(metering_points); //! } //! +//! // Let's call `add_two` for the second time! //! { //! wasm_trap_t* trap = wasm_func_call(add_two, &arguments_as_array, &results_as_array); //! assert(trap == NULL); //! assert(results[0].of.i32 == 42); //! +//! // There is 2 points left! //! wasmer_metering_points_t* metering_points = wasmer_metering_get_remaining_points(instance); -//! assert(wasmer_metering_points_unwrap_or(metering_points, exhausted_value) == 2); +//! assert(wasmer_metering_points_unwrap_or(metering_points, is_exhausted) == 2); //! assert(wasmer_metering_points_is_exhausted(metering_points) == false); //! wasmer_metering_points_delete(metering_points); //! } //! +//! // Let's call `add_two` for the third time! //! { //! wasm_trap_t* trap = wasm_func_call(add_two, &arguments_as_array, &results_as_array); +//! // Oh, it failed! //! assert(trap != NULL); //! +//! // There is 0 point left… they are exhausted. //! wasmer_metering_points_t* metering_points = wasmer_metering_get_remaining_points(instance); -//! assert(wasmer_metering_points_unwrap_or(metering_points, exhausted_value) == exhausted_value); +//! assert(wasmer_metering_points_unwrap_or(metering_points, is_exhausted) == is_exhausted); //! assert(wasmer_metering_points_is_exhausted(metering_points) == true); //! wasmer_metering_points_delete(metering_points); //! } @@ -113,18 +133,37 @@ use wasmer_middlewares::{ Metering, }; -/// Opaque type representing a MeteringPoints. +/// Opaque type representing metering points, i.e. the actual number +/// of remaining points for a given [`wasmer_metering_t`]. +/// +/// To get a value of that type, see the +/// [`wasmer_metering_get_remaining_points`]. +/// +/// # Example +/// +/// See module's documentation. #[allow(non_camel_case_types)] pub struct wasmer_metering_points_t { pub(crate) inner: MeteringPoints, } +/// Deletes a [`wasmer_metering_points_t`]. +/// +/// # Example +/// +/// See module's documentation. #[no_mangle] pub unsafe extern "C" fn wasmer_metering_points_delete( _metering_points: Option>, ) { } +/// Returns the number of remaining points if any, otherwise returned +/// the given `exhausted` value if points are exhausted. +/// +/// # Example +/// +/// See module's documentation. #[no_mangle] pub unsafe extern "C" fn wasmer_metering_points_unwrap_or( metering_points: &wasmer_metering_points_t, @@ -136,6 +175,11 @@ pub unsafe extern "C" fn wasmer_metering_points_unwrap_or( } } +/// Checks whether the number of metering points are exhausted. +/// +/// # Example +/// +/// See module's documentation. #[no_mangle] pub unsafe extern "C" fn wasmer_metering_points_is_exhausted( metering_points: &wasmer_metering_points_t, @@ -143,13 +187,27 @@ pub unsafe extern "C" fn wasmer_metering_points_is_exhausted( matches!(metering_points.inner, MeteringPoints::Exhausted) } -/// Opaque type representing a MeteringPoints. +/// Opaque type representing a metering middleware. +/// +/// To transform this specific middleware into a generic one, please +/// see [`wasmer_metering_as_middleware`]. +/// +/// # Example +/// +/// See module's documentation. #[allow(non_camel_case_types)] pub struct wasmer_metering_t { #[allow(dead_code)] pub(crate) inner: Arc u64>>, } +/// Creates a new metering middleware with an initial limit, i.e. a +/// total number of operators to execute (regarding their respective +/// cost). +/// +/// # Example +/// +/// See module's documentation. #[no_mangle] pub unsafe extern "C" fn wasmer_metering_new(initial_limit: u64) -> Box { let cost_function = |operator: &Operator| -> u64 { @@ -166,9 +224,21 @@ pub unsafe extern "C" fn wasmer_metering_new(initial_limit: u64) -> Box>) {} +/// Returns the remaining metering points, inside a +/// [`wasmer_metering_points_t`] value. The caller is responsible to +/// free this value by using [`wasmer_metering_points_delete`]. +/// +/// # Example +/// +/// See module's documentation. #[no_mangle] pub unsafe extern "C" fn wasmer_metering_get_remaining_points( instance: &wasm_instance_t, @@ -178,6 +248,80 @@ pub unsafe extern "C" fn wasmer_metering_get_remaining_points( }) } +/// Set a new amount of points for the given metering middleware. +/// +/// # Example +/// +/// This example is pointless as the number of points aren't updated +/// by the WebAssembly module execution, it only illustrates the +/// `wasmer_metering_set_remaining_points` function. +/// +/// ```rust +/// # use inline_c::assert_c; +/// # fn main() { +/// # (assert_c! { +/// # #include "tests/wasmer_wasm.h" +/// # +/// int main() { +/// // Set the initial amount of points to 10. +/// wasmer_metering_t* metering = wasmer_metering_new(7); +/// +/// // Consume `metering` to produce `middleware`. +/// wasmer_middleware_t* middleware = wasmer_metering_as_middleware(metering); +/// +/// // Create the configuration (which consumes `middleware`), +/// // the engine, and the store. +/// wasm_config_t* config = wasm_config_new(); +/// wasm_config_push_middleware(config, middleware); +/// +/// wasm_engine_t* engine = wasm_engine_new_with_config(config); +/// +/// wasm_store_t* store = wasm_store_new(engine); +/// +/// // Create the module and instantiate it. +/// wasm_byte_vec_t wat; +/// wasmer_byte_vec_new_from_string(&wat, "(module)"); +/// wasm_byte_vec_t wasm; +/// wat2wasm(&wat, &wasm); +/// +/// wasm_module_t* module = wasm_module_new(store, &wasm); +/// assert(module); +/// +/// wasm_extern_vec_t imports = WASM_EMPTY_VEC; +/// wasm_trap_t* traps = NULL; +/// wasm_instance_t* instance = wasm_instance_new(store, module, &imports, &traps); +/// assert(instance); +/// +/// // Read the number of points. +/// { +/// wasmer_metering_points_t* points = wasmer_metering_get_remaining_points(instance); +/// assert(wasmer_metering_points_unwrap_or(points, -1) == 7); +/// +/// wasmer_metering_points_delete(points); +/// } +/// +/// // Set a new number of points. +/// wasmer_metering_set_remaining_points(instance, 42); +/// +/// // Read the number of points. +/// { +/// wasmer_metering_points_t* points = wasmer_metering_get_remaining_points(instance); +/// assert(wasmer_metering_points_unwrap_or(points, -1) == 42); +/// +/// wasmer_metering_points_delete(points); +/// } +/// +/// wasm_instance_delete(instance); +/// wasm_module_delete(module); +/// wasm_store_delete(store); +/// wasm_engine_delete(engine); +/// +/// return 0; +/// } +/// # }) +/// # .success(); +/// # } +/// ``` #[no_mangle] pub unsafe extern "C" fn wasmer_metering_set_remaining_points( instance: &wasm_instance_t, @@ -186,6 +330,15 @@ pub unsafe extern "C" fn wasmer_metering_set_remaining_points( set_remaining_points(&instance.inner, new_limit); } +/// Transforms a [`wasmer_metering_t`] into a generic +/// [`wasmer_middleware_t`], to then be pushed in the configuration with +/// [`wasm_config_push_middleware`][super::wasm_config_push_middleware]. +/// +/// This function takes ownership of `metering`. +/// +/// # Example +/// +/// See module's documentation. #[no_mangle] pub unsafe extern "C" fn wasmer_metering_as_middleware( metering: Option>, diff --git a/lib/c-api/src/wasm_c_api/unstable/middlewares/mod.rs b/lib/c-api/src/wasm_c_api/unstable/middlewares/mod.rs index 930c8b69d04..1402ce74ead 100644 --- a/lib/c-api/src/wasm_c_api/unstable/middlewares/mod.rs +++ b/lib/c-api/src/wasm_c_api/unstable/middlewares/mod.rs @@ -1,3 +1,6 @@ +//! Unstable non-standard Wasmer-specific types to manipulate module +//! middlewares. + pub mod metering; use super::super::engine::wasm_config_t; @@ -7,13 +10,27 @@ use wasmer_compiler::ModuleMiddleware; #[cfg(all(feature = "middlewares", not(feature = "compiler")))] compile_error!("The `middlewares` feature requires the `compiler` feature to be turned on"); -/// Opaque representing a middleware. +/// Opaque representing any kind of middleware. +/// +/// It's used by `wasm_config_push_middleware`. A specific middleware +/// is transformed into this type to get a generic middleware. See for +/// example +/// [`wasmer_metering_as_middleware`][metering::wasmer_metering_as_middleware]. #[derive(Debug)] #[allow(non_camel_case_types)] pub struct wasmer_middleware_t { pub(in crate::wasm_c_api) inner: Arc, } +/// Updates the configuration to add a module middleware. +/// +/// This function takes ownership of `middleware`. +/// +/// This is a Wasmer-specific function. +/// +/// # Example +/// +/// See the documentation of the [`metering`] module. #[no_mangle] pub extern "C" fn wasm_config_push_middleware( config: &mut wasm_config_t, From 0c4e0633f48bb7fe56222c377a6fd22bc012cb46 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Tue, 2 Mar 2021 16:32:54 +0100 Subject: [PATCH 17/34] chore(c-api) Update headers. --- lib/c-api/build.rs | 2 +- lib/c-api/wasmer_wasm.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/c-api/build.rs b/lib/c-api/build.rs index 587c4026ab9..2df3d99c383 100644 --- a/lib/c-api/build.rs +++ b/lib/c-api/build.rs @@ -516,7 +516,7 @@ fn exclude_items_from_wasm_c_api(builder: Builder) -> Builder { .exclude_item("wasmer_metering_points_unwrap_or") .exclude_item("wasmer_metering_set_remaining_points") .exclude_item("wasmer_metering_t") - .exclude_item("wasmer_module_middleware_t") + .exclude_item("wasmer_middleware_t") .exclude_item("wasmer_module_name") .exclude_item("wasmer_module_set_name") .exclude_item("wasmer_named_extern_module") diff --git a/lib/c-api/wasmer_wasm.h b/lib/c-api/wasmer_wasm.h index 4920e39c238..5e351d91f5b 100644 --- a/lib/c-api/wasmer_wasm.h +++ b/lib/c-api/wasmer_wasm.h @@ -143,7 +143,7 @@ typedef struct wasmer_metering_points_t wasmer_metering_points_t; typedef struct wasmer_metering_t wasmer_metering_t; -typedef struct wasmer_module_middleware_t wasmer_module_middleware_t; +typedef struct wasmer_middleware_t wasmer_middleware_t; #if defined(WASMER_WASI_ENABLED) typedef struct wasmer_named_extern_t wasmer_named_extern_t; @@ -254,7 +254,7 @@ bool wasi_get_unordered_imports(const wasm_store_t *store, wasi_version_t wasi_get_wasi_version(const wasm_module_t *module); #endif -void wasm_config_push_middleware(wasm_config_t *config, wasmer_module_middleware_t *middleware); +void wasm_config_push_middleware(wasm_config_t *config, wasmer_middleware_t *middleware); #if defined(WASMER_COMPILER_ENABLED) void wasm_config_set_compiler(wasm_config_t *config, wasmer_compiler_t compiler); @@ -280,7 +280,7 @@ int wasmer_last_error_length(void); int wasmer_last_error_message(char *buffer, int length); -wasmer_module_middleware_t *wasmer_metering_as_middleware(wasmer_metering_t *metering); +wasmer_middleware_t *wasmer_metering_as_middleware(wasmer_metering_t *metering); void wasmer_metering_delete(wasmer_metering_t *_metering); From 902f58e32d7cdf15c4fbb603978cb564c4337323 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Tue, 2 Mar 2021 17:42:43 +0100 Subject: [PATCH 18/34] !tmp --- .../unstable/middlewares/metering.rs | 23 +- lib/c-api/src/wasm_c_api/unstable/mod.rs | 2 +- .../src/wasm_c_api/unstable/parser/mod.rs | 3 + .../wasm_c_api/unstable/parser/operator.rs | 1016 +++++++++++++++++ lib/c-api/wasmer_wasm.h | 5 +- 5 files changed, 1035 insertions(+), 14 deletions(-) create mode 100644 lib/c-api/src/wasm_c_api/unstable/parser/mod.rs create mode 100644 lib/c-api/src/wasm_c_api/unstable/parser/operator.rs diff --git a/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs b/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs index c258a39b167..a96b9b603a2 100644 --- a/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs +++ b/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs @@ -125,6 +125,7 @@ //! ``` use super::super::super::instance::wasm_instance_t; +use super::super::parser::operator::Operator as COperator; use super::wasmer_middleware_t; use std::sync::Arc; use wasmer::wasmparser::Operator; @@ -197,10 +198,12 @@ pub unsafe extern "C" fn wasmer_metering_points_is_exhausted( /// See module's documentation. #[allow(non_camel_case_types)] pub struct wasmer_metering_t { - #[allow(dead_code)] - pub(crate) inner: Arc u64>>, + pub(crate) inner: Arc u64>>, } +#[allow(non_camel_case_types)] +pub type wasmer_metering_cost_function_t = extern "C" fn(operator: COperator) -> u64; + /// Creates a new metering middleware with an initial limit, i.e. a /// total number of operators to execute (regarding their respective /// cost). @@ -209,16 +212,12 @@ pub struct wasmer_metering_t { /// /// See module's documentation. #[no_mangle] -pub unsafe extern "C" fn wasmer_metering_new(initial_limit: u64) -> Box { - let cost_function = |operator: &Operator| -> u64 { - match operator { - Operator::I32Const { .. } - | Operator::I64Const { .. } - | Operator::F32Const { .. } - | Operator::F64Const { .. } => 0, - _ => 1, - } - }; +pub extern "C" fn wasmer_metering_new( + initial_limit: u64, + cost_function: wasmer_metering_cost_function_t, +) -> Box { + let cost_function = |operator: &Operator| -> u64 { cost_function(operator.into()) }; + Box::new(wasmer_metering_t { inner: Arc::new(Metering::new(initial_limit, cost_function)), }) diff --git a/lib/c-api/src/wasm_c_api/unstable/mod.rs b/lib/c-api/src/wasm_c_api/unstable/mod.rs index 185b50a23b0..0526309db7a 100644 --- a/lib/c-api/src/wasm_c_api/unstable/mod.rs +++ b/lib/c-api/src/wasm_c_api/unstable/mod.rs @@ -2,7 +2,7 @@ pub mod engine; #[cfg(feature = "middlewares")] pub mod middlewares; pub mod module; +pub mod parser; pub mod target_lexicon; - #[cfg(feature = "wasi")] pub mod wasi; diff --git a/lib/c-api/src/wasm_c_api/unstable/parser/mod.rs b/lib/c-api/src/wasm_c_api/unstable/parser/mod.rs new file mode 100644 index 00000000000..f4086e59574 --- /dev/null +++ b/lib/c-api/src/wasm_c_api/unstable/parser/mod.rs @@ -0,0 +1,3 @@ +//! Unstable non-standard Wasmer-specific types about WebAssembly parser. + +pub mod operator; diff --git a/lib/c-api/src/wasm_c_api/unstable/parser/operator.rs b/lib/c-api/src/wasm_c_api/unstable/parser/operator.rs new file mode 100644 index 00000000000..85df6993966 --- /dev/null +++ b/lib/c-api/src/wasm_c_api/unstable/parser/operator.rs @@ -0,0 +1,1016 @@ +use wasmer::wasmparser::Operator as OriginalOperator; + +#[repr(C)] +pub enum Operator { + Unreachable, + Nop, + Block, + Loop, + If, + Else, + Try, + Catch, + Throw, + Rethrow, + Unwind, + End, + Br, + BrIf, + BrTable, + Return, + Call, + CallIndirect, + ReturnCall, + ReturnCallIndirect, + Drop, + Select, + TypedSelect, + LocalGet, + LocalSet, + LocalTee, + GlobalGet, + GlobalSet, + I32Load, + I64Load, + F32Load, + F64Load, + I32Load8S, + I32Load8U, + I32Load16S, + I32Load16U, + I64Load8S, + I64Load8U, + I64Load16S, + I64Load16U, + I64Load32S, + I64Load32U, + I32Store, + I64Store, + F32Store, + F64Store, + I32Store8, + I32Store16, + I64Store8, + I64Store16, + I64Store32, + MemorySize, + MemoryGrow, + I32Const, + I64Const, + F32Const, + F64Const, + RefNull, + RefIsNull, + RefFunc, + I32Eqz, + I32Eq, + I32Ne, + I32LtS, + I32LtU, + I32GtS, + I32GtU, + I32LeS, + I32LeU, + I32GeS, + I32GeU, + I64Eqz, + I64Eq, + I64Ne, + I64LtS, + I64LtU, + I64GtS, + I64GtU, + I64LeS, + I64LeU, + I64GeS, + I64GeU, + F32Eq, + F32Ne, + F32Lt, + F32Gt, + F32Le, + F32Ge, + F64Eq, + F64Ne, + F64Lt, + F64Gt, + F64Le, + F64Ge, + I32Clz, + I32Ctz, + I32Popcnt, + I32Add, + I32Sub, + I32Mul, + I32DivS, + I32DivU, + I32RemS, + I32RemU, + I32And, + I32Or, + I32Xor, + I32Shl, + I32ShrS, + I32ShrU, + I32Rotl, + I32Rotr, + I64Clz, + I64Ctz, + I64Popcnt, + I64Add, + I64Sub, + I64Mul, + I64DivS, + I64DivU, + I64RemS, + I64RemU, + I64And, + I64Or, + I64Xor, + I64Shl, + I64ShrS, + I64ShrU, + I64Rotl, + I64Rotr, + F32Abs, + F32Neg, + F32Ceil, + F32Floor, + F32Trunc, + F32Nearest, + F32Sqrt, + F32Add, + F32Sub, + F32Mul, + F32Div, + F32Min, + F32Max, + F32Copysign, + F64Abs, + F64Neg, + F64Ceil, + F64Floor, + F64Trunc, + F64Nearest, + F64Sqrt, + F64Add, + F64Sub, + F64Mul, + F64Div, + F64Min, + F64Max, + F64Copysign, + I32WrapI64, + I32TruncF32S, + I32TruncF32U, + I32TruncF64S, + I32TruncF64U, + I64ExtendI32S, + I64ExtendI32U, + I64TruncF32S, + I64TruncF32U, + I64TruncF64S, + I64TruncF64U, + F32ConvertI32S, + F32ConvertI32U, + F32ConvertI64S, + F32ConvertI64U, + F32DemoteF64, + F64ConvertI32S, + F64ConvertI32U, + F64ConvertI64S, + F64ConvertI64U, + F64PromoteF32, + I32ReinterpretF32, + I64ReinterpretF64, + F32ReinterpretI32, + F64ReinterpretI64, + I32Extend8S, + I32Extend16S, + I64Extend8S, + I64Extend16S, + I64Extend32S, + I32TruncSatF32S, + I32TruncSatF32U, + I32TruncSatF64S, + I32TruncSatF64U, + I64TruncSatF32S, + I64TruncSatF32U, + I64TruncSatF64S, + I64TruncSatF64U, + MemoryInit, + DataDrop, + MemoryCopy, + MemoryFill, + TableInit, + ElemDrop, + TableCopy, + TableFill, + TableGet, + TableSet, + TableGrow, + TableSize, + MemoryAtomicNotify, + MemoryAtomicWait32, + MemoryAtomicWait64, + AtomicFence, + I32AtomicLoad, + I64AtomicLoad, + I32AtomicLoad8U, + I32AtomicLoad16U, + I64AtomicLoad8U, + I64AtomicLoad16U, + I64AtomicLoad32U, + I32AtomicStore, + I64AtomicStore, + I32AtomicStore8, + I32AtomicStore16, + I64AtomicStore8, + I64AtomicStore16, + I64AtomicStore32, + I32AtomicRmwAdd, + I64AtomicRmwAdd, + I32AtomicRmw8AddU, + I32AtomicRmw16AddU, + I64AtomicRmw8AddU, + I64AtomicRmw16AddU, + I64AtomicRmw32AddU, + I32AtomicRmwSub, + I64AtomicRmwSub, + I32AtomicRmw8SubU, + I32AtomicRmw16SubU, + I64AtomicRmw8SubU, + I64AtomicRmw16SubU, + I64AtomicRmw32SubU, + I32AtomicRmwAnd, + I64AtomicRmwAnd, + I32AtomicRmw8AndU, + I32AtomicRmw16AndU, + I64AtomicRmw8AndU, + I64AtomicRmw16AndU, + I64AtomicRmw32AndU, + I32AtomicRmwOr, + I64AtomicRmwOr, + I32AtomicRmw8OrU, + I32AtomicRmw16OrU, + I64AtomicRmw8OrU, + I64AtomicRmw16OrU, + I64AtomicRmw32OrU, + I32AtomicRmwXor, + I64AtomicRmwXor, + I32AtomicRmw8XorU, + I32AtomicRmw16XorU, + I64AtomicRmw8XorU, + I64AtomicRmw16XorU, + I64AtomicRmw32XorU, + I32AtomicRmwXchg, + I64AtomicRmwXchg, + I32AtomicRmw8XchgU, + I32AtomicRmw16XchgU, + I64AtomicRmw8XchgU, + I64AtomicRmw16XchgU, + I64AtomicRmw32XchgU, + I32AtomicRmwCmpxchg, + I64AtomicRmwCmpxchg, + I32AtomicRmw8CmpxchgU, + I32AtomicRmw16CmpxchgU, + I64AtomicRmw8CmpxchgU, + I64AtomicRmw16CmpxchgU, + I64AtomicRmw32CmpxchgU, + V128Load, + V128Store, + V128Const, + I8x16Splat, + I8x16ExtractLaneS, + I8x16ExtractLaneU, + I8x16ReplaceLane, + I16x8Splat, + I16x8ExtractLaneS, + I16x8ExtractLaneU, + I16x8ReplaceLane, + I32x4Splat, + I32x4ExtractLane, + I32x4ReplaceLane, + I64x2Splat, + I64x2ExtractLane, + I64x2ReplaceLane, + F32x4Splat, + F32x4ExtractLane, + F32x4ReplaceLane, + F64x2Splat, + F64x2ExtractLane, + F64x2ReplaceLane, + I8x16Eq, + I8x16Ne, + I8x16LtS, + I8x16LtU, + I8x16GtS, + I8x16GtU, + I8x16LeS, + I8x16LeU, + I8x16GeS, + I8x16GeU, + I16x8Eq, + I16x8Ne, + I16x8LtS, + I16x8LtU, + I16x8GtS, + I16x8GtU, + I16x8LeS, + I16x8LeU, + I16x8GeS, + I16x8GeU, + I32x4Eq, + I32x4Ne, + I32x4LtS, + I32x4LtU, + I32x4GtS, + I32x4GtU, + I32x4LeS, + I32x4LeU, + I32x4GeS, + I32x4GeU, + I64x2Eq, + I64x2Ne, + F32x4Eq, + F32x4Ne, + F32x4Lt, + F32x4Gt, + F32x4Le, + F32x4Ge, + F64x2Eq, + F64x2Ne, + F64x2Lt, + F64x2Gt, + F64x2Le, + F64x2Ge, + V128Not, + V128And, + V128AndNot, + V128Or, + V128Xor, + V128Bitselect, + V128AnyTrue, + I8x16Abs, + I8x16Neg, + I8x16AllTrue, + I8x16Bitmask, + I8x16Shl, + I8x16ShrS, + I8x16ShrU, + I8x16Add, + I8x16AddSatS, + I8x16AddSatU, + I8x16Sub, + I8x16SubSatS, + I8x16SubSatU, + I8x16MinS, + I8x16MinU, + I8x16MaxS, + I8x16MaxU, + I16x8Abs, + I16x8Neg, + I16x8AllTrue, + I16x8Bitmask, + I16x8Shl, + I16x8ShrS, + I16x8ShrU, + I16x8Add, + I16x8AddSatS, + I16x8AddSatU, + I16x8Sub, + I16x8SubSatS, + I16x8SubSatU, + I16x8Mul, + I16x8MinS, + I16x8MinU, + I16x8MaxS, + I16x8MaxU, + I32x4Abs, + I32x4Neg, + I32x4AllTrue, + I32x4Bitmask, + I32x4Shl, + I32x4ShrS, + I32x4ShrU, + I32x4Add, + I32x4Sub, + I32x4Mul, + I32x4MinS, + I32x4MinU, + I32x4MaxS, + I32x4MaxU, + I32x4DotI16x8S, + I64x2Neg, + I64x2AllTrue, + I64x2Bitmask, + I64x2Shl, + I64x2ShrS, + I64x2ShrU, + I64x2Add, + I64x2Sub, + I64x2Mul, + F32x4Ceil, + F32x4Floor, + F32x4Trunc, + F32x4Nearest, + F64x2Ceil, + F64x2Floor, + F64x2Trunc, + F64x2Nearest, + F32x4Abs, + F32x4Neg, + F32x4Sqrt, + F32x4Add, + F32x4Sub, + F32x4Mul, + F32x4Div, + F32x4Min, + F32x4Max, + F32x4PMin, + F32x4PMax, + F64x2Abs, + F64x2Neg, + F64x2Sqrt, + F64x2Add, + F64x2Sub, + F64x2Mul, + F64x2Div, + F64x2Min, + F64x2Max, + F64x2PMin, + F64x2PMax, + I32x4TruncSatF32x4S, + I32x4TruncSatF32x4U, + F32x4ConvertI32x4S, + F32x4ConvertI32x4U, + I8x16Swizzle, + I8x16Shuffle, + V128Load8Splat, + V128Load16Splat, + V128Load32Splat, + V128Load32Zero, + V128Load64Splat, + V128Load64Zero, + I8x16NarrowI16x8S, + I8x16NarrowI16x8U, + I16x8NarrowI32x4S, + I16x8NarrowI32x4U, + I16x8WidenLowI8x16S, + I16x8WidenHighI8x16S, + I16x8WidenLowI8x16U, + I16x8WidenHighI8x16U, + I32x4WidenLowI16x8S, + I32x4WidenHighI16x8S, + I32x4WidenLowI16x8U, + I32x4WidenHighI16x8U, + I64x2WidenLowI32x4S, + I64x2WidenHighI32x4S, + I64x2WidenLowI32x4U, + I64x2WidenHighI32x4U, + I16x8ExtMulLowI8x16S, + I16x8ExtMulHighI8x16S, + I16x8ExtMulLowI8x16U, + I16x8ExtMulHighI8x16U, + I32x4ExtMulLowI16x8S, + I32x4ExtMulHighI16x8S, + I32x4ExtMulLowI16x8U, + I32x4ExtMulHighI16x8U, + I64x2ExtMulLowI32x4S, + I64x2ExtMulHighI32x4S, + I64x2ExtMulLowI32x4U, + I64x2ExtMulHighI32x4U, + V128Load8x8S, + V128Load8x8U, + V128Load16x4S, + V128Load16x4U, + V128Load32x2S, + V128Load32x2U, + V128Load8Lane, + V128Load16Lane, + V128Load32Lane, + V128Load64Lane, + V128Store8Lane, + V128Store16Lane, + V128Store32Lane, + V128Store64Lane, + I8x16RoundingAverageU, + I16x8RoundingAverageU, + I16x8Q15MulrSatS, + F32x4DemoteF64x2Zero, + F64x2PromoteLowF32x4, + F64x2ConvertLowI32x4S, + F64x2ConvertLowI32x4U, + I32x4TruncSatF64x2SZero, + I32x4TruncSatF64x2UZero, +} + +impl<'a> From<&OriginalOperator<'a>> for Operator { + fn from(operator: &OriginalOperator<'a>) -> Self { + use OriginalOperator::*; + + match operator { + Unreachable => Self::Unreachable, + Nop => Self::Nop, + Block { .. } => Self::Block, + Loop { .. } => Self::Loop, + If { .. } => Self::If, + Else => Self::Else, + Try { .. } => Self::Try, + Catch { .. } => Self::Catch, + Throw { .. } => Self::Throw, + Rethrow { .. } => Self::Rethrow, + Unwind => Self::Unwind, + End => Self::End, + Br { .. } => Self::Br, + BrIf { .. } => Self::BrIf, + BrTable { .. } => Self::BrTable, + Return => Self::Return, + Call { .. } => Self::Call, + CallIndirect { .. } => Self::CallIndirect, + ReturnCall { .. } => Self::ReturnCall, + ReturnCallIndirect { .. } => Self::ReturnCallIndirect, + Drop => Self::Drop, + Select => Self::Select, + TypedSelect { .. } => Self::TypedSelect, + LocalGet { .. } => Self::LocalGet, + LocalSet { .. } => Self::LocalSet, + LocalTee { .. } => Self::LocalTee, + GlobalGet { .. } => Self::GlobalGet, + GlobalSet { .. } => Self::GlobalSet, + I32Load { .. } => Self::I32Load, + I64Load { .. } => Self::I64Load, + F32Load { .. } => Self::F32Load, + F64Load { .. } => Self::F64Load, + I32Load8S { .. } => Self::I32Load8S, + I32Load8U { .. } => Self::I32Load8U, + I32Load16S { .. } => Self::I32Load16S, + I32Load16U { .. } => Self::I32Load16U, + I64Load8S { .. } => Self::I64Load8S, + I64Load8U { .. } => Self::I64Load8U, + I64Load16S { .. } => Self::I64Load16S, + I64Load16U { .. } => Self::I64Load16U, + I64Load32S { .. } => Self::I64Load32S, + I64Load32U { .. } => Self::I64Load32U, + I32Store { .. } => Self::I32Store, + I64Store { .. } => Self::I64Store, + F32Store { .. } => Self::F32Store, + F64Store { .. } => Self::F64Store, + I32Store8 { .. } => Self::I32Store8, + I32Store16 { .. } => Self::I32Store16, + I64Store8 { .. } => Self::I64Store8, + I64Store16 { .. } => Self::I64Store16, + I64Store32 { .. } => Self::I64Store32, + MemorySize { .. } => Self::MemorySize, + MemoryGrow { .. } => Self::MemoryGrow, + I32Const { .. } => Self::I32Const, + I64Const { .. } => Self::I64Const, + F32Const { .. } => Self::F32Const, + F64Const { .. } => Self::F64Const, + RefNull { .. } => Self::RefNull, + RefIsNull => Self::RefIsNull, + RefFunc { .. } => Self::RefFunc, + I32Eqz => Self::I32Eqz, + I32Eq => Self::I32Eq, + I32Ne => Self::I32Ne, + I32LtS => Self::I32LtS, + I32LtU => Self::I32LtU, + I32GtS => Self::I32GtS, + I32GtU => Self::I32GtU, + I32LeS => Self::I32LeS, + I32LeU => Self::I32LeU, + I32GeS => Self::I32GeS, + I32GeU => Self::I32GeU, + I64Eqz => Self::I64Eqz, + I64Eq => Self::I64Eq, + I64Ne => Self::I64Ne, + I64LtS => Self::I64LtS, + I64LtU => Self::I64LtU, + I64GtS => Self::I64GtS, + I64GtU => Self::I64GtU, + I64LeS => Self::I64LeS, + I64LeU => Self::I64LeU, + I64GeS => Self::I64GeS, + I64GeU => Self::I64GeU, + F32Eq => Self::F32Eq, + F32Ne => Self::F32Ne, + F32Lt => Self::F32Lt, + F32Gt => Self::F32Gt, + F32Le => Self::F32Le, + F32Ge => Self::F32Ge, + F64Eq => Self::F64Eq, + F64Ne => Self::F64Ne, + F64Lt => Self::F64Lt, + F64Gt => Self::F64Gt, + F64Le => Self::F64Le, + F64Ge => Self::F64Ge, + I32Clz => Self::I32Clz, + I32Ctz => Self::I32Ctz, + I32Popcnt => Self::I32Popcnt, + I32Add => Self::I32Add, + I32Sub => Self::I32Sub, + I32Mul => Self::I32Mul, + I32DivS => Self::I32DivS, + I32DivU => Self::I32DivU, + I32RemS => Self::I32RemS, + I32RemU => Self::I32RemU, + I32And => Self::I32And, + I32Or => Self::I32Or, + I32Xor => Self::I32Xor, + I32Shl => Self::I32Shl, + I32ShrS => Self::I32ShrS, + I32ShrU => Self::I32ShrU, + I32Rotl => Self::I32Rotl, + I32Rotr => Self::I32Rotr, + I64Clz => Self::I64Clz, + I64Ctz => Self::I64Ctz, + I64Popcnt => Self::I64Popcnt, + I64Add => Self::I64Add, + I64Sub => Self::I64Sub, + I64Mul => Self::I64Mul, + I64DivS => Self::I64DivS, + I64DivU => Self::I64DivU, + I64RemS => Self::I64RemS, + I64RemU => Self::I64RemU, + I64And => Self::I64And, + I64Or => Self::I64Or, + I64Xor => Self::I64Xor, + I64Shl => Self::I64Shl, + I64ShrS => Self::I64ShrS, + I64ShrU => Self::I64ShrU, + I64Rotl => Self::I64Rotl, + I64Rotr => Self::I64Rotr, + F32Abs => Self::F32Abs, + F32Neg => Self::F32Neg, + F32Ceil => Self::F32Ceil, + F32Floor => Self::F32Floor, + F32Trunc => Self::F32Trunc, + F32Nearest => Self::F32Nearest, + F32Sqrt => Self::F32Sqrt, + F32Add => Self::F32Add, + F32Sub => Self::F32Sub, + F32Mul => Self::F32Mul, + F32Div => Self::F32Div, + F32Min => Self::F32Min, + F32Max => Self::F32Max, + F32Copysign => Self::F32Copysign, + F64Abs => Self::F64Abs, + F64Neg => Self::F64Neg, + F64Ceil => Self::F64Ceil, + F64Floor => Self::F64Floor, + F64Trunc => Self::F64Trunc, + F64Nearest => Self::F64Nearest, + F64Sqrt => Self::F64Sqrt, + F64Add => Self::F64Add, + F64Sub => Self::F64Sub, + F64Mul => Self::F64Mul, + F64Div => Self::F64Div, + F64Min => Self::F64Min, + F64Max => Self::F64Max, + F64Copysign => Self::F64Copysign, + I32WrapI64 => Self::I32WrapI64, + I32TruncF32S => Self::I32TruncF32S, + I32TruncF32U => Self::I32TruncF32U, + I32TruncF64S => Self::I32TruncF64S, + I32TruncF64U => Self::I32TruncF64U, + I64ExtendI32S => Self::I64ExtendI32S, + I64ExtendI32U => Self::I64ExtendI32U, + I64TruncF32S => Self::I64TruncF32S, + I64TruncF32U => Self::I64TruncF32U, + I64TruncF64S => Self::I64TruncF64S, + I64TruncF64U => Self::I64TruncF64U, + F32ConvertI32S => Self::F32ConvertI32S, + F32ConvertI32U => Self::F32ConvertI32U, + F32ConvertI64S => Self::F32ConvertI64S, + F32ConvertI64U => Self::F32ConvertI64U, + F32DemoteF64 => Self::F32DemoteF64, + F64ConvertI32S => Self::F64ConvertI32S, + F64ConvertI32U => Self::F64ConvertI32U, + F64ConvertI64S => Self::F64ConvertI64S, + F64ConvertI64U => Self::F64ConvertI64U, + F64PromoteF32 => Self::F64PromoteF32, + I32ReinterpretF32 => Self::I32ReinterpretF32, + I64ReinterpretF64 => Self::I64ReinterpretF64, + F32ReinterpretI32 => Self::F32ReinterpretI32, + F64ReinterpretI64 => Self::F64ReinterpretI64, + I32Extend8S => Self::I32Extend8S, + I32Extend16S => Self::I32Extend16S, + I64Extend8S => Self::I64Extend8S, + I64Extend16S => Self::I64Extend16S, + I64Extend32S => Self::I64Extend32S, + I32TruncSatF32S => Self::I32TruncSatF32S, + I32TruncSatF32U => Self::I32TruncSatF32U, + I32TruncSatF64S => Self::I32TruncSatF64S, + I32TruncSatF64U => Self::I32TruncSatF64U, + I64TruncSatF32S => Self::I64TruncSatF32S, + I64TruncSatF32U => Self::I64TruncSatF32U, + I64TruncSatF64S => Self::I64TruncSatF64S, + I64TruncSatF64U => Self::I64TruncSatF64U, + MemoryInit { .. } => Self::MemoryInit, + DataDrop { .. } => Self::DataDrop, + MemoryCopy { .. } => Self::MemoryCopy, + MemoryFill { .. } => Self::MemoryFill, + TableInit { .. } => Self::TableInit, + ElemDrop { .. } => Self::ElemDrop, + TableCopy { .. } => Self::TableCopy, + TableFill { .. } => Self::TableFill, + TableGet { .. } => Self::TableGet, + TableSet { .. } => Self::TableSet, + TableGrow { .. } => Self::TableGrow, + TableSize { .. } => Self::TableSize, + MemoryAtomicNotify { .. } => Self::MemoryAtomicNotify, + MemoryAtomicWait32 { .. } => Self::MemoryAtomicWait32, + MemoryAtomicWait64 { .. } => Self::MemoryAtomicWait64, + AtomicFence { .. } => Self::AtomicFence, + I32AtomicLoad { .. } => Self::I32AtomicLoad, + I64AtomicLoad { .. } => Self::I64AtomicLoad, + I32AtomicLoad8U { .. } => Self::I32AtomicLoad8U, + I32AtomicLoad16U { .. } => Self::I32AtomicLoad16U, + I64AtomicLoad8U { .. } => Self::I64AtomicLoad8U, + I64AtomicLoad16U { .. } => Self::I64AtomicLoad16U, + I64AtomicLoad32U { .. } => Self::I64AtomicLoad32U, + I32AtomicStore { .. } => Self::I32AtomicStore, + I64AtomicStore { .. } => Self::I64AtomicStore, + I32AtomicStore8 { .. } => Self::I32AtomicStore8, + I32AtomicStore16 { .. } => Self::I32AtomicStore16, + I64AtomicStore8 { .. } => Self::I64AtomicStore8, + I64AtomicStore16 { .. } => Self::I64AtomicStore16, + I64AtomicStore32 { .. } => Self::I64AtomicStore32, + I32AtomicRmwAdd { .. } => Self::I32AtomicRmwAdd, + I64AtomicRmwAdd { .. } => Self::I64AtomicRmwAdd, + I32AtomicRmw8AddU { .. } => Self::I32AtomicRmw8AddU, + I32AtomicRmw16AddU { .. } => Self::I32AtomicRmw16AddU, + I64AtomicRmw8AddU { .. } => Self::I64AtomicRmw8AddU, + I64AtomicRmw16AddU { .. } => Self::I64AtomicRmw16AddU, + I64AtomicRmw32AddU { .. } => Self::I64AtomicRmw32AddU, + I32AtomicRmwSub { .. } => Self::I32AtomicRmwSub, + I64AtomicRmwSub { .. } => Self::I64AtomicRmwSub, + I32AtomicRmw8SubU { .. } => Self::I32AtomicRmw8SubU, + I32AtomicRmw16SubU { .. } => Self::I32AtomicRmw16SubU, + I64AtomicRmw8SubU { .. } => Self::I64AtomicRmw8SubU, + I64AtomicRmw16SubU { .. } => Self::I64AtomicRmw16SubU, + I64AtomicRmw32SubU { .. } => Self::I64AtomicRmw32SubU, + I32AtomicRmwAnd { .. } => Self::I32AtomicRmwAnd, + I64AtomicRmwAnd { .. } => Self::I64AtomicRmwAnd, + I32AtomicRmw8AndU { .. } => Self::I32AtomicRmw8AndU, + I32AtomicRmw16AndU { .. } => Self::I32AtomicRmw16AndU, + I64AtomicRmw8AndU { .. } => Self::I64AtomicRmw8AndU, + I64AtomicRmw16AndU { .. } => Self::I64AtomicRmw16AndU, + I64AtomicRmw32AndU { .. } => Self::I64AtomicRmw32AndU, + I32AtomicRmwOr { .. } => Self::I32AtomicRmwOr, + I64AtomicRmwOr { .. } => Self::I64AtomicRmwOr, + I32AtomicRmw8OrU { .. } => Self::I32AtomicRmw8OrU, + I32AtomicRmw16OrU { .. } => Self::I32AtomicRmw16OrU, + I64AtomicRmw8OrU { .. } => Self::I64AtomicRmw8OrU, + I64AtomicRmw16OrU { .. } => Self::I64AtomicRmw16OrU, + I64AtomicRmw32OrU { .. } => Self::I64AtomicRmw32OrU, + I32AtomicRmwXor { .. } => Self::I32AtomicRmwXor, + I64AtomicRmwXor { .. } => Self::I64AtomicRmwXor, + I32AtomicRmw8XorU { .. } => Self::I32AtomicRmw8XorU, + I32AtomicRmw16XorU { .. } => Self::I32AtomicRmw16XorU, + I64AtomicRmw8XorU { .. } => Self::I64AtomicRmw8XorU, + I64AtomicRmw16XorU { .. } => Self::I64AtomicRmw16XorU, + I64AtomicRmw32XorU { .. } => Self::I64AtomicRmw32XorU, + I32AtomicRmwXchg { .. } => Self::I32AtomicRmwXchg, + I64AtomicRmwXchg { .. } => Self::I64AtomicRmwXchg, + I32AtomicRmw8XchgU { .. } => Self::I32AtomicRmw8XchgU, + I32AtomicRmw16XchgU { .. } => Self::I32AtomicRmw16XchgU, + I64AtomicRmw8XchgU { .. } => Self::I64AtomicRmw8XchgU, + I64AtomicRmw16XchgU { .. } => Self::I64AtomicRmw16XchgU, + I64AtomicRmw32XchgU { .. } => Self::I64AtomicRmw32XchgU, + I32AtomicRmwCmpxchg { .. } => Self::I32AtomicRmwCmpxchg, + I64AtomicRmwCmpxchg { .. } => Self::I64AtomicRmwCmpxchg, + I32AtomicRmw8CmpxchgU { .. } => Self::I32AtomicRmw8CmpxchgU, + I32AtomicRmw16CmpxchgU { .. } => Self::I32AtomicRmw16CmpxchgU, + I64AtomicRmw8CmpxchgU { .. } => Self::I64AtomicRmw8CmpxchgU, + I64AtomicRmw16CmpxchgU { .. } => Self::I64AtomicRmw16CmpxchgU, + I64AtomicRmw32CmpxchgU { .. } => Self::I64AtomicRmw32CmpxchgU, + V128Load { .. } => Self::V128Load, + V128Store { .. } => Self::V128Store, + V128Const { .. } => Self::V128Const, + I8x16Splat => Self::I8x16Splat, + I8x16ExtractLaneS { .. } => Self::I8x16ExtractLaneS, + I8x16ExtractLaneU { .. } => Self::I8x16ExtractLaneU, + I8x16ReplaceLane { .. } => Self::I8x16ReplaceLane, + I16x8Splat => Self::I16x8Splat, + I16x8ExtractLaneS { .. } => Self::I16x8ExtractLaneS, + I16x8ExtractLaneU { .. } => Self::I16x8ExtractLaneU, + I16x8ReplaceLane { .. } => Self::I16x8ReplaceLane, + I32x4Splat => Self::I32x4Splat, + I32x4ExtractLane { .. } => Self::I32x4ExtractLane, + I32x4ReplaceLane { .. } => Self::I32x4ReplaceLane, + I64x2Splat => Self::I64x2Splat, + I64x2ExtractLane { .. } => Self::I64x2ExtractLane, + I64x2ReplaceLane { .. } => Self::I64x2ReplaceLane, + F32x4Splat => Self::F32x4Splat, + F32x4ExtractLane { .. } => Self::F32x4ExtractLane, + F32x4ReplaceLane { .. } => Self::F32x4ReplaceLane, + F64x2Splat => Self::F64x2Splat, + F64x2ExtractLane { .. } => Self::F64x2ExtractLane, + F64x2ReplaceLane { .. } => Self::F64x2ReplaceLane, + I8x16Eq => Self::I8x16Eq, + I8x16Ne => Self::I8x16Ne, + I8x16LtS => Self::I8x16LtS, + I8x16LtU => Self::I8x16LtU, + I8x16GtS => Self::I8x16GtS, + I8x16GtU => Self::I8x16GtU, + I8x16LeS => Self::I8x16LeS, + I8x16LeU => Self::I8x16LeU, + I8x16GeS => Self::I8x16GeS, + I8x16GeU => Self::I8x16GeU, + I16x8Eq => Self::I16x8Eq, + I16x8Ne => Self::I16x8Ne, + I16x8LtS => Self::I16x8LtS, + I16x8LtU => Self::I16x8LtU, + I16x8GtS => Self::I16x8GtS, + I16x8GtU => Self::I16x8GtU, + I16x8LeS => Self::I16x8LeS, + I16x8LeU => Self::I16x8LeU, + I16x8GeS => Self::I16x8GeS, + I16x8GeU => Self::I16x8GeU, + I32x4Eq => Self::I32x4Eq, + I32x4Ne => Self::I32x4Ne, + I32x4LtS => Self::I32x4LtS, + I32x4LtU => Self::I32x4LtU, + I32x4GtS => Self::I32x4GtS, + I32x4GtU => Self::I32x4GtU, + I32x4LeS => Self::I32x4LeS, + I32x4LeU => Self::I32x4LeU, + I32x4GeS => Self::I32x4GeS, + I32x4GeU => Self::I32x4GeU, + I64x2Eq => Self::I64x2Eq, + I64x2Ne => Self::I64x2Ne, + F32x4Eq => Self::F32x4Eq, + F32x4Ne => Self::F32x4Ne, + F32x4Lt => Self::F32x4Lt, + F32x4Gt => Self::F32x4Gt, + F32x4Le => Self::F32x4Le, + F32x4Ge => Self::F32x4Ge, + F64x2Eq => Self::F64x2Eq, + F64x2Ne => Self::F64x2Ne, + F64x2Lt => Self::F64x2Lt, + F64x2Gt => Self::F64x2Gt, + F64x2Le => Self::F64x2Le, + F64x2Ge => Self::F64x2Ge, + V128Not => Self::V128Not, + V128And => Self::V128And, + V128AndNot => Self::V128AndNot, + V128Or => Self::V128Or, + V128Xor => Self::V128Xor, + V128Bitselect => Self::V128Bitselect, + V128AnyTrue => Self::V128AnyTrue, + I8x16Abs => Self::I8x16Abs, + I8x16Neg => Self::I8x16Neg, + I8x16AllTrue => Self::I8x16AllTrue, + I8x16Bitmask => Self::I8x16Bitmask, + I8x16Shl => Self::I8x16Shl, + I8x16ShrS => Self::I8x16ShrS, + I8x16ShrU => Self::I8x16ShrU, + I8x16Add => Self::I8x16Add, + I8x16AddSatS => Self::I8x16AddSatS, + I8x16AddSatU => Self::I8x16AddSatU, + I8x16Sub => Self::I8x16Sub, + I8x16SubSatS => Self::I8x16SubSatS, + I8x16SubSatU => Self::I8x16SubSatU, + I8x16MinS => Self::I8x16MinS, + I8x16MinU => Self::I8x16MinU, + I8x16MaxS => Self::I8x16MaxS, + I8x16MaxU => Self::I8x16MaxU, + I16x8Abs => Self::I16x8Abs, + I16x8Neg => Self::I16x8Neg, + I16x8AllTrue => Self::I16x8AllTrue, + I16x8Bitmask => Self::I16x8Bitmask, + I16x8Shl => Self::I16x8Shl, + I16x8ShrS => Self::I16x8ShrS, + I16x8ShrU => Self::I16x8ShrU, + I16x8Add => Self::I16x8Add, + I16x8AddSatS => Self::I16x8AddSatS, + I16x8AddSatU => Self::I16x8AddSatU, + I16x8Sub => Self::I16x8Sub, + I16x8SubSatS => Self::I16x8SubSatS, + I16x8SubSatU => Self::I16x8SubSatU, + I16x8Mul => Self::I16x8Mul, + I16x8MinS => Self::I16x8MinS, + I16x8MinU => Self::I16x8MinU, + I16x8MaxS => Self::I16x8MaxS, + I16x8MaxU => Self::I16x8MaxU, + I32x4Abs => Self::I32x4Abs, + I32x4Neg => Self::I32x4Neg, + I32x4AllTrue => Self::I32x4AllTrue, + I32x4Bitmask => Self::I32x4Bitmask, + I32x4Shl => Self::I32x4Shl, + I32x4ShrS => Self::I32x4ShrS, + I32x4ShrU => Self::I32x4ShrU, + I32x4Add => Self::I32x4Add, + I32x4Sub => Self::I32x4Sub, + I32x4Mul => Self::I32x4Mul, + I32x4MinS => Self::I32x4MinS, + I32x4MinU => Self::I32x4MinU, + I32x4MaxS => Self::I32x4MaxS, + I32x4MaxU => Self::I32x4MaxU, + I32x4DotI16x8S => Self::I32x4DotI16x8S, + I64x2Neg => Self::I64x2Neg, + I64x2AllTrue => Self::I64x2AllTrue, + I64x2Bitmask => Self::I64x2Bitmask, + I64x2Shl => Self::I64x2Shl, + I64x2ShrS => Self::I64x2ShrS, + I64x2ShrU => Self::I64x2ShrU, + I64x2Add => Self::I64x2Add, + I64x2Sub => Self::I64x2Sub, + I64x2Mul => Self::I64x2Mul, + F32x4Ceil => Self::F32x4Ceil, + F32x4Floor => Self::F32x4Floor, + F32x4Trunc => Self::F32x4Trunc, + F32x4Nearest => Self::F32x4Nearest, + F64x2Ceil => Self::F64x2Ceil, + F64x2Floor => Self::F64x2Floor, + F64x2Trunc => Self::F64x2Trunc, + F64x2Nearest => Self::F64x2Nearest, + F32x4Abs => Self::F32x4Abs, + F32x4Neg => Self::F32x4Neg, + F32x4Sqrt => Self::F32x4Sqrt, + F32x4Add => Self::F32x4Add, + F32x4Sub => Self::F32x4Sub, + F32x4Mul => Self::F32x4Mul, + F32x4Div => Self::F32x4Div, + F32x4Min => Self::F32x4Min, + F32x4Max => Self::F32x4Max, + F32x4PMin => Self::F32x4PMin, + F32x4PMax => Self::F32x4PMax, + F64x2Abs => Self::F64x2Abs, + F64x2Neg => Self::F64x2Neg, + F64x2Sqrt => Self::F64x2Sqrt, + F64x2Add => Self::F64x2Add, + F64x2Sub => Self::F64x2Sub, + F64x2Mul => Self::F64x2Mul, + F64x2Div => Self::F64x2Div, + F64x2Min => Self::F64x2Min, + F64x2Max => Self::F64x2Max, + F64x2PMin => Self::F64x2PMin, + F64x2PMax => Self::F64x2PMax, + I32x4TruncSatF32x4S => Self::I32x4TruncSatF32x4S, + I32x4TruncSatF32x4U => Self::I32x4TruncSatF32x4U, + F32x4ConvertI32x4S => Self::F32x4ConvertI32x4S, + F32x4ConvertI32x4U => Self::F32x4ConvertI32x4U, + I8x16Swizzle => Self::I8x16Swizzle, + I8x16Shuffle { .. } => Self::I8x16Shuffle, + V128Load8Splat { .. } => Self::V128Load8Splat, + V128Load16Splat { .. } => Self::V128Load16Splat, + V128Load32Splat { .. } => Self::V128Load32Splat, + V128Load32Zero { .. } => Self::V128Load32Zero, + V128Load64Splat { .. } => Self::V128Load64Splat, + V128Load64Zero { .. } => Self::V128Load64Zero, + I8x16NarrowI16x8S => Self::I8x16NarrowI16x8S, + I8x16NarrowI16x8U => Self::I8x16NarrowI16x8U, + I16x8NarrowI32x4S => Self::I16x8NarrowI32x4S, + I16x8NarrowI32x4U => Self::I16x8NarrowI32x4U, + I16x8WidenLowI8x16S => Self::I16x8WidenLowI8x16S, + I16x8WidenHighI8x16S => Self::I16x8WidenHighI8x16S, + I16x8WidenLowI8x16U => Self::I16x8WidenLowI8x16U, + I16x8WidenHighI8x16U => Self::I16x8WidenHighI8x16U, + I32x4WidenLowI16x8S => Self::I32x4WidenLowI16x8S, + I32x4WidenHighI16x8S => Self::I32x4WidenHighI16x8S, + I32x4WidenLowI16x8U => Self::I32x4WidenLowI16x8U, + I32x4WidenHighI16x8U => Self::I32x4WidenHighI16x8U, + I64x2WidenLowI32x4S => Self::I64x2WidenLowI32x4S, + I64x2WidenHighI32x4S => Self::I64x2WidenHighI32x4S, + I64x2WidenLowI32x4U => Self::I64x2WidenLowI32x4U, + I64x2WidenHighI32x4U => Self::I64x2WidenHighI32x4U, + I16x8ExtMulLowI8x16S => Self::I16x8ExtMulLowI8x16S, + I16x8ExtMulHighI8x16S => Self::I16x8ExtMulHighI8x16S, + I16x8ExtMulLowI8x16U => Self::I16x8ExtMulLowI8x16U, + I16x8ExtMulHighI8x16U => Self::I16x8ExtMulHighI8x16U, + I32x4ExtMulLowI16x8S => Self::I32x4ExtMulLowI16x8S, + I32x4ExtMulHighI16x8S => Self::I32x4ExtMulHighI16x8S, + I32x4ExtMulLowI16x8U => Self::I32x4ExtMulLowI16x8U, + I32x4ExtMulHighI16x8U => Self::I32x4ExtMulHighI16x8U, + I64x2ExtMulLowI32x4S => Self::I64x2ExtMulLowI32x4S, + I64x2ExtMulHighI32x4S => Self::I64x2ExtMulHighI32x4S, + I64x2ExtMulLowI32x4U => Self::I64x2ExtMulLowI32x4U, + I64x2ExtMulHighI32x4U => Self::I64x2ExtMulHighI32x4U, + V128Load8x8S { .. } => Self::V128Load8x8S, + V128Load8x8U { .. } => Self::V128Load8x8U, + V128Load16x4S { .. } => Self::V128Load16x4S, + V128Load16x4U { .. } => Self::V128Load16x4U, + V128Load32x2S { .. } => Self::V128Load32x2S, + V128Load32x2U { .. } => Self::V128Load32x2U, + V128Load8Lane { .. } => Self::V128Load8Lane, + V128Load16Lane { .. } => Self::V128Load16Lane, + V128Load32Lane { .. } => Self::V128Load32Lane, + V128Load64Lane { .. } => Self::V128Load64Lane, + V128Store8Lane { .. } => Self::V128Store8Lane, + V128Store16Lane { .. } => Self::V128Store16Lane, + V128Store32Lane { .. } => Self::V128Store32Lane, + V128Store64Lane { .. } => Self::V128Store64Lane, + I8x16RoundingAverageU => Self::I8x16RoundingAverageU, + I16x8RoundingAverageU => Self::I16x8RoundingAverageU, + I16x8Q15MulrSatS => Self::I16x8Q15MulrSatS, + F32x4DemoteF64x2Zero => Self::F32x4DemoteF64x2Zero, + F64x2PromoteLowF32x4 => Self::F64x2PromoteLowF32x4, + F64x2ConvertLowI32x4S => Self::F64x2ConvertLowI32x4S, + F64x2ConvertLowI32x4U => Self::F64x2ConvertLowI32x4U, + I32x4TruncSatF64x2SZero => Self::I32x4TruncSatF64x2SZero, + I32x4TruncSatF64x2UZero => Self::I32x4TruncSatF64x2UZero, + } + } +} diff --git a/lib/c-api/wasmer_wasm.h b/lib/c-api/wasmer_wasm.h index 5e351d91f5b..f86cb632cf4 100644 --- a/lib/c-api/wasmer_wasm.h +++ b/lib/c-api/wasmer_wasm.h @@ -160,6 +160,8 @@ typedef struct { } wasmer_named_extern_vec_t; #endif +typedef uint64_t (*wasmer_metering_cost_function_t)(COperator operator); + #ifdef __cplusplus extern "C" { #endif // __cplusplus @@ -286,7 +288,8 @@ void wasmer_metering_delete(wasmer_metering_t *_metering); wasmer_metering_points_t *wasmer_metering_get_remaining_points(const wasm_instance_t *instance); -wasmer_metering_t *wasmer_metering_new(uint64_t initial_limit); +wasmer_metering_t *wasmer_metering_new(uint64_t initial_limit, + wasmer_metering_cost_function_t cost_function); void wasmer_metering_points_delete(wasmer_metering_points_t *_metering_points); From 487c96452a6ed440d250679abc7f70565c3aa39e Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Thu, 4 Mar 2021 17:05:27 +0100 Subject: [PATCH 19/34] feat(middleware) Relax `F` in `Metering` by removing `Clone` and `Copy`. The `F` parameter for `Metering`, and therefore for `FunctionMetering`, no longer requires to implement the `Clone` and `Copy` traits. --- lib/middlewares/src/metering.rs | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/lib/middlewares/src/metering.rs b/lib/middlewares/src/metering.rs index 4f968ed709b..94a07df2880 100644 --- a/lib/middlewares/src/metering.rs +++ b/lib/middlewares/src/metering.rs @@ -3,7 +3,7 @@ use std::convert::TryInto; use std::fmt; -use std::sync::Mutex; +use std::sync::{Arc, Mutex}; use wasmer::wasmparser::{Operator, Type as WpType, TypeOrFuncType as WpTypeOrFuncType}; use wasmer::{ ExportIndex, FunctionMiddleware, GlobalInit, GlobalType, Instance, LocalFunctionIndex, @@ -47,21 +47,21 @@ impl fmt::Debug for MeteringGlobalIndexes { /// 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. -pub struct Metering u64 + Copy + Clone + Send + Sync> { +pub struct Metering u64 + Send + Sync> { /// Initial limit of points. initial_limit: u64, /// Function that maps each operator to a cost in "points". - cost_function: F, + cost_function: Arc, /// The global indexes for metering points. global_indexes: Mutex>, } /// The function-level metering middleware. -pub struct FunctionMetering u64 + Copy + Clone + Send + Sync> { +pub struct FunctionMetering u64 + Send + Sync> { /// Function that maps each operator to a cost in "points". - cost_function: F, + cost_function: Arc, /// The global indexes for metering points. global_indexes: MeteringGlobalIndexes, @@ -80,18 +80,18 @@ pub enum MeteringPoints { Exhausted, } -impl u64 + Copy + Clone + Send + Sync> Metering { +impl u64 + Send + Sync> Metering { /// Creates a `Metering` middleware. pub fn new(initial_limit: u64, cost_function: F) -> Self { Self { initial_limit, - cost_function, + cost_function: Arc::new(cost_function), global_indexes: Mutex::new(None), } } } -impl u64 + Copy + Clone + Send + Sync> fmt::Debug for Metering { +impl u64 + Send + Sync> fmt::Debug for Metering { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Metering") .field("initial_limit", &self.initial_limit) @@ -101,13 +101,11 @@ impl u64 + Copy + Clone + Send + Sync> fmt::Debug for Meteri } } -impl u64 + Copy + Clone + Send + Sync + 'static> ModuleMiddleware - for Metering -{ +impl u64 + Send + Sync + 'static> ModuleMiddleware for Metering { /// Generates a `FunctionMiddleware` for a given function. fn generate_function_middleware(&self, _: LocalFunctionIndex) -> Box { Box::new(FunctionMetering { - cost_function: self.cost_function, + cost_function: self.cost_function.clone(), global_indexes: self.global_indexes.lock().unwrap().clone().unwrap(), accumulated_cost: 0, }) @@ -156,7 +154,7 @@ impl u64 + Copy + Clone + Send + Sync + 'static> ModuleMiddl } } -impl u64 + Copy + Clone + Send + Sync> fmt::Debug for FunctionMetering { +impl u64 + Send + Sync> fmt::Debug for FunctionMetering { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("FunctionMetering") .field("cost_function", &"") @@ -165,9 +163,7 @@ impl u64 + Copy + Clone + Send + Sync> fmt::Debug for Functi } } -impl u64 + Copy + Clone + Send + Sync> FunctionMiddleware - for FunctionMetering -{ +impl u64 + Send + Sync> FunctionMiddleware for FunctionMetering { fn feed<'a>( &mut self, operator: Operator<'a>, From 7780423c81cdf0de42f65f3a900655c13480a73e Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Thu, 4 Mar 2021 17:07:47 +0100 Subject: [PATCH 20/34] feat(c-api) `wasmer_metering_t` contains a closure to the cost function. --- lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs b/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs index a96b9b603a2..0a923fa032b 100644 --- a/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs +++ b/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs @@ -198,7 +198,7 @@ pub unsafe extern "C" fn wasmer_metering_points_is_exhausted( /// See module's documentation. #[allow(non_camel_case_types)] pub struct wasmer_metering_t { - pub(crate) inner: Arc u64>>, + pub(crate) inner: Arc u64 + Send + Sync>>>, } #[allow(non_camel_case_types)] @@ -216,10 +216,10 @@ pub extern "C" fn wasmer_metering_new( initial_limit: u64, cost_function: wasmer_metering_cost_function_t, ) -> Box { - let cost_function = |operator: &Operator| -> u64 { cost_function(operator.into()) }; + let cost_function = move |operator: &Operator| -> u64 { cost_function(operator.into()) }; Box::new(wasmer_metering_t { - inner: Arc::new(Metering::new(initial_limit, cost_function)), + inner: Arc::new(Metering::new(initial_limit, Box::new(cost_function))), }) } From e2c4f1ee6913db3852b4e3c6bbe4edf46b88dae2 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Thu, 4 Mar 2021 17:15:28 +0100 Subject: [PATCH 21/34] feat(c-api) Rename `Operator` to `wasmer_parser_operator_t`. --- .../unstable/middlewares/metering.rs | 4 +- .../wasm_c_api/unstable/parser/operator.rs | 11 +- lib/c-api/wasmer_wasm.h | 506 +++++++++++++++++- 3 files changed, 513 insertions(+), 8 deletions(-) diff --git a/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs b/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs index 0a923fa032b..88633be3042 100644 --- a/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs +++ b/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs @@ -125,7 +125,7 @@ //! ``` use super::super::super::instance::wasm_instance_t; -use super::super::parser::operator::Operator as COperator; +use super::super::parser::operator::wasmer_parser_operator_t; use super::wasmer_middleware_t; use std::sync::Arc; use wasmer::wasmparser::Operator; @@ -202,7 +202,7 @@ pub struct wasmer_metering_t { } #[allow(non_camel_case_types)] -pub type wasmer_metering_cost_function_t = extern "C" fn(operator: COperator) -> u64; +pub type wasmer_metering_cost_function_t = extern "C" fn(operator: wasmer_parser_operator_t) -> u64; /// Creates a new metering middleware with an initial limit, i.e. a /// total number of operators to execute (regarding their respective diff --git a/lib/c-api/src/wasm_c_api/unstable/parser/operator.rs b/lib/c-api/src/wasm_c_api/unstable/parser/operator.rs index 85df6993966..83819dac5f9 100644 --- a/lib/c-api/src/wasm_c_api/unstable/parser/operator.rs +++ b/lib/c-api/src/wasm_c_api/unstable/parser/operator.rs @@ -1,7 +1,8 @@ -use wasmer::wasmparser::Operator as OriginalOperator; +use wasmer::wasmparser::Operator; #[repr(C)] -pub enum Operator { +#[allow(non_camel_case_types)] +pub enum wasmer_parser_operator_t { Unreachable, Nop, Block, @@ -505,9 +506,9 @@ pub enum Operator { I32x4TruncSatF64x2UZero, } -impl<'a> From<&OriginalOperator<'a>> for Operator { - fn from(operator: &OriginalOperator<'a>) -> Self { - use OriginalOperator::*; +impl<'a> From<&Operator<'a>> for wasmer_parser_operator_t { + fn from(operator: &Operator<'a>) -> Self { + use Operator::*; match operator { Unreachable => Self::Unreachable, diff --git a/lib/c-api/wasmer_wasm.h b/lib/c-api/wasmer_wasm.h index f86cb632cf4..6a5bf06be87 100644 --- a/lib/c-api/wasmer_wasm.h +++ b/lib/c-api/wasmer_wasm.h @@ -129,6 +129,510 @@ typedef enum { OBJECT_FILE = 2, } wasmer_engine_t; +typedef enum { + Unreachable, + Nop, + Block, + Loop, + If, + Else, + Try, + Catch, + Throw, + Rethrow, + Unwind, + End, + Br, + BrIf, + BrTable, + Return, + Call, + CallIndirect, + ReturnCall, + ReturnCallIndirect, + Drop, + Select, + TypedSelect, + LocalGet, + LocalSet, + LocalTee, + GlobalGet, + GlobalSet, + I32Load, + I64Load, + F32Load, + F64Load, + I32Load8S, + I32Load8U, + I32Load16S, + I32Load16U, + I64Load8S, + I64Load8U, + I64Load16S, + I64Load16U, + I64Load32S, + I64Load32U, + I32Store, + I64Store, + F32Store, + F64Store, + I32Store8, + I32Store16, + I64Store8, + I64Store16, + I64Store32, + MemorySize, + MemoryGrow, + I32Const, + I64Const, + F32Const, + F64Const, + RefNull, + RefIsNull, + RefFunc, + I32Eqz, + I32Eq, + I32Ne, + I32LtS, + I32LtU, + I32GtS, + I32GtU, + I32LeS, + I32LeU, + I32GeS, + I32GeU, + I64Eqz, + I64Eq, + I64Ne, + I64LtS, + I64LtU, + I64GtS, + I64GtU, + I64LeS, + I64LeU, + I64GeS, + I64GeU, + F32Eq, + F32Ne, + F32Lt, + F32Gt, + F32Le, + F32Ge, + F64Eq, + F64Ne, + F64Lt, + F64Gt, + F64Le, + F64Ge, + I32Clz, + I32Ctz, + I32Popcnt, + I32Add, + I32Sub, + I32Mul, + I32DivS, + I32DivU, + I32RemS, + I32RemU, + I32And, + I32Or, + I32Xor, + I32Shl, + I32ShrS, + I32ShrU, + I32Rotl, + I32Rotr, + I64Clz, + I64Ctz, + I64Popcnt, + I64Add, + I64Sub, + I64Mul, + I64DivS, + I64DivU, + I64RemS, + I64RemU, + I64And, + I64Or, + I64Xor, + I64Shl, + I64ShrS, + I64ShrU, + I64Rotl, + I64Rotr, + F32Abs, + F32Neg, + F32Ceil, + F32Floor, + F32Trunc, + F32Nearest, + F32Sqrt, + F32Add, + F32Sub, + F32Mul, + F32Div, + F32Min, + F32Max, + F32Copysign, + F64Abs, + F64Neg, + F64Ceil, + F64Floor, + F64Trunc, + F64Nearest, + F64Sqrt, + F64Add, + F64Sub, + F64Mul, + F64Div, + F64Min, + F64Max, + F64Copysign, + I32WrapI64, + I32TruncF32S, + I32TruncF32U, + I32TruncF64S, + I32TruncF64U, + I64ExtendI32S, + I64ExtendI32U, + I64TruncF32S, + I64TruncF32U, + I64TruncF64S, + I64TruncF64U, + F32ConvertI32S, + F32ConvertI32U, + F32ConvertI64S, + F32ConvertI64U, + F32DemoteF64, + F64ConvertI32S, + F64ConvertI32U, + F64ConvertI64S, + F64ConvertI64U, + F64PromoteF32, + I32ReinterpretF32, + I64ReinterpretF64, + F32ReinterpretI32, + F64ReinterpretI64, + I32Extend8S, + I32Extend16S, + I64Extend8S, + I64Extend16S, + I64Extend32S, + I32TruncSatF32S, + I32TruncSatF32U, + I32TruncSatF64S, + I32TruncSatF64U, + I64TruncSatF32S, + I64TruncSatF32U, + I64TruncSatF64S, + I64TruncSatF64U, + MemoryInit, + DataDrop, + MemoryCopy, + MemoryFill, + TableInit, + ElemDrop, + TableCopy, + TableFill, + TableGet, + TableSet, + TableGrow, + TableSize, + MemoryAtomicNotify, + MemoryAtomicWait32, + MemoryAtomicWait64, + AtomicFence, + I32AtomicLoad, + I64AtomicLoad, + I32AtomicLoad8U, + I32AtomicLoad16U, + I64AtomicLoad8U, + I64AtomicLoad16U, + I64AtomicLoad32U, + I32AtomicStore, + I64AtomicStore, + I32AtomicStore8, + I32AtomicStore16, + I64AtomicStore8, + I64AtomicStore16, + I64AtomicStore32, + I32AtomicRmwAdd, + I64AtomicRmwAdd, + I32AtomicRmw8AddU, + I32AtomicRmw16AddU, + I64AtomicRmw8AddU, + I64AtomicRmw16AddU, + I64AtomicRmw32AddU, + I32AtomicRmwSub, + I64AtomicRmwSub, + I32AtomicRmw8SubU, + I32AtomicRmw16SubU, + I64AtomicRmw8SubU, + I64AtomicRmw16SubU, + I64AtomicRmw32SubU, + I32AtomicRmwAnd, + I64AtomicRmwAnd, + I32AtomicRmw8AndU, + I32AtomicRmw16AndU, + I64AtomicRmw8AndU, + I64AtomicRmw16AndU, + I64AtomicRmw32AndU, + I32AtomicRmwOr, + I64AtomicRmwOr, + I32AtomicRmw8OrU, + I32AtomicRmw16OrU, + I64AtomicRmw8OrU, + I64AtomicRmw16OrU, + I64AtomicRmw32OrU, + I32AtomicRmwXor, + I64AtomicRmwXor, + I32AtomicRmw8XorU, + I32AtomicRmw16XorU, + I64AtomicRmw8XorU, + I64AtomicRmw16XorU, + I64AtomicRmw32XorU, + I32AtomicRmwXchg, + I64AtomicRmwXchg, + I32AtomicRmw8XchgU, + I32AtomicRmw16XchgU, + I64AtomicRmw8XchgU, + I64AtomicRmw16XchgU, + I64AtomicRmw32XchgU, + I32AtomicRmwCmpxchg, + I64AtomicRmwCmpxchg, + I32AtomicRmw8CmpxchgU, + I32AtomicRmw16CmpxchgU, + I64AtomicRmw8CmpxchgU, + I64AtomicRmw16CmpxchgU, + I64AtomicRmw32CmpxchgU, + V128Load, + V128Store, + V128Const, + I8x16Splat, + I8x16ExtractLaneS, + I8x16ExtractLaneU, + I8x16ReplaceLane, + I16x8Splat, + I16x8ExtractLaneS, + I16x8ExtractLaneU, + I16x8ReplaceLane, + I32x4Splat, + I32x4ExtractLane, + I32x4ReplaceLane, + I64x2Splat, + I64x2ExtractLane, + I64x2ReplaceLane, + F32x4Splat, + F32x4ExtractLane, + F32x4ReplaceLane, + F64x2Splat, + F64x2ExtractLane, + F64x2ReplaceLane, + I8x16Eq, + I8x16Ne, + I8x16LtS, + I8x16LtU, + I8x16GtS, + I8x16GtU, + I8x16LeS, + I8x16LeU, + I8x16GeS, + I8x16GeU, + I16x8Eq, + I16x8Ne, + I16x8LtS, + I16x8LtU, + I16x8GtS, + I16x8GtU, + I16x8LeS, + I16x8LeU, + I16x8GeS, + I16x8GeU, + I32x4Eq, + I32x4Ne, + I32x4LtS, + I32x4LtU, + I32x4GtS, + I32x4GtU, + I32x4LeS, + I32x4LeU, + I32x4GeS, + I32x4GeU, + I64x2Eq, + I64x2Ne, + F32x4Eq, + F32x4Ne, + F32x4Lt, + F32x4Gt, + F32x4Le, + F32x4Ge, + F64x2Eq, + F64x2Ne, + F64x2Lt, + F64x2Gt, + F64x2Le, + F64x2Ge, + V128Not, + V128And, + V128AndNot, + V128Or, + V128Xor, + V128Bitselect, + V128AnyTrue, + I8x16Abs, + I8x16Neg, + I8x16AllTrue, + I8x16Bitmask, + I8x16Shl, + I8x16ShrS, + I8x16ShrU, + I8x16Add, + I8x16AddSatS, + I8x16AddSatU, + I8x16Sub, + I8x16SubSatS, + I8x16SubSatU, + I8x16MinS, + I8x16MinU, + I8x16MaxS, + I8x16MaxU, + I16x8Abs, + I16x8Neg, + I16x8AllTrue, + I16x8Bitmask, + I16x8Shl, + I16x8ShrS, + I16x8ShrU, + I16x8Add, + I16x8AddSatS, + I16x8AddSatU, + I16x8Sub, + I16x8SubSatS, + I16x8SubSatU, + I16x8Mul, + I16x8MinS, + I16x8MinU, + I16x8MaxS, + I16x8MaxU, + I32x4Abs, + I32x4Neg, + I32x4AllTrue, + I32x4Bitmask, + I32x4Shl, + I32x4ShrS, + I32x4ShrU, + I32x4Add, + I32x4Sub, + I32x4Mul, + I32x4MinS, + I32x4MinU, + I32x4MaxS, + I32x4MaxU, + I32x4DotI16x8S, + I64x2Neg, + I64x2AllTrue, + I64x2Bitmask, + I64x2Shl, + I64x2ShrS, + I64x2ShrU, + I64x2Add, + I64x2Sub, + I64x2Mul, + F32x4Ceil, + F32x4Floor, + F32x4Trunc, + F32x4Nearest, + F64x2Ceil, + F64x2Floor, + F64x2Trunc, + F64x2Nearest, + F32x4Abs, + F32x4Neg, + F32x4Sqrt, + F32x4Add, + F32x4Sub, + F32x4Mul, + F32x4Div, + F32x4Min, + F32x4Max, + F32x4PMin, + F32x4PMax, + F64x2Abs, + F64x2Neg, + F64x2Sqrt, + F64x2Add, + F64x2Sub, + F64x2Mul, + F64x2Div, + F64x2Min, + F64x2Max, + F64x2PMin, + F64x2PMax, + I32x4TruncSatF32x4S, + I32x4TruncSatF32x4U, + F32x4ConvertI32x4S, + F32x4ConvertI32x4U, + I8x16Swizzle, + I8x16Shuffle, + V128Load8Splat, + V128Load16Splat, + V128Load32Splat, + V128Load32Zero, + V128Load64Splat, + V128Load64Zero, + I8x16NarrowI16x8S, + I8x16NarrowI16x8U, + I16x8NarrowI32x4S, + I16x8NarrowI32x4U, + I16x8WidenLowI8x16S, + I16x8WidenHighI8x16S, + I16x8WidenLowI8x16U, + I16x8WidenHighI8x16U, + I32x4WidenLowI16x8S, + I32x4WidenHighI16x8S, + I32x4WidenLowI16x8U, + I32x4WidenHighI16x8U, + I64x2WidenLowI32x4S, + I64x2WidenHighI32x4S, + I64x2WidenLowI32x4U, + I64x2WidenHighI32x4U, + I16x8ExtMulLowI8x16S, + I16x8ExtMulHighI8x16S, + I16x8ExtMulLowI8x16U, + I16x8ExtMulHighI8x16U, + I32x4ExtMulLowI16x8S, + I32x4ExtMulHighI16x8S, + I32x4ExtMulLowI16x8U, + I32x4ExtMulHighI16x8U, + I64x2ExtMulLowI32x4S, + I64x2ExtMulHighI32x4S, + I64x2ExtMulLowI32x4U, + I64x2ExtMulHighI32x4U, + V128Load8x8S, + V128Load8x8U, + V128Load16x4S, + V128Load16x4U, + V128Load32x2S, + V128Load32x2U, + V128Load8Lane, + V128Load16Lane, + V128Load32Lane, + V128Load64Lane, + V128Store8Lane, + V128Store16Lane, + V128Store32Lane, + V128Store64Lane, + I8x16RoundingAverageU, + I16x8RoundingAverageU, + I16x8Q15MulrSatS, + F32x4DemoteF64x2Zero, + F64x2PromoteLowF32x4, + F64x2ConvertLowI32x4S, + F64x2ConvertLowI32x4U, + I32x4TruncSatF64x2SZero, + I32x4TruncSatF64x2UZero, +} wasmer_parser_operator_t; + #if defined(WASMER_WASI_ENABLED) typedef struct wasi_config_t wasi_config_t; #endif @@ -160,7 +664,7 @@ typedef struct { } wasmer_named_extern_vec_t; #endif -typedef uint64_t (*wasmer_metering_cost_function_t)(COperator operator); +typedef uint64_t (*wasmer_metering_cost_function_t)(wasmer_parser_operator_t operator); #ifdef __cplusplus extern "C" { From 0163b33ff3344195a0d022e209ec9bfb01e8f1ce Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Thu, 4 Mar 2021 17:29:39 +0100 Subject: [PATCH 22/34] test(c-api) Update the test to use a custom user-defined cost function. --- .../unstable/middlewares/metering.rs | 28 +++++++++++++++++-- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs b/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs index 88633be3042..2e791d0a443 100644 --- a/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs +++ b/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs @@ -13,9 +13,23 @@ //! # (assert_c! { //! # #include "tests/wasmer_wasm.h" //! # +//! // Define our “cost function”. +//! uint64_t cost_function(wasmer_parser_operator_t operator) { +//! switch(operator) { +//! case I32Const: +//! case I64Const: +//! case F32Const: +//! case F64Const: +//! return 0; +//! +//! default: +//! return 1; +//! } +//! } +//! //! int main() { -//! // Create a new metering middleware. -//! wasmer_metering_t* metering = wasmer_metering_new(10); +//! // Create a new metering middleware, with our cost function. +//! wasmer_metering_t* metering = wasmer_metering_new(10, cost_function); //! //! // Consume `metering` to produce a generic `wasmer_middle_t` value. //! wasmer_middleware_t* middleware = wasmer_metering_as_middleware(metering); @@ -261,9 +275,17 @@ pub unsafe extern "C" fn wasmer_metering_get_remaining_points( /// # (assert_c! { /// # #include "tests/wasmer_wasm.h" /// # +/// // Define a dummy “cost function”. +/// uint64_t cost_function(wasmer_parser_operator_t operator) { +/// switch(operator) { +/// default: +/// return 0; +/// } +/// } +/// /// int main() { /// // Set the initial amount of points to 10. -/// wasmer_metering_t* metering = wasmer_metering_new(7); +/// wasmer_metering_t* metering = wasmer_metering_new(7, cost_function); /// /// // Consume `metering` to produce `middleware`. /// wasmer_middleware_t* middleware = wasmer_metering_as_middleware(metering); From e7c78e77ee1b4700785c51f1e8f91ab64d0dcd46 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Thu, 4 Mar 2021 21:49:39 +0100 Subject: [PATCH 23/34] test(c-api) Update tests for the metering API. --- .../unstable/middlewares/metering.rs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs b/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs index 2e791d0a443..d1b8b9ea299 100644 --- a/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs +++ b/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs @@ -16,14 +16,18 @@ //! // Define our “cost function”. //! uint64_t cost_function(wasmer_parser_operator_t operator) { //! switch(operator) { +//! // `local.get` and `i32.const` cost 1 unit. +//! case LocalGet: //! case I32Const: -//! case I64Const: -//! case F32Const: -//! case F64Const: -//! return 0; +//! return 1; +//! +//! // `i32.add` costs 2 units. +//! case I32Add: +//! return 2; //! +//! // The other operations are free. //! default: -//! return 1; +//! return 0; //! } //! } //! @@ -51,8 +55,6 @@ //! " (func $add_two_f (type $add_t) (param $value i32) (result i32)\n" //! " local.get $value\n" //! " i32.const 1\n" -//! " i32.add\n" -//! " i32.const 1\n" //! " i32.add)\n" //! " (export \"add_two\" (func $add_two_f)))" //! ); @@ -78,7 +80,7 @@ //! const wasm_func_t* add_two = wasm_extern_as_func(exports.data[0]); //! assert(add_two); //! -//! wasm_val_t arguments[1] = { WASM_I32_VAL(40) }; +//! wasm_val_t arguments[1] = { WASM_I32_VAL(41) }; //! wasm_val_t results[1] = { WASM_INIT_VAL }; //! //! wasm_val_vec_t arguments_as_array = WASM_ARRAY_VEC(arguments); From f0024c5994b9426ec4fa009a0d744421ebf633db Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Thu, 4 Mar 2021 22:34:04 +0100 Subject: [PATCH 24/34] doc(c-api) Fix typos. --- lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs b/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs index d1b8b9ea299..507032199fc 100644 --- a/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs +++ b/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs @@ -1,5 +1,5 @@ //! Unstable non-standard Wasmer-specific API that contains everything -//! to create a the middleware metering API. +//! to create the middleware metering API. //! //! The metering middleware is used for tracking how many operators //! are executed in total and putting a limit on the total number of @@ -35,7 +35,7 @@ //! // Create a new metering middleware, with our cost function. //! wasmer_metering_t* metering = wasmer_metering_new(10, cost_function); //! -//! // Consume `metering` to produce a generic `wasmer_middle_t` value. +//! // Consume `metering` to produce a generic `wasmer_middleware_t` value. //! wasmer_middleware_t* middleware = wasmer_metering_as_middleware(metering); //! //! // Create a new configuration, and push the middleware in it. @@ -175,7 +175,7 @@ pub unsafe extern "C" fn wasmer_metering_points_delete( ) { } -/// Returns the number of remaining points if any, otherwise returned +/// Returns the number of remaining points if any, otherwise returns /// the given `exhausted` value if points are exhausted. /// /// # Example From 4f2ba728ddf23d144162aec200e0f1cbe87ccbed Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Thu, 4 Mar 2021 22:53:02 +0100 Subject: [PATCH 25/34] feat(c-api) Simplify the metering API. This patch removes the following type and functions: * `wasmer_metering_points_t`, * `wasmer_metering_points_delete`, * `wasmer_metering_points_is_exhausted`, * `wasmer_metering_points_t`, * `wasmer_metering_points_unwrap_or`. Now, `wasmer_metering_get_remaining_points` returns the number of points, with zero to represent `MeteringPoints::Exhausted`. The API is greatly simplified as there is no longer need to allocate and deallocate a `wasmer_metering_points_t` type. --- lib/c-api/build.rs | 4 - .../unstable/middlewares/metering.rs | 111 ++++-------------- lib/c-api/wasmer_wasm.h | 11 +- 3 files changed, 21 insertions(+), 105 deletions(-) diff --git a/lib/c-api/build.rs b/lib/c-api/build.rs index 79dd9910650..bbd7e983cac 100644 --- a/lib/c-api/build.rs +++ b/lib/c-api/build.rs @@ -523,10 +523,6 @@ fn exclude_items_from_wasm_c_api(builder: Builder) -> Builder { .exclude_item("wasmer_metering_delete") .exclude_item("wasmer_metering_get_remaining_points") .exclude_item("wasmer_metering_new") - .exclude_item("wasmer_metering_points_delete") - .exclude_item("wasmer_metering_points_is_exhausted") - .exclude_item("wasmer_metering_points_t") - .exclude_item("wasmer_metering_points_unwrap_or") .exclude_item("wasmer_metering_set_remaining_points") .exclude_item("wasmer_metering_t") .exclude_item("wasmer_middleware_t") diff --git a/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs b/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs index 507032199fc..02e127a5776 100644 --- a/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs +++ b/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs @@ -86,9 +86,6 @@ //! wasm_val_vec_t arguments_as_array = WASM_ARRAY_VEC(arguments); //! wasm_val_vec_t results_as_array = WASM_ARRAY_VEC(results); //! -//! // Let's define a value when points are exhausted. -//! uint64_t is_exhausted = -1; -//! //! // Let's call `add_two` for the first time! //! { //! wasm_trap_t* trap = wasm_func_call(add_two, &arguments_as_array, &results_as_array); @@ -96,10 +93,7 @@ //! assert(results[0].of.i32 == 42); //! //! // There is 6 points left! -//! wasmer_metering_points_t* metering_points = wasmer_metering_get_remaining_points(instance); -//! assert(wasmer_metering_points_unwrap_or(metering_points, is_exhausted) == 6); -//! assert(wasmer_metering_points_is_exhausted(metering_points) == false); -//! wasmer_metering_points_delete(metering_points); +//! assert(wasmer_metering_get_remaining_points(instance) == 6); //! } //! //! // Let's call `add_two` for the second time! @@ -109,10 +103,7 @@ //! assert(results[0].of.i32 == 42); //! //! // There is 2 points left! -//! wasmer_metering_points_t* metering_points = wasmer_metering_get_remaining_points(instance); -//! assert(wasmer_metering_points_unwrap_or(metering_points, is_exhausted) == 2); -//! assert(wasmer_metering_points_is_exhausted(metering_points) == false); -//! wasmer_metering_points_delete(metering_points); +//! assert(wasmer_metering_get_remaining_points(instance) == 2); //! } //! //! // Let's call `add_two` for the third time! @@ -122,10 +113,7 @@ //! assert(trap != NULL); //! //! // There is 0 point left… they are exhausted. -//! wasmer_metering_points_t* metering_points = wasmer_metering_get_remaining_points(instance); -//! assert(wasmer_metering_points_unwrap_or(metering_points, is_exhausted) == is_exhausted); -//! assert(wasmer_metering_points_is_exhausted(metering_points) == true); -//! wasmer_metering_points_delete(metering_points); +//! assert(wasmer_metering_get_remaining_points(instance) == 0); //! } //! //! wasm_instance_delete(instance); @@ -150,60 +138,6 @@ use wasmer_middlewares::{ Metering, }; -/// Opaque type representing metering points, i.e. the actual number -/// of remaining points for a given [`wasmer_metering_t`]. -/// -/// To get a value of that type, see the -/// [`wasmer_metering_get_remaining_points`]. -/// -/// # Example -/// -/// See module's documentation. -#[allow(non_camel_case_types)] -pub struct wasmer_metering_points_t { - pub(crate) inner: MeteringPoints, -} - -/// Deletes a [`wasmer_metering_points_t`]. -/// -/// # Example -/// -/// See module's documentation. -#[no_mangle] -pub unsafe extern "C" fn wasmer_metering_points_delete( - _metering_points: Option>, -) { -} - -/// Returns the number of remaining points if any, otherwise returns -/// the given `exhausted` value if points are exhausted. -/// -/// # Example -/// -/// See module's documentation. -#[no_mangle] -pub unsafe extern "C" fn wasmer_metering_points_unwrap_or( - metering_points: &wasmer_metering_points_t, - exhausted: u64, -) -> u64 { - match metering_points.inner { - MeteringPoints::Remaining(value) => value, - MeteringPoints::Exhausted => exhausted, - } -} - -/// Checks whether the number of metering points are exhausted. -/// -/// # Example -/// -/// See module's documentation. -#[no_mangle] -pub unsafe extern "C" fn wasmer_metering_points_is_exhausted( - metering_points: &wasmer_metering_points_t, -) -> bool { - matches!(metering_points.inner, MeteringPoints::Exhausted) -} - /// Opaque type representing a metering middleware. /// /// To transform this specific middleware into a generic one, please @@ -217,12 +151,19 @@ pub struct wasmer_metering_t { pub(crate) inner: Arc u64 + Send + Sync>>>, } +/// Function type to represent a user-defined cost function +/// implemented in C. +/// +/// # Example +/// +/// See module's documentation. #[allow(non_camel_case_types)] pub type wasmer_metering_cost_function_t = extern "C" fn(operator: wasmer_parser_operator_t) -> u64; /// Creates a new metering middleware with an initial limit, i.e. a /// total number of operators to execute (regarding their respective -/// cost). +/// cost), in addition to a cost function. The cost function defines +/// the cost of an operation, that will decrease the initial limit. /// /// # Example /// @@ -247,20 +188,18 @@ pub extern "C" fn wasmer_metering_new( #[no_mangle] pub unsafe extern "C" fn wasmer_metering_delete(_metering: Option>) {} -/// Returns the remaining metering points, inside a -/// [`wasmer_metering_points_t`] value. The caller is responsible to -/// free this value by using [`wasmer_metering_points_delete`]. +/// Returns the remaining metering points. Zero means points are +/// exhausted, otherwise it returns the number of points. /// /// # Example /// /// See module's documentation. #[no_mangle] -pub unsafe extern "C" fn wasmer_metering_get_remaining_points( - instance: &wasm_instance_t, -) -> Box { - Box::new(wasmer_metering_points_t { - inner: get_remaining_points(&instance.inner), - }) +pub unsafe extern "C" fn wasmer_metering_get_remaining_points(instance: &wasm_instance_t) -> u64 { + match get_remaining_points(&instance.inner) { + MeteringPoints::Remaining(value) => value, + MeteringPoints::Exhausted => 0, + } } /// Set a new amount of points for the given metering middleware. @@ -316,23 +255,13 @@ pub unsafe extern "C" fn wasmer_metering_get_remaining_points( /// assert(instance); /// /// // Read the number of points. -/// { -/// wasmer_metering_points_t* points = wasmer_metering_get_remaining_points(instance); -/// assert(wasmer_metering_points_unwrap_or(points, -1) == 7); -/// -/// wasmer_metering_points_delete(points); -/// } +/// assert(wasmer_metering_get_remaining_points(instance) == 7); /// /// // Set a new number of points. /// wasmer_metering_set_remaining_points(instance, 42); /// /// // Read the number of points. -/// { -/// wasmer_metering_points_t* points = wasmer_metering_get_remaining_points(instance); -/// assert(wasmer_metering_points_unwrap_or(points, -1) == 42); -/// -/// wasmer_metering_points_delete(points); -/// } +/// assert(wasmer_metering_get_remaining_points(instance) == 42); /// /// wasm_instance_delete(instance); /// wasm_module_delete(module); diff --git a/lib/c-api/wasmer_wasm.h b/lib/c-api/wasmer_wasm.h index 7a6d4004b83..f1109506512 100644 --- a/lib/c-api/wasmer_wasm.h +++ b/lib/c-api/wasmer_wasm.h @@ -645,8 +645,6 @@ typedef struct wasmer_cpu_features_t wasmer_cpu_features_t; typedef struct wasmer_features_t wasmer_features_t; -typedef struct wasmer_metering_points_t wasmer_metering_points_t; - typedef struct wasmer_metering_t wasmer_metering_t; typedef struct wasmer_middleware_t wasmer_middleware_t; @@ -816,18 +814,11 @@ wasmer_middleware_t *wasmer_metering_as_middleware(wasmer_metering_t *metering); void wasmer_metering_delete(wasmer_metering_t *_metering); -wasmer_metering_points_t *wasmer_metering_get_remaining_points(const wasm_instance_t *instance); +uint64_t wasmer_metering_get_remaining_points(const wasm_instance_t *instance); wasmer_metering_t *wasmer_metering_new(uint64_t initial_limit, wasmer_metering_cost_function_t cost_function); -void wasmer_metering_points_delete(wasmer_metering_points_t *_metering_points); - -bool wasmer_metering_points_is_exhausted(const wasmer_metering_points_t *metering_points); - -uint64_t wasmer_metering_points_unwrap_or(const wasmer_metering_points_t *metering_points, - uint64_t exhausted); - void wasmer_metering_set_remaining_points(const wasm_instance_t *instance, uint64_t new_limit); void wasmer_module_name(const wasm_module_t *module, wasm_name_t *out); From f233ca444e5c37f52063dbda082bc85a63cc0d48 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Thu, 4 Mar 2021 23:17:14 +0100 Subject: [PATCH 26/34] chore(api) The `compiler` feature enables `wasmer-compiler/translator`. --- Cargo.lock | 1 - lib/api/Cargo.toml | 1 + lib/c-api/Cargo.toml | 2 +- lib/c-api/src/wasm_c_api/engine.rs | 2 +- lib/c-api/src/wasm_c_api/unstable/middlewares/mod.rs | 2 +- lib/c-api/src/wasm_c_api/unstable/target_lexicon.rs | 2 +- 6 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2991a3435a8..fb4029c4e6e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2354,7 +2354,6 @@ dependencies = [ "thiserror", "typetag", "wasmer", - "wasmer-compiler", "wasmer-compiler-cranelift", "wasmer-compiler-llvm", "wasmer-compiler-singlepass", diff --git a/lib/api/Cargo.toml b/lib/api/Cargo.toml index 0972819e8f0..f9286c04c17 100644 --- a/lib/api/Cargo.toml +++ b/lib/api/Cargo.toml @@ -44,6 +44,7 @@ maintenance = { status = "actively-developed" } [features] default = ["wat", "default-cranelift", "default-jit"] compiler = [ + "wasmer-compiler/translator", "wasmer-engine-jit/compiler", "wasmer-engine-native/compiler", ] diff --git a/lib/c-api/Cargo.toml b/lib/c-api/Cargo.toml index 49a3f2c2d9a..a6987d89854 100644 --- a/lib/c-api/Cargo.toml +++ b/lib/c-api/Cargo.toml @@ -16,7 +16,6 @@ crate-type = ["cdylib", "rlib", "staticlib"] [dependencies] wasmer = { version = "1.0.2", path = "../api", default-features = false } -wasmer-compiler = { version = "1.0.2", path = "../compiler" } wasmer-compiler-cranelift = { version = "1.0.2", path = "../compiler-cranelift", optional = true } wasmer-compiler-singlepass = { version = "1.0.2", path = "../compiler-singlepass", optional = true } wasmer-compiler-llvm = { version = "1.0.2", path = "../compiler-llvm", optional = true } @@ -68,6 +67,7 @@ object-file = [ "engine", ] compiler = [ + "wasmer/compiler", "wasmer-engine-jit/compiler", "wasmer-engine-native/compiler", "wasmer-engine-object-file/compiler" diff --git a/lib/c-api/src/wasm_c_api/engine.rs b/lib/c-api/src/wasm_c_api/engine.rs index 0d9d1c362a8..e9014320292 100644 --- a/lib/c-api/src/wasm_c_api/engine.rs +++ b/lib/c-api/src/wasm_c_api/engine.rs @@ -286,7 +286,7 @@ pub struct wasm_engine_t { // Compiler JIT #[cfg(feature = "compiler")] -use wasmer_compiler::CompilerConfig; +use wasmer::CompilerConfig; #[cfg(feature = "compiler")] fn get_default_compiler_config() -> Box { cfg_if! { diff --git a/lib/c-api/src/wasm_c_api/unstable/middlewares/mod.rs b/lib/c-api/src/wasm_c_api/unstable/middlewares/mod.rs index 1402ce74ead..6a1c86daa40 100644 --- a/lib/c-api/src/wasm_c_api/unstable/middlewares/mod.rs +++ b/lib/c-api/src/wasm_c_api/unstable/middlewares/mod.rs @@ -5,7 +5,7 @@ pub mod metering; use super::super::engine::wasm_config_t; use std::sync::Arc; -use wasmer_compiler::ModuleMiddleware; +use wasmer::ModuleMiddleware; #[cfg(all(feature = "middlewares", not(feature = "compiler")))] compile_error!("The `middlewares` feature requires the `compiler` feature to be turned on"); diff --git a/lib/c-api/src/wasm_c_api/unstable/target_lexicon.rs b/lib/c-api/src/wasm_c_api/unstable/target_lexicon.rs index bea0ec64ef4..cf16829f7f0 100644 --- a/lib/c-api/src/wasm_c_api/unstable/target_lexicon.rs +++ b/lib/c-api/src/wasm_c_api/unstable/target_lexicon.rs @@ -58,7 +58,7 @@ use crate::error::CApiError; use enumset::EnumSet; use std::slice; use std::str::{self, FromStr}; -use wasmer_compiler::{CpuFeature, Target, Triple}; +use wasmer::{CpuFeature, Target, Triple}; /// Unstable non-standard Wasmer-specific API to represent a triple + /// CPU features pair. From df0bdebc0075d411d927d5546e3f7f89a38c10ed Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Thu, 4 Mar 2021 23:36:33 +0100 Subject: [PATCH 27/34] fix(makefile) `build-capi` includes the `middlewares` feature. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index ff37010c22e..d740e7bf8e6 100644 --- a/Makefile +++ b/Makefile @@ -387,7 +387,7 @@ build-docs-capi: build-capi: cargo build --manifest-path lib/c-api/Cargo.toml --release \ - --no-default-features --features deprecated,wat,jit,native,object-file,wasi $(capi_default_features) $(capi_compiler_features) + --no-default-features --features deprecated,wat,jit,native,object-file,wasi,middlewares $(capi_default_features) $(capi_compiler_features) build-capi-singlepass: cargo build --manifest-path lib/c-api/Cargo.toml --release \ From 2d20f44365652e3267712380e497fc5134e6e4db Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Thu, 4 Mar 2021 23:39:43 +0100 Subject: [PATCH 28/34] fix(c-api) Remove useless `unsafe` marker. --- .../src/wasm_c_api/unstable/middlewares/metering.rs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs b/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs index 02e127a5776..396df008918 100644 --- a/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs +++ b/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs @@ -186,7 +186,7 @@ pub extern "C" fn wasmer_metering_new( /// /// See module's documentation. #[no_mangle] -pub unsafe extern "C" fn wasmer_metering_delete(_metering: Option>) {} +pub extern "C" fn wasmer_metering_delete(_metering: Option>) {} /// Returns the remaining metering points. Zero means points are /// exhausted, otherwise it returns the number of points. @@ -195,7 +195,7 @@ pub unsafe extern "C" fn wasmer_metering_delete(_metering: Option u64 { +pub extern "C" fn wasmer_metering_get_remaining_points(instance: &wasm_instance_t) -> u64 { match get_remaining_points(&instance.inner) { MeteringPoints::Remaining(value) => value, MeteringPoints::Exhausted => 0, @@ -275,10 +275,7 @@ pub unsafe extern "C" fn wasmer_metering_get_remaining_points(instance: &wasm_in /// # } /// ``` #[no_mangle] -pub unsafe extern "C" fn wasmer_metering_set_remaining_points( - instance: &wasm_instance_t, - new_limit: u64, -) { +pub extern "C" fn wasmer_metering_set_remaining_points(instance: &wasm_instance_t, new_limit: u64) { set_remaining_points(&instance.inner, new_limit); } @@ -292,7 +289,7 @@ pub unsafe extern "C" fn wasmer_metering_set_remaining_points( /// /// See module's documentation. #[no_mangle] -pub unsafe extern "C" fn wasmer_metering_as_middleware( +pub extern "C" fn wasmer_metering_as_middleware( metering: Option>, ) -> Option> { let metering = metering?; From 96524b57961d343e8adce0ac7597dce435741f01 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Fri, 5 Mar 2021 00:23:46 +0100 Subject: [PATCH 29/34] chore(c-api) Update headers. --- lib/c-api/wasmer_wasm.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/c-api/wasmer_wasm.h b/lib/c-api/wasmer_wasm.h index d4361ee87cd..a6753a07556 100644 --- a/lib/c-api/wasmer_wasm.h +++ b/lib/c-api/wasmer_wasm.h @@ -129,7 +129,7 @@ typedef enum wasmer_engine_t { OBJECT_FILE = 2, } wasmer_engine_t; -typedef enum { +typedef enum wasmer_parser_operator_t { Unreachable, Nop, Block, @@ -664,7 +664,7 @@ typedef struct wasmer_named_extern_vec_t { } wasmer_named_extern_vec_t; #endif -typedef uint64_t (*wasmer_metering_cost_function_t)(wasmer_parser_operator_t operator); +typedef uint64_t (*wasmer_metering_cost_function_t)(enum wasmer_parser_operator_t operator); #ifdef __cplusplus extern "C" { @@ -760,7 +760,7 @@ bool wasi_get_unordered_imports(const wasm_store_t *store, enum wasi_version_t wasi_get_wasi_version(const wasm_module_t *module); #endif -void wasm_config_push_middleware(wasm_config_t *config, wasmer_middleware_t *middleware); +void wasm_config_push_middleware(wasm_config_t *config, struct wasmer_middleware_t *middleware); #if defined(WASMER_COMPILER_ENABLED) void wasm_config_set_compiler(wasm_config_t *config, enum wasmer_compiler_t compiler); @@ -811,14 +811,14 @@ int wasmer_last_error_length(void); int wasmer_last_error_message(char *buffer, int length); -wasmer_middleware_t *wasmer_metering_as_middleware(wasmer_metering_t *metering); +struct wasmer_middleware_t *wasmer_metering_as_middleware(struct wasmer_metering_t *metering); -void wasmer_metering_delete(wasmer_metering_t *_metering); +void wasmer_metering_delete(struct wasmer_metering_t *_metering); uint64_t wasmer_metering_get_remaining_points(const wasm_instance_t *instance); -wasmer_metering_t *wasmer_metering_new(uint64_t initial_limit, - wasmer_metering_cost_function_t cost_function); +struct wasmer_metering_t *wasmer_metering_new(uint64_t initial_limit, + wasmer_metering_cost_function_t cost_function); void wasmer_metering_set_remaining_points(const wasm_instance_t *instance, uint64_t new_limit); From 8517547826dff7ff21b941078d30f0b040bb4a30 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Fri, 5 Mar 2021 00:24:13 +0100 Subject: [PATCH 30/34] fix(engine-native) Fix Cargo.lock and `Library::new` is unsafe. --- Cargo.lock | 26 +++----------------------- lib/engine-native/src/artifact.rs | 2 +- 2 files changed, 4 insertions(+), 24 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7cd314f3bd7..eb73620585a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -266,7 +266,7 @@ checksum = "f54d78e30b388d4815220c8dd03fea5656b6c6d32adb59e89061552a102f8da1" dependencies = [ "glob", "libc", - "libloading 0.7.0", + "libloading", ] [[package]] @@ -1123,26 +1123,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "libloading" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f84d96438c15fcd6c3f244c8fce01d1e2b9c6b5623e9c711dc9286d8fc92d6a" -dependencies = [ - "cfg-if 1.0.0", - "winapi", -] - -[[package]] -name = "libloading" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f84d96438c15fcd6c3f244c8fce01d1e2b9c6b5623e9c711dc9286d8fc92d6a" -dependencies = [ - "cfg-if 1.0.0", - "winapi", -] - [[package]] name = "llvm-sys" version = "110.0.1" @@ -2561,7 +2541,7 @@ dependencies = [ "bincode", "cfg-if 0.1.10", "leb128", - "libloading 0.6.7", + "libloading", "serde", "tempfile", "tracing", @@ -2580,7 +2560,7 @@ dependencies = [ "bincode", "cfg-if 0.1.10", "leb128", - "libloading 0.6.7", + "libloading", "serde", "tempfile", "tracing", diff --git a/lib/engine-native/src/artifact.rs b/lib/engine-native/src/artifact.rs index 450752fefd8..8c77216cf20 100644 --- a/lib/engine-native/src/artifact.rs +++ b/lib/engine-native/src/artifact.rs @@ -317,7 +317,7 @@ impl NativeArtifact { if is_cross_compiling { Self::from_parts_crosscompiled(metadata, shared_filepath) } else { - let lib = Library::new(&shared_filepath).map_err(to_compile_error)?; + let lib = unsafe { Library::new(&shared_filepath).map_err(to_compile_error)? }; Self::from_parts(&mut engine_inner, metadata, shared_filepath, lib) } } From 1700c2d056751c27fb140e407fdcf672c73d8333 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Fri, 5 Mar 2021 00:41:03 +0100 Subject: [PATCH 31/34] feat(c-api) Return ~1 if metering are exhausted. Add `wasmer_metering_points_are_exhausted`. --- lib/c-api/build.rs | 1 + .../unstable/middlewares/metering.rs | 25 ++++++++++++++++--- lib/c-api/wasmer_wasm.h | 2 ++ 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/lib/c-api/build.rs b/lib/c-api/build.rs index bbd7e983cac..1f899c076f9 100644 --- a/lib/c-api/build.rs +++ b/lib/c-api/build.rs @@ -523,6 +523,7 @@ fn exclude_items_from_wasm_c_api(builder: Builder) -> Builder { .exclude_item("wasmer_metering_delete") .exclude_item("wasmer_metering_get_remaining_points") .exclude_item("wasmer_metering_new") + .exclude_item("wasmer_metering_points_are_exhausted") .exclude_item("wasmer_metering_set_remaining_points") .exclude_item("wasmer_metering_t") .exclude_item("wasmer_middleware_t") diff --git a/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs b/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs index 396df008918..446ec3ab33e 100644 --- a/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs +++ b/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs @@ -94,6 +94,7 @@ //! //! // There is 6 points left! //! assert(wasmer_metering_get_remaining_points(instance) == 6); +//! assert(wasmer_metering_points_are_exhausted(instance) == false); //! } //! //! // Let's call `add_two` for the second time! @@ -104,6 +105,7 @@ //! //! // There is 2 points left! //! assert(wasmer_metering_get_remaining_points(instance) == 2); +//! assert(wasmer_metering_points_are_exhausted(instance) == false); //! } //! //! // Let's call `add_two` for the third time! @@ -113,7 +115,7 @@ //! assert(trap != NULL); //! //! // There is 0 point left… they are exhausted. -//! assert(wasmer_metering_get_remaining_points(instance) == 0); +//! assert(wasmer_metering_points_are_exhausted(instance) == true); //! } //! //! wasm_instance_delete(instance); @@ -188,8 +190,10 @@ pub extern "C" fn wasmer_metering_new( #[no_mangle] pub extern "C" fn wasmer_metering_delete(_metering: Option>) {} -/// Returns the remaining metering points. Zero means points are -/// exhausted, otherwise it returns the number of points. +/// Returns the remaining metering points. `u64::MAX` means +/// points are exhausted, otherwise it returns the number of +/// points. Notice that it could include zero! Zero doesn't mean +/// points are exhausted _yet_. /// /// # Example /// @@ -198,10 +202,23 @@ pub extern "C" fn wasmer_metering_delete(_metering: Option u64 { match get_remaining_points(&instance.inner) { MeteringPoints::Remaining(value) => value, - MeteringPoints::Exhausted => 0, + MeteringPoints::Exhausted => std::u64::MAX, } } +/// Returns true if the remaning points are exhausted, false otherwise. +/// +/// # Example +/// +/// See module's documentation. +#[no_mangle] +pub extern "C" fn wasmer_metering_points_are_exhausted(instance: &wasm_instance_t) -> bool { + matches!( + get_remaining_points(&instance.inner), + MeteringPoints::Exhausted, + ) +} + /// Set a new amount of points for the given metering middleware. /// /// # Example diff --git a/lib/c-api/wasmer_wasm.h b/lib/c-api/wasmer_wasm.h index a6753a07556..beedd9c0c06 100644 --- a/lib/c-api/wasmer_wasm.h +++ b/lib/c-api/wasmer_wasm.h @@ -820,6 +820,8 @@ uint64_t wasmer_metering_get_remaining_points(const wasm_instance_t *instance); struct wasmer_metering_t *wasmer_metering_new(uint64_t initial_limit, wasmer_metering_cost_function_t cost_function); +bool wasmer_metering_points_are_exhausted(const wasm_instance_t *instance); + void wasmer_metering_set_remaining_points(const wasm_instance_t *instance, uint64_t new_limit); void wasmer_module_name(const wasm_module_t *module, wasm_name_t *out); From 06a00d9bd0e7d2fa0556ef36bbbaa0d5ca2879b5 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Fri, 5 Mar 2021 00:53:24 +0100 Subject: [PATCH 32/34] doc(c-api) Update documentation for clarity. --- lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs | 8 ++++---- lib/c-api/src/wasm_c_api/unstable/middlewares/mod.rs | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs b/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs index 446ec3ab33e..b0cf22f30c3 100644 --- a/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs +++ b/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs @@ -223,9 +223,9 @@ pub extern "C" fn wasmer_metering_points_are_exhausted(instance: &wasm_instance_ /// /// # Example /// -/// This example is pointless as the number of points aren't updated -/// by the WebAssembly module execution, it only illustrates the -/// `wasmer_metering_set_remaining_points` function. +/// This example only illustrates the +/// `wasmer_metering_set_remaining_points` function, as the number of +/// points aren't updated by the WebAssembly module execution /// /// ```rust /// # use inline_c::assert_c; @@ -242,7 +242,7 @@ pub extern "C" fn wasmer_metering_points_are_exhausted(instance: &wasm_instance_ /// } /// /// int main() { -/// // Set the initial amount of points to 10. +/// // Set the initial amount of points to 7. /// wasmer_metering_t* metering = wasmer_metering_new(7, cost_function); /// /// // Consume `metering` to produce `middleware`. diff --git a/lib/c-api/src/wasm_c_api/unstable/middlewares/mod.rs b/lib/c-api/src/wasm_c_api/unstable/middlewares/mod.rs index 6a1c86daa40..d9bd52121c7 100644 --- a/lib/c-api/src/wasm_c_api/unstable/middlewares/mod.rs +++ b/lib/c-api/src/wasm_c_api/unstable/middlewares/mod.rs @@ -12,8 +12,8 @@ compile_error!("The `middlewares` feature requires the `compiler` feature to be /// Opaque representing any kind of middleware. /// -/// It's used by `wasm_config_push_middleware`. A specific middleware -/// is transformed into this type to get a generic middleware. See for +/// Used by `wasm_config_push_middleware`. A specific middleware is +/// transformed into this type to get a generic middleware. See for /// example /// [`wasmer_metering_as_middleware`][metering::wasmer_metering_as_middleware]. #[derive(Debug)] From d3f7b7ef70376767ae9b12295c8f435735d5a828 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Fri, 5 Mar 2021 00:57:40 +0100 Subject: [PATCH 33/34] chore(c-api) Change `operator` to `wasm_operator` (reserved keyword in C++). --- .../src/wasm_c_api/unstable/middlewares/metering.rs | 11 ++++++----- lib/c-api/wasmer_wasm.h | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs b/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs index b0cf22f30c3..7dbac3759d3 100644 --- a/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs +++ b/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs @@ -14,8 +14,8 @@ //! # #include "tests/wasmer_wasm.h" //! # //! // Define our “cost function”. -//! uint64_t cost_function(wasmer_parser_operator_t operator) { -//! switch(operator) { +//! uint64_t cost_function(wasmer_parser_operator_t wasm_operator) { +//! switch(wasm_operator) { //! // `local.get` and `i32.const` cost 1 unit. //! case LocalGet: //! case I32Const: @@ -160,7 +160,8 @@ pub struct wasmer_metering_t { /// /// See module's documentation. #[allow(non_camel_case_types)] -pub type wasmer_metering_cost_function_t = extern "C" fn(operator: wasmer_parser_operator_t) -> u64; +pub type wasmer_metering_cost_function_t = + extern "C" fn(wasm_operator: wasmer_parser_operator_t) -> u64; /// Creates a new metering middleware with an initial limit, i.e. a /// total number of operators to execute (regarding their respective @@ -234,8 +235,8 @@ pub extern "C" fn wasmer_metering_points_are_exhausted(instance: &wasm_instance_ /// # #include "tests/wasmer_wasm.h" /// # /// // Define a dummy “cost function”. -/// uint64_t cost_function(wasmer_parser_operator_t operator) { -/// switch(operator) { +/// uint64_t cost_function(wasmer_parser_operator_t wasm_operator) { +/// switch(wasm_operator) { /// default: /// return 0; /// } diff --git a/lib/c-api/wasmer_wasm.h b/lib/c-api/wasmer_wasm.h index beedd9c0c06..21721a4ef34 100644 --- a/lib/c-api/wasmer_wasm.h +++ b/lib/c-api/wasmer_wasm.h @@ -664,7 +664,7 @@ typedef struct wasmer_named_extern_vec_t { } wasmer_named_extern_vec_t; #endif -typedef uint64_t (*wasmer_metering_cost_function_t)(enum wasmer_parser_operator_t operator); +typedef uint64_t (*wasmer_metering_cost_function_t)(enum wasmer_parser_operator_t wasm_operator); #ifdef __cplusplus extern "C" { From 21ea09f8ff09faa544a467598ba6319b0be8bcb5 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Fri, 5 Mar 2021 01:03:54 +0100 Subject: [PATCH 34/34] chore(c-api) Fix merge conflicts. --- lib/c-api/build.rs | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/lib/c-api/build.rs b/lib/c-api/build.rs index 1f899c076f9..06eacfa2908 100644 --- a/lib/c-api/build.rs +++ b/lib/c-api/build.rs @@ -476,28 +476,6 @@ fn exclude_items_from_wasm_c_api(builder: Builder) -> Builder { .exclude_item("wasm_config_set_engine") .exclude_item("wasm_config_set_features") .exclude_item("wasm_config_set_target") - .exclude_item("wasm_cpu_features_add") - .exclude_item("wasm_cpu_features_delete") - .exclude_item("wasm_cpu_features_new") - .exclude_item("wasm_cpu_features_t") - .exclude_item("wasm_module_name") - .exclude_item("wasm_module_set_name") - .exclude_item("wasm_named_extern_module") - .exclude_item("wasm_named_extern_name") - .exclude_item("wasm_named_extern_t") - .exclude_item("wasm_named_extern_unwrap") - .exclude_item("wasm_named_extern_vec_copy") - .exclude_item("wasm_named_extern_vec_delete") - .exclude_item("wasm_named_extern_vec_new") - .exclude_item("wasm_named_extern_vec_new_empty") - .exclude_item("wasm_named_extern_vec_new_uninitialized") - .exclude_item("wasm_target_delete") - .exclude_item("wasm_target_new") - .exclude_item("wasm_target_t") - .exclude_item("wasm_triple_delete") - .exclude_item("wasm_triple_new") - .exclude_item("wasm_triple_new_from_host") - .exclude_item("wasm_triple_t") .exclude_item("wasmer_compiler_t") .exclude_item("wasmer_cpu_features_add") .exclude_item("wasmer_cpu_features_delete")