Previous: C# data passing conventions, Up: Data passing conventions   [Contents]


15.3.3 Java data passing conventions

The Mercury primitive types are mapped to the following Java types:

Mercury typeJava type
intint
int8byte
int16short
int32int
int64long
uintint
uint8byte
uint16short
uint32int
uint64long
floatdouble
charint
stringjava.lang.String

Note that since Java lacks unsigned integer types, Mercury’s unsigned integer types correspond to signed integer types in Java.

Also, note that the Mercury type char is mapped like int; not to the Java type char because that only holds 16-bit numeric values.

For the Mercury standard library type ‘bool.bool’, there is a corresponding Java type, bool.Bool_0. Java code can refer to the boolean data constructors ‘yes’ and ‘no’, as bool.YES and bool.NO respectively.

For the Mercury standard library type ‘builtin.comparison_result’, there is a corresponding Java type, builtin.Comparison_result_0. Java code can refer to the data constructors of this type, ‘(<)’, ‘(=)’ and ‘(>)’, as builtin.COMPARE_LESS, builtin.COMPARE_EQUAL and builtin.COMPARE_GREATER respectively.

Mercury variables of a type for which there is a Java ‘pragma foreign_type’ declaration (see Using foreign types from Mercury) will be passed as the corresponding Java type.

Mercury tuple types are passed as java.lang.Object[] where the length of the array is the number of elements in the tuple.

Mercury variables whose types are universally quantified type variables will have generic types. Mercury variables whose types are existentially quantified type variables will be passed as java.lang.Object.

Mercury variables whose type is a Mercury discriminated union type will be passed as a Java type whose type name is determined from the Mercury type name (ignoring any type parameters) followed by an underscore and then the type arity, expressed as a decimal integer. The first character of the type name will have its case inverted, and the name may be mangled to satisfy Java lexical rules. Generics are used in the Java type for any type parameters.

For example, the following Mercury type corresponds to the Java class that follows (some implementation details elided):

:- type maybe(T)
    --->    yes(yes_field :: T)
    ;       no.

public static class Maybe_1<T> {
    public static class Yes_1<T> extends Maybe_1 {
        public T yes_field;
        public Yes_1(T x) { … }
    }
    public static class No_0<T> extends Maybe_1 {
        public No_0() { … }
    }
}

Java code generated by the Mercury compiler is placed in the ‘jmercury’ package. Mercury module qualifiers are converted into a Java class name by concatenating the components with double underscore separators (‘__’). For example the Mercury type ‘foo.bar.baz/1’ will be passed as the Java type ‘jmercury.foo__bar.Baz_1’.

Mercury array types are mapped to Java array types.

Mercury variables whose type is a Mercury equivalence type will be passed as the representation of the right hand side of the equivalence type.

This mapping is subject to change and you should try to avoid writing code that relies heavily upon a particular representation of Mercury terms.

Mercury arguments declared with input modes are passed by value to the corresponding Java function. If the Mercury procedure is a function whose result has an input mode, then the Mercury function result is appended to the list of input parameters, so that the Mercury function result becomes the last parameter to the corresponding Java function.

Arguments of type ‘io.state’ or ‘store.store(_)’ are not passed or returned at all. (The reason for this is that these types represent mutable state, and in Java modifications to mutable state are done via side effects, rather than argument passing.)

The handling of multiple output arguments is as follows.

If the Mercury procedure is deterministic and has no output arguments, then the return type of the Java function is void; if it has one output argument, then the return value of the function is that output argument.

If the Mercury procedure is deterministic and has two or more output arguments, then the return type of the Java function is void. At the position of each output argument, the Java function takes a value of the type ‘jmercury.runtime.Ref<T>’ where ‘T’ is the Java type corresponding to the type of the output argument. ‘Ref’ is a class with a single field ‘val’, which is assigned the output value when the function returns.

If the Mercury procedure is semi-deterministic, then the Java function returns a ‘boolean’. A ‘true’ return value denotes success and ‘false’ denotes failure. Output arguments are handled in the same way as multiple outputs for deterministic procedures, using the ‘Ref’ class. On failure the values of the ‘val’ fields are undefined.

Mercury lists can be manipulated by Java code using the following methods, which are defined by the Mercury implementation.

boolean   list.is_empty(List_1<E> list)     // test if a list is empty
E         list.det_head(List_1<E> list)     // get the head of a list
List_1<E> list.det_tail(List_1<E> list)     // get the tail of a list
List_1<E> list.empty_list()                 // create an empty list
<E, F extends E> List_1<E> list.cons(F head, List_1<E> tail)
                                            // construct a list with
                                            // the given head and tail

Previous: C# data passing conventions, Up: Data passing conventions   [Contents]