[m-rev.] for review: Arrays for the .NET backend

Tyson Dowd trd at cs.mu.OZ.AU
Fri Aug 3 02:17:58 AEST 2001


Hi,

This change implements the compiler portion of getting arrays to work on
the .NET backend.  The library part will follow in a few minutes.

===================================================================


Estimated hours taken: 13
Branches: main

Implement arrays in the .NET backend.

Arrays are implemented in an unusual way.  
array(T) is mapped to the .NET type T[] for all concrete types T.
However, if T is a type variable, we map array(T) to System.Array.

System.Array is the superclass of all array types, so we can always
pass T[] where System.Array is expected.  

This mapping allows us to use the Mercury array library module to
operate on arrays that may be exposed by other .NET components (for
example Byte[] or int[]).

In some cases the Mercury compiler will know the value of T, but it may
be calling code that operates on array(T) in a generic fashion.
If the callee returns an array(T), the Mercury compiler can be sure
that this is really T[], but the .NET backend is not that clever.

In that case we have to cast from System.Array to T[] after the call.
(This is very similar to how we unbox return values with type T where T is
known in the caller but not the callee).

compiler/ml_call_gen.m:
	Implement the cast to the known instance of array(T) for return
	values of array.

compiler/mlds.m:
	Add a new MLDS type mlds__mercury_array_type to represent the
	Mercury array/1 type.
	Turn the Mercury type array/1 into mlds__mercury_array_type.

compiler/mlds_to_c.m:
compiler/mlds_to_gcc.m:
	Use MR_Word to represent mlds__mercury_array_type, unless we are
	using --high-level-data, in which case we use the appropriately
	named high-level-data type.
	
compiler/mlds_to_il.m:
	Draw a distinction between the il_object_array_type (object[])
	and the il_generic_array_type (class System.Array).
	Map mlds__mercury_array_type(ElemType) to class System.Array if 
	ElemType is a type variable, or ElemType[] otherwise.

compiler/mlds_to_java.m:
	Map mlds__mercury_array_type(ElemType) to class Object[] if 
	ElemType is a type variable, or ElemType[] otherwise.
	(type variables are mapped to Object anyway, so this falls
	out of the code anyway).
	(This is untested).
	


Index: compiler/ml_call_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_call_gen.m,v
retrieving revision 1.25
diff -u -r1.25 ml_call_gen.m
--- compiler/ml_call_gen.m	2001/07/06 17:11:59	1.25
+++ compiler/ml_call_gen.m	2001/08/02 15:09:19
@@ -752,6 +752,18 @@
 			unop(box(MLDS_SourceType), VarRval)) }
 	;
 		%
+		% if converting from an array(T) to array(X) where
+		% X is a concrete instance, we should insert a cast
+		% to the concrete instance.
+		%
+		{ type_to_type_id(SourceType, TypeId, TypeArgs) },
+		{ type_id_is_array(TypeId) },
+		{ TypeArgs = [term__variable(_)] }
+	->
+		ml_gen_type(DestType, MLDS_DestType),
+		{ ArgRval = unop(cast(MLDS_DestType), VarRval) }
+	;
+		%
 		% if converting from one concrete type to a different
 		% one, then cast
 		%
Index: compiler/mlds.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mlds.m,v
retrieving revision 1.65
diff -u -r1.65 mlds.m
--- compiler/mlds.m	2001/07/20 14:13:57	1.65
+++ compiler/mlds.m	2001/08/02 15:09:20
@@ -538,6 +538,17 @@
 						% enum, float, etc.
 		)
 
+	 	% The Mercury array type is treated specially, some backends
+		% will treat it like any other mercury_type, whereas other may
+		% use a special representation for it.
+		% Arrays are type constructors in some backends, and so it is
+		% easier to represent it here as a special type constructor.
+		% (if we used the mercury_type representation above, we would
+		% only classify the topmost level of the type, whereas we
+		% really want to classify the element type for arrays, so
+		% we can generate int[] for array(int)).
+	;	mlds__mercury_array_type(mlds__type)
+
 		% The type for the continuation functions used
 		% to handle nondeterminism
 	;	mlds__cont_type(mlds__return_types)
