aboutsummaryrefslogtreecommitdiff
path: root/libjava/link.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/link.cc')
-rw-r--r--libjava/link.cc24
1 files changed, 16 insertions, 8 deletions
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;