[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