[Jython-checkins] jython: Updated ASM to 5.0.3 for Java 8 support

jim.baker jython-checkins at python.org
Mon Jan 5 18:14:58 CET 2015


https://hg.python.org/jython/rev/cd3fe8336fb2
changeset:   7500:cd3fe8336fb2
user:        Jim Baker <jim.baker at rackspace.com>
date:        Mon Jan 05 10:14:22 2015 -0700
summary:
  Updated ASM to 5.0.3 for Java 8 support

Using ASM 4 to target Java 8 works for code generation, but not for
code introspection, such as analyzing jars or supporting Clamp. Fixed
by upgrading to ASM 5. Replaced Jython-specific code to analyze access
permissions from a classfile in favor of ASM.

For Jython developers working on code compilation: when emitting
bytecode, if you are visiting a method that's owned by an interface
(not implemented by a class), you need to use different
visitMethodInsn. See the change in CodeCompiler#visitWith - the only
change that was currently required.

Bumped bytecode magic.

files:
  build.xml                                                        |   12 +-
  extlibs/asm-4.0.jar                                              |  Bin 
  extlibs/asm-5.0.3.jar                                            |  Bin 
  extlibs/asm-commons-4.0.jar                                      |  Bin 
  extlibs/asm-commons-5.0.3.jar                                    |  Bin 
  extlibs/asm-util-4.0.jar                                         |  Bin 
  extlibs/asm-util-5.0.3.jar                                       |  Bin 
  src/org/python/compiler/Code.java                                |   18 +-
  src/org/python/compiler/CodeCompiler.java                        |    6 +-
  src/org/python/compiler/JavaMaker.java                           |    2 +-
  src/org/python/compiler/ProxyMaker.java                          |    2 +-
  src/org/python/core/AnnotationReader.java                        |   11 +-
  src/org/python/core/imp.java                                     |    2 +-
  src/org/python/core/packagecache/PackageManager.java             |   92 +++------
  src/org/python/expose/generate/ExposedFieldFinder.java           |    2 +-
  src/org/python/expose/generate/ExposedMethodFinder.java          |    2 +-
  src/org/python/expose/generate/ExposedTypeProcessor.java         |   17 +-
  src/org/python/expose/generate/Exposer.java                      |    6 +-
  src/org/python/expose/generate/RestrictiveAnnotationVisitor.java |    2 +-
  19 files changed, 76 insertions(+), 98 deletions(-)


diff --git a/build.xml b/build.xml
--- a/build.xml
+++ b/build.xml
@@ -150,9 +150,9 @@
             <pathelement path="${extlibs.dir}/antlr-3.1.3.jar" />
             <pathelement path="${extlibs.dir}/stringtemplate-3.2.1.jar" />
             <pathelement path="${extlibs.dir}/commons-compress-1.9.jar"/>
-            <pathelement path="${extlibs.dir}/asm-4.0.jar" />
-            <pathelement path="${extlibs.dir}/asm-commons-4.0.jar" />
-            <pathelement path="${extlibs.dir}/asm-util-4.0.jar" />
+            <pathelement path="${extlibs.dir}/asm-5.0.3.jar" />
+            <pathelement path="${extlibs.dir}/asm-commons-5.0.3.jar" />
+            <pathelement path="${extlibs.dir}/asm-util-5.0.3.jar" />
             <pathelement path="${extlibs.dir}/guava-18.0.jar" />
             <pathelement path="${extlibs.dir}/icu4j-54_1_1.jar" />
             <pathelement path="${extlibs.dir}/jffi-arm-Linux.jar"/>
@@ -576,9 +576,9 @@
             <zipfileset src="${dist.dir}/${jython.dev.jar}"/>
             <zipfileset src="extlibs/antlr-runtime-3.1.3.jar"/>
             <rule pattern="org.antlr.runtime.**" result="org.python.antlr.runtime. at 1"/>
-            <zipfileset src="extlibs/asm-4.0.jar"/>
-            <zipfileset src="extlibs/asm-commons-4.0.jar"/>
-            <zipfileset src="extlibs/asm-util-4.0.jar"/>
+            <zipfileset src="extlibs/asm-5.0.3.jar"/>
+            <zipfileset src="extlibs/asm-commons-5.0.3.jar"/>
+            <zipfileset src="extlibs/asm-util-5.0.3.jar"/>
             <rule pattern="org.objectweb.asm.**" result="org.python.objectweb.asm. at 1"/>
 	    <zipfileset src="extlibs/bcpkix-jdk15on-150.jar" excludes="META-INF/**"/>
 	    <rule pattern="org.bouncycastle.**" result="org.python.bouncycastle. at 1"/>
