diff options
author | tromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-01-09 19:58:05 +0000 |
---|---|---|
committer | tromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-01-09 19:58:05 +0000 |
commit | 65bf3316cf384588453604be6b4f0ed3751a8b0f (patch) | |
tree | 996a5f57d4a68c53473382e45cb22f574cb3e4db /libjava/link.cc | |
parent | 8fc56618a84446beccd45b80381cdfe0e94050df (diff) | |
download | gcc-65bf3316cf384588453604be6b4f0ed3751a8b0f.tar.gz |
Merged gcj-eclipse branch to trunk.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@120621 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libjava/link.cc')
-rw-r--r-- | libjava/link.cc | 217 |
1 files changed, 120 insertions, 97 deletions
diff --git a/libjava/link.cc b/libjava/link.cc index 5fc82e58b14..929be3a8702 100644 --- a/libjava/link.cc +++ b/libjava/link.cc @@ -264,6 +264,107 @@ _Jv_Linker::find_field (jclass klass, jclass owner, return the_field; } +_Jv_Method * +_Jv_Linker::resolve_method_entry (jclass klass, jclass &found_class, + int class_index, int name_and_type_index, + bool init, bool is_iface) +{ + _Jv_Constants *pool = &klass->constants; + jclass owner = resolve_pool_entry (klass, class_index).clazz; + + if (init && owner != klass) + _Jv_InitClass (owner); + + _Jv_ushort name_index, type_index; + _Jv_loadIndexes (&pool->data[name_and_type_index], + name_index, + type_index); + + _Jv_Utf8Const *method_name = pool->data[name_index].utf8; + _Jv_Utf8Const *method_signature = pool->data[type_index].utf8; + + _Jv_Method *the_method = 0; + found_class = 0; + + // We're going to cache a pointer to the _Jv_Method object + // when we find it. So, to ensure this doesn't get moved from + // beneath us, we first put all the needed Miranda methods + // into the target class. + wait_for_state (klass, JV_STATE_LOADED); + + // First search the class itself. + the_method = search_method_in_class (owner, klass, + method_name, method_signature); + + if (the_method != 0) + { + found_class = owner; + goto end_of_method_search; + } + + // If we are resolving an interface method, search the + // interface's superinterfaces (A superinterface is not an + // interface's superclass - a superinterface is implemented by + // the interface). + if (is_iface) + { + _Jv_ifaces ifaces; + ifaces.count = 0; + ifaces.len = 4; + ifaces.list = (jclass *) _Jv_Malloc (ifaces.len + * sizeof (jclass *)); + + get_interfaces (owner, &ifaces); + + for (int i = 0; i < ifaces.count; i++) + { + jclass cls = ifaces.list[i]; + the_method = search_method_in_class (cls, klass, method_name, + method_signature); + if (the_method != 0) + { + found_class = cls; + break; + } + } + + _Jv_Free (ifaces.list); + + if (the_method != 0) + goto end_of_method_search; + } + + // Finally, search superclasses. + the_method = (search_method_in_superclasses + (owner->getSuperclass (), klass, method_name, + method_signature, &found_class)); + + + end_of_method_search: + + // FIXME: if (cls->loader != klass->loader), then we + // must actually check that the types of arguments + // correspond. That is, for each argument type, and + // the return type, doing _Jv_FindClassFromSignature + // with either loader should produce the same result, + // i.e., exactly the same jclass object. JVMS 5.4.3.3 + + if (the_method == 0) + { + java::lang::StringBuffer *sb = new java::lang::StringBuffer(); + sb->append(JvNewStringLatin1("method ")); + sb->append(owner->getName()); + sb->append(JvNewStringLatin1(".")); + sb->append(_Jv_NewStringUTF(method_name->chars())); + sb->append(JvNewStringLatin1(" with signature ")); + sb->append(_Jv_NewStringUTF(method_signature->chars())); + sb->append(JvNewStringLatin1(" was not found.")); + throw new java::lang::NoSuchMethodError (sb->toString()); + } + + return the_method; +} + _Jv_word _Jv_Linker::resolve_pool_entry (jclass klass, int index, bool lazy) { @@ -289,7 +390,7 @@ _Jv_Linker::resolve_pool_entry (jclass klass, int index, bool lazy) if ((pool->tags[index] & JV_CONSTANT_ResolvedFlag) != 0) return pool->data[index]; - switch (pool->tags[index]) + switch (pool->tags[index] & ~JV_CONSTANT_LazyFlag) { case JV_CONSTANT_Class: { @@ -365,8 +466,9 @@ _Jv_Linker::resolve_pool_entry (jclass klass, int index, bool lazy) if (owner->state == JV_STATE_PHANTOM) throw new java::lang::NoClassDefFoundError(owner->getName()); - if (owner != klass) - _Jv_InitClass (owner); + // We don't initialize 'owner', but we do make sure that its + // fields exist. + wait_for_state (owner, JV_STATE_PREPARED); _Jv_ushort name_index, type_index; _Jv_loadIndexes (&pool->data[name_and_type_index], @@ -381,8 +483,9 @@ _Jv_Linker::resolve_pool_entry (jclass klass, int index, bool lazy) &found_class, field_name, field_type_name); - if (owner != found_class) - _Jv_InitClass (found_class); + // Initialize the field's declaring class, not its qualifying + // class. + _Jv_InitClass (found_class); pool->data[index].field = the_field; pool->tags[index] |= JV_CONSTANT_ResolvedFlag; } @@ -395,96 +498,13 @@ _Jv_Linker::resolve_pool_entry (jclass klass, int index, bool lazy) _Jv_loadIndexes (&pool->data[index], class_index, name_and_type_index); - jclass owner = (resolve_pool_entry (klass, class_index)).clazz; - - if (owner != klass) - _Jv_InitClass (owner); - - _Jv_ushort name_index, type_index; - _Jv_loadIndexes (&pool->data[name_and_type_index], - name_index, - type_index); - - _Jv_Utf8Const *method_name = pool->data[name_index].utf8; - _Jv_Utf8Const *method_signature = pool->data[type_index].utf8; - - _Jv_Method *the_method = 0; - jclass found_class = 0; - // We're going to cache a pointer to the _Jv_Method object - // when we find it. So, to ensure this doesn't get moved from - // beneath us, we first put all the needed Miranda methods - // into the target class. - wait_for_state (klass, JV_STATE_LOADED); - - // First search the class itself. - the_method = search_method_in_class (owner, klass, - method_name, method_signature); - - if (the_method != 0) - { - found_class = owner; - goto end_of_method_search; - } - - // If we are resolving an interface method, search the - // interface's superinterfaces (A superinterface is not an - // interface's superclass - a superinterface is implemented by - // the interface). - if (pool->tags[index] == JV_CONSTANT_InterfaceMethodref) - { - _Jv_ifaces ifaces; - ifaces.count = 0; - ifaces.len = 4; - ifaces.list = (jclass *) _Jv_Malloc (ifaces.len - * sizeof (jclass *)); - - get_interfaces (owner, &ifaces); - - for (int i = 0; i < ifaces.count; i++) - { - jclass cls = ifaces.list[i]; - the_method = search_method_in_class (cls, klass, method_name, - method_signature); - if (the_method != 0) - { - found_class = cls; - break; - } - } - - _Jv_Free (ifaces.list); - - if (the_method != 0) - goto end_of_method_search; - } - - // Finally, search superclasses. - the_method = (search_method_in_superclasses - (owner->getSuperclass (), klass, method_name, - method_signature, &found_class)); - - end_of_method_search: - - // FIXME: if (cls->loader != klass->loader), then we - // must actually check that the types of arguments - // correspond. That is, for each argument type, and - // the return type, doing _Jv_FindClassFromSignature - // with either loader should produce the same result, - // i.e., exactly the same jclass object. JVMS 5.4.3.3 - - if (the_method == 0) - { - java::lang::StringBuffer *sb = new java::lang::StringBuffer(); - sb->append(JvNewStringLatin1("method ")); - sb->append(owner->getName()); - sb->append(JvNewStringLatin1(".")); - sb->append(_Jv_NewStringUTF(method_name->chars())); - sb->append(JvNewStringLatin1(" with signature ")); - sb->append(_Jv_NewStringUTF(method_signature->chars())); - sb->append(JvNewStringLatin1(" was not found.")); - throw new java::lang::NoSuchMethodError (sb->toString()); - } + _Jv_Method *the_method; + jclass found_class; + the_method = resolve_method_entry (klass, found_class, + class_index, name_and_type_index, + true, + pool->tags[index] == JV_CONSTANT_InterfaceMethodref); pool->data[index].rmethod = klass->engine->resolve_method(the_method, @@ -1950,11 +1970,14 @@ _Jv_Linker::wait_for_state (jclass klass, int state) // Print some debugging info if requested. Interpreted classes are // handled in defineclass, so we only need to handle the two // pre-compiled cases here. - if (gcj::verbose_class_flag - && (klass->state == JV_STATE_COMPILED + if ((klass->state == JV_STATE_COMPILED || klass->state == JV_STATE_PRELOADING) && ! _Jv_IsInterpretedClass (klass)) - print_class_loaded (klass); + { + if (gcj::verbose_class_flag) + print_class_loaded (klass); + ++gcj::loadedClasses; + } try { |