[m-rev.] diff: construct for java backend

Peter Wang novalazy at gmail.com
Fri Aug 7 16:14:37 AEST 2009


On 2009-07-31, Peter Wang <novalazy at gmail.com> wrote:
> Branches: main
> 
> Implementation of construct and construct_tuple for Java backend.
> 

Branches: main

The implementation of construct/3 for Java needs to take into account name
mangling of module and functor names.

library/rtti_implementation.m:
        Replicate the name mangling algorithm in the construct implementation
        for Java.

compiler/prog_foreign.m:
        Add a forwarding comment if the name mangling algorithm changes.

tests/hard_coded/Mmakefile:
tests/hard_coded/construct_mangle.exp:
tests/hard_coded/construct_mangle.m:
        Add test case.

diff --git a/compiler/prog_foreign.m b/compiler/prog_foreign.m
index fd1d269..4aece91 100644
--- a/compiler/prog_foreign.m
+++ b/compiler/prog_foreign.m
@@ -387,8 +387,8 @@ name_mangle_no_leading_digit(Name) = name_mangle_2(no, Name).
 
 name_mangle_2(AllowLeadingDigit, Name) = MangledName :-
     % Warning: any changes to the name mangling algorithm here may also
-    % require changes to profiler/demangle.m, util/mdemangle.c and
-    % compiler/name_mangle.m.
+    % require changes to profiler/demangle.m, util/mdemangle.c,
+    % compiler/name_mangle.m and library/rtti_implementation.m.
 
     (
         string.is_all_alnum_or_underscore(Name),
@@ -431,6 +431,9 @@ convert_to_valid_c_identifier(String) = Name :-
     % name is not found in the table, then we use a fall-back method which
     % produces ugly names.
     %
+    % Additions to this table should be reflected in rtti_implementation.m,
+    % in the ML_name_mangle() method.
+    %
 :- pred name_conversion_table(string::in, string::out) is semidet.
 
 name_conversion_table("\\=", "f_not_equal").
diff --git a/library/rtti_implementation.m b/library/rtti_implementation.m
index 8c2c5bb..1f0a872 100644
--- a/library/rtti_implementation.m
+++ b/library/rtti_implementation.m
@@ -1302,14 +1302,18 @@ iterate(Start, Max, Func) = Results :-
         Class<?> cls;
 
         if (tc.type_ctor_num_functors == 1) {
-            cls = Class.forName(""jmercury."" + tc.type_ctor_module_name
-                + ""$"" + ML_flipInitialCase(tc.type_ctor_name)
+            cls = Class.forName(
+                ""jmercury."" + ML_name_mangle(tc.type_ctor_module_name)
+                + ""$"" + ML_flipInitialCase(ML_name_mangle(tc.type_ctor_name))
                 + ""_"" + tc.arity);
         } else {
-            cls = Class.forName(""jmercury."" + tc.type_ctor_module_name
-                + ""$"" + ML_flipInitialCase(tc.type_ctor_name)
+            cls = Class.forName(
+                ""jmercury."" + ML_name_mangle(tc.type_ctor_module_name)
+                + ""$"" + ML_flipInitialCase(
+                            ML_name_mangle(tc.type_ctor_name))
                 + ""_"" + tc.arity
-                + ""$"" + ML_flipInitialCase(functor_desc.du_functor_name)
+                + ""$"" + ML_flipInitialCase(
+                            ML_name_mangle(functor_desc.du_functor_name))
                 + ""_"" + functor_desc.du_functor_orig_arity);
         }
 
@@ -1360,8 +1364,9 @@ iterate(Start, Max, Func) = Results :-
         throws ClassNotFoundException, NoSuchFieldException,
             IllegalAccessException
     {
-        Class<?> cls = Class.forName(""jmercury."" + tc.type_ctor_module_name
-            + ""$"" + ML_flipInitialCase(tc.type_ctor_name)
+        Class<?> cls = Class.forName(
+            ""jmercury."" + ML_name_mangle(tc.type_ctor_module_name)
+            + ""$"" + ML_flipInitialCase(ML_name_mangle(tc.type_ctor_name))
             + ""_"" + tc.arity);
 
         String field_name = ""K"" + i;
@@ -1386,6 +1391,43 @@ iterate(Start, Max, Func) = Results :-
         return s;
     }
 
+    private static String
+    ML_name_mangle(String s)
+    {
+        if (s.matches(""[A-Za-z_][A-Za-z0-9_]*"")) {
+            if (s.startsWith(""f_"")) {
+                return ""f__"" + s.substring(2);
+            } else {
+                return s;
+            }
+        }
+
+        /* This is from prog_foreign.name_conversion_table. */
+        if (s.equals(""\\\\="")) return ""f_not_equal"";
+        if (s.equals("">="")) return ""f_greater_or_equal"";
+        if (s.equals(""=<"")) return ""f_less_or_equal"";
+        if (s.equals(""="")) return ""f_equal"";
+        if (s.equals(""<"")) return ""f_less_than"";
+        if (s.equals("">"")) return ""f_greater_than"";
+        if (s.equals(""-"")) return ""f_minus"";
+        if (s.equals(""+"")) return ""f_plus"";
+        if (s.equals(""*"")) return ""f_times"";
+        if (s.equals(""/"")) return ""f_slash"";
+        if (s.equals("","")) return ""f_comma"";
+        if (s.equals("";"")) return ""f_semicolon"";
+        if (s.equals(""!"")) return ""f_cut"";
+        if (s.equals(""{}"")) return ""f_tuple"";
+        if (s.equals(""[|]"")) return ""f_cons"";
+        if (s.equals(""[]"")) return ""f_nil"";
+
+        StringBuilder sb = new StringBuilder(""f"");
+        for (int i = 0; i < s.length(); i++) {
+            sb.append('_');
+            sb.append(s.codePointAt(i));
+        }
+        return sb.toString();
+    }
+
     private static Object[]
     ML_list_to_array(list.List_1 list, int arity)
     {
diff --git a/tests/hard_coded/Mmakefile b/tests/hard_coded/Mmakefile
index 0135843..3c5270f 100644
--- a/tests/hard_coded/Mmakefile
+++ b/tests/hard_coded/Mmakefile
@@ -30,6 +30,7 @@ ORDINARY_PROGS=	\
 	constraint \
 	constraint_order \
 	construct_bug \
+	construct_mangle \
 	construct_test \
 	construct_test_exist \
 	contains_char \
diff --git a/tests/hard_coded/construct_mangle.exp b/tests/hard_coded/construct_mangle.exp
new file mode 100644
index 0000000..dbab897
--- /dev/null
+++ b/tests/hard_coded/construct_mangle.exp
@@ -0,0 +1,51 @@
+univ_cons(' ')
+univ_cons((!))
+univ_cons('\"')
+univ_cons('#')
+univ_cons('$')
+univ_cons('%')
+univ_cons((&))
+univ_cons('\'')
+univ_cons('(')
+univ_cons(')')
+univ_cons((*))
+univ_cons((+))
+univ_cons((','))
+univ_cons((-))
+univ_cons((.))
+univ_cons((/))
+univ_cons('0')
+univ_cons('1')
+univ_cons('2')
+univ_cons('3')
+univ_cons('4')
+univ_cons('5')
+univ_cons('6')
+univ_cons('7')
+univ_cons('8')
+univ_cons('9')
+univ_cons((:))
+univ_cons((;))
+univ_cons((<))
+univ_cons((=))
+univ_cons((=<))
+univ_cons((>))
+univ_cons((>=))
+univ_cons('?')
+univ_cons((@))
+univ_cons('[')
+univ_cons([])
+univ_cons('[|]')
+univ_cons((\))
+univ_cons((\=))
+univ_cons(']')
+univ_cons((^))
+univ_cons('_')
+univ_cons('`')
+univ_cons('abc~!@#$%^&*()_+|xyz')
+univ_cons(f_this_also_requires_mangling)
+univ_cons('{')
+univ_cons({})
+univ_cons('|')
+univ_cons('}')
+univ_cons((~))
diff --git a/tests/hard_coded/construct_mangle.m b/tests/hard_coded/construct_mangle.m
new file mode 100644
index 0000000..1e6c1ab
--- /dev/null
+++ b/tests/hard_coded/construct_mangle.m
@@ -0,0 +1,117 @@
+%-----------------------------------------------------------------------------%
+% Test construction of name mangled functors (e.g. on Java).
+
+:- module construct_mangle.
+:- interface.
+
+:- import_module io.
+
+:- pred main(io::di, io::uo) is det.
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module int.
+:- import_module list.
+:- import_module construct.
+:- import_module type_desc.
+:- import_module univ.
+:- import_module string.
+
+%-----------------------------------------------------------------------------%
+
+main(!IO) :-
+    Type = type_of(_ : requires_mangling),
+    ( NumFunctors = num_functors(Type) ->
+        list.foldl(test_functor(Type), 0 .. NumFunctors - 1, !IO)
+    ;
+        io.write_string("failed\n", !IO)
+    ).
+
+    % This must not be an enumeration as enumerations on Java are represented
+    % in a way such that name mangling doesn't apply.
+    %
+:- type requires_mangling
+    --->    (' ')
+    ;       ('!')
+    ;       ('"')
+    ;       ('#')
+    ;       ('$')
+    ;       ('%')
+    ;       ('&')
+    ;       ('''')
+    ;       ('(')
+    ;       (')')
+    ;       ('*')
+    ;       ('+')
+    ;       (',')
+    ;       ('-')
+    ;       ('.')
+    ;       ('/')
+    ;       ('0')
+    ;       ('1')
+    ;       ('2')
+    ;       ('3')
+    ;       ('4')
+    ;       ('5')
+    ;       ('6')
+    ;       ('7')
+    ;       ('8')
+    ;       ('9')
+    ;       (':')
+    ;       (';')
+    ;       ('<')
+    ;       ('=')
+    ;       ('>')
+    ;       ('?')
+    ;       ('@')
+    ;       ('[')
+    ;       ('\\')
+    ;       (']')
+    ;       ('^')
+    ;       ('_')
+    ;       ('`')
+    ;       ('{')
+    ;       ('|')
+    ;       ('}')
+    ;       ('~')
+    ;       ('\\=')
+    ;       ('>=')
+    ;       ('=<')
+    ;       ('{}')
+    ;       ('[|]')
+    ;       ('[]')
+    ;       ('abc~!@#$%^&*()_+|xyz')
+    ;       f_this_also_requires_mangling
+    ;       force_non_enum(int).
+
+:- pred test_functor(type_desc::in, int::in, io::di, io::uo) is det.
+
+test_functor(Type, FunctorNumber, !IO) :-
+    ( get_functor(Type, FunctorNumber, Name, Arity, ArgTypes) ->
+        (
+            ArgTypes = [],
+            (
+                find_functor(Type, Name, Arity, FunctorNumber, _),
+                Univ = construct(Type, FunctorNumber, [])
+            ->
+                io.write(Univ, !IO),
+                io.nl(!IO)
+            ;
+                io.write_string("failed FunctorNumber = ", !IO),
+                io.write_int(FunctorNumber, !IO),
+                io.nl(!IO)
+            )
+        ;
+            ArgTypes = [_ | _]
+        )
+    ;
+        io.write_string("failed FunctorNumber = ", !IO),
+        io.write_int(FunctorNumber, !IO),
+        io.nl(!IO)
+    ).
+
+%-----------------------------------------------------------------------------%
+% vim: ft=mercury ts=8 sts=4 sw=4 et

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