This is the mail archive of the java-patches@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]

Patch: FYI: clean up _Jv_FindClassFromSignature


I'm checking this in on the trunk.

This cleans up _Jv_FindClassFromSignature and its callers.  It no
longer recurses, and now it can be used from the method signature
parsing code.  All its callers now handle a NULL return properly.

Tom

Index: ChangeLog
from  Tom Tromey  <tromey@redhat.com>
	* jni.cc (_Jv_JNI_GetAnyFieldID): Throw ClassNotFoundException.
	* java/lang/reflect/natMethod.cc (_Jv_GetTypesFromSignature):
	Rewrote to use _Jv_FindClassFromSignature.
	* verify.cc (resolve): throw NoClassDefFoundError.
	* link.cc (resolve_field): Throw NoClassDefFoundError.
	(find_field): Likewise.
	* prims.cc (_Jv_FindClassFromSignature): Removed recursion.
	Handle error cases.  Added 'endp' argument.
	* include/jvm.h (_Jv_FindClassFromSignature): Updated prototype.

Index: jni.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/jni.cc,v
retrieving revision 1.95
diff -u -r1.95 jni.cc
--- jni.cc 23 Feb 2005 17:36:23 -0000 1.95
+++ jni.cc 5 Apr 2005 22:23:46 -0000
@@ -46,6 +46,7 @@
 #include <java/nio/DirectByteBufferImpl$ReadWrite.h>
 #include <java/util/IdentityHashMap.h>
 #include <gnu/gcj/RawData.h>
+#include <java/lang/ClassNotFoundException.h>
 
 #include <gcj/method.h>
 #include <gcj/field.h>
@@ -1200,8 +1201,8 @@
       for (int i = 0; i <= len; ++i)
 	s[i] = (sig[i] == '/') ? '.' : sig[i];
       jclass field_class = _Jv_FindClassFromSignature ((char *) s, NULL);
-
-      // FIXME: what if field_class == NULL?
+      if (! field_class)
+	throw new java::lang::ClassNotFoundException(JvNewStringUTF(s));
 
       java::lang::ClassLoader *loader = clazz->getClassLoaderInternal ();
       while (clazz != NULL)
Index: link.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/link.cc,v
retrieving revision 1.12
diff -u -r1.12 link.cc
--- link.cc 17 Mar 2005 00:18:45 -0000 1.12
+++ link.cc 5 Apr 2005 22:23:46 -0000
@@ -90,8 +90,11 @@
 {
   if (! field->isResolved ())
     {
-      _Jv_Utf8Const *sig = (_Jv_Utf8Const*)field->type;
-      field->type = _Jv_FindClassFromSignature (sig->chars(), loader);
+      _Jv_Utf8Const *sig = (_Jv_Utf8Const *) field->type;
+      jclass type = _Jv_FindClassFromSignature (sig->chars(), loader);
+      if (type == NULL)
+	throw new java::lang::NoClassDefFoundError(field->name->toString());
+      field->type = type;
       field->flags &= ~_Jv_FIELD_UNRESOLVED_FLAG;
     }
 }
@@ -174,6 +177,8 @@
   // it cheaper.
   jclass field_type = _Jv_FindClassFromSignature (field_type_name->chars(),
 						  klass->loader);
+  if (field_type == NULL)
+    throw new java::lang::NoClassDefFoundError(field_name->toString());
 
   jclass found_class = 0;
   _Jv_Field *the_field = find_field_helper (owner, field_name,
Index: prims.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/prims.cc,v
retrieving revision 1.108
diff -u -r1.108 prims.cc
--- prims.cc 2 Apr 2005 02:26:50 -0000 1.108
+++ prims.cc 5 Apr 2005 22:23:47 -0000
@@ -675,46 +675,79 @@
 }
 
 jclass
