[m-users.] ordering of foreign_proc + foreign_code declarations
Keri Harris
keri at gentoo.org
Sun Jul 26 18:21:47 AEST 2020
Hello.
I have a question regarding the (lexical) ordering of foreign_proc +
foreign_code declarations in a Mercury module. The Mercury Language
Reference Manual contains the following:
Entities declared in ‘pragma foreign_code’ declarations are visible
in ‘pragma foreign_proc’ declarations that specify the same foreign
language and occur in the same Mercury module. [1]
It's unclear to me whether this means that a foreign_code declaration
lexically appearing *after* a foreign_proc declaration in the same
Mercury module must be visible to that foreign_proc. Experimentation
shows that the generated foreign language source file produces
different orderings depending on the grade:
$ cat my_module.m
:- module my_module.
:- interface.
:- import_module io.
:- pred my_pred(io::di, io::uo) is det.
:- implementation.
:- pragma foreign_proc(c,
my_pred(IO0::di, IO::uo),
[will_not_call_mercury, promise_pure, thread_safe], "
(void)my_var;
IO = IO0;
").
:- pragma foreign_code(c, "
int my_var;
").
$ mmc --make hlc.gc libmy_module
Making Mercury/int3s/my_module.int3
Making Mercury/ints/my_module.int
Making Mercury/cs/my_module.c
Making Mercury/os/my_module.o
Making libmy_module.a
Making Mercury/os/my_module.pic_o
Making libmy_module.so
$ grep "my_pred\|my_var" Mercury/cs/my_module.c
int my_var;
my_module__my_pred_2_p_0(void)
#define MR_PROC_LABEL my_module__my_pred_2_p_0
(void)my_var;
$ mmc --make asm_fast.gc libmy_module
Making Mercury/int3s/my_module.int3
Making Mercury/ints/my_module.int
Making Mercury/cs/my_module.c
Making Mercury/os/my_module.o
my_module.m: In function ‘my_module_module0’:
my_module.m:14:11: error: ‘my_var’ undeclared (first use in this
function)
my_module.m:14:11: note: each undeclared identifier is reported only
once for each function it appears in
** Error making `Mercury/os/my_module.o'.
$ grep "my_pred\|my_var" Mercury/cs/my_module.c
MR_def_extern_entry(my_module__my_pred_2_0)
MR_init_entry1(my_module__my_pred_2_0);
MR_INIT_PROC_LAYOUT_ADDR(mercury__my_module__my_pred_2_0);
/* code for 'my_pred'/2 mode 0 */
MR_define_entry(mercury__my_module__my_pred_2_0);
#define MR_PROC_LABEL mercury__my_module__my_pred_2_0
(void)my_var;
int my_var;
I noticed this difference in behaviour when investigating a build
failure of extras/mopenssl using libressl (or older versions of OpenSSL
where CRYPTO_set_id_callback/CRYPTO_set_locking_callback are not
defined away to nothing). mopenssl.m contains:
:- pragma foreign_proc(c,
ssl_library_init(IO0::di, IO::uo),
[thread_safe, promise_pure, tabled_for_io], "
<snip>
CRYPTO_set_id_callback((unsigned long (*)())pthreads_thread_id);
CRYPTO_set_locking_callback((void (*)())pthreads_locking_callback);
<snip>
").
:- pragma foreign_code(c, "
#ifdef MR_THREAD_SAFE
void pthreads_locking_callback(int mode, int type, char *file, int
line)
{
<snip>
}
unsigned long pthreads_thread_id(void)
{
<snip>
}
#endif
").
A compile can lead to:
mmc --compile-to-c --grade asm_fast.par.gc.stseg mopenssl >
mopenssl.err 2>&1
mgnuc --grade asm_fast.par.gc.stseg -- -O2 -pipe -march=native
-fno-diagnostics-color -c mopenssl.c -o mopenssl.o
mopenssl.m: In function ‘mopenssl_module10’:
mopenssl.m:116:49: error: ‘pthreads_thread_id’ undeclared (first use in
this function)
mopenssl.m:116:49: note: each undeclared identifier is reported only
once for each function it appears in
mopenssl.m:116:5: warning: function declaration isn’t a prototype [-
Wstrict-prototypes]
mopenssl.m:117:45: error: ‘pthreads_locking_callback’ undeclared (first
use in this function); did you mean ‘CRYPTO_set_locking_callback’?
mopenssl.m:117:5: warning: function declaration isn’t a prototype [-
Wstrict-prototypes]
mopenssl.m: At top level:
mopenssl.m:125:6: warning: no previous prototype for
‘pthreads_locking_callback’ [-Wmissing-prototypes]
mopenssl.m:135:15: warning: no previous prototype for
‘pthreads_thread_id’ [-Wmissing-prototypes]
Thanks
Keri
[1]
https://www.mercurylang.org/information/doc-latest/mercury_ref/Adding-foreign-definitions.html
More information about the users
mailing list