[m-rev.] for review: correct types in java foreign procs

Julien Fischer juliensf at csse.unimelb.edu.au
Wed Sep 2 12:14:56 AEST 2009


On Mon, 31 Aug 2009, Peter Wang wrote:

> Branches: main
>
> Expose correct types to Java foreign code, e.g. a variable with a non-foreign
> type like `list(T)' is now visible to Java foreign code with the type
> `list.List_1' instead of `java.lang.Object'.
>
> A complication is that foreign code for mutables is generated in the compiler
> frontend, which doesn't know about the types used by the backends.  For Java,
> mutable variables had the generic type `Object' (except for primitives types)
> but as we now generate foreign procs with the correct variable types, the code
> for accessing a mutable would be type incorrect, e.g.
>
>        X = mutable_var;  /* list.List_1 = Object */
>
> Here we handle generated mutable predicates as a special case, using `Object'
> for the global variable and argument types and generating typecasts as before.
> The correct fix would be to move mutable code generation into the backends.

Yes, there are a bunch of bugs, #19 for example, that also require that fix.
(If you are contemplating making such a fix, we should discuss it beforehand.)

> compiler/make_hlds_passes.m:
>        Make Java mutable variables always have the type `java.lang.Object'.
>
>        Mark Java mutable predicates with `may_not_duplicate' attributes, as
>        the generated code doesn't contain class-qualifiers for the mutable
>        variable, so copying that code into other Java files won't work.
> compiler/mlds.m:
>        Add a new target code component `target_code_type(Type)' which is a
>        placeholder for a type, to be substituted by the backend when target
>        code is being printed out.
>
> compiler/ml_code_gen.m:
>        Generate Java foreign procs using `target_code_type' to declare local
>        variables, except for mutable predicates as described above.
>
>        Rename a predicate shared for C and Java.
>
>        Assign dummy type variables the value `null' in the Java backend
>        instead of `0'.
>
> compiler/foreign.m:
>        Add a comment for `exported_type_to_string'.
>
> compiler/mlds_to_java.m:
>        Handle the addition of `target_code_type'.
>
>        Output `java.lang.Output' for builtin dummy types.  We were
>        inconsistent as to whether builtin dummy types should be represented by
>        `int' or `Object'.
>
>        Output line number context in another spot.
>
> compiler/ml_elim_nested.m:
> compiler/ml_optimize.m:
> compiler/ml_util.m:
> compiler/mlds_to_c.m:
> compiler/mlds_to_il.m:
>        Conform to the addition of `target_code_type'.
>
> library/exception.m:
> library/io.m:
> library/list.m:
> library/rtti_implementation.m:
> library/string.m:
> library/type_desc.m:
>        Delete casts in some Java foreign code which are no longer required.
>
> diff --git a/compiler/foreign.m b/compiler/foreign.m
> index d289bab..947e4ff 100644
> --- a/compiler/foreign.m
> +++ b/compiler/foreign.m
> @@ -745,6 +745,8 @@ exported_type_to_string(Lang, ExportedType) = Result :-
>                 ; Type = type_variable(_, _)
>                 ; Type = kinded_type(_, _)
>                 ),
> +                % This is here so we can share some code between C and Java
> +                % backends.  This is not the correct type to use in general.
>                 Result = "java.lang.Object"
>             )
>         ;
> diff --git a/compiler/make_hlds_passes.m b/compiler/make_hlds_passes.m
> index 849055f..1a84c3d 100644
> --- a/compiler/make_hlds_passes.m
> +++ b/compiler/make_hlds_passes.m
> @@ -2311,12 +2311,8 @@ add_java_mutable_defn(TargetMutableName, Type, IsConstant,
> :- pred get_java_mutable_global_foreign_defn(module_info::in, mer_type::in,
>     string::in, bool::in, prog_context::in, item::out) is det.
>
> -get_java_mutable_global_foreign_defn(ModuleInfo, Type, TargetMutableName,
> +get_java_mutable_global_foreign_defn(_ModuleInfo, _Type, TargetMutableName,
>         IsConstant, Context, DefnItem) :-
> -    module_info_get_globals(ModuleInfo, Globals),
> -    globals.lookup_bool_option(Globals, mutable_always_boxed, AlwaysBoxed),
> -    TypeName = global_foreign_type_name(AlwaysBoxed, lang_java, ModuleInfo,
> -        Type),
>     MutableMutexVarName = mutable_mutex_var_name(TargetMutableName),
>
>     % Constant mutables do not require mutexes as their values are never
> @@ -2331,7 +2327,7 @@ get_java_mutable_global_foreign_defn(ModuleInfo, Type, TargetMutableName,
>     ),
>
>     DefnBody = string.append_list([
> -        "static ", TypeName, " ", TargetMutableName, ";\n" | LockDefn]),
> +        "static java.lang.Object ", TargetMutableName, ";\n" | LockDefn]),
>     DefnPragma = pragma_foreign_code(lang_java, DefnBody),
>     DefnItemPragma = item_pragma_info(compiler(mutable_decl), DefnPragma,
>         Context, -1),
> @@ -2348,7 +2344,11 @@ add_java_mutable_preds(ItemMutable, TargetMutableName,
>     ItemMutable = item_mutable_info(MercuryMutableName, _Type, InitTerm, Inst,
>         MutAttrs, MutVarset, Context, _SeqNum),
>     IsConstant = mutable_var_constant(MutAttrs),
> -    Attrs = default_attributes(lang_java),
> +    Attrs0 = default_attributes(lang_java),
> +    % The mutable variable name is not module-qualified so cannot be exported
> +    % to `.opt' files. We could add the qualification but it would be better
> +    % to move the mutable code generation into the backends first.
> +    set_may_duplicate(yes(proc_may_not_duplicate), Attrs0, Attrs),
>     module_info_get_globals(!.ModuleInfo, Globals),
>     globals.lookup_bool_option(Globals, mutable_always_boxed, AlwaysBoxed),
>     (
> diff --git a/compiler/ml_code_gen.m b/compiler/ml_code_gen.m
> index 801349a..608ef55 100644
> --- a/compiler/ml_code_gen.m
> +++ b/compiler/ml_code_gen.m
> @@ -2382,10 +2382,10 @@ ml_gen_nondet_pragma_foreign_proc(CodeModel, Attributes, PredId, _ProcId,
>         ], HashUndefs),
>
>     % Generate code to set the values of the input variables.
> -    ml_gen_pragma_c_input_arg_list(Lang, Args, AssignInputsList, !Info),
> +    ml_gen_pragma_c_java_input_arg_list(Lang, Args, AssignInputsList, !Info),
>
>     % Generate code to assign the values of the output variables.
> -    ml_gen_pragma_c_output_arg_list(Lang, Args, Context,
> +    ml_gen_pragma_c_output_arg_list(Args, Context,
>         AssignOutputsList, ConvDecls, ConvStatements, !Info),
>
>     % Generate code fragments to obtain and release the global lock.
> @@ -2601,21 +2601,29 @@ ml_gen_ordinary_pragma_foreign_proc(CodeModel, Attributes, PredId, ProcId,
>     prog_context::in, list(mlds_defn)::out, list(statement)::out,
>     ml_gen_info::in, ml_gen_info::out) is det.
>
> -ml_gen_ordinary_pragma_java_proc(_CodeModel, Attributes, _PredId, _ProcId,
> +ml_gen_ordinary_pragma_java_proc(_CodeModel, Attributes, PredId, _ProcId,
>         Args, ExtraArgs, JavaCode, Context, Decls, Statements, !Info) :-
> -
>     Lang = get_foreign_language(Attributes),
>
> +    ml_gen_info_get_module_info(!.Info, ModuleInfo),
> +    module_info_pred_info(ModuleInfo, PredId, PredInfo),
> +    pred_info_get_markers(PredInfo, Markers),
> +    ( check_marker(Markers, marker_mutable_access_pred) ->
> +        MutableSpecial = mutable_special_case
> +    ;
> +        MutableSpecial = not_mutable_special_case
> +    ),
> +
>     % Generate <declaration of one local variable for each arg>
> -    ml_gen_pragma_c_decls(!.Info, Lang, Args, ArgDeclsList),
> +    ml_gen_pragma_java_decls(!.Info, MutableSpecial, Args, ArgDeclsList),
>     expect(unify(ExtraArgs, []), this_file,
>         "ml_gen_ordinary_pragma_java_proc: extra args"),
>
>     % Generate code to set the values of the input variables.
> -    ml_gen_pragma_c_input_arg_list(Lang, Args, AssignInputsList, !Info),
> +    ml_gen_pragma_c_java_input_arg_list(Lang, Args, AssignInputsList, !Info),
>
>     % Generate MLDS statements to assign the values of the output variables.
> -    ml_gen_pragma_java_output_arg_list(Lang, Args, Context,
> +    ml_gen_pragma_java_output_arg_list(MutableSpecial, Args, Context,
>         AssignOutputsList, ConvDecls, ConvStatements, !Info),
>
>     % Put it all together
> @@ -2971,10 +2979,10 @@ ml_gen_ordinary_pragma_c_proc(OrdinaryKind, Attributes, PredId, _ProcId,
>     ml_gen_pragma_c_decls(!.Info, Lang, Args, ArgDeclsList),
>
>     % Generate code to set the values of the input variables.
> -    ml_gen_pragma_c_input_arg_list(Lang, Args, AssignInputsList, !Info),
> +    ml_gen_pragma_c_java_input_arg_list(Lang, Args, AssignInputsList, !Info),
>
>     % Generate code to assign the values of the output variables.
> -    ml_gen_pragma_c_output_arg_list(Lang, Args, Context,
> +    ml_gen_pragma_c_output_arg_list(Args, Context,
>         AssignOutputsList, ConvDecls, ConvStatements, !Info),
>
>     % Generate code fragments to obtain and release the global lock.
> @@ -3142,9 +3150,6 @@ get_target_code_attributes(Lang, [ProcAttr | ProcAttrs]) = TargetAttrs :-
> :- pred ml_gen_pragma_c_decls(ml_gen_info::in, foreign_language::in,
>     list(foreign_arg)::in, list(target_code_component)::out) is det.
>
> -    % XXX Maybe this ought to be renamed as it works for, and
> -    % is used by the Java back-end as well.
> -    %
> ml_gen_pragma_c_decls(_, _, [], []).
> ml_gen_pragma_c_decls(Info, Lang, [Arg | Args], [Decl | Decls]) :-
>     ml_gen_pragma_c_decl(Info, Lang, Arg, Decl),
> @@ -3181,6 +3186,55 @@ ml_gen_pragma_c_decl(Info, Lang, Arg, Decl) :-
>
> %-----------------------------------------------------------------------------%
>
> +:- type mutable_special_case
> +    --->    mutable_special_case
> +    ;       not_mutable_special_case.

Document this type.

The change looks fine otherwise.

Julien.
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to:       mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions:          mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------



More information about the reviews mailing list