+ Searches a class and every super class for a method.
+
+*******************************************************************************/
+
+methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *desc)
+{
+ /*log_text("Trying to resolve a method");
+ utf_display(c->name);
+ utf_display(name);
+ utf_display(desc);*/
+
+ while (c) {
+ /*log_text("Looking in:");
+ utf_display(c->name);*/
+ methodinfo *m = class_findmethod(c, name, desc);
+ if (m) return m;
+ /* search superclass */
+ c = c->super;
+ }
+ /*log_text("method not found:");*/
+
+ return NULL;
+}
+
+
+/****************** Function: class_resolveinterfacemethod_int ****************
+
+ Internally used helper function. Do not use this directly.
+
+*******************************************************************************/
+
+static
+methodinfo *class_resolveinterfacemethod_int(classinfo *c, utf *name, utf *desc)
+{
+ methodinfo *mi;
+ int i;
+
+ mi = class_findmethod(c,name,desc);
+ if (mi)
+ return mi;
+
+ /* try the superinterfaces */
+ for (i=0; i<c->interfacescount; ++i) {
+ mi = class_resolveinterfacemethod_int(c->interfaces[i],name,desc);
+ if (mi)
+ return mi;
+ }
+
+ return NULL;
+}
+
+/******************** Function: class_resolveinterfacemethod ******************
+
+ Resolves a reference from REFERER to a method with NAME and DESC in
+ interface C.
+
+ If the method cannot be resolved the return value is NULL. If EXCEPT is
+ true *exceptionptr is set, too.
+
+*******************************************************************************/
+
+methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *desc,
+ classinfo *referer, bool except)
+{
+ methodinfo *mi;
+
+ /* XXX resolve class c */
+ /* XXX check access from REFERER to C */
+
+ if (!(c->flags & ACC_INTERFACE)) {
+ if (except)
+ *exceptionptr =
+ new_exception(string_java_lang_IncompatibleClassChangeError);
+
+ return NULL;
+ }
+
+ mi = class_resolveinterfacemethod_int(c, name, desc);
+
+ if (mi)
+ return mi;
+
+ /* try class java.lang.Object */
+ mi = class_findmethod(class_java_lang_Object, name, desc);
+
+ if (mi)
+ return mi;
+
+ if (except)
+ *exceptionptr =
+ new_exception_utfmessage(string_java_lang_NoSuchMethodError, name);
+
+ return NULL;
+}
+
+
+/********************* Function: class_resolveclassmethod *********************
+
+ Resolves a reference from REFERER to a method with NAME and DESC in
+ class C.
+
+ If the method cannot be resolved the return value is NULL. If EXCEPT is
+ true *exceptionptr is set, too.
+
+*******************************************************************************/
+
+methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *desc,
+ classinfo *referer, bool except)
+{
+ classinfo *cls;
+ methodinfo *mi;
+ s4 i;
+ char msg[MAXLOGTEXT];
+
+ /* XXX resolve class c */
+ /* XXX check access from REFERER to C */
+
+/* if (c->flags & ACC_INTERFACE) { */
+/* if (except) */
+/* *exceptionptr = */
+/* new_exception(string_java_lang_IncompatibleClassChangeError); */
+/* return NULL; */
+/* } */
+
+ /* try class c and its superclasses */
+ cls = c;
+ do {
+ mi = class_findmethod(cls, name, desc);
+ if (mi)
+ goto found;
+ } while ((cls = cls->super) != NULL); /* try the superclass */
+
+ /* try the superinterfaces */
+ for (i = 0; i < c->interfacescount; ++i) {
+ mi = class_resolveinterfacemethod_int(c->interfaces[i], name, desc);
+ if (mi)
+ goto found;
+ }
+
+ if (except) {
+ utf_sprint(msg, c->name);
+ sprintf(msg + strlen(msg), ".");
+ utf_sprint(msg + strlen(msg), name);
+ utf_sprint(msg + strlen(msg), desc);
+
+ *exceptionptr =
+ new_exception_message(string_java_lang_NoSuchMethodError, msg);
+ }