-
Notifications
You must be signed in to change notification settings - Fork 68
Expand file tree
/
Copy pathbeam.ex
More file actions
62 lines (55 loc) · 1.98 KB
/
beam.ex
File metadata and controls
62 lines (55 loc) · 1.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
defmodule ElixirScript.Beam do
@moduledoc false
@doc """
Takes a module and finds the expanded AST
from the debug info inside the beam file.
For protocols, this will return a list of
all the protocol implementations
"""
@spec debug_info(atom) :: {:ok | :error, map | binary}
def debug_info(module)
#Replace some modules with ElixirScript versions
def debug_info(module) when module in [String, Agent] do
case debug_info(Module.concat(ElixirScript, module)) do
{:ok, info} ->
{:ok, Map.put(info, :module, module)}
e ->
e
end
end
def debug_info(module) when is_atom(module) do
#TODO: Get modified date from _beam_path to check for cached version?
with {_, beam, _beam_path} <- :code.get_object_code(module),
{:ok, {^module, [debug_info: {:debug_info_v1, backend, data}]}} <- :beam_lib.chunks(beam, [:debug_info]),
{:ok, {^module, attribute_info}} = :beam_lib.chunks(beam, [:attributes]) do
if Keyword.get(attribute_info[:attributes], :protocol) do
get_protocol_implementations(module)
else
backend.debug_info(:elixir_v1, module, data, [])
end
else
:error ->
{:error, "Unknown module"}
{:error,:beam_lib,{:unknown_chunk,"non_existing.beam",:debug_info}} ->
{:error, "Unsupported version of Erlang"}
{:error,:beam_lib,{:missing_chunk, _ , _}} ->
{:error, "Debug info not available"}
{:error,:beam_lib,{:file_error,"non_existing.beam",:enoent}} ->
{:error, "Debug info not available"}
end
end
defp get_protocol_implementations(module) do
implementations = module
|> Protocol.extract_impls(:code.get_path())
|> Enum.map(fn(x) -> Module.concat([module, x]) end)
|> Enum.map(fn(x) ->
case debug_info(x) do
{:ok, info} ->
{x, info}
_ ->
raise "Unable to compile protocol implementation #{inspect x}"
end
end)
{:ok, module, implementations}
end
end