mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-09 06:08:29 +00:00
Merge branch 'master' into test-c-api-inline-c-rs
This commit is contained in:
14
CHANGELOG.md
14
CHANGELOG.md
@@ -7,7 +7,7 @@
|
||||
|
||||
## **[Unreleased]**
|
||||
|
||||
- [#1710](https://github.com/wasmerio/wasmer/pull/1710) Memory for function call trampolines is now owned by the Artifact.
|
||||
## 1.0.0-alpha5 - 2020-11-06
|
||||
|
||||
### Added
|
||||
|
||||
@@ -22,15 +22,26 @@
|
||||
- [#1715](https://github.com/wasmerio/wasmer/pull/1715) Register errors from `wasm_module_serialize` in the Wasm C API.
|
||||
- [#1709](https://github.com/wasmerio/wasmer/pull/1709) Implement `wasm_module_name` and `wasm_module_set_name` in the Wasm(er) C API.
|
||||
- [#1700](https://github.com/wasmerio/wasmer/pull/1700) Implement `wasm_externtype_copy` in the Wasm C API.
|
||||
- [#1785](https://github.com/wasmerio/wasmer/pull/1785) Add more examples on the Rust API.
|
||||
- [#1783](https://github.com/wasmerio/wasmer/pull/1783) Handle initialized but empty results in `wasm_func_call` in the Wasm C API.
|
||||
- [#1780](https://github.com/wasmerio/wasmer/pull/1780) Implement new SIMD zero-extend loads in compiler-llvm.
|
||||
- [#1754](https://github.com/wasmerio/wasmer/pull/1754) Implement aarch64 ABI for compiler-llvm.
|
||||
- [#1693](https://github.com/wasmerio/wasmer/pull/1693) Add `wasmer create-exe` subcommand.
|
||||
|
||||
### Changed
|
||||
|
||||
- [#1772](https://github.com/wasmerio/wasmer/pull/1772) Remove lifetime parameter from `NativeFunc`.
|
||||
- [#1762](https://github.com/wasmerio/wasmer/pull/1762) Allow the `=` sign in a WASI environment variable value.
|
||||
- [#1710](https://github.com/wasmerio/wasmer/pull/1710) Memory for function call trampolines is now owned by the Artifact.
|
||||
- [#1781](https://github.com/wasmerio/wasmer/pull/1781) Cranelift upgrade to 0.67.
|
||||
- [#1777](https://github.com/wasmerio/wasmer/pull/1777) Wasmparser update to 0.65.
|
||||
- [#1775](https://github.com/wasmerio/wasmer/pull/1775) Improve LimitingTunables implementation.
|
||||
- [#1720](https://github.com/wasmerio/wasmer/pull/1720) Autodetect llvm regardless of architecture.
|
||||
|
||||
### Fixed
|
||||
|
||||
- [#1718](https://github.com/wasmerio/wasmer/pull/1718) Fix panic in the API in some situations when the memory's min bound was greater than the memory's max bound.
|
||||
- [#1731](https://github.com/wasmerio/wasmer/pull/1731) In compiler-llvm always load before store, to trigger any traps before any bytes are written.
|
||||
|
||||
## 1.0.0-alpha4 - 2020-10-08
|
||||
|
||||
@@ -43,6 +54,7 @@
|
||||
- [#1690](https://github.com/wasmerio/wasmer/pull/1690) Fix `wasm_memorytype_limits` where `min` and `max` represents pages, not bytes. Additionally, fixes the max limit sentinel value.
|
||||
- [#1671](https://github.com/wasmerio/wasmer/pull/1671) Fix probestack firing inappropriately, and sometimes over/under allocating stack.
|
||||
- [#1660](https://github.com/wasmerio/wasmer/pull/1660) Fix issue preventing map-dir aliases starting with `/` from working properly.
|
||||
- [#1624](https://github.com/wasmerio/wasmer/pull/1624) Add Value::I32/Value::I64 converters from unsigned ints.
|
||||
|
||||
### Changed
|
||||
- [#1682](https://github.com/wasmerio/wasmer/pull/1682) Improve error reporting when making a memory with invalid settings.
|
||||
|
||||
43
Cargo.toml
43
Cargo.toml
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "wasmer-workspace"
|
||||
version = "1.0.0-alpha4"
|
||||
version = "1.0.0-alpha5"
|
||||
description = "Wasmer workspace"
|
||||
authors = ["Wasmer Engineering Team <engineering@wasmer.io>"]
|
||||
repository = "https://github.com/wasmerio/wasmer"
|
||||
@@ -10,19 +10,19 @@ publish = false
|
||||
autoexamples = false
|
||||
|
||||
[dependencies]
|
||||
wasmer = { version = "1.0.0-alpha4", path = "lib/api", default-features = false }
|
||||
wasmer-compiler = { version = "1.0.0-alpha4", path = "lib/compiler" }
|
||||
wasmer-compiler-cranelift = { version = "1.0.0-alpha4", path = "lib/compiler-cranelift", optional = true }
|
||||
wasmer-compiler-singlepass = { version = "1.0.0-alpha4", path = "lib/compiler-singlepass", optional = true }
|
||||
wasmer-compiler-llvm = { version = "1.0.0-alpha4", path = "lib/compiler-llvm", optional = true }
|
||||
wasmer-engine = { version = "1.0.0-alpha4", path = "lib/engine" }
|
||||
wasmer-engine-jit = { version = "1.0.0-alpha4", path = "lib/engine-jit", optional = true }
|
||||
wasmer-engine-native = { version = "1.0.0-alpha4", path = "lib/engine-native", optional = true }
|
||||
wasmer-engine-object-file = { version = "1.0.0-alpha4", path = "lib/engine-object-file", optional = true }
|
||||
wasmer-wasi = { version = "1.0.0-alpha4", path = "lib/wasi", optional = true }
|
||||
wasmer-wast = { version = "1.0.0-alpha4", path = "tests/lib/wast", optional = true }
|
||||
wasmer-cache = { version = "1.0.0-alpha4", path = "lib/cache", optional = true }
|
||||
wasmer-types = { version = "1.0.0-alpha4", path = "lib/wasmer-types" }
|
||||
wasmer = { version = "1.0.0-alpha5", path = "lib/api", default-features = false }
|
||||
wasmer-compiler = { version = "1.0.0-alpha5", path = "lib/compiler" }
|
||||
wasmer-compiler-cranelift = { version = "1.0.0-alpha5", path = "lib/compiler-cranelift", optional = true }
|
||||
wasmer-compiler-singlepass = { version = "1.0.0-alpha5", path = "lib/compiler-singlepass", optional = true }
|
||||
wasmer-compiler-llvm = { version = "1.0.0-alpha5", path = "lib/compiler-llvm", optional = true }
|
||||
wasmer-engine = { version = "1.0.0-alpha5", path = "lib/engine" }
|
||||
wasmer-engine-jit = { version = "1.0.0-alpha5", path = "lib/engine-jit", optional = true }
|
||||
wasmer-engine-native = { version = "1.0.0-alpha5", path = "lib/engine-native", optional = true }
|
||||
wasmer-engine-object-file = { version = "1.0.0-alpha5", path = "lib/engine-object-file", optional = true }
|
||||
wasmer-wasi = { version = "1.0.0-alpha5", path = "lib/wasi", optional = true }
|
||||
wasmer-wast = { version = "1.0.0-alpha5", path = "tests/lib/wast", optional = true }
|
||||
wasmer-cache = { version = "1.0.0-alpha5", path = "lib/cache", optional = true }
|
||||
wasmer-types = { version = "1.0.0-alpha5", path = "lib/wasmer-types" }
|
||||
cfg-if = "1.0"
|
||||
|
||||
[workspace]
|
||||
@@ -230,3 +230,18 @@ required-features = ["cranelift"]
|
||||
name = "memory"
|
||||
path = "examples/memory.rs"
|
||||
required-features = ["cranelift"]
|
||||
|
||||
[[example]]
|
||||
name = "instance"
|
||||
path = "examples/instance.rs"
|
||||
required-features = ["cranelift"]
|
||||
|
||||
[[example]]
|
||||
name = "errors"
|
||||
path = "examples/errors.rs"
|
||||
required-features = ["cranelift"]
|
||||
|
||||
[[example]]
|
||||
name = "imported-function-env"
|
||||
path = "examples/imports_function_env.rs"
|
||||
required-features = ["cranelift"]
|
||||
|
||||
@@ -134,7 +134,7 @@ qjs >
|
||||
[js logo]: ./assets/languages/js.svg
|
||||
[js integration]: https://github.com/wasmerio/wasmer-js
|
||||
[`@wasmerio` npm packages]: https://www.npmjs.com/org/wasmer
|
||||
[js docs]: https://docs.wasmer.io/wasmer-js/wasmer-js
|
||||
[js docs]: https://docs.wasmer.io/integrations/js/reference-api
|
||||
|
||||
[ruby logo]: ./assets/languages/ruby.svg
|
||||
[ruby integration]: https://github.com/wasmerio/wasmer-ruby
|
||||
|
||||
@@ -37,6 +37,173 @@ The examples are written in a difficulty/discovery order. Concepts that
|
||||
are explained in an example is not necessarily re-explained in a next
|
||||
example.
|
||||
|
||||
### Basics
|
||||
|
||||
1. [**Instantiating a module**][instance], explains the basics of using Wasmer
|
||||
and how to create an instance out of a Wasm module.
|
||||
|
||||
_Keywords_: instance, module.
|
||||
|
||||
<details>
|
||||
<summary><em>Execute the example</em></summary>
|
||||
|
||||
```shell
|
||||
$ cargo run --example instance --release --features "cranelift"
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
2. [**Handling errors**][errors], explains the basics of interacting with
|
||||
Wasm module memory.
|
||||
|
||||
_Keywords_: memory, module.
|
||||
|
||||
<details>
|
||||
<summary><em>Execute the example</em></summary>
|
||||
|
||||
```shell
|
||||
$ cargo run --example memory --release --features "cranelift"
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
3. [**Interacting with memory**][memory], explains the basics of interacting with
|
||||
Wasm module memory.
|
||||
|
||||
_Keywords_: memory, module.
|
||||
|
||||
<details>
|
||||
<summary><em>Execute the example</em></summary>
|
||||
|
||||
```shell
|
||||
$ cargo run --example memory --release --features "cranelift"
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Exports
|
||||
|
||||
1. [**Exported global**][exported-global], explains how to work with
|
||||
exported globals: get/set their value, have information about their
|
||||
type.
|
||||
|
||||
_Keywords_: export, global.
|
||||
|
||||
<details>
|
||||
<summary><em>Execute the example</em></summary>
|
||||
|
||||
```shell
|
||||
$ cargo run --example exported-globals --release --features "cranelift"
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
2. [**Exported function**][exported-function], explains how to get and
|
||||
how to call an exported function. They come in 2 flavors: dynamic,
|
||||
and “static”/native. The pros and cons are discussed briefly.
|
||||
|
||||
_Keywords_: export, function, dynamic, static, native.
|
||||
|
||||
<details>
|
||||
<summary><em>Execute the example</em></summary>
|
||||
|
||||
```shell
|
||||
$ cargo run --example exported-function --release --features "cranelift"
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
|
||||
3. [**Exported memory**][exported-memory], explains how to read from
|
||||
and write to exported memory.
|
||||
|
||||
_Keywords_: export, memory.
|
||||
|
||||
<details>
|
||||
<summary><em>Execute the example</em></summary>
|
||||
|
||||
```shell
|
||||
$ cargo run --example exported-memory --release --features "cranelift"
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Imports
|
||||
|
||||
1. [**Imported global**][imported-global], explains how to work with
|
||||
imported globals: create globals, import them, get/set their value.
|
||||
|
||||
_Keywords_: import, global.
|
||||
|
||||
<details>
|
||||
<summary><em>Execute the example</em></summary>
|
||||
|
||||
```shell
|
||||
$ cargo run --example imported-globals --release --features "cranelift"
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
2. [**Imported function**][imported-function], explains how to define
|
||||
an imported function. They come in 2 flavors: dynamic,
|
||||
and “static”/native.
|
||||
|
||||
_Keywords_: import, function, dynamic, static, native.
|
||||
|
||||
<details>
|
||||
<summary><em>Execute the example</em></summary>
|
||||
|
||||
```shell
|
||||
$ cargo run --example imported-function --release --features "cranelift"
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Externs
|
||||
|
||||
1. [**Table**][table], explains how to use Wasm Tables from the Wasmer API.
|
||||
|
||||
_Keywords_: basic, table, call_indirect
|
||||
|
||||
<details>
|
||||
<summary><em>Execute the example</em></summary>
|
||||
|
||||
```shell
|
||||
$ cargo run --example table --release --features "cranelift"
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
2. [**Memory**][memory], explains how to use Wasm Memories from
|
||||
the Wasmer API. Memory example is a work in progress.
|
||||
|
||||
_Keywords_: basic, memory
|
||||
|
||||
<details>
|
||||
<summary><em>Execute the example</em></summary>
|
||||
|
||||
```shell
|
||||
$ cargo run --example memory --release --features "cranelift"
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Tunables
|
||||
|
||||
1. **Limit memory**, explains how to use Tunables to limit the
|
||||
size of an exported Wasm memory
|
||||
|
||||
_Keywords_: basic, tunables, memory
|
||||
|
||||
<details>
|
||||
<summary><em>Execute the example</em></summary>
|
||||
|
||||
```shell
|
||||
$ cargo run --example tunables-limit-memory --release --features "cranelift"
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Engines
|
||||
|
||||
1. [**JIT engine**][engine-jit], explains what an engine is, what the
|
||||
@@ -107,7 +274,7 @@ example.
|
||||
|
||||
### Compilers
|
||||
|
||||
5. [**Singlepass compiler**][compiler-singlepass], explains how to use
|
||||
1. [**Singlepass compiler**][compiler-singlepass], explains how to use
|
||||
the [`wasmer-compiler-singlepass`] compiler.
|
||||
|
||||
_Keywords_: compiler, singlepass.
|
||||
@@ -121,7 +288,7 @@ example.
|
||||
|
||||
</details>
|
||||
|
||||
6. [**Cranelift compiler**][compiler-cranelift], explains how to use
|
||||
2. [**Cranelift compiler**][compiler-cranelift], explains how to use
|
||||
the [`wasmer-compiler-cranelift`] compiler.
|
||||
|
||||
_Keywords_: compiler, cranelift.
|
||||
@@ -135,7 +302,7 @@ example.
|
||||
|
||||
</details>
|
||||
|
||||
7. [**LLVM compiler**][compiler-llvm], explains how to use the
|
||||
3. [**LLVM compiler**][compiler-llvm], explains how to use the
|
||||
[`wasmer-compiler-llvm`] compiler.
|
||||
|
||||
_Keywords_: compiler, llvm.
|
||||
@@ -149,133 +316,9 @@ example.
|
||||
|
||||
</details>
|
||||
|
||||
### Exports
|
||||
|
||||
8. [**Exported global**][exported-global], explains how to work with
|
||||
exported globals: get/set their value, have information about their
|
||||
type.
|
||||
|
||||
_Keywords_: export, global.
|
||||
|
||||
<details>
|
||||
<summary><em>Execute the example</em></summary>
|
||||
|
||||
```shell
|
||||
$ cargo run --example exported-globals --release --features "cranelift"
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
9. [**Exported function**][exported-function], explains how to get and
|
||||
how to call an exported function. They come in 2 flavors: dynamic,
|
||||
and “static”/native. The pros and cons are discussed briefly.
|
||||
|
||||
_Keywords_: export, function, dynamic, static, native.
|
||||
|
||||
<details>
|
||||
<summary><em>Execute the example</em></summary>
|
||||
|
||||
```shell
|
||||
$ cargo run --example exported-function --release --features "cranelift"
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
|
||||
10. [**Exported memory**][exported-memory], explains how to read from
|
||||
and write to exported memory.
|
||||
|
||||
_Keywords_: export, memory.
|
||||
|
||||
<details>
|
||||
<summary><em>Execute the example</em></summary>
|
||||
|
||||
```shell
|
||||
$ cargo run --example exported-memory --release --features "cranelift"
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Imports
|
||||
|
||||
11. [**Imported global**][imported-global], explains how to work with
|
||||
imported globals: create globals, import them, get/set their value.
|
||||
|
||||
_Keywords_: import, global.
|
||||
|
||||
<details>
|
||||
<summary><em>Execute the example</em></summary>
|
||||
|
||||
```shell
|
||||
$ cargo run --example imported-globals --release --features "cranelift"
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
12. [**Imported function**][imported-function], explains how to define
|
||||
an imported function. They come in 2 flavors: dynamic,
|
||||
and “static”/native.
|
||||
|
||||
_Keywords_: import, function, dynamic, static, native.
|
||||
|
||||
<details>
|
||||
<summary><em>Execute the example</em></summary>
|
||||
|
||||
```shell
|
||||
$ cargo run --example imported-function --release --features "cranelift"
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Externs
|
||||
|
||||
13. [**Table**][table], explains how to use Wasm Tables from the Wasmer API.
|
||||
|
||||
_Keywords_: basic, table, call_indirect
|
||||
|
||||
<details>
|
||||
<summary><em>Execute the example</em></summary>
|
||||
|
||||
```shell
|
||||
$ cargo run --example table --release --features "cranelift"
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
14. [**Memory**][memory], explains how to use Wasm Memories from
|
||||
the Wasmer API. Memory example is a work in progress.
|
||||
|
||||
_Keywords_: basic, memory
|
||||
|
||||
<details>
|
||||
<summary><em>Execute the example</em></summary>
|
||||
|
||||
```shell
|
||||
$ cargo run --example memory --release --features "cranelift"
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Tunables
|
||||
|
||||
15. **Limit memory**, explains how to use Tunables to limit the
|
||||
size of an exported Wasm Memories
|
||||
|
||||
_Keywords_: basic, tunables, memory
|
||||
|
||||
<details>
|
||||
<summary><em>Execute the example</em></summary>
|
||||
|
||||
```shell
|
||||
$ cargo run --example tunables-limit-memory --release --features "cranelift"
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
|
||||
### Integrations
|
||||
|
||||
16. [**WASI**][wasi], explains how to use the [WebAssembly System
|
||||
1. [**WASI**][wasi], explains how to use the [WebAssembly System
|
||||
Interface][WASI] (WASI), i.e. the [`wasmer-wasi`] crate.
|
||||
|
||||
_Keywords_: wasi, system, interface
|
||||
@@ -301,6 +344,7 @@ example.
|
||||
[exported-memory]: ./exports_memory.rs
|
||||
[imported-global]: ./imports_global.rs
|
||||
[imported-function]: ./imports_function.rs
|
||||
[instance]: ./instance.rs
|
||||
[wasi]: ./wasi.rs
|
||||
[table]: ./table.rs
|
||||
[memory]: ./memory.rs
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
//! This example shows how the host can terminate execution of Wasm early from
|
||||
//! inside a host function called by the Wasm.
|
||||
//! There are cases where you may want to interrupt this synchronous execution of the WASM module
|
||||
//! while the it is calling a host function. This can be useful for saving resources, and not
|
||||
//! returning back to the guest WASM for execution, when you already know the WASM execution will
|
||||
//! fail, or no longer be needed.
|
||||
//!
|
||||
//! In this example, we will run a WASM module that calls the imported host function
|
||||
//! interrupt_execution. This host function will immediately stop executing the WebAssembly module.
|
||||
//!
|
||||
//! You can run the example directly by executing in Wasmer root:
|
||||
//!
|
||||
//! ```shell
|
||||
//! cargo run --example early-exit --release --features "cranelift"
|
||||
//! ```
|
||||
//!
|
||||
//! Ready?
|
||||
|
||||
use anyhow::bail;
|
||||
use std::fmt;
|
||||
@@ -21,12 +34,6 @@ impl fmt::Display for ExitCode {
|
||||
// And then we implement `std::error::Error`.
|
||||
impl std::error::Error for ExitCode {}
|
||||
|
||||
// The host function that we'll use to terminate execution.
|
||||
fn early_exit() {
|
||||
// This is where it happens.
|
||||
RuntimeError::raise(Box::new(ExitCode(1)));
|
||||
}
|
||||
|
||||
fn main() -> anyhow::Result<()> {
|
||||
// Let's declare the Wasm module with the text representation.
|
||||
let wasm_bytes = wat2wasm(
|
||||
@@ -44,21 +51,40 @@ fn main() -> anyhow::Result<()> {
|
||||
"#,
|
||||
)?;
|
||||
|
||||
// Create a Store.
|
||||
// Note that we don't need to specify the engine/compiler if we want to use
|
||||
// the default provided by Wasmer.
|
||||
// You can use `Store::default()` for that.
|
||||
let store = Store::new(&JIT::new(&Cranelift::default()).engine());
|
||||
|
||||
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() {
|
||||
// This is where it happens.
|
||||
RuntimeError::raise(Box::new(ExitCode(1)));
|
||||
}
|
||||
|
||||
// Create an import object.
|
||||
let import_object = imports! {
|
||||
"env" => {
|
||||
"early_exit" => Function::new_native(&store, early_exit),
|
||||
}
|
||||
};
|
||||
|
||||
println!("Instantiating module...");
|
||||
// Let's instantiate the Wasm module.
|
||||
let instance = Instance::new(&module, &import_object)?;
|
||||
|
||||
// Here we go.
|
||||
//
|
||||
// Get the `run` function which we'll use as our entrypoint.
|
||||
let run_func: NativeFunc<(i32, i32), i32> =
|
||||
instance.exports.get_native_function("run").unwrap();
|
||||
println!("Calling `run` function...");
|
||||
let run_func: NativeFunc<(i32, i32), i32> = instance.exports.get_native_function("run")?;
|
||||
|
||||
// When we call a function it can either succeed or fail.
|
||||
// When we call a function it can either succeed or fail. We expect it to fail.
|
||||
match run_func.call(1, 7) {
|
||||
Ok(result) => {
|
||||
bail!(
|
||||
@@ -66,12 +92,13 @@ fn main() -> anyhow::Result<()> {
|
||||
result
|
||||
);
|
||||
}
|
||||
// We're expecting it to fail.
|
||||
// We attempt to downcast the error into the error type that we were expecting.
|
||||
// In case of a failure, which we expect, we attempt to downcast the error into the error
|
||||
// type that we were expecting.
|
||||
Err(e) => match e.downcast::<ExitCode>() {
|
||||
// We found the exit code used to terminate execution.
|
||||
Ok(exit_code) => {
|
||||
println!("Exited early with exit code: {}", exit_code);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Err(e) => {
|
||||
|
||||
103
examples/errors.rs
Normal file
103
examples/errors.rs
Normal file
@@ -0,0 +1,103 @@
|
||||
//! A Wasm module can sometimes be invalid or trigger traps, and in those case we will get
|
||||
//! an error back from the API.
|
||||
//!
|
||||
//! In this example we'll see how to handle such errors in the most
|
||||
//! basic way. To do that we'll use a Wasm module that we know will
|
||||
//! produce an error.
|
||||
//!
|
||||
//! You can run the example directly by executing in Wasmer root:
|
||||
//!
|
||||
//! ```shell
|
||||
//! cargo run --example errors --release --features "cranelift"
|
||||
//! ```
|
||||
//!
|
||||
//! Ready?
|
||||
|
||||
use wasmer::{imports, wat2wasm, Instance, Module, Store};
|
||||
use wasmer_compiler_cranelift::Cranelift;
|
||||
use wasmer_engine_jit::JIT;
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
// Let's declare the Wasm module with the text representation.
|
||||
let wasm_bytes = wat2wasm(
|
||||
br#"
|
||||
(module
|
||||
(type $do_div_by_zero_t (func (result i32)))
|
||||
(func $do_div_by_zero_f (type $do_div_by_zero_t) (result i32)
|
||||
i32.const 4
|
||||
i32.const 0
|
||||
i32.div_s)
|
||||
|
||||
(type $div_by_zero_t (func (result i32)))
|
||||
(func $div_by_zero_f (type $div_by_zero_t) (result i32)
|
||||
call $do_div_by_zero_f)
|
||||
(export "div_by_zero" (func $div_by_zero_f)))
|
||||
"#,
|
||||
)?;
|
||||
|
||||
// Create a Store.
|
||||
// Note that we don't need to specify the engine/compiler if we want to use
|
||||
// the default provided by Wasmer.
|
||||
// You can use `Store::default()` for that.
|
||||
let store = Store::new(&JIT::new(&Cranelift::default()).engine());
|
||||
|
||||
println!("Compiling module...");
|
||||
// Let's compile the Wasm module.
|
||||
let module = Module::new(&store, wasm_bytes)?;
|
||||
|
||||
// Create an import object.
|
||||
let import_object = imports! {};
|
||||
|
||||
println!("Instantiating module...");
|
||||
// Let's instantiate the Wasm module.
|
||||
let instance = Instance::new(&module, &import_object)?;
|
||||
|
||||
// Here we go.
|
||||
//
|
||||
// The Wasm module exports a function called `div_by_zero`. As its name
|
||||
// implies, this function will try to do a division by zero and thus
|
||||
// produce an error.
|
||||
//
|
||||
// Let's get it.
|
||||
let div_by_zero = instance
|
||||
.exports
|
||||
.get_function("div_by_zero")?
|
||||
.native::<(), i32>()?;
|
||||
|
||||
println!("Calling `div_by_zero` function...");
|
||||
// Let's call the `div_by_zero` exported function.
|
||||
let result = div_by_zero.call();
|
||||
|
||||
// When we call a function it can either succeed or fail. We expect it to fail.
|
||||
match result {
|
||||
Ok(_) => {
|
||||
// This should have thrown an error, return an error
|
||||
panic!("div_by_zero did not error");
|
||||
}
|
||||
Err(e) => {
|
||||
// Log the error
|
||||
println!("Error caught from `div_by_zero`: {}", e.message());
|
||||
|
||||
// Errors come with a trace we can inspect to get more
|
||||
// information on the execution flow.
|
||||
let frames = e.trace();
|
||||
let frames_len = frames.len();
|
||||
|
||||
for i in 0..frames_len {
|
||||
println!(
|
||||
" Frame #{}: {:?}::{:?}",
|
||||
frames_len - i,
|
||||
frames[i].module_name(),
|
||||
frames[i].function_name().or(Some("<func>")).unwrap()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_exported_function() -> Result<(), Box<dyn std::error::Error>> {
|
||||
main()
|
||||
}
|
||||
@@ -72,10 +72,11 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
println!("Calling `sum` function...");
|
||||
// Let's call the `sum` exported function. The parameters are a
|
||||
// slice of `Value`s. The results are a boxed slice of `Value`s.
|
||||
let results = sum.call(&[Value::I32(1), Value::I32(2)])?;
|
||||
let args = [Value::I32(1), Value::I32(2)];
|
||||
let result = sum.call(&args)?;
|
||||
|
||||
println!("Results: {:?}", results);
|
||||
assert_eq!(results.to_vec(), vec![Value::I32(3)]);
|
||||
println!("Results: {:?}", result);
|
||||
assert_eq!(result.to_vec(), vec![Value::I32(3)]);
|
||||
|
||||
// That was fun. But what if we can get rid of the `Value`s? Well,
|
||||
// that's possible with the `NativeFunction` API. The function
|
||||
@@ -85,16 +86,16 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
// `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 = sum.native::<(i32, i32), i32>()?;
|
||||
let sum_native = sum.native::<(i32, i32), i32>()?;
|
||||
|
||||
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.call(1, 2)?;
|
||||
let result = sum_native.call(3, 4)?;
|
||||
|
||||
println!("Results: {:?}", result);
|
||||
assert_eq!(result, 3);
|
||||
assert_eq!(result, 7);
|
||||
|
||||
// Much nicer, isn't it?
|
||||
//
|
||||
|
||||
@@ -68,16 +68,16 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let one = instance.exports.get_global("one")?;
|
||||
let some = instance.exports.get_global("some")?;
|
||||
|
||||
println!("Getting global type informations...");
|
||||
println!("Getting globals types information...");
|
||||
// Let's get the globals types. The results are `GlobalType`s.
|
||||
let one_type = one.ty();
|
||||
let some_type = some.ty();
|
||||
|
||||
println!("one type: {:?} {:?}", one_type.mutability, one_type.ty);
|
||||
println!("`one` type: {:?} {:?}", one_type.mutability, one_type.ty);
|
||||
assert_eq!(one_type.mutability, Mutability::Const);
|
||||
assert_eq!(one_type.ty, Type::F32);
|
||||
|
||||
println!("some type: {:?} {:?}", some_type.mutability, some_type.ty);
|
||||
println!("`some` type: {:?} {:?}", some_type.mutability, some_type.ty);
|
||||
assert_eq!(some_type.mutability, Mutability::Var);
|
||||
assert_eq!(some_type.ty, Type::F32);
|
||||
|
||||
@@ -93,14 +93,14 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
.get_function("get_one")?
|
||||
.native::<(), f32>()?;
|
||||
|
||||
let one_result = get_one.call()?;
|
||||
let some_result = some.get();
|
||||
let one_value = get_one.call()?;
|
||||
let some_value = some.get();
|
||||
|
||||
println!("one value: {:?}", one_result);
|
||||
assert_eq!(one_result, 1.0);
|
||||
println!("`one` value: {:?}", one_value);
|
||||
assert_eq!(one_value, 1.0);
|
||||
|
||||
println!("some value: {:?}", some_result);
|
||||
assert_eq!(some_result, Value::F32(0.0));
|
||||
println!("`some` value: {:?}", some_value);
|
||||
assert_eq!(some_value, Value::F32(0.0));
|
||||
|
||||
println!("Setting global values...");
|
||||
// Trying to set the value of a immutable global (`const`)
|
||||
@@ -112,7 +112,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
);
|
||||
|
||||
let one_result = one.get();
|
||||
println!("one value after `set`: {:?}", one_result);
|
||||
println!("`one` value after `set`: {:?}", one_result);
|
||||
assert_eq!(one_result, Value::F32(1.0));
|
||||
|
||||
// Setting the values of globals can be done in two ways:
|
||||
@@ -126,12 +126,12 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
.native::<f32, ()>()?;
|
||||
set_some.call(21.0)?;
|
||||
let some_result = some.get();
|
||||
println!("some value after `set_some`: {:?}", some_result);
|
||||
println!("`some` value after `set_some`: {:?}", some_result);
|
||||
assert_eq!(some_result, Value::F32(21.0));
|
||||
|
||||
some.set(Value::F32(42.0))?;
|
||||
let some_result = some.get();
|
||||
println!("some value after `set`: {:?}", some_result);
|
||||
println!("`some` value after `set`: {:?}", some_result);
|
||||
assert_eq!(some_result, Value::F32(42.0));
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -70,7 +70,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
}
|
||||
let multiply_native = Function::new_native(&store, multiply);
|
||||
|
||||
// Create an empty import object.
|
||||
// Create an import object.
|
||||
let import_object = imports! {
|
||||
"env" => {
|
||||
"multiply_dynamic" => multiply_dynamic,
|
||||
|
||||
129
examples/imports_function_env.rs
Normal file
129
examples/imports_function_env.rs
Normal file
@@ -0,0 +1,129 @@
|
||||
//! A Wasm module can import entities, like functions, memories,
|
||||
//! globals and tables.
|
||||
//!
|
||||
//! In this example, we'll create a system for getting and adjusting a counter value. However, host
|
||||
//! functions are not limited to storing data outside of WASM, they're normal host functions and
|
||||
//! can do anything that the host can do.
|
||||
//!
|
||||
//! 1. There will be a `get_counter` function that will return an i32 of
|
||||
//! the current global counter,
|
||||
//! 2. There will be an `add_to_counter` function will add the passed
|
||||
//! i32 value to the counter, and return an i32 of the current
|
||||
//! global counter.
|
||||
//!
|
||||
//! You can run the example directly by executing in Wasmer root:
|
||||
//!
|
||||
//! ```shell
|
||||
//! cargo run --example imported-function-env --release --features "cranelift"
|
||||
//! ```
|
||||
//!
|
||||
//! Ready?
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::sync::Arc;
|
||||
use wasmer::{imports, wat2wasm, Function, Instance, Module, Store};
|
||||
use wasmer_compiler_cranelift::Cranelift;
|
||||
use wasmer_engine_jit::JIT;
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
// Let's declare the Wasm module with the text representation.
|
||||
let wasm_bytes = wat2wasm(
|
||||
br#"
|
||||
(module
|
||||
(func $get_counter (import "env" "get_counter") (result i32))
|
||||
(func $add_to_counter (import "env" "add_to_counter") (param i32) (result i32))
|
||||
|
||||
(type $increment_t (func (param i32) (result i32)))
|
||||
(func $increment_f (type $increment_t) (param $x i32) (result i32)
|
||||
(block
|
||||
(loop
|
||||
(call $add_to_counter (i32.const 1))
|
||||
(set_local $x (i32.sub (get_local $x) (i32.const 1)))
|
||||
(br_if 1 (i32.eq (get_local $x) (i32.const 0)))
|
||||
(br 0)))
|
||||
call $get_counter)
|
||||
(export "increment_counter_loop" (func $increment_f)))
|
||||
"#,
|
||||
)?;
|
||||
|
||||
// Create a Store.
|
||||
// Note that we don't need to specify the engine/compiler if we want to use
|
||||
// the default provided by Wasmer.
|
||||
// You can use `Store::default()` for that.
|
||||
let store = Store::new(&JIT::new(&Cranelift::default()).engine());
|
||||
|
||||
println!("Compiling module...");
|
||||
// Let's compile the Wasm module.
|
||||
let module = Module::new(&store, wasm_bytes)?;
|
||||
|
||||
// We create some shared data here, `Arc` is required because we may
|
||||
// move our WebAssembly instance to another thread to run it. RefCell
|
||||
// lets us get shared mutabilty which is fine because we know we won't
|
||||
// run host calls concurrently. If concurrency is a possibilty, we'd have
|
||||
// to use a `Mutex`.
|
||||
let shared_counter: Arc<RefCell<i32>> = Arc::new(RefCell::new(0));
|
||||
|
||||
// Once we have our counter we'll wrap it inside en `Env` which we'll pass
|
||||
// to our imported functions.
|
||||
//
|
||||
// This struct may have been anything. The only constraint is it must be
|
||||
// possible to know the size of the `Env` at compile time (i.e it has to
|
||||
// implement the `Sized` trait).
|
||||
struct Env {
|
||||
counter: Arc<RefCell<i32>>,
|
||||
}
|
||||
|
||||
// Create the functions
|
||||
fn get_counter(env: &mut Env) -> i32 {
|
||||
*env.counter.borrow()
|
||||
}
|
||||
fn add_to_counter(env: &mut Env, add: i32) -> i32 {
|
||||
let mut counter_ref = env.counter.borrow_mut();
|
||||
|
||||
*counter_ref += add;
|
||||
*counter_ref
|
||||
}
|
||||
|
||||
// Create an import object.
|
||||
let import_object = imports! {
|
||||
"env" => {
|
||||
"get_counter" => Function::new_native_with_env(&store, Env { counter: shared_counter.clone() }, get_counter),
|
||||
"add_to_counter" => Function::new_native_with_env(&store, Env { counter: shared_counter.clone() }, add_to_counter),
|
||||
}
|
||||
};
|
||||
|
||||
println!("Instantiating module...");
|
||||
// Let's instantiate the Wasm module.
|
||||
let instance = Instance::new(&module, &import_object)?;
|
||||
|
||||
// Here we go.
|
||||
//
|
||||
// The Wasm module exports a function called `increment_counter_loop`. Let's get it.
|
||||
let increment_counter_loop = instance
|
||||
.exports
|
||||
.get_function("increment_counter_loop")?
|
||||
.native::<i32, i32>()?;
|
||||
|
||||
let counter_value: i32 = *shared_counter.borrow();
|
||||
println!("Initial ounter value: {:?}", counter_value);
|
||||
|
||||
println!("Calling `increment_counter_loop` function...");
|
||||
// Let's call the `increment_counter_loop` exported function.
|
||||
//
|
||||
// It will loop five times thus incrementing our counter five times.
|
||||
let result = increment_counter_loop.call(5)?;
|
||||
|
||||
let counter_value: i32 = *shared_counter.borrow();
|
||||
println!("New counter value (host): {:?}", counter_value);
|
||||
assert_eq!(counter_value, 5);
|
||||
|
||||
println!("New counter value (guest): {:?}", counter_value);
|
||||
assert_eq!(result, 5);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_imported_function_env() -> Result<(), Box<dyn std::error::Error>> {
|
||||
main()
|
||||
}
|
||||
80
examples/instance.rs
Normal file
80
examples/instance.rs
Normal file
@@ -0,0 +1,80 @@
|
||||
//! Wasmer will let you easily run Wasm module in a Rust host.
|
||||
//!
|
||||
//! This example illustrates the basics of using Wasmer through a "Hello World"-like project:
|
||||
//!
|
||||
//! 1. How to load a Wasm modules as bytes
|
||||
//! 2. How to compile the module
|
||||
//! 3. How to create an instance of the module
|
||||
//!
|
||||
//! You can run the example directly by executing in Wasmer root:
|
||||
//!
|
||||
//! ```shell
|
||||
//! cargo run --example instance --release --features "cranelift"
|
||||
//! ```
|
||||
//!
|
||||
//! Ready?
|
||||
|
||||
use wasmer::{imports, wat2wasm, Instance, Module, Store};
|
||||
use wasmer_compiler_cranelift::Cranelift;
|
||||
use wasmer_engine_jit::JIT;
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
// Let's declare the Wasm module.
|
||||
//
|
||||
// We are using the text representation of the module here but you can also load `.wasm`
|
||||
// files using the `include_bytes!` macro.
|
||||
let wasm_bytes = wat2wasm(
|
||||
br#"
|
||||
(module
|
||||
(type $add_one_t (func (param i32) (result i32)))
|
||||
(func $add_one_f (type $add_one_t) (param $value i32) (result i32)
|
||||
local.get $value
|
||||
i32.const 1
|
||||
i32.add)
|
||||
(export "add_one" (func $add_one_f)))
|
||||
"#,
|
||||
)?;
|
||||
|
||||
// Create a Store.
|
||||
// Note that we don't need to specify the engine/compiler if we want to use
|
||||
// the default provided by Wasmer.
|
||||
// You can use `Store::default()` for that.
|
||||
let store = Store::new(&JIT::new(&Cranelift::default()).engine());
|
||||
|
||||
println!("Compiling module...");
|
||||
// Let's compile the Wasm module.
|
||||
let module = Module::new(&store, wasm_bytes)?;
|
||||
|
||||
// Create an empty import object.
|
||||
let import_object = imports! {};
|
||||
|
||||
println!("Instantiating module...");
|
||||
// Let's instantiate the Wasm module.
|
||||
let instance = Instance::new(&module, &import_object)?;
|
||||
|
||||
// We now have an instance ready to be used.
|
||||
//
|
||||
// From an `Instance` we can retrieve any exported entities.
|
||||
// Each of these entities is covered in others examples.
|
||||
//
|
||||
// Here we are retrieving the exported function. We won't go into details here
|
||||
// as the main focus of this example is to show how to create an instance out
|
||||
// of a Wasm module and have basic interactions with it.
|
||||
let add_one = instance
|
||||
.exports
|
||||
.get_function("add_one")?
|
||||
.native::<i32, i32>()?;
|
||||
|
||||
println!("Calling `add_one` function...");
|
||||
let result = add_one.call(1)?;
|
||||
|
||||
println!("Results of `add_one`: {:?}", result);
|
||||
assert_eq!(result, 2);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_exported_function() -> Result<(), Box<dyn std::error::Error>> {
|
||||
main()
|
||||
}
|
||||
@@ -1,4 +1,21 @@
|
||||
use wasmer::{imports, wat2wasm, Instance, Module, NativeFunc, Pages, Store};
|
||||
//! With Wasmer you'll be able to interact with guest module memory.
|
||||
//!
|
||||
//! This example illustrates the basics of interacting with Wasm module memory.:
|
||||
//!
|
||||
//! 1. How to load a Wasm modules as bytes
|
||||
//! 2. How to compile the module
|
||||
//! 3. How to create an instance of the module
|
||||
//!
|
||||
//! You can run the example directly by executing in Wasmer root:
|
||||
//!
|
||||
//! ```shell
|
||||
//! cargo run --example memory --release --features "cranelift"
|
||||
//! ```
|
||||
//!
|
||||
//! Ready?
|
||||
|
||||
use std::mem;
|
||||
use wasmer::{imports, wat2wasm, Bytes, Instance, Module, NativeFunc, Pages, Store};
|
||||
use wasmer_compiler_cranelift::Cranelift;
|
||||
use wasmer_engine_jit::JIT;
|
||||
|
||||
@@ -6,6 +23,10 @@ use wasmer_engine_jit::JIT;
|
||||
// TODO: clean it up and comment it https://github.com/wasmerio/wasmer/issues/1749
|
||||
|
||||
fn main() -> anyhow::Result<()> {
|
||||
// Let's declare the Wasm module.
|
||||
//
|
||||
// We are using the text representation of the module here but you can also load `.wasm`
|
||||
// files using the `include_bytes!` macro.
|
||||
let wasm_bytes = wat2wasm(
|
||||
r#"
|
||||
(module
|
||||
@@ -32,48 +53,87 @@ fn main() -> anyhow::Result<()> {
|
||||
.as_bytes(),
|
||||
)?;
|
||||
|
||||
// We set up our store with an engine and a compiler.
|
||||
// Create a Store.
|
||||
// Note that we don't need to specify the engine/compiler if we want to use
|
||||
// the default provided by Wasmer.
|
||||
// You can use `Store::default()` for that.
|
||||
let store = Store::new(&JIT::new(&Cranelift::default()).engine());
|
||||
// Then compile our Wasm.
|
||||
|
||||
println!("Compiling module...");
|
||||
// Let's compile the Wasm module.
|
||||
let module = Module::new(&store, wasm_bytes)?;
|
||||
|
||||
// Create an empty import object.
|
||||
let import_object = imports! {};
|
||||
// And instantiate it with no imports.
|
||||
|
||||
println!("Instantiating module...");
|
||||
// Let's instantiate the Wasm module.
|
||||
let instance = Instance::new(&module, &import_object)?;
|
||||
|
||||
// The module exports some utility functions, let's get them.
|
||||
//
|
||||
// These function will be used later in this example.
|
||||
let mem_size: NativeFunc<(), i32> = instance.exports.get_native_function("mem_size")?;
|
||||
let get_at: NativeFunc<i32, i32> = instance.exports.get_native_function("get_at")?;
|
||||
let set_at: NativeFunc<(i32, i32), ()> = instance.exports.get_native_function("set_at")?;
|
||||
let memory = instance.exports.get_memory("memory")?;
|
||||
|
||||
let mem_addr = 0x2220;
|
||||
let val = 0xFEFEFFE;
|
||||
|
||||
// We now have an instance ready to be used.
|
||||
//
|
||||
// We will start by querying the most intersting information
|
||||
// about the memory: its size. There are mainly two ways of getting
|
||||
// this:
|
||||
// * the size as a number of `Page`s
|
||||
// * the size as a number of bytes
|
||||
//
|
||||
// The size in bytes can be found either by querying its pages or by
|
||||
// querying the memory directly.
|
||||
println!("Querying memory size...");
|
||||
assert_eq!(memory.size(), Pages::from(1));
|
||||
assert_eq!(memory.size().bytes(), Bytes::from(65536 as usize));
|
||||
assert_eq!(memory.data_size(), 65536);
|
||||
|
||||
// Sometimes, the guest module may also export a function to let you
|
||||
// query the memory. Here we have a `mem_size` function, let's try it:
|
||||
let result = mem_size.call()?;
|
||||
println!("Memory size: {:?}", result);
|
||||
assert_eq!(Pages::from(result as u32), memory.size());
|
||||
|
||||
// Now that we know the size of our memory, it's time to see how wa
|
||||
// can change this.
|
||||
//
|
||||
// A memory can be grown to allow storing more things into it. Let's
|
||||
// see how we can do that:
|
||||
println!("Growing memory...");
|
||||
// Here we are requesting two more pages for our memory.
|
||||
memory.grow(2)?;
|
||||
assert_eq!(memory.size(), Pages::from(3));
|
||||
let result = mem_size.call()?;
|
||||
assert_eq!(result, 3);
|
||||
assert_eq!(memory.data_size(), 65536 * 3);
|
||||
|
||||
// -------------
|
||||
// Now that we know how to query and adjust the size of the memory,
|
||||
// let's see how wa can write to it or read from it.
|
||||
//
|
||||
// We'll only focus on how to do this using exported functions, the goal
|
||||
// is to show how to work with memory addresses. Here we'll use absolute
|
||||
// addresses to write and read a value.
|
||||
let mem_addr = 0x2220;
|
||||
let val = 0xFEFEFFE;
|
||||
set_at.call(mem_addr, val)?;
|
||||
// -------------
|
||||
|
||||
let page_size = 0x1_0000;
|
||||
let result = get_at.call(page_size * 3 - 4)?;
|
||||
memory.grow(1025)?;
|
||||
assert_eq!(result, 123456);
|
||||
assert_eq!(memory.size(), Pages::from(1028));
|
||||
set_at.call(page_size * 1027 - 4, 123456)?;
|
||||
let result = get_at.call(page_size * 1027 - 4)?;
|
||||
assert_eq!(result, 123456);
|
||||
set_at.call(1024, 123456)?;
|
||||
let result = get_at.call(1024)?;
|
||||
assert_eq!(result, 123456);
|
||||
|
||||
// -------------
|
||||
let result = get_at.call(mem_addr)?;
|
||||
println!("Value at {:#x?}: {:?}", mem_addr, result);
|
||||
assert_eq!(result, val);
|
||||
|
||||
// Now instead of using hard coded memory addresses, let's try to write
|
||||
// something at the end of the second memory page and read it.
|
||||
let page_size = 0x1_0000;
|
||||
let mem_addr = (page_size * 2) - mem::size_of_val(&val) as i32;
|
||||
let val = 0xFEA09;
|
||||
set_at.call(mem_addr, val)?;
|
||||
|
||||
let result = get_at.call(mem_addr)?;
|
||||
println!("Value at {:#x?}: {:?}", mem_addr, result);
|
||||
assert_eq!(result, val);
|
||||
// -------------
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ use wasmer_engine_jit::JIT;
|
||||
/// After adjusting the memory limits, it delegates all other logic
|
||||
/// to the base tunables.
|
||||
pub struct LimitingTunables<T: Tunables> {
|
||||
/// The maxium a linear memory is allowed to be (in Wasm pages, 65 KiB each).
|
||||
/// The maximum a linear memory is allowed to be (in Wasm pages, 64 KiB each).
|
||||
/// Since Wasmer ensures there is only none or one memory, this is practically
|
||||
/// an upper limit for the guest memory.
|
||||
limit: Pages,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "wasmer"
|
||||
version = "1.0.0-alpha4"
|
||||
version = "1.0.0-alpha5"
|
||||
description = "High-performant WebAssembly runtime"
|
||||
categories = ["wasm"]
|
||||
keywords = ["wasm", "webassembly", "runtime", "vm"]
|
||||
@@ -11,15 +11,15 @@ readme = "README.md"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
wasmer-vm = { path = "../vm", version = "1.0.0-alpha4" }
|
||||
wasmer-compiler-singlepass = { path = "../compiler-singlepass", version = "1.0.0-alpha4", optional = true }
|
||||
wasmer-compiler-cranelift = { path = "../compiler-cranelift", version = "1.0.0-alpha4", optional = true }
|
||||
wasmer-compiler-llvm = { path = "../compiler-llvm", version = "1.0.0-alpha4", optional = true }
|
||||
wasmer-compiler = { path = "../compiler", version = "1.0.0-alpha4" }
|
||||
wasmer-engine = { path = "../engine", version = "1.0.0-alpha4" }
|
||||
wasmer-engine-jit = { path = "../engine-jit", version = "1.0.0-alpha4", optional = true }
|
||||
wasmer-engine-native = { path = "../engine-native", version = "1.0.0-alpha4", optional = true }
|
||||
wasmer-types = { path = "../wasmer-types", version = "1.0.0-alpha4" }
|
||||
wasmer-vm = { path = "../vm", version = "1.0.0-alpha5" }
|
||||
wasmer-compiler-singlepass = { path = "../compiler-singlepass", version = "1.0.0-alpha5", optional = true }
|
||||
wasmer-compiler-cranelift = { path = "../compiler-cranelift", version = "1.0.0-alpha5", optional = true }
|
||||
wasmer-compiler-llvm = { path = "../compiler-llvm", version = "1.0.0-alpha5", optional = true }
|
||||
wasmer-compiler = { path = "../compiler", version = "1.0.0-alpha5" }
|
||||
wasmer-engine = { path = "../engine", version = "1.0.0-alpha5" }
|
||||
wasmer-engine-jit = { path = "../engine-jit", version = "1.0.0-alpha5", optional = true }
|
||||
wasmer-engine-native = { path = "../engine-native", version = "1.0.0-alpha5", optional = true }
|
||||
wasmer-types = { path = "../wasmer-types", version = "1.0.0-alpha5" }
|
||||
indexmap = { version = "1.4", features = ["serde-1"] }
|
||||
cfg-if = "0.1"
|
||||
wat = { version = "1.0", optional = true }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "wasmer-c-api"
|
||||
version = "1.0.0-alpha4"
|
||||
version = "1.0.0-alpha5"
|
||||
description = "Wasmer C API library"
|
||||
categories = ["wasm", "api-bindings"]
|
||||
keywords = ["wasm", "webassembly", "runtime"]
|
||||
@@ -15,18 +15,18 @@ edition = "2018"
|
||||
crate-type = ["cdylib", "rlib", "staticlib"]
|
||||
|
||||
[dependencies]
|
||||
wasmer = { version = "1.0.0-alpha4", path = "../api", default-features = false }
|
||||
wasmer-compiler = { version = "1.0.0-alpha4", path = "../compiler" }
|
||||
wasmer-compiler-cranelift = { version = "1.0.0-alpha4", path = "../compiler-cranelift", optional = true }
|
||||
wasmer-compiler-singlepass = { version = "1.0.0-alpha4", path = "../compiler-singlepass", optional = true }
|
||||
wasmer-compiler-llvm = { version = "1.0.0-alpha4", path = "../compiler-llvm", optional = true }
|
||||
wasmer-emscripten = { version = "1.0.0-alpha4", path = "../emscripten", optional = true }
|
||||
wasmer-engine = { version = "1.0.0-alpha4", path = "../engine" }
|
||||
wasmer-engine-jit = { version = "1.0.0-alpha4", path = "../engine-jit", optional = true }
|
||||
wasmer-engine-native = { version = "1.0.0-alpha4", path = "../engine-native", optional = true }
|
||||
wasmer-engine-object-file = { version = "1.0.0-alpha4", path = "../engine-object-file", optional = true }
|
||||
wasmer-wasi = { version = "1.0.0-alpha4", path = "../wasi", optional = true }
|
||||
wasmer-types = { version = "1.0.0-alpha4", path = "../wasmer-types" }
|
||||
wasmer = { version = "1.0.0-alpha5", path = "../api", default-features = false }
|
||||
wasmer-compiler = { version = "1.0.0-alpha5", path = "../compiler" }
|
||||
wasmer-compiler-cranelift = { version = "1.0.0-alpha5", path = "../compiler-cranelift", optional = true }
|
||||
wasmer-compiler-singlepass = { version = "1.0.0-alpha5", path = "../compiler-singlepass", optional = true }
|
||||
wasmer-compiler-llvm = { version = "1.0.0-alpha5", path = "../compiler-llvm", optional = true }
|
||||
wasmer-emscripten = { version = "1.0.0-alpha5", path = "../emscripten", optional = true }
|
||||
wasmer-engine = { version = "1.0.0-alpha5", path = "../engine" }
|
||||
wasmer-engine-jit = { version = "1.0.0-alpha5", path = "../engine-jit", optional = true }
|
||||
wasmer-engine-native = { version = "1.0.0-alpha5", path = "../engine-native", optional = true }
|
||||
wasmer-engine-object-file = { version = "1.0.0-alpha5", path = "../engine-object-file", optional = true }
|
||||
wasmer-wasi = { version = "1.0.0-alpha5", path = "../wasi", optional = true }
|
||||
wasmer-types = { version = "1.0.0-alpha5", path = "../wasmer-types" }
|
||||
cfg-if = "0.1"
|
||||
lazy_static = "1"
|
||||
libc = { version = "^0.2", default-features = false }
|
||||
@@ -37,7 +37,7 @@ typetag = { version = "0.1", optional = true }
|
||||
paste = "0.1"
|
||||
# for generating code in the same way thot the wasm-c-api does
|
||||
# Commented out for now until we can find a solution to the exported function problem
|
||||
# wasmer-wasm-c-api = { version = "1.0.0-alpha4", path = "crates/wasm-c-api" }
|
||||
# wasmer-wasm-c-api = { version = "1.0.0-alpha5", path = "crates/wasm-c-api" }
|
||||
|
||||
[dev-dependencies]
|
||||
inline-c = "0.1"
|
||||
|
||||
24
lib/c-api/src/wasm_c_api/externals/function.rs
vendored
24
lib/c-api/src/wasm_c_api/externals/function.rs
vendored
@@ -154,18 +154,34 @@ pub unsafe extern "C" fn wasm_func_call(
|
||||
.into_iter()
|
||||
.map(TryInto::try_into)
|
||||
.collect::<Result<Vec<Val>, _>>()
|
||||
.expect("Argument conversion failed")
|
||||
.expect("Arguments conversion failed")
|
||||
})
|
||||
.unwrap_or_default();
|
||||
|
||||
match func.inner.call(¶ms) {
|
||||
Ok(wasm_results) => {
|
||||
*results = wasm_results
|
||||
let vals = wasm_results
|
||||
.into_iter()
|
||||
.map(TryInto::try_into)
|
||||
.collect::<Result<Vec<wasm_val_t>, _>>()
|
||||
.expect("Argument conversion failed")
|
||||
.into();
|
||||
.expect("Results conversion failed");
|
||||
|
||||
// `results` is an uninitialized vector. Set a new value.
|
||||
if results.is_uninitialized() {
|
||||
*results = vals.into();
|
||||
}
|
||||
// `results` is an initialized but empty vector. Fill it
|
||||
// item per item.
|
||||
else {
|
||||
let slice = results
|
||||
.into_slice_mut()
|
||||
.expect("`wasm_func_call`, results' size is greater than 0 but data is NULL");
|
||||
|
||||
for (result, value) in slice.iter_mut().zip(vals.iter()) {
|
||||
(*result).kind = value.kind;
|
||||
(*result).of = value.of;
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
@@ -57,12 +57,24 @@ macro_rules! wasm_declare_vec {
|
||||
|
||||
impl [<wasm_ $name _vec_t>] {
|
||||
pub unsafe fn into_slice(&self) -> Option<&[[<wasm_ $name _t>]]>{
|
||||
if self.data.is_null() {
|
||||
if self.is_uninitialized() {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(::std::slice::from_raw_parts(self.data, self.size))
|
||||
}
|
||||
|
||||
pub unsafe fn into_slice_mut(&mut self) -> Option<&mut [[<wasm_ $name _t>]]>{
|
||||
if self.is_uninitialized() {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(::std::slice::from_raw_parts_mut(self.data, self.size))
|
||||
}
|
||||
|
||||
pub fn is_uninitialized(&self) -> bool {
|
||||
self.data.is_null()
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: investigate possible memory leak on `init` (owned pointer)
|
||||
|
||||
@@ -4,10 +4,10 @@ project (WasmerWasmCApiTests)
|
||||
# Examples as tests from the `wasm-c-api` repository.
|
||||
add_executable(wasm-c-api-callback wasm-c-api/example/callback.c)
|
||||
#add_executable(wasm-c-api-finalize wasm-c-api/example/finalize.c)
|
||||
#add_executable(wasm-c-api-global wasm-c-api/example/global.c)
|
||||
add_executable(wasm-c-api-global wasm-c-api/example/global.c)
|
||||
add_executable(wasm-c-api-hello wasm-c-api/example/hello.c)
|
||||
#add_executable(wasm-c-api-hostref wasm-c-api/example/hostref.c)
|
||||
#add_executable(wasm-c-api-memory wasm-c-api/example/memory.c)
|
||||
add_executable(wasm-c-api-memory wasm-c-api/example/memory.c)
|
||||
#add_executable(wasm-c-api-multi wasm-c-api/example/multi.c)
|
||||
add_executable(wasm-c-api-reflect wasm-c-api/example/reflect.c)
|
||||
add_executable(wasm-c-api-serialize wasm-c-api/example/serialize.c)
|
||||
@@ -57,12 +57,12 @@ add_test(NAME wasm-c-api-callback
|
||||
# WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/wasm-c-api/example/
|
||||
#)
|
||||
|
||||
#target_link_libraries(wasm-c-api-global general ${WASMER_LIB})
|
||||
#target_compile_options(wasm-c-api-global PRIVATE ${COMPILER_OPTIONS})
|
||||
#add_test(NAME wasm-c-api-global
|
||||
# COMMAND wasm-c-api-global
|
||||
# WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/wasm-c-api/example/
|
||||
#)
|
||||
target_link_libraries(wasm-c-api-global general ${WASMER_LIB})
|
||||
target_compile_options(wasm-c-api-global PRIVATE ${COMPILER_OPTIONS})
|
||||
add_test(NAME wasm-c-api-global
|
||||
COMMAND wasm-c-api-global
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/wasm-c-api/example/
|
||||
)
|
||||
|
||||
target_link_libraries(wasm-c-api-hello general ${WASMER_LIB})
|
||||
target_compile_options(wasm-c-api-hello PRIVATE ${COMPILER_OPTIONS})
|
||||
@@ -78,12 +78,12 @@ add_test(NAME wasm-c-api-hello
|
||||
# WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/wasm-c-api/example/
|
||||
#)
|
||||
|
||||
#target_link_libraries(wasm-c-api-memory general ${WASMER_LIB})
|
||||
#target_compile_options(wasm-c-api-memory PRIVATE ${COMPILER_OPTIONS})
|
||||
#add_test(NAME wasm-c-api-memory
|
||||
# COMMAND wasm-c-api-memory
|
||||
# WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/wasm-c-api/example/
|
||||
#)
|
||||
target_link_libraries(wasm-c-api-memory general ${WASMER_LIB})
|
||||
target_compile_options(wasm-c-api-memory PRIVATE ${COMPILER_OPTIONS})
|
||||
add_test(NAME wasm-c-api-memory
|
||||
COMMAND wasm-c-api-memory
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/wasm-c-api/example/
|
||||
)
|
||||
|
||||
#target_link_libraries(wasm-c-api-multi general ${WASMER_LIB})
|
||||
#target_compile_options(wasm-c-api-multi PRIVATE ${COMPILER_OPTIONS})
|
||||
|
||||
4
lib/cache/Cargo.toml
vendored
4
lib/cache/Cargo.toml
vendored
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "wasmer-cache"
|
||||
version = "1.0.0-alpha4"
|
||||
version = "1.0.0-alpha5"
|
||||
description = "Cache system for Wasmer WebAssembly runtime"
|
||||
categories = ["wasm", "caching"]
|
||||
keywords = ["wasm", "webassembly", "cache"]
|
||||
@@ -11,7 +11,7 @@ readme = "README.md"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
wasmer = { path = "../api", version = "1.0.0-alpha4", default-features = false }
|
||||
wasmer = { path = "../api", version = "1.0.0-alpha5", default-features = false }
|
||||
memmap = "0.7"
|
||||
hex = "0.4"
|
||||
thiserror = "1"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "wasmer-cli"
|
||||
version = "1.0.0-alpha4"
|
||||
version = "1.0.0-alpha5"
|
||||
description = "Wasmer CLI"
|
||||
categories = ["wasm", "command-line-interface"]
|
||||
keywords = ["wasm", "webassembly", "cli"]
|
||||
@@ -17,22 +17,22 @@ path = "src/bin/wasmer.rs"
|
||||
doc = false
|
||||
|
||||
[dependencies]
|
||||
wasmer = { version = "1.0.0-alpha4", path = "../api", default-features = false }
|
||||
wasmer-compiler = { version = "1.0.0-alpha4", path = "../compiler" }
|
||||
wasmer-compiler-cranelift = { version = "1.0.0-alpha4", path = "../compiler-cranelift", optional = true }
|
||||
wasmer-compiler-singlepass = { version = "1.0.0-alpha4", path = "../compiler-singlepass", optional = true }
|
||||
wasmer-compiler-llvm = { version = "1.0.0-alpha4", path = "../compiler-llvm", optional = true }
|
||||
wasmer-emscripten = { version = "1.0.0-alpha4", path = "../emscripten", optional = true }
|
||||
wasmer-engine = { version = "1.0.0-alpha4", path = "../engine" }
|
||||
wasmer-engine-jit = { version = "1.0.0-alpha4", path = "../engine-jit", optional = true }
|
||||
wasmer-engine-native = { version = "1.0.0-alpha4", path = "../engine-native", optional = true }
|
||||
wasmer-engine-object-file = { version = "1.0.0-alpha4", path = "../engine-object-file", optional = true }
|
||||
wasmer-vm = { version = "1.0.0-alpha4", path = "../vm" }
|
||||
wasmer-wasi = { version = "1.0.0-alpha4", path = "../wasi", optional = true }
|
||||
wasmer-wasi-experimental-io-devices = { version = "1.0.0-alpha4", path = "../wasi-experimental-io-devices", optional = true }
|
||||
wasmer-wast = { version = "1.0.0-alpha4", path = "../../tests/lib/wast", optional = true }
|
||||
wasmer-cache = { version = "1.0.0-alpha4", path = "../cache", optional = true }
|
||||
wasmer-types = { version = "1.0.0-alpha4", path = "../wasmer-types" }
|
||||
wasmer = { version = "1.0.0-alpha5", path = "../api", default-features = false }
|
||||
wasmer-compiler = { version = "1.0.0-alpha5", path = "../compiler" }
|
||||
wasmer-compiler-cranelift = { version = "1.0.0-alpha5", path = "../compiler-cranelift", optional = true }
|
||||
wasmer-compiler-singlepass = { version = "1.0.0-alpha5", path = "../compiler-singlepass", optional = true }
|
||||
wasmer-compiler-llvm = { version = "1.0.0-alpha5", path = "../compiler-llvm", optional = true }
|
||||
wasmer-emscripten = { version = "1.0.0-alpha5", path = "../emscripten", optional = true }
|
||||
wasmer-engine = { version = "1.0.0-alpha5", path = "../engine" }
|
||||
wasmer-engine-jit = { version = "1.0.0-alpha5", path = "../engine-jit", optional = true }
|
||||
wasmer-engine-native = { version = "1.0.0-alpha5", path = "../engine-native", optional = true }
|
||||
wasmer-engine-object-file = { version = "1.0.0-alpha5", path = "../engine-object-file", optional = true }
|
||||
wasmer-vm = { version = "1.0.0-alpha5", path = "../vm" }
|
||||
wasmer-wasi = { version = "1.0.0-alpha5", path = "../wasi", optional = true }
|
||||
wasmer-wasi-experimental-io-devices = { version = "1.0.0-alpha5", path = "../wasi-experimental-io-devices", optional = true }
|
||||
wasmer-wast = { version = "1.0.0-alpha5", path = "../../tests/lib/wast", optional = true }
|
||||
wasmer-cache = { version = "1.0.0-alpha5", path = "../cache", optional = true }
|
||||
wasmer-types = { version = "1.0.0-alpha5", path = "../wasmer-types" }
|
||||
atty = "0.2"
|
||||
colored = "2.0"
|
||||
anyhow = "1.0"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "wasmer-compiler-cranelift"
|
||||
version = "1.0.0-alpha4"
|
||||
version = "1.0.0-alpha5"
|
||||
description = "Cranelift compiler for Wasmer WebAssembly runtime"
|
||||
categories = ["wasm"]
|
||||
keywords = ["wasm", "webassembly", "compiler", "cranelift"]
|
||||
@@ -12,9 +12,9 @@ readme = "README.md"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
wasmer-compiler = { path = "../compiler", version = "1.0.0-alpha4", features = ["translator"], default-features = false }
|
||||
wasmer-vm = { path = "../vm", version = "1.0.0-alpha4" }
|
||||
wasmer-types = { path = "../wasmer-types", version = "1.0.0-alpha4", default-features = false, features = ["std"] }
|
||||
wasmer-compiler = { path = "../compiler", version = "1.0.0-alpha5", features = ["translator"], default-features = false }
|
||||
wasmer-vm = { path = "../vm", version = "1.0.0-alpha5" }
|
||||
wasmer-types = { path = "../wasmer-types", version = "1.0.0-alpha5", default-features = false, features = ["std"] }
|
||||
cranelift-codegen = { version = "0.67", default-features = false, features = ["x86", "arm64"] }
|
||||
cranelift-frontend = { version = "0.67", default-features = false }
|
||||
tracing = "0.1"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "wasmer-compiler-llvm"
|
||||
version = "1.0.0-alpha4"
|
||||
version = "1.0.0-alpha5"
|
||||
description = "LLVM compiler for Wasmer WebAssembly runtime"
|
||||
categories = ["wasm"]
|
||||
keywords = ["wasm", "webassembly", "compiler", "llvm"]
|
||||
@@ -12,9 +12,9 @@ readme = "README.md"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
wasmer-compiler = { path = "../compiler", version = "1.0.0-alpha4", features = ["translator"] }
|
||||
wasmer-vm = { path = "../vm", version = "1.0.0-alpha4" }
|
||||
wasmer-types = { path = "../wasmer-types", version = "1.0.0-alpha4" }
|
||||
wasmer-compiler = { path = "../compiler", version = "1.0.0-alpha5", features = ["translator"] }
|
||||
wasmer-vm = { path = "../vm", version = "1.0.0-alpha5" }
|
||||
wasmer-types = { path = "../wasmer-types", version = "1.0.0-alpha5" }
|
||||
target-lexicon = { version = "0.11", default-features = false }
|
||||
smallvec = "1"
|
||||
goblin = "0.2"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "wasmer-compiler-singlepass"
|
||||
version = "1.0.0-alpha4"
|
||||
version = "1.0.0-alpha5"
|
||||
description = "Singlepass compiler for Wasmer WebAssembly runtime"
|
||||
categories = ["wasm"]
|
||||
keywords = ["wasm", "webassembly", "compiler", "singlepass"]
|
||||
@@ -12,9 +12,9 @@ readme = "README.md"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
wasmer-compiler = { path = "../compiler", version = "1.0.0-alpha4", features = ["translator"], default-features = false }
|
||||
wasmer-vm = { path = "../vm", version = "1.0.0-alpha4" }
|
||||
wasmer-types = { path = "../wasmer-types", version = "1.0.0-alpha4", default-features = false, features = ["std"] }
|
||||
wasmer-compiler = { path = "../compiler", version = "1.0.0-alpha5", features = ["translator"], default-features = false }
|
||||
wasmer-vm = { path = "../vm", version = "1.0.0-alpha5" }
|
||||
wasmer-types = { path = "../wasmer-types", version = "1.0.0-alpha5", default-features = false, features = ["std"] }
|
||||
rayon = "1.5"
|
||||
hashbrown = { version = "0.9", optional = true }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "wasmer-compiler"
|
||||
version = "1.0.0-alpha4"
|
||||
version = "1.0.0-alpha5"
|
||||
description = "Base compiler abstraction for Wasmer WebAssembly runtime"
|
||||
categories = ["wasm", "no-std"]
|
||||
keywords = ["wasm", "webassembly", "compiler"]
|
||||
@@ -11,8 +11,8 @@ readme = "README.md"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
wasmer-vm = { path = "../vm", version = "1.0.0-alpha4" }
|
||||
wasmer-types = { path = "../wasmer-types", version = "1.0.0-alpha4", default-features = false }
|
||||
wasmer-vm = { path = "../vm", version = "1.0.0-alpha5" }
|
||||
wasmer-types = { path = "../wasmer-types", version = "1.0.0-alpha5", default-features = false }
|
||||
wasmparser = { version = "0.65", optional = true, default-features = false }
|
||||
target-lexicon = { version = "0.11", default-features = false }
|
||||
enumset = "1.0"
|
||||
|
||||
@@ -14,16 +14,16 @@ edition = "2018"
|
||||
maintenance = { status = "deprecated" }
|
||||
|
||||
[dependencies]
|
||||
wasmer-types = { path = "../../wasmer-types", version = "1.0.0-alpha4" }
|
||||
wasmer = { path = "../../api", version = "1.0.0-alpha4" }
|
||||
wasmer-cache = { path = "../../cache", version = "1.0.0-alpha4" }
|
||||
wasmer-compiler = { path = "../../compiler", version = "1.0.0-alpha4", features = ["translator"] }
|
||||
wasmer-compiler-llvm = { path = "../../compiler-llvm", version = "1.0.0-alpha4", optional = true }
|
||||
wasmer-compiler-cranelift = { path = "../../compiler-cranelift", version = "1.0.0-alpha4", optional = true }
|
||||
wasmer-compiler-singlepass = { path = "../../compiler-singlepass", version = "1.0.0-alpha4", optional = true }
|
||||
wasmer-engine = { path = "../../engine", version = "1.0.0-alpha4" }
|
||||
wasmer-engine-jit = { path = "../../engine-jit", version = "1.0.0-alpha4" }
|
||||
wasmer-vm = { path = "../../vm", version = "1.0.0-alpha4" }
|
||||
wasmer-types = { path = "../../wasmer-types", version = "1.0.0-alpha5" }
|
||||
wasmer = { path = "../../api", version = "1.0.0-alpha5" }
|
||||
wasmer-cache = { path = "../../cache", version = "1.0.0-alpha5" }
|
||||
wasmer-compiler = { path = "../../compiler", version = "1.0.0-alpha5", features = ["translator"] }
|
||||
wasmer-compiler-llvm = { path = "../../compiler-llvm", version = "1.0.0-alpha5", optional = true }
|
||||
wasmer-compiler-cranelift = { path = "../../compiler-cranelift", version = "1.0.0-alpha5", optional = true }
|
||||
wasmer-compiler-singlepass = { path = "../../compiler-singlepass", version = "1.0.0-alpha5", optional = true }
|
||||
wasmer-engine = { path = "../../engine", version = "1.0.0-alpha5" }
|
||||
wasmer-engine-jit = { path = "../../engine-jit", version = "1.0.0-alpha5" }
|
||||
wasmer-vm = { path = "../../vm", version = "1.0.0-alpha5" }
|
||||
lazy_static = "1.4"
|
||||
|
||||
[build-dependencies]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "wasmer-emscripten"
|
||||
version = "1.0.0-alpha4"
|
||||
version = "1.0.0-alpha5"
|
||||
description = "Emscripten implementation library for Wasmer WebAssembly runtime"
|
||||
categories = ["wasm", "os"]
|
||||
keywords = ["wasm", "webassembly", "abi", "emscripten", "posix"]
|
||||
@@ -16,7 +16,7 @@ lazy_static = "1.4"
|
||||
libc = "^0.2"
|
||||
log = "0.4"
|
||||
time = "0.1"
|
||||
wasmer = { path = "../api", version = "1.0.0-alpha4", default-features = false }
|
||||
wasmer = { path = "../api", version = "1.0.0-alpha5", default-features = false }
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
getrandom = "0.2"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "wasmer-engine-jit"
|
||||
version = "1.0.0-alpha4"
|
||||
version = "1.0.0-alpha5"
|
||||
description = "Wasmer JIT Engine"
|
||||
categories = ["wasm"]
|
||||
keywords = ["wasm", "webassembly", "engine", "jit"]
|
||||
@@ -11,10 +11,10 @@ readme = "README.md"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
wasmer-types = { path = "../wasmer-types", version = "1.0.0-alpha4" }
|
||||
wasmer-compiler = { path = "../compiler", version = "1.0.0-alpha4", features = ["translator"] }
|
||||
wasmer-vm = { path = "../vm", version = "1.0.0-alpha4" }
|
||||
wasmer-engine = { path = "../engine", version = "1.0.0-alpha4" }
|
||||
wasmer-types = { path = "../wasmer-types", version = "1.0.0-alpha5" }
|
||||
wasmer-compiler = { path = "../compiler", version = "1.0.0-alpha5", features = ["translator"] }
|
||||
wasmer-vm = { path = "../vm", version = "1.0.0-alpha5" }
|
||||
wasmer-engine = { path = "../engine", version = "1.0.0-alpha5" }
|
||||
# flexbuffers = { path = "../../../flatbuffers/rust/flexbuffers", version = "0.1.0" }
|
||||
region = "2.2"
|
||||
serde = { version = "1.0", features = ["derive", "rc"] }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "wasmer-engine-native"
|
||||
version = "1.0.0-alpha4"
|
||||
version = "1.0.0-alpha5"
|
||||
description = "Wasmer Native Engine"
|
||||
categories = ["wasm"]
|
||||
keywords = ["wasm", "webassembly", "engine", "native"]
|
||||
@@ -11,11 +11,11 @@ readme = "README.md"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
wasmer-types = { path = "../wasmer-types", version = "1.0.0-alpha4" }
|
||||
wasmer-compiler = { path = "../compiler", version = "1.0.0-alpha4" }
|
||||
wasmer-vm = { path = "../vm", version = "1.0.0-alpha4" }
|
||||
wasmer-engine = { path = "../engine", version = "1.0.0-alpha4" }
|
||||
wasmer-object = { path = "../object", version = "1.0.0-alpha4" }
|
||||
wasmer-types = { path = "../wasmer-types", version = "1.0.0-alpha5" }
|
||||
wasmer-compiler = { path = "../compiler", version = "1.0.0-alpha5" }
|
||||
wasmer-vm = { path = "../vm", version = "1.0.0-alpha5" }
|
||||
wasmer-engine = { path = "../engine", version = "1.0.0-alpha5" }
|
||||
wasmer-object = { path = "../object", version = "1.0.0-alpha5" }
|
||||
serde = { version = "1.0", features = ["derive", "rc"] }
|
||||
cfg-if = "0.1"
|
||||
tracing = "0.1"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "wasmer-engine-object-file"
|
||||
version = "1.0.0-alpha4"
|
||||
version = "1.0.0-alpha5"
|
||||
authors = ["Wasmer Engineering Team <engineering@wasmer.io>"]
|
||||
description = "Wasmer Object File Engine"
|
||||
categories = ["wasm"]
|
||||
@@ -11,11 +11,11 @@ readme = "README.md"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
wasmer-types = { path = "../wasmer-types", version = "1.0.0-alpha4" }
|
||||
wasmer-compiler = { path = "../compiler", version = "1.0.0-alpha4" }
|
||||
wasmer-types = { path = "../wasmer-types", version = "1.0.0-alpha5" }
|
||||
wasmer-compiler = { path = "../compiler", version = "1.0.0-alpha5" }
|
||||
wasmer-vm = { path = "../vm", version = "1.0.0-alpha01.0" }
|
||||
wasmer-engine = { path = "../engine", version = "1.0.0-alpha4" }
|
||||
wasmer-object = { path = "../object", version = "1.0.0-alpha4" }
|
||||
wasmer-engine = { path = "../engine", version = "1.0.0-alpha5" }
|
||||
wasmer-object = { path = "../object", version = "1.0.0-alpha5" }
|
||||
serde = { version = "1.0", features = ["derive", "rc"] }
|
||||
cfg-if = "0.1"
|
||||
tracing = "0.1"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "wasmer-engine"
|
||||
version = "1.0.0-alpha4"
|
||||
version = "1.0.0-alpha5"
|
||||
description = "Wasmer Engine abstraction"
|
||||
categories = ["wasm"]
|
||||
keywords = ["wasm", "webassembly", "engine"]
|
||||
@@ -11,9 +11,9 @@ readme = "README.md"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
wasmer-types = { path = "../wasmer-types", version = "1.0.0-alpha4" }
|
||||
wasmer-compiler = { path = "../compiler", version = "1.0.0-alpha4" }
|
||||
wasmer-vm = { path = "../vm", version = "1.0.0-alpha4" }
|
||||
wasmer-types = { path = "../wasmer-types", version = "1.0.0-alpha5" }
|
||||
wasmer-compiler = { path = "../compiler", version = "1.0.0-alpha5" }
|
||||
wasmer-vm = { path = "../vm", version = "1.0.0-alpha5" }
|
||||
target-lexicon = { version = "0.11", default-features = false }
|
||||
# flexbuffers = { path = "../../../flatbuffers/rust/flexbuffers", version = "0.1.0" }
|
||||
backtrace = "0.3"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "wasmer-object"
|
||||
version = "1.0.0-alpha4"
|
||||
version = "1.0.0-alpha5"
|
||||
description = "Wasmer Native Object generator"
|
||||
categories = ["wasm"]
|
||||
keywords = ["wasm", "webassembly"]
|
||||
@@ -11,8 +11,8 @@ readme = "README.md"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
wasmer-types = { path = "../wasmer-types", version = "1.0.0-alpha4" }
|
||||
wasmer-compiler = { path = "../compiler", version = "1.0.0-alpha4", default-features = false, features = [
|
||||
wasmer-types = { path = "../wasmer-types", version = "1.0.0-alpha5" }
|
||||
wasmer-compiler = { path = "../compiler", version = "1.0.0-alpha5", default-features = false, features = [
|
||||
"std",
|
||||
"translator"
|
||||
] }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "wasmer-vm"
|
||||
version = "1.0.0-alpha4"
|
||||
version = "1.0.0-alpha5"
|
||||
description = "Runtime library support for Wasmer"
|
||||
categories = ["wasm"]
|
||||
keywords = ["wasm", "webassembly"]
|
||||
@@ -11,7 +11,7 @@ readme = "README.md"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
wasmer-types = { path = "../wasmer-types", version = "1.0.0-alpha4" }
|
||||
wasmer-types = { path = "../wasmer-types", version = "1.0.0-alpha5" }
|
||||
region = "2.2"
|
||||
libc = { version = "^0.2", default-features = false }
|
||||
memoffset = "0.5"
|
||||
|
||||
@@ -69,11 +69,11 @@ impl Global {
|
||||
unsafe {
|
||||
let definition = &*self.vm_global_definition.get();
|
||||
match self.ty().ty {
|
||||
Type::I32 => Value::I32(*definition.as_i32()),
|
||||
Type::I64 => Value::I64(*definition.as_i64()),
|
||||
Type::F32 => Value::F32(*definition.as_f32()),
|
||||
Type::F64 => Value::F64(*definition.as_f64()),
|
||||
Type::V128 => Value::V128(*definition.as_u128()),
|
||||
Type::I32 => Value::I32(definition.to_i32()),
|
||||
Type::I64 => Value::I64(definition.to_i64()),
|
||||
Type::F32 => Value::F32(definition.to_f32()),
|
||||
Type::F64 => Value::F64(definition.to_f64()),
|
||||
Type::V128 => Value::V128(definition.to_u128()),
|
||||
_ => unimplemented!("Global::get for {:?}", self.ty),
|
||||
}
|
||||
}
|
||||
@@ -111,7 +111,7 @@ impl Global {
|
||||
Value::I64(i) => *definition.as_i64_mut() = i,
|
||||
Value::F32(f) => *definition.as_f32_mut() = f,
|
||||
Value::F64(f) => *definition.as_f64_mut() = f,
|
||||
Value::V128(x) => *definition.as_u128_bits_mut() = x.to_ne_bytes(),
|
||||
Value::V128(x) => *definition.as_bytes_mut() = x.to_ne_bytes(),
|
||||
_ => unimplemented!("Global::set for {:?}", val.ty()),
|
||||
}
|
||||
Ok(())
|
||||
|
||||
@@ -1179,9 +1179,9 @@ fn get_memory_init_start(init: &DataInitializer<'_>, instance: &Instance) -> usi
|
||||
if let Some(base) = init.location.base {
|
||||
let val = unsafe {
|
||||
if let Some(def_index) = instance.module.local_global_index(base) {
|
||||
*instance.global(def_index).as_u32()
|
||||
instance.global(def_index).to_u32()
|
||||
} else {
|
||||
*instance.imported_global(base).definition.as_ref().as_u32()
|
||||
instance.imported_global(base).definition.as_ref().to_u32()
|
||||
}
|
||||
};
|
||||
start += usize::try_from(val).unwrap();
|
||||
@@ -1232,9 +1232,9 @@ fn get_table_init_start(init: &TableInitializer, instance: &Instance) -> usize {
|
||||
if let Some(base) = init.base {
|
||||
let val = unsafe {
|
||||
if let Some(def_index) = instance.module.local_global_index(base) {
|
||||
*instance.global(def_index).as_u32()
|
||||
instance.global(def_index).to_u32()
|
||||
} else {
|
||||
*instance.imported_global(base).definition.as_ref().as_u32()
|
||||
instance.imported_global(base).definition.as_ref().to_u32()
|
||||
}
|
||||
};
|
||||
start += usize::try_from(val).unwrap();
|
||||
@@ -1333,7 +1333,7 @@ fn initialize_globals(instance: &Instance) {
|
||||
GlobalInit::I64Const(x) => *(*to).as_i64_mut() = *x,
|
||||
GlobalInit::F32Const(x) => *(*to).as_f32_mut() = *x,
|
||||
GlobalInit::F64Const(x) => *(*to).as_f64_mut() = *x,
|
||||
GlobalInit::V128Const(x) => *(*to).as_u128_bits_mut() = *x.bytes(),
|
||||
GlobalInit::V128Const(x) => *(*to).as_bytes_mut() = *x.bytes(),
|
||||
GlobalInit::GetGlobal(x) => {
|
||||
let from: VMGlobalDefinition =
|
||||
if let Some(def_x) = module.local_global_index(*x) {
|
||||
|
||||
@@ -385,7 +385,8 @@ pub unsafe extern "C" fn wasmer_data_drop(vmctx: *mut VMContext, data_index: u32
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// To be defined (TODO)
|
||||
/// Only safe to call when wasm code is on the stack, aka `wasmer_call` or
|
||||
/// `wasmer_call_trampoline` must have been previously called.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn wasmer_raise_trap(trap_code: TrapCode) -> ! {
|
||||
let trap = Trap::new_from_runtime(trap_code);
|
||||
|
||||
@@ -11,6 +11,7 @@ use crate::table::Table;
|
||||
use crate::trap::{Trap, TrapCode};
|
||||
use std::any::Any;
|
||||
use std::convert::TryFrom;
|
||||
use std::fmt;
|
||||
use std::ptr::{self, NonNull};
|
||||
use std::sync::Arc;
|
||||
use std::u32;
|
||||
@@ -454,6 +455,34 @@ mod test_vmtable_definition {
|
||||
}
|
||||
}
|
||||
|
||||
/// A typesafe wrapper around the storage for a global variables.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Accessing the different members of this union is always safe because there
|
||||
/// are no invalid values for any of the types and the whole object is
|
||||
/// initialized by VMGlobalDefinition::new().
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(C, align(16))]
|
||||
pub union VMGlobalDefinitionStorage {
|
||||
as_i32: i32,
|
||||
as_u32: u32,
|
||||
as_f32: f32,
|
||||
as_i64: i64,
|
||||
as_u64: u64,
|
||||
as_f64: f64,
|
||||
as_u128: u128,
|
||||
bytes: [u8; 16],
|
||||
}
|
||||
|
||||
impl fmt::Debug for VMGlobalDefinitionStorage {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("VMGlobalDefinitionStorage")
|
||||
.field("bytes", unsafe { &self.bytes })
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
/// The storage for a WebAssembly global defined within the instance.
|
||||
///
|
||||
/// TODO: Pack the globals more densely, rather than using the same size
|
||||
@@ -461,7 +490,7 @@ mod test_vmtable_definition {
|
||||
#[derive(Debug, Clone)]
|
||||
#[repr(C, align(16))]
|
||||
pub struct VMGlobalDefinition {
|
||||
storage: [u8; 16],
|
||||
storage: VMGlobalDefinitionStorage,
|
||||
// If more elements are added here, remember to add offset_of tests below!
|
||||
}
|
||||
|
||||
@@ -502,207 +531,158 @@ mod test_vmglobal_definition {
|
||||
impl VMGlobalDefinition {
|
||||
/// Construct a `VMGlobalDefinition`.
|
||||
pub fn new() -> Self {
|
||||
Self { storage: [0; 16] }
|
||||
Self {
|
||||
storage: VMGlobalDefinitionStorage { bytes: [0; 16] },
|
||||
}
|
||||
}
|
||||
|
||||
/// Return a reference to the value as an i32.
|
||||
/// Return the value as an i32.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// To be defined (TODO).
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
pub unsafe fn as_i32(&self) -> &i32 {
|
||||
&*(self.storage.as_ref().as_ptr() as *const i32)
|
||||
/// If this is not an I32 typed global it is unspecified what value is returned.
|
||||
pub fn to_i32(&self) -> i32 {
|
||||
unsafe { self.storage.as_i32 }
|
||||
}
|
||||
|
||||
/// Return a mutable reference to the value as an i32.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// To be defined (TODO).
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
/// It is the callers responsibility to make sure the global has I32 type.
|
||||
/// Until the returned borrow is dropped, reads and writes of this global
|
||||
/// must be done exclusively through this borrow. That includes reads and
|
||||
/// writes of globals inside wasm functions.
|
||||
pub unsafe fn as_i32_mut(&mut self) -> &mut i32 {
|
||||
&mut *(self.storage.as_mut().as_mut_ptr() as *mut i32)
|
||||
&mut self.storage.as_i32
|
||||
}
|
||||
|
||||
/// Return a reference to the value as a u32.
|
||||
/// Return a reference to the value as an u32.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// To be defined (TODO).
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
pub unsafe fn as_u32(&self) -> &u32 {
|
||||
&*(self.storage.as_ref().as_ptr() as *const u32)
|
||||
/// If this is not an I32 typed global it is unspecified what value is returned.
|
||||
pub fn to_u32(&self) -> u32 {
|
||||
unsafe { self.storage.as_u32 }
|
||||
}
|
||||
|
||||
/// Return a mutable reference to the value as an u32.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// To be defined (TODO).
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
/// It is the callers responsibility to make sure the global has I32 type.
|
||||
/// Until the returned borrow is dropped, reads and writes of this global
|
||||
/// must be done exclusively through this borrow. That includes reads and
|
||||
/// writes of globals inside wasm functions.
|
||||
pub unsafe fn as_u32_mut(&mut self) -> &mut u32 {
|
||||
&mut *(self.storage.as_mut().as_mut_ptr() as *mut u32)
|
||||
&mut self.storage.as_u32
|
||||
}
|
||||
|
||||
/// Return a reference to the value as an i64.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// To be defined (TODO).
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
pub unsafe fn as_i64(&self) -> &i64 {
|
||||
&*(self.storage.as_ref().as_ptr() as *const i64)
|
||||
/// If this is not an I64 typed global it is unspecified what value is returned.
|
||||
pub fn to_i64(&self) -> i64 {
|
||||
unsafe { self.storage.as_i64 }
|
||||
}
|
||||
|
||||
/// Return a mutable reference to the value as an i64.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// To be defined (TODO).
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
/// It is the callers responsibility to make sure the global has I32 type.
|
||||
/// Until the returned borrow is dropped, reads and writes of this global
|
||||
/// must be done exclusively through this borrow. That includes reads and
|
||||
/// writes of globals inside wasm functions.
|
||||
pub unsafe fn as_i64_mut(&mut self) -> &mut i64 {
|
||||
&mut *(self.storage.as_mut().as_mut_ptr() as *mut i64)
|
||||
&mut self.storage.as_i64
|
||||
}
|
||||
|
||||
/// Return a reference to the value as an u64.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// To be defined (TODO).
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
pub unsafe fn as_u64(&self) -> &u64 {
|
||||
&*(self.storage.as_ref().as_ptr() as *const u64)
|
||||
/// If this is not an I64 typed global it is unspecified what value is returned.
|
||||
pub fn to_u64(&self) -> u64 {
|
||||
unsafe { self.storage.as_u64 }
|
||||
}
|
||||
|
||||
/// Return a mutable reference to the value as an u64.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// To be defined (TODO).
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
/// It is the callers responsibility to make sure the global has I64 type.
|
||||
/// Until the returned borrow is dropped, reads and writes of this global
|
||||
/// must be done exclusively through this borrow. That includes reads and
|
||||
/// writes of globals inside wasm functions.
|
||||
pub unsafe fn as_u64_mut(&mut self) -> &mut u64 {
|
||||
&mut *(self.storage.as_mut().as_mut_ptr() as *mut u64)
|
||||
&mut self.storage.as_u64
|
||||
}
|
||||
|
||||
/// Return a reference to the value as an f32.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// To be defined (TODO).
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
pub unsafe fn as_f32(&self) -> &f32 {
|
||||
&*(self.storage.as_ref().as_ptr() as *const f32)
|
||||
/// If this is not an F32 typed global it is unspecified what value is returned.
|
||||
pub fn to_f32(&self) -> f32 {
|
||||
unsafe { self.storage.as_f32 }
|
||||
}
|
||||
|
||||
/// Return a mutable reference to the value as an f32.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// To be defined (TODO).
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
/// It is the callers responsibility to make sure the global has F32 type.
|
||||
/// Until the returned borrow is dropped, reads and writes of this global
|
||||
/// must be done exclusively through this borrow. That includes reads and
|
||||
/// writes of globals inside wasm functions.
|
||||
pub unsafe fn as_f32_mut(&mut self) -> &mut f32 {
|
||||
&mut *(self.storage.as_mut().as_mut_ptr() as *mut f32)
|
||||
}
|
||||
|
||||
/// Return a reference to the value as f32 bits.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// To be defined (TODO).
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
pub unsafe fn as_f32_bits(&self) -> &u32 {
|
||||
&*(self.storage.as_ref().as_ptr() as *const u32)
|
||||
}
|
||||
|
||||
/// Return a mutable reference to the value as f32 bits.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// To be defined (TODO).
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
pub unsafe fn as_f32_bits_mut(&mut self) -> &mut u32 {
|
||||
&mut *(self.storage.as_mut().as_mut_ptr() as *mut u32)
|
||||
&mut self.storage.as_f32
|
||||
}
|
||||
|
||||
/// Return a reference to the value as an f64.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// To be defined (TODO).
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
pub unsafe fn as_f64(&self) -> &f64 {
|
||||
&*(self.storage.as_ref().as_ptr() as *const f64)
|
||||
/// If this is not an F64 typed global it is unspecified what value is returned.
|
||||
pub fn to_f64(&self) -> f64 {
|
||||
unsafe { self.storage.as_f64 }
|
||||
}
|
||||
|
||||
/// Return a mutable reference to the value as an f64.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// To be defined (TODO).
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
/// It is the callers responsibility to make sure the global has F64 type.
|
||||
/// Until the returned borrow is dropped, reads and writes of this global
|
||||
/// must be done exclusively through this borrow. That includes reads and
|
||||
/// writes of globals inside wasm functions.
|
||||
pub unsafe fn as_f64_mut(&mut self) -> &mut f64 {
|
||||
&mut *(self.storage.as_mut().as_mut_ptr() as *mut f64)
|
||||
}
|
||||
|
||||
/// Return a reference to the value as f64 bits.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// To be defined (TODO).
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
pub unsafe fn as_f64_bits(&self) -> &u64 {
|
||||
&*(self.storage.as_ref().as_ptr() as *const u64)
|
||||
}
|
||||
|
||||
/// Return a mutable reference to the value as f64 bits.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// To be defined (TODO).
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
pub unsafe fn as_f64_bits_mut(&mut self) -> &mut u64 {
|
||||
&mut *(self.storage.as_mut().as_mut_ptr() as *mut u64)
|
||||
&mut self.storage.as_f64
|
||||
}
|
||||
|
||||
/// Return a reference to the value as an u128.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// To be defined (TODO).
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
pub unsafe fn as_u128(&self) -> &u128 {
|
||||
&*(self.storage.as_ref().as_ptr() as *const u128)
|
||||
/// If this is not an V128 typed global it is unspecified what value is returned.
|
||||
pub fn to_u128(&self) -> u128 {
|
||||
unsafe { self.storage.as_u128 }
|
||||
}
|
||||
|
||||
/// Return a mutable reference to the value as an u128.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// To be defined (TODO).
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
/// It is the callers responsibility to make sure the global has V128 type.
|
||||
/// Until the returned borrow is dropped, reads and writes of this global
|
||||
/// must be done exclusively through this borrow. That includes reads and
|
||||
/// writes of globals inside wasm functions.
|
||||
pub unsafe fn as_u128_mut(&mut self) -> &mut u128 {
|
||||
&mut *(self.storage.as_mut().as_mut_ptr() as *mut u128)
|
||||
&mut self.storage.as_u128
|
||||
}
|
||||
|
||||
/// Return a reference to the value as u128 bits.
|
||||
/// Return a reference to the value as bytes.
|
||||
pub fn to_bytes(&self) -> [u8; 16] {
|
||||
unsafe { self.storage.bytes }
|
||||
}
|
||||
|
||||
/// Return a mutable reference to the value as bytes.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// To be defined (TODO).
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
pub unsafe fn as_u128_bits(&self) -> &[u8; 16] {
|
||||
&*(self.storage.as_ref().as_ptr() as *const [u8; 16])
|
||||
}
|
||||
|
||||
/// Return a mutable reference to the value as u128 bits.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// To be defined (TODO).
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
pub unsafe fn as_u128_bits_mut(&mut self) -> &mut [u8; 16] {
|
||||
&mut *(self.storage.as_mut().as_mut_ptr() as *mut [u8; 16])
|
||||
/// Until the returned borrow is dropped, reads and writes of this global
|
||||
/// must be done exclusively through this borrow. That includes reads and
|
||||
/// writes of globals inside wasm functions.
|
||||
pub unsafe fn as_bytes_mut(&mut self) -> &mut [u8; 16] {
|
||||
&mut self.storage.bytes
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "wasmer-wasi-experimental-io-devices"
|
||||
version = "1.0.0-alpha4"
|
||||
version = "1.0.0-alpha5"
|
||||
description = "An experimental non-standard WASI extension for graphics"
|
||||
categories = ["wasm"]
|
||||
keywords = ["wasm", "webassembly", "types"]
|
||||
@@ -14,7 +14,7 @@ edition = "2018"
|
||||
maintenance = { status = "experimental" }
|
||||
|
||||
[dependencies]
|
||||
wasmer-wasi = { version = "1.0.0-alpha4", path = "../wasi" }
|
||||
wasmer-wasi = { version = "1.0.0-alpha5", path = "../wasi" }
|
||||
tracing = "0.1"
|
||||
minifb = "0.19"
|
||||
ref_thread_local = "0.0"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "wasmer-wasi"
|
||||
version = "1.0.0-alpha4"
|
||||
version = "1.0.0-alpha5"
|
||||
description = "WASI implementation library for Wasmer WebAssembly runtime"
|
||||
categories = ["wasm", "os"]
|
||||
keywords = ["wasm", "webassembly", "wasi", "sandbox", "ABI"]
|
||||
@@ -21,7 +21,7 @@ getrandom = "0.2"
|
||||
time = "0.1"
|
||||
typetag = "0.1"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
wasmer = { path = "../api", version = "1.0.0-alpha4", default-features = false }
|
||||
wasmer = { path = "../api", version = "1.0.0-alpha5", default-features = false }
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
winapi = "0.3"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "wasmer-types"
|
||||
version = "1.0.0-alpha4"
|
||||
version = "1.0.0-alpha5"
|
||||
description = "Wasmer Common Types"
|
||||
categories = ["wasm", "no-std", "data-structures"]
|
||||
keywords = ["wasm", "webassembly", "types"]
|
||||
|
||||
@@ -21,7 +21,7 @@ except ImportError:
|
||||
|
||||
|
||||
# TODO: find this automatically
|
||||
target_version = "1.0.0-alpha4"
|
||||
target_version = "1.0.0-alpha5"
|
||||
|
||||
# TODO: generate this by parsing toml files
|
||||
dep_graph = {
|
||||
@@ -126,8 +126,11 @@ def main():
|
||||
# sleep for 16 seconds between crates to ensure the crates.io index has time to update
|
||||
# this can be optimized with knowledge of our dep graph via toposort; we can even publish
|
||||
# crates in parallel; however this is out of scope for the first version of this script
|
||||
if no_dry_run:
|
||||
print("Sleeping for 16 seconds to allow the `crates.io` index to update...")
|
||||
time.sleep(16)
|
||||
else:
|
||||
print("In dry-run: not sleeping for crates.io to update.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# A script to update the version of all the crates at the same time
|
||||
PREVIOUS_VERSION='1.0.0-alpha3'
|
||||
NEXT_VERSION='1.0.0-alpha4'
|
||||
PREVIOUS_VERSION='1.0.0-alpha4'
|
||||
NEXT_VERSION='1.0.0-alpha5'
|
||||
|
||||
# quick hack
|
||||
fd Cargo.toml --exec sed -i '' "s/version = \"$PREVIOUS_VERSION\"/version = \"$NEXT_VERSION\"/"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[Setup]
|
||||
AppName=Wasmer
|
||||
AppVersion=1.0.0-alpha4
|
||||
AppVersion=1.0.0-alpha5
|
||||
DefaultDirName={pf}\Wasmer
|
||||
DefaultGroupName=Wasmer
|
||||
Compression=lzma2
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "wasmer-integration-tests-cli"
|
||||
version = "1.0.0-alpha4"
|
||||
version = "1.0.0-alpha5"
|
||||
authors = ["Wasmer Engineering Team <engineering@wasmer.io>"]
|
||||
description = "CLI integration tests"
|
||||
repository = "https://github.com/wasmerio/wasmer"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "wasmer-engine-dummy"
|
||||
version = "1.0.0-alpha4"
|
||||
version = "1.0.0-alpha5"
|
||||
authors = ["Wasmer Engineering Team <engineering@wasmer.io>"]
|
||||
description = "Wasmer placeholder engine"
|
||||
license = "MIT"
|
||||
@@ -8,10 +8,10 @@ edition = "2018"
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
wasmer-types = { path = "../../../lib/wasmer-types", version = "1.0.0-alpha4" }
|
||||
wasmer-compiler = { path = "../../../lib/compiler", version = "1.0.0-alpha4" }
|
||||
wasmer-vm = { path = "../../../lib/vm", version = "1.0.0-alpha4" }
|
||||
wasmer-engine = { path = "../../../lib/engine", version = "1.0.0-alpha4" }
|
||||
wasmer-types = { path = "../../../lib/wasmer-types", version = "1.0.0-alpha5" }
|
||||
wasmer-compiler = { path = "../../../lib/compiler", version = "1.0.0-alpha5" }
|
||||
wasmer-vm = { path = "../../../lib/vm", version = "1.0.0-alpha5" }
|
||||
wasmer-engine = { path = "../../../lib/engine", version = "1.0.0-alpha5" }
|
||||
serde = { version = "1.0", features = ["derive", "rc"], optional = true }
|
||||
serde_bytes = { version = "0.11", optional = true }
|
||||
bincode = { version = "1.2", optional = true }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "wasmer-wast"
|
||||
version = "1.0.0-alpha4"
|
||||
version = "1.0.0-alpha5"
|
||||
authors = ["Wasmer Engineering Team <engineering@wasmer.io>"]
|
||||
description = "wast testing support for wasmer"
|
||||
license = "MIT OR (Apache-2.0 WITH LLVM-exception)"
|
||||
@@ -12,8 +12,8 @@ edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0"
|
||||
wasmer = { path = "../../../lib/api", version = "1.0.0-alpha4", default-features = false }
|
||||
wasmer-wasi = { path = "../../../lib/wasi", version = "1.0.0-alpha4" }
|
||||
wasmer = { path = "../../../lib/api", version = "1.0.0-alpha5", default-features = false }
|
||||
wasmer-wasi = { path = "../../../lib/wasi", version = "1.0.0-alpha5" }
|
||||
wast = "17.0"
|
||||
serde = "1"
|
||||
tempfile = "3"
|
||||
|
||||
Reference in New Issue
Block a user