diff --git a/extlibs/asm-4.0.jar b/extlibs/asm-4.0.jar
deleted file mode 100644
index 6d63075eb7331f7120ef25603a2ade856d12f715..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
[stripped]
diff --git a/extlibs/asm-5.0.3.jar b/extlibs/asm-5.0.3.jar
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..573535b1d55acb9f787747dffb31231a0bcd9e59
GIT binary patch
[stripped]
diff --git a/extlibs/asm-commons-4.0.jar b/extlibs/asm-commons-4.0.jar
deleted file mode 100644
index 8d564b1e029e7b4f5c984c3fa67293ded9962e5b..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
[stripped]
diff --git a/extlibs/asm-commons-5.0.3.jar b/extlibs/asm-commons-5.0.3.jar
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..514a6dc2e1a8e94f0b6e32c2c8309300853a2110
GIT binary patch
[stripped]
diff --git a/extlibs/asm-util-4.0.jar b/extlibs/asm-util-4.0.jar
deleted file mode 100644
index 0e1059583543a10cde82abfcfe3fbde37347c8a7..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
[stripped]
diff --git a/extlibs/asm-util-5.0.3.jar b/extlibs/asm-util-5.0.3.jar
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..e89f1b7b67e54e57b7e9ce062537292676bafb19
GIT binary patch
[stripped]
diff --git a/src/org/python/compiler/Code.java b/src/org/python/compiler/Code.java
--- a/src/org/python/compiler/Code.java
+++ b/src/org/python/compiler/Code.java
@@ -22,7 +22,7 @@
     //XXX: I'd really like to get sig and access out of here since MethodVistitor
     //     should already have this information.
     public Code(MethodVisitor mv, String sig, int access) {
-        super(ASM4);
+        super(ASM5);
         this.mv = mv;
         this.sig = sig;
         nlocals = -sigSize(sig, false);
@@ -153,8 +153,8 @@
         mv.visitMaxs(arg0, arg1);
     }
 
-    public void visitMethodInsn(int arg0, String arg1, String arg2, String arg3) {
-        mv.visitMethodInsn(arg0, arg1, arg2, arg3);
+    public void visitMethodInsn(int arg0, String arg1, String arg2, String arg3, boolean itf) {
+        mv.visitMethodInsn(arg0, arg1, arg2, arg3, itf);
     }
 
     public void visitMultiANewArrayInsn(String arg0, int arg1) {
@@ -468,19 +468,23 @@
     }
 
     public void invokeinterface(String owner, String name, String type) {
-        mv.visitMethodInsn(INVOKEINTERFACE, owner, name, type);
+        mv.visitMethodInsn(INVOKEINTERFACE, owner, name, type, false);
+    }
+
+    public void invokeinterface(String owner, String name, String type, boolean itf) {
+        mv.visitMethodInsn(INVOKEINTERFACE, owner, name, type, itf);
     }
 
     public void invokespecial(String owner, String name, String type) {
-        mv.visitMethodInsn(INVOKESPECIAL, owner, name, type);
+        mv.visitMethodInsn(INVOKESPECIAL, owner, name, type, false);
     }
 
     public void invokestatic(String owner, String name, String type) {
-        mv.visitMethodInsn(INVOKESTATIC, owner, name, type);
+        mv.visitMethodInsn(INVOKESTATIC, owner, name, type, false);
     }
     
     public void invokevirtual(String owner, String name, String type) {
-        mv.visitMethodInsn(INVOKEVIRTUAL, owner, name, type);
+        mv.visitMethodInsn(INVOKEVIRTUAL, owner, name, type, false);
     }
     
     public void ireturn() {
diff --git a/src/org/python/compiler/CodeCompiler.java b/src/org/python/compiler/CodeCompiler.java
--- a/src/org/python/compiler/CodeCompiler.java
+++ b/src/org/python/compiler/CodeCompiler.java
@@ -2691,7 +2691,7 @@
         // value = mgr.__enter__()
         loadThreadState();
         code.invokeinterface(Type.getType(ContextManager.class).getInternalName(),
-                __enter__.getName(), __enter__.getDescriptor());
+                __enter__.getName(), __enter__.getDescriptor(), true);
         int value_tmp = code.getLocal(p(PyObject.class));
         code.astore(value_tmp);
 
@@ -2716,7 +2716,7 @@
                 loadThreadState();
                 compiler.code.aconst_null();
                 compiler.code.invokeinterface(Type.getType(ContextManager.class).getInternalName(),
-                        __exit__.getName(), __exit__.getDescriptor());
+                        __exit__.getName(), __exit__.getDescriptor(), true);
                 compiler.code.pop();
             }
         };
