1%%
2%% %CopyrightBegin%
3%%
4%% Copyright Ericsson AB 1997-2018. All Rights Reserved.
5%%
6%% Licensed under the Apache License, Version 2.0 (the "License");
7%% you may not use this file except in compliance with the License.
8%% You may obtain a copy of the License at
9%%
10%%     http://www.apache.org/licenses/LICENSE-2.0
11%%
12%% Unless required by applicable law or agreed to in writing, software
13%% distributed under the License is distributed on an "AS IS" BASIS,
14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15%% See the License for the specific language governing permissions and
16%% limitations under the License.
17%%
18%% %CopyrightEnd%
19%%
20-module(beam_listing).
21
22-export([module/2]).
23
24-include("core_parse.hrl").
25-include("v3_kernel.hrl").
26-include("beam_ssa.hrl").
27-include("beam_disasm.hrl").
28
29-import(lists, [foreach/2]).
30
31-type code() :: cerl:c_module()
32              | beam_utils:module_code()
33              | #k_mdef{}
34              | [_].                            %form-based format
35
36-spec module(file:io_device(), code()) -> 'ok'.
37
38module(File, #c_module{}=Core) ->
39    %% This is a core module.
40    io:put_chars(File, core_pp:format(Core));
41module(File, #k_mdef{}=Kern) ->
42    %% This is a kernel module.
43    io:put_chars(File, v3_kernel_pp:format(Kern));
44    %%io:put_chars(File, io_lib:format("~p~n", [Kern]));
45module(File, #b_module{name=Mod,exports=Exp,attributes=Attr,body=Fs}) ->
46    io:format(File, "module ~p.\n", [Mod]),
47    io:format(File, "exports ~p.\n", [Exp]),
48    io:format(File, "attributes ~p.\n\n", [Attr]),
49    PP = [beam_ssa_pp:format_function(F) || F <- Fs],
50    io:put_chars(File, lists:join($\n, PP));
51module(Stream, {Mod,Exp,Attr,Code,NumLabels}) ->
52    %% This is output from v3_codegen.
53    io:format(Stream, "{module, ~p}.  %% version = ~w\n",
54	      [Mod, beam_opcodes:format_number()]),
55    io:format(Stream, "\n{exports, ~p}.\n", [Exp]),
56    io:format(Stream, "\n{attributes, ~p}.\n", [Attr]),
57    io:format(Stream, "\n{labels, ~p}.\n", [NumLabels]),
58    foreach(
59      fun ({function,Name,Arity,Entry,Asm}) ->
60	      io:format(Stream, "\n\n{function, ~w, ~w, ~w}.\n",
61			[Name, Arity, Entry]),
62	      io:put_chars(Stream, format_asm(Asm))
63      end, Code);
64module(Stream, [_|_]=Fs) ->
65    %% Form-based abstract format.
66    foreach(fun (F) -> io:format(Stream, "~p.\n", [F]) end, Fs).
67
68format_asm([{label,L}|Is]) ->
69    [io_lib:format("  {label,~p}.\n", [L])|format_asm(Is)];
70format_asm([I|Is]) ->
71    [io_lib:format("    ~p", [I]),".\n"|format_asm(Is)];
72format_asm([]) -> [].
73