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 trunk / gnu-classpath] String.format(...) undefined


On 02 Mar 2007 14:54:10 -0700
Tom Tromey <tromey@redhat.com> wrote:

> >>>>> "Hanno" == Hanno Meyer-Thurow <h.mth@web.de> writes:
> 
> Hanno> I have no idea how to get that. Are there any Java debugging
> Hanno> docs somewhere?
> 
> http://gcc.gnu.org/wiki/Debugging_tips_for_libgcj

Thanks for the link!

Anyway, I got a raw evil hack that works halfway. I bet this is the wrong
way to solve but fixes at least arraymethods in annotation of type Class
and String. The primitive type arraymethods get correct Signature but
elements are not written to the array like they should.

What should be?

Annotation arraymethods can be of type Class, String and primitive type.

What is right now?

Annotation arraymethods are always of type Object that fails with
isInstance method check. The primitive type array elements are stored
as their Java Object counterpart.

What does this evil hack do?

It tells _Jv_NewObjectArray what kind of array it should create.
Then, it checks what kind of elements are within and stores
that type of elements in the array.

What is wrong with this hack?

For example

	b_arr[i] = ((Byte*)(parseAnnotationElement(klass, pool, bytes, last)))->byteValue();

parseAnnotationElement returns the correct Object/value but then
somehow the information is mixed up and ->byteValue() returns '0'.

Though, double type elements are stored correctly in their double array.
And long type elements throw an Exception:

Exception in thread "main" java.lang.InternalError: expected pool constant 6 but got 5
   at java.lang.Class.getDeclaredAnnotations(Class.java:1359)
   at java.lang.Class.getAnnotations(Class.java:1276)
   at java.lang.Class.getAnnotation(Class.java:1255)
   at Test.main(Test.java:57)


Some testresults with Sun JDK 1.6.0 and GIJ:

$ /opt/sun-jdk-1.6.0/bin/java Test
4
7
2
c
a
c
4
7
2
true
false
true
4
7
2
4.000005
7.1234
2.9
4.0
7.0
2.0

$ /usr/lib/gcj/bin/gij Test
0
0
0


