Fixing a new bug: Considering parameters with Type and Type array, e.g., T and T[].
authorRahmadi Trimananda <rtrimana@uci.edu>
Sat, 29 Jun 2019 23:32:26 +0000 (16:32 -0700)
committerRahmadi Trimananda <rtrimana@uci.edu>
Sat, 29 Jun 2019 23:32:26 +0000 (16:32 -0700)
examples/Reflection.java
src/main/gov/nasa/jpf/jvm/JVMClassInfo.java
src/main/gov/nasa/jpf/vm/Types.java
src/peers/gov/nasa/jpf/vm/JPF_java_lang_reflect_Method.java

index 9502a04564bb056d6b4c9950f7f0805a63eb1030..ac036c2282b337771991cf372ab8676d508d54f5 100644 (file)
@@ -7,6 +7,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Map;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 
 import java.math.BigInteger;
 import java.security.ProtectionDomain;
 
 import java.math.BigInteger;
 import java.security.ProtectionDomain;
@@ -50,26 +51,39 @@ public class Reflection {
                  return listString;
           }*/
        }
                  return listString;
           }*/
        }
-       
-           private static int digitsPerInt[] = {0, 0, 30, 19, 15, 13, 11,
-            11, 10, 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6,
-            6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5};
-                       
-               private static long bitsPerDigit[] = { 0, 0,
-            1024, 1624, 2048, 2378, 2648, 2875, 3072, 3247, 3402, 3543, 3672,
-            3790, 3899, 4001, 4096, 4186, 4271, 4350, 4426, 4498, 4567, 4633,
-            4696, 4756, 4814, 4870, 4923, 4975, 5025, 5074, 5120, 5166, 5210,
-            5253, 5295};
 
    public static void main(String[] args) {
 
    public static void main(String[] args) {
+          
+         BigInteger bi = new BigInteger("-1");
+         System.out.println(bi);
+          
+         /* TODO: Enumerate all methods in Class.class 
+      Method[] methods = Class.class.getMethods();
+      for(Method mth : methods) {
+                 //System.out.println("===========================");
+         //System.out.println("Method: " + mth.getName());
+                 Type[] parameters = mth.getGenericParameterTypes();
+                 for (int i = 0; i < parameters.length; i++) {
+                    System.out.println(parameters[i]);
+                 }
+                 System.out.println();
+                 Type returnType = mth.getGenericReturnType();
+                 System.out.println(returnType + "\n");
+      }*/
 
 
-      /*Method[] methods = SampleClass.class.getMethods();
+      Method[] methods = Collection.class.getMethods();
       //  Method[] methods = Class.class.getMethods();
         Method method = null;
         for(Method meth : methods) {
       //  Method[] methods = Class.class.getMethods();
         Method method = null;
         for(Method meth : methods) {
-            if (meth.getName().equals("setSampleField")) {
-                method = meth;
-            }
+                               System.out.println("===========================");
+                               //System.out.println("Method: " + meth.toString());
+                               Type[] parameters = meth.getGenericParameterTypes();
+                               for (int i = 0; i < parameters.length; i++) {
+                                       System.out.println(parameters[i]);
+                               }
+                               Type returnType = meth.getGenericReturnType();
+                               System.out.println(returnType);
+                               System.out.println("===========================");
         }
         Type[] parameters = method.getGenericParameterTypes();
       //Type[] parameters = methods[0].getGenericParameterTypes();
         }
         Type[] parameters = method.getGenericParameterTypes();
       //Type[] parameters = methods[0].getGenericParameterTypes();
@@ -78,11 +92,7 @@ public class Reflection {
       }
       System.out.println();
       Type returnType = method.getGenericReturnType();
       }
       System.out.println();
       Type returnType = method.getGenericReturnType();
-         Class.class.getSimpleName();*/
-      //System.out.println(returnType);
-         
-      //BigInteger bi = new BigInteger("-1");
-         //System.out.println(bi);
+      System.out.println(returnType);
          
         /* TODO: This is an excerpt of the BigInteger library
                int radix = 10;
          
         /* TODO: This is an excerpt of the BigInteger library
                int radix = 10;
@@ -160,14 +170,15 @@ public class Reflection {
             System.out.println(interfaces[i]);
         }*/
       
             System.out.println(interfaces[i]);
         }*/
       
-      
-         /*Method[] methods = Class.class.getMethods();
+      /*
+         Method[] methods = Collection.class.getMethods();
          Method method = null;
       for(Method mth : methods) {
          Method method = null;
       for(Method mth : methods) {
-        if (mth.getName().equals("getConstructor")) {
+        if (mth.getName().equals("toArray")) {
         //if (mth.getName().equals("isAssignableFrom")) {
         //if (mth.getName().equals("getSuperclass")) {
            method = mth;
         //if (mth.getName().equals("isAssignableFrom")) {
         //if (mth.getName().equals("getSuperclass")) {
            method = mth;
+                  break;
         }
       }
       Type[] parameters = method.getGenericParameterTypes();
         }
       }
       Type[] parameters = method.getGenericParameterTypes();
@@ -178,20 +189,6 @@ public class Reflection {
       System.out.println();
       Type returnType = method.getGenericReturnType();
       System.out.println(returnType);*/
       System.out.println();
       Type returnType = method.getGenericReturnType();
       System.out.println(returnType);*/
-      
-      /* TODO: Enumerate all methods in Class.class */
-      /*Method[] methods = Class.class.getMethods();
-      for(Method mth : methods) {
-                 System.out.println("===========================");
-         System.out.println("Method: " + mth.getName());
-                 Type[] parameters = mth.getGenericParameterTypes();
-                 for (int i = 0; i < parameters.length; i++) {
-                    System.out.println(parameters[i]);
-                 }
-                 System.out.println();
-                 Type returnType = mth.getGenericReturnType();
-                 System.out.println(returnType + "\n");
-      }*/
 
       /*Class[] parameterTypes = methods[0].getParameterTypes();
       for(Class parameterType: parameterTypes){
 
       /*Class[] parameterTypes = methods[0].getParameterTypes();
       for(Class parameterType: parameterTypes){
@@ -213,8 +210,8 @@ public class Reflection {
       }
       System.out.println();*/
          
       }
       System.out.println();*/
          
