[m-rev.] for review: fix C foreign_type
Peter Ross
peter.ross at miscrit.be
Fri May 17 19:15:15 AEST 2002
On Fri, May 17, 2002 at 12:43:49AM +1000, Fergus Henderson wrote:
> For review by Pete and/or Tyson.
>
> Estimated hours taken: 12
> Branches: main
>
> Implement C `pragma foreign_type' properly.
>
This looks fine modulo adding some comments. Feel free to check in.
>
> Workspace: /home/ceres/fjh/mercury
> Index: compiler/export.m
> ===================================================================
> RCS file: /home/mercury1/repository/mercury/compiler/export.m,v
> retrieving revision 1.54
> diff -u -d -r1.54 export.m
> --- compiler/export.m 7 May 2002 14:43:39 -0000 1.54
> +++ compiler/export.m 16 May 2002 12:24:02 -0000
> @@ -335,15 +335,25 @@
> RetArgMode = top_out,
> \+ type_util__is_dummy_argument_type(RetType)
> ->
> - C_RetType = llds_exported_type_string(Module, RetType),
> + Export_RetType = foreign__to_exported_type(Module,
> + RetType),
> + C_RetType = foreign__to_type_string(c, Export_RetType),
> argloc_to_string(RetArgLoc, RetArgString0),
> convert_type_from_mercury(RetArgString0, RetType,
> RetArgString),
> string__append_list(["\t", C_RetType,
> " return_value;\n"],
> MaybeDeclareRetval),
> - string__append_list(["\treturn_value = ", RetArgString,
> - ";\n"], MaybeFail),
> + ( foreign__is_foreign_type(Export_RetType) = yes ->
> + string__append_list(
> + ["\tMR_MAYBE_UNBOX_FOREIGN_TYPE(",
> + C_RetType, ", ", RetArgString,
> + ", return_value);\n"], SetReturnValue)
> + ;
> + string__append_list(["\treturn_value = ",
> + RetArgString, ";\n"], SetReturnValue)
> + ),
> + MaybeFail = SetReturnValue,
> string__append_list(["\treturn return_value;\n"],
> MaybeSucceed),
> ArgInfoTypes2 = ArgInfoTypes1
A comment explaining why they need to unboxed rather than boxed would be
appropiate. I took me a bit of thinking to work out why, because my
first thought was that input args need to be boxed, but of course this
code is for the pragma export.
> @@ -435,7 +445,7 @@
> ;
> ArgName = ""
> ),
> - TypeString0 = llds_exported_type_string(Module, Type),
> + TypeString0 = foreign__to_type_string(c, Module, Type),
> (
> Mode = top_out
> ->
> @@ -445,11 +455,11 @@
> TypeString = TypeString0
> ).
>
> -:- pred get_input_args(assoc_list(arg_info, type), int, string).
> -:- mode get_input_args(in, in, out) is det.
> +:- pred get_input_args(assoc_list(arg_info, type), int, module_info, string).
> +:- mode get_input_args(in, in, in, out) is det.
>
> -get_input_args([], _, "").
> -get_input_args([AT|ATs], Num0, Result) :-
> +get_input_args([], _, _, "").
> +get_input_args([AT|ATs], Num0, ModuleInfo, Result) :-
> AT = ArgInfo - Type,
> ArgInfo = arg_info(ArgLoc, Mode),
> Num is Num0 + 1,
> @@ -460,9 +470,18 @@
> string__append("Mercury__argument", NumString, ArgName0),
> convert_type_to_mercury(ArgName0, Type, ArgName),
> argloc_to_string(ArgLoc, ArgLocString),
> - string__append_list(
> - ["\t", ArgLocString, " = ", ArgName, ";\n" ],
> - InputArg)
> + Export_Type = foreign__to_exported_type(ModuleInfo, Type),
> + ( foreign__is_foreign_type(Export_Type) = yes ->
> + C_Type = foreign__to_type_string(c, Export_Type),
> + string__append_list(
> + ["\tMR_MAYBE_BOX_FOREIGN_TYPE(",
> + C_Type, ", ", ArgName, ", ",
> + ArgLocString, ");\n"], InputArg)
> + ;
> + string__append_list(
> + ["\t", ArgLocString, " = ", ArgName, ";\n" ],
> + InputArg)
> + )
> ;
> Mode = top_out,
> InputArg = ""
Ditto.
> @@ -470,14 +489,14 @@
> Mode = top_unused,
> InputArg = ""
> ),
> - get_input_args(ATs, Num, TheRest),
> + get_input_args(ATs, Num, ModuleInfo, TheRest),
> string__append(InputArg, TheRest, Result).
>
> -:- pred copy_output_args(assoc_list(arg_info, type), int, string).
> -:- mode copy_output_args(in, in, out) is det.
> +:- pred copy_output_args(assoc_list(arg_info, type), int, module_info, string).
> +:- mode copy_output_args(in, in, in, out) is det.
>
> -copy_output_args([], _, "").
> -copy_output_args([AT|ATs], Num0, Result) :-
> +copy_output_args([], _, _, "").
> +copy_output_args([AT|ATs], Num0, ModuleInfo, Result) :-
> AT = ArgInfo - Type,
> ArgInfo = arg_info(ArgLoc, Mode),
> Num is Num0 + 1,
> @@ -486,19 +505,27 @@
> OutputArg = ""
> ;
> Mode = top_out,
> -
> string__int_to_string(Num, NumString),
> string__append("Mercury__argument", NumString, ArgName),
> argloc_to_string(ArgLoc, ArgLocString0),
> convert_type_from_mercury(ArgLocString0, Type, ArgLocString),
> - string__append_list(
> - ["\t*", ArgName, " = ", ArgLocString, ";\n" ],
> - OutputArg)
> + Export_Type = foreign__to_exported_type(ModuleInfo, Type),
> + ( foreign__is_foreign_type(Export_Type) = yes ->
> + C_Type = foreign__to_type_string(c, Export_Type),
> + string__append_list(
> + ["\tMR_MAYBE_UNBOX_FOREIGN_TYPE(",
> + C_Type, ", ", ArgLocString, ", ",
> + ArgName, ");\n"], OutputArg)
> + ;
> + string__append_list(
> + ["\t*", ArgName, " = ", ArgLocString, ";\n" ],
> + OutputArg)
> + )
> ;
> Mode = top_unused,
> OutputArg = ""
> ),
> - copy_output_args(ATs, Num, TheRest),
> + copy_output_args(ATs, Num, ModuleInfo, TheRest),
> string__append(OutputArg, TheRest, Result).
>
> % convert an argument location (currently just a register number)
Ditto.
> Index: compiler/ml_code_gen.m
> ===================================================================
> RCS file: /home/mercury1/repository/mercury/compiler/ml_code_gen.m,v
> retrieving revision 1.114
> diff -u -d -r1.114 ml_code_gen.m
> --- compiler/ml_code_gen.m 7 May 2002 11:03:02 -0000 1.114
> +++ compiler/ml_code_gen.m 16 May 2002 11:57:22 -0000
> @@ -2913,41 +2913,62 @@
..
> + % For --no-high-level-data, we only need to use
> + % a cast is for polymorphic types, which are
> + % `Word' in the C interface but `MR_Box' in the
> + % MLDS back-end.
> + % Except for MC++, where polymorphic types
> + % are MR_Box.
Have you tested this on the MC++ backend? I am not sure that things
will still work, but considering I am rewriting that part of the
compiler at the moment, if there are any problems I will fix them.
> Index: compiler/mlds.m
> ===================================================================
> RCS file: /home/mercury1/repository/mercury/compiler/mlds.m,v
> retrieving revision 1.90
> diff -u -d -r1.90 mlds.m
> --- compiler/mlds.m 7 May 2002 11:03:04 -0000 1.90
> +++ compiler/mlds.m 16 May 2002 07:51:03 -0000
> @@ -1632,7 +1632,9 @@
>
> %-----------------------------------------------------------------------------%
>
> -% Currently we return mlds__types that are just the same as Mercury types,
> +% There is some special-case handling for arrays and foreign_types here.
> +% But apart from that,
> +% currently we return mlds__types that are just the same as Mercury types,
> % except that we also store the type category, so that we
> % can tell if the type is an enumeration or not, without
> % needing to refer to the HLDS type_table.
> @@ -1676,7 +1678,15 @@
> ; Target = java,
> sorry(this_file, "foreign types on the java backend")
> ; Target = asm,
> - sorry(this_file, "foreign types on the asm backend")
> + ( MaybeC = yes(CForeignType),
> + ForeignType = c(CForeignType)
> + ; MaybeC = no,
> + % XXX This ought to be checked by the
> + % front-end, e.g. check_foreign_type
> + % in make_hlds.
> + sorry(this_file,
> + "mercury_type_to_mlds_type: No C foreign type")
> + )
> ),
> MLDSType = mlds__foreign_type(ForeignType)
> ;
Change the sorry to unexpected and abstract the code in
make_hlds__check_foreign_type for the C target and reuse it for the asm
target.
> Index: compiler/mlds_to_c.m
> ===================================================================
> RCS file: /home/mercury1/repository/mercury/compiler/mlds_to_c.m,v
> retrieving revision 1.128
> diff -u -d -r1.128 mlds_to_c.m
> --- compiler/mlds_to_c.m 7 May 2002 11:03:05 -0000 1.128
> +++ compiler/mlds_to_c.m 16 May 2002 13:48:58 -0000
> @@ -650,7 +650,7 @@
> mlds_output_pragma_export_type(prefix, mercury_array_type(_ElemType)) -->
> io__write_string("MR_Word").
> mlds_output_pragma_export_type(prefix, mercury_type(_, _, ExportedType)) -->
> - io__write_string(to_type_string(c, ExportedType)).
> + io__write_string(foreign__to_type_string(c, ExportedType)).
> mlds_output_pragma_export_type(prefix, mlds__cont_type(_)) -->
> io__write_string("MR_Word").
> mlds_output_pragma_export_type(prefix, mlds__commit_type) -->
> @@ -663,8 +663,13 @@
> io__write_string("MR_Float").
> mlds_output_pragma_export_type(prefix, mlds__native_char_type) -->
> io__write_string("MR_Char").
> -mlds_output_pragma_export_type(prefix, mlds__foreign_type(_)) -->
> - io__write_string("MR_Box").
> +mlds_output_pragma_export_type(prefix, mlds__foreign_type(ForeignType)) -->
> + ( { ForeignType = c(c(Name)) },
> + io__write_string(Name)
> + ; { ForeignType = il(_) },
> + { unexpected(this_file,
> + "mlds_output_type_prefix: il foreign_type") }
> + ).
> mlds_output_pragma_export_type(prefix, mlds__class_type(_, _, _)) -->
> io__write_string("MR_Word").
> mlds_output_pragma_export_type(prefix, mlds__array_type(_)) -->
> @@ -698,53 +703,157 @@
> mlds_output_pragma_export_defn_body(ModuleName, FuncName, Signature) -->
> { Signature = mlds__func_params(Parameters, RetTypes) },
>
> + % Declare local variables corresponding to any foreign_type
> + % parameters
> + { IsCForeignType = (pred(Arg::in) is semidet :-
> + Arg = mlds__argument(_Name, Type, _GCTraceCode),
> + Type = mlds__foreign_type(c(_))) },
> + { IsCForeignTypePtr = (pred(Arg::in) is semidet :-
> + Arg = mlds__argument(_Name, Type, _GCTraceCode),
> + Type = mlds__ptr_type(mlds__foreign_type(c(_)))) },
> + { CForeignTypeInputs = list__filter(IsCForeignType, Parameters) },
> + { CForeignTypeOutputs = list__filter(IsCForeignTypePtr, Parameters) },
> + io__write_list(CForeignTypeInputs ++ CForeignTypeOutputs, "",
> + (pred(Arg::in, di, uo) is det -->
> + { Arg = mlds__argument(Name, Type, _GC_TraceCode) },
> + io__write_string("\t"),
> + mlds_output_data_decl_ho(mlds_output_type_prefix,
> + mlds_output_type_suffix,
> + qual(ModuleName, boxed_name(Name)), Type),
> + io__write_string(";\n"))),
> +
> + % Declare a local variable or two for the return value, if needed
> + ( { RetTypes = [RetType1] } ->
> + ( { RetType1 = mlds__foreign_type(c(_)) } ->
> + io__write_string("\t"),
> + mlds_output_pragma_export_type(RetType1),
> + io__write_string(" ret_value;\n"),
> + io__write_string("\t"),
> + mlds_output_type(RetType1),
> + io__write_string(" boxed_ret_value;\n")
> + ;
> + io__write_string("\t"),
> + mlds_output_pragma_export_type(RetType1),
> + io__write_string(" ret_value;\n")
> + )
> + ;
> + []
> + ),
> +
> + % Generate code to box any foreign_type input parameters
> + io__write_list(CForeignTypeInputs, "",
> + (pred(Arg::in, di, uo) is det -->
> + { Arg = mlds__argument(Name, Type, _GC_TraceCode) },
> + { QualName = qual(ModuleName, Name) },
> + { BoxedQualName = qual(ModuleName, boxed_name(Name)) },
> + io__write_string("\tMR_MAYBE_BOX_FOREIGN_TYPE("),
> + mlds_output_pragma_export_type(Type),
> + io__write_string(", "),
> + mlds_output_fully_qualified_name(QualName),
> + io__write_string(", "),
> + mlds_output_fully_qualified_name(BoxedQualName),
> + io__write_string(");\n"))),
> +
Again a comment about why they need to unboxed rather than boxed.
> + % Generate code to actually call the Mercury procedure which
> + % is being exported
> ( { RetTypes = [] } ->
> - io__write_string("\t")
> - ; { RetTypes = [RetType] } ->
> - io__write_string("\treturn ("),
> - mlds_output_pragma_export_type(RetType),
> - io__write_string(") ")
> + io__write_string("\t"),
> + mlds_output_pragma_export_call(ModuleName, FuncName,
> + Parameters)
> + ; { RetTypes = [RetType2] } ->
> + ( { RetType2 = mlds__foreign_type(c(_)) } ->
> + io__write_string("\tboxed_ret_value = ")
> + ;
> + io__write_string("\tret_value = ("),
> + mlds_output_pragma_export_type(RetType2),
> + io__write_string(")")
> + ),
> + mlds_output_pragma_export_call(ModuleName, FuncName,
> + Parameters)
> ;
> + % This is just for MLDS dumps when compiling to non-C targets.
> + % So we don't need to worry about boxing/unboxing foreign types
> + % here.
> io__write_string("\treturn ("),
> mlds_output_return_list(RetTypes,
> mlds_output_pragma_export_type),
> io__write_string(") ")
> ),
>
> + % Generate code to unbox any foreign_type output parameters
> + io__write_list(CForeignTypeOutputs, "",
> + (pred(Arg::in, di, uo) is det -->
> + { Arg = mlds__argument(Name, Type, _GC_TraceCode) },
> + { QualName = qual(ModuleName, Name) },
> + { BoxedQualName = qual(ModuleName, boxed_name(Name)) },
> + io__write_string("\tMR_MAYBE_UNBOX_FOREIGN_TYPE("),
> + mlds_output_pragma_export_type(Type),
> + io__write_string(", "),
> + mlds_output_fully_qualified_name(BoxedQualName),
> + io__write_string(", *"),
> + mlds_output_fully_qualified_name(QualName),
> + io__write_string(");\n"))),
> +
Ditto boxing/unboxing.
> + % Generate the final statement to unbox and return the
> + % return value, if needed.
> + ( { RetTypes = [RetType3] } ->
> + ( { RetType3 = mlds__foreign_type(c(_)) } ->
> + io__write_string("\tMR_MAYBE_UNBOX_FOREIGN_TYPE("),
> + mlds_output_pragma_export_type(RetType3),
> + io__write_string(", boxed_ret_value, ret_value);\n")
> + ;
> + []
> + ),
> + io__write_string("\treturn ret_value;\n")
> + ;
> + []
> + ).
> +
Ditto boxing/unboxing.
--------------------------------------------------------------------------
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