Funs behaving differently after native compilation

Mikael Pettersson mikpe@REDACTED
Thu Jan 12 17:47:20 CET 2006


Joel Reymont writes:
 > Folks,
 > 
 > My funs seem to behave differently when the beams are compiled to  
 > native code.
 > 
 > Is there an explanation to this? I am passing indeed passing funs as  
 > {M, F} and then calling them as per the code below.
 > 
 > Why does it work when the code is byte-compiled and how do I work  
 > around these errors?
 > 
 > monitor(self(), Sock, {gen_udp, close})
 > 
 > monitor(Sock, Closer) ->
 >      receive
 > 	{'DOWN', _, process, _, _} ->
 > 	    Closer(Sock);
 > 	Any ->
 > 	    io:format("Monitor: Unknown:~n~p~n", [Any]),
 > 	    monitor(sock, Closer)
 >      end.
 > 
 > My make file:
 > 
 > {'*',[native]}.
 > 
 > The errors that I get when my code is compiled to native:
 > 
 > =ERROR REPORT==== 12-Jan-2006::15:42:25 ===
 > Error in process <0.31.0> with exit value: {{'EXIT',{{badfun, 
 > {randomplay,script}},[]}},[]}

A simpler test module:
==snip==
-module(bar).
-compile(export_all).

test1() -> bar1({?MODULE,f}, 42).
test2() -> bar2({?MODULE,f}, 42).
test3() -> bar3({?MODULE,f}, 42).

bar1(MF, X) -> MF(X).
bar2(MF, X) -> apply(MF, [X]).
bar3({M,F}, X) -> M:F(X).

f(42) -> ok.
==snip==

In this module, test1() to test3() all work in BEAM mode,
but only test2() and test3() work after compilation to native code:
bar:test1() results in a badfun exception.

HiPE could allow bar:test1() to work. The reason it doesn't is
largely political: some people have strong opinions against the
old-fashioned {M,F} functions, and since there are alternatives,
there have been little incentive to extend the compiler to support
them. A secondary reason is that it would cause code bloat for all
MF(X)-like expressions.

/Mikael



More information about the erlang-questions mailing list