WebAssembly is a great technology. It brings ubiquity to our applications, so they can run anywhere: from browsers to servers, from Windows to Unix, from Desktop to Mobile…
…but not that fast though. 🏃♂️
So once applications are compiled to WebAssembly, how can we make sure they run on all platforms?
Or —in other words — what is the best ABI that all applications should target?
Let’s start from the beginning…
ABI stands for Application Binary Interface (wiki page).
We can see an ABI as a contract between two binary applications, to assure that one binary is able to access certain native functions from the other binary.
Each time we compile a C or C++ application there is a set of system calls that the application will normally use, for example, to open a file, read its contents… or even opening a socket.
The same concept can be applied when we compile applications to WebAssembly. What is the most common & complete set of syscalls that we should run there?
These are the most ABI strategies used for WebAssembly:
- Emscripten: Emscripten defines a subset on top of the POSIX ABI.
- Go: Go doesn’t define any explicit ABI. Different dependencies can plug its own exports into the WebAssembly imported functions. It’s a very flexible approach but can get messy when trying to reach a platform-agnostic application.
Olin, however, takes an interesting approach for its ABI.
Wasmer currently only supports Emscripten. But, Why?
But… wouldn’t be great if there is a common ABI that Go, Rust, C, C++, etc. can all use as a target while being platform-independent?
This way, we would only need to implement the ABI one time and have easy interoperability between different WebAssembly compiled modules in any platform and context.
One initiative that we think will stick on the long term will be creating a new ABI like POSIX, but created specifically for WebAssembly environments: PWSIX.
However, we are still far from having a standard defined that will fit all platforms with a common set of syscalls. Because of that, we think there might be an easier strategy for the short-term: CloudABI.
CloudABI was born with the goal of providing a common permission mechanism on top the syscalls.
WebAssembly provides a secure sandbox which only allows a program to call functions provided by the host environment. CloudABI is a minimal POSIX style API which allows strict control over the resources a program is allowed to access. By combining a secure sandbox and a capabilities-based security host environment, a new finer-grained compute is possible without the overhead of containers or virtualization.
Instead of allowing applications to open arbitrary files on disk and connect to arbitrary systems on the network, you as a user exactly inject those resources that the application should access
So, what can we learn from CloudABI?
Apart from introducing the concept of permissions to execute certain syscalls, it also reduces the number of syscalls needed for the implementer to just 49.
Here’s a great intro on what are all the advantages of using CloudABI: