[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