diff options
author | Andrew Haley <aph@redhat.com> | 2005-04-29 18:35:36 +0000 |
---|---|---|
committer | Andrew Haley <aph@gcc.gnu.org> | 2005-04-29 18:35:36 +0000 |
commit | f3dc41fe8e21d79b5338eca6fa50e894b6a4db14 (patch) | |
tree | ba9d688326059397b1b085f20d47c6aba292b04f /libjava | |
parent | 528a7d226228804091bbcccca1ee5e97656e0092 (diff) | |
download | gcc-f3dc41fe8e21d79b5338eca6fa50e894b6a4db14.zip gcc-f3dc41fe8e21d79b5338eca6fa50e894b6a4db14.tar.gz gcc-f3dc41fe8e21d79b5338eca6fa50e894b6a4db14.tar.bz2 |
re PR java/19285 (Interfaces not initialized by static field access)
2005-04-27 Andrew Haley <aph@redhat.com>
PR java/19285
* prims.cc (_Jv_ResolvePoolEntry): New function.
* include/jvm.h (_Jv_Linker::find_field): New arg: found_class.
* link.cc (_Jv_Linker::find_field): New arg: found_class.
(resolve_pool_entry): Initialize the class in which a field is
found.
(link_symbol_table): Pass new arg to found_class.
From-SVN: r99006
Diffstat (limited to 'libjava')
-rw-r--r-- | libjava/ChangeLog | 10 | ||||
-rw-r--r-- | libjava/include/jvm.h | 2 | ||||
-rw-r--r-- | libjava/link.cc | 24 | ||||
-rw-r--r-- | libjava/prims.cc | 16 |
4 files changed, 43 insertions, 9 deletions
diff --git a/libjava/ChangeLog b/libjava/ChangeLog index db83c3d..68bee91 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,13 @@ +2005-04-27 Andrew Haley <aph@redhat.com> + + PR java/19285 + * prims.cc (_Jv_ResolvePoolEntry): New function. + * include/jvm.h (_Jv_Linker::find_field): New arg: found_class. + * link.cc (_Jv_Linker::find_field): New arg: found_class. + (resolve_pool_entry): Initialize the class in which a field is + found. + (link_symbol_table): Pass new arg to found_class. + 2005-04-29 Michael Koch <konqueror@gmx.de> * java/nio/charset/Charset.java diff --git a/libjava/include/jvm.h b/libjava/include/jvm.h index bbc809b..90b6162 100644 --- a/libjava/include/jvm.h +++ b/libjava/include/jvm.h @@ -238,7 +238,7 @@ class _Jv_Linker private: static _Jv_Field *find_field_helper(jclass, _Jv_Utf8Const *, _Jv_Utf8Const *, jclass *); - static _Jv_Field *find_field(jclass, jclass, _Jv_Utf8Const *, + static _Jv_Field *find_field(jclass, jclass, jclass *, _Jv_Utf8Const *, _Jv_Utf8Const *); static void prepare_constant_time_tables(jclass); static jshort get_interfaces(jclass, _Jv_ifaces *); diff --git a/libjava/link.cc b/libjava/link.cc index 176b538..0a70573 100644 --- a/libjava/link.cc +++ b/libjava/link.cc @@ -165,11 +165,14 @@ _Jv_Linker::has_field_p (jclass search, _Jv_Utf8Const *field_name) // KLASS is the class that is requesting the field. // OWNER is the class in which the field should be found. // FIELD_TYPE_NAME is the type descriptor for the field. +// Fill FOUND_CLASS with the address of the class in which the field +// is actually declared. // This function does the class loader type checks, and // also access checks. Returns the field, or throws an // exception on error. _Jv_Field * _Jv_Linker::find_field (jclass klass, jclass owner, + jclass *found_class, _Jv_Utf8Const *field_name, _Jv_Utf8Const *field_type_name) { @@ -180,9 +183,8 @@ _Jv_Linker::find_field (jclass klass, jclass owner, 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, - field_type->name, &found_class); + field_type->name, found_class); if (the_field == 0) { @@ -195,7 +197,7 @@ _Jv_Linker::find_field (jclass klass, jclass owner, throw new java::lang::NoSuchFieldError (sb->toString()); } - if (_Jv_CheckAccess (klass, found_class, the_field->flags)) + if (_Jv_CheckAccess (klass, *found_class, the_field->flags)) { // Note that the field returned by find_field_helper is always // resolved. There's no point checking class loaders here, @@ -212,7 +214,7 @@ _Jv_Linker::find_field (jclass klass, jclass owner, = new java::lang::StringBuffer (); sb->append(klass->getName()); sb->append(JvNewStringLatin1(": ")); - sb->append(found_class->getName()); + sb->append((*found_class)->getName()); sb->append(JvNewStringLatin1(".")); sb->append(_Jv_NewStringUtf8Const (field_name)); throw new java::lang::IllegalAccessError(sb->toString()); @@ -300,9 +302,13 @@ _Jv_Linker::resolve_pool_entry (jclass klass, int index) _Jv_Utf8Const *field_name = pool->data[name_index].utf8; _Jv_Utf8Const *field_type_name = pool->data[type_index].utf8; - _Jv_Field *the_field = find_field (klass, owner, field_name, + jclass found_class = 0; + _Jv_Field *the_field = find_field (klass, owner, + &found_class, + field_name, field_type_name); - + if (owner != found_class) + _Jv_InitClass (found_class); pool->data[index].field = the_field; pool->tags[index] |= JV_CONSTANT_ResolvedFlag; } @@ -967,7 +973,8 @@ _Jv_Linker::link_symbol_table (jclass klass) // Try fields. { wait_for_state(target_class, JV_STATE_PREPARED); - _Jv_Field *the_field = find_field (klass, target_class, + jclass found_class; + _Jv_Field *the_field = find_field (klass, target_class, &found_class, sym.name, sym.signature); if ((the_field->flags & java::lang::reflect::Modifier::STATIC)) throw new java::lang::IncompatibleClassChangeError; @@ -1047,7 +1054,8 @@ _Jv_Linker::link_symbol_table (jclass klass) // Try fields. { wait_for_state(target_class, JV_STATE_PREPARED); - _Jv_Field *the_field = find_field (klass, target_class, + jclass found_class; + _Jv_Field *the_field = find_field (klass, target_class, &found_class, sym.name, sym.signature); if ((the_field->flags & java::lang::reflect::Modifier::STATIC)) klass->atable->addresses[index] = the_field->u.addr; diff --git a/libjava/prims.cc b/libjava/prims.cc index b625145..98d3023 100644 --- a/libjava/prims.cc +++ b/libjava/prims.cc @@ -359,6 +359,22 @@ _Jv_ThrowNullPointerException () throw new java::lang::NullPointerException; } +// Resolve an entry in the constant pool and return the target +// address. +void * +_Jv_ResolvePoolEntry (jclass this_class, jint index) +{ + _Jv_Constants *pool = &this_class->constants; + + if ((pool->tags[index] & JV_CONSTANT_ResolvedFlag) != 0) + return pool->data[index].field->u.addr; + + JvSynchronize sync (this_class); + return (_Jv_Linker::resolve_pool_entry (this_class, index)) + .field->u.addr; +} + + // Explicitly throw a no memory exception. // The collector calls this when it encounters an out-of-memory condition. void _Jv_ThrowNoMemory() |