From f928756b2b7f26b90d962cc038d4ba68619c1bf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= Date: Mon, 13 Feb 2012 09:45:22 +0100 Subject: 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 --- lib/compiler/src/cerl_inline.erl | 24 +++++++++++++++++++++- lib/compiler/test/compilation_SUITE.erl | 1 + .../test/compilation_SUITE_data/on_load_inline.erl | 23 +++++++++++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 lib/compiler/test/compilation_SUITE_data/on_load_inline.erl (limited to 'lib/compiler') 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 diff --git a/lib/compiler/test/compilation_SUITE.erl b/lib/compiler/test/compilation_SUITE.erl index 664582a3a8..408fd5ed53 100644 --- a/lib/compiler/test/compilation_SUITE.erl +++ b/lib/compiler/test/compilation_SUITE.erl @@ -159,6 +159,7 @@ split({int, N}, <>) -> ?comp(convopts). ?comp(otp_7202). ?comp(on_load). +?comp(on_load_inline). beam_compiler_7(doc) -> "Code snippet submitted from Ulf Wiger which fails in R3 Beam."; diff --git a/lib/compiler/test/compilation_SUITE_data/on_load_inline.erl b/lib/compiler/test/compilation_SUITE_data/on_load_inline.erl new file mode 100644 index 0000000000..322843b61e --- /dev/null +++ b/lib/compiler/test/compilation_SUITE_data/on_load_inline.erl @@ -0,0 +1,23 @@ +-module(on_load_inline). +-export([?MODULE/0]). +-on_load(on_load/0). +-compile(inline). + +?MODULE() -> + [{pid,Pid}] = ets:lookup(on_load_executed, pid), + exit(Pid, kill), + ok. + +on_load() -> + Parent = self(), + spawn(fun() -> + T = ets:new(on_load_executed, [named_table]), + ets:insert(T, {pid,self()}), + Parent ! done, + receive + wait_forever -> ok + end + end), + receive + done -> ok + end. -- cgit v1.2.3