Re: [Java] Function binding

John Moeller <[email protected]>
Newsgroups gmane.comp.lib.boost.langbinding
Message-ID <[email protected]>
David Abrahams wrote:
> on Sun Jun 24 2007, John Moeller <fishcorn-AT-gmail.com> wrote:
> 
>> I promise that there will be some questions in here, but I wanted to 
>> offer a bit of background first.
>>
>> If I understand it correctly, the means of determining conversions of 
>> function arguments from xxx functions to C++ functions is done through 
>> the registry, probably in one of two scenarios:
>>
>> 1.  If a C++ argument type is known in advance (through a bound invoker, 
>> for example), this argument type is a key in the registry to find the 
>> correct conversion for the xxx type.
>> 2.  If a C++ argument type is not known in advance (because of a need 
>> for overload resolution), each overload should be attempted on-the-fly, 
>> and as soon as an overload is found whose conversions all succeed, then 
>> those converted values are used for the invoke() method of the invoker.
> 
> I don't think 1 and 2 have anything to do with one another.  They seem
> to be on different axes.  I also don't know what you mean by "a bound
> invoker."  The process is uniform whether there is one overload or N.

By a "bound invoker," I mean a langbinding::function::invoker object 
that could be tied directly to a xxx function call.  I realized later 
that that's basically an impossibility without static converter chains.

>> I have no problems with the above method; I'd surmise that it's 
>> extremely useful (and possibly necessary) to use with a 
>> dynamically-typed language.  However, for a statically-typed and 
>> statically-declared language like Java, it doesn't really work.
> 
> Hm?
> 
>> The problem is that there needs to be a function 
> 
> Java or C++ function?
> 
>> for the Java class to link to.
> 
> How did classes come into it?  I know everything in Java is a class,
> but still...
> 
> What do you mean by "link?"

The normal way of implementing native bindings with JNI is to expose a 
function from your native library that has a signature that corresponds 
to the signature of the Java native method being bound.

This is an impossibility (rather, impractical to the point of 
impossibility) without compile-time conversion, but as you point out 
below, Rene has a novel solution to this problem.  Shunting everything 
through an interface that passes packaged function calls eliminates the 
need for compile-time function generation.

>> Since there isn't a way to generate a function dynamically (other
>> than to have a forwarding function with every possible argument
>> combination defined ahead of time; while possible up to a max arity,
>> it isn't feasible), that means that there needs to be a static
>> (i.e., compile-time) way of creating a forwarding function that the
>> Java class may link to.
> 
> If necessary, You can use the same backend interface that will be used
> by the dynamic languages to generate C++ code that will be compiled in
> a separate phase.  However it sounds like Rene has a slicker option.
> I guess if Rene's approach is too slow, both options can be made
> available.

That's an approach I thought of as well, but I was hoping to avoid it. 
I like Rene's approach better; though it could have some overhead.  What 
I worry about is the "unboxing" of primitive arguments (int, double, 
etc.).  It's generally an unnoticable overhead (if any) to call a native 
function, but it can get hefty to go in reverse.

>> (By the way: varargs won't work; I investigated this possibility,
>> and it turns out that on Windows implementations of the Sun JVM (and
>> by extension, other JVM's), JNICALL is defined to be __stdcall.
>> That means no varargs.)
>>
>> The obvious way that I thought of to handle something like this was
>> to use fusion and/or mpl to create a (compile-time) transformed
>> argument list from a set of user-defined type associations.  Much
>> like the user defines a set of dynamic conversion functions for use
>> with the invoker class, a user could define a set of metafunctions
>> that would define legal conversions at compile time.  This would
>> enable the transformed argument list to be used to generate an
>> instantiation of a function that could be linked to a Java class.
>> This lazy list could then be used to perform the actual conversions
>> at runtime.
> 
> I'm not convinced the drawbacks would be worth the advantages.  For
> one thing, it would bind the front-end at compile time to a particular
> backend language, which we're trying to get away from.  If you can
> make the front-end language-agnostic then you can properly focus
> expertise.

That makes a lot of sense.

> Also I'm pretty sure that compilation would be slow for large
> bindings.  Boost.Python already is slow for large bindings.  Using
> more type erasure will speed that up dramatically.

Yeah, I suppose it's a tradeoff.  Development cycles can get frustrating 
with long build times.

I appreciate the explanations.  That clears a lot up for me.

-- 

John Moeller
[email protected]


-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.