From dfca5e04f0e655a64a21ce499ac9d080187fec56 Mon Sep 17 00:00:00 2001 From: Peter Wang Date: Thu, 9 Jul 2009 05:18:08 +0000 Subject: [PATCH] Make Java classes corresponding to Mercury types automatically serialisable. Branches: main Make Java classes corresponding to Mercury types automatically serialisable. java/runtime/MercuryType.java: Make MercuryType extend java.io.Serializable. compiler/mlds_to_java.m: java/runtime/MercuryEnum.java: Add a MercuryEnum interface which is implemented by classes corresponding to Mercury enumerations. Previously enumerations didn't implement MercuryType. compiler/ml_type_gen.m: Make enumeration classes implement MercuryType and MercuryEnum. library/builtin.m: Make builtin.copy check for MercuryEnum instead of relying on enumeration classes not to implement MercuryType. This is not strictly necessary but avoids copying instances of enumeration classes. --- compiler/ml_type_gen.m | 46 ++++++++++++++++++++++++++++------- compiler/mlds_to_java.m | 1 + java/runtime/MercuryEnum.java | 13 ++++++++++ java/runtime/MercuryType.java | 6 ++--- library/builtin.m | 4 +++ 5 files changed, 58 insertions(+), 12 deletions(-) create mode 100644 java/runtime/MercuryEnum.java diff --git a/compiler/ml_type_gen.m b/compiler/ml_type_gen.m index 9e79d62e4..d51efc75e 100644 --- a/compiler/ml_type_gen.m +++ b/compiler/ml_type_gen.m @@ -180,13 +180,13 @@ ml_gen_type_2(TypeBody, ModuleInfo, TypeCtor, TypeDefn, !Defns) :- ( DuTypeKind = du_type_kind_mercury_enum ; DuTypeKind = du_type_kind_foreign_enum(_) ), - ml_gen_enum_type(TypeCtor, TypeDefn, Ctors, TagValues, + ml_gen_enum_type(ModuleInfo, TypeCtor, TypeDefn, Ctors, TagValues, MaybeEqualityMembers, !Defns) ; DuTypeKind = du_type_kind_direct_dummy, % XXX We shouldn't have to generate an MLDS type for these types, % but it is not easy to ensure that we never refer to that type. - ml_gen_enum_type(TypeCtor, TypeDefn, Ctors, TagValues, + ml_gen_enum_type(ModuleInfo, TypeCtor, TypeDefn, Ctors, TagValues, MaybeEqualityMembers, !Defns) ; ( DuTypeKind = du_type_kind_notag(_, _, _) @@ -219,11 +219,11 @@ ml_gen_type_2(TypeBody, ModuleInfo, TypeCtor, TypeDefn, !Defns) :- % generator can treat it specially if need be (e.g. generating % a C enum rather than a class). % -:- pred ml_gen_enum_type(type_ctor::in, hlds_type_defn::in, +:- pred ml_gen_enum_type(module_info::in, type_ctor::in, hlds_type_defn::in, list(constructor)::in, cons_tag_values::in, list(mlds_defn)::in, list(mlds_defn)::in, list(mlds_defn)::out) is det. -ml_gen_enum_type(TypeCtor, TypeDefn, Ctors, TagValues, +ml_gen_enum_type(ModuleInfo, TypeCtor, TypeDefn, Ctors, TagValues, MaybeEqualityMembers, MLDS_Defns0, MLDS_Defns) :- hlds_data.get_type_defn_context(TypeDefn, Context), MLDS_Context = mlds_make_context(Context), @@ -243,7 +243,29 @@ ml_gen_enum_type(TypeCtor, TypeDefn, Ctors, TagValues, % Enums don't import or inherit anything. Imports = [], Inherits = [], - Implements = [], + + % Make all Java classes corresponding to types implement the MercuryType + % and MercuryEnum interfaces. + module_info_get_globals(ModuleInfo, Globals), + globals.get_target(Globals, Target), + ( + Target = target_java, + InterfaceModuleName = mercury_module_name_to_mlds( + java_names.mercury_runtime_package_name), + TypeInterface = qual(InterfaceModuleName, module_qual, "MercuryType"), + TypeInterfaceDefn = mlds_class_type(TypeInterface, 0, mlds_interface), + EnumInterface = qual(InterfaceModuleName, module_qual, "MercuryEnum"), + EnumInterfaceDefn = mlds_class_type(EnumInterface, 0, mlds_interface), + Implements = [TypeInterfaceDefn, EnumInterfaceDefn] + ; + ( Target = target_c + ; Target = target_il + ; Target = target_asm + ; Target = target_x86_64 + ; Target = target_erlang + ), + Implements = [] + ), % Put it all together. MLDS_TypeName = entity_type(MLDS_ClassName, MLDS_ClassArity), @@ -471,16 +493,22 @@ ml_gen_du_parent_type(ModuleInfo, TypeCtor, TypeDefn, Ctors, TagValues, Imports = [], Inherits = [], - % For the implementation of arrays in Java, we need to be able to find out - % whether a class corresponds to a Mercury type or functor. We make - % classes corresponding to types implement the MercuryType interface. - ( Target = target_java -> + % Make all Java classes corresponding to types implement the MercuryType + % interface. + ( + Target = target_java, InterfaceModuleName = mercury_module_name_to_mlds( java_names.mercury_runtime_package_name), Interface = qual(InterfaceModuleName, module_qual, "MercuryType"), InterfaceDefn = mlds_class_type(Interface, 0, mlds_interface), Implements = [InterfaceDefn] ; + ( Target = target_c + ; Target = target_il + ; Target = target_asm + ; Target = target_x86_64 + ; Target = target_erlang + ), Implements = [] ), diff --git a/compiler/mlds_to_java.m b/compiler/mlds_to_java.m index 5a220b586..9b43902ff 100644 --- a/compiler/mlds_to_java.m +++ b/compiler/mlds_to_java.m @@ -228,6 +228,7 @@ rval_is_enum_object(Rval) :- % :- pred interface_is_special(string::in) is semidet. +interface_is_special("MercuryEnum"). interface_is_special("MercuryType"). interface_is_special("MethodPtr"). diff --git a/java/runtime/MercuryEnum.java b/java/runtime/MercuryEnum.java new file mode 100644 index 000000000..464b6e970 --- /dev/null +++ b/java/runtime/MercuryEnum.java @@ -0,0 +1,13 @@ +// +// Copyright (C) 2009 The University of Melbourne. +// This file may only be copied under the terms of the GNU Library General +// Public License - see the file COPYING.LIB in the Mercury distribution. +// +// This interface is implemented by all classes generated by the Java back-end +// which correspond to Mercury-defined enumeration types. +// + +package jmercury.runtime; + +public interface MercuryEnum { +} diff --git a/java/runtime/MercuryType.java b/java/runtime/MercuryType.java index f000c0039..b78e3aa39 100644 --- a/java/runtime/MercuryType.java +++ b/java/runtime/MercuryType.java @@ -3,11 +3,11 @@ // This file may only be copied under the terms of the GNU Library General // Public License - see the file COPYING.LIB in the Mercury distribution. // -// This interface is implemented by wrapper classes which are automatically -// generated by the Java back-end to implement method pointers in Java. +// This interface is implemented by all classes generated by the Java back-end +// which correspond to Mercury-defined types. // package jmercury.runtime; -public interface MercuryType { +public interface MercuryType extends java.io.Serializable { } diff --git a/library/builtin.m b/library/builtin.m index 22136ee6b..75d7fd821 100644 --- a/library/builtin.m +++ b/library/builtin.m @@ -821,9 +821,13 @@ special__Compare____tuple_0_0(ref object[] result, // We'll only copy objects of Mercury-defined types. We could copy // more but that's what we do for C backends and it's enough. + // We don't copy enumeration instances. if (!(original instanceof jmercury.runtime.MercuryType)) { return original; } + if (original instanceof jmercury.runtime.MercuryEnum) { + return original; + } // Make a new instance of the class and fill in the fields. // This requires the class have a default constructor.