This is the mail archive of the kawa@sourceware.org mailing list for the Kawa project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
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.
I have an attempted solution now. After compiling each child LambdaExp, we search its superclass hierarchy for a method with the same name and parameter types. If we find one, and its return type is less specific than the return type of the LambdaExp we just compiled, then add a bridge method.
(define-simple-class A () ((get) ::A #!null)) (define-simple-class B (A) ((get) ::B #!null))
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.
-- Jamison Hope The PTR Group www.theptrgroup.com
Attachment:
bridge2.patch
Description: Binary data
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |