What is a WASI

From the last article, we have a general idea of what WebAssembly is and how to write some applications with Go. In this article, we will talk about WASI again. After reading this article, we will have a general idea of WebAssembly. This article will also give you a brief overview, but will not go into depth. If you are interested, you will need to do more research on your own.

4. Misinformation About WASI 4. Misinformation about WASI 4. Misinformation about WASI 4. Misinformation about WASI 4.

In the operating system, the application program wants to operate resources through the Kernel. The Kernel provides system interfaces, and different systems (Windows, Linux, Mac, etc.) have different interfaces. For example, The Windows API is used in the Windows system. On Mac or Linux, there are POSIX apis. An application that wants to call across platforms needs to abstract different system calls into interfaces to provide a unified standard. We have tried to write a Wasm Web application before, we need to use JS glue code to run the Wasm module, while JavaScript calls the browser Web API, and then the browser calls the system interface. Wasm in the browser, the interaction with the Kernel is done by the browser, Wasm does not need to worry too much.

So, if Wasm is out of the browser, does it not run? How do we get Wasm to run outside of a Web browser?

To make Wasm run outside of a Web browser, first of all, we need to think about who plays the role of JavaScript and browser? Can Wasm call the physical machine system interface directly? We know that WebAssembly ISA binary instruction set based on virtual instruction set architecture (v-isa), so what WebAssembly needs ISA virtual machine-oriented system interface, why not directly interact with the system? We just need to emulate what JS and browsers do and implement Runtime. Let’s think about how WebAssembly’s system interface standard was designed.

When designing a system interface, there are two very important attributes, portability and security. Portability means that we can convert the same Wasm binary file into different system calls on different systems. Security refers to the control of user access rights during system calls. We cannot directly give third-party packages direct access to system resources. For this reason, we need to construct a sandbox environment that is isolated from system resources. To access system resources, we use the Wasm Runtime to interact with the Kernel, which is done by the browser in the Web browser. When implementing a Wasm Runtime, we need a standard, which is WASI (WebAssembly System Interface), which is still evolving. WASI, as an abstract interface layer, is implemented by Wasm binaries before system calls.

Wasm is compiled without knowing what operating system it is for. Imagine that without WASI, the C/C++ code compiled into the Wasm binary, the corresponding system call referring to one of the environments, could not compile once, run everywhere, and our goal of portability would not be achieved.

The design of WASI

Now that you know what WASI does, let’s look at how WASI was specifically designed.

WASI is designed as a set of modular standard interfaces, of which the most basic core module is WASI-Core. Wasi-core contains wasI abstract function interfaces for file, network, and other related system calls. Here’s a graph from Lin Clark’s blog:

In addition to WASI-Core, other subsets such as “sensors”, “Crypto”, “Processes”, “Multimedia”, etc. are organized as separate submodules.

Using fopen as an example, for C/C++, we created a WASI-sysroot which implements LIBC based on WASI-Core, we compiled source code into wASM binary using WASI-SDK, Finally, the system call is made through __wasi_path_open. In Rust, Rust uses WASi-core directly in the standard library, directly introducing __wasi_path_open.

__wasi_path_open is an abstract system call function generated according to WASI standard. Fopen is a file manipulation function, which is divided into wasI-code subsets. The WASI Runtime we talked about earlier provides portability by implementing subsets such as WASI-Core, and these Runtime engines provide a sandbox environment where the host can choose which WASI-Core functions can be passed in program by program. Only the functions passed in support of system calls. Not all system functions can be called, which ensures security.

Okay, here’s the problem. Wasm makes a lot of sense for Web browsers, even if it’s not supported enough right now; What was the significance of WASI’s emergence? Can’t projects I compiled directly in C/C++ work? Wow, Wasm + WASI is more about the WASI sandbox, which is actually Assembly+Docker. Well, forget Java and the JVM, and don’t ask node.js if it isn’t similar to JavaScript. WASI’s big idea is to write applications in any language that can run efficiently on any platform, and when all the current standards and plans are worked out, this technology will be interesting. All right, hold your breath, and we’ll come back in 10 years, and we’ll see what happens.

WASI Runtime is introduced

By now you should know what WASI Runtime does. If you’re not sure, you should get a good idea of where Runtime fits into the picture below. Here’s how Wasm functions are implemented on different engines:

