[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