[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