WebAssembly (Wasm) runtimes

Timothy McCallum
Wasm
Published in
5 min readMay 7, 2022

This article discusses WebAssembly a.k.a Wasm runtimes. In particular, how a WebAssembly runtime can provide additional resources and features. In addition, we introduce a new technology whereby users can create their own WebAssembly runtime plugins.

What are WebAssembly (Wasm) runtimes?

WebAssembly’s execution behaviour is defined in terms of an abstract machine that models the program state. It includes a “stack”, which records operand values and control constructs, and an abstract store containing global state. For each instruction, there is a rule that specifies the effect of its execution on the program state [1]. A WebAssembly runtime facilitates all of the necessary interactions between the “stack” (an ephemeral stand-alone stack-based Virtual Machine (VM)) which runs the WebAssembly binary format and the environment in which that VM exists.

WebAssembly VM

The semantics of WebAssembly are laid out in these official WebAssembly documents (Core Specification, Javascript Interface & Web API). These documents define and explain the core concepts which make up WebAssembly, providing details about values, instructions, tables, modules and much more. The specification documents also dive further into how WebAssembly can be implemented. For example, the WebAssembly Specification Draft Release 2.0 refers to the semantic phases of Webassembly which covers decoding, validation & execution; including instantiating a module and invoking an exported function on a module instance and so forth [2]. The WebAssembly VM fundamentally complies with the WebAssembly specifications outlined above.

WebAssembly Runtime Environment

WebAssembly runtimes essentially provide an opportunity to call the aforementioned VM. Each runtime implementation varies, but typically the runtime allows the WebAssembly binary format to be passed to the VM (upon the VM’s fresh instantiation). The runtime also allows the caller to invoke a function (as well as pass in any required function parameters). The WebAssembly runtime provides a mechanism for the “result” of the function invocation to be returned back to the caller. Lastly, once execution is complete, the WebAssembly runtime is able to terminate the ephemeral VM instance.

As we will see later on, the Wasm runtime implementer can offer varying levels of resources and communication between the VM and the caller.

Client vs Server

Javascript

As we already know, Javascript is one of the core technologies of the web. Javascript can run inside your web browser thanks to the browser’s specific runtime environment which at the core sits a Javascript engine. Perhaps the most well known engine is Google’s open source JavaScript engine, V8 [3]. Interestingly, whilst Javascript can run in a web browser, Javascript can also be run on the server side. For example using either the NodeJS or Deno runtime systems.

WebAssembly

Similarly, WebAssembly can run inside a Web browser (thanks to Javascript engines like V8 adding support for Wasm circa 2007). Thankfully though, from a server-side perspective, WebAssembly does not make any “Web-specific” assumptions or provide Web-specific features itself. In fact, WebAssembly actually aims to support any operating system and so naturally WebAssembly can be run on a variety of hardware & devices. However for this to occur, this WebAssembly runtimes technology must be present.

Photo by Ian Battaglia on Unsplash

WasmEdge

One such WebAssembly runtime is called WasmEdge.

“WasmEdge is a lightweight, high-performance, and extensible WebAssembly runtime. It is the fastest Wasm VM today. WasmEdge is an official sandbox project hosted by the CNCF. Its use cases include modern web application architectures (Isomorphic & Jamstack applications), microservices on the edge cloud, serverless SaaS APIs, embedded functions, smart contracts, and smart devices” [4].

Hosted, as a sandbox project, by Cloud Native Computing Foundation (CNCF), the WasmEdge runtime aims to become an open source “reference implementation” of Wasm and its edge-related extensions.

The WasmEdge runtime is a really interesting example because it offers a lot flexibility in relation to where it can be deployed and also offers a lot of additional resources and features to the caller. Here are a few of WasmEdge’s use cases.

Use cases

WasmEdge works with popular web UI frameworks, such as React, Vue, Yew, and Percy, to support isomorphic server-side rendering (SSR) functions on edge servers. It also provides a lighweight, secure and high-performance runtime for microservices. It is fully compatible with application service frameworks such as Dapr, and service orchestrators like Kubernetes. The benefits of the WasmEdge runtime over native-compiled machine code include security, safety, portability, manageability, and developer productivity. WasmEdge runs on Android, OpenHarmony, and seL4 RTOS devices [5].

Features

Ahead Of Time (AOT) optimizations

Just in Time compiling (JIT) occurs as the caller is interacting with the code, compiling the code on-demand at a server or client level. In contrast, Ahead of Time compiling (AOT) is when code compilation happens during the program’s build time, before the caller interacts with the program. The discussion of which compiling method is “better” is nuanced. For example, assuming that the machine being used to run the program has sufficient computational resources, JIT can be more efficient due to it compiling code on the same machine that will later execute that same code. Additionally, JIT can optimize code in a way that AOT cannot because it can dynamically compile only code which is relevant to the user at any given time. This increases efficiency and decreases memory usage. However, AOT generally has faster initial load times and more consistent performance than JIT. This is in part due to the fact that AOT compilers can implement specific advanced optimisations, which would be considered too onerous for JIT to perform at runtime. WasmEdge runtime actually provides both JIT and AOT modes (based on LLVM AOT).

Extensions

  • Network sockets (Rust and JavaScript SDKs)
  • Async polling (for Rust Future and JS async)
  • Tensorflow inference (Tutorial)
  • Key value storage
  • Database connector
  • Gas meters for resource constraints

Javascript support

  • ES6 module and std API support
  • Implement JS APIs in Rust (Tutorial)
  • Import C native shared library functions as JS functions (Tutorial)

Host functions (static libraries)

Aside from the above, WasmEdge also facilitates customized runtimes with native functions in C or GO.

Custom user-defined plug-ins

As demonstrated in the latest WasmEdge Community Call, WasmEdge has spent a lot of time refactoring their software, creating clear separation between components, which ultimately allows users of the runtime to write their own plugins. Having all of this available inside the actual runtime then enables us to write applications which are powered by this engine / runtime. This essentially does away with using any host functions (static libraries) which is better all round. The driving force behind these updates is questions such as:

“How can a Wasm runtime connect to a database for persistent storage?”

“How can a Wasm runtime use network sockets to make network calls?”

Once created and saved to disk the Wasm runtime can dynamically load these plugins. This new technology allows much greater flexibility and functionality without loosing portability.

If you have any questions or require any additional information please visit the following sites, where you will find links to open source code, documentation and more.

References

[1] https://webassembly.github.io/spec/core/_download/WebAssembly.pdf

[2] https://webassembly.github.io/spec/core/intro/overview.html#semantic-phases

[3] https://chromium.googlesource.com/v8/v8

[4] https://github.com/WasmEdge/WasmEdge

[5] https://wasmedge.org/book/en/intro/use.html

--

--

Timothy McCallum
Wasm
Editor for

I'm a technical writer and copy editor exploring WebAssembly (Wasm), software automation, and Artificial Intelligence (AI) while mastering Rust, Python, & Bash.