jni.cc (_Jv_JNI_GetAnyFieldID): Throw ClassNotFoundException.

* 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.

From-SVN: r97660
This commit is contained in:
Tom Tromey 2005-04-05 22:26:26 +00:00 committed by Tom Tromey
parent 13148dd26a
commit 8b6e769053
9 changed files with 117 additions and 71 deletions

View File

@ -1,3 +1,15 @@
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> 2005-04-05 Tom Tromey <tromey@redhat.com>
* Makefile.in: Rebuilt. * Makefile.in: Rebuilt.

View File

@ -448,7 +448,8 @@ extern void _Jv_UnregisterClass (_Jv_Utf8Const*, java::lang::ClassLoader*);
extern jclass _Jv_FindClass (_Jv_Utf8Const *name, extern jclass _Jv_FindClass (_Jv_Utf8Const *name,
java::lang::ClassLoader *loader); java::lang::ClassLoader *loader);
extern jclass _Jv_FindClassFromSignature (char *, extern jclass _Jv_FindClassFromSignature (char *,
java::lang::ClassLoader *loader); java::lang::ClassLoader *loader,
char ** = NULL);
extern void _Jv_GetTypesFromSignature (jmethodID method, extern void _Jv_GetTypesFromSignature (jmethodID method,
jclass declaringClass, jclass declaringClass,
JArray<jclass> **arg_types_out, JArray<jclass> **arg_types_out,

View File

@ -252,6 +252,8 @@ _Jv_FindClass (_Jv_Utf8Const *name, java::lang::ClassLoader *loader)
// Not even a bootstrap loader, try the built-in cache. // Not even a bootstrap loader, try the built-in cache.
klass = _Jv_FindClassInCache (name); klass = _Jv_FindClassInCache (name);
if (klass)
{
bool found = false; bool found = false;
for (int i = 0; i < bootstrap_index; ++i) for (int i = 0; i < bootstrap_index; ++i)
{ {
@ -269,10 +271,11 @@ _Jv_FindClass (_Jv_Utf8Const *name, java::lang::ClassLoader *loader)
} }
} }
} }
}
else else
{ {
// we need classes to be in the hash while // We need classes to be in the hash while we're loading, so
// we're loading, so that they can refer to themselves. // that they can refer to themselves.
_Jv_Linker::wait_for_state (klass, JV_STATE_LOADED); _Jv_Linker::wait_for_state (klass, JV_STATE_LOADED);
} }

View File

@ -123,6 +123,7 @@ java::lang::VMClassLoader::getPrimitiveClass (jchar type)
char sig[2]; char sig[2];
sig[0] = (char) type; sig[0] = (char) type;
sig[1] = '\0'; sig[1] = '\0';
// Note: this cannot return NULL, since the input is always correct.
return _Jv_FindClassFromSignature (sig, NULL); return _Jv_FindClassFromSignature (sig, NULL);
} }

View File