c
0
0
4
false
false
false
0
4
7
4.000005
7.1234
2.9
0.0
4.0
7.0
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Test.Array01({4, 7, 2})
@Test.Array02({'c', 'a', 'c'})
@Test.Array03({4, 7, 2})
@Test.Array04({true, false, true})
@Test.Array05({4, 7, 2})
@Test.Array06({4.000005, 7.1234, 2.9})
@Test.Array07({4, 7, 2})
//@Test.Array08({4674, 73657, 24585})
public class Test {
	@Retention(RetentionPolicy.RUNTIME)
	@Target(ElementType.TYPE)
	public @interface Array01 {
		public byte[] value();
	}
	@Retention(RetentionPolicy.RUNTIME)
	@Target(ElementType.TYPE)
	public @interface Array02 {
		public char[] value();
	}
	@Retention(RetentionPolicy.RUNTIME)
	@Target(ElementType.TYPE)
	public @interface Array03 {
		public short[] value();
	}
	@Retention(RetentionPolicy.RUNTIME)
	@Target(ElementType.TYPE)
	public @interface Array04 {
		public boolean[] value();
	}
	@Retention(RetentionPolicy.RUNTIME)
	@Target(ElementType.TYPE)
	public @interface Array05 {
		public int[] value();
	}
	@Retention(RetentionPolicy.RUNTIME)
	@Target(ElementType.TYPE)
	public @interface Array06 {
		public double[] value();
	}
	@Retention(RetentionPolicy.RUNTIME)
	@Target(ElementType.TYPE)
	public @interface Array07 {
		public float[] value();
	}
/*	@Retention(RetentionPolicy.RUNTIME)
	@Target(ElementType.TYPE)
	public @interface Array08 {
		public long[] value();
	}
*/
	public static void main(String[] args) {
		Array01 a1 = (Test.class).getAnnotation(Array01.class);
		for ( byte c : a1.value() )
			System.out.println(c);
		Array02 a2 = (Test.class).getAnnotation(Array02.class);
		for ( char c : a2.value() )
			System.out.println(c);
		Array03 a3 = (Test.class).getAnnotation(Array03.class);
		for ( short c : a3.value() )
			System.out.println(c);
		Array04 a4 = (Test.class).getAnnotation(Array04.class);
		for ( boolean c : a4.value() )
			System.out.println(c);
		Array05 a5 = (Test.class).getAnnotation(Array05.class);
		for ( int c : a5.value() )
			System.out.println(c);
		Array06 a6 = (Test.class).getAnnotation(Array06.class);
		for ( double c : a6.value() )
			System.out.println(c);
		Array07 a7 = (Test.class).getAnnotation(Array07.class);
		for ( float c : a7.value() )
			System.out.println(c);
/*		Array08 a8 = (Test.class).getAnnotation(Array08.class);
		for ( long c : a8.value() )
			System.out.println(c);
*/	}
}
--- libjava/java/lang/natClass.cc.orig	2007-02-28 12:39:01.000000000 +0100
+++ libjava/java/lang/natClass.cc	2007-03-01 13:47:07.000000000 +0100
@@ -1204,11 +1204,79 @@
     case '[':
       {
 	int n_array_elts = read_u2 (bytes, last);
+	jclass anno_class;
+	switch (*bytes)
+	  {
+	  case 's': anno_class = &String::class$; break;
+	  case 'c': anno_class = &Class::class$; break;
+	  default:  anno_class = _Jv_FindClassFromSignature((char*)bytes,
+					klass->getClassLoaderInternal());
+	  }
 	jobjectArray aresult = _Jv_NewObjectArray (n_array_elts,
-						   &Object::class$, NULL);
+						   anno_class, NULL);
+	switch (*bytes)
+	  {
+	  case 'B':
+	    {
+	jbyte *b_arr = (jbyte*) elements (aresult);
+	for (int i = 0; i < n_array_elts; ++i)
+	  b_arr[i] = ((Byte*)(parseAnnotationElement(klass, pool, bytes, last)))->byteValue();
+	break;
+	    }
+	  case 'C':
+	    {
+	jchar *c_arr = (jchar*) elements (aresult);
+	for (int i = 0; i < n_array_elts; ++i)
+	  c_arr[i] = ((Character*)(parseAnnotationElement(klass, pool, bytes, last)))->charValue();
+	break;
+	    }
+	  case 'S':
+	    {
+	jshort *s_arr = (jshort*) elements (aresult);
+	for (int i = 0; i < n_array_elts; ++i)
+	  s_arr[i] = ((Short*)(parseAnnotationElement(klass, pool, bytes, last)))->shortValue();
+	break;
+	    }
+	  case 'Z':
+	    {
+	jboolean *z_arr = (jboolean*) elements (aresult);
+	for (int i = 0; i < n_array_elts; ++i)
+	  z_arr[i] = ((Boolean*)(parseAnnotationElement(klass, pool, bytes, last)))->booleanValue();
+	break;
+	    }
+	  case 'I':
+	    {
+	jint *i_arr = (jint*) elements (aresult);
+	for (int i = 0; i < n_array_elts; ++i)
+	  i_arr[i] = ((Integer*)(parseAnnotationElement(klass, pool, bytes, last)))->intValue();
+	break;
+	    }
+	  case 'D':
+	    {
+	jdouble *d_arr = (jdouble*) elements (aresult);
+	for (int i = 0; i < n_array_elts; ++i)
+	  d_arr[i] = ((Double*)(parseAnnotationElement(klass, pool, bytes, last)))->doubleValue();
+	break;
+	    }
+	  case 'F':
+	    {
+	jfloat *f_arr = (jfloat*) elements (aresult);
+	for (int i = 0; i < n_array_elts; ++i)
+	  f_arr[i] = ((Float*)(parseAnnotationElement(klass, pool, bytes, last)))->floatValue();
+	break;
+	    }
+	  case 'J':
+	    {
+	long *j_arr = (long*) elements (aresult);
+	for (int i = 0; i < n_array_elts; ++i)
+	  j_arr[i] = ((Long*)(parseAnnotationElement(klass, pool, bytes, last)))->longValue();
+	break;
+	    }
+	  default:
 	jobject *elts = elements (aresult);
 	for (int i = 0; i < n_array_elts; ++i)
 	  elts[i] = parseAnnotationElement(klass, pool, bytes, last);
+	  }
 	result = aresult;
       }
       break;

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