You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

34 lines
872 B

use anyhow::{Context as _, Result};
use wasmtime::*;
#[test]
fn test_invoke_func_via_table() -> Result<()> {
let mut store = Store::<()>::default();
Support parsing the text format in `wasmtime` crate (#813) * Support parsing the text format in `wasmtime` crate This commit adds support to the `wasmtime::Module` type to parse the text format. This is often quite convenient to support in testing or tinkering with the runtime. Additionally the `wat` parser is pretty lightweight and easy to add to builds, so it&#39;s relatively easy for us to support as well! The exact manner that this is now supported comes with a few updates to the existing API: * A new optional feature of the `wasmtime` crate, `wat`, has been added. This is enabled by default. * The `Module::new` API now takes `impl AsRef&lt;[u8]&gt;` instead of just `&amp;[u8]`, and when the `wat` feature is enabled it will attempt to interpret it either as a wasm binary or as the text format. Note that this check is quite cheap since you just check the first byte. * A `Module::from_file` API was added as a convenience to parse a file from disk, allowing error messages for `*.wat` files on disk to be a bit nicer. * APIs like `Module::new_unchecked` and `Module::validate` remain unchanged, they require the binary format to be called. The intention here is to make this as convenient as possible for new developers of the `wasmtime` crate. By changing the default behavior though this has ramifications such as, for example, supporting the text format implicitly through the C API now. * Handle review comments * Update more tests to avoid usage of `wat` crate * Go back to unchecked for now in wasm_module_new Looks like C# tests rely on this?
5 years ago
let wat = r#"
(module
(func $f (result i64) (i64.const 42))
Support parsing the text format in `wasmtime` crate (#813) * Support parsing the text format in `wasmtime` crate This commit adds support to the `wasmtime::Module` type to parse the text format. This is often quite convenient to support in testing or tinkering with the runtime. Additionally the `wat` parser is pretty lightweight and easy to add to builds, so it&#39;s relatively easy for us to support as well! The exact manner that this is now supported comes with a few updates to the existing API: * A new optional feature of the `wasmtime` crate, `wat`, has been added. This is enabled by default. * The `Module::new` API now takes `impl AsRef&lt;[u8]&gt;` instead of just `&amp;[u8]`, and when the `wat` feature is enabled it will attempt to interpret it either as a wasm binary or as the text format. Note that this check is quite cheap since you just check the first byte. * A `Module::from_file` API was added as a convenience to parse a file from disk, allowing error messages for `*.wat` files on disk to be a bit nicer. * APIs like `Module::new_unchecked` and `Module::validate` remain unchanged, they require the binary format to be called. The intention here is to make this as convenient as possible for new developers of the `wasmtime` crate. By changing the default behavior though this has ramifications such as, for example, supporting the text format implicitly through the C API now. * Handle review comments * Update more tests to avoid usage of `wat` crate * Go back to unchecked for now in wasm_module_new Looks like C# tests rely on this?
5 years ago
(table (export "table") 1 1 anyfunc)
(elem (i32.const 0) $f)
)
"#;
let module = Module::new(store.engine(), wat).context("> Error compiling module!")?;
let instance =
Instance::new(&mut store, &module, &[]).context("> Error instantiating module!")?;
let f = instance
.get_table(&mut store, "table")
.unwrap()
.get(&mut store, 0)
Document and update the API of the `externals.rs` module (#812) * Document and update the API of the `externals.rs` module This commit ensures that all public methods and items are documented in the `externals.rs` module, notably all external values that can be imported and exported in WebAssembly. Along the way this also tidies up the API and fixes a few bugs: * `Global::new` now returns a `Result` and fails if the provided value does not match the type of the global. * `Global::set` now returns a `Result` and fails if the global is either immutable or the provided value doesn&#39;t match the type of the global. * `Table::new` now fails if the provided initializer does not match the element type. * `Table::get` now returns `Option&lt;Val&gt;` instead of implicitly returning null. * `Table::set` now returns `Result&lt;()&gt;`, returning an error on out of bounds or if the input type is of the wrong type. * `Table::grow` now returns `Result&lt;u32&gt;`, returning the previous number of table elements if succesful or an error if the maximum is reached or the initializer value is of the wrong type. Additionally a bug was fixed here where if the wrong initializer was provided the table would be grown still, but initialization would fail. * `Memory::data` was renamed to `Memory::data_unchecked_mut`. Additionally `Memory::data_unchecked` was added. Lots of caveats were written down about how using the method can go wrong. * `Memory::grow` now returns `Result&lt;u32&gt;`, returning an error if growth fails or the number of pages previous the growth if successful. * Run rustfmt * Fix another test * Update crates/api/src/externals.rs Co-Authored-By: Sergei Pepyakin &lt;s.pepyakin@gmail.com&gt; Co-authored-by: Sergei Pepyakin &lt;s.pepyakin@gmail.com&gt;
5 years ago
.unwrap()
.funcref()
.unwrap()
.unwrap()
.clone();
Optimize `Func::call` and its C API (#3319) * Optimize `Func::call` and its C API This commit is an alternative to #3298 which achieves effectively the same goal of optimizing the `Func::call` API as well as its C API sibling of `wasmtime_func_call`. The strategy taken here is different than #3298 though where a new API isn&#39;t created, rather a small tweak to an existing API is done. Specifically this commit handles the major sources of slowness with `Func::call` with: * Looking up the type of a function, to typecheck the arguments with and use to guide how the results should be loaded, no longer hits the rwlock in the `Engine` but instead each `Func` contains its own `FuncType`. This can be an unnecessary allocation for funcs not used with `Func::call`, so this is a downside of this implementation relative to #3298. A mitigating factor, though, is that instance exports are loaded lazily into the `Store` and in theory not too many funcs are active in the store as `Func` objects. * Temporary storage is amortized with a long-lived `Vec` in the `Store` rather than allocating a new vector on each call. This is basically the same strategy as #3294 only applied to different types in different places. Specifically `wasmtime::Store` now retains a `Vec&lt;u128&gt;` for `Func::call`, and the C API retains a `Vec&lt;Val&gt;` for calling `Func::call`. * Finally, an API breaking change is made to `Func::call` and its type signature (as well as `Func::call_async`). Instead of returning `Box&lt;[Val]&gt;` as it did before this function now takes a `results: &amp;mut [Val]` parameter. This allows the caller to manage the allocation and we can amortize-remove it in `wasmtime_func_call` by using space after the parameters in the `Vec&lt;Val&gt;` we&#39;re passing in. This change is naturally a breaking change and we&#39;ll want to consider it carefully, but mitigating factors are that most embeddings are likely using `TypedFunc::call` instead and this signature taking a mutable slice better aligns with `Func::new` which receives a mutable slice for the results. Overall this change, in the benchmark of &#34;call a nop function from the C API&#34; is not quite as good as #3298. It&#39;s still a bit slower, on the order of 15ns, because there&#39;s lots of capacity checks around vectors and the type checks are slightly less optimized than before. Overall though this is still significantly better than today because allocations and the rwlock to acquire the type information are both avoided. I personally feel that this change is the best to do because it has less of an API impact than #3298. * Rebase issues
3 years ago
let mut results = [Val::I32(0)];
f.call(&mut store, &[], &mut results).unwrap();
assert_eq!(results[0].unwrap_i64(), 42);
Ok(())
}