@@ -2761,7 +2761,7 @@
         loadThreadState();
         code.swap();
         code.invokeinterface(Type.getType(ContextManager.class).getInternalName(),
-                __exit__.getName(), __exit__.getDescriptor());
+                __exit__.getName(), __exit__.getDescriptor(), true);
 
         // # The exceptional case is handled here
         // exc = False # implicit
diff --git a/src/org/python/compiler/JavaMaker.java b/src/org/python/compiler/JavaMaker.java
--- a/src/org/python/compiler/JavaMaker.java
+++ b/src/org/python/compiler/JavaMaker.java
@@ -49,7 +49,7 @@
         code.visitLdcInsn(pythonClass);
         code.visitVarInsn(ALOAD, 1);
         code.visitMethodInsn(INVOKESTATIC, "org/python/core/Py", "initProxy",
-            makeSig("V", $pyProxy, $str, $str, $objArr));
+            makeSig("V", $pyProxy, $str, $str, $objArr), false);
         code.visitInsn(RETURN);
 
     }
diff --git a/src/org/python/compiler/ProxyMaker.java b/src/org/python/compiler/ProxyMaker.java
--- a/src/org/python/compiler/ProxyMaker.java
+++ b/src/org/python/compiler/ProxyMaker.java
@@ -729,7 +729,7 @@
     protected void callInitProxy(Class<?>[] parameters, Code code) throws Exception {
         code.visitVarInsn(ALOAD, 0);
         getArgs(code, parameters);
-        code.visitMethodInsn(INVOKEVIRTUAL, classfile.name, "__initProxy__", makeSig("V", $objArr));
+        code.visitMethodInsn(INVOKEVIRTUAL, classfile.name, "__initProxy__", makeSig("V", $objArr), false);
         code.visitInsn(RETURN);
     }
     
diff --git a/src/org/python/core/AnnotationReader.java b/src/org/python/core/AnnotationReader.java
--- a/src/org/python/core/AnnotationReader.java
+++ b/src/org/python/core/AnnotationReader.java
@@ -5,6 +5,7 @@
 package org.python.core;
 
 import java.io.IOException;
+import java.io.InputStream;
 
 import org.objectweb.asm.AnnotationVisitor;
 import org.objectweb.asm.ClassReader;
@@ -35,25 +36,23 @@
      * @throws IOException - if the classfile is malformed.
      */
     public AnnotationReader(byte[] data) throws IOException {
-        super(Opcodes.ASM4);
+        super(Opcodes.ASM5);
         ClassReader r;
         try {
             r = new ClassReader(data);
         } catch (ArrayIndexOutOfBoundsException e) {
-            IOException ioe = new IOException("Malformed bytecode: not enough data");
-            ioe.initCause(e);// IOException didn't grow a constructor that could take a cause till
-                             // 1.6, so do it the old fashioned way
+            IOException ioe = new IOException("Malformed bytecode: not enough data", e);
             throw ioe;
         }
         r.accept(this, 0);
     }
-    
+
     @Override
     public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
         nextVisitIsVersion = desc.equals("Lorg/python/compiler/APIVersion;");
         nextVisitIsMTime = desc.equals("Lorg/python/compiler/MTime;");
         nextVisitIsFilename = desc.equals("Lorg/python/compiler/Filename;");
