[m-dev.] diff: update NEWS file for MLDS trailing, etc.

Fergus Henderson fjh at cs.mu.OZ.AU
Tue Dec 19 01:10:20 AEDT 2000


On 15-Dec-2000, Fergus Henderson <fjh at cs.mu.OZ.AU> wrote:
> Thanks for pointing that out.  I plan to document that it works except
> for argument types `float' and `char', and to change the code to (in
> MLDS grades) check for those argument types and if they're found,
> throw an exception.  I'll post a diff shortly.

Estimated hours taken: 2

Fix some problems with dynamic linking for the MLDS back-end.

extras/dynamic_linking/name_mangle.m:
browser/name_mangle.m:
	Fix a bug with the name mangling of the arity for functions;
	the mangling algorithm here didn't match what the compiler
	actually outputs.
	Clarify the documentation about the meaning of the `arity'
	field.

extras/dynamic_linking/dl.m:
	Fix a bug with the arity checks for functions;
	they were always failing.

	For the MLDS back-end, check that the argument type
	isn't `char' or `float'; those are not supported.
	Document that restriction.

extras/dynamic_linking/dl_test.m:
extras/dynamic_linking/dl_test.exp:
extras/dynamic_linking/hello.m:
	Add a test of dynamically linking functions and
	passing and returning floating-point arguments.

NEWS:
	Document the restriction that dl__mercury_sym doesn't support
	argument types `float' or `char' for the MLDS back-end.

Workspace: /home/pgrad/fjh/ws/hg
Index: extras/dynamic_linking/dl.m
===================================================================
RCS file: /home/mercury1/repository/mercury/extras/dynamic_linking/dl.m,v
retrieving revision 1.2
diff -u -d -r1.2 dl.m
--- extras/dynamic_linking/dl.m	2000/11/21 07:38:53	1.2
+++ extras/dynamic_linking/dl.m	2000/12/18 13:52:31
@@ -40,11 +40,16 @@
 % it; see dl_test.m for an example of this.
 %
 % The type `T' below must be a higher-order type whose arity and
-% argument types match that of the specified procedure.
+% argument types exactly match that of the specified procedure.
 % The implementation may check this at runtime, but is not required
 % to do so.  (The current implementation checks that the type is a
 % higher-order type with the appropriate arity, but it does not
 % check the argument types.)
+%
+% WARNING: for the `--high-level-code' back-end (the `hl*' grades),
+% calling dl__mercury_sym for procedures with argument types `float'
+% or `char' is not supported.
+
 :- pred dl__mercury_sym(handle::in, mercury_proc::in, dl__result(T)::out,
 	io__state::di, io__state::uo) is det.
 
@@ -53,7 +58,7 @@
 	io__state::di, io__state::uo) is det.
 
 :- implementation.
