aboutsummaryrefslogtreecommitdiff
path: root/libjava
diff options
context:
space:
mode:
authorAndrew Haley <aph@redhat.com>2005-04-29 18:35:36 +0000
committerAndrew Haley <aph@gcc.gnu.org>2005-04-29 18:35:36 +0000
commitf3dc41fe8e21d79b5338eca6fa50e894b6a4db14 (patch)
treeba9d688326059397b1b085f20d47c6aba292b04f /libjava
parent528a7d226228804091bbcccca1ee5e97656e0092 (diff)
downloadgcc-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/ChangeLog10
-rw-r--r--libjava/include/jvm.h2
-rw-r--r--libjava/link.cc24
-rw-r--r--libjava/prims.cc16
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()