-_Jv_FindClassFromSignature (char *sig, java::lang::ClassLoader *loader)
+_Jv_FindClassFromSignature (char *sig, java::lang::ClassLoader *loader,
+			    char **endp)
 {
+  // First count arrays.
+  int array_count = 0;
+  while (*sig == '[')
+    {
+      ++sig;
+      ++array_count;
+    }
+
+  jclass result = NULL;
   switch (*sig)
     {
     case 'B':
-      return JvPrimClass (byte);
+      result = JvPrimClass (byte);
+      break;
     case 'S':
-      return JvPrimClass (short);
+      result = JvPrimClass (short);
+      break;
     case 'I':
-      return JvPrimClass (int);
+      result = JvPrimClass (int);
+      break;
     case 'J':
-      return JvPrimClass (long);
+      result = JvPrimClass (long);
+      break;
     case 'Z':
-      return JvPrimClass (boolean);
+      result = JvPrimClass (boolean);
+      break;
     case 'C':
-      return JvPrimClass (char);
+      result = JvPrimClass (char);
+      break;
     case 'F':
-      return JvPrimClass (float);
+      result = JvPrimClass (float);
+      break;
     case 'D':
-      return JvPrimClass (double);
+      result = JvPrimClass (double);
+      break;
     case 'V':
-      return JvPrimClass (void);
+      result = JvPrimClass (void);
+      break;
     case 'L':
       {
-	int i;
-	for (i = 1; sig[i] && sig[i] != ';'; ++i)
-	  ;
-	_Jv_Utf8Const *name = _Jv_makeUtf8Const (&sig[1], i - 1);
-	return _Jv_FindClass (name, loader);
-      }
-    case '[':
-      {
-	jclass klass = _Jv_FindClassFromSignature (&sig[1], loader);
-	if (! klass)
-	  return NULL;
-	return _Jv_GetArrayClass (klass, loader);
+	char *save = ++sig;
+	while (*sig && *sig != ';')
+	  ++sig;
+	// Do nothing if signature appears to be malformed.
+	if (*sig == ';')
+	  {
+	    _Jv_Utf8Const *name = _Jv_makeUtf8Const (save, sig - save);
+	    result = _Jv_FindClass (name, loader);
+	  }
+	break;
       }
+    default:
+      // Do nothing -- bad signature.
+      break;
     }
 
-  return NULL;			// Placate compiler.
+  if (endp)
+    {
+      // Not really the "end", but the last valid character that we
+      // looked at.
+      *endp = sig;
+    }
+
+  if (! result)
+    return NULL;
+
+  // Find arrays.
+  while (array_count-- > 0)
+    result = _Jv_GetArrayClass (result, loader);
+  return result;
 }
 
 
Index: verify.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/verify.cc,v
retrieving revision 1.68
diff -u -r1.68 verify.cc
--- verify.cc 22 Feb 2005 18:14:04 -0000 1.68
+++ verify.cc 5 Apr 2005 22:23:48 -0000
@@ -31,6 +31,7 @@
 #include <java/lang/Throwable.h>
 #include <java/lang/reflect/Modifier.h>
 #include <java/lang/StringBuffer.h>
+#include <java/lang/NoClassDefFoundError.h>
 
 #ifdef VERIFY_DEBUG
 #include <stdio.h>
@@ -368,7 +369,11 @@
 	= verifier->current_class->getClassLoaderInternal();
       // We might see either kind of name.  Sigh.
       if (data.name->first() == 'L' && data.name->limit()[-1] == ';')
-	data.klass = _Jv_FindClassFromSignature (data.name->chars(), loader);
+	{
+	  data.klass = _Jv_FindClassFromSignature (data.name->chars(), loader);
+	  if (data.klass == NULL)
+	    throw new java::lang::NoClassDefFoundError(data.name->toString());
+	}
       else
 	data.klass = Class::forName (_Jv_NewStringUtf8Const (data.name),
 				     false, loader);