@@ -1497,8 +1508,17 @@
 % XXX It might be a better idea to get rid of the mercury_type/2
 % MLDS type and instead fully convert all Mercury types to MLDS types.
 
-mercury_type_to_mlds_type(ModuleInfo, Type) = mercury_type(Type, Category) :-
-	classify_type(Type, ModuleInfo, Category).
+mercury_type_to_mlds_type(ModuleInfo, Type) = MLDSType :-
+	( 
+		type_to_type_id(Type, TypeId, [ElemType]),
+		TypeId = qualified(unqualified("array"), "array") - 1
+	->
+		MLDSElemType = mercury_type_to_mlds_type(ModuleInfo, ElemType),
+		MLDSType = mlds__mercury_array_type(MLDSElemType)
+	;
+		classify_type(Type, ModuleInfo, Category),
+		MLDSType = mercury_type(Type, Category)
+	).
 
 %-----------------------------------------------------------------------------%
 
Index: compiler/mlds_to_c.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mlds_to_c.m,v
retrieving revision 1.99
diff -u -r1.99 mlds_to_c.m
--- compiler/mlds_to_c.m	2001/07/20 14:13:58	1.99
+++ compiler/mlds_to_c.m	2001/08/02 15:09:21
@@ -602,6 +602,9 @@
 :- mode mlds_output_pragma_export_type(in, in, di, uo) is det.
 
 mlds_output_pragma_export_type(suffix, _Type) --> [].
+		% Array types are exported as MR_Word
+mlds_output_pragma_export_type(prefix, mercury_array_type(_ElemType)) -->
+	io__write_string("MR_Word").
 mlds_output_pragma_export_type(prefix, mercury_type(Type, _)) -->
 	{ export__type_to_type_string(Type, String) },
 	io__write_string(String).
@@ -840,6 +843,7 @@
 :- mode mlds_type_contains_type(in, out) is multi.
 
 mlds_type_contains_type(Type, Type).
+mlds_type_contains_type(mlds__mercury_array_type(Type), Type).
 mlds_type_contains_type(mlds__array_type(Type), Type).
 mlds_type_contains_type(mlds__ptr_type(Type), Type).
 mlds_type_contains_type(mlds__func_type(Parameters), Type) :-
@@ -1523,6 +1527,17 @@
 
 mlds_output_type_prefix(mercury_type(Type, TypeCategory)) -->
 	mlds_output_mercury_type_prefix(Type, TypeCategory).
