Skip to content

Commit e36c8f1

Browse files
committed
Merge pull request #1200 from pguyot/w25/fix-undef-error
Fix undef error when a function is undefined These changes are made under both the "Apache 2.0" and the "GNU Lesser General Public License 2.1 or later" license terms (dual license). SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
2 parents 0769412 + 79c29d4 commit e36c8f1

File tree

5 files changed

+83
-0
lines changed

5 files changed

+83
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ in ESP-IDF Kconfig options.
3030
`02411048` was not completely right, and it was converting match context to bogus binaries.
3131
- Fix creation of multiple links for the same process and not removing link at trapped exits.
3232
See issue [#1193](https://github.com/atomvm/AtomVM/issues/1193).
33+
- Fix error that is raised when a function is undefined
3334

3435
## [0.6.2] - 25-05-2024
3536

src/libAtomVM/opcodesswitch.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1116,10 +1116,12 @@ static void destroy_extended_registers(Context *ctx, unsigned int live)
11161116
} else { \
11171117
fun_module = globalcontext_get_module(ctx->global, module_name); \
11181118
if (IS_NULL_PTR(fun_module)) { \
1119+
SET_ERROR(UNDEF_ATOM); \
11191120
HANDLE_ERROR(); \
11201121
} \
11211122
label = module_search_exported_function(fun_module, function_name, fun_arity, glb); \
11221123
if (UNLIKELY(label == 0)) { \
1124+
SET_ERROR(UNDEF_ATOM); \
11231125
HANDLE_ERROR(); \
11241126
} \
11251127
} \
@@ -5108,11 +5110,13 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb)
51085110
Module *target_module = globalcontext_get_module(ctx->global, module_name);
51095111
if (IS_NULL_PTR(target_module)) {
51105112
pc = orig_pc;
5113+
SET_ERROR(UNDEF_ATOM);
51115114
HANDLE_ERROR();
51125115
}
51135116
int target_label = module_search_exported_function(target_module, function_name, arity, glb);
51145117
if (target_label == 0) {
51155118
pc = orig_pc;
5119+
SET_ERROR(UNDEF_ATOM);
51165120
HANDLE_ERROR();
51175121
}
51185122
ctx->cp = module_address(mod->module_index, pc - code);
@@ -5164,10 +5168,12 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb)
51645168
} else {
51655169
Module *target_module = globalcontext_get_module(ctx->global, module_name);
51665170
if (IS_NULL_PTR(target_module)) {
5171+
SET_ERROR(UNDEF_ATOM);
51675172
HANDLE_ERROR();
51685173
}
51695174
int target_label = module_search_exported_function(target_module, function_name, arity, glb);
51705175
if (target_label == 0) {
5176+
SET_ERROR(UNDEF_ATOM);
51715177
HANDLE_ERROR();
51725178
}
51735179
JUMP_TO_LABEL(target_module, target_label);

tests/erlang_tests/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ compile_erlang(test_system_info)
178178
compile_erlang(test_binary_to_term)
179179
compile_erlang(test_selective_receive)
180180
compile_erlang(test_timeout_not_integer)
181+
compile_erlang(test_undef)
181182

182183
compile_erlang(test_funs0)
183184
compile_erlang(test_funs1)
@@ -637,6 +638,7 @@ add_custom_target(erlang_test_modules DEPENDS
637638
test_binary_to_term.beam
638639
test_selective_receive.beam
639640
test_timeout_not_integer.beam
641+
test_undef.beam
640642

641643
test_funs0.beam
642644
test_funs1.beam

tests/erlang_tests/test_undef.erl

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
%
2+
% This file is part of AtomVM.
3+
%
4+
% Copyright 2024 Paul Guyot <pguyot@kallisys.net>
5+
%
6+
% Licensed under the Apache License, Version 2.0 (the "License");
7+
% you may not use this file except in compliance with the License.
8+
% You may obtain a copy of the License at
9+
%
10+
% http://www.apache.org/licenses/LICENSE-2.0
11+
%
12+
% Unless required by applicable law or agreed to in writing, software
13+
% distributed under the License is distributed on an "AS IS" BASIS,
14+
% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
% See the License for the specific language governing permissions and
16+
% limitations under the License.
17+
%
18+
% SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
19+
%
20+
21+
-module(test_undef).
22+
23+
-export([
24+
start/0, test_undef_apply/1, test_undef_apply_last/1, test_undef_call/1, apply_last/2, call/1
25+
]).
26+
27+
start() ->
28+
ok = test_undef_apply(test_undef_module),
29+
ok = test_undef_apply(?MODULE),
30+
ok = test_undef_apply_last(test_undef_module),
31+
ok = test_undef_apply_last(?MODULE),
32+
ok = test_undef_call(test_undef_module),
33+
ok = test_undef_call(?MODULE),
34+
0.
35+
36+
test_undef_apply(Module) ->
37+
% At least with OTP27 compiler, this compiles to:
38+
% {apply,0}.
39+
try
40+
Module:undef_function(),
41+
{unexpected, ok}
42+
catch
43+
error:undef -> ok;
44+
T:V -> {unexpected, T, V}
45+
end.
46+
47+
test_undef_apply_last(Module) ->
48+
try
49+
apply_last(Module, undef_function),
50+
{unexpected, ok}
51+
catch
52+
error:undef -> ok;
53+
T:V -> {unexpected, T, V}
54+
end.
55+
56+
apply_last(Module, Func) ->
57+
% At least with OTP27 compiler, this compiles to:
58+
% {apply_last,0,0}.
59+
Module:Func().
60+
61+
test_undef_call(Module) ->
62+
try
63+
call(fun Module:undef_function/0),
64+
{unexpected, ok}
65+
catch
66+
error:undef -> ok;
67+
T:V -> {unexpected, T, V}
68+
end.
69+
70+
call(Fun) ->
71+
% At least with OTP27 compiler, this compiles to:
72+
% {apply_last,0,0}.
73+
Fun().

tests/test.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,7 @@ struct Test tests[] = {
358358
TEST_CASE(test_binary_to_term),
359359
TEST_CASE(test_selective_receive),
360360
TEST_CASE(test_timeout_not_integer),
361+
TEST_CASE(test_undef),
361362
TEST_CASE(test_bs),
362363
TEST_CASE(test_bs_int),
363364
TEST_CASE(test_bs_int_unaligned),

0 commit comments

Comments
 (0)