@ -38,6 +38,7 @@ details. */
#include <java/lang/Class.h> #include <java/lang/Class.h>
#include <gcj/method.h> #include <gcj/method.h>
#include <gnu/gcj/RawData.h> #include <gnu/gcj/RawData.h>
#include <java/lang/NoClassDefFoundError.h>
#include <stdlib.h> #include <stdlib.h>
@ -235,6 +236,8 @@ _Jv_GetTypesFromSignature (jmethodID method,
char *ptr = sig->chars(); char *ptr = sig->chars();
int numArgs = 0; int numArgs = 0;
/* First just count the number of parameters. */ /* First just count the number of parameters. */
// FIXME: should do some validation here, e.g., that there is only
// one return type.
for (; ; ptr++) for (; ; ptr++)
{ {
switch (*ptr) switch (*ptr)
@ -271,44 +274,26 @@ _Jv_GetTypesFromSignature (jmethodID method,
jclass* argPtr = elements (args); jclass* argPtr = elements (args);
for (ptr = sig->chars(); *ptr != '\0'; ptr++) for (ptr = sig->chars(); *ptr != '\0'; ptr++)
{ {
int num_arrays = 0; if (*ptr == '(')
jclass type; continue;
for (; *ptr == '['; ptr++) if (*ptr == ')')
num_arrays++;
switch (*ptr)
{ {
default:
return;
case ')':
argPtr = return_type_out; argPtr = return_type_out;
continue; 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) char *end_ptr;
type = _Jv_GetArrayClass (type, loader); 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 // ARGPTR can be NULL if we are processing the return value of a
// call from Constructor. // call from Constructor.
if (argPtr) if (argPtr)
*argPtr++ = type; *argPtr++ = type;
ptr = end_ptr;
} }
*arg_types_out = args; *arg_types_out = args;
} }

View File

@ -46,6 +46,7 @@ details. */
#include <java/nio/DirectByteBufferImpl$ReadWrite.h> #include <java/nio/DirectByteBufferImpl$ReadWrite.h>
#include <java/util/IdentityHashMap.h> #include <java/util/IdentityHashMap.h>
#include <gnu/gcj/RawData.h> #include <gnu/gcj/RawData.h>
#include <java/lang/ClassNotFoundException.h>
#include <gcj/method.h> #include <gcj/method.h>
#include <gcj/field.h> #include <gcj/field.h>
@ -1200,8 +1201,8 @@ _Jv_JNI_GetAnyFieldID (JNIEnv *env, jclass clazz,
for (int i = 0; i <= len; ++i) for (int i = 0; i <= len; ++i)
s[i] = (sig[i] == '/') ? '.' : sig[i]; s[i] = (sig[i] == '/') ? '.' : sig[i];
jclass field_class = _Jv_FindClassFromSignature ((char *) s, NULL); jclass field_class = _Jv_FindClassFromSignature ((char *) s, NULL);
if (! field_class)
// FIXME: what if field_class == NULL? throw new java::lang::ClassNotFoundException(JvNewStringUTF(s));
java::lang::ClassLoader *loader = clazz->getClassLoaderInternal (); java::lang::ClassLoader *loader = clazz->getClassLoaderInternal ();
while (clazz != NULL) while (clazz != NULL)

View File

@ -91,7 +91,10 @@ _Jv_Linker::resolve_field (_Jv_Field *field, java::lang::ClassLoader *loader)
if (! field->isResolved ()) if (! field->isResolved ())
{ {
_Jv_Utf8Const *sig = (_Jv_Utf8Const *) field->type; _Jv_Utf8Const *sig = (_Jv_Utf8Const *) field->type;
field->type = _Jv_FindClassFromSignature (sig->chars(), loader); 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; field->flags &= ~_Jv_FIELD_UNRESOLVED_FLAG;
} }
} }
@ -174,6 +177,8 @@ _Jv_Linker::find_field (jclass klass, jclass owner,
// it cheaper. // it cheaper.
jclass field_type = _Jv_FindClassFromSignature (field_type_name->chars(), jclass field_type = _Jv_FindClassFromSignature (field_type_name->chars(),
klass->loader); klass->loader);
if (field_type == NULL)
throw new java::lang::NoClassDefFoundError(field_name->toString());
jclass found_class = 0; jclass found_class = 0;
_Jv_Field *the_field = find_field_helper (owner, field_name, _Jv_Field *the_field = find_field_helper (owner, field_name,

View File

@ -675,46 +675,79 @@ _Jv_InitPrimClass (jclass cl, char *cname, char sig, int len)
} }
jclass 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) switch (*sig)
{ {
case 'B': case 'B':
return JvPrimClass (byte); result = JvPrimClass (byte);
break;
case 'S': case 'S':
return JvPrimClass (short); result = JvPrimClass (short);
break;
case 'I': case 'I':
return JvPrimClass (int); result = JvPrimClass (int);
break;
case 'J': case 'J':
return JvPrimClass (long); result = JvPrimClass (long);
break;
case 'Z': case 'Z':
return JvPrimClass (boolean); result = JvPrimClass (boolean);
break;
case 'C': case 'C':
return JvPrimClass (char); result = JvPrimClass (char);
break;
case 'F': case 'F':
return JvPrimClass (float); result = JvPrimClass (float);
break;
case 'D': case 'D':
return JvPrimClass (double); result = JvPrimClass (double);
break;
case 'V': case 'V':
return JvPrimClass (void); result = JvPrimClass (void);
break;
case 'L': case 'L':
{ {
int i; char *save = ++sig;
for (i = 1; sig[i] && sig[i] != ';'; ++i) while (*sig && *sig != ';')
; ++sig;
_Jv_Utf8Const *name = _Jv_makeUtf8Const (&sig[1], i - 1); // Do nothing if signature appears to be malformed.
return _Jv_FindClass (name, loader); if (*sig == ';')
}
case '[':
{ {
jclass klass = _Jv_FindClassFromSignature (&sig[1], loader); _Jv_Utf8Const *name = _Jv_makeUtf8Const (save, sig - save);
if (! klass) result = _Jv_FindClass (name, loader);
return NULL;
return _Jv_GetArrayClass (klass, 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;
} }

View File

@ -31,6 +31,7 @@ details. */
#include <java/lang/Throwable.h> #include <java/lang/Throwable.h>
#include <java/lang/reflect/Modifier.h> #include <java/lang/reflect/Modifier.h>
#include <java/lang/StringBuffer.h> #include <java/lang/StringBuffer.h>
#include <java/lang/NoClassDefFoundError.h>
#ifdef VERIFY_DEBUG #ifdef VERIFY_DEBUG
#include <stdio.h> #include <stdio.h>
@ -368,7 +369,11 @@ private:
= verifier->current_class->getClassLoaderInternal(); = verifier->current_class->getClassLoaderInternal();
// We might see either kind of name. Sigh. // We might see either kind of name. Sigh.
if (data.name->first() == 'L' && data.name->limit()[-1] == ';') 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 else
data.klass = Class::forName (_Jv_NewStringUtf8Const (data.name), data.klass = Class::forName (_Jv_NewStringUtf8Const (data.name),
false, loader); false, loader);