对于如下源码test.erl1
2
3
4-module(test).
-export([fac/1]).
fac(1) -> 1;
fac(N) -> N * fac(N - 1).
在各编译期有不同的形式
可以在erlang shell里使用c命令编译
Erlang/OTP 18 [erts-7.0] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false]
Eshell V7.0 (abort with ^G)
1>c(test, 'P')
.
Warning: No object file created - nothing loaded
也可以用erlc
$ erlc -help
Usage: erlc [Options] file.ext ...
Options:
...
-E generate listing of expanded code (Erlang compiler)
-S generate assembly listing (Erlang compiler)
-P generate listing of preprocessed code (Erlang compiler)
+term pass the Erlang term unchanged to the compiler
P
生成经过预处理和parse transform的代码, 扩展名.P
$ erlc -P test.erl1
2
3
4
5
6
7
8
9
10-file("test.erl", 1).
-module(test).
-export([fac/1]).
fac(1) ->
1;
fac(N) ->
N * fac(N - 1).
E
生成经过所有源代码处理的代码, 扩展名.E
$ erlc -E test.erl1
2
3
4
5
6
7
8
9
10
11
12-file("test.erl", 1).
fac(1) ->
1;
fac(N) ->
N * fac(N - 1).
module_info() ->
erlang:get_module_info(test).
module_info(X) ->
erlang:get_module_info(test, X).
S
生成中间汇编码, 扩展名.S
$ erlc -S test.erl1
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{module, test}. %% version = 0
{exports, [{fac,1},{module_info,0},{module_info,1}]}.
{attributes, []}.
{labels, 8}.
{function, fac, 1, 2}.
{label,1}.
{line,[{location,"test.erl",3}]}.
{func_info,{atom,test},{atom,fac},1}.
{label,2}.
{test,is_eq_exact,{f,3},[{x,0},{integer,1}]}.
return.
{label,3}.
{allocate_zero,1,1}.
{line,[{location,"test.erl",4}]}.
{gc_bif,'-',{f,0},1,[{x,0},{integer,1}],{x,1}}.
{move,{x,0},{y,0}}.
{move,{x,1},{x,0}}.
{line,[{location,"test.erl",4}]}.
{call,1,{f,2}}.
{line,[{location,"test.erl",4}]}.
{gc_bif,'*',{f,0},1,[{y,0},{x,0}],{x,0}}.
{deallocate,1}.
return.
{function, module_info, 0, 5}.
{label,4}.
{line,[]}.
{func_info,{atom,test},{atom,module_info},0}.
{label,5}.
{move,{atom,test},{x,0}}.
{line,[]}.
{call_ext_only,1,{extfunc,erlang,get_module_info,1}}.
{function, module_info, 1, 7}.
{label,6}.
{line,[]}.
{func_info,{atom,test},{atom,module_info},1}.
{label,7}.
{move,{x,0},{x,1}}.
{move,{atom,test},{x,0}}.
{line,[]}.
{call_ext_only,2,{extfunc,erlang,get_module_info,2}}.
erts_debug:df/1
从beam生成VM opcode, 扩展名dis
$ erl
Erlang/OTP 18 [erts-7.0] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false]Eshell V7.0 (abort with ^G)
1> erts_debug:df(test).
ok
1 | 00007F0BDC63C3D0: i_func_info_IaaI 0 test start_link 0 |
Core Erlang
Core Erlang是Erlang的一种中间表现形式, 尽可能保持语法简单, 稳定和可读性以方便工具解析或手工修改
换句话说,通过Core Erlang我们可以透过语法糖看到真实的代码逻辑
$ erl
Erlang/OTP 18 [erts-7.0] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false]Eshell V7.0 (abort with ^G)
1> c(test,[to_core]).
Warning: No object file created - nothing loaded
ok
1 | module 'test' ['fac'/1, |
参考链接
http://www.cnblogs.com/me-sa/p/know-a-little-erlang-opcode.html
http://blog.yufeng.info/archives/498