diff options
author | John Högberg <john@erlang.org> | 2020-03-26 15:57:55 +0100 |
---|---|---|
committer | John Högberg <john@erlang.org> | 2020-03-26 17:11:54 +0100 |
commit | 0f0f62de4ebaec00006be70c6d7e700801e77b76 (patch) | |
tree | a44ac80cad17c22f74d888e92f76904486988624 /erts | |
parent | 851a440f5ea208e3a066402b87c734f001a490ec (diff) | |
download | erlang-0f0f62de4ebaec00006be70c6d7e700801e77b76.tar.gz |
erts: Fix external fun application of erlang:apply/3
Fun = fun erlang:apply/3,
... snip ...
Fun(erlang, self, []).
Code like the above would always crash because the CIF was just a
stub that threw `badarg`, and the actual implementation in the
`erlang` module was overwritten after an apply/3-specific loader
hack was removed when refactoring CIF tracing.
Since the CIF was only used for its MFA in an error handling macro,
it's better to declare the MFA in said macro and skip the CIF
altogether.
Diffstat (limited to 'erts')
-rw-r--r-- | erts/emulator/beam/bif.c | 21 | ||||
-rw-r--r-- | erts/emulator/beam/bif.tab | 1 | ||||
-rw-r--r-- | erts/emulator/beam/instrs.tab | 3 | ||||
-rw-r--r-- | erts/emulator/beam/ops.tab | 6 | ||||
-rw-r--r-- | erts/emulator/test/bif_SUITE.erl | 18 |
5 files changed, 19 insertions, 30 deletions
diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c index ef2a1bce81..5beab81b98 100644 --- a/erts/emulator/beam/bif.c +++ b/erts/emulator/beam/bif.c @@ -2358,27 +2358,6 @@ done: } /**********************************************************************/ -/* - * apply/3 is implemented as an instruction and as erlang code in the - * erlang module. - * - * There is only one reason that apply/3 is included in the BIF table: - * The error handling code in the beam emulator passes the pointer to - * this function to the error handling code if the apply instruction - * fails. The error handling use the function pointer to lookup - * erlang:apply/3 in the BIF table. - * - * This function will never be called. (It could be if init did something - * like this: apply(erlang, apply, [M, F, A]). Not recommended.) - */ - -BIF_RETTYPE apply_3(BIF_ALIST_3) -{ - BIF_ERROR(BIF_P, BADARG); -} - - -/**********************************************************************/ /* integer to float */ diff --git a/erts/emulator/beam/bif.tab b/erts/emulator/beam/bif.tab index 5d60a0f140..5fb8441a15 100644 --- a/erts/emulator/beam/bif.tab +++ b/erts/emulator/beam/bif.tab @@ -46,7 +46,6 @@ ubif erlang:abs/1 bif erlang:adler32/1 bif erlang:adler32/2 bif erlang:adler32_combine/3 -bif erlang:apply/3 bif erlang:atom_to_list/1 bif erlang:binary_to_list/1 bif erlang:binary_to_list/3 diff --git a/erts/emulator/beam/instrs.tab b/erts/emulator/beam/instrs.tab index d36f871ab5..697c777825 100644 --- a/erts/emulator/beam/instrs.tab +++ b/erts/emulator/beam/instrs.tab @@ -237,7 +237,8 @@ APPLY(I, Deallocate, Next) { } HANDLE_APPLY_ERROR() { - I = handle_error(c_p, I, reg, &bif_trap_export[BIF_apply_3].info.mfa); + static ErtsCodeMFA apply3_mfa = {am_erlang, am_apply, 3}; + I = handle_error(c_p, I, reg, &apply3_mfa); goto post_error_handling; } diff --git a/erts/emulator/beam/ops.tab b/erts/emulator/beam/ops.tab index 70602c6798..686299b366 100644 --- a/erts/emulator/beam/ops.tab +++ b/erts/emulator/beam/ops.tab @@ -827,9 +827,9 @@ call_ext_only u==2 u$func:erlang:apply/2 => i_apply_fun_only # The apply/3 BIF is an instruction. # -call_ext u==3 u$bif:erlang:apply/3 => i_apply -call_ext_last u==3 u$bif:erlang:apply/3 D => i_apply_last D -call_ext_only u==3 u$bif:erlang:apply/3 => i_apply_only +call_ext u==3 u$func:erlang:apply/3 => i_apply +call_ext_last u==3 u$func:erlang:apply/3 D => i_apply_last D +call_ext_only u==3 u$func:erlang:apply/3 => i_apply_only # # The yield/0 BIF is an instruction diff --git a/erts/emulator/test/bif_SUITE.erl b/erts/emulator/test/bif_SUITE.erl index af27d4d4a9..a5f2e70d71 100644 --- a/erts/emulator/test/bif_SUITE.erl +++ b/erts/emulator/test/bif_SUITE.erl @@ -39,7 +39,8 @@ process_info_blast/1, os_env_case_sensitivity/1, test_length/1, - fixed_apply_badarg/1]). + fixed_apply_badarg/1, + external_fun_apply3/1]). suite() -> [{ct_hooks,[ts_install_cth]}, @@ -55,7 +56,7 @@ all() -> error_stacktrace, error_stacktrace_during_call_trace, group_leader_prio, group_leader_prio_dirty, is_process_alive, process_info_blast, os_env_case_sensitivity, - test_length,fixed_apply_badarg]. + test_length,fixed_apply_badarg,external_fun_apply3]. %% Uses erlang:display to test that erts_printf does not do deep recursion display(Config) when is_list(Config) -> @@ -353,8 +354,6 @@ auto_imports([], Errors) -> extract_functions(M, Abstr) -> [{{M,F,A},Body} || {function,_,F,A,Body} <- Abstr]. -check_stub({erlang,apply,3}, _) -> - ok; check_stub({_,F,A}, B) -> try [{clause,_,Args,[],Body}] = B, @@ -1317,6 +1316,17 @@ fixed_apply_badarg(Config) when is_list(Config) -> ok. +external_fun_apply3(_Config) -> + %% erlang:apply/3 would always badarg when called through an external fun. + + Apply = id(fun erlang:apply/3), + Self = Apply(erlang, self, []), + true = is_pid(Self), + + {'EXIT',{undef,_}} = (catch Apply(does, 'not', [exist])), + + ok. + %% helpers id(I) -> I. |