[m-rev.] for review: --trace-table-io-require

Fergus Henderson fjh at cs.mu.OZ.AU
Fri Jul 19 21:34:29 AEST 2002


On 19-Jul-2002, Zoltan Somogyi <zs at cs.mu.OZ.AU> wrote:
> 
> Until now, programmers could add `tabled_for_io' annotations to foreign_procs
> that do I/O, which asks the compiler to make those foreign_procs idempotent,
> i.e. ensures that they are performed at most once even in the presence of a
> retry operation in the debugger. This change adds a compiler option,
> --trace-table-io-require, which generates an error if a foreign_proc that does
> I/O does not have this annotation. Specifying this option thus ensures
> that all I/O done by the program is idempotent.

Hmm... I don't really understand the rational for these annotations.
What's the point of writing "tabled_for_io" annotations,
if they are required for all foreign_procs that do I/O?
Can't the compiler infer these annotations automatically
from the type?

> +++ browser/dl.m	2002/07/18 05:58:23
> @@ -35,7 +35,7 @@
>  
>  % high-level interface to the C function dlsym().
>  % This version returns a higher-order predicate or function term.
> -% The user must use an inst cast (implemented using pragma c_code)
> +% The user must use an inst cast (implemented using foreign_proc)
>  % to cast this term to the appropriate higher-order inst before calling
>  % it; see dl_test.m for an example of this.

"foriegn_proc" is still not yet officially supported.
So it should be:
... (implemented using pragma c_code or foreign_proc)

>  :- pred high_level_code is semidet.
> -:- pragma c_code(high_level_code, [will_not_call_mercury, thread_safe], "
> +:- pragma foreign_proc("C", high_level_code,
> +	[will_not_call_mercury, promise_pure, tabled_for_io, thread_safe],
> +"
>  #ifdef MR_HIGHLEVEL_CODE
>  	SUCCESS_INDICATOR = MR_TRUE;
>  #else

Why is that tabled_for_io?

> Index: compiler/gcc.m
...
>  :- pred call_gcc_backend(string::in, int::out,
>  		io__state::di, io__state::uo) is det.
> -:- pragma import(call_gcc_backend(in, out, di, uo), "MC_call_gcc_backend").
> +:- pragma import(call_gcc_backend(in, out, di, uo),
> +	[will_not_call_mercury, tabled_for_io],
> +	"MC_call_gcc_backend").

will_not_call_mercury is not correct there.
The GCC back-end will invoke a callback that ends up
calling back to Mercury code from the Mercury compiler front-end.

Likewise in browser/dl.m:
> -:- pragma c_code(dlopen(FileName::in, Mode::in, Scope::in, Result::out,
> -               _IO0::di, _IO::uo), [], "
> -{
> +:- pragma foreign_proc("C",
> +       dlopen(FileName::in, Mode::in, Scope::in, Result::out,
> +               _IO0::di, _IO::uo),
> +       [will_not_call_mercury, promise_pure, tabled_for_io],
> +"{

As the comment two lines above this code says,
dlopen() could invoke module initializers (e.g. C++ constructors
for global variables) that could call Mercury code,
so will_not_call_mercury is not safe here.

Likewise for dlclose().

Otherwise this change looks fine.

-- 
Fergus Henderson <fjh at cs.mu.oz.au>  |  "I have always known that the pursuit
The University of Melbourne         |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  |     -- the last words of T. S. Garp.
--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list