An implementation of the Erlang VM in Rust. We aim to be complete, correct and fast, in that order of importance.
OTP 22+ compatible (sans the distributed bits for now) — all your code should eventually run on Enigma unchanged. Deprecated opcodes won't be supported.
Because it's fun and I've been learning a lot. BEAM and HiPE are awesome, but they're massive (~300k SLOC). A small implementation makes it easier for new people to learn Erlang internals. We also get a platform to quickly iterate on ideas for inclusion into BEAM.
Only prerequisite to building Enigma is Rust. Use rustup to install the latest nightly rust. At this time we don't support stable / beta anymore, because we're relying on async/await, which is scheduled to run in stable some time in Q3 2019.
To boot up OTP you will also need to compile the standard library. At the moment, that relies on the BEAM build system:
git submodule update --init --depth 1
cd otp
/otp_build setup -a
make libs
make local_setup
We hope to simplify this step in the future (once enigma can run the compiler).
Run cargo run
to install dependencies, build and run the VM. By default, it
will boot up the erlang shell (iex also works, but has some rendering bugs).
Expect crashes, but a lot of the functionality is already available.
Pre-built binaries for various platforms will be available, once we reach a certain level of stability.
We implement most of the opcodes, and about half of all BIFs. You can view a detailed progress breakdown on opcodes or BIFs.
init:start
).Process scheduling is implemented on top of rust futures:
Future possibilities:
Until the VM doesn't reach a certain level of completeness, it doesn't make sense to consider these.
Note: NIF/FFI ABI compatibility with OTP is going to be quite some work. But, a rust-style NIF interface will be available. It would also probably be possible to make an adapter compatible with rustler.
Contributors are very welcome!
The easiest way to get started is to look at the notes
folder and pick a BIF
or an opcode to implement. Take a look at src/bif.rs
and the bif
folder on
how other BIFs are implemented. There's also a few issues open with the good first issue
tag, which would also be a good introduction to the internals.
Alternatively, search the codebase for TODO
, FIXME
or unimplemented!
,
those mark various places where a partial implementation exists, but a bit more
work needs to be done.
Test coverage is currently lacking, and there's varying levels of documentation; I will be addressing these soon.
We also have a #enigma channel on the Elixir Slack.