diff options
-rw-r--r-- | libjava/ChangeLog | 12 | ||||
-rw-r--r-- | libjava/include/jvm.h | 3 | ||||
-rw-r--r-- | libjava/java/lang/natClassLoader.cc | 29 | ||||
-rw-r--r-- | libjava/java/lang/natVMClassLoader.cc | 1 | ||||
-rw-r--r-- | libjava/java/lang/reflect/natMethod.cc | 43 | ||||
-rw-r--r-- | libjava/jni.cc | 5 | ||||
-rw-r--r-- | libjava/link.cc | 9 | ||||
-rw-r--r-- | libjava/prims.cc | 79 | ||||
-rw-r--r-- | libjava/verify.cc | 7 |
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); |