diff --git a/libjava/ChangeLog b/libjava/ChangeLog index db83c3d3435..68bee9172f0 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,13 @@ +2005-04-27 Andrew Haley + + 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 * java/nio/charset/Charset.java diff --git a/libjava/include/jvm.h b/libjava/include/jvm.h index bbc809bc162..90b61627f3d 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 176b538d64a..0a705736628 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 b62514581dd..98d30232451 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()