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);
}
}
}