aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/src
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2012-02-13 09:45:22 +0100
committerBjörn Gustavsson <[email protected]>2012-02-13 10:29:00 +0100
commitf928756b2b7f26b90d962cc038d4ba68619c1bf5 (patch)
tree6b2ce27df934cd6d2c77d50821e9dfe02a5294af /lib/compiler/src
parentc3fb91d203412c16d008b4c36fb13c0d776d8c46 (diff)
downloadotp-f928756b2b7f26b90d962cc038d4ba68619c1bf5.tar.gz
otp-f928756b2b7f26b90d962cc038d4ba68619c1bf5.tar.bz2
otp-f928756b2b7f26b90d962cc038d4ba68619c1bf5.zip
compiler: Teach the inliner to preserve on_load functions
The inliner was ignorant of on_load functions and would discard them (unless they were exported or referenced). Noticed-by: Yiannis Tsiouris <[email protected]>
Diffstat (limited to 'lib/compiler/src')
-rw-r--r--lib/compiler/src/cerl_inline.erl24
1 files changed, 23 insertions, 1 deletions
diff --git a/lib/compiler/src/cerl_inline.erl b/lib/compiler/src/cerl_inline.erl
index c15103999f..589685d72d 100644
--- a/lib/compiler/src/cerl_inline.erl
+++ b/lib/compiler/src/cerl_inline.erl
@@ -1262,8 +1262,9 @@ i_receive_1(E, Cs, T, B, S) ->
i_module(E, Ctxt, Ren, Env, S) ->
%% Cf. `i_letrec'. Note that we pass a dummy constant value for the
%% "body" parameter.
+ Exps = i_module_exports(E),
{Es, _, Xs1, S1} = i_letrec(module_defs(E), void(),
- module_exports(E), Ctxt, Ren, Env, S),
+ Exps, Ctxt, Ren, Env, S),
%% Sanity check:
case Es of
[] ->
@@ -1276,6 +1277,27 @@ i_module(E, Ctxt, Ren, Env, S) ->
E1 = update_c_module(E, module_name(E), Xs1, module_attrs(E), Es),
{E1, count_size(weight(module), S1)}.
+i_module_exports(E) ->
+ %% If a function is named in an `on_load' attribute, we will
+ %% pretend that it is exported to ensure that it will not be removed.
+ Exps = module_exports(E),
+ Attrs = module_attrs(E),
+ case i_module_on_load(Attrs) of
+ none ->
+ Exps;
+ [{_,_}=FA] ->
+ ordsets:add_element(c_var(FA), Exps)
+ end.
+
+i_module_on_load([{Key,Val}|T]) ->
+ case concrete(Key) of
+ on_load ->
+ concrete(Val);
+ _ ->
+ i_module_on_load(T)
+ end;
+i_module_on_load([]) -> none.
+
%% Binary-syntax expressions are too complicated to do anything
%% interesting with here - that is beyond the scope of this program;
%% also, their construction could have side effects, so even in effect