Fixing the ClassLoader.defineClass() method issue that could not find the necessary...
authorrtrimana <rtrimana@uci.edu>
Thu, 27 Jun 2019 19:42:35 +0000 (12:42 -0700)
committerrtrimana <rtrimana@uci.edu>
Thu, 27 Jun 2019 19:42:35 +0000 (12:42 -0700)
examples/ClassDemo.java
examples/SunClassLoader.java [new file with mode: 0644]
src/main/gov/nasa/jpf/vm/ClassLoaderInfo.java
src/peers/gov/nasa/jpf/vm/JPF_java_lang_ClassLoader.java

index 0a76996..d0e10a1 100644 (file)
@@ -2,10 +2,15 @@ import java.lang.*;
 import java.lang.reflect.*;
 import java.util.*;
 import java.math.*;
+import java.lang.ClassLoader;
 
 public class ClassDemo {
 
    public static void main(String[] args) throws Exception {
+   
+      ClassLoader cl = new ClassLoader();
+      byte[] bytes = new byte[150];
+      Class cls = cl.defineClass("sun.reflect.MagicAccessorImpl", bytes, 0, bytes.length);
 
       // returns an array of TypeVariable object
       TypeVariable[] tValue = List.class.getTypeParameters();
diff --git a/examples/SunClassLoader.java b/examples/SunClassLoader.java
new file mode 100644 (file)
index 0000000..195c3a6
--- /dev/null
@@ -0,0 +1,38 @@
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.MethodVisitor;
+
+import java.util.Map;
+import java.util.HashMap;
+
+/**
+ * Special class loader, which when running on Sun VM allows to generate accessor classes for any method
+ */
+public class SunClassLoader extends ClassLoader implements Opcodes {
+    private void loadMagic() {
+        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
+        cw.visit(Opcodes.V1_4, Opcodes.ACC_PUBLIC, "sun/reflect/GroovyMagic", null, "sun/reflect/MagicAccessorImpl", null);
+        MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
+        mv.visitCode();
+        mv.visitVarInsn(ALOAD, 0);
+        mv.visitMethodInsn(INVOKESPECIAL, "sun/reflect/MagicAccessorImpl", "<init>", "()V", false);
+        mv.visitInsn(RETURN);
+        mv.visitMaxs(0,0);
+        mv.visitEnd();
+        cw.visitEnd();
+
+        define(cw.toByteArray(), "sun.reflect.GroovyMagic");
+    }
+
+    protected void define(byte[] bytes, final String name) {
+        //knownClasses.put(name, defineClass(name, bytes, 0, bytes.length));
+        Class cls = defineClass(name, bytes, 0, bytes.length);
+    }
+
+    protected final Map<String,Class> knownClasses = new HashMap<String,Class>();
+
+    public static void main(String[] args) {
+        SunClassLoader sun = new SunClassLoader();
+        sun.loadMagic();
+    }
+}
index 07fbf5f..dec2423 100644 (file)
@@ -585,7 +585,12 @@ public class ClassLoaderInfo
           }          
         }
       }
-      
+      // TODO: Fix for Groovy's model-checking
+      // TODO: May need to do a recursive lookup
+      if (parent != null) {
+        return parent.loadClass(typeName);
+      }
+
       // initiate the roundtrip & bail out
       pushloadClassFrame(typeName);
       throw new LoadOnJPFRequired(typeName);
index 4fd6a25..136c12e 100644 (file)
@@ -144,9 +144,10 @@ public class JPF_java_lang_ClassLoader extends NativePeer {
     byte[] buffer = env.getByteArrayObject(bufferRef);
     
     try {
+
       ClassInfo ci = cl.getResolvedClassInfo( cname, buffer, offset, length);
 
-      // Note: if the representation is not of a supported major or minor version, loading 
+      // Note: if the representation is not of a supported major or minor version, loading
       // throws an UnsupportedClassVersionError. But for now, we do not check for this here 
       // since we don't do much with minor and major versions