Index: include/jvm.h
===================================================================
RCS file: /cvs/gcc/gcc/libjava/include/jvm.h,v
retrieving revision 1.82
diff -u -r1.82 jvm.h
--- include/jvm.h 2 Apr 2005 02:26:51 -0000 1.82
+++ include/jvm.h 5 Apr 2005 22:23:48 -0000
@@ -448,7 +448,8 @@
 extern jclass _Jv_FindClass (_Jv_Utf8Const *name,
 			     java::lang::ClassLoader *loader);
 extern jclass _Jv_FindClassFromSignature (char *,
-					  java::lang::ClassLoader *loader);
+					  java::lang::ClassLoader *loader,
+					  char ** = NULL);
 extern void _Jv_GetTypesFromSignature (jmethodID method,
 				       jclass declaringClass,
 				       JArray<jclass> **arg_types_out,
Index: java/lang/natClassLoader.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/natClassLoader.cc,v
retrieving revision 1.79
diff -u -r1.79 natClassLoader.cc
--- java/lang/natClassLoader.cc 1 Apr 2005 19:19:13 -0000 1.79
+++ java/lang/natClassLoader.cc 5 Apr 2005 22:23:49 -0000
@@ -252,27 +252,30 @@
 	  // Not even a bootstrap loader, try the built-in cache.
 	  klass = _Jv_FindClassInCache (name);
 
-	  bool found = false;
-	  for (int i = 0; i < bootstrap_index; ++i)
+	  if (klass)
 	    {
-	      if (bootstrap_class_list[i] == klass)
+	      bool found = false;
+	      for (int i = 0; i < bootstrap_index; ++i)
 		{
-		  found = true;
-		  break;
+		  if (bootstrap_class_list[i] == klass)
+		    {
+		      found = true;
+		      break;
+		    }
+		}
+	      if (! found)
+		{
+		  if (bootstrap_index == BOOTSTRAP_CLASS_LIST_SIZE)
+		    abort ();
+		  bootstrap_class_list[bootstrap_index++] = klass;
 		}
-	    }
-	  if (! found)
-	    {
-	      if (bootstrap_index == BOOTSTRAP_CLASS_LIST_SIZE)
-		abort ();
-	      bootstrap_class_list[bootstrap_index++] = klass;
 	    }
 	}
     }
   else
     {
-      // we need classes to be in the hash while
-      // we're loading, so that they can refer to themselves. 
+      // We need classes to be in the hash while we're loading, so
+      // that they can refer to themselves.
       _Jv_Linker::wait_for_state (klass, JV_STATE_LOADED);
     }
 
Index: java/lang/natVMClassLoader.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/natVMClassLoader.cc,v
retrieving revision 1.9
diff -u -r1.9 natVMClassLoader.cc
--- java/lang/natVMClassLoader.cc 1 Apr 2005 19:19:13 -0000 1.9
+++ java/lang/natVMClassLoader.cc 5 Apr 2005 22:23:49 -0000
@@ -123,6 +123,7 @@
   char sig[2];
   sig[0] = (char) type;
   sig[1] = '\0';
+  // Note: this cannot return NULL, since the input is always correct.
   return _Jv_FindClassFromSignature (sig, NULL);
 }
 
Index: java/lang/reflect/natMethod.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/reflect/natMethod.cc,v
retrieving revision 1.45
diff -u -r1.45 natMethod.cc
--- java/lang/reflect/natMethod.cc 10 Mar 2005 19:02:20 -0000 1.45
+++ java/lang/reflect/natMethod.cc 5 Apr 2005 22:23:49 -0000
@@ -38,6 +38,7 @@
 #include <java/lang/Class.h>
 #include <gcj/method.h>
 #include <gnu/gcj/RawData.h>
+#include <java/lang/NoClassDefFoundError.h>
 
 #include <stdlib.h>
 
@@ -235,6 +236,8 @@
   char *ptr = sig->chars();
   int numArgs = 0;
   /* First just count the number of parameters. */
+  // FIXME: should do some validation here, e.g., that there is only
+  // one return type.
   for (; ; ptr++)
     {
       switch (*ptr)
@@ -271,44 +274,26 @@
   jclass* argPtr = elements (args);
   for (ptr = sig->chars(); *ptr != '\0'; ptr++)
     {
-      int num_arrays = 0;
-      jclass type;
-      for (; *ptr == '[';  ptr++)
-	num_arrays++;
-      switch (*ptr)
+      if (*ptr == '(')
+	continue;
+      if (*ptr == ')')
 	{
-	default:
-	  return;
-	case ')':
 	  argPtr = return_type_out;
 	  continue;
-	case '(':
-	  continue;
-	case 'V':
-	case 'B':
-	case 'C':
-	case 'D':
-	case 'F':
-	case 'S':
-	case 'I':
-	case 'J':
-	case 'Z':
-	  type = _Jv_FindClassFromSignature(ptr, loader);
-	  break;
-	case 'L':
-	  type = _Jv_FindClassFromSignature(ptr, loader);
-	  do 
-	    ptr++;
-	  while (*ptr != ';' && ptr[1] != '\0');
-	  break;
 	}
 
-      while (--num_arrays >= 0)
-	type = _Jv_GetArrayClass (type, loader);
+      char *end_ptr;
+      jclass type = _Jv_FindClassFromSignature (ptr, loader, &end_ptr);
+      if (type == NULL)
+	// FIXME: This isn't ideal.
+	throw new java::lang::NoClassDefFoundError (sig->toString());
+
       // ARGPTR can be NULL if we are processing the return value of a
       // call from Constructor.
       if (argPtr)
 	*argPtr++ = type;
+
+      ptr = end_ptr;
     }
   *arg_types_out = args;
 }


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