summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libjava/ChangeLog12
-rw-r--r--libjava/include/jvm.h3
-rw-r--r--libjava/java/lang/natClassLoader.cc29
-rw-r--r--libjava/java/lang/natVMClassLoader.cc1
-rw-r--r--libjava/java/lang/reflect/natMethod.cc43
-rw-r--r--libjava/jni.cc5
-rw-r--r--libjava/link.cc9
-rw-r--r--libjava/prims.cc79
-rw-r--r--libjava/verify.cc7
9 files changed, 117 insertions, 71 deletions
diff --git a/libjava/ChangeLog b/libjava/ChangeLog
index 52e79eba376..6411c2a9692 100644
--- a/libjava/ChangeLog
+++ b/libjava/ChangeLog
@@ -1,5 +1,17 @@
2005-04-05 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.
+
+2005-04-05 Tom Tromey <tromey@redhat.com>
+
* Makefile.in: Rebuilt.
* Makefile.am (lib_gnu_java_awt_peer_gtk_la_SOURCES): Removed
gtk_awt_peer_sources.
diff --git a/libjava/include/jvm.h b/libjava/include/jvm.h
index a95b7124aa8..bbc809bc162 100644
--- a/libjava/include/jvm.h
+++ b/libjava/include/jvm.h
@@ -448,7 +448,8 @@ extern void _Jv_UnregisterClass (_Jv_Utf8Const*, java::lang::ClassLoader*);
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,
diff --git a/libjava/java/lang/natClassLoader.cc b/libjava/java/lang/natClassLoader.cc
index 00292f93dad..b8d87c6062b 100644
--- a/libjava/java/lang/natClassLoader.cc
+++ b/libjava/java/lang/natClassLoader.cc
@@ -252,27 +252,30 @@ _Jv_FindClass (_Jv_Utf8Const *name, java::lang::ClassLoader *loader)
// 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);
}
diff --git a/libjava/java/lang/natVMClassLoader.cc b/libjava/java/lang/natVMClassLoader.cc
index e6c3b947d24..182b8d72743 100644
--- a/libjava/java/lang/natVMClassLoader.cc
+++ b/libjava/java/lang/natVMClassLoader.cc
@@ -123,6 +123,7 @@ java::lang::VMClassLoader::getPrimitiveClass (jchar type)
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);
}
diff --git a/libjava/java/lang/reflect/natMethod.cc b/libjava/java/lang/reflect/natMethod.cc
index 4329443146c..b616d1bab63 100644
--- a/libjava/java/lang/reflect/natMethod.cc
+++ b/libjava/java/lang/reflect/natMethod.cc
@@ -38,6 +38,7 @@ details. */
#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 @@ _Jv_GetTypesFromSignature (jmethodID method,
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 @@ _Jv_GetTypesFromSignature (jmethodID method,
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;
}
diff --git a/libjava/jni.cc b/libjava/jni.cc
index 5f9d5f79e71..b68c3bb887f 100644
--- a/libjava/jni.cc
+++ b/libjava/jni.cc
@@ -46,6 +46,7 @@ details. */
#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 @@ _Jv_JNI_GetAnyFieldID (JNIEnv *env, jclass clazz,
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)
diff --git a/libjava/link.cc b/libjava/link.cc
index 909a7b68a0e..176b538d64a 100644
--- a/libjava/link.cc
+++ b/libjava/link.cc
@@ -90,8 +90,11 @@ _Jv_Linker::resolve_field (_Jv_Field *field, java::lang::ClassLoader *loader)
{
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 @@ _Jv_Linker::find_field (jclass klass, jclass owner,
// 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,
diff --git a/libjava/prims.cc b/libjava/prims.cc
index 70601712238..fadc466bc0e 100644
--- a/libjava/prims.cc
+++ b/libjava/prims.cc
@@ -675,46 +675,79 @@ _Jv_InitPrimClass (jclass cl, char *cname, char sig, int len)
}
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;
}
diff --git a/libjava/verify.cc b/libjava/verify.cc
index 141f27af797..a47571bb809 100644
--- a/libjava/verify.cc
+++ b/libjava/verify.cc
@@ -31,6 +31,7 @@ details. */
#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 @@ private:
= 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);