X-Git-Url: http://plrg.eecs.uci.edu/git/?p=jpf-core.git;a=blobdiff_plain;f=src%2Fpeers%2Fgov%2Fnasa%2Fjpf%2Fvm%2FJPF_java_lang_Class.java;h=ef0d782b998fb735dfa40828b1ed1c98600ace24;hp=90a5dcfef67e39c01dd8f165e1dfcc63b4f5500c;hb=8407476b0dce3b2c1d1a5093d55df109aa7f9789;hpb=a9bc9081ebda74eb6ee5451d2b719405db3a955c diff --git a/src/peers/gov/nasa/jpf/vm/JPF_java_lang_Class.java b/src/peers/gov/nasa/jpf/vm/JPF_java_lang_Class.java index 90a5dcf..ef0d782 100644 --- a/src/peers/gov/nasa/jpf/vm/JPF_java_lang_Class.java +++ b/src/peers/gov/nasa/jpf/vm/JPF_java_lang_Class.java @@ -17,15 +17,14 @@ */ package gov.nasa.jpf.vm; -import gov.nasa.jpf.Config; -import gov.nasa.jpf.annotation.MJI; - import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.Set; +import gov.nasa.jpf.Config; +import gov.nasa.jpf.annotation.MJI; /** * MJI NativePeer class for java.lang.Class library abstraction @@ -35,7 +34,7 @@ public class JPF_java_lang_Class extends NativePeer { static final String FIELD_CLASSNAME = "java.lang.reflect.Field"; static final String METHOD_CLASSNAME = "java.lang.reflect.Method"; static final String CONSTRUCTOR_CLASSNAME = "java.lang.reflect.Constructor"; - + public static boolean init (Config conf){ // we create Method and Constructor objects, so we better make sure these // classes are initialized (they already might be) @@ -107,6 +106,170 @@ public class JPF_java_lang_Class extends NativePeer { return MJIEnv.NULL; } } + + // TODO: Fix for Groovy's model-checking + private static int getParameterizedTypeImplObj(String[] parameterizedTypes, String ownerType, + MJIEnv env, int actObjRef, int rawObjRef) { + + ThreadInfo ti = env.getThreadInfo(); + ClassLoaderInfo cli = env.getSystemClassLoaderInfo(); + ClassInfo ci = cli.getResolvedClassInfo("sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl"); + // Create a new object of type ParameterizedTypeImpl + int paramTypeRef = env.newObject(ci); + ElementInfo ei = env.getModifiableElementInfo(paramTypeRef); + // Get field information and fill out the fields + // rawType field + ei.setReferenceField("rawType", rawObjRef); + + // actualTypeArguments + int[] types = new int[parameterizedTypes.length]; + for(int j = 0; j < parameterizedTypes.length; j++) { + types[j] = getTypeVariableImplObject(env, actObjRef, parameterizedTypes[j]); + } + int aRef = env.newObjectArray("Ljava/lang/reflect/Type;", parameterizedTypes.length); + // Set references for every array element + for (int j = 0; j < parameterizedTypes.length; j++) { + env.setReferenceArrayElement(aRef, j, types[j]); + } + ei.setReferenceField("actualTypeArguments", aRef); + + // ownerType + if (ownerType != null) { + ClassInfo oci = ClassLoaderInfo.getCurrentResolvedClassInfo(ownerType); + if (!oci.isRegistered()) { + oci.registerClass(ti); + } + ei.setReferenceField("ownerType", oci.getClassObjectRef()); + } else { + ei.setReferenceField("ownerType", MJIEnv.NULL); + } + + return paramTypeRef; + } + + private static int getTypeVariableImplObject(MJIEnv env, int objRef, String parameterizedType) { + + ClassLoaderInfo cli = env.getSystemClassLoaderInfo(); + ClassInfo ci = cli.getResolvedClassInfo("sun.reflect.generics.reflectiveObjects.TypeVariableImpl"); + + int typeVarRef = env.newObject(ci); + ElementInfo ei = env.getModifiableElementInfo(typeVarRef); + // genericDeclaration contains this java.lang.reflect.Method object + ei.setReferenceField("genericDeclaration", objRef); + ei.setReferenceField("name", env.newString(parameterizedType)); + + return typeVarRef; + } + + @MJI + public int getGenericSuperclass____Ljava_lang_reflect_Type_2 (MJIEnv env, int robj){ + ClassInfo ci = env.getReferredClassInfo( robj); + ClassInfo sci = ci.getSuperClass(); + if (sci != null) { + String[] typeVars = sci.getGenericTypeVariableNames(); + // Not a generic class + if (typeVars.length == 0) { + return sci.getClassObjectRef(); + } + String className = sci.getName(); + String ownerType = Types.getOwnerClassName(className); + int gRef = getParameterizedTypeImplObj(typeVars, ownerType, env, ci.getClassObjectRef(), sci.getClassObjectRef()); + + return gRef; + } else { + return MJIEnv.NULL; + } + } + + @MJI + public int getGenericInterfaces_____3Ljava_lang_reflect_Type_2 (MJIEnv env, int robj) { + ClassInfo ci = env.getReferredClassInfo(robj); + int aref = MJIEnv.NULL; + ThreadInfo ti = env.getThreadInfo(); + // contrary to the API doc, this only returns the interfaces directly + // implemented by this class, not it's bases + // <2do> this is not exactly correct, since the interfaces should be ordered + Set interfaces = ci.getInterfaceClassInfos(); + + aref = env.newObjectArray("Ljava/lang/Class;", interfaces.size()); + + int i=0; + for (ClassInfo ifc: interfaces){ + if (Types.isGenericSignature(ifc.getGenericSignature())) { + String className = ifc.getName(); + String ownerType = Types.getOwnerClassName(className); + String[] typeVars = ifc.getGenericTypeVariableNames(); + int paramTypeObj = getParameterizedTypeImplObj(typeVars, ownerType, env, ci.getClassObjectRef(), + ifc.getClassObjectRef()); + env.setReferenceArrayElement(aref, i++, paramTypeObj); + } else { + env.setReferenceArrayElement(aref, i++, ifc.getClassObjectRef()); + } + } + + return aref; + } + + @MJI + public int getTypeParameters_____3Ljava_lang_reflect_TypeVariable_2 (MJIEnv env, int robj){ + // Get the ClassInfo for this class + ClassInfo tci = env.getReferredClassInfo(robj); + String[] typeVars = tci.getGenericTypeVariableNames(); + + // Return with null if this is not a generic class + if (typeVars.length == 0) { + int aRef = env.newObjectArray("Ljava/lang/reflect/TypeVariable;", 0); + return aRef; + } + // Now create a TypeVariableImpl object for every type variable name; get the ClassInfo for TypeVariableImpl + ClassLoaderInfo cli = env.getSystemClassLoaderInfo(); + ClassInfo ci = cli.getResolvedClassInfo("sun.reflect.generics.reflectiveObjects.TypeVariableImpl"); + int[] var = new int[typeVars.length]; + + for(int i = 0; i < typeVars.length; i++) { + int typeVarRef = env.newObject(ci); + ElementInfo ei = env.getModifiableElementInfo(typeVarRef); + ei.setReferenceField("genericDeclaration", tci.getClassObjectRef()); + ei.setReferenceField("name", env.newString(typeVars[i])); + var[i] = typeVarRef; + } + int aRef = env.newObjectArray("Ljava/lang/reflect/TypeVariable;", typeVars.length); + + // Set references for every array element + for (int i = 0; i < typeVars.length; i++) { + env.setReferenceArrayElement(aRef, i, var[i]); + } + + return aRef; + } + + @MJI + public int getProtectionDomain____Ljava_security_ProtectionDomain_2 (MJIEnv env, int robj) { + // Now create a ProtectionDomain object + ClassLoaderInfo cli = env.getSystemClassLoaderInfo(); + ClassInfo pdci = cli.getResolvedClassInfo("java.security.ProtectionDomain"); + + int proDomRef = MJIEnv.NULL; + /* + TODO: Defer the following to future implementations + TODO: Currently Groovy runs well without actually instantiating a ProtectionDomain object properly + int proDomRef = env.newObject(pdci); + ElementInfo ei = env.getModifiableElementInfo(proDomRef); + ei.setReferenceField("codesource", MJIEnv.NULL); + ei.setReferenceField("classloader", MJIEnv.NULL); + ei.setBooleanField("hasAllPerm", true); + ei.setBooleanField("staticPermissions", true); + + // Load the Permission (AllPermission class) + ClassInfo pci = cli.getResolvedClassInfo("java.security.AllPermission"); + int permRef = env.newObject(pci); + ElementInfo pei = env.getModifiableElementInfo(permRef); + pei.setReferenceField("name", env.newString("")); + ei.setReferenceField("permissions", permRef);*/ + + return proDomRef; + } + // TODO: Fix for Groovy's model-checking @MJI public int getAnnotation__Ljava_lang_Class_2__Ljava_lang_annotation_Annotation_2 (MJIEnv env, int robj,