From b2f52fb6cd7b6063be859e00e953366c0f9af63e Mon Sep 17 00:00:00 2001 From: jubianchi Date: Wed, 4 Nov 2020 10:06:19 +0100 Subject: [PATCH] doc(migration): Start writing the examples --- docs/migration_to_1.0.0.md | 132 +++++++++++++++++++++++++++++++------ 1 file changed, 111 insertions(+), 21 deletions(-) diff --git a/docs/migration_to_1.0.0.md b/docs/migration_to_1.0.0.md index c05f903697a..112520f76d8 100644 --- a/docs/migration_to_1.0.0.md +++ b/docs/migration_to_1.0.0.md @@ -1,7 +1,7 @@ # Migrating from Wasmer 0.x to Wasmer 1.0.0 Wasmer 1.0.0 is currently in alpha and is our primary focus. This document will -describe the differences between 0.x Wasmer and Wasmer 1.0.0 and provide examples +describe the differences between Wasmer 0.x and Wasmer 1.0.0 and provide examples to make migrating to the new API as simple as possible. Some features are still under development during the alpha of Wasmer 1.0.0. This document @@ -9,36 +9,57 @@ will aim to make clear what these features are. ## Table of Contents -- Rationale for changes in 1.0.0 -- How to use Wasmer 1.0.0 -- Project structure -- TODO: specific differences +- [Rationale for changes in 1.0.0](#rationale-for-changes-in-100) +- [How to use Wasmer 1.0.0](#how-to-use-wasmer-100) + - [Installing Wasmer CLI](#installing-wamser-cli) + - [Using Wasmer 1.0.0](#using-wamser-100) +- [Project structure](#project-structure) +- [Differences](#differences) + - [Instantiating modules](#instantiating-modules) + - [Passing host functions](#passing-host-functions) + - [Accessing the environment as a host function](#accessing-the-environment-as-a-host-function) + - [Error handling](#error-handling) + - [Caching modules](#caching-modules) + - [Metering](#metering) ## Rationale for changes in 1.0.0 -TODO: explain why 1.0.0 exists +Wasmer 0.x was great but as the WASM community and standards evolve we felt the need to make Wasmer also follow these +changes. + +Wasmer 1.x is what we think a necessary rewrite of a big part of the project to make it more future-proof. + +This version introduces many new features and makes using Wasmer more natural. We did a hard work making it as close +to the standard API as possible while always providing good performances, flexibility and stability. + +The rewrite of the Wasmer Runtime also comes with a rewrite of the languages integrations to achieve the same goals: +providing a clearer API and improving the feature set. + +In this document you will discover the major changes between Wasmer 0.x and Wasmer 1.x by highlighting how to use the +new Rust API. ## How to use Wasmer 1.0.0 -### Installing Wasmer +### Installing Wasmer CLI See [wasmer.io] for installation instructions. If you already have wasmer installed, run `wasmer self-update`. -Install the latest versions of wasmer with [wasmer-nightly]. +Install the latest versions of Wasmer with [wasmer-nightly] or by following the steps described in the +documentation: [Getting Started][getting-started]. ### Using Wasmer 1.0.0 -The CLI interface for Wasmer 1.0.0 is mostly the same as it was in Wasmer 0.X. +The CLI interface for Wasmer 1.0.0 is mostly the same as it was in Wasmer 0.x. One difference is that rather than specifying the compiler with `--backend=cranelift`, in Wasmer 1.0.0 we prefer using the name of the backend as a flag directly, for example: `--cranelift`. -The top level crates that users will usually interface with are: +The top-level crates that users will usually interface with are: -- [wasmer] - core API +- [wasmer] - Wasmer's core runtime API - [wasmer-wasi] - Wasmer's WASI implementation - [wasmer-emscripten] - Wasmer's Emscripten implementation - TODO: @@ -47,21 +68,22 @@ See the [examples] to find out how to do specific things in Wasmer 1.0.0. ## Project Structure -![Wasmer depgraph](./deps_dedup.svg) +![Wasmer dependencies graph](./deps_dedup.svg) The figure above shows the core Wasmer crates and their dependencies with transitive dependencies deduplicated. Wasmer 1.0.0 has two core architectural abstractions: engines and compilers. -A compiler is a system that translates Wasm into a format that can be understood -more directly by a real computer. +An engine is a system that processes WASM with a compiler and prepares it to be executed. -An engine is a system that processes Wasm with a compiler and prepares it to be executed. +A compiler is a system that translates WASM into a format that can be understood +more directly by a real computer: machine code. -TODO: better explain what the engine actually does +For example, in the [examples] you'll see that we are using the JIT engine and the Cranelift compiler. The JIT engine +will generate machine code at runtime, using Cranelift, and then execute it. For most uses, users will primarily use the [wasmer] crate directly, perhaps with one of our -provided ABIs such as [wasmer-wasi]. However for users that need finer grained control over +provided ABIs such as [wasmer-wasi]. However, for users that need finer grained control over the behavior of wasmer, other crates such as [wasmer-compiler] and [wasmer-engine] may be used to implement custom compilers and engines respectively. @@ -69,15 +91,79 @@ to implement custom compilers and engines respectively. ### Instantiating modules -TODO: link to example, etc. +With Wasmer 0.x, instantiating a module was a matter of calling `wasmer::compiler::compile` and then calling +`instanciate` on the compiled module. + +While simple, this did not give you full-control over Wasmer's configuration. For example, choosing another compiler +was not straightforward. + +With Wasmer 1.x, we changed this part and made the API look more like how Wasmer works internally to give you more +control: + +```diff +- let module = compile(&wasm_bytes[..])?; ++ let engine = JIT::new(&Cranelift::default()).engine(); ++ let store = Store::new(&engine); ++ let module = Module::new(&store, wasm_bytes)?; +- let instance = module.instantiate(&imports)?; ++ let instance = Instance::new(&module, &import_object)?; +``` + +Note that we did not cover how to create the import object here. This is because this part works the same as it used to +with Wasmer 0.x. + +To get more information on how instantiation now works, have a look at the [dedicated example][instance-example] ### Passing host functions -TODO: link to example showing advanced uses of the import object, show some example code inline and compare it to old wasmer +With Wasmer 0.x passing host functions to the guest was primarily done using the `func!` macro or by directly using +`Func::new` or `DynamicFunc::new`. + +Given we have a function like: + +```rust +fn sum(a: i32, b: i32) -> i32 { + a + b +} +``` + +We want to import this function in the guest module, let's have a look at how it differs between Wasmer 0.x and +Wasmer 1.x: + +```diff +let import_object = imports! { + "env" => { +- "sum" => func!(sum), ++ "sum" => Function::new_native(&store, sum), + } +} +``` + +The above example illustrates how to import what we call "native functions". There were already available in Wasmer +0.x through the `func!` macro or with `Func::new`. + +There is a second flavor for imported functions: dynamic functions. With Wasmer 0;x you would have created such a +function using `DynamicFunc::new`, here is how it's done with Wasmer 1.x: + +```rust +let sum_signature = FunctionType::new(vec![Type::I32, Type::I32], vec![Type::I32]); +let sum = Function::new(&store, &sum_signature, |args| { + let result = args[0].unwrap_I32() + args[1].unwrap_i32(); + + Ok(vec![Value::I32(result)]) +}); +``` + +Both examples address different needs and have their own pros and cons. We encourage you to have a look at the +dedicated example: [Exposing host functions][host-functions-example]. + +Note that having this API for functions now looks more like the other entities APIs: globals, memories, tables. Here is +a quick example introducing each of them: [Imports & Exports][imports-exports-example] ### Accessing the environment as a host function -TODO: link to example showing host functions accessing VM internals such as memory, calling other functions, etc., show some example code inline and compare it to old wasmer +TODO: link to example showing host functions accessing VM internals such as memory, calling other functions, etc., +show some example code inline and compare it to old wasmer ### Error handling @@ -91,7 +177,7 @@ TODO: link to example, etc. TODO: link to example, etc. -[examples]: https://github.com/wasmerio/wasmer/tree/master/examples +[examples]: https://docs.wasmer.io/integrations/examples [wasmer]: https://crates.io/crates/wasmer/1.0.0-alpha3 [wasmer-wasi]: https://crates.io/crates/wasmer-wasi/1.0.0-alpha3 [wasmer-emscripten]: https://crates.io/crates/wasmer-emscripten/1.0.0-alpha3 @@ -99,3 +185,7 @@ TODO: link to example, etc. [wasmer-compiler]: https://crates.io/crates/wasmer-compiler/1.0.0-alpha3 [wasmer.io]: https://wasmer.io [wasmer-nightly]: https://github.com/wasmerio/wasmer-nightly/ +[getting-started]: https://docs.wasmer.io/ecosystem/wasmer/getting-started +[instance-example]: https://docs.wasmer.io/integrations/examples/instance +[imports-exports-example]: https://docs.wasmer.io/integrations/examples/imports-and-exports +[host-functions-example]: https://docs.wasmer.io/integrations/examples/host-functions \ No newline at end of file