Parameterizing on incomplete types
Per Bothner
per@bothner.com
Sat Dec 3 21:03:00 GMT 2011
On 12/03/2011 10:59 AM, Jamison Hope wrote:
> OK, here's what I've got so far. It appears to handle our Comparable
> test case
>
> (define-simple-class Foo (java.lang.Comparable[Foo])
> (x ::int)
> ((compare-to (o ::Foo)) ::int
> (- x o:x)))
>
> generating a bridge method equivalent to
>
> public int compareTo(java.lang.Object o)
> {
> return this.compareTo((Foo) o);
> }
That's a pretty good start. Thanks!
> The patch consists of two parts: the new
> Compilation#generateBridgeMethod(),
> and a few lines added to ClassExp#compileMembers.
I would prefer to keep generateBridgeMethod in ClassExp,
even if it has to be a static method with an explicit Compilation
method: It's only called from one class, and there is too much stuff
in Compilation.java anyway.
> generateBridgeMethod takes an existing method and desired arg/return types,
> creates a new method with the desired signature and emits bytecode to
> checkcast
> its args and then call the existing method. In my limited testing so
> far, this
> is the same bytecode generated by javac for similar cases.
>
> The addition to ClassExp sits after the call to getImplMethods() where
> the current
> "missing implementation" error is. Before triggering that error, we look
> to see
> if the problem was 0 implementations found (as opposed to multiple,
> which is a
> different problem), and if so, we look to see if there's a method with
> the right
> name and number of args but wrong signature. If there is such a method,
> then
> we check its arg types and return type to see if they're compatible with
> the
> required signature, and if so we generate the bridge method. If not,
> then we still
> do the error message.
One problem is this doesn't handle multiple overloaded methods with the
same number of parameters. You might have to iterate over the list
returned from getDeclaredMethods() and check each if it's bridgeable.
(At the least add a comment about the limitation.)
There is also the case of an abstract class that implements an
instantiated method. Should we generate the bridge method in the
abstract class, or only when we get to a concrete class? Ideally,
I think the former. (I'm guessing javac does that, but I haven't
verified it.) But this is fine-tuning.
Ideally, one would go carefully through the Java Language Specification
to better understand the issues. That is probably best done if/when
we add wildcard support, definition of generic types, and sotherwise
start approaching "completeness" (i.e. Java parity). We quite a ways
from that. (I would like a mechanism where generic instantiation can
inherit or default a wildcard from the type declaration, as in Scala.)
> I'm not handling covariant returns yet, because I'm not sure where/how
> to check
> for those. We could use the same generateBridgeMethod there, but in that
> case the
> checkcast instructions aren't needed. I suppose I should put the
> emitCheckcast
> inside of something like "if
> (bridge_arg_types[i].compare(src_arg_types[i]) != 0)".
That's handled automatically by the castNeeded in emitCheckCast.
--
--Per Bothner
per@bothner.com http://per.bothner.com/
More information about the Kawa
mailing list