-:- import_module std_util, require, string, list.
+:- import_module std_util, require, string, list, int.
 
 :- pragma c_header_code("
 	#include <stdio.h>
@@ -123,7 +128,8 @@
 
 mercury_sym(Handle, MercuryProc0, Result) -->
 	{ check_proc_spec_matches_result_type(Result, _,
-		MercuryProc0, MercuryProc) },
+		MercuryProc0, MercuryProc1) },
+	{ check_type_is_supported(Result, _, MercuryProc1, MercuryProc) },
 	{ MangledName = proc_name_mangle(MercuryProc) },
 	sym(Handle, MangledName, Result0),
 	{
@@ -152,6 +158,11 @@
 	Proc0 = mercury_proc(IsPredOrFunc, _Module, _Name, ProcArity, _Mode),
 	type_ctor_name_and_arity(type_ctor(type_of(Value)),
 		TypeModule, TypeName, TypeArity),
+	( TypeName = "func" ->
+		TypeProcArity = TypeArity - 1
+	;
+		TypeProcArity = TypeArity
+	),
 	(
 		( TypeModule \= "builtin"
 		; TypeName \= "pred", TypeName \= "func"
@@ -176,10 +187,10 @@
 			Msg),
 		error(Msg)
 	;
-		ProcArity \= TypeArity
+		ProcArity \= TypeProcArity
 	->
 		string__int_to_string(ProcArity, ProcArityString),
-		string__int_to_string(TypeArity, TypeArityString),
+		string__int_to_string(TypeProcArity, TypeArityString),
 		string__append_list([
 			"dl__mercury_sym: arity mismatch: ",
 			"argument has ", ProcArityString, " argument(s), ",
@@ -190,6 +201,46 @@
 		Proc = Proc0
 	).
 
+%
+% Check that the given higher-order type is supported.
+%
+% For the MLDS back-end, we normally need wrapper functions
+% for closures; the wrapper functions convert from type MR_Box
+% to the appropriate argument type, and then call the function
+% with the unboxed argument types.  Generating those on-the-fly
+% here would be tricky!  Instead, we only try to handle the cases
+% where wrappers are normally not needed, i.e. arguments with
+% types other than `char' or `float'.  All other argument types
+% are word-sized, and will hopefully be passed in the same way
+% by the C compiler.
+%
+% This procedure checks, for the MLDS back-end, that you're
+% not using it on a procedure with argument types `char' or
+% `float'.
+%
+% XXX this doesn't catch the case of no_tag types that
+% end up being equivalent to `float' or `char'.
+%
+:- pred check_type_is_supported(dl__result(T)::unused, T::unused,
+		mercury_proc::in, mercury_proc::out) is det.
+check_type_is_supported(_Result, Value, Proc0, Proc) :-
+	(
+		high_level_code,
+		list__member(ArgType, type_args(type_of(Value))),
+		% The following line might be more efficient,
+		% but is not yet supported by the MLDS back-end
+		% ArgType = type_of(_ `with_type` float))
+		ArgTypeCtor = type_ctor(ArgType),
+		( type_ctor_name(ArgTypeCtor) = "float"
+		; type_ctor_name(ArgTypeCtor) = "char"
+		),
+		type_ctor_module_name(ArgTypeCtor) = "builtin"
+	->
+		error("sorry, not implemented: dl__mercury_sym for procedure with argument type `float' or `char'")
+	;
+		Proc = Proc0
+	).
+
 sym(handle(Handle), Name, Result) -->
 	dlsym(Handle, Name, Pointer),
 	( { is_null(Pointer) } ->
@@ -244,3 +295,16 @@
 	dlclose((void *)Handle)
 #endif
 ").
+
+%-----------------------------------------------------------------------------%
+
+:- pred high_level_code is semidet.
+:- pragma c_code(high_level_code, [will_not_call_mercury, thread_safe], "
+#ifdef MR_HIGHLEVEL_CODE
+	SUCCESS_INDICATOR = TRUE;
+#else
+	SUCCESS_INDICATOR = FALSE;
+#endif
+").
+
+%-----------------------------------------------------------------------------%
Index: extras/dynamic_linking/dl_test.exp
===================================================================
RCS file: /home/mercury1/repository/mercury/extras/dynamic_linking/dl_test.exp,v
retrieving revision 1.1
diff -u -d -r1.1 dl_test.exp
--- extras/dynamic_linking/dl_test.exp	1998/12/06 06:15:16	1.1
+++ extras/dynamic_linking/dl_test.exp	2000/12/15 09:00:37
@@ -1 +1,2 @@
 Hello, world
+1.0 + 2.0 + 3.0 = 6.000000
Index: extras/dynamic_linking/dl_test.m
===================================================================
RCS file: /home/mercury1/repository/mercury/extras/dynamic_linking/dl_test.m,v
retrieving revision 1.1
diff -u -d -r1.1 dl_test.m
--- extras/dynamic_linking/dl_test.m	1998/12/06 06:15:16	1.1
+++ extras/dynamic_linking/dl_test.m	2000/12/18 14:07:33
@@ -12,7 +12,7 @@
 :- pred main(state::di, state::uo) is det.
 
 :- implementation.
-:- import_module dl, name_mangle.
+:- import_module dl, name_mangle, string, list.
 
 main -->
 	%
@@ -48,6 +48,32 @@
 			%
 			HelloPred
 		),
+
+		{ Add3Proc = mercury_proc(function, unqualified("hello"),
+					"add3", 3, 0) },
+		dl__mercury_sym(Handle, Add3Proc, MaybeAdd3),
+		(
+			{ MaybeAdd3 = error(Msg2) },
+			print("dlsym failed: "), print(Msg2), nl
+		;
+			{ MaybeAdd3 = ok(Add3Func0) },
+			%
+			% Cast the higher-order term that we obtained
+			% to the correct higher-order inst.
+			%
+			{ wrapper(Add3Func) =
+				inst_cast_add3(wrapper(Add3Func0)) },
+			%%% { CastWrapper = inst_cast_add3(wrapper(Add3Func0)) },
+			%%% { CastWrapper = wrapper(Add3Func) },
+			%
+			% Call the procedure whose address
+			% we just obtained.
+			%
+			{ Sum = Add3Func(1.0, 2.0, 3.0) },
+			io__format("1.0 + 2.0 + 3.0 = %f\n", [f(Sum)])
+		),
+
+
 		%
 		% unload the object code in the libhello.so file
 		%
@@ -62,9 +88,9 @@
 
 %
 % dl__mercury_sym returns a higher-order term with inst `ground'.
-% We need to cast it to the right higher-order inst, namely
-% `pred(di, uo) is det' before we can actually call it.
-% The function inst_cast/1 defined below does that.
+% We need to cast it to the right higher-order inst, which for the
+% `hello' procedure is `pred(di, uo) is det', before we can actually
+% call it.  The function inst_cast/1 defined below does that.
 %
 
 :- type io_pred == pred(io__state, io__state).
@@ -74,3 +100,18 @@
 :- mode inst_cast(in) = out(io_pred) is det.
 :- pragma c_code(inst_cast(X::in) = (Y::out(io_pred)),
 	[will_not_call_mercury, thread_safe], "Y = X").
+
+% Likewise for `add3'.
+% Note that for arguments of function type, the function type
+% normally gets automatically propagated into the inst.
+% We use a wrapper type to avoid that.
+
+:- type add3 == (func(float, float, float) = float).
+:- type add3_wrapper ---> wrapper(add3).
+:- inst add3_wrapper ---> wrapper(func(in, in, in) = out is det).
+
+:- func inst_cast_add3(add3_wrapper) = add3_wrapper.
+:- mode inst_cast_add3(in) = out(add3_wrapper) is det.
+:- pragma c_code(inst_cast_add3(X::in) = (Y::out(add3_wrapper)),
+	[will_not_call_mercury, thread_safe], "Y = X").
+
Index: extras/dynamic_linking/hello.m
===================================================================
RCS file: /home/mercury1/repository/mercury/extras/dynamic_linking/hello.m,v
retrieving revision 1.1
diff -u -d -r1.1 hello.m
--- extras/dynamic_linking/hello.m	1998/12/06 06:15:17	1.1
+++ extras/dynamic_linking/hello.m	2000/12/15 08:38:41
@@ -1,15 +1,23 @@
 % Example module for use with dynamic linking.
 % The driver program dl_test.m dynamically loads the object code
-% for this module and then calls the predicate hello/2.
+% for this module and then calls the procedures defined here,
+% e.g. hello/2.
 
 % This source file is hereby placed in the public domain.  -fjh (the author).
 
 :- module hello.
 :- interface.
 :- import_module io.
+:- import_module float.
 
+% a very basic test: print "Hello world"
 :- pred hello(state::di, state::uo) is det.
 
+% test passing floating point arguments
+:- func add3(float, float, float) = float.
+
 :- implementation.
 
 hello --> print("Hello, world\n").
+
+add3(X, Y, Z) = X + Y + Z.
Index: extras/dynamic_linking/name_mangle.m
===================================================================
RCS file: /home/mercury1/repository/mercury/extras/dynamic_linking/name_mangle.m,v
retrieving revision 1.2
diff -u -d -r1.2 name_mangle.m
--- extras/dynamic_linking/name_mangle.m	2000/12/15 03:14:11	1.2
+++ extras/dynamic_linking/name_mangle.m	2000/12/15 09:02:50
@@ -46,7 +46,9 @@
 
 :- type pred_name == string.
 
-:- type arity == int.
+:- type arity == int.		% note that for functions that arity here
+				% does *not* include the function result
+				% e.g. int:'*' has arity 2, not 3.
 
 :- type mode_num == int.	% mode numbers start from zero
 
@@ -88,12 +90,7 @@
 		qualify_name(ModuleName, Name0, LabelName0)
 	),
 	name_mangle(LabelName0, LabelName1),
-	( PredOrFunc = function ->
-		OrigArity is Arity - 1
-	;
-		OrigArity = Arity
-	),
-	string__int_to_string(OrigArity, ArityString),
+	string__int_to_string(Arity, ArityString),
 	string__int_to_string(ModeNum, ModeNumString),
 	string__append_list([LabelName1, "_", ArityString, "_", ModeNumString],
 		LabelName2),
@@ -129,17 +126,14 @@
 	name_mangle(LabelName0, LabelName1),
 	(
 		PredOrFunc = predicate,
-		PredOrFuncString = "p"
+		PredOrFuncString = "p",
+		ArityAsPred = Arity
 	;
 		PredOrFunc = function,
-		PredOrFuncString = "f"
-	),
-	( PredOrFunc = function ->
-		OrigArity is Arity - 1
-	;
-		OrigArity = Arity
+		PredOrFuncString = "f",
+		ArityAsPred = Arity + 1
 	),
-	string__int_to_string(OrigArity, ArityString),
+	string__int_to_string(ArityAsPred, ArityString),
 	string__int_to_string(ModeNum, ModeNumString),
 	string__append_list([LabelName1, "_", ArityString, "_",
 		PredOrFuncString, "_", ModeNumString],
Index: NEWS
===================================================================
RCS file: /home/mercury1/repository/mercury/NEWS,v
retrieving revision 1.183
diff -u -d -r1.183 NEWS
--- NEWS	2000/12/14 12:16:53	1.183
+++ NEWS	2000/12/15 09:56:14
@@ -166,7 +166,9 @@
   sometimes it is better than the old back-end, sometimes it is worse.
   There are a few optimizations that we have not yet implemented for
   the new back-end that might make a significant difference for some
-  applications.  But we encourage those for whom performance is
+  applications.  But there are also some optimizations which we have
+  implemented for the new back-end that have not been implemented for
+  the old back-end.  We encourage those for whom performance is
   important to try their application with both the old and new
   back-ends and compare for themselves.
 
@@ -185,6 +187,9 @@
 	- the Aditi deductive database interface
   	- the `--split-c-files' option
   	- the `--introduce-accumulators' option
+	- dynamic linking (via the dl__mercury_sym procedure in
+	  extras/dynamic/dl.m in the mercury-extras distribution)
+	  for procedures with arguments of type `float' or `char'
 
 Changes to the development environment:
 
-- 
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