Skip to content

Commit

Permalink
Merge #3072
Browse files Browse the repository at this point in the history
3072: Add back `Function::*_with_env(…)` r=silwol a=silwol

<!-- 
Prior to submitting a PR, review the CONTRIBUTING.md document for recommendations on how to test:
https://github.com/wasmerio/wasmer/blob/master/CONTRIBUTING.md#pull-requests

-->

Closes: #3064

# Description
<!-- 
Provide details regarding the change including motivation,
links to related issues, and the context of the PR.
-->

# Review

- [x] Add a short description of the change to the CHANGELOG.md file


Co-authored-by: Wolfgang Silbermayr <wolfgang@silbermayr.at>
  • Loading branch information
bors[bot] and silwol authored Aug 5, 2022
2 parents 663f922 + dcb3497 commit ced8378
Show file tree
Hide file tree
Showing 70 changed files with 1,867 additions and 1,628 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ Looking for changes that affect our C API? See the [C API Changelog](lib/c-api/C
- [#3048](https://github.com/wasmerio/wasmer/pull/3048) Automatically publish wasmer as "cloudcompiler" package to wapm.dev on every release
- [#3075](https://github.com/wasmerio/wasmer/pull/3075) Remove __wbindgen_thread_id

- [#3072](https://github.com/wasmerio/wasmer/pull/3072) Add back `Function::*_with_env(…)` functions

### Fixed

## 3.0.0-alpha.4 - 2022/07/28
Expand Down
9 changes: 7 additions & 2 deletions docs/migration_to_3.0.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,13 @@ This version introduces the following changes to make the Wasmer API more ergono

1. `ImportsObject` and the traits `Resolver`, `NamedResolver`, etc have been removed and replaced with a single simple type `Imports`. This reduces the complexity of setting up an `Instance`. The helper macro `imports!` can still be used.
2. The `Store` will keep track of all memory and functions used, removing old tracking and Weak/Strong pointer usage. Every function and memory that can be defined is associated to a specific `Store`, and cannot be mixed with another `Store`
3. `WasmerEnv` and associated traits and macro have been removed. To use a function environment, you will need to create a `FunctionEnv` object and pass it along when you construct the function. The environment can be retrieved from the first argument of the function. All functions now takes a mandatory first argument that is of type `FunctionEnvMut<'_, _>`, with `_` being either nothing `()` or the defined environment type. The function creation `XXX_with_env(...)` don't exist anymore, simply use `Function::new(...)` or `Function::native_new(...)` with the correct `FunctionEnv<_>` type. Because the `WasmerEnv` and all helpers don't exists anymore, you have to import memory yourself, there isn't any per instance initialisation automatically done anymore. It's especially important in wasi use with `WasiEnv`. `Env` can be accessed from a `FunctionEnvMut<'_, WasiEnv>` using `FunctionEnvMut::data()` or `FunctionEnvMut::data_mut()`.
4. The `Engine`s API has been simplified, Instead of the user choosing and setting up an engine explicitly, everything now uses a single engine. All functionalities of the `universal`, `staticlib` and `dylib` engines should be available in this new engine unless explicitly stated as unsupported.
3. `NativeFunc` has been renamed to `TypedFunction`, accordingly the following functions have been renamed:
* `Function::native(…)``Function::typed(…)`
* `Function::new_native(…)``Function::new_typed(…)`
* `Function::new_native_with_env(…)``Function::new_typed_with_env(…)`
The previous variants still exist in order to support the migration, but they have been deprecated.
4. `WasmerEnv` and associated traits and macro have been removed. To use a function environment, you will need to create a `FunctionEnv` object and pass it along when you construct the function. For convenience, these functions also exist in a variant without the environment for simpler use cases that don't need it. For the variants with the environment, it can be retrieved from the first argument of the function. Because the `WasmerEnv` and all helpers don't exists anymore, you have to import memory yourself, there isn't any per instance initialisation automatically done anymore. It's especially important in wasi use with `WasiEnv`. `Env` can be accessed from a `FunctionEnvMut<'_, WasiEnv>` using `FunctionEnvMut::data()` or `FunctionEnvMut::data_mut()`.
5. The `Engine`s API has been simplified, Instead of the user choosing and setting up an engine explicitly, everything now uses a single engine. All functionalities of the `universal`, `staticlib` and `dylib` engines should be available in this new engine unless explicitly stated as unsupported.

## How to use Wasmer 3.0.0

Expand Down
10 changes: 3 additions & 7 deletions examples/early_exit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,7 @@
use anyhow::bail;
use std::fmt;
use wasmer::{
imports, wat2wasm, Function, FunctionEnv, FunctionEnvMut, Instance, Module, Store,
TypedFunction,
};
use wasmer::{imports, wat2wasm, Function, Instance, Module, Store, TypedFunction};
use wasmer_compiler_cranelift::Cranelift;

// First we need to create an error type that we'll use to signal the end of execution.
Expand Down Expand Up @@ -58,22 +55,21 @@ fn main() -> anyhow::Result<()> {
// the default provided by Wasmer.
// You can use `Store::default()` for that.
let mut store = Store::new(Cranelift::default());
let env = FunctionEnv::new(&mut store, ());

println!("Compiling module...");
// Let's compile the Wasm module.
let module = Module::new(&store, wasm_bytes)?;

// We declare the host function that we'll use to terminate execution.
fn early_exit(_env: FunctionEnvMut<()>) -> Result<(), ExitCode> {
fn early_exit() -> Result<(), ExitCode> {
// This is where it happens.
Err(ExitCode(1))
}

// Create an import object.
let import_object = imports! {
"env" => {
"early_exit" => Function::new_native(&mut store, &env, early_exit),
"early_exit" => Function::new_typed(&mut store, early_exit),
}
};

Expand Down
2 changes: 1 addition & 1 deletion examples/engine_headless.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
//! Ready?
use tempfile::NamedTempFile;
use wasmer::{imports, wat2wasm, EngineBuilder, FunctionEnv, Instance, Module, Store, Value};
use wasmer::{imports, wat2wasm, EngineBuilder, Instance, Module, Store, Value};
use wasmer_compiler_cranelift::Cranelift;

fn main() -> Result<(), Box<dyn std::error::Error>> {
Expand Down
4 changes: 2 additions & 2 deletions examples/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
//!
//! Ready?
use wasmer::{imports, wat2wasm, FunctionEnv, Instance, Module, Store, TypedFunction};
use wasmer::{imports, wat2wasm, Instance, Module, Store, TypedFunction};
use wasmer_compiler_cranelift::Cranelift;

fn main() -> Result<(), Box<dyn std::error::Error>> {
Expand Down Expand Up @@ -61,7 +61,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let div_by_zero: TypedFunction<(), i32> = instance
.exports
.get_function("div_by_zero")?
.native(&mut store)?;
.typed(&mut store)?;

println!("Calling `div_by_zero` function...");
// Let's call the `div_by_zero` exported function.
Expand Down
8 changes: 4 additions & 4 deletions examples/exports_function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
//!
//! Ready?
use wasmer::{imports, wat2wasm, FunctionEnv, Instance, Module, Store, TypedFunction, Value};
use wasmer::{imports, wat2wasm, Instance, Module, Store, TypedFunction, Value};
use wasmer_compiler_cranelift::Cranelift;

fn main() -> Result<(), Box<dyn std::error::Error>> {
Expand Down Expand Up @@ -81,17 +81,17 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
// that's possible with the `TypedFunction` API. The function
// will use native Rust values.
//
// Note that `native` takes 2 generic parameters: `Args` and
// Note that `typed` takes 2 generic parameters: `Args` and
// `Rets`, respectively for the parameters and the results. If
// those values don't match the exported function signature, an
// error will be raised.
let sum_native: TypedFunction<(i32, i32), i32> = sum.native(&mut store)?;
let sum_typed: TypedFunction<(i32, i32), i32> = sum.typed(&mut store)?;

println!("Calling `sum` function (natively)...");
// Let's call the `sum` exported function. The parameters are
// statically typed Rust values of type `i32` and `i32`. The
// result, in this case particular case, in a unit of type `i32`.
let result = sum_native.call(&mut store, 3, 4)?;
let result = sum_typed.call(&mut store, 3, 4)?;

println!("Results: {:?}", result);
assert_eq!(result, 7);
Expand Down
8 changes: 3 additions & 5 deletions examples/exports_global.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@
//!
//! Ready?
use wasmer::{
imports, wat2wasm, FunctionEnv, Instance, Module, Mutability, Store, Type, TypedFunction, Value,
};
use wasmer::{imports, wat2wasm, Instance, Module, Mutability, Store, Type, TypedFunction, Value};
use wasmer_compiler_cranelift::Cranelift;

fn main() -> Result<(), Box<dyn std::error::Error>> {
Expand Down Expand Up @@ -92,7 +90,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let get_one: TypedFunction<(), f32> = instance
.exports
.get_function("get_one")?
.native(&mut store)?;
.typed(&mut store)?;

let one_value = get_one.call(&mut store)?;
let some_value = some.get(&mut store);
Expand Down Expand Up @@ -124,7 +122,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let set_some: TypedFunction<f32, ()> = instance
.exports
.get_function("set_some")?
.native(&mut store)?;
.typed(&mut store)?;
set_some.call(&mut store, 21.0)?;
let some_result = some.get(&mut store);
println!("`some` value after `set_some`: {:?}", some_result);
Expand Down
8 changes: 3 additions & 5 deletions examples/exports_memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
//!
//! Ready?
use wasmer::{imports, wat2wasm, FunctionEnv, Instance, Module, Store, TypedFunction, WasmPtr};
use wasmer::{imports, wat2wasm, Instance, Module, Store, TypedFunction, WasmPtr};
use wasmer_compiler_cranelift::Cranelift;

fn main() -> Result<(), Box<dyn std::error::Error>> {
Expand Down Expand Up @@ -56,7 +56,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
//
// The Wasm module exports a memory under "mem". Let's get it.
let memory = instance.exports.get_memory("mem")?;

// Now that we have the exported memory, let's get some
// information about it.
//
Expand All @@ -80,9 +80,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
// We will get bytes out of the memory so we need to
// decode them into a string.
let memory_view = memory.view(&store);
let str = ptr
.read_utf8_string(&memory_view, length as u32)
.unwrap();
let str = ptr.read_utf8_string(&memory_view, length as u32).unwrap();
println!("Memory contents: {:?}", str);

// What about changing the contents of the memory with a more
Expand Down
4 changes: 1 addition & 3 deletions examples/features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@
//!
//! Ready?
use wasmer::{
imports, wat2wasm, EngineBuilder, Features, FunctionEnv, Instance, Module, Store, Value,
};
use wasmer::{imports, wat2wasm, EngineBuilder, Features, Instance, Module, Store, Value};
use wasmer_compiler_cranelift::Cranelift;

fn main() -> anyhow::Result<()> {
Expand Down
13 changes: 3 additions & 10 deletions examples/hello_world.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,7 @@
//! cargo run --example hello-world --release --features "cranelift"
//! ```
use wasmer::{
imports, wat2wasm, Function, FunctionEnv, FunctionEnvMut, Instance, Module, Store,
TypedFunction,
};
use wasmer::{imports, wat2wasm, Function, Instance, Module, Store, TypedFunction};
use wasmer_compiler_cranelift::Cranelift;

fn main() -> anyhow::Result<()> {
Expand Down Expand Up @@ -52,13 +49,9 @@ fn main() -> anyhow::Result<()> {
// A `Module` is a compiled WebAssembly module that isn't ready to execute yet.
let module = Module::new(&store, wasm_bytes)?;

// Next we'll set up our `Module` so that we can execute it. First, create
// a `FunctionEnv` in which to instantiate our `Module`.
let context = FunctionEnv::new(&mut store, ());

// We define a function to act as our "env" "say_hello" function imported in the
// Wasm program above.
fn say_hello_world(_env: FunctionEnvMut<'_, ()>) {
fn say_hello_world() {
println!("Hello, world!")
}

Expand All @@ -67,7 +60,7 @@ fn main() -> anyhow::Result<()> {
// We use the default namespace "env".
"env" => {
// And call our function "say_hello".
"say_hello" => Function::new_native(&mut store, &context, say_hello_world),
"say_hello" => Function::new_typed(&mut store, say_hello_world),
}
};

Expand Down
7 changes: 3 additions & 4 deletions examples/imports_exports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
//! Ready?
use wasmer::{
imports, wat2wasm, Function, FunctionEnv, FunctionType, Global, Instance, Memory, Module,
Store, Table, Type, Value,
imports, wat2wasm, Function, FunctionType, Global, Instance, Memory, Module, Store, Table,
Type, Value,
};
use wasmer_compiler_cranelift::Cranelift;

Expand All @@ -44,7 +44,6 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
// the default provided by Wasmer.
// You can use `Store::default()` for that.
let mut store = Store::new(Cranelift::default());
let env = FunctionEnv::new(&mut store, ());

println!("Compiling module...");
// Let's compile the Wasm module.
Expand All @@ -59,7 +58,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
// covered in more detail in other examples.
println!("Creating the imported function...");
let host_function_signature = FunctionType::new(vec![], vec![Type::I32]);
let host_function = Function::new(&mut store, &env, &host_function_signature, |_env, _args| {
let host_function = Function::new(&mut store, &host_function_signature, |_args| {
Ok(vec![Value::I32(42)])
});

Expand Down
34 changes: 14 additions & 20 deletions examples/imports_function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
br#"
(module
(func $multiply_dynamic (import "env" "multiply_dynamic") (param i32) (result i32))
(func $multiply_native (import "env" "multiply_native") (param i32) (result i32))
(func $multiply_typed (import "env" "multiply_typed") (param i32) (result i32))
(type $sum_t (func (param i32) (param i32) (result i32)))
(func $sum_f (type $sum_t) (param $x i32) (param $y i32) (result i32)
(call $multiply_dynamic (local.get $x))
(call $multiply_native (local.get $y))
(call $multiply_typed (local.get $y))
i32.add)
(export "sum" (func $sum_f)))
"#,
Expand All @@ -45,46 +45,40 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
// the default provided by Wasmer.
// You can use `Store::default()` for that.
let mut store = Store::new(Cranelift::default());
let env1 = FunctionEnv::new(&mut store, ());
struct MyEnv;
let env2 = FunctionEnv::new(&mut store, MyEnv {});
let env = FunctionEnv::new(&mut store, MyEnv {});

println!("Compiling module...");
// Let's compile the Wasm module.
let module = Module::new(&store, wasm_bytes)?;

// Create the functions
let multiply_dynamic_signature = FunctionType::new(vec![Type::I32], vec![Type::I32]);
let multiply_dynamic = Function::new(
&mut store,
&env1,
&multiply_dynamic_signature,
|_env, args| {
println!("Calling `multiply_dynamic`...");
let multiply_dynamic = Function::new(&mut store, &multiply_dynamic_signature, |args| {
println!("Calling `multiply_dynamic`...");

let result = args[0].unwrap_i32() * 2;
let result = args[0].unwrap_i32() * 2;

println!("Result of `multiply_dynamic`: {:?}", result);
println!("Result of `multiply_dynamic`: {:?}", result);

Ok(vec![Value::I32(result)])
},
);
Ok(vec![Value::I32(result)])
});

fn multiply(_env: FunctionEnvMut<MyEnv>, a: i32) -> i32 {
println!("Calling `multiply_native`...");
println!("Calling `multiply_typed`...");
let result = a * 3;

println!("Result of `multiply_native`: {:?}", result);
println!("Result of `multiply_typed`: {:?}", result);

result
}
let multiply_native = Function::new_native(&mut store, &env2, multiply);
let multiply_typed = Function::new_typed_with_env(&mut store, &env, multiply);

// Create an import object.
let import_object = imports! {
"env" => {
"multiply_dynamic" => multiply_dynamic,
"multiply_native" => multiply_native,
"multiply_typed" => multiply_typed,
}
};

Expand All @@ -96,7 +90,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
//
// The Wasm module exports a function called `sum`. Let's get it.
let sum: TypedFunction<(i32, i32), i32> =
instance.exports.get_function("sum")?.native(&mut store)?;
instance.exports.get_function("sum")?.typed(&mut store)?;

println!("Calling `sum` function...");
// Let's call the `sum` exported function. It will call each
Expand Down
6 changes: 3 additions & 3 deletions examples/imports_function_env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
// Create an import object.
let import_object = imports! {
"env" => {
"get_counter" => Function::new_native(&mut store, &env, get_counter),
"add_to_counter" => Function::new_native(&mut store, &env, add_to_counter),
"get_counter" => Function::new_typed_with_env(&mut store, &env, get_counter),
"add_to_counter" => Function::new_typed_with_env(&mut store, &env, add_to_counter),
}
};

Expand All @@ -112,7 +112,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let increment_counter_loop: TypedFunction<i32, i32> = instance
.exports
.get_function("increment_counter_loop")?
.native(&mut store)?;
.typed(&mut store)?;

let counter_value: i32 = *shared_counter.lock().unwrap();
println!("Initial ounter value: {:?}", counter_value);
Expand Down
10 changes: 4 additions & 6 deletions examples/imports_global.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@
//!
//! Ready?
use wasmer::{
imports, wat2wasm, FunctionEnv, Global, Instance, Module, Store, TypedFunction, Value,
};
use wasmer::{imports, wat2wasm, Global, Instance, Module, Store, TypedFunction, Value};
use wasmer_compiler_cranelift::Cranelift;

fn main() -> Result<(), Box<dyn std::error::Error>> {
Expand Down Expand Up @@ -69,11 +67,11 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let get_some: TypedFunction<(), f32> = instance
.exports
.get_function("get_some")?
.native(&mut store)?;
.typed(&mut store)?;
let get_other: TypedFunction<(), f32> = instance
.exports
.get_function("get_other")?
.native(&mut store)?;
.typed(&mut store)?;

let some_result = get_some.call(&mut store)?;
let other_result = get_other.call(&mut store)?;
Expand Down Expand Up @@ -106,7 +104,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let set_other: TypedFunction<f32, ()> = instance
.exports
.get_function("set_other")?
.native(&mut store)?;
.typed(&mut store)?;
set_other.call(&mut store, 42.0)?;

println!("other value (via Global API): {:?}", other.get(&mut store));
Expand Down
Loading

0 comments on commit ced8378

Please sign in to comment.