[foreign] RFR 8210264: cleanup semantics of function pointer conversion
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Mon Sep 3 10:04:34 UTC 2018
On 01/09/18 04:46, John Rose wrote:
> On Aug 31, 2018, at 9:04 AM, Maurizio Cimadamore
> <maurizio.cimadamore at oracle.com
> <mailto:maurizio.cimadamore at oracle.com>> wrote:
>>
>> http://cr.openjdk.java.net/~mcimadamore/panama/8210264/
>> <http://cr.openjdk.java.net/%7Emcimadamore/panama/8210264/>
>
> This is a good cleanup.
>
> An object is allowed to implement two functional interfaces, and even
> two interfaces which annotated as native callbacks. So it is possible
> that allocateCallback will be presented with an ambiguous input.
> I suggest that Util.findCallback throw an exception in that case,
> instead of returning the first marked FI that that it finds.
>
> This won't harm correct code but will let us exclude some corner
> cases.
>
> Another way to slice this is to require a runtime witness as follows:
>
> <T> Callback<T> allocateCallback(Class<T> funcInt, T funcIntfInstance);
> default <T> Callback<T> allocateCallback(T funcIntfInstance) {
> return
> allocateCallback(Utils.findCallback(funcIntfInstance.getClass()),
> funcIntfInstance);
> }
>
> I.e., allow explicit specification of which FI we care about but specify
> a sensible default. The explicit specification has two effects: First,
> it allows cast-free passing of a lambda, and second it allows the
> approach to scale to non-native FI types (assuming the scope
> has rules for dealing with type conversion).
I thought about the latter a lot. Honestly, I'd prefer an API point such
as the one you describe - e.g. with an explicit Class type witness.
That's the first iteration of the API I experimented with - and I found
one big usability hurdle with that: the need to pass in opaque
functional interface names generated by jextract. E.g. what you will be
looking at would be something like:
qsort(... scope.allocateCallback(StdLib$Func23.class, (p1, p2) -> ... ) )
While I agree this makes the API a lot tighter and avoids the need of a
dynamic lookup which I dislike, I can also imagine that users will be
pretty annoyed at having to dig an obscure functional interface name
just to make the API happy.
Now, the approach I put forward is not bullet proof in this regard: if
javac inference fails (although, after changes brought in by Java SE 8
that should be quite rare), the user will still have to dig a type
witness by hand:
scope.<StdLib$23>allocateCallback( (p1, p2) -> ... )
But this would be (i) very rare and (ii) we could mitigate a lot of the
pain by having jextract generate predictable functional interface names.
E.g. instead of Func$23, using Function_ptr_ptr would be a lot clearer
(and would allow reuse on the jextract side).
I don't think trick (ii) is enough to make a client swallow the fact of
putting in an explicit witness on any callback call - but maybe I'm
worrying too much about compactness of client code? But maybe you are
suggesting the witness-accepting 'allocateCallback' not as a
replacement, but as a complement for the version included in my patch?
Maurizio
>
> — John
More information about the panama-dev
mailing list