Browse Source

fixed a bug of method dispatch.


git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@237 30ef5769-5b8d-40dd-aea6-55b5d6557bb3
tags/rel_3_17_1_ga
chiba 18 years ago
parent
commit
35e52a2c0b
1 changed files with 22 additions and 15 deletions
  1. 22
    15
      src/main/javassist/compiler/MemberResolver.java

+ 22
- 15
src/main/javassist/compiler/MemberResolver.java View File

public static class Method { public static class Method {
public CtClass declaring; public CtClass declaring;
public MethodInfo info; public MethodInfo info;
public int notmatch;


public Method(CtClass c, MethodInfo i) {
public Method(CtClass c, MethodInfo i, int n) {
declaring = c; declaring = c;
info = i; info = i;
notmatch = n;
} }


/** /**
if (current.getName().equals(methodName)) { if (current.getName().equals(methodName)) {
int res = compareSignature(current.getDescriptor(), int res = compareSignature(current.getDescriptor(),
argTypes, argDims, argClassNames); argTypes, argDims, argClassNames);
Method r = new Method(clazz, current);
if (res == YES)
return r;
else if (res == MAYBE)
maybe = r;
if (res != NO) {
Method r = new Method(clazz, current, res);
if (res == YES)
return r;
else
maybe = r;
}
} }


Method m = lookupMethod(clazz, methodName, argTypes, argDims, Method m = lookupMethod(clazz, methodName, argTypes, argDims,
int res = compareSignature(minfo.getDescriptor(), int res = compareSignature(minfo.getDescriptor(),
argTypes, argDims, argClassNames); argTypes, argDims, argClassNames);
if (res != NO) { if (res != NO) {
Method r = new Method(clazz, minfo);
Method r = new Method(clazz, minfo, res);
if (res == YES) if (res == YES)
return r; return r;
else if (maybe == null)
else if (maybe == null || maybe.notmatch > res)
maybe = r; maybe = r;
} }
} }
return maybe; return maybe;
} }


private static final int YES = 2;
private static final int MAYBE = 1;
private static final int NO = 0;
private static final int YES = 0;
private static final int NO = -1;


/* /*
* Returns YES if actual parameter types matches the given signature. * Returns YES if actual parameter types matches the given signature.
* *
* This method does not correctly implement the Java method dispatch * This method does not correctly implement the Java method dispatch
* algorithm. * algorithm.
*
* If some of the parameter types exactly match but others are subtypes of
* the corresponding type in the signature, this method returns the number
* of parameter types that do not exactly match.
*/ */
private int compareSignature(String desc, int[] argTypes, private int compareSignature(String desc, int[] argTypes,
int[] argDims, String[] argClassNames) int[] argDims, String[] argClassNames)


// if the thread reaches here, c must be 'L'. // if the thread reaches here, c must be 'L'.
i = desc.indexOf(';', i) + 1; i = desc.indexOf(';', i) + 1;
result = MAYBE;
result++;
if (i <= 0) if (i <= 0)
return NO; // invalid descriptor? return NO; // invalid descriptor?
} }
CtClass clazz = lookupClassByJvmName(argClassNames[n]); CtClass clazz = lookupClassByJvmName(argClassNames[n]);
try { try {
if (clazz.subtypeOf(lookupClassByJvmName(cname))) if (clazz.subtypeOf(lookupClassByJvmName(cname)))
result = MAYBE;
result++;
else else
return NO; return NO;
} }
catch (NotFoundException e) { catch (NotFoundException e) {
result = MAYBE; // should be NO?
result++; // should be NO?
} }
} }


if (t != at) if (t != at)
if (t == INT if (t == INT
&& (at == SHORT || at == BYTE || at == CHAR)) && (at == SHORT || at == BYTE || at == CHAR))
result = MAYBE;
result++;
else else
return NO; return NO;
} }

Loading…
Cancel
Save