Skip to content
🃏 Decompile Elixir modules to Erlang abstract code
Elixir
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
config
lib
test
.gitignore
LICENSE
README.md
mix.exs
mix.lock

README.md

Decompilerl

Decompile Elixir/BEAM to Erlang abstract code.

Why?

When I started working with Elixir, my biggest gripe (coming from the Erlang world) was that I had no clue what it really compiled to.

This tool aims to provide some answers.

Sample question: what is a struct?

defmodule TheStruct do
  defstruct foo: 1

  alias __MODULE__

  def new do
    %TheStruct{foo: 2}
  end
end
Decompilerl.decompile(TheStruct)
%% lots of irrelevant stuff...

'__struct__'() ->
    #{'__struct__' => 'Elixir.TheStruct', foo => 1}.

'__struct__'(_@1) ->
    {_@6, _@7} = 'Elixir.Enum':reduce(_@1,
                                      {'__struct__'(), []},
                                      fun ({_@2, _@3}, {_@4, _@5}) ->
                                              {maps:update(_@2, _@3, _@4),
                                               lists:delete(_@2, _@5)}
                                      end),
    case _@7 of
      [] -> _@6;
      _ ->
          erlang:error('Elixir.ArgumentError':exception(<<"the following keys must also be given "
                                                          "when building ",
                                                          "struct ",
                                                          ('Elixir.Kernel':inspect('Elixir.TheStruct'))/binary,
                                                          ": ",
                                                          ('Elixir.Kernel':inspect(_@7))/binary>>))
    end.

new() ->
    #{'__struct__' => 'Elixir.TheStruct', foo => 2,
      '__struct__' => 'Elixir.TheStruct'}.

There we go! struct is an Erlang map with a special key __struct__ => ?MODULE that allows pattern matching further down the line. Noice!

Command-line interface

You can build Decompilerl as a standalone executable (escript).

$ mix escript.build
Compiled lib/cli.ex
Compiled lib/decompilerl.ex
Generated escript decompilerl with MIX_ENV=dev

$ ./decompilerl

Decompilerl

usage: decompierl <beam_file> [-o <erl_file> | --output=<erl_file>]

Usage

By default, Decompilerl.decompile spits the Erlang abstract code to stdout. When provided with a second (optional) argument, it'll dump it to a file.

$ iex -S mix

iex(1)> Decompilerl.decompile(Decompilerl, "/tmp/foo.erl")
You can’t perform that action at this time.