-        return new AnnotationVisitor(Opcodes.ASM4) {
+        return new AnnotationVisitor(Opcodes.ASM5) {
 
         	public void visit(String name, Object value) {
         		if (nextVisitIsVersion) {
diff --git a/src/org/python/core/imp.java b/src/org/python/core/imp.java
--- a/src/org/python/core/imp.java
+++ b/src/org/python/core/imp.java
@@ -27,7 +27,7 @@
 
     private static final String UNKNOWN_SOURCEFILE = "<unknown>";
 
-    private static final int APIVersion = 35;
+    private static final int APIVersion = 36;
 
     public static final int NO_MTIME = -1;
 
diff --git a/src/org/python/core/packagecache/PackageManager.java b/src/org/python/core/packagecache/PackageManager.java
--- a/src/org/python/core/packagecache/PackageManager.java
+++ b/src/org/python/core/packagecache/PackageManager.java
@@ -3,13 +3,18 @@
 
 package org.python.core.packagecache;
 
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.Opcodes;
 import org.python.core.Py;
 import org.python.core.PyJavaPackage;
 import org.python.core.PyList;
 import org.python.core.PyObject;
 import org.python.core.PyStringMap;
+import org.python.core.util.FileUtil;
 
-import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
 
 /**
  * Abstract package manager.
@@ -164,73 +169,40 @@
         return p;
     }
 
+
+    private static class AccessVisitor extends ClassVisitor {
+
+        private int class_access;
+
+        public AccessVisitor() throws IOException {
+            super(Opcodes.ASM5);
+        }
+
+        @Override
+        public void visit(int version, int access, String name,
+                          String signature, String superName, String[] interfaces) {
+            class_access = access;
+        }
+
+        public int getClassAccess() {
+            return class_access;
+        }
+    }
+
     /**
      * Check that a given stream is a valid Java .class file. And return its
      * access permissions as an int.
      */
     static protected int checkAccess(java.io.InputStream cstream)
-            throws java.io.IOException {
-        java.io.DataInputStream istream = new java.io.DataInputStream(cstream);
-
+            throws IOException {
         try {
-            int magic = istream.readInt();
-            if (magic != 0xcafebabe) {
-                return -1;
-            }
-        } catch (EOFException eof) {
-            //Empty or 1 byte file.
+            ClassReader reader = new ClassReader(cstream);
+            AccessVisitor visitor = new AccessVisitor();
+            reader.accept(visitor, 0);
+            return visitor.getClassAccess();
+        } catch (RuntimeException e) {
             return -1;
         }
-        //int minor =
-        istream.readShort();
-        //int major =
-        istream.readShort();
-
-        // Check versions???
-        // System.out.println("magic: "+magic+", "+major+", "+minor);
-        int nconstants = istream.readShort();
-        for (int i = 1; i < nconstants; i++) {
-            int cid = istream.readByte();
-            // System.out.println(""+i+" : "+cid);
-            switch (cid) {
-            case 7:
-                istream.skipBytes(2);
-                break;
-            case 9:
-            case 10:
-            case 11:
-                istream.skipBytes(4);
-                break;
-            case 8:
-                istream.skipBytes(2);
-                break;
-            case 3:
-            case 4:
-                istream.skipBytes(4);
-                break;
-            case 5:
-            case 6:
-                istream.skipBytes(8);
-                i++;
-                break;
-            case 12:
-                istream.skipBytes(4);
-                break;
-            case 1:
-                // System.out.println("utf: "+istream.readUTF()+";");
-                int slength = istream.readUnsignedShort();
-                istream.skipBytes(slength);
-                break;
-            default:
-                // System.err.println("unexpected cid: "+cid+", "+i+", "+
-                // nconstants);
-                // for (int j=0; j<10; j++)
-                // System.err.print(", "+istream.readByte());
-                // System.err.println();
-                return -1;
-            }
-        }
-        return istream.readShort();
     }
 
 }
diff --git a/src/org/python/expose/generate/ExposedFieldFinder.java b/src/org/python/expose/generate/ExposedFieldFinder.java
--- a/src/org/python/expose/generate/ExposedFieldFinder.java
+++ b/src/org/python/expose/generate/ExposedFieldFinder.java
@@ -14,7 +14,7 @@
     private String doc;
 
     public ExposedFieldFinder(String name, FieldVisitor delegate) {
-        super(Opcodes.ASM4);
+        super(Opcodes.ASM5);
         fieldName = name;
         this.delegate = delegate;
     }
diff --git a/src/org/python/expose/generate/ExposedMethodFinder.java b/src/org/python/expose/generate/ExposedMethodFinder.java
--- a/src/org/python/expose/generate/ExposedMethodFinder.java
+++ b/src/org/python/expose/generate/ExposedMethodFinder.java
@@ -35,7 +35,7 @@
                                String desc,
                                String[] exceptions,
                                MethodVisitor delegate) {
-        super(Opcodes.ASM4, delegate);
+        super(Opcodes.ASM5, delegate);
         this.typeName = typeName;
         this.onType = onType;
         this.access = access;
diff --git a/src/org/python/expose/generate/ExposedTypeProcessor.java b/src/org/python/expose/generate/ExposedTypeProcessor.java
--- a/src/org/python/expose/generate/ExposedTypeProcessor.java
+++ b/src/org/python/expose/generate/ExposedTypeProcessor.java
@@ -114,7 +114,7 @@
         private boolean generatedStaticBlock;
 
         private TypeProcessor(ClassVisitor cv) {
-            super(Opcodes.ASM4, cv);
+            super(Opcodes.ASM5, cv);
         }
 
         @Override
@@ -194,11 +194,14 @@
                     .replace('.', '/'));
             mv.visitTypeInsn(NEW, typeExposerType.getInternalName());
             mv.visitInsn(DUP);
-            mv.visitMethodInsn(INVOKESPECIAL, typeExposerType.getInternalName(), "<init>", "()V");
-            mv.visitMethodInsn(INVOKESTATIC,
-                               PYTYPE.getInternalName(),
-                               "addBuilder",
-                               Type.getMethodDescriptor(VOID, new Type[] {CLASS, TYPEBUILDER}));
+            mv.visitMethodInsn(
+                    INVOKESPECIAL, typeExposerType.getInternalName(), "<init>", "()V", false);
+            mv.visitMethodInsn(
+                    INVOKESTATIC,
+                    PYTYPE.getInternalName(),
+                    "addBuilder",
+                    Type.getMethodDescriptor(VOID, new Type[]{CLASS, TYPEBUILDER}),
+                    false);
         }
 
         /** Adds an inner class reference to inner from the class being visited. */
@@ -225,7 +228,7 @@
                                                                            desc,
                                                                            signature,
                                                                            exceptions);
-                return new MethodVisitor(Opcodes.ASM4, passthroughVisitor) {
+                return new MethodVisitor(Opcodes.ASM5, passthroughVisitor) {
 
                     @Override
                     public void visitCode() {
diff --git a/src/org/python/expose/generate/Exposer.java b/src/org/python/expose/generate/Exposer.java
--- a/src/org/python/expose/generate/Exposer.java
+++ b/src/org/python/expose/generate/Exposer.java
@@ -160,7 +160,7 @@
         mv.visitMethodInsn(INVOKESPECIAL,
                            onType.getInternalName(),
                            "<init>",
-                           methodDesc(VOID, args));
+                           methodDesc(VOID, args), false);
     }
 
     /** Calls the method on onType with the given return type and argument types. */
@@ -168,7 +168,7 @@
         mv.visitMethodInsn(INVOKEVIRTUAL,
                            onType.getInternalName(),
                            methodName,
-                           methodDesc(returnType, args));
+                           methodDesc(returnType, args), false);
     }
 
     /** Calls the static method on onType with the given return type and argument types. */
@@ -176,7 +176,7 @@
         mv.visitMethodInsn(INVOKESTATIC,
                            onType.getInternalName(),
                            methodName,
-                           methodDesc(returnType, args));
+                           methodDesc(returnType, args), false);
     }
 
     /** Produces a method descriptor with ret as its return type that takes args. */
diff --git a/src/org/python/expose/generate/RestrictiveAnnotationVisitor.java b/src/org/python/expose/generate/RestrictiveAnnotationVisitor.java
--- a/src/org/python/expose/generate/RestrictiveAnnotationVisitor.java
+++ b/src/org/python/expose/generate/RestrictiveAnnotationVisitor.java
@@ -10,7 +10,7 @@
 public class RestrictiveAnnotationVisitor extends AnnotationVisitor {
 
     public RestrictiveAnnotationVisitor() {
-        super(Opcodes.ASM4);
+        super(Opcodes.ASM5);
     }
 
     public AnnotationVisitor visitAnnotation(String name, String desc) {

-- 
Repository URL: https://hg.python.org/jython


More information about the Jython-checkins mailing list