-         ProtectionDomain pd = Class.class.getProtectionDomain();
-      System.out.println(pd);
+         //ProtectionDomain pd = Class.class.getProtectionDomain();
+      //System.out.println(pd);
    }
 }
 
    }
 }
 
index 7f3309f31de05f687d17c5fabd895a697de81b41..9c3159abafa394e0371151d53853baa7773879fb 100644 (file)
@@ -116,10 +116,12 @@ public class JVMClassInfo extends ClassInfo {
     }
     
     @Override
     }
     
     @Override
-    public void setBootstrapMethod (ClassFile cf, Object tag, int idx, int refKind, String cls, String mth, String descriptor, int[] cpArgs) {    
-   
+    public void setBootstrapMethod (ClassFile cf, Object tag, int idx, int refKind, String cls, String mth, String descriptor, int[] cpArgs) {
+
+      // TODO: Fix for Groovy's model-checking
+      // TODO: Probably a bug here since cpArgs could be of length 1 sometimes!
       int lambdaRefKind = cf.mhRefTypeAt(cpArgs[1]);
       int lambdaRefKind = cf.mhRefTypeAt(cpArgs[1]);
-      
+
       int mrefIdx = cf.mhMethodRefIndexAt(cpArgs[1]);
       String clsName = cf.methodClassNameAt(mrefIdx).replace('/', '.');
       ClassInfo eclosingLambdaCls;
       int mrefIdx = cf.mhMethodRefIndexAt(cpArgs[1]);
       String clsName = cf.methodClassNameAt(mrefIdx).replace('/', '.');
       ClassInfo eclosingLambdaCls;
index 313e8aab7d0fb0f01027262c8ea64abc1ea0fe91..30efa1fe872d11b15957bf79763e0bde5526f8ef 100644 (file)
@@ -912,6 +912,13 @@ public class Types {
       return getTypeName(signature.substring(1)) + "[]";
     }
 
       return getTypeName(signature.substring(1)) + "[]";
     }
 
+    // If it does not contain '<' and '>' then it is
+    // a Type signature, e.g., T, U, etc.
+    if (Types.isParameterWithType(signature)) {
+      // Clean the ';' character first and return the Type
+      return Types.getTypeParameter(signature.replace(";", ""));
+    }
+
     int len1 = len-1;
     if (signature.charAt(len1) == ';') {
       // TODO: Fix for Groovy's model-checking
     int len1 = len-1;
     if (signature.charAt(len1) == ';') {
       // TODO: Fix for Groovy's model-checking
@@ -1105,7 +1112,7 @@ public class Types {
       return 1 + getTypeLength(signature, idx + 1);
 
     case 'L':
       return 1 + getTypeLength(signature, idx + 1);
 
     case 'L':
-
+    default:
       int semicolon = signature.indexOf(';', idx);
       // TODO: Fix for Groovy's model-checking
       // Check if this is a generic!
       int semicolon = signature.indexOf(';', idx);
       // TODO: Fix for Groovy's model-checking
       // Check if this is a generic!
@@ -1132,7 +1139,7 @@ public class Types {
       return semicolon - idx + 1;
     }
 
       return semicolon - idx + 1;
     }
 
-    throw new JPFException("invalid type signature");
+    //throw new JPFException("invalid type signature");
   }
 
   /**
   }
 
   /**
@@ -1282,6 +1289,10 @@ public class Types {
   public static boolean isTypeParameter(String parameterizedType, String signature) {
     if (signature == null || signature.equals(""))
       return false;
   public static boolean isTypeParameter(String parameterizedType, String signature) {
     if (signature == null || signature.equals(""))
       return false;
+    // The comparison has to be done without the "[]" part if it is an array
+    if (Types.isArraySignature(parameterizedType)) {
+      parameterizedType = Types.getArrayClassName(parameterizedType);
+    }
     String typeParamSig = parameterizedType.concat(":");
     return signature.contains(typeParamSig);
   }
     String typeParamSig = parameterizedType.concat(":");
     return signature.contains(typeParamSig);
   }
@@ -1301,6 +1312,14 @@ public class Types {
     return signature.replaceAll("\\+L|-L", "");
   }
 
     return signature.replaceAll("\\+L|-L", "");
   }
 
+  public static boolean isParameterWithType(String signature) {
+    // Does not contain a class name
+    if (!signature.contains(".") && !signature.contains("/")) {
+      return true;
+    }
+    return false;
+  }
+
   public static String getTypeParameter(String signature) {
     if (signature == null || signature.equals(""))
       return signature;
   public static String getTypeParameter(String signature) {
     if (signature == null || signature.equals(""))
       return signature;
index 3baa1651b31a3fdbdaa777a8fa0e16d723e9f10a..05c049fa7a9138614cf748bc4777fd5f3598ba28 100644 (file)
@@ -128,7 +128,12 @@ public class JPF_java_lang_reflect_Method extends NativePeer {
 
     // Get field information and fill out the fields
     String clsSig = Types.getArrayClassName(signature);
 
     // Get field information and fill out the fields
     String clsSig = Types.getArrayClassName(signature);
-    int paramTypeRef = getParameterizedTypeImplObj(clsSig, env, objRef, mi);
+    int paramTypeRef;
+    if (Types.isParameterWithType(clsSig)) {
+      paramTypeRef = getTypeVariableImplObject(env, objRef, clsSig);
+    } else {
+      paramTypeRef = getParameterizedTypeImplObj(clsSig, env, objRef, mi);
+    }
     ei.setReferenceField("genericComponentType", paramTypeRef);
 
     return genArrRef;
     ei.setReferenceField("genericComponentType", paramTypeRef);
 
     return genArrRef;
@@ -266,6 +271,8 @@ public class JPF_java_lang_reflect_Method extends NativePeer {
     String[] argTypeNames = mi.getArgumentGenericTypeNames();
     int[] ar = new int[argTypeNames.length];
 
     String[] argTypeNames = mi.getArgumentGenericTypeNames();
     int[] ar = new int[argTypeNames.length];
 
+    String classGenericSig = mi.getClassInfo().getGenericSignature();
+    String methodGenericSig = mi.getGenericSignature();
     for (int i = 0; i < argTypeNames.length; i++) {
       // Change this into just the generic class type if it is a generic class
       if (Types.isGenericSignature(argTypeNames[i])) {
     for (int i = 0; i < argTypeNames.length; i++) {
       // Change this into just the generic class type if it is a generic class
       if (Types.isGenericSignature(argTypeNames[i])) {
@@ -275,6 +282,14 @@ public class JPF_java_lang_reflect_Method extends NativePeer {
         } else {
           ar[i] = getParameterizedTypeImplObj(argTypeNames[i], env, objRef, mi);
         }
         } else {
           ar[i] = getParameterizedTypeImplObj(argTypeNames[i], env, objRef, mi);
         }
+      } else if (Types.isTypeParameter(argTypeNames[i], methodGenericSig) ||
+                 Types.isTypeParameter(argTypeNames[i], classGenericSig)) {
+        if (Types.isArraySignature(argTypeNames[i])) {
+          // Generic array
+          ar[i] = getGenericArrayTypeImplObj(argTypeNames[i], env, objRef, mi);
+        } else {
+          ar[i] = getTypeVariableImplObject(env, objRef, argTypeNames[i]);
+        }
       } else {
         ClassInfo ci = ClassLoaderInfo.getCurrentResolvedClassInfo(argTypeNames[i]);
         if (!ci.isRegistered()) {
       } else {
         ClassInfo ci = ClassLoaderInfo.getCurrentResolvedClassInfo(argTypeNames[i]);
         if (!ci.isRegistered()) {
@@ -300,13 +315,25 @@ public class JPF_java_lang_reflect_Method extends NativePeer {
     MethodInfo mi = getMethodInfo(env, objRef);
     ThreadInfo ti = env.getThreadInfo();
 
     MethodInfo mi = getMethodInfo(env, objRef);
     ThreadInfo ti = env.getThreadInfo();
 
+    String genRetType = mi.getGenericReturnTypeName();
+    String classGenericSig = mi.getClassInfo().getGenericSignature();
+    String methodGenericSig = mi.getGenericSignature();
     int retRef;
     int retRef;
-    if (Types.isGenericSignature(mi.getGenericReturnTypeName())) {
-      if (Types.isArraySignature(mi.getGenericReturnTypeName())) {
+
+    if (Types.isGenericSignature(genRetType)) {
+      if (Types.isArraySignature(genRetType)) {
+        // Generic array
+        retRef = getGenericArrayTypeImplObj(genRetType, env, objRef, mi);
+      } else {
+        retRef = getParameterizedTypeImplObj(genRetType, env, objRef, mi);
+      }
+    } else if (Types.isTypeParameter(genRetType, methodGenericSig) ||
+               Types.isTypeParameter(genRetType, classGenericSig)) {
+      if (Types.isArraySignature(genRetType)) {
         // Generic array
         // Generic array
-        retRef = getGenericArrayTypeImplObj(mi.getGenericReturnTypeName(), env, objRef, mi);
+        retRef = getGenericArrayTypeImplObj(genRetType, env, objRef, mi);
       } else {
       } else {
-        retRef = getParameterizedTypeImplObj(mi.getGenericReturnTypeName(), env, objRef, mi);
+        retRef = getTypeVariableImplObject(env, objRef, genRetType);
       }
     } else {
       ClassInfo ci = ClassLoaderInfo.getCurrentResolvedClassInfo(mi.getReturnTypeName());
       }
     } else {
       ClassInfo ci = ClassLoaderInfo.getCurrentResolvedClassInfo(mi.getReturnTypeName());