[m-dev.] for review: add MC++ implementation of library and runtime

Fergus Henderson fjh at cs.mu.OZ.AU
Sun Dec 10 19:33:52 AEDT 2000


On 04-Dec-2000, Tyson Dowd <trd at cs.mu.OZ.AU> wrote:
> +% io__do_open(File, Mode, ResultCode, Stream, IO0, IO1).
> +%	Attempts to open a file in the specified mode.
> +%	ResultCode is 0 for success, -1 for failure.
> +:- pragma foreign_code("MC++",
> +	io__do_open(FileName::in, Mode::in, ResultCode::out,
> +			Stream::out, IO0::di, IO::uo),
> +			[will_not_call_mercury, thread_safe],
> +"
> +	MR_MercuryFile mf = mercury_open(FileName, Mode);
> +	MR_c_pointer_to_word(Stream, mf);
> +	update_io(IO0, IO);
> +").

That needs to set ResultCode.

> +:- pragma foreign_code("MC++",
> +	io__get_exit_status(ExitStatus::out, IO0::di, IO::uo),
> +		will_not_call_mercury, "
> +	ExitStatus = System::Environment::get_ExitCode();
> +	MR_Runtime::SORRY(""foreign code for this function"");
> +	update_io(IO0, IO);
> +").

Is the call to SORRY() there needed?
If so, best to put it at the start, rather than in the middle.

> +:- pragma foreign_code("C",
> +	library__version(Version::out), will_not_call_mercury,
> +"
>  	MR_ConstString version_string = 
>  		MR_VERSION "", configured for "" MR_FULLARCH;
>  	/*
...
> +:- pragma foreign_code("MC++",
> +	library__version(Version::out), will_not_call_mercury,
> +"
> +	Version = String::Concat(MR_VERSION,
> +		"", configured for "", MR_FULLARCH);
>  ").

Doesn't ANSI C string literal concatenation work in MC++?

library/math.m:
> +:- pragma foreign_decl("MC++", "
>  
> +	// This is not defined in the .NET Frameworks.
> +
> +	#define	ML_FLOAT_LN2		0.69314718055994530941
> +").

I don't understand the comment here.
Why is the code here different for MC++ than it is for C?
The code for C defines ML_FLOAT_E and ML_FLOAT_PI too.

library/private_builtin.m:
> +:- pragma foreign_code("MC++", "
> +
> +    MR_DEFINE_BUILTIN_TYPE_CTOR_INFO(private_builtin, type_ctor_info, 1,
> +		MR_TYPECTOR_REP_TYPEINFO) 
> +    MR_DEFINE_BUILTIN_TYPE_CTOR_INFO(private_builtin, type_info, 1,
> +		MR_TYPECTOR_REP_TYPEINFO) 
> +    MR_DEFINE_BUILTIN_TYPE_CTOR_INFO(private_builtin, base_typeclass_info, 1,
> +		MR_TYPECTOR_REP_TYPECLASSINFO) 
> +    MR_DEFINE_BUILTIN_TYPE_CTOR_INFO(private_builtin, typeclass_info, 1,
> +		MR_TYPECTOR_REP_TYPECLASSINFO) 
> +
> +	// XXX These static constants are duplicated both here and in
> +	// mercury_cpp.cpp.
> +	// This is because other library modules reference them
> +	// from MC++ code (so they depend on the versions in the runtime to
> +	// make the dependencies simple) whereas the compiler generates
> +	// references to the ones here. 
> +
> +    static int MR_TYPECTOR_REP_ENUM 			= MR_TYPECTOR_REP_ENUM_val;
> +    static int MR_TYPECTOR_REP_ENUM_USEREQ 		= MR_TYPECTOR_REP_ENUM_USEREQ_val;
> +    static int MR_TYPECTOR_REP_DU				= MR_TYPECTOR_REP_DU_val;
> +    static int MR_TYPECTOR_REP_DU_USEREQ		= 3;
> +    static int MR_TYPECTOR_REP_NOTAG			= 4;
> +    static int MR_TYPECTOR_REP_NOTAG_USEREQ		= 5;
> +    static int MR_TYPECTOR_REP_EQUIV			= 6;
> +    static int MR_TYPECTOR_REP_EQUIV_VAR		= 7;
> +    static int MR_TYPECTOR_REP_INT		    	= 8;
> +    static int MR_TYPECTOR_REP_CHAR		    	= 9;
> +    static int MR_TYPECTOR_REP_FLOAT			=10;
> +    static int MR_TYPECTOR_REP_STRING			=11;
> +    static int MR_TYPECTOR_REP_PRED		    	=12;
> +    static int MR_TYPECTOR_REP_UNIV		    	=13;
> +    static int MR_TYPECTOR_REP_VOID		    	=14;
> +    static int MR_TYPECTOR_REP_C_POINTER		=15;
> +    static int MR_TYPECTOR_REP_TYPEINFO			=16;
> +    static int MR_TYPECTOR_REP_TYPECLASSINFO	=17;
> +    static int MR_TYPECTOR_REP_ARRAY			=18;
> +    static int MR_TYPECTOR_REP_SUCCIP			=19;
> +    static int MR_TYPECTOR_REP_HP				=20;
> +    static int MR_TYPECTOR_REP_CURFR			=21;
> +    static int MR_TYPECTOR_REP_MAXFR			=22;
> +    static int MR_TYPECTOR_REP_REDOFR			=23;
> +    static int MR_TYPECTOR_REP_REDOIP			=24;
> +    static int MR_TYPECTOR_REP_TRAIL_PTR		=25;
> +    static int MR_TYPECTOR_REP_TICKET			=26;
> +    static int MR_TYPECTOR_REP_NOTAG_GROUND		=27;
> +    static int MR_TYPECTOR_REP_NOTAG_GROUND_USEREQ	=28;
> +    static int MR_TYPECTOR_REP_EQUIV_GROUND		=29;
> +
> +    static int MR_SECTAG_NONE				= 0;
> +    static int MR_SECTAG_LOCAL				= 1;
> +    static int MR_SECTAG_REMOTE				= 2;

Please put comments at the definitions of the corresponding
enums in the runtime directory saying that they are duplicated here.

library/std_util.m:
> +:- pragma foreign_code("MC++", 
> +		get_registers(_HeapPtr::out, _SolutionsHeapPtr::out,
> +		_TrailPtr::out), will_not_call_mercury,
> +"
> +	MR_Runtime::SORRY(""foreign code for this function"");
> +").

The following is better code for that one:

	/*
	** For MC++, we always use the MS garbage collector,
	** so we don't have to worry here about heap reclamation on failure.
	*/
	HeapPtr = SolutionsHeapPtr = 0;

	#ifdef MR_USE_TRAIL
		/* XXX trailing not yet implemented for the MLDS back-end */
		MR_Runtime::SORRY(""foreign code for this function"");
	#else
		TrailPtr = 0
	#endif

>  :- impure pred check_for_floundering(trail_ptr::in) is det.
> -:- pragma c_code(check_for_floundering(TrailPtr::in), [will_not_call_mercury],
> +:- pragma foreign_code("C", 
> +	check_for_floundering(TrailPtr::in), [will_not_call_mercury],
>  "
>  #ifdef MR_USE_TRAIL
>  	/* check for outstanding delayed goals (``floundering'') */
>  	MR_reset_ticket(TrailPtr, MR_solve);
>  #endif
>  ").
> +:- pragma foreign_code("MC++", 
> +	check_for_floundering(_TrailPtr::in), [will_not_call_mercury],
> +"
> +	MR_Runtime::SORRY(""foreign code for this function"");
> +").

The following is better code for that one:

	#ifdef MR_USE_TRAIL
		MR_Runtime::SORRY(""foreign code for this function"");
	#endif

>  %
>  % Discard the topmost trail ticket.
>  %
>  :- impure pred discard_trail_ticket is det.
> -:- pragma c_code(discard_trail_ticket, [will_not_call_mercury],
> +:- pragma foreign_code("C", 
> +	discard_trail_ticket, [will_not_call_mercury],
>  "
>  #ifdef MR_USE_TRAIL
>  	MR_discard_ticket();
>  #endif
>  ").
> +:- pragma foreign_code("MC++", 
> +	discard_trail_ticket, [will_not_call_mercury],
> +"
> +	MR_Runtime::SORRY(""foreign code for this function"");
> +").

Likewise here, put the call to SORRY() inside #ifdef MR_USE_TRAIL.
These procedures are supposed to do nothing if MR_USE_TRAIL
is not defined.

>  %
>  % Swap the heap with the solutions heap
>  %
>  :- impure pred swap_heap_and_solutions_heap is det.
> -:- pragma c_code(swap_heap_and_solutions_heap,
> +:- pragma foreign_code("C", 
> +	swap_heap_and_solutions_heap,
>  	will_not_call_mercury,
>  "
>  #ifndef CONSERVATIVE_GC
> @@ -853,6 +876,12 @@
>      }
>  #endif
>  ").
> +:- pragma foreign_code("MC++", 
> +	swap_heap_and_solutions_heap,
> +	will_not_call_mercury,
> +"
> +	MR_Runtime::SORRY(""foreign code for this function"");
> +").

The following would be better:

	/*
	** For the IL back-end, we use the system heap, rather
	** than defining our own heaps.  So we don't need to
	** worry about swapping them.  Hence do nothing here.
	*/

> +:- pragma foreign_code("MC++",
> +	partial_deep_copy(_SolutionsHeapPtr::in,
> +		_OldVal::in, _NewVal::out), will_not_call_mercury,
> +"
> +	MR_Runtime::SORRY(""foreign code for this function"");
> +").

The following code would be better:

	/*
	** For the IL back-end, we don't do heap reclamation on failure,
	** so we don't need to worry about making deep copies here.
	** Shallow copies will suffice.
	*/
	NewVal = OldVal;

> +:- pragma foreign_code("MC++", 
> +	partial_deep_copy(_SolutionsHeapPtr::in,
> +		_OldVal::mdi, _NewVal::muo), will_not_call_mercury,
> +"
> +	MR_Runtime::SORRY(""foreign code for this function"");
> +").
> +:- pragma foreign_code("MC++", partial_deep_copy(_SolutionsHeapPtr::in,
> +		_OldVal::di, _NewVal::uo), will_not_call_mercury,
> +"
> +	MR_Runtime::SORRY(""foreign code for this function"");
> +").

Likewise for these two.

> +:- pragma foreign_code("MC++", 
> +	reset_solutions_heap(_SolutionsHeapPtr::in),
> +	will_not_call_mercury,
> +"
> +	MR_Runtime::SORRY(""foreign code for this function"");
> +").

Again the right thing to do here is to do nothing.

	/*
	** For the IL back-end, we don't have a separate "solutions heap".
	** Hence this operation is a NOP.
	*/


If you prefer I'm happy to commit all these fixes for the MC++ versions
of all-solutions stuff as a separate change.

> +:- pragma foreign_code("MC++",
> +	type_to_univ(Value::out, Univ::in), will_not_call_mercury, 
> +"{
> +	MR_Word univ_type_info = Value->GetValue(0);
> +	if (MR_compare_type_info(TypeInfo_for_T, univ_type_info)
> +			== MR_COMPARE_EQUAL) {

The `{' there should be one a new line.

> --- library/store.m	2000/11/23 02:00:15	1.25
> +++ library/store.m	2000/12/01 03:34:05
> @@ -208,7 +208,8 @@
>  :- implementation.
>  :- import_module std_util.
>  
> -:- type some_store_type ---> some_store_type.
> +	% XXX aaargh yet again stupid broken compiler
> +:- type some_store_type ---> some_store_type ; aaa.

Make sure you undo that one.

[...to be continued...]

> +/*
> +** Note that the code for this is identical to the code for 
> +** table_nondet_return_all_ans/2 (above).
> +** Any changes to this code should also be made there.
> +*/
> +:- pragma foreign_code("MC++",
> +	table_multi_return_all_ans(_T::in, _A::out),

-- 
Fergus Henderson <fjh at cs.mu.oz.au>  |  "I have always known that the pursuit
                                    |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  |     -- the last words of T. S. Garp.
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to:       mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions:          mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------



More information about the developers mailing list