+#if 0
+ s4 i;
+#if defined(JOWENN_DEBUG1) || defined(JOWENN_DEBUG2)
+ char *buffer;
+ int buffer_len, pos;
+#endif
+#ifdef JOWENN_DEBUG1
+
+ buffer_len =
+ utf_strlen(name) + utf_strlen(desc) + utf_strlen(c->name) + 64;
+
+ buffer = MNEW(char, buffer_len);
+
+ strcpy(buffer, "class_findmethod: method:");
+ utf_sprint(buffer + strlen(buffer), name);
+ strcpy(buffer + strlen(buffer), ", desc: ");
+ utf_sprint(buffer + strlen(buffer), desc);
+ strcpy(buffer + strlen(buffer), ", classname: ");
+ utf_sprint(buffer + strlen(buffer), c->name);
+
+ log_text(buffer);
+
+ MFREE(buffer, char, buffer_len);
+#endif
+ for (i = 0; i < c->methodscount; i++) {
+#ifdef JOWENN_DEBUG2
+ buffer_len =
+ utf_strlen(c->methods[i].name) + utf_strlen(c->methods[i].descriptor)+ 64;
+
+ buffer = MNEW(char, buffer_len);
+
+ strcpy(buffer, "class_findmethod: comparing to method:");
+ utf_sprint(buffer + strlen(buffer), c->methods[i].name);
+ strcpy(buffer + strlen(buffer), ", desc: ");
+ utf_sprint(buffer + strlen(buffer), c->methods[i].descriptor);
+
+ log_text(buffer);
+
+ MFREE(buffer, char, buffer_len);
+#endif
+
+ if ((c->methods[i].name == name) && ((desc == NULL) ||
+ (c->methods[i].descriptor == desc))) {
+ return &(c->methods[i]);
+ }
+ }
+#ifdef JOWENN_DEBUG2
+ class_showconstantpool(c);
+ log_text("class_findmethod: returning NULL");
+#endif
+ return NULL;
+#endif
+
+ s4 idx=class_findmethodIndex(c, name, desc);
+/* if (idx==-1) log_text("class_findmethod: method not found");*/
+ if (idx == -1) return NULL;
+
+ return &(c->methods[idx]);
+}
+
+
+/*********************** Function: class_fetchmethod **************************
+
+ like class_findmethod, but aborts with an error if the method is not found
+
+*******************************************************************************/
+
+methodinfo *class_fetchmethod(classinfo *c, utf *name, utf *desc)
+{
+ methodinfo *mi;
+ mi = class_findmethod(c, name, desc);
+
+ if (!mi) {
+ log_plain("Class: "); if (c) log_plain_utf(c->name); log_nl();
+ log_plain("Method: "); if (name) log_plain_utf(name); log_nl();
+ log_plain("Descriptor: "); if (desc) log_plain_utf(desc); log_nl();
+ panic("Method not found");
+ }
+
+ return mi;
+}
+
+
+/*********************** Function: class_findmethod_w**************************
+
+ like class_findmethod, but logs a warning if the method is not found
+
+*******************************************************************************/
+
+methodinfo *class_findmethod_w(classinfo *c, utf *name, utf *desc, char *from)
+{
+ methodinfo *mi;
+ mi = class_findmethod(c, name, desc);
+
+ if (!mi) {
+ log_plain("Class: "); if (c) log_plain_utf(c->name); log_nl();
+ log_plain("Method: "); if (name) log_plain_utf(name); log_nl();
+ log_plain("Descriptor: "); if (desc) log_plain_utf(desc); log_nl();
+
+ if ( c->flags & ACC_PUBLIC ) log_plain(" PUBLIC ");
+ if ( c->flags & ACC_PRIVATE ) log_plain(" PRIVATE ");
+ if ( c->flags & ACC_PROTECTED ) log_plain(" PROTECTED ");
+ if ( c->flags & ACC_STATIC ) log_plain(" STATIC ");
+ if ( c->flags & ACC_FINAL ) log_plain(" FINAL ");
+ if ( c->flags & ACC_SYNCHRONIZED ) log_plain(" SYNCHRONIZED ");
+ if ( c->flags & ACC_VOLATILE ) log_plain(" VOLATILE ");
+ if ( c->flags & ACC_TRANSIENT ) log_plain(" TRANSIENT ");
+ if ( c->flags & ACC_NATIVE ) log_plain(" NATIVE ");
+ if ( c->flags & ACC_INTERFACE ) log_plain(" INTERFACE ");
+ if ( c->flags & ACC_ABSTRACT ) log_plain(" ABSTRACT ");
+
+ log_plain(from);
+ log_plain(" : WARNING: Method not found");log_nl( );
+ }
+
+ return mi;
+}
+
+
+/************************* Function: class_findmethod_approx ******************
+
+ like class_findmethod but ignores the return value when comparing the
+ descriptor.
+
+*******************************************************************************/
+
+methodinfo *class_findmethod_approx(classinfo *c, utf *name, utf *desc)
+{
+ s4 i;
+
+ for (i = 0; i < c->methodscount; i++) {
+ if (c->methods[i].name == name) {
+ utf *meth_descr = c->methods[i].descriptor;
+
+ if (desc == NULL)
+ /* ignore type */
+ return &(c->methods[i]);
+
+ if (desc->blength <= meth_descr->blength) {
+ /* current position in utf text */
+ char *desc_utf_ptr = desc->text;
+ char *meth_utf_ptr = meth_descr->text;
+ /* points behind utf strings */
+ char *desc_end = utf_end(desc);
+ char *meth_end = utf_end(meth_descr);
+ char ch;
+
+ /* compare argument types */
+ while (desc_utf_ptr < desc_end && meth_utf_ptr < meth_end) {
+
+ if ((ch = *desc_utf_ptr++) != (*meth_utf_ptr++))
+ break; /* no match */
+
+ if (ch == ')')
+ return &(c->methods[i]); /* all parameter types equal */
+ }
+ }
+ }
+ }
+
+ return NULL;
+}
+
+
+/***************** Function: class_resolvemethod_approx ***********************
+
+ Searches a class and every super class for a method (without paying
+ attention to the return value)
+
+*******************************************************************************/
+
+methodinfo *class_resolvemethod_approx(classinfo *c, utf *name, utf *desc)
+{
+ while (c) {
+ /* search for method (ignore returntype) */
+ methodinfo *m = class_findmethod_approx(c, name, desc);
+ /* method found */
+ if (m) return m;
+ /* search superclass */
+ c = c->super;
+ }
+
+ return NULL;
+}
+
+
+/************************* Function: class_resolvemethod ***********************
+
+ Searches a class and every super class for a method.
+
+*******************************************************************************/
+
+methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *desc)
+{
+ while (c) {
+ methodinfo *m = class_findmethod(c, name, desc);
+ if (m) return m;
+ /* search superclass */
+ c = c->super;
+ }
+
+ 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.
+
+*******************************************************************************/
+
+methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *desc,
+ classinfo *referer)
+{
+ methodinfo *mi;
+
+ /* XXX resolve class c */
+ /* XXX check access from REFERER to C */
+
+ if ((c->flags & ACC_INTERFACE) == 0)
+ return NULL; /* should throw IncompatibleClassChangeError */
+
+ mi = class_resolveinterfacemethod_int(c,name,desc);
+ if (mi)
+ goto found;
+
+ /* try class java.lang.Object */
+ mi = class_findmethod(class_java_lang_Object,name,desc);
+ if (mi)
+ goto found;
+
+ return NULL; /* should throw NoSuchMethodError */
+
+ found:
+ return mi;
+}
+
+/********************* Function: class_resolveclassmethod *********************
+
+ Resolves a reference from REFERER to a method with NAME and DESC in
+ class C.
+
+*******************************************************************************/
+
+methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *desc,
+ classinfo *referer)
+{
+ methodinfo *mi;
+ int i;
+ classinfo *cls;
+
+ /* XXX resolve class c */
+ /* XXX check access from REFERER to C */
+
+ if ((c->flags & ACC_INTERFACE) != 0)
+ return NULL; /* should throw IncompatibleClassChangeError */
+
+ /* 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;
+ }
+
+ return NULL; /* should throw NoSuchMethodError */
+
+ found:
+ if ((mi->flags & ACC_ABSTRACT) != 0 &&
+ (c->flags & ACC_ABSTRACT) == 0)
+ return NULL; /* should throw AbstractMethodError */
+
+ /* XXX check access rights */
+
+ return mi;
+}
+