Wasmtime, Wasmer are some of the more popular Runtime implementations. Node.js is a JavaScript runtime based on the Chrome V8 engine, which was designed for JavaScript out of the browser itself, so naturally Wasm WASI has already been supported.

Wasmtime comes from the Byte Consortium, which Mozilla and others have formed to promote WebAssembly and promote open source Wasm.

Write wasI-based applications

When we discussed Wasm on the Web in our last article, we wrote code in high-level languages (C/C++, Rust, Go, etc.) and compiled it directly into Wasm binaries. However, note that This is done using tools or language compilers based on JavaScript apis to convert to wASM binaries, which still end up using JavaScript calls that call the browser and then interact with the kernel (as wASM currently supports, We’ll keep an eye on what happens next).

So if we were to write Wasm using WASI, not relying on browsers, not relying on JavaScript, then we wouldn’t be able to do it through the current tool chain that only supports embedding into the Web, we would need to do it with a wasI-enabled runtime, Current WASI Runtime support is not very good because the WASI standard is still evolving.

However, let’s look at WASI in action with an example.

Wasmer

Let’s write a simple Demo using the Wasmer runtime as an example. Wasmer has better support for various languages, and even maintains WAPM as a package management tool for Wasm Modules.

To install WASMER (may require scientific Internet access) :

curl https://get.wasmer.io -sSfL | sh
Copy the code

The installation is successful. View the version:

$wasmer --version wasmer 1.0.2Copy the code

We won’t go into the details of how wasmer works, but the command-line wasmer –help provides a detailed description of the CLI toolchain.

Rust is by far the best supported because WASI, Wasmer, and the like are themselves developed based on Rust. Still, we’re going to use Go as our development language. Ok, Go + WASI.

Wasmer-go

Because Wasmer is written in Rust, support packages for different languages are required. Wasmer-go is the Wasmer implementation of GO. In fact, WASMER-Go is directly supported by embedding a Wasmer.

Install wasmer – go:

go get github.com/wasmerio/wasmer-go/wasmer
Copy the code

We will support Wasm using WASmer-Go in two ways:

  • Write the WAT text format and then introduce it into the program;
  • Import wASM module files directly;

If I import wASM module files directly, can I compile with Go Build? ** not currently! ** We want to use Go to write Wasm, but we use Go to write functions and compile them using the Go tool chain. Wasm is currently not available in Wasmer Runtime, because the Go compiler converts.wasm to JS only. Only available in browsers, Wasm in the Go compiler is experimental, and WASI is not yet supported. Follow up. (Now 2021-03-10)

You can use Rust to write.rs to.wasm and then import it, although this is strange because I’m using Wasmer-Go and I have to find a tool chain to build wASM. Otherwise, I’ll just write WAT for now.

Go Demo

Let’s run through the official example:

Package the main import (" FMT "" github.com/wasmerio/wasmer-go/wasmer") func main () {/ / manual WAT to write text wasmBytes: = [] byte (` (module (type (func (param i32 i32) (result i32))) (func (type 0) local.get 0 local.get 1 i32.add) (export "sum" (func NewEngine := wasmer.newengine () // Create a storage space store := wasmer.newStore (engine) err := wasmer.NewModule(store, wasmBytes) if err ! = nil { fmt.Println("Failed to compile module:", NewImportObject() := wasmer.newImportobject (); // Initialize the WebAssembly module into the object instance. err := wasmer.NewInstance(module, importObject) if err ! = nil {panic(FMT.Sprintln("Failed to instantiate the module:", err))} err := instance.Exports.GetFunction("sum") if err ! = nil {panic(ftt.sprintln ("Failed to get the 'add_one' function:", err))} result, err := sum(1, 2) if err! Println("Results of 'sum' :", Results of 'sum' :", Results of 'sum' :", result) // Output: // Results of `sum`: 3 }Copy the code

Execute this program:

$ go run main.go
Results of `sum`: 3
Copy the code

I got the right answer. Ok, actually Go writing WASI and I think the handling example is enough.

summary

For now, WE can only say what we are interested in and have fun with WASI. It is not recommended to spend too much time. After all, many things are still unclear. For WebAssembly applications, let’s focus first on the Web, which is already showing its edge and some people are trying it out.

——-

Interested can follow the public account: write a line of code to touch a fish, receive the latest tweets.