[Soot-list] a problem on soot method
Eric Bodden
eric.bodden at mail.mcgill.ca
Fri Aug 17 04:29:43 EDT 2007
Hi.
I looked into this and cannot reproduce this. Could you please try the
current Soot release? (2.2.4). Also make sure that your soot-classpath
is set correctly and you don't accidentally pick up a wrong version of
ClassMap.
Eric
On 17/08/07, zhou yuming <cs.zhou.yuming at gmail.com> wrote:
> Hi,
>
> In the class "ClassMap", there are two methods with the same name but
> different parameters:
>
> private static Method[] getAccessibleMethods(Class clazz)
> private static int getAccessibleMethods( Class clazz, MethodInfo[]
> methodInfos, int upcastCount)
>
> According to my understanding, the corresponding sootclass should contain
> both methods. However, I found that only the first method was included. I
> do not understand why the sootclass excluded the second method. Whatever
> soot 2.1.0 or 2.2.1 is used, the result is the same.
>
> Could you please give me a hand? Thanks
>
>
> Zhouyuming
>
>
> The sootmethods in the soot class:
>
> <ClassMap: void <clinit>()>
> <ClassMap: void <init>(java.lang.Class)>
> <ClassMap: java.lang.Class getCachedClass()>
> <ClassMap: java.lang.reflect.Method
> findMethod(java.lang.String,java.lang.Object[])>
> <ClassMap: void populateMethodCache()>
> <ClassMap: java.lang.String makeMethodKey(java.lang.reflect.Method)>
> <ClassMap: java.lang.String
> makeMethodKey(java.lang.String,java.lang.Object[])>
> <ClassMap: java.lang.reflect.Method[] getAccessibleMethods(java.lang.Class)>
> <ClassMap: java.lang.reflect.Method
> getPublicMethod(java.lang.reflect.Method)>
> <ClassMap: java.lang.reflect.Method
> getPublicMethod(java.lang.Class,java.lang.String,java.lang.Class[])>
>
>
>
>
>
>
>
>
> -----------------------------------
>
>
> import java.util.Map;
> import java.util.List;
> import java.util.Hashtable;
>
> import java.lang.reflect.Method;
> import java.lang.reflect.Modifier;
>
> public class ClassMap
> {
> private static final class CacheMiss { }
> private static final CacheMiss CACHE_MISS = new CacheMiss();
> private static final Object OBJECT = new Object();
>
> private Class clazz;
>
> private Map methodCache = new Hashtable();
>
> private MethodMap methodMap = new MethodMap();
>
> public ClassMap(Class clazz)
> {
> this.clazz = clazz;
> populateMethodCache();
> }
>
> Class getCachedClass()
> {
> return clazz;
> }
>
> public Method findMethod(String name, Object[] params)
> {
> String methodKey = makeMethodKey(name, params);
> Object cacheEntry = methodCache.get( methodKey );
>
> if (cacheEntry == CACHE_MISS)
> {
> return null;
> }
>
> if (cacheEntry == null)
> {
> cacheEntry = methodMap.find( name,
> params );
>
> if ( cacheEntry == null )
> {
> methodCache.put( methodKey,
> CACHE_MISS );
> }
> else
> {
> methodCache.put( methodKey,
> cacheEntry );
> }
> }
>
> // Yes, this might just be null.
>
> return (Method) cacheEntry;
> }
>
> private void populateMethodCache()
> {
> StringBuffer methodKey;
>
>
> Method[] methods = getAccessibleMethods(clazz);
>
> for (int i = 0; i < methods.length; i++)
> {
> Method method = methods[i];
>
>
> Method publicMethod = getPublicMethod( method );
>
>
> if ( publicMethod != null)
> {
> methodMap.add( publicMethod );
> methodCache.put( makeMethodKey( publicMethod),
> publicMethod);
> }
> }
> }
>
> private String makeMethodKey(Method method)
> {
> Class[] parameterTypes = method.getParameterTypes();
>
> StringBuffer methodKey = new
> StringBuffer().append(method.getName());
>
> for (int j = 0; j < parameterTypes.length; j++)
> {
> if (parameterTypes[j].isPrimitive())
> {
> if (parameterTypes[j].equals(Boolean.TYPE))
> methodKey.append("java.lang.Boolean");
> else if (parameterTypes[j].equals(Byte.TYPE))
> methodKey.append("java.lang.Byte");
> else if (parameterTypes[j].equals( Character.TYPE))
> methodKey.append("java.lang.Character");
> else if (parameterTypes[j].equals(Double.TYPE))
> methodKey.append("java.lang.Double");
> else if (parameterTypes[j].equals(Float.TYPE))
> methodKey.append("java.lang.Float");
> else if (parameterTypes[j].equals(Integer.TYPE))
> methodKey.append("java.lang.Integer");
> else if (parameterTypes[j].equals(Long.TYPE))
> methodKey.append("java.lang.Long");
> else if (parameterTypes[j].equals( Short.TYPE))
> methodKey.append("java.lang.Short");
> }
> else
> methodKey.append(parameterTypes[j].getName());
> }
>
> return methodKey.toString();
> }
>
> private static String makeMethodKey(String method, Object[] params)
> {
> StringBuffer methodKey = new StringBuffer().append(method);
>
> for (int j = 0; j < params.length; j++)
> {
> if (params[j] == null)
> params[j] = OBJECT;
>
>
> methodKey.append(params[j].getClass().getName());
>
> }
>
> return methodKey.toString();
> }
>
> private static Method[] getAccessibleMethods(Class clazz)
> {
> Method[] methods = clazz.getMethods();
>
>
> if (Modifier.isPublic(clazz.getModifiers()))
> {
> return methods;
> }
>
>
> MethodInfo[] methodInfos = new MethodInfo[methods.length];
>
> for(int i = methods.length; i-- > 0; )
> {
> methodInfos[i] = new MethodInfo(methods[i]);
> }
>
> int upcastCount = getAccessibleMethods(clazz, methodInfos, 0);
>
> if(upcastCount < methods.length)
> {
> methods = new Method[upcastCount];
> }
>
> int j = 0;
> for(int i = 0; i < methodInfos.length; ++i)
> {
> MethodInfo methodInfo = methodInfos[i];
> if(methodInfo.upcast)
> {
> methods[j++] = methodInfo.method;
> }
> }
> return methods;
> }
>
> private static int getAccessibleMethods( Class clazz, MethodInfo[]
> methodInfos, int upcastCount)
> {
> int l = methodInfos.length;
>
> if( Modifier.isPublic(clazz.getModifiers()) )
> {
> for(int i = 0; i < l && upcastCount < l; ++i)
> {
> try
> {
> MethodInfo methodInfo = methodInfos[i];
>
> if(!methodInfo.upcast)
> {
> methodInfo.tryUpcasting(clazz);
> }
>
> upcastCount++;
> }
> catch(NoSuchMethodException e)
> {
> }
> }
>
>
> if(upcastCount == l)
> {
> return upcastCount;
> }
> }
>
>
> Class superclazz = clazz.getSuperclass();
>
> if(superclazz != null)
> {
> upcastCount = getAccessibleMethods(superclazz , methodInfos,
> upcastCount);
>
> if(upcastCount == l)
> {
> return upcastCount;
> }
> }
>
>
> Class[] interfaces = clazz.getInterfaces();
>
> for(int i = interfaces.length; i-- > 0; )
> {
> upcastCount =
> getAccessibleMethods(interfaces[i], methodInfos,
> upcastCount);
>
> if(upcastCount == l)
> {
> return upcastCount;
> }
> }
>
> return upcastCount;
> }
>
> public static Method getPublicMethod(Method method)
> {
> Class clazz = method.getDeclaringClass();
>
> /*
> * Short circuit for (hopefully the majority of) cases where the
> declaring
> * class is public.
> */
>
> if((clazz.getModifiers() & Modifier.PUBLIC) != 0)
> {
> return method;
> }
>
> return getPublicMethod(clazz, method.getName(),
> method.getParameterTypes());
> }
>
> private static Method getPublicMethod(Class clazz, String name, Class[]
> paramTypes)
> {
>
> if((clazz.getModifiers() & Modifier.PUBLIC) != 0)
> {
> try
> {
> return clazz.getMethod(name, paramTypes);
> }
> catch(NoSuchMethodException e)
> {
> return null;
> }
> }
>
>
> Class superclazz = clazz.getSuperclass();
>
> if ( superclazz != null )
> {
> Method superclazzMethod = getPublicMethod(superclazz, name,
> paramTypes);
>
> if(superclazzMethod != null)
> {
> return superclazzMethod;
> }
> }
>
>
> Class[] interfaces = clazz.getInterfaces();
>
> for(int i = 0; i < interfaces.length; ++i)
> {
> Method interfaceMethod = getPublicMethod(interfaces[i], name,
> paramTypes);
>
> if(interfaceMethod != null)
> {
> return interfaceMethod;
> }
> }
>
> return null;
> }
>
> private static final class MethodInfo
> {
> Method method;
> String name;
> Class[] parameterTypes;
> boolean upcast;
>
> MethodInfo(Method method)
> {
> this.method = null;
> name = method.getName();
> parameterTypes = method.getParameterTypes();
> upcast = false;
> }
>
> void tryUpcasting(Class clazz)
> throws NoSuchMethodException
> {
> method = clazz.getMethod(name, parameterTypes);
> name = null;
> parameterTypes = null;
> upcast = true;
> }
> }
> }
>
>
> _______________________________________________
> Soot-list mailing list
> Soot-list at sable.mcgill.ca
> http://mailman.cs.mcgill.ca/mailman/listinfo/soot-list
>
>
--
Eric Bodden
Sable Research Group
McGill University, Montréal, Canada
More information about the Soot-list
mailing list