diff options
author | aph <aph@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-06-08 14:00:43 +0000 |
---|---|---|
committer | aph <aph@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-06-08 14:00:43 +0000 |
commit | d69ad40b46114268021512410165a7ea3b32196c (patch) | |
tree | 83ae3658665a4f6c170a94e91e6c36e86cf6b124 /libjava/link.cc | |
parent | 792f183828f1c38c2b580e1e6cee3e5768f60666 (diff) | |
download | gcc-d69ad40b46114268021512410165a7ea3b32196c.tar.gz |
2006-06-07 Andrew Haley <aph@redhat.com>
* include/jvm.h (_Jv_Linker::maybe_adjust_signature): New.
(_Jv_Linker::uaddr): New.
* link.cc (resolve_pool_entry): Call search_method_in_superclasses
instead of an open-coded loop around search_method_in_class.
(search_method_in_class): Add a new arg, check_perms.
(search_method_in_superclasses): New.
(link_symbol_table): Call maybe_adjust_signature() to extract the
least significnt bit of the signature pointer. Do this three
times, for instace method calls, static methods, and interfaces.
Call search_method_in_superclasses() instead of
_Jv_LookupDeclaredMethod.
(typedef uaddr): Delete.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@114486 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libjava/link.cc')
-rw-r--r-- | libjava/link.cc | 89 |
1 files changed, 63 insertions, 26 deletions
diff --git a/libjava/link.cc b/libjava/link.cc index f95b1287888..5fc82e58b14 100644 --- a/libjava/link.cc +++ b/libjava/link.cc @@ -55,8 +55,6 @@ details. */ using namespace gcj; -typedef unsigned int uaddr __attribute__ ((mode (pointer))); - template<typename T> struct aligner { @@ -461,19 +459,11 @@ _Jv_Linker::resolve_pool_entry (jclass klass, int index, bool lazy) goto end_of_method_search; } - // Finally, search superclasses. - for (jclass cls = owner->getSuperclass (); cls != 0; - cls = cls->getSuperclass ()) - { - the_method = search_method_in_class (cls, klass, method_name, - method_signature); - if (the_method != 0) - { - found_class = cls; - break; - } - } - + // 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 @@ -534,11 +524,12 @@ _Jv_Linker::resolve_class_ref (jclass klass, jclass *classref) } // Find a method declared in the cls that is referenced from klass and -// perform access checks. +// perform access checks if CHECK_PERMS is true. _Jv_Method * _Jv_Linker::search_method_in_class (jclass cls, jclass klass, _Jv_Utf8Const *method_name, - _Jv_Utf8Const *method_signature) + _Jv_Utf8Const *method_signature, + bool check_perms) { using namespace java::lang::reflect; @@ -551,7 +542,7 @@ _Jv_Linker::search_method_in_class (jclass cls, jclass klass, method_signature))) continue; - if (_Jv_CheckAccess (klass, cls, method->accflags)) + if (!check_perms || _Jv_CheckAccess (klass, cls, method->accflags)) return method; else { @@ -568,6 +559,30 @@ _Jv_Linker::search_method_in_class (jclass cls, jclass klass, return 0; } +// Like search_method_in_class, but work our way up the superclass +// chain. +_Jv_Method * +_Jv_Linker::search_method_in_superclasses (jclass cls, jclass klass, + _Jv_Utf8Const *method_name, + _Jv_Utf8Const *method_signature, + jclass *found_class, bool check_perms) +{ + _Jv_Method *the_method = NULL; + + for ( ; cls != 0; cls = cls->getSuperclass ()) + { + the_method = search_method_in_class (cls, klass, method_name, + method_signature, check_perms); + if (the_method != 0) + { + if (found_class) + *found_class = cls; + break; + } + } + + return the_method; +} #define INITIAL_IOFFSETS_LEN 4 #define INITIAL_IFACES_LEN 4 @@ -1076,6 +1091,8 @@ _Jv_Linker::link_symbol_table (jclass klass) _Jv_Method *meth = NULL; _Jv_Utf8Const *signature = sym.signature; + uaddr special; + maybe_adjust_signature (signature, special); if (target_class == NULL) throw new java::lang::NoClassDefFoundError @@ -1101,8 +1118,15 @@ _Jv_Linker::link_symbol_table (jclass klass) // it out now. wait_for_state(target_class, JV_STATE_PREPARED); - meth = _Jv_LookupDeclaredMethod(target_class, sym.name, - sym.signature); + try + { + meth = (search_method_in_superclasses + (target_class, klass, sym.name, signature, + NULL, special == 0)); + } + catch (::java::lang::IllegalAccessError *e) + { + } // Every class has a throwNoSuchMethodErrorIndex method that // it inherits from java.lang.Object. Find its vtable @@ -1158,7 +1182,7 @@ _Jv_Linker::link_symbol_table (jclass klass) try { the_field = find_field (klass, target_class, &found_class, - sym.name, sym.signature); + sym.name, signature); if ((the_field->flags & java::lang::reflect::Modifier::STATIC)) throw new java::lang::IncompatibleClassChangeError; else @@ -1185,7 +1209,10 @@ _Jv_Linker::link_symbol_table (jclass klass) _Jv_FindClassNoException (sym.class_name, klass->loader); _Jv_Method *meth = NULL; + _Jv_Utf8Const *signature = sym.signature; + uaddr special; + maybe_adjust_signature (signature, special); // ??? Setting this pointer to null will at least get us a // NullPointerException @@ -1193,7 +1220,7 @@ _Jv_Linker::link_symbol_table (jclass klass) // If the target class is missing we prepare a function call // that throws a NoClassDefFoundError and store the address of - // that newly prepare method in the atable. The user can run + // that newly prepared method in the atable. The user can run // code in classes where the missing class is part of the // execution environment as long as it is never referenced. if (target_class == NULL) @@ -1219,8 +1246,15 @@ _Jv_Linker::link_symbol_table (jclass klass) throw new VerifyError(sb->toString()); } - meth = _Jv_LookupDeclaredMethod(target_class, sym.name, - sym.signature); + try + { + meth = (search_method_in_superclasses + (target_class, klass, sym.name, signature, + NULL, special == 0)); + } + catch (::java::lang::IllegalAccessError *e) + { + } if (meth != NULL) { @@ -1250,7 +1284,7 @@ _Jv_Linker::link_symbol_table (jclass klass) wait_for_state(target_class, JV_STATE_PREPARED); jclass found_class; _Jv_Field *the_field = find_field (klass, target_class, &found_class, - sym.name, sym.signature); + sym.name, signature); if ((the_field->flags & java::lang::reflect::Modifier::STATIC)) klass->atable->addresses[index] = the_field->u.addr; else @@ -1270,14 +1304,17 @@ _Jv_Linker::link_symbol_table (jclass klass) ++index) { jclass target_class = _Jv_FindClass (sym.class_name, klass->loader); + _Jv_Utf8Const *signature = sym.signature; + uaddr special; + maybe_adjust_signature (signature, special); jclass cls; int i; wait_for_state(target_class, JV_STATE_LOADED); bool found = _Jv_getInterfaceMethod (target_class, cls, i, - sym.name, sym.signature); + sym.name, signature); if (found) { |