+mlds_output_type_prefix(mercury_array_type(_ElemType)) -->
+	globals__io_lookup_bool_option(highlevel_data, HighLevelData),
+	( { HighLevelData = yes } ->
+		mlds_output_mercury_user_type_name(
+			qualified(unqualified("array"), "array") - 1,
+			user_type)
+	;
+		% for the --no-high-level-data case,
+		% we just treat everything as `MR_Word'
+		io__write_string("MR_Word")
+	).
 mlds_output_type_prefix(mlds__native_int_type)   --> io__write_string("int").
 mlds_output_type_prefix(mlds__native_float_type) --> io__write_string("float").
 mlds_output_type_prefix(mlds__native_bool_type)  --> io__write_string("bool").
@@ -1640,15 +1655,8 @@
 	globals__io_lookup_bool_option(highlevel_data, HighLevelData),
 	( { HighLevelData = yes } ->
 		( { type_to_type_id(Type, TypeId, _ArgsTypes) } ->
-			{ ml_gen_type_name(TypeId, ClassName, ClassArity) },
-			{ TypeCategory = enum_type ->
-				MLDS_Type = mlds__class_type(ClassName,
-					ClassArity, mlds__enum)
-			;
-				MLDS_Type = mlds__ptr_type(mlds__class_type(
-					ClassName, ClassArity, mlds__class))
-			},
-			mlds_output_type_prefix(MLDS_Type)
+			mlds_output_mercury_user_type_name(TypeId,
+				TypeCategory)
 		;
 			{ error("mlds_output_mercury_user_type_prefix") }
 		)
@@ -1658,6 +1666,21 @@
 		io__write_string("MR_Word")
 	).
 
+:- pred mlds_output_mercury_user_type_name(type_id, builtin_type,
+		io__state, io__state).
+:- mode mlds_output_mercury_user_type_name(in, in, di, uo) is det.
+
+mlds_output_mercury_user_type_name(TypeId, TypeCategory) -->
+	{ ml_gen_type_name(TypeId, ClassName, ClassArity) },
+	{ TypeCategory = enum_type ->
+		MLDS_Type = mlds__class_type(ClassName,
+			ClassArity, mlds__enum)
+	;
+		MLDS_Type = mlds__ptr_type(mlds__class_type(
+			ClassName, ClassArity, mlds__class))
+	},
+	mlds_output_type_prefix(MLDS_Type).
+
 :- pred mlds_output_type_suffix(mlds__type, io__state, io__state).
 :- mode mlds_output_type_suffix(in, di, uo) is det.
 
@@ -1680,6 +1703,7 @@
 :- mode mlds_output_type_suffix(in, in, di, uo) is det.
 
 mlds_output_type_suffix(mercury_type(_, _), _) --> [].
+mlds_output_type_suffix(mercury_array_type(_), _) --> [].
 mlds_output_type_suffix(mlds__native_int_type, _) --> [].
 mlds_output_type_suffix(mlds__native_float_type, _) --> [].
 mlds_output_type_suffix(mlds__native_bool_type, _) --> [].
Index: compiler/mlds_to_gcc.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mlds_to_gcc.m,v
retrieving revision 1.49
diff -u -r1.49 mlds_to_gcc.m
--- compiler/mlds_to_gcc.m	2001/07/31 16:44:34	1.49
+++ compiler/mlds_to_gcc.m	2001/08/02 15:09:22
@@ -1668,7 +1668,15 @@
 :- pred build_type(mlds__type, initializer_array_size, global_info,
 		gcc__type, io__state, io__state).
 :- mode build_type(in, in, in, out, di, uo) is det.
-
+	
+	% Just represent Mercury arrays as MR_Word.
+build_type(mercury_array_type(_ElemType), _, _, GCC_Type) -->
+	globals__io_lookup_bool_option(highlevel_data, HighLevelData),
+	( { HighLevelData = yes } ->
+		{ sorry(this_file, "--high-level-data (mercury_array_type)") }
+	;
+		{ GCC_Type = 'MR_Word' }
+	).
 build_type(mercury_type(Type, TypeCategory), _, _, GCC_Type) -->
 	build_mercury_type(Type, TypeCategory, GCC_Type).
 build_type(mlds__native_int_type, _, _, gcc__integer_type_node) --> [].
Index: compiler/mlds_to_il.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mlds_to_il.m,v
retrieving revision 1.56
diff -u -r1.56 mlds_to_il.m
--- compiler/mlds_to_il.m	2001/07/26 10:58:35	1.56
+++ compiler/mlds_to_il.m	2001/08/02 15:09:24
@@ -2441,8 +2441,16 @@
 
 	% XXX make sure all the types are converted correctly
 
-mlds_type_to_ilds_type(_, mlds__rtti_type(_RttiName)) = il_array_type.
+mlds_type_to_ilds_type(_, mlds__rtti_type(_RttiName)) = il_object_array_type.
 
+mlds_type_to_ilds_type(DataRep, mlds__mercury_array_type(ElementType)) = 
+	( ElementType = mlds__mercury_type(_, polymorphic_type) ->
+		il_generic_array_type
+	;
+		ilds__type([], '[]'(mlds_type_to_ilds_type(DataRep,
+			ElementType), []))
+	).
+
 mlds_type_to_ilds_type(DataRep, mlds__array_type(ElementType)) = 
 	ilds__type([], '[]'(mlds_type_to_ilds_type(DataRep, ElementType), [])).
 
@@ -2494,15 +2502,15 @@
 mlds_type_to_ilds_type(_, mercury_type(_, float_type)) =
 	ilds__type([], float64).
 mlds_type_to_ilds_type(_, mercury_type(_, str_type)) = il_string_type.
-mlds_type_to_ilds_type(_, mercury_type(_, pred_type)) = il_array_type.
-mlds_type_to_ilds_type(_, mercury_type(_, tuple_type)) = il_array_type.
-mlds_type_to_ilds_type(_, mercury_type(_, enum_type)) = il_array_type.
+mlds_type_to_ilds_type(_, mercury_type(_, pred_type)) = il_object_array_type.
+mlds_type_to_ilds_type(_, mercury_type(_, tuple_type)) = il_object_array_type.
+mlds_type_to_ilds_type(_, mercury_type(_, enum_type)) = il_object_array_type.
 mlds_type_to_ilds_type(_, mercury_type(_, polymorphic_type)) = il_generic_type.
 mlds_type_to_ilds_type(DataRep, mercury_type(MercuryType, user_type)) = 
 	( DataRep ^ highlevel_data = yes ->
 		mercury_type_to_highlevel_class_type(MercuryType)
 	;
-		il_array_type
+		il_object_array_type
 	).
 mlds_type_to_ilds_type(_, mlds__unknown_type) = _ :-
 	unexpected(this_file, "mlds_type_to_ilds_type: unknown_type").
@@ -2523,7 +2531,7 @@
 		(
 			type_id_is_array(TypeId)
 		->
-			ILType = il_array_type
+			ILType = il_object_array_type
 		;
 			ml_gen_type_name(TypeId, ClassName, Arity),
 			ILType = ilds__type([], class(
@@ -3031,7 +3039,7 @@
 	mangle_dataname(DataName, FieldName),
 	mangle_dataname_module(yes(DataName), ModuleName, NewModuleName),
 	ClassName = mlds_module_name_to_class_name(NewModuleName),
-	FieldRef = make_fieldref(il_array_type, ClassName, FieldName).
+	FieldRef = make_fieldref(il_object_array_type, ClassName, FieldName).
 
 
 %-----------------------------------------------------------------------------%
@@ -3209,13 +3217,21 @@
 il_generic_enum_name = il_system_name(["Enum"]).
 
 %-----------------------------------------------------------------------------%
+%
+% The mapping to the object array type (used like MR_Word).
+%
+	% il_object_array_type means array of System.Object.
+:- func il_object_array_type = ilds__type.
+il_object_array_type = ilds__type([], '[]'(il_generic_type, [])).
+
+%-----------------------------------------------------------------------------%
 %
-% The mapping to the array type (used like MR_Word).
+% The mapping to the library array type (array(T))
 %
 
-	% il_array_type means array of System.Object.
-:- func il_array_type = ilds__type.
-il_array_type = ilds__type([], '[]'(il_generic_type, [])).
+	% il_generic_array_type means array of System.Object.
+:- func il_generic_array_type = ilds__type.
+il_generic_array_type = ilds__type([], class(il_system_name(["Array"]))).
 
 %-----------------------------------------------------------------------------%
 %
Index: compiler/mlds_to_java.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mlds_to_java.m,v
retrieving revision 1.10
diff -u -r1.10 mlds_to_java.m
--- compiler/mlds_to_java.m	2001/07/12 15:44:58	1.10
+++ compiler/mlds_to_java.m	2001/08/02 15:09:27
@@ -856,6 +856,7 @@
 get_java_type_initializer(mercury_type(_, enum_type)) = "null".
 get_java_type_initializer(mercury_type(_, polymorphic_type)) = "null".
 get_java_type_initializer(mercury_type(_, user_type)) = "null".
+get_java_type_initializer(mlds__mercury_array_type(_)) = "null".
 get_java_type_initializer(mlds__cont_type(_)) = "null".
 get_java_type_initializer(mlds__commit_type) = "null".
 get_java_type_initializer(mlds__native_bool_type) = "false".
@@ -1206,6 +1207,10 @@
 
 output_type(mercury_type(Type, TypeCategory)) -->
 	output_mercury_type(Type, TypeCategory).
+
+output_type(mercury_array_type(_MLDSType)) -->
+	io__write_string("java.lang.Object").
 output_type(mlds__native_int_type)   --> io__write_string("int").
 output_type(mlds__native_float_type) --> io__write_string("double").
 output_type(mlds__native_bool_type) --> io__write_string("boolean").

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