Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate architecture documents to artifact #154

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .art/settings.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# ---- Artifact Project Settings ----

# Paths containing artifact markdown/toml files
artifact_paths = ["architecture"]

# Paths to exclude when loading artifacts
exclude_artifact_paths = []

# Paths containing code that has artifact links
code_paths = [
"src/",
"lib/",
]

# Paths to exclude when searching through code
exclude_code_paths = [
"lib/emscripten/emtests/",

]


# TODO: change to below
# code_url = "https://github.com/wasmerio/wasmer/blob/master/{file}#L{line}"
code_url = "https://github.com/vitiral/wasmer/blob/art/{file}#L{line}"
55 changes: 55 additions & 0 deletions ARCHITECTURE-NEW.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# SPC-arch
<details>
<summary><b>metadata</b></summary>
<b>partof:</b> <i>none</i></a><br>
<b>parts:</b> <i>none</i></a><br>
<b>file:</b> <a href="https://github.com/vitiral/wasmer/blob/art/architecture/spc.md#L1">architecture/spc.md</a><br>
<b>impl:</b> <a href="https://github.com/vitiral/wasmer/blob/art/src/bin/wasmer.rs#L1">src/bin/wasmer.rs[0]</a><br>
<b>spc:</b>100.00&nbsp;&nbsp;<b>tst:</b>0.00<br>
<hr>
</details>


Wasmer is a binary application which aims to be a universal runtime for wasm.
Currently it is an commandline executable which runs a `.wasm` file like so:

```
wasmer run nginix.wasm
```

See the `README.md` for user documentation and purpose.

Wasmer uses the following components:

- [wabt](https://github.com/pepyakin/wabt-rs): for transforming `.wast` files to `.wasm` and also to run WebAssembly spectests
- [wasmparser](https://github.com/yurydelendik/wasmparser.rs): for parsing the `.wasm` files and translating them into WebAssembly Modules
- [Cranelift](https://github.com/cranestation/cranelift): for compiling WASM function binaries into Machine IR

## High Level Overview

The first time you run `wasmer run <file>`, wasmer will do the following in <a title="/home/rett/open/wasmer/src/bin/wasmer.rs[54]" style="color: #0074D9" href="https://github.com/vitiral/wasmer/blob/art/src/bin/wasmer.rs#L55"><b>.execute_wasm</b></a>:

- Check if `<file>` is a `.wast` file. If so, transform it to `.wasm`
- Check that the provided binary is a valid WebAssembly one. That means, that its binary format starts with `\0asm`.
- If it looks like a WebAssembly file, try to parse it with `webassembly::compile` and generate a `Module` from it
- Create the correct import objects based on whether it is an emscripten file or not. If it is an empscripten file, it will add special imports for it.
- Instantiate the module with the correct imports.
- Try to call the WebAssembly start function, or if unexistent try to search for the one that is exported as `main`.


## Phase 1: Generating the Module / IR

The main entry point is <a title="/home/rett/open/wasmer/lib/runtime/src/lib.rs[125]" style="color: #0074D9" href="https://github.com/vitiral/wasmer/blob/art/lib/runtime/src/lib.rs#L126"><b>.compile</b></a>, but the machinery is really in the default compiler,
the <a title="/home/rett/open/wasmer/lib/clif-backend/src/lib.rs[37]" style="color: #0074D9" href="https://github.com/vitiral/wasmer/blob/art/lib/clif-backend/src/lib.rs#L38"><b>.clif_compiler</b></a>.

As the WebAssembly file is being parsed, it will read the sections in the WebAssembly file (memory, table, function, global and element definitions) using the `ModuleEnv` (<a title="/home/rett/open/wasmer/lib/clif-backend/src/module_env.rs[23]" style="color: #0074D9" href="https://github.com/vitiral/wasmer/blob/art/lib/clif-backend/src/module_env.rs#L24"><b>.module_env</b></a>) as the structure to initial processing and hold this information.

However, the real IR initialization happens while a function body is being parsed/created. That means, when the parser reads the section `(func ...)`.
While the function body is being parsed the corresponding `FuncEnvironment` (<a title="/home/rett/open/wasmer/lib/clif-backend/src/func_env.rs[16]" style="color: #0074D9" href="https://github.com/vitiral/wasmer/blob/art/lib/clif-backend/src/func_env.rs#L17"><b>.func_env</b></a>) methods will be called. This happens in <a title="/home/rett/open/wasmer/lib/clif-backend/src/module_env.rs[386]" style="color: #0074D9" href="https://github.com/vitiral/wasmer/blob/art/lib/clif-backend/src/module_env.rs#L387"><b>.define_function_body</b></a>.

So for example, if the function is using a table, the `make_table` method within that `FuncEnvironment` will be called.
Each of this methods will return the corresponding IR representation.

The `Module` creation will be finished once the parsing is done, and will hold all the function IR as well as the imports/exports.


44 changes: 44 additions & 0 deletions architecture/spc.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# SPC-arch

Wasmer is a binary application which aims to be a universal runtime for wasm.
Currently it is an commandline executable which runs a `.wasm` file like so:

```
wasmer run nginix.wasm
```

See the `README.md` for user documentation and purpose.

Wasmer uses the following components:

- [wabt](https://github.com/pepyakin/wabt-rs): for transforming `.wast` files to `.wasm` and also to run WebAssembly spectests
- [wasmparser](https://github.com/yurydelendik/wasmparser.rs): for parsing the `.wasm` files and translating them into WebAssembly Modules
- [Cranelift](https://github.com/cranestation/cranelift): for compiling WASM function binaries into Machine IR

## High Level Overview

The first time you run `wasmer run <file>`, wasmer will do the following in [[.execute_wasm]]:

- Check if `<file>` is a `.wast` file. If so, transform it to `.wasm`
- Check that the provided binary is a valid WebAssembly one. That means, that its binary format starts with `\0asm`.
- If it looks like a WebAssembly file, try to parse it with `webassembly::compile` and generate a `Module` from it
- Create the correct import objects based on whether it is an emscripten file or not. If it is an empscripten file, it will add special imports for it.
- Instantiate the module with the correct imports.
- Try to call the WebAssembly start function, or if unexistent try to search for the one that is exported as `main`.


## Phase 1: Generating the Module / IR

The main entry point is [[.compile]], but the machinery is really in the default compiler,
the [[.clif_compiler]].

As the WebAssembly file is being parsed, it will read the sections in the WebAssembly file (memory, table, function, global and element definitions) using the `ModuleEnv` ([[.module_env]]) as the structure to initial processing and hold this information.

However, the real IR initialization happens while a function body is being parsed/created. That means, when the parser reads the section `(func ...)`.
While the function body is being parsed the corresponding `FuncEnvironment` ([[.func_env]]) methods will be called. This happens in [[.define_function_body]].

So for example, if the function is using a table, the `make_table` method within that `FuncEnvironment` will be called.
Each of this methods will return the corresponding IR representation.

The `Module` creation will be finished once the parsing is done, and will hold all the function IR as well as the imports/exports.

1 change: 1 addition & 0 deletions lib/clif-backend/src/func_env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use wasmer_runtime_core::{
vm,
};

/// #SPC-arch.func_env
pub struct FuncEnv<'env, 'module, 'isa> {
env: &'env ModuleEnv<'module, 'isa>,
}
Expand Down
3 changes: 3 additions & 0 deletions lib/clif-backend/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ extern crate serde;

use wasmparser::{self, WasmDecoder};

/// An empty struct to implement logic needed for Cranelift internals.
///
/// See the design (#SPC-arch.clif_compiler) for more information.
pub struct CraneliftCompiler {}

impl CraneliftCompiler {
Expand Down
5 changes: 5 additions & 0 deletions lib/clif-backend/src/module_env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ use wasmer_runtime_core::{
units::Pages,
};

/// Module environment for cranelift compiler.
///
/// See the design (#SPC-arch.module_env) for more details.
pub struct ModuleEnv<'module, 'isa> {
pub module: &'module mut Module,
isa: &'isa isa::TargetIsa,
Expand Down Expand Up @@ -380,6 +383,8 @@ impl<'module, 'isa, 'data> ModuleEnvironment<'data> for ModuleEnv<'module, 'isa>
}

/// Provides the contents of a function body.
///
/// design: #SPC-arch.define_function_body
fn define_function_body(&mut self, body_bytes: &'data [u8]) -> cranelift_wasm::WasmResult<()> {
let mut func_translator = FuncTranslator::new();

Expand Down
4 changes: 3 additions & 1 deletion lib/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
//! let value = add_one.call(42)?;
//!
//! assert_eq!(value, 43);
//!
//!
//! Ok(())
//! }
//! ```
Expand Down Expand Up @@ -123,6 +123,8 @@ pub use self::cache::Cache;
/// compile a module before it can be instantiated
/// (otherwise, the [`instantiate`] function should be used).
///
/// design: #SPC-arch.compile
///
/// [`Module`]: struct.Module.html
/// [`instantiate`]: fn.instantiate.html
///
Expand Down
3 changes: 3 additions & 0 deletions src/bin/wasmer.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/// #SPC-arch
extern crate structopt;

use std::fs::File;
Expand Down Expand Up @@ -50,6 +51,8 @@ fn read_file_contents(path: &PathBuf) -> Result<Vec<u8>, io::Error> {
}

/// Execute a wasm/wat file
///
/// design: #SPC-arch.execute_wasm
fn execute_wasm(options: &Run) -> Result<(), String> {
let wasm_path = &options.path;

Expand Down