[m-rev.] for review: make I/O tabling respect pragma no_inline

Julien Fischer juliensf at cs.mu.OZ.AU
Wed Sep 14 17:18:13 AEST 2005


On Wed, 14 Sep 2005, Ian MacLarty wrote:

...

> > > tests/debugger/Mercury.options:
> > > tests/debugger/Mmakefile:
> > > tests/debugger/io_tab_goto.data:
> > > tests/debugger/io_tab_goto.exp:
> > > tests/debugger/io_tab_goto.inp:
> > > tests/debugger/io_tab_goto.m:
> > > 	Test that foreign C code with labels is I/O tabled correctly.
> > >
> >
> > I suggest also updating the user guide extion on I/O tabling to warn about
> > C code that contains labels.
> >
>
> I don't think that's the right place.  I think it should be documented
> with the tabled_for_io attribute in the reference manual, however the
> tabled_for_io attribute isn't documented at all, so I've added the
> following to the reference manual:
>
It strikes me as being a reasonable place to put it, after all
that's where the debugger documentation is.

> @@ -6004,6 +6004,15 @@
>
>  @table @asis
>
> + at item @samp{tabled_for_io}
> +This attribute should be attached to foreign procs which do I/O.  It
Either foreign_procs or foreign procedures

s/which/that/

> +tells the debugger to make calls to the foreign proc idempotent.
Likewise, either foreign_proc or foreign procedure

> +This allows the debugger to safely retry accross such calls and also
s/accross/across/

> +allows safe declarative debugging of code containing such calls.
> +For more information see the I/O tabling section of the Mercury user guide.
> +If the foreign proc contains gotos then the @samp{pragma no_inline}
> +directive should also be given.
> +
Section 14.1.2 of the reference manual describes the situations where
you don't want to inline foreign code - you also don't want to do
it when you have static local variables.  (It may be worth pointing
the reader to this discussion, although we should really move into
the documentation for the new foreign language interface.)

> I actually missed something:  The introduced predicate must not be traced.
> If it is traced then the event numbers of events after the I/O action will
> be different when the I/O action is reexecuted (because the introduced
> predicate won't be reexecuted).
>
> Here's the interdiff that fixes this:
>
> only in patch2:
> --- compiler/trace_params.m	29 Aug 2005 08:44:13 -0000	1.24
> +++ compiler/trace_params.m	14 Sep 2005 04:59:39 -0000
> @@ -180,6 +180,14 @@
>  				SpecialPred = (initialise),
>  				EffTraceLevel = TraceLevel
>  			)
> +		; Origin = created(io_tabling) ->
> +			% Predicates called by a predicate which is I/O

s/which/that/

> +			% tabled should not be traced.  If such a predicate
> +			% were allowed to generate events then the event
> +			% numbers of events after the I/O primitive would be
> +			% different between the first and subsequent
> +			% (idempotent) executions of the same I/O action.
> +			EffTraceLevel = none
>  		;
>  			pred_info_import_status(PredInfo, Status),
>  			(
> only in patch2:
> --- /dev/null	1 Jan 1970 00:00:00 -0000
> +++ tests/debugger/declarative/tabled_read_decl_goto.m	14 Sep 2005 05:24:26 -0000
> @@ -0,0 +1,174 @@
> +% We define our own I/O primitives, in case the library was compiled without
> +% IO tabling.
> +
> +:- module tabled_read_decl_goto.
> +
> +:- interface.
> +
> +:- import_module io.
> +
> +:- pred main(io__state, io__state).
> +:- mode main(di, uo) is det.
> +
> +:- implementation.
> +
> +:- import_module list, char, int.
> +
> +main -->
> +	tabled_read_decl_goto__open_input("tabled_read_decl_goto.data", Res,
> +		Stream),
> +	( { Res = 0 } ->
> +		tabled_read_decl_goto__part_1(Stream),
> +		tabled_read_decl_goto__part_2(Stream),
> +		tabled_read_decl_goto__part_3
> +	;
> +		io__write_string("could not open tabled_read.data\n")
> +	).
> +
> +:- pred tabled_read_decl_goto__part_1(c_pointer::in,
> +	io__state::di, io__state::uo) is det.
> +
> +tabled_read_decl_goto__part_1(Stream) -->
> +	tabled_read_decl_goto__test(Stream, A),
> +	tabled_read_decl_goto__write_int(A),
> +	tabled_read_decl_goto__poly_test(Stream, ['a', 'b', 'c'], B),
> +	tabled_read_decl_goto__write_int(B).
> +
> +:- pred tabled_read_decl_goto__part_2(c_pointer::in,
> +	io__state::di, io__state::uo) is det.
> +
> +tabled_read_decl_goto__part_2(Stream) -->
> +	tabled_read_decl_goto__test(Stream, A),
> +	tabled_read_decl_goto__write_int(A).
> +
> +:- pred tabled_read_decl_goto__part_3(io__state::di, io__state::uo) is det.
> +
> +tabled_read_decl_goto__part_3(!IO) :-
> +	tabled_read_decl_goto__fake_io(X, !IO),
> +	tabled_read_decl_goto__write_int(X, !IO).
> +
> +:- pred tabled_read_decl_goto__test(c_pointer::in, int::out,
> +	io__state::di, io__state::uo) is det.
> +
> +tabled_read_decl_goto__test(Stream, N) -->
> +		% BUG: the 1 should be 0
> +	tabled_read_decl_goto__test_2(Stream, 1, N).
> +
> +:- pred tabled_read_decl_goto__test_2(c_pointer::in, int::in, int::out,
> +	io__state::di, io__state::uo) is det.
> +
> +tabled_read_decl_goto__test_2(Stream, SoFar, N) -->
> +	tabled_read_decl_goto__read_char_code(Stream, CharCode),
> +	(
> +		{ char__to_int(Char, CharCode) },
> +		{ char__is_digit(Char) },
> +		{ char__digit_to_int(Char, CharInt) }
> +	->
> +		tabled_read_decl_goto__test_2(Stream, SoFar * 10 + CharInt, N)
> +	;
> +		{ N = SoFar }
> +	).
> +
> +:- pred tabled_read_decl_goto__poly_test(c_pointer::in, T::in, int::out,
> +	io__state::di, io__state::uo) is det.
> +
> +tabled_read_decl_goto__poly_test(Stream, Unused, N) -->
> +		% BUG: the 1 should be 0
> +	tabled_read_decl_goto__poly_test_2(Stream, Unused, 1, N).
> +
> +:- pred tabled_read_decl_goto__poly_test_2(c_pointer::in, T::in, int::in,
> +	int::out, io__state::di, io__state::uo) is det.
> +
> +tabled_read_decl_goto__poly_test_2(Stream, Unused, SoFar, N) -->
> +	tabled_read_decl_goto__poly_read_char_code(Stream, Unused, CharCode),
> +	(
> +		{ char__to_int(Char, CharCode) },
> +		{ char__is_digit(Char) },
> +		{ char__digit_to_int(Char, CharInt) }
> +	->
> +		tabled_read_decl_goto__poly_test_2(Stream, Unused,
> +			SoFar * 10 + CharInt, N)
> +	;
> +		{ N = SoFar }
> +	).
> +
> +:- pragma c_header_code("#include <stdio.h>").
> +
Is there any reason you are not using
	:- pragma foreign_decl("C", "#include <stdio.h>")

here?

Julien.


--------------------------------------------------------------------------
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