WebAssembly as a Universal Binary Format (Part I: Native executables)
Founder & CEO
August 8, 2022
At Wasmer, we have worked tirelessly on making WebAssembly as widely adopted as possible.
One of the things we identified that could help broaden the adoption is using the Wasm binaries to create native executables for any given platform or chipset, so WebAssembly can really become the lingua franca for all the software applications out there.
Given a program.wasm
, we could ideally generate native binaries (that don’t depend on any kind of compilation at runtime) that run anywhere:
program.exe
./program
(Mach-O 64-bit executable x86_64)./program
(Mach-O 64-bit executable arm64)./program
(ELF 64-bit executable x86_64)./program
(ELF 64-bit executable aarch64)A binary that is completely sandboxed and with minimal runtime overhead.
All that we presented is not just a theoretical idea …it’s already fully working in the latest release of Wasmer (3.0.0-beta) 🎉
In this article we will review how we made this possible (thanks to static objects, Zig, and a lot of love!).
There has been similar alternatives, like the great αcτµαlly pδrταblε εxεcµταblε (ape in short) from Justine to generate multi-platform x86 binaries, or GraalVM to generate native executables from Java bytecode. We’ll review them in the Part II of this article series.
If you want to try this on your laptop, please make sure you have the latest beta version of Wasmer installed.
curl https://get.wasmer.io -sSfL | sh -s "3.0.0-beta"
First, let's download wasm2wat.wasm from wapm:
$ curl https://registry-cdn.wapm.io/contents/_/wabt/1.0.12/out/wasi/wasm2wat.wasm -o wasm2wat.wasm
Let's use create-exe (it requires Zig or Clang installed in your system, and Wasmer 3.0.0-beta1):
$ wasmer create-exe wasm2wat.wasm -o ./wasm2wat
Now, let's execute the wasm2wat
standalone binary!
$ ./wasm2wat
usage: wasm2wat [options] filename
Read a file in the WebAssembly binary format, and convert it to
the WebAssembly text format.
examples:
# parse binary file test.wasm and write text file test.wast
$ wasm2wat test.wasm -o test.wat
Note: the wasm2wat binary will actually work standalone in the platform without requiring to have Wasmer installed at all, and it will also be completely sandboxed by default.
As new chipsets are being added and used in the ecosystem (ARM, RISC-V), we need to ensure current tools continue working with them.
If CLI tools start targeting WebAssembly as their end target, we can let Wasmer automatically generate native executables for each platform and chipset, so when new chips and OSS appear, we don’t need to worry about recompiling again our software. They will just simply work.
Apart from this, native binaries are automatically sandboxed and do not have any permissions into the underlying OS unless explicitly determined, making them much safer than the normal binaries we use daily.
create-exe
black magic works?In a nutshell, this is what happens under the hood when calling wasmer create-exe
: we convert the Wasm to a static object file, generating a C header file to help the linker link the Wasm exported functions with the compiled object file symbols, and then we use a C compiler/linker file to join everything together: the static object (generated from the Wasm file), a minimal libwasmer.a (headless, with no compilers) and the WASI glue code.
Now, let’s get into some depth on how we made this possible:
.o
in Linux / macOS or .obj
in Windows).Engine::deserialize_object
.In Wasmer 3.0 we used the power of Zig for doing cross-compilation from the C glue code into other machines.
This made almost trivial to generate a for macOS from Linux (as an example).
$ wasmer create-exe wasm2wat.wasm --target=x86_64-darwin -o ./wasm2wat
$ file ./wasm2wat
./wasm2wat: Mach-O 64-bit executable x86_64
So by default, if you are cross-compiling we try to use zig cc
instead of cc
so we can easily cross compile from one machine to the other with no extra dependencies.
With all these awesome features, we already started the integration of native executables in the Wasmer ecosystem.
Please read the Part II of the article series to see how we integrated the Native Executables into the WebAssembly Package Manager: WAPM:
Syrus Akbary is an enterpreneur and programmer. Specifically known for his contributions to the field of WebAssembly. He is the Founder and CEO of Wasmer, an innovative company that focuses on creating developer tools and infrastructure for running Wasm
Founder & CEO
🚀 First, let’s try it out!
Why this is useful?
🔮 How the `create-exe` black magic works?
⚡️ Zig for Cross-Compilation
wapmwebassemblyregistry
Syrus AkbaryAugust 19, 2022
wapmwasmer registryengineeringregistry
Syrus AkbaryMarch 2, 2022
wapmengineeringregistry
Syrus AkbaryApril 22, 2022