You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by db...@apache.org on 2013/12/04 01:43:18 UTC

svn commit: r1547656 - in /commons/proper/bcel/trunk/src/main/java/org/apache/bcel: ./ classfile/ generic/ util/

Author: dbrosius
Date: Wed Dec  4 00:43:17 2013
New Revision: 1547656

URL: http://svn.apache.org/r1547656
Log:
initial support for INVOKE_DYNAMIC. Patch by Bill Pugh, reviewed by dbrosius

Added:
    commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/INVOKEDYNAMIC.java
    commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/VisitorSupportsInvokeDynamic.java
Modified:
    commons/proper/bcel/trunk/src/main/java/org/apache/bcel/Constants.java
    commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/Utility.java
    commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/EmptyVisitor.java
    commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/Instruction.java
    commons/proper/bcel/trunk/src/main/java/org/apache/bcel/util/ClassPath.java

Modified: commons/proper/bcel/trunk/src/main/java/org/apache/bcel/Constants.java
URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/main/java/org/apache/bcel/Constants.java?rev=1547656&r1=1547655&r2=1547656&view=diff
==============================================================================
--- commons/proper/bcel/trunk/src/main/java/org/apache/bcel/Constants.java (original)
+++ commons/proper/bcel/trunk/src/main/java/org/apache/bcel/Constants.java Wed Dec  4 00:43:17 2013
@@ -281,8 +281,8 @@ public interface Constants {
     "CONSTANT_Float", "CONSTANT_Long", "CONSTANT_Double",
     "CONSTANT_Class", "CONSTANT_String", "CONSTANT_Fieldref",
     "CONSTANT_Methodref", "CONSTANT_InterfaceMethodref",
-    "CONSTANT_NameAndType", "CONSTANT_MethodHandle",
-    "CONSTANT_MethodType", "CONSTANT_InvokeDynamic" };
+    "CONSTANT_NameAndType", "", "", "CONSTANT_MethodHandle",
+    "CONSTANT_MethodType", "", "CONSTANT_InvokeDynamic" };
 
   /** The name of the static initializer, also called "class
    *  initialization method" or "interface initialization
@@ -1170,7 +1170,7 @@ public interface Constants {
     0/*dreturn*/, 0/*areturn*/, 0/*return*/,
     2/*getstatic*/, 2/*putstatic*/, 2/*getfield*/,
     2/*putfield*/, 2/*invokevirtual*/, 2/*invokespecial*/, 2/*invokestatic*/,
-    4/*invokeinterface*/, UNDEFINED, 2/*new*/,
+    4/*invokeinterface*/, 5/*invokedynamic*/, 2/*new*/,
     1/*newarray*/, 2/*anewarray*/,
     0/*arraylength*/, 0/*athrow*/, 2/*checkcast*/,
     2/*instanceof*/, 0/*monitorenter*/,
@@ -1243,7 +1243,7 @@ public interface Constants {
     {T_SHORT}/*putstatic*/, {T_SHORT}/*getfield*/,
     {T_SHORT}/*putfield*/, {T_SHORT}/*invokevirtual*/,
     {T_SHORT}/*invokespecial*/, {T_SHORT}/*invokestatic*/,
-    {T_SHORT, T_BYTE, T_BYTE}/*invokeinterface*/, {},
+    {T_SHORT, T_BYTE, T_BYTE}/*invokeinterface*/, {T_SHORT, T_BYTE, T_BYTE}/*invokedynamic*/,
     {T_SHORT}/*new*/, {T_BYTE}/*newarray*/,
     {T_SHORT}/*anewarray*/, {}/*arraylength*/, {}/*athrow*/,
     {T_SHORT}/*checkcast*/, {T_SHORT}/*instanceof*/,
@@ -1290,7 +1290,7 @@ public interface Constants {
     "tableswitch", "lookupswitch", "ireturn", "lreturn", "freturn",
     "dreturn", "areturn", "return", "getstatic", "putstatic", "getfield",
     "putfield", "invokevirtual", "invokespecial", "invokestatic",
-    "invokeinterface", ILLEGAL_OPCODE, "new", "newarray", "anewarray",
+    "invokeinterface", "invokedynamic", "new", "newarray", "anewarray",
     "arraylength", "athrow", "checkcast", "instanceof", "monitorenter",
     "monitorexit", "wide", "multianewarray", "ifnull", "ifnonnull",
     "goto_w", "jsr_w", "breakpoint", ILLEGAL_OPCODE, ILLEGAL_OPCODE,
@@ -1346,7 +1346,7 @@ public interface Constants {
     UNPREDICTABLE/*putstatic*/, 1/*getfield*/, UNPREDICTABLE/*putfield*/,
     UNPREDICTABLE/*invokevirtual*/, UNPREDICTABLE/*invokespecial*/,
     UNPREDICTABLE/*invokestatic*/,
-    UNPREDICTABLE/*invokeinterface*/, UNDEFINED, 0/*new*/, 1/*newarray*/, 1/*anewarray*/,
+    UNPREDICTABLE/*invokeinterface*/, UNPREDICTABLE/*invokedynamic*/, 0/*new*/, 1/*newarray*/, 1/*anewarray*/,
     1/*arraylength*/, 1/*athrow*/, 1/*checkcast*/, 1/*instanceof*/, 1/*monitorenter*/,
     1/*monitorexit*/, 0/*wide*/, UNPREDICTABLE/*multianewarray*/, 1/*ifnull*/, 1/*ifnonnull*/,
     0/*goto_w*/, 0/*jsr_w*/, 0/*breakpoint*/, UNDEFINED, UNDEFINED,
@@ -1402,7 +1402,7 @@ public interface Constants {
     0/*dreturn*/, 0/*areturn*/, 0/*return*/, UNPREDICTABLE/*getstatic*/, 0/*putstatic*/,
     UNPREDICTABLE/*getfield*/, 0/*putfield*/, UNPREDICTABLE/*invokevirtual*/,
     UNPREDICTABLE/*invokespecial*/, UNPREDICTABLE/*invokestatic*/,
-    UNPREDICTABLE/*invokeinterface*/, UNDEFINED, 1/*new*/, 1/*newarray*/, 1/*anewarray*/,
+    UNPREDICTABLE/*invokeinterface*/, UNPREDICTABLE/*invokedynamic*/, 1/*new*/, 1/*newarray*/, 1/*anewarray*/,
     1/*arraylength*/, 1/*athrow*/, 1/*checkcast*/, 1/*instanceof*/, 0/*monitorenter*/,
     0/*monitorexit*/, 0/*wide*/, 1/*multianewarray*/, 0/*ifnull*/, 0/*ifnonnull*/,
     0/*goto_w*/, 1/*jsr_w*/, 0/*breakpoint*/, UNDEFINED, UNDEFINED,

Modified: commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/Utility.java
URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/Utility.java?rev=1547656&r1=1547655&r2=1547656&view=diff
==============================================================================
--- commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/Utility.java (original)
+++ commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/Utility.java Wed Dec  4 00:43:17 2013
@@ -347,8 +347,11 @@ public abstract class Utility {
             case Constants.INVOKESTATIC:
             case Constants.INVOKEVIRTUAL:
                 index = bytes.readUnsignedShort();
+                Constant c = constant_pool.getConstant(index);
+                if (c.getTag() != Constants.CONSTANT_Methodref && c.getTag() != Constants.CONSTANT_InterfaceMethodref)
+                	    throw new ClassFormatException("Expected class `CONSTANT_Methodref' or 'CONSTANT_InterfaceMethodref' at index " + index + " and got " +c);
                 buf.append("\t").append(
-                        constant_pool.constantToString(index, Constants.CONSTANT_Methodref))
+                        constant_pool.constantToString(c))
                         .append((verbose ? " (" + index + ")" : ""));
                 break;
             case Constants.INVOKEINTERFACE:
@@ -360,6 +363,16 @@ public abstract class Utility {
                         .append(verbose ? " (" + index + ")\t" : "").append(nargs).append("\t")
                         .append(bytes.readUnsignedByte()); // Last byte is a reserved space
                 break;
+            case Constants.INVOKEDYNAMIC:
+                index = bytes.readUnsignedShort();
+                int ignored = bytes.readUnsignedShort(); 
+                ConstantInvokeDynamic id = (ConstantInvokeDynamic) constant_pool.getConstant(index, Constants.CONSTANT_InvokeDynamic);
+                buf.append("\t").append("<dyn>.").append(
+                        constant_pool
+                                .constantToString(id.getNameAndTypeIndex(), Constants.CONSTANT_NameAndType));
+                if (verbose)
+                        buf.append(" (" + index + "/" + id.getNameAndTypeIndex() +")");
+                break;
             /* Operands are references to items in constant pool
              */
             case Constants.LDC_W:

Modified: commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/EmptyVisitor.java
URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/EmptyVisitor.java?rev=1547656&r1=1547655&r2=1547656&view=diff
==============================================================================
--- commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/EmptyVisitor.java (original)
+++ commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/EmptyVisitor.java Wed Dec  4 00:43:17 2013
@@ -23,7 +23,7 @@ package org.apache.bcel.generic;
  * @version $Id$
  * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
  */
-public abstract class EmptyVisitor implements Visitor {
+public abstract class EmptyVisitor implements VisitorSupportsInvokeDynamic {
 
     public void visitStackInstruction( StackInstruction obj ) {
     }
@@ -743,4 +743,8 @@ public abstract class EmptyVisitor imple
 
     public void visitBREAKPOINT( BREAKPOINT obj ) {
     }
+
+
+	public void visitINVOKEDYNAMIC(INVOKEDYNAMIC obj) {
+	}
 }

Added: commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/INVOKEDYNAMIC.java
URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/INVOKEDYNAMIC.java?rev=1547656&view=auto
==============================================================================
--- commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/INVOKEDYNAMIC.java (added)
+++ commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/INVOKEDYNAMIC.java Wed Dec  4 00:43:17 2013
@@ -0,0 +1,191 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License. 
+ *
+ */
+package org.apache.bcel.generic;
+
+import java.io.IOException;
+import java.util.StringTokenizer;
+
+import org.apache.bcel.Constants;
+import org.apache.bcel.ExceptionConstants;
+import org.apache.bcel.classfile.Constant;
+import org.apache.bcel.classfile.ConstantCP;
+import org.apache.bcel.classfile.ConstantInvokeDynamic;
+import org.apache.bcel.classfile.ConstantNameAndType;
+import org.apache.bcel.classfile.ConstantPool;
+import org.apache.bcel.classfile.ConstantUtf8;
+import org.apache.bcel.util.ByteSequence;
+
+/**
+ * Class for INVOKEDYNAMIC. Not an instance of InvokeInstruction, since that class
+ * expects to be able to get the class of the method. Ignores the bootstrap
+ * mechanism entirely.
+ *
+ * @version $Id: InvokeInstruction.java 1152072 2011-07-29 01:54:05Z dbrosius $
+ * @author  Bill Pugh
+ */
+public class INVOKEDYNAMIC extends FieldOrMethod implements ExceptionThrower,
+        StackConsumer, StackProducer {
+
+    private static final long serialVersionUID = 1L;
+
+
+    /**
+     * Empty constructor needed for the Class.newInstance() statement in
+     * Instruction.readInstruction(). Not to be used otherwise.
+     */
+    INVOKEDYNAMIC() {
+    }
+
+
+    /**
+     * @param index to constant pool
+     */
+    public INVOKEDYNAMIC(short opcode, int index) {
+        super(opcode, index);
+    }
+
+
+    /**
+     * @return mnemonic for instruction with symbolic references resolved
+     */
+    @Override
+    public String toString( ConstantPool cp ) {
+        Constant c = cp.getConstant(index);
+        StringTokenizer tok = new StringTokenizer(cp.constantToString(c));
+        return Constants.OPCODE_NAMES[opcode] + " " + tok.nextToken().replace('.', '/')
+                + tok.nextToken();
+    }
+
+    public ConstantNameAndType getNameAndType( ConstantPoolGen cpg ) {
+        ConstantPool cp = cpg.getConstantPool();
+        ConstantInvokeDynamic id = (ConstantInvokeDynamic) cp.getConstant(index);
+        return (ConstantNameAndType) cp.getConstant(id.getNameAndTypeIndex());
+     }
+    
+    /** @return signature of referenced method/field.
+     */
+    public String getSignature( ConstantPoolGen cpg ) {
+    	    ConstantPool cp = cpg.getConstantPool();
+        ConstantNameAndType cnat = getNameAndType(cpg);
+        return ((ConstantUtf8) cp.getConstant(cnat.getSignatureIndex())).getBytes();
+    }
+
+    /** @return name of referenced method/field.
+     */
+    public String getName( ConstantPoolGen cpg ) {
+         ConstantPool cp = cpg.getConstantPool();
+         ConstantNameAndType cnat = getNameAndType(cpg);
+         return ((ConstantUtf8) cp.getConstant(cnat.getNameIndex())).getBytes();
+    }
+
+    /**
+     * Also works for instructions whose stack effect depends on the
+     * constant pool entry they reference.
+     * @return Number of words consumed from stack by this instruction
+     */
+    @Override
+    public int consumeStack( ConstantPoolGen cpg ) {
+
+        String signature = getSignature(cpg);
+        return  Type.getArgumentTypesSize(signature);
+    }
+
+
+    /**
+     * Also works for instructions whose stack effect depends on the
+     * constant pool entry they reference.
+     * @return Number of words produced onto stack by this instruction
+     */
+    @Override
+    public int produceStack( ConstantPoolGen cpg ) {
+    	String signature = getSignature(cpg);
+    	return Type.getReturnTypeSize(signature);
+    }
+
+
+    /** @return return type of referenced method.
+     */
+    @Override
+    public Type getType( ConstantPoolGen cpg ) {
+        return getReturnType(cpg);
+    }
+
+
+    /** @return name of referenced method.
+     */
+    public String getMethodName( ConstantPoolGen cpg ) {
+        return getName(cpg);
+    }
+
+
+    /** @return return type of referenced method.
+     */
+    public Type getReturnType( ConstantPoolGen cpg ) {
+        return Type.getReturnType(getSignature(cpg));
+    }
+
+
+    /** @return argument types of referenced method.
+     */
+    public Type[] getArgumentTypes( ConstantPoolGen cpg ) {
+        return Type.getArgumentTypes(getSignature(cpg));
+    }
+    
+    /**
+     * Read needed data (i.e., index) from file.
+     */
+    @Override
+    protected void initFromFile( ByteSequence bytes, boolean wide ) throws IOException {
+        super.initFromFile(bytes, wide);
+        length = 5;
+        bytes.readUnsignedShort();
+    }
+
+    public Class<?>[] getExceptions() {
+        Class<?>[] cs = new Class[4 + ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION.length];
+        System.arraycopy(ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION, 0, cs, 0,
+                ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION.length);
+        cs[ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION.length + 3] = ExceptionConstants.INCOMPATIBLE_CLASS_CHANGE_ERROR;
+        cs[ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION.length + 2] = ExceptionConstants.ILLEGAL_ACCESS_ERROR;
+        cs[ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION.length + 1] = ExceptionConstants.ABSTRACT_METHOD_ERROR;
+        cs[ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION.length] = ExceptionConstants.UNSATISFIED_LINK_ERROR;
+        return cs;
+    }
+
+
+    /**
+     * Call corresponding visitor method(s). The order is:
+     * Call visitor methods of implemented interfaces first, then
+     * call methods according to the class hierarchy in descending order,
+     * i.e., the most specific visitXXX() call comes last.
+     *
+     * @param v Visitor object
+     */
+    @Override
+    public void accept( Visitor v ) {
+        v.visitExceptionThrower(this);
+        v.visitTypedInstruction(this);
+        v.visitStackConsumer(this);
+        v.visitStackProducer(this);
+        v.visitLoadClass(this);
+        v.visitCPInstruction(this);
+        v.visitFieldOrMethod(this);
+        if (v instanceof VisitorSupportsInvokeDynamic) 
+            ((VisitorSupportsInvokeDynamic)v).visitINVOKEDYNAMIC(this);
+    }
+}

Modified: commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/Instruction.java
URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/Instruction.java?rev=1547656&r1=1547655&r2=1547656&view=diff
==============================================================================
--- commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/Instruction.java (original)
+++ commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/Instruction.java Wed Dec  4 00:43:17 2013
@@ -20,6 +20,7 @@ package org.apache.bcel.generic;
 import java.io.DataOutputStream;
 import java.io.IOException;
 import java.io.Serializable;
+
 import org.apache.bcel.Constants;
 import org.apache.bcel.classfile.ConstantPool;
 import org.apache.bcel.util.ByteSequence;
@@ -407,6 +408,9 @@ public abstract class Instruction implem
 			case Constants.INVOKEINTERFACE:
 				obj = new INVOKEINTERFACE();
 				break;
+			case Constants.INVOKEDYNAMIC:
+				obj = new INVOKEDYNAMIC();
+				break;
 			case Constants.NEW:
 				obj = new NEW();
 				break;

Added: commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/VisitorSupportsInvokeDynamic.java
URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/VisitorSupportsInvokeDynamic.java?rev=1547656&view=auto
==============================================================================
--- commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/VisitorSupportsInvokeDynamic.java (added)
+++ commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/VisitorSupportsInvokeDynamic.java Wed Dec  4 00:43:17 2013
@@ -0,0 +1,7 @@
+package org.apache.bcel.generic;
+
+public interface VisitorSupportsInvokeDynamic extends Visitor{
+
+
+	void visitINVOKEDYNAMIC(INVOKEDYNAMIC obj);
+}

Modified: commons/proper/bcel/trunk/src/main/java/org/apache/bcel/util/ClassPath.java
URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/main/java/org/apache/bcel/util/ClassPath.java?rev=1547656&r1=1547655&r2=1547656&view=diff
==============================================================================
--- commons/proper/bcel/trunk/src/main/java/org/apache/bcel/util/ClassPath.java (original)
+++ commons/proper/bcel/trunk/src/main/java/org/apache/bcel/util/ClassPath.java Wed Dec  4 00:43:17 2013
@@ -86,7 +86,8 @@ public class ClassPath implements Serial
                         }
                     }
                 } catch (IOException e) {
-                    System.err.println("CLASSPATH component " + file + ": " + e);
+                    if (path.endsWith(".zip") || path.endsWith(".jar"))
+                        System.err.println("CLASSPATH component " + file + ": " + e);
                 }
             }
         }