This is the mail archive of the java@gcc.gnu.org mailing list for the Java 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]

Re: GCJ and generics


Cedric Berger wrote:
> Alan Eliasen wrote:
> 
>>   Unfortunately, the compiler gets partway through (with lots of
>> warnings) and then gives the following errors like:
>>
>> c:\DOCUME~1\eliasen\LOCALS~1\Temp/ccusaaaa.s: Assembler messages:
>> c:\DOCUME~1\eliasen\LOCALS~1\Temp/ccusaaaa.s:4439: Error: symbol
>> `__ZN5frink5units22BasicObjectEnumeration11nextElementEv' is already
>> defined
>>  
> I think generics define multiple functions with the same arguments
> but different return values. Could that be the problem?

   Hmmmm... yes, in a way, that's right.  However, for example, in one
case I listed,

public class BasicObjectEnumeration<T>
	implements java.util.Enumeration<String>

which has a method, written as:

 public String nextElement()

   Thus, BasicObjectEnumeration's nextElement method should always
return a String, yet gcj complains about it.  Hmmm...let's see what's
happening.

   Running javap shows that the following two methods are declared in
the .class file:

public java.lang.String nextElement();
  Signature: ()Ljava/lang/String;

public java.lang.Object nextElement();
  Signature: ()Ljava/lang/Object;

  Decompilation shows that one of these methods is just a bridge that
delegates to the other:

public java.lang.Object nextElement();
  Signature: ()Ljava/lang/Object;
  Code:
   0:   aload_0
   1:   invokevirtual   #15; //Method nextElement:()Ljava/lang/String;
   4:   areturn

   The version that returns String has all the code.

   The Java spec (section 8.4.2) indicates that:

   "The signature of a method consists of the name of the method and the
number and types of formal parameters to the method. A class may not
declare two methods with the same signature, or a compile-time error
occurs."

   Forgive my ignorance, but it also seems that the bytecode indicates
that the return type *is* specified in some way as part of the signature
in the bytecode.  From my initial understanding of the spec, I didn't
think that the return type was part of the signature, but it's there in
the decompilation.  It seems that it would be necessary for the return
type to be stored *somehow* for type verification to work.

   At first look, it seems like the new generics compilers may violate
the spec, but it can be interpreted to mean only at compile-time, or
that the return type can be considered in some way to be part of the
signature.  Generic compilers rely entirely on this behavior to work,
and the bytecode doesn't seem to cause problems with any JVM.

   As I understand the type erasure that's going on in generics, (which
I verified by doing a decompilation of several files,) the function

public java.lang.Object nextElement()

   is always the one that gets called from other classes.  The caller
just wraps the return value with an explicit cast (a checkcast bytecode
immediately follows *in the caller*) to String.  (The cast is inserted
by the generics compiler, not the programmer.)  The generic compiler
provides a guarantee that a cast inserted by the compiler will not fail.

   If this is the case, and this type of thing may exist in bytecode,
especially when the generic compiler comes out in full force with Java
1.5, should this be handled differently than it is now?  Should this
bytecode be handled by gcj?  Should the return code be made part of the
"mangled" signature in gcj so the ambiguity can be resolved?

-- 
  Alan Eliasen                 | "You cannot reason a person out of a
  eliasen@mindspring.com       |  position he did not reason himself
  http://futureboy.homeip.net/ |  into in the first place."
                               |     --Jonathan Swift


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]