wa_embedder
View SourceA WebAssembly-to-BEAM compiler for the Erlang ecosystem, written in Erlang. It
parses a .wasm binary (via wa_parser),
translates each function to Erlang abstract format, and compiles and loads the
result as a native BEAM module that you can call directly.
This is the Erlang package. Elixir projects can depend on it directly, or use
the companion wa_embedder_ex package
for an idiomatic Elixir API (WaEmbedder.compile/1..4 + WaEmbedder.ImportError).
Repository layout (monorepo)
Two hex packages live in this repository:
| Path | Package | Tool | Role |
|---|---|---|---|
| repo root | wa_embedder | rebar3 | The compiler core (pure Erlang) |
wa_embedder_ex/ | wa_embedder_ex | mix | Thin Elixir wrapper + the test suite |
test_data/ | — | cmake | Shared WAT/C .wasm fixtures |
The dependency direction is one-way: wa_embedder_ex (Elixir) → wa_embedder
(Erlang) → wa_parser (Erlang). The core has no Elixir dependency.
Installation (rebar3)
%% rebar.config
{deps, [{wa_embedder, "~> 0.1"}]}.Usage
{module, Mod} = wa_embedder:compile("module.wasm"),
Result = Mod:some_exported_fun(Arg).compile/1,2,3,4 compiles and loads the module and returns the
code:load_binary/3 result ({module, ModuleName} on success). Modules with
imports take an imports map resolving each WASM import to an Erlang target
(MFA tuple, external fun, or closure); unsatisfiable imports raise
erlang:error({import_error, Map}).
Development
A nix develop shell provides erlang, elixir, rebar3, and the fixture
toolchain (cmake, ninja, wabt, binaryen). Local sibling dependencies are
wired automatically on shell entry:
- Core → parser: rebar3 has no native
{path, ...}dep, so the shell hook creates a_checkouts/wa_parsersymlink to the sibling../wa_parsercheckout (a rebar3 checkout takes precedence over the{wa_parser, "~> 0.1"}hex dep). - Wrapper → core: the shell sets
WA_EMBEDDER_PATH=..sowa_embedder_ex/mix.exsbuilds against the sibling Erlang core.
Build and test
# Erlang core (repo root)
rebar3 compile
# Elixir wrapper + full fixture suite (in wa_embedder_ex/)
cd wa_embedder_ex && mix test
The test suite lives in wa_embedder_ex/test/ and compiles the WAT/C fixtures
under the repo-root test_data/ (built by CMake/Ninja before the suite runs).
Building the fixtures manually
cd test_data
cmake -B build -G Ninja
ninja -C build # WAT fixtures (default); `ninja -C build c_fixtures` for the C chain
Packaging
Build the hex tarballs without the local dev overrides so the correct hex deps are recorded:
# Core: remove the dev checkout so {wa_parser, "~> 0.1"} is recorded
rm -rf _checkouts && rebar3 hex build
# Wrapper: unset WA_EMBEDDER_PATH so the {:wa_embedder, "~> 0.1"} hex dep is used
cd wa_embedder_ex && env -u WA_EMBEDDER_PATH mix hex.build
Publish order: publish wa_embedder (core) first, then wa_embedder_ex (the
wrapper's hex dep on the core cannot resolve until the core is on hex).
License
Released into the public domain under the Unlicense.