[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