[m-dev.] Re: Signature of generated JAVA methods
Holger Krug
hkrug at rationalizer.com
Wed Feb 20 00:35:17 AEDT 2002
On Tue, Feb 19, 2002 at 11:52:40PM +1100, Fergus Henderson wrote:
> On 19-Feb-2002, Holger Krug <hkrug at rationalizer.com> wrote:
> > Following your last review messages I've got the impression, that the
> > Java port of Mercury now is really in the main focus. That is fine !
>
> Well, our summer student Michael Wybrow, who has been working on the
> Java port, is finishing up next week. So this trend might not continue.
Michael, could he put some summary of your work on the mailing list,
when you leave ? Would be nice !
> > Andre just now showed me his first generated Java code. As I
> > understand his work up to now he achieved to remove all the hindrances
> > from the Mercury compiler which "protect" the user from generated Java
> > code. Having taken a look at the Java code and after discussion with
> > Andre I have some questions concerning the signature of generated
> > Java code.
> >
> > As I understand, Andre has to generate Code for `det' and `semidet'
> > procedures, because the other determinisms will be transformed away by
> > a HLDS transformation.
>
> For `pragma foreign_proc', yes, that's correct.
That is our current focus.
> > Andre proposed the following signatures for genereted Java procedures:
>
> Do you mean these signatures should be used for Java procedures imported
> to Mercury or exported from Mercury with the Java interface equivalents of
> `pragma import' and `pragma export'?
I spoke about the code generated from `pragma foreign_proc'.
> > A) det/semidet: Object[] name(InType1 in1, .... , InTypen inn);
> > In the `semidet' case the array of Objects forming the return
> > value gets one additional output parameter of boolean type.
>
> This matches the calling convention used by the Java code
> that the current Mercury compiler generates.
>
> Note that it's not strictly necessary that the generated code and
> the foreign language interface use the same interface, since `pragma import'
> and `pragma export' are implemented using forwarding procedures anyway.
> Indeed, for the MLDS->C back-end and C interface, they don't, e.g. the
> MLDS->C back-end uses "MR_Box" in some places where the C interface uses
> "MR_Word" (this is mainly for backwards compatibility reasons).
>
> But it would certainly be *nicer* if the convention used by the
> foreign interface matched that used by the generated code.
>
> > My first proposal after Andre's presentation was:
> >
> > B) det/semidet: Object[] name(InType1 in1, .... , InTypen inn);
> > For the `semidet' determinism failure is indicated by returning `null'.
> > (Whereas an empty number of output parameters is indicated by
> > returning an empty array.)
>
> This is a good idea. It is both more efficient and more natural
> (for Java programmers) than `A'.
>
> Unfortunately it is hard to make this work nicely given the current design
> of the MLDS back-end, where we map HLDS->MLDS->Java, rather than going
> directly from HLDS->Java. The trouble is that the information about
> determinism is lost when converting HLDS->MLDS, but the conversion from
> multiple outputs to an array happens when converting from MLDS->Java.
I do not understand this fully. Do you speak about generating a) the
method definition or b) the method call in Java ?
I suppose b), because for a) there should be no problem at all. Do you
mean that there is some general MLDS->somelang code, which assume a
certain from of the return value ?
If you meant a), so I cannot understand, why the MLDS->Java conversion
must know about the determinism. It should simply wrap the code
provided by the user. The user calls `return null;' whenever she wants
to indicate failure.
> > Following the approach taken in (A) and (B) I think the generated code
> > should contain the construction of the array of output parameters on
> > the users behalf, using a fixed name (e.g. `ret'). Andre told me,
> > that he ask you already about the name of this array, so this seems to
> > be on track. As a consequence of this, I deem, Andre should generate
> > a `return ret;' statement at the end of the method body.
> > Better than having a fixed name of the array of output parameters
> > would be the use of the same names as in the Mercury signature of the
> > foreign proc not only for input parameters but also for output
> > parameters.
>
> In a `pragma foreign_proc', the user's code should definitely refer
> to the output variables by name, not as `ret[N]'.
> Here's an example:
>
> :- pred foo(int, float, int).
> :- pragma foreign_proc(java, foo(X::in, Y::out, Z::out), "
> /* this is the user's java code */
> Y = X * 1.23;
> Z = X + 42;
> ").
>
> For this example, the Mercury compiler should either generate something
> like this:
>
> static object[] foo_1(int HeadVar__1) {
> double HeadVar__2;
> int HeadVar__3;
>
> {
> int X;
> double Y;
> int Z;
>
> X = HeadVar__1;
>
> /* this is the user's java code */
> Y = X * 1.23;
> Z = X + 42;
>
> HeadVar__2 = Y;
> HeadVar__3 = Z;
> }
>
> return new object[] { new java.lang.Double(HeadVar__2),
> new java.lang.Integer(HeadVar__3) };
> }
>
> or like this:
>
> static object[] foo_1(int HeadVar__1) {
> double HeadVar__2;
> int HeadVar__3;
> object[] ret;
>
> {
> int X;
> double Y;
> int Z;
>
> X = HeadVar__1;
>
> /* this is the user's java code */
> Y = X * 1.23;
> Z = X + 42;
>
> HeadVar__2 = Y;
> HeadVar__3 = Z;
> }
>
> ret = new object[2];
> ret[0] = new java.lang.Double(HeadVar__1);
> ret[1] = new java.lang.Integer(HeadVar__2);
> return ret;
> }
OK, I see.
> But note that only the nested block
> is generated from the `pragma foreign_proc' HLDS goal
> (which becomes the `inline_target_code' MLDS statement).
> The function declaration, the local variable declarations
> at the top of the function body, and the return statement(s)
> at the end will be generated from other parts of the HLDS/MLDS
> by already-existing parts of the Mercury->MLDS->Java back-end.
Seems not to be the case, but it's now a simple work for Andre.
> > 4) What thoughts exist concerning debugging Java code ? Unfortunately the
> > approach taken for C code (indicate the line numbers of the originial
> > code to the preprocessor) does not work for Java.
>
> Is there no equivalent to #line in Java?
I would be very surprised.
> If so, for the short term I'd say just debug the generated Java code.
Hence we should add the line number of the mercury could as comments:
> :- pred foo(int, float, int).
> :- pragma foreign_proc(java, foo(X::in, Y::out, Z::out), "
> /* this is the user's java code */
> Y = X * 1.23;
> Z = X + 42;
> ").
int X;
double Y;
int Z;
X = HeadVar__1;
/* start foreign proc at users_mercury.m:10452 */
/* this is the user's java code */
Y = X * 1.23;
Z = X + 42;
/* end foreign proc at users_mercury.m:10456 */
HeadVar__2 = Y;
HeadVar__3 = Z;
--
Holger Krug
hkrug at rationalizer.com
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to: mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions: mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------
More information about the developers
mailing list