[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