Author: chas Date: Sun Jul 19 21:10:46 2015 New Revision: 1691855 URL: http://svn.apache.org/r1691855 Log: BCEL-209 Bug fixes and improvements to InvokeDynamic and BootStrapMethods implementation
Modified: commons/proper/bcel/trunk/src/changes/changes.xml commons/proper/bcel/trunk/src/main/java/org/apache/bcel/Constants.java commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/BootstrapMethod.java commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/BootstrapMethods.java commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/ConstantCP.java commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/ConstantInvokeDynamic.java commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/ConstantPool.java commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/DescendingVisitor.java commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/EmptyVisitor.java commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/Utility.java commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/Visitor.java commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/ConstantPoolGen.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/FieldOrMethod.java commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/GETFIELD.java commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/GETSTATIC.java commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/INVOKEDYNAMIC.java commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/INVOKEINTERFACE.java commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/INVOKESPECIAL.java commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/INVOKESTATIC.java commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/INVOKEVIRTUAL.java commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/InstructionFactory.java commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/InvokeInstruction.java commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/PUTFIELD.java commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/PUTSTATIC.java commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/Visitor.java commons/proper/bcel/trunk/src/main/java/org/apache/bcel/util/CodeHTML.java commons/proper/bcel/trunk/src/main/java/org/apache/bcel/util/InstructionFinder.java commons/proper/bcel/trunk/src/main/java/org/apache/bcel/verifier/statics/Pass3aVerifier.java commons/proper/bcel/trunk/src/main/java/org/apache/bcel/verifier/structurals/ExecutionVisitor.java commons/proper/bcel/trunk/src/main/java/org/apache/bcel/verifier/structurals/InstConstraintVisitor.java commons/proper/bcel/trunk/src/test/java/org/apache/bcel/visitors/CounterVisitor.java Modified: commons/proper/bcel/trunk/src/changes/changes.xml URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/changes/changes.xml?rev=1691855&r1=1691854&r2=1691855&view=diff ============================================================================== --- commons/proper/bcel/trunk/src/changes/changes.xml (original) +++ commons/proper/bcel/trunk/src/changes/changes.xml Sun Jul 19 21:10:46 2015 @@ -63,6 +63,9 @@ The <action> type attribute can be add,u <body> <release version="6.0" date="TBA" description="Major release with Java 7 and 8 support"> + <action issue="BCEL-209" type="fix" due-to="Mark Roberts"> + Bug fixes and improvements to InvokeDynamic and BootStrapMethods implementation + </action> <action issue="BCEL-187" type="fix" due-to="Jérôme Leroux"> Verification error when an invoke references a method defined in superclass </action> 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=1691855&r1=1691854&r2=1691855&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 Sun Jul 19 21:10:46 2015 @@ -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*/, 5/*invokedynamic*/, 2/*new*/, + 4/*invokeinterface*/, 4/*invokedynamic*/, 2/*new*/, 1/*newarray*/, 2/*anewarray*/, 0/*arraylength*/, 0/*athrow*/, 2/*checkcast*/, 2/*instanceof*/, 0/*monitorenter*/, @@ -1525,9 +1525,9 @@ public static final byte ATTR_RUNTIMEINV public static final byte REF_newInvokeSpecial = 8; public static final byte REF_invokeInterface = 9; - public static final String[] REF_NAMES = { - "getfield", "getstatic", "putfield", - "putstatic", "invokevirtual", "invokestatic", - "invokespecial", "new dup invokespecial", "invokeinterface" - }; + /** The names of the referencd_kinds of a CONSTANT_MethodHandle_info. */ + public static final String[] METHODHANDLE_NAMES = { + "", "getField", "getStatic", "putField", "putStatic", "invokeVirtual", + "invokeStatic", "invokeSpecial", "newInvokeSpecial", "invokeInterface" }; + } Modified: commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/BootstrapMethod.java URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/BootstrapMethod.java?rev=1691855&r1=1691854&r2=1691855&view=diff ============================================================================== --- commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/BootstrapMethod.java (original) +++ commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/BootstrapMethod.java Sun Jul 19 21:10:46 2015 @@ -22,8 +22,12 @@ import java.io.DataOutputStream; import java.io.IOException; import java.io.Serializable; +import org.apache.bcel.Constants; + /** - * Entry of the bootstrap_methods table. + * This class represents a bootstrap method attribute, i.e., the bootstrap + * method ref, the number of bootstrap arguments and an array of the + * bootstrap arguments. * * @see <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.23">The class File Format : The BootstrapMethods Attribute</a> * @since 6.0 @@ -35,10 +39,17 @@ public class BootstrapMethod implements /** Index of the CONSTANT_MethodHandle_info structure in the constant_pool table */ private int bootstrap_method_ref; + private int num_bootstrap_arguments; + /** Array of references to the constant_pool table */ private int[] bootstrap_arguments; - public BootstrapMethod() { + + /** + * Initialize from another object. + */ + public BootstrapMethod(BootstrapMethod c) { + this(c.getBootstrapMethodRef(), c.getNumBootstrapArguments(), c.getBootstrapArguments()); } /** @@ -46,37 +57,95 @@ public class BootstrapMethod implements * * @param input Input stream * @throws IOException - * @throws ClassFormatException */ - BootstrapMethod(DataInput input) throws IOException, ClassFormatException { - bootstrap_method_ref = input.readUnsignedShort(); + BootstrapMethod(DataInput input) throws IOException { + this(input.readUnsignedShort(), input.readUnsignedShort(), (int[]) null); - int num_bootstrap_methods = input.readUnsignedShort(); - - bootstrap_arguments = new int[num_bootstrap_methods]; - for (int i = 0; i < num_bootstrap_methods; i++) { + bootstrap_arguments = new int[num_bootstrap_arguments]; + for (int i = 0; i < num_bootstrap_arguments; i++) { bootstrap_arguments[i] = input.readUnsignedShort(); } } + + /** + * @param bootstrap_method_ref int index into constant_pool of CONSTANT_MethodHandle + * @param num_bootstrap_arguments int count of number of boostrap arguments + * @param bootstrap_arguments int[] indices into constant_pool of CONSTANT_<type>_info + */ + public BootstrapMethod(int bootstrap_method_ref, int num_bootstrap_arguments, int[] bootstrap_arguments) { + this.bootstrap_method_ref = bootstrap_method_ref; + this.num_bootstrap_arguments = num_bootstrap_arguments; + this.bootstrap_arguments = bootstrap_arguments; + } + + /** + * @return index into constant_pool of bootstrap_method + */ public int getBootstrapMethodRef() { return bootstrap_method_ref; } + /** + * @param bootstrap_method_ref int index into constant_pool of CONSTANT_MethodHandle + */ public void setBootstrapMethodRef(int bootstrap_method_ref) { this.bootstrap_method_ref = bootstrap_method_ref; } + /** + * @return int[] of bootstrap_method indices into constant_pool of CONSTANT_<type>_info + */ public int[] getBootstrapArguments() { return bootstrap_arguments; } + /** + * @return count of number of boostrap arguments + */ + public int getNumBootstrapArguments() { + return num_bootstrap_arguments; + } + + /** + * @param bootstrap_arguments int[] indices into constant_pool of CONSTANT_<type>_info + */ public void setBootstrapArguments(int[] bootstrap_arguments) { this.bootstrap_arguments = bootstrap_arguments; } /** - * Dump object to file stream on binary format. + * @return String representation. + */ + @Override + public final String toString() { + return "BootstrapMethod(" + bootstrap_method_ref + ", " + num_bootstrap_arguments + ", " + //UNDONE + //+ bootstrap_arguments + ")"; + + "UNDONE)"; + } + + /** + * @return Resolved string representation + */ + public final String toString( ConstantPool constant_pool ) { + StringBuilder buf = new StringBuilder(); + String bootstrap_method_name; + bootstrap_method_name = constant_pool.constantToString(bootstrap_method_ref, + Constants.CONSTANT_MethodHandle); + buf.append(Utility.compactClassName(bootstrap_method_name)); + if (num_bootstrap_arguments > 0) { + buf.append("\n Method Arguments:"); + for (int i = 0; i < num_bootstrap_arguments; i++) { + buf.append("\n ").append(i).append(": "); + buf.append(constant_pool.constantToString(constant_pool.getConstant(bootstrap_arguments[i]))); + } + } + return buf.toString(); + } + + /** + * Dump object to file stream in binary format. * * @param file Output file stream * @throws IOException Modified: commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/BootstrapMethods.java URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/BootstrapMethods.java?rev=1691855&r1=1691854&r2=1691855&view=diff ============================================================================== --- commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/BootstrapMethods.java (original) +++ commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/BootstrapMethods.java Sun Jul 19 21:10:46 2015 @@ -35,11 +35,35 @@ public class BootstrapMethods extends At private BootstrapMethod[] bootstrap_methods; + /** + * Initialize from another object. Note that both objects use the same + * references (shallow copy). Use clone() for a physical copy. + */ + public BootstrapMethods(BootstrapMethods c) { + this(c.getNameIndex(), c.getLength(), c.getBootstrapMethods(), c.getConstantPool()); + } + + + /** + * @param name_index Index in constant pool to CONSTANT_Utf8 + * @param length Content length in bytes + * @param bootstrap_methods array of bootstrap methods + * @param constant_pool Array of constants + */ public BootstrapMethods(int name_index, int length, BootstrapMethod[] bootstrap_methods, ConstantPool constant_pool) { super(Constants.ATTR_BOOTSTRAP_METHODS, name_index, length, constant_pool); this.bootstrap_methods = bootstrap_methods; } + /** + * Construct object from Input stream. + * + * @param name_index Index in constant pool to CONSTANT_Utf8 + * @param length Content length in bytes + * @param input Input stream + * @param constant_pool Array of constants + * @throws IOException + */ BootstrapMethods(int name_index, int length, DataInput input, ConstantPool constant_pool) throws IOException { this(name_index, length, (BootstrapMethod[]) null, constant_pool); @@ -50,19 +74,31 @@ public class BootstrapMethods extends At } } + /** + * @return array of bootstrap method "records" + */ public final BootstrapMethod[] getBootstrapMethods() { return bootstrap_methods; } + /** + * @param bootstrap_methods the array of bootstrap methods + */ public final void setBootstrapMethods(BootstrapMethod[] bootstrap_methods) { this.bootstrap_methods = bootstrap_methods; } + /** + * @param v Visitor object + */ @Override public void accept(Visitor v) { v.visitBootstrapMethods(this); } + /** + * @return deep copy of this attribute + */ @Override public BootstrapMethods copy(ConstantPool _constant_pool) { BootstrapMethods c = (BootstrapMethods) clone(); @@ -90,4 +126,20 @@ public class BootstrapMethods extends At bootstrap_method.dump(file); } } + + /** + * @return String representation. + */ + @Override + public final String toString() { + StringBuilder buf = new StringBuilder(); + buf.append("BootstrapMethods("); + buf.append(bootstrap_methods.length); + buf.append("):\n"); + for (int i = 0; i < bootstrap_methods.length; i++) { + buf.append(" ").append(i).append(": "); + buf.append(bootstrap_methods[i].toString(constant_pool)).append("\n"); + } + return buf.toString(); + } } Modified: commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/ConstantCP.java URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/ConstantCP.java?rev=1691855&r1=1691854&r2=1691855&view=diff ============================================================================== --- commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/ConstantCP.java (original) +++ commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/ConstantCP.java Sun Jul 19 21:10:46 2015 @@ -24,20 +24,25 @@ import java.io.IOException; import org.apache.bcel.Constants; /** - * Abstract super class for Fieldref and Methodref constants. + * Abstract super class for Fieldref, Methodref, InterfaceMethodref and + * InvokeDynamic constants. * * @version $Id$ * @author <A HREF="mailto:m.d...@gmx.de">M. Dahm</A> * @see ConstantFieldref * @see ConstantMethodref * @see ConstantInterfaceMethodref + * @see ConstantInvokeDynamic */ public abstract class ConstantCP extends Constant { private static final long serialVersionUID = -6275762995206209402L; /** References to the constants containing the class and the field signature */ + // Note that this field is used to store the + // bootstrap_method_attr_index of a ConstantInvokeDynamic. protected int class_index; // TODO make private (has getter & setter) + // This field has the same meaning for all subclasses. protected int name_and_type_index; // TODO make private (has getter & setter) @@ -87,7 +92,7 @@ public abstract class ConstantCP extends /** - * @return Reference (index) to class this field or method belongs to. + * @return Reference (index) to class this constant refers to. */ public final int getClassIndex() { return class_index; @@ -95,10 +100,13 @@ public abstract class ConstantCP extends /** - * @return Reference (index) to signature of the field. + * @return Reference (index) to bootstrap method this constant refers to. + * + * Note that this method is a functional duplicate of getClassIndex + * for use by ConstantInvokeDynamic. */ - public final int getNameAndTypeIndex() { - return name_and_type_index; + public final int getBootstrapMethodAttrIndex() { + return class_index; // AKA bootstrap_method_attr_index } @@ -111,10 +119,21 @@ public abstract class ConstantCP extends /** - * @return Class this field belongs to. + * @param bootstrap_method_attr_index points to a BootstrapMethod. + * + * Note that this method is a functional duplicate of setClassIndex + * for use by ConstantInvokeDynamic. */ - public String getClass( ConstantPool cp ) { - return cp.constantToString(class_index, Constants.CONSTANT_Class); + public final void setBootstrapMethodAttrIndex(int bootstrap_method_attr_index) { + this.class_index = bootstrap_method_attr_index; + } + + + /** + * @return Reference (index) to signature of the field. + */ + public final int getNameAndTypeIndex() { + return name_and_type_index; } @@ -127,10 +146,20 @@ public abstract class ConstantCP extends /** + * @return Class this field belongs to. + */ + public String getClass( ConstantPool cp ) { + return cp.constantToString(class_index, Constants.CONSTANT_Class); + } + + + /** * @return String representation. + * + * not final as ConstantInvokeDynamic needs to modify */ @Override - public final String toString() { + public String toString() { return super.toString() + "(class_index = " + class_index + ", name_and_type_index = " + name_and_type_index + ")"; } Modified: commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/ConstantInvokeDynamic.java URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/ConstantInvokeDynamic.java?rev=1691855&r1=1691854&r2=1691855&view=diff ============================================================================== --- commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/ConstantInvokeDynamic.java (original) +++ commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/ConstantInvokeDynamic.java Sun Jul 19 21:10:46 2015 @@ -18,7 +18,6 @@ package org.apache.bcel.classfile; import java.io.DataInput; -import java.io.DataOutputStream; import java.io.IOException; import org.apache.bcel.Constants; @@ -31,18 +30,15 @@ import org.apache.bcel.Constants; * @see Constant * @since 6.0 */ -public final class ConstantInvokeDynamic extends Constant { +public final class ConstantInvokeDynamic extends ConstantCP { private static final long serialVersionUID = 4310367359017396174L; - private int bootstrap_method_attr_index; - private int name_and_type_index; - /** * Initialize from another object. */ public ConstantInvokeDynamic(ConstantInvokeDynamic c) { - this(c.getBootstrapMethodAttrIndex(), c.getNameAndTypeIndex()); + super(Constants.CONSTANT_InvokeDynamic, c.getBootstrapMethodAttrIndex(), c.getNameAndTypeIndex()); } @@ -53,15 +49,12 @@ public final class ConstantInvokeDynamic * @throws IOException */ ConstantInvokeDynamic(DataInput file) throws IOException { - this(file.readUnsignedShort(), file.readUnsignedShort()); + super(Constants.CONSTANT_InvokeDynamic, file); } - public ConstantInvokeDynamic(int bootstrap_method_attr_index, - int name_and_type_index) { - super(Constants.CONSTANT_InvokeDynamic); - this.bootstrap_method_attr_index = bootstrap_method_attr_index; - this.name_and_type_index = name_and_type_index; + public ConstantInvokeDynamic(int bootstrap_method_attr_index, int name_and_type_index) { + super(Constants.CONSTANT_InvokeDynamic, bootstrap_method_attr_index, name_and_type_index); } @@ -74,41 +67,7 @@ public final class ConstantInvokeDynamic */ @Override public void accept( Visitor v ) { - // TODO Add .visitMethodType to Visitor interface - } - - - /** - * Dump name and signature index to file stream in binary format. - * - * @param file Output file stream - * @throws IOException - */ - @Override - public final void dump( DataOutputStream file ) throws IOException { - file.writeByte(tag); - file.writeShort(bootstrap_method_attr_index); - file.writeShort(name_and_type_index); - } - - - public int getBootstrapMethodAttrIndex() { - return bootstrap_method_attr_index; - } - - - public void setBootstrapMethodAttrIndex(int bootstrap_method_attr_index) { - this.bootstrap_method_attr_index = bootstrap_method_attr_index; - } - - - public int getNameAndTypeIndex() { - return name_and_type_index; - } - - - public void setNameAndTypeIndex(int name_and_type_index) { - this.name_and_type_index = name_and_type_index; + v.visitConstantInvokeDynamic(this); } @@ -117,8 +76,7 @@ public final class ConstantInvokeDynamic */ @Override public final String toString() { - return super.toString() + "(bootstrap_method_attr_index = " + - bootstrap_method_attr_index + ", name_and_type_index = " + - name_and_type_index + ")"; + // UNDONE: need to string replace "class_index" with "bootstrap_method_attr_index" + return super.toString(); } } Modified: commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/ConstantPool.java URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/ConstantPool.java?rev=1691855&r1=1691854&r2=1691855&view=diff ============================================================================== --- commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/ConstantPool.java (original) +++ commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/ConstantPool.java Sun Jul 19 21:10:46 2015 @@ -132,7 +132,7 @@ public class ConstantPool implements Clo case Constants.CONSTANT_NameAndType: str = (constantToString(((ConstantNameAndType) c).getNameIndex(), Constants.CONSTANT_Utf8) - + " " + constantToString(((ConstantNameAndType) c).getSignatureIndex(), + + ":" + constantToString(((ConstantNameAndType) c).getSignatureIndex(), Constants.CONSTANT_Utf8)); break; case Constants.CONSTANT_InterfaceMethodref: @@ -143,8 +143,12 @@ public class ConstantPool implements Clo Constants.CONSTANT_NameAndType)); break; case Constants.CONSTANT_MethodHandle: + // Note that the ReferenceIndex may point to a Fieldref, Methodref or + // InterfaceMethodref - so we need to peek ahead to get the actual type. ConstantMethodHandle cmh = (ConstantMethodHandle) c; - str = Constants.REF_NAMES[cmh.getReferenceKind()] + " " + constantToString(constant_pool[cmh.getReferenceIndex()]); + str = Constants.METHODHANDLE_NAMES[cmh.getReferenceKind()] + + " " + constantToString(cmh.getReferenceIndex(), + getConstant(cmh.getReferenceIndex()).getTag()); break; case Constants.CONSTANT_MethodType: ConstantMethodType cmt = (ConstantMethodType) c; @@ -152,7 +156,9 @@ public class ConstantPool implements Clo break; case Constants.CONSTANT_InvokeDynamic: ConstantInvokeDynamic cid = ((ConstantInvokeDynamic) c); - str = cid.getBootstrapMethodAttrIndex() + ": " + constantToString(cid.getNameAndTypeIndex(), Constants.CONSTANT_NameAndType); + str = cid.getBootstrapMethodAttrIndex() + + ":" + constantToString(cid.getNameAndTypeIndex(), + Constants.CONSTANT_NameAndType); break; default: // Never reached throw new RuntimeException("Unknown constant type " + tag); Modified: commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/DescendingVisitor.java URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/DescendingVisitor.java?rev=1691855&r1=1691854&r2=1691855&view=diff ============================================================================== --- commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/DescendingVisitor.java (original) +++ commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/DescendingVisitor.java Sun Jul 19 21:10:46 2015 @@ -312,6 +312,14 @@ public class DescendingVisitor implement stack.pop(); } + public void visitConstantInvokeDynamic( + ConstantInvokeDynamic constant) + { + stack.push(constant); + constant.accept(visitor); + stack.pop(); + } + public void visitConstantLong(ConstantLong constant) { stack.push(constant); @@ -365,6 +373,18 @@ public class DescendingVisitor implement stack.pop(); } + public void visitBootstrapMethods(BootstrapMethods bm) + { + stack.push(bm); + bm.accept(visitor); + // BootstrapMethod[] bms = bm.getBootstrapMethods(); + // for (int i = 0; i < bms.length; i++) + // { + // bms[i].accept(this); + // } + stack.pop(); + } + public void visitDeprecated(Deprecated attribute) { stack.push(attribute); @@ -425,13 +445,6 @@ public class DescendingVisitor implement { stack.push(obj); obj.accept(visitor); - stack.pop(); - } - - public void visitBootstrapMethods(BootstrapMethods obj) - { - stack.push(obj); - obj.accept(visitor); stack.pop(); } Modified: commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/EmptyVisitor.java URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/EmptyVisitor.java?rev=1691855&r1=1691854&r2=1691855&view=diff ============================================================================== --- commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/EmptyVisitor.java (original) +++ commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/EmptyVisitor.java Sun Jul 19 21:10:46 2015 @@ -78,6 +78,10 @@ public class EmptyVisitor implements Vis { } + public void visitConstantInvokeDynamic(ConstantInvokeDynamic obj) + { + } + public void visitConstantLong(ConstantLong obj) { } @@ -126,6 +130,10 @@ public class EmptyVisitor implements Vis { } + public void visitBootstrapMethods(BootstrapMethods obj) + { + } + public void visitJavaClass(JavaClass obj) { } @@ -190,10 +198,6 @@ public class EmptyVisitor implements Vis { } - public void visitBootstrapMethods(BootstrapMethods obj) - { - } - public void visitMethodParameters(MethodParameters obj) { } 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=1691855&r1=1691854&r2=1691855&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 Sun Jul 19 21:10:46 2015 @@ -340,14 +340,18 @@ public abstract class Utility { */ case Constants.INVOKESPECIAL: 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); - } + // With Java8 operand may be either a CONSTANT_Methodref + // or a CONSTANT_InterfaceMethodref. (markro) + buf.append("\t").append( + constant_pool.constantToString(index, c.getTag())) + .append((verbose ? " (" + index + ")" : "")); + break; + case Constants.INVOKEVIRTUAL: + index = bytes.readUnsignedShort(); buf.append("\t").append( - constant_pool.constantToString(c)) + constant_pool.constantToString(index, Constants.CONSTANT_Methodref)) .append((verbose ? " (" + index + ")" : "")); break; case Constants.INVOKEINTERFACE: @@ -361,14 +365,12 @@ public abstract class Utility { 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( + buf.append("\t").append( constant_pool - .constantToString(id.getNameAndTypeIndex(), Constants.CONSTANT_NameAndType)); - if (verbose) { - buf.append(" (" + index + "/" + id.getNameAndTypeIndex() +")"); - } + .constantToString(index, Constants.CONSTANT_InvokeDynamic)) + .append(verbose ? " (" + index + ")\t" : "") + .append(bytes.readUnsignedByte()) // Thrid byte is a reserved space + .append(bytes.readUnsignedByte()); // Last byte is a reserved space break; /* Operands are references to items in constant pool */ @@ -829,7 +831,18 @@ public abstract class Utility { return compactClassName(signature.substring(1, index), chopit); } case 'L': { // Full class name - int index = signature.indexOf(';'); // Look for closing `;' + // should this be a while loop? can there be more than + // one generic clause? (markro) + int fromIndex = signature.indexOf('<'); // generic type? + if (fromIndex < 0) { + fromIndex = 0; + } else { + fromIndex = signature.indexOf('>', fromIndex); + if (fromIndex < 0) { + throw new ClassFormatException("Invalid signature: " + signature); + } + } + int index = signature.indexOf(';', fromIndex); // Look for closing `;' if (index < 0) { throw new ClassFormatException("Invalid signature: " + signature); } Modified: commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/Visitor.java URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/Visitor.java?rev=1691855&r1=1691854&r2=1691855&view=diff ============================================================================== --- commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/Visitor.java (original) +++ commons/proper/bcel/trunk/src/main/java/org/apache/bcel/classfile/Visitor.java Sun Jul 19 21:10:46 2015 @@ -43,6 +43,8 @@ public interface Visitor void visitConstantInterfaceMethodref(ConstantInterfaceMethodref obj); + void visitConstantInvokeDynamic(ConstantInvokeDynamic obj); + void visitConstantLong(ConstantLong obj); void visitConstantMethodref(ConstantMethodref obj); Modified: commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/ConstantPoolGen.java URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/ConstantPoolGen.java?rev=1691855&r1=1691854&r2=1691855&view=diff ============================================================================== --- commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/ConstantPoolGen.java (original) +++ commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/ConstantPoolGen.java Sun Jul 19 21:10:46 2015 @@ -28,6 +28,7 @@ import org.apache.bcel.classfile.Constan import org.apache.bcel.classfile.ConstantFloat; import org.apache.bcel.classfile.ConstantInteger; import org.apache.bcel.classfile.ConstantInterfaceMethodref; +import org.apache.bcel.classfile.ConstantInvokeDynamic; import org.apache.bcel.classfile.ConstantLong; import org.apache.bcel.classfile.ConstantMethodref; import org.apache.bcel.classfile.ConstantNameAndType; @@ -127,14 +128,25 @@ public class ConstantPoolGen implements } } else if (c instanceof ConstantCP) { ConstantCP m = (ConstantCP) c; + String class_name; + ConstantUtf8 u8; + + if (c instanceof ConstantInvokeDynamic) { + class_name = Integer.toString(m.getBootstrapMethodAttrIndex()); + // since name can't begin with digit, can use + // METHODREF_DELIM with out fear of duplicates. + } else { ConstantClass clazz = (ConstantClass) constants[m.getClassIndex()]; + u8 = (ConstantUtf8) constants[clazz.getNameIndex()]; + class_name = u8.getBytes().replace('/', '.'); + } + ConstantNameAndType n = (ConstantNameAndType) constants[m.getNameAndTypeIndex()]; - ConstantUtf8 u8 = (ConstantUtf8) constants[clazz.getNameIndex()]; - String class_name = u8.getBytes().replace('/', '.'); u8 = (ConstantUtf8) constants[n.getNameIndex()]; String method_name = u8.getBytes(); u8 = (ConstantUtf8) constants[n.getSignatureIndex()]; String signature = u8.getBytes(); + String delim = METHODREF_DELIM; if (c instanceof ConstantInterfaceMethodref) { delim = IMETHODREF_DELIM; 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=1691855&r1=1691854&r2=1691855&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 Sun Jul 19 21:10:46 2015 @@ -744,9 +744,6 @@ public abstract class EmptyVisitor imple public void visitBREAKPOINT( BREAKPOINT obj ) { } - public void visitNameSignatureInstruction(NameSignatureInstruction obj) { - } - public void visitINVOKEDYNAMIC(INVOKEDYNAMIC obj) { } } Modified: commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/FieldOrMethod.java URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/FieldOrMethod.java?rev=1691855&r1=1691854&r2=1691855&view=diff ============================================================================== --- commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/FieldOrMethod.java (original) +++ commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/FieldOrMethod.java Sun Jul 19 21:10:46 2015 @@ -18,7 +18,12 @@ package org.apache.bcel.generic; import org.apache.bcel.classfile.ConstantCP; +import org.apache.bcel.classfile.ConstantNameAndType; import org.apache.bcel.classfile.ConstantPool; +import org.apache.bcel.classfile.ConstantUtf8; + +// We have removed Deprecated from getClassName() as we continue to use +// it with our tools and want to remove warnings. (markro) /** * Super class for InvokeInstruction and FieldInstruction, since they have @@ -27,7 +32,7 @@ import org.apache.bcel.classfile.Constan * @version $Id$ * @author <A HREF="mailto:m.d...@gmx.de">M. Dahm</A> */ -public abstract class FieldOrMethod extends NameSignatureInstruction implements LoadClass { +public abstract class FieldOrMethod extends CPInstruction implements LoadClass { private static final long serialVersionUID = 2036985877748835708L; @@ -48,8 +53,28 @@ public abstract class FieldOrMethod exte } + /** @return signature of referenced method/field. + */ + public String getSignature( ConstantPoolGen cpg ) { + ConstantPool cp = cpg.getConstantPool(); + ConstantCP cmr = (ConstantCP) cp.getConstant(index); + ConstantNameAndType cnat = (ConstantNameAndType) cp.getConstant(cmr.getNameAndTypeIndex()); + return ((ConstantUtf8) cp.getConstant(cnat.getSignatureIndex())).getBytes(); + } + + + /** @return name of referenced method/field. + */ + public String getName( ConstantPoolGen cpg ) { + ConstantPool cp = cpg.getConstantPool(); + ConstantCP cmr = (ConstantCP) cp.getConstant(index); + ConstantNameAndType cnat = (ConstantNameAndType) cp.getConstant(cmr.getNameAndTypeIndex()); + return ((ConstantUtf8) cp.getConstant(cnat.getNameIndex())).getBytes(); + } + + /** @return name of the referenced class/interface - * @deprecated If the instruction references an array class, + * deprecated If the instruction references an array class, * this method will return "java.lang.Object". * For code generated by Java 1.5, this answer is * sometimes wrong (e.g., if the "clone()" method is @@ -57,7 +82,7 @@ public abstract class FieldOrMethod exte * the getReferenceType() method, which correctly distinguishes * between class types and array types. */ - @Deprecated +// @Deprecated public String getClassName( ConstantPoolGen cpg ) { ConstantPool cp = cpg.getConstantPool(); ConstantCP cmr = (ConstantCP) cp.getConstant(index); Modified: commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/GETFIELD.java URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/GETFIELD.java?rev=1691855&r1=1691854&r2=1691855&view=diff ============================================================================== --- commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/GETFIELD.java (original) +++ commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/GETFIELD.java Sun Jul 19 21:10:46 2015 @@ -80,7 +80,6 @@ public class GETFIELD extends FieldInstr v.visitTypedInstruction(this); v.visitLoadClass(this); v.visitCPInstruction(this); - v.visitNameSignatureInstruction(this); v.visitFieldOrMethod(this); v.visitFieldInstruction(this); v.visitGETFIELD(this); Modified: commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/GETSTATIC.java URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/GETSTATIC.java?rev=1691855&r1=1691854&r2=1691855&view=diff ============================================================================== --- commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/GETSTATIC.java (original) +++ commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/GETSTATIC.java Sun Jul 19 21:10:46 2015 @@ -78,7 +78,6 @@ public class GETSTATIC extends FieldInst v.visitTypedInstruction(this); v.visitLoadClass(this); v.visitCPInstruction(this); - v.visitNameSignatureInstruction(this); v.visitFieldOrMethod(this); v.visitFieldInstruction(this); v.visitGETSTATIC(this); Modified: 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=1691855&r1=1691854&r2=1691855&view=diff ============================================================================== --- commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/INVOKEDYNAMIC.java (original) +++ commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/INVOKEDYNAMIC.java Sun Jul 19 21:10:46 2015 @@ -17,14 +17,11 @@ */ package org.apache.bcel.generic; +import java.io.DataOutputStream; 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.ConstantInvokeDynamic; -import org.apache.bcel.classfile.ConstantNameAndType; import org.apache.bcel.classfile.ConstantPool; import org.apache.bcel.util.ByteSequence; @@ -34,11 +31,9 @@ import org.apache.bcel.util.ByteSequence * mechanism entirely. * * @version $Id: InvokeInstruction.java 1152072 2011-07-29 01:54:05Z dbrosius $ - * @author Bill Pugh * @since 6.0 */ -public class INVOKEDYNAMIC extends NameSignatureInstruction implements ExceptionThrower, - StackConsumer, StackProducer { +public class INVOKEDYNAMIC extends InvokeInstruction { private static final long serialVersionUID = 1L; @@ -51,103 +46,45 @@ public class INVOKEDYNAMIC extends NameS } - /** - * @param index to constant pool - */ - public INVOKEDYNAMIC(short opcode, int index) { - super(opcode, index); + public INVOKEDYNAMIC(int index) { + super(Constants.INVOKEDYNAMIC, index); } /** - * @return mnemonic for instruction with symbolic references resolved + * Dump instruction as byte code to stream out. + * @param out Output stream */ @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(); - } - - /** - * Get the ConstantInvokeDynamic associated with this instruction - */ - - public ConstantInvokeDynamic getInvokeDynamic( ConstantPoolGen cpg ) { - ConstantPool cp = cpg.getConstantPool(); - return (ConstantInvokeDynamic) cp.getConstant(index); + public void dump( DataOutputStream out ) throws IOException { + out.writeByte(opcode); + out.writeShort(index); + out.writeByte(0); + out.writeByte(0); } - @Override - public ConstantNameAndType getNameAndType( ConstantPoolGen cpg ) { - ConstantPool cp = cpg.getConstantPool(); - ConstantInvokeDynamic id = getInvokeDynamic(cpg); - return (ConstantNameAndType) cp.getConstant(id.getNameAndTypeIndex()); - } /** - * 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. + * Read needed data (i.e., index) from file. */ @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)); + protected void initFromFile( ByteSequence bytes, boolean wide ) throws IOException { + super.initFromFile(bytes, wide); + length = 5; + bytes.readByte(); // Skip 0 byte + bytes.readByte(); // Skip 0 byte } - /** @return argument types of referenced method. - */ - public Type[] getArgumentTypes( ConstantPoolGen cpg ) { - return Type.getArgumentTypes(getSignature(cpg)); - } - /** - * Read needed data (i.e., index) from file. + * @return mnemonic for instruction with symbolic references resolved */ @Override - protected void initFromFile( ByteSequence bytes, boolean wide ) throws IOException { - super.initFromFile(bytes, wide); - length = 5; - bytes.readUnsignedShort(); + public String toString( ConstantPool cp ) { + return super.toString(cp); } + public Class<?>[] getExceptions() { Class<?>[] cs = new Class[4 + ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION.length]; System.arraycopy(ExceptionConstants.EXCS_INTERFACE_METHOD_RESOLUTION, 0, cs, 0, @@ -174,8 +111,10 @@ public class INVOKEDYNAMIC extends NameS v.visitTypedInstruction(this); v.visitStackConsumer(this); v.visitStackProducer(this); + v.visitLoadClass(this); v.visitCPInstruction(this); - v.visitNameSignatureInstruction(this); + v.visitFieldOrMethod(this); + v.visitInvokeInstruction(this); v.visitINVOKEDYNAMIC(this); } } Modified: commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/INVOKEINTERFACE.java URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/INVOKEINTERFACE.java?rev=1691855&r1=1691854&r2=1691855&view=diff ============================================================================== --- commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/INVOKEINTERFACE.java (original) +++ commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/INVOKEINTERFACE.java Sun Jul 19 21:10:46 2015 @@ -133,7 +133,6 @@ public final class INVOKEINTERFACE exten v.visitStackProducer(this); v.visitLoadClass(this); v.visitCPInstruction(this); - v.visitNameSignatureInstruction(this); v.visitFieldOrMethod(this); v.visitInvokeInstruction(this); v.visitINVOKEINTERFACE(this); Modified: commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/INVOKESPECIAL.java URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/INVOKESPECIAL.java?rev=1691855&r1=1691854&r2=1691855&view=diff ============================================================================== --- commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/INVOKESPECIAL.java (original) +++ commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/INVOKESPECIAL.java Sun Jul 19 21:10:46 2015 @@ -75,7 +75,6 @@ public class INVOKESPECIAL extends Invok v.visitStackProducer(this); v.visitLoadClass(this); v.visitCPInstruction(this); - v.visitNameSignatureInstruction(this); v.visitFieldOrMethod(this); v.visitInvokeInstruction(this); v.visitINVOKESPECIAL(this); Modified: commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/INVOKESTATIC.java URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/INVOKESTATIC.java?rev=1691855&r1=1691854&r2=1691855&view=diff ============================================================================== --- commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/INVOKESTATIC.java (original) +++ commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/INVOKESTATIC.java Sun Jul 19 21:10:46 2015 @@ -72,7 +72,6 @@ public class INVOKESTATIC extends Invoke v.visitStackProducer(this); v.visitLoadClass(this); v.visitCPInstruction(this); - v.visitNameSignatureInstruction(this); v.visitFieldOrMethod(this); v.visitInvokeInstruction(this); v.visitINVOKESTATIC(this); Modified: commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/INVOKEVIRTUAL.java URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/INVOKEVIRTUAL.java?rev=1691855&r1=1691854&r2=1691855&view=diff ============================================================================== --- commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/INVOKEVIRTUAL.java (original) +++ commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/INVOKEVIRTUAL.java Sun Jul 19 21:10:46 2015 @@ -75,7 +75,6 @@ public class INVOKEVIRTUAL extends Invok v.visitLoadClass(this); v.visitCPInstruction(this); v.visitFieldOrMethod(this); - v.visitNameSignatureInstruction(this); v.visitInvokeInstruction(this); v.visitINVOKEVIRTUAL(this); } Modified: commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/InstructionFactory.java URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/InstructionFactory.java?rev=1691855&r1=1691854&r2=1691855&view=diff ============================================================================== --- commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/InstructionFactory.java (original) +++ commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/InstructionFactory.java Sun Jul 19 21:10:46 2015 @@ -61,7 +61,7 @@ public class InstructionFactory implemen } - /** Create an invoke instruction. + /** Create an invoke instruction. (Except for invokedynamic.) * * @param class_name name of the called class * @param name name of the called method @@ -98,6 +98,32 @@ public class InstructionFactory implemen } } + /** Create an invokedynamic instruction. + * + * @param bootstrap_index index into the bootstrap_methods array + * @param name name of the called method + * @param ret_type return type of method + * @param arg_types argument types of method + * @see Constants + */ +/* + * createInvokeDynamic only needed if instrumention code wants to generate + * a new invokedynamic instruction. I don't think we need. (markro) + * + public InvokeInstruction createInvokeDynamic( int bootstrap_index, String name, Type ret_type, + Type[] arg_types) { + int index; + int nargs = 0; + String signature = Type.getMethodSignature(ret_type, arg_types); + for (int i = 0; i < arg_types.length; i++) { + nargs += arg_types[i].getSize(); + } + // UNDONE - needs to be added to ConstantPoolGen + //index = cp.addInvokeDynamic(bootstrap_index, name, signature); + index = 0; + return new INVOKEDYNAMIC(index); + } + */ /** Create a call to the most popular System.out.println() method. * Modified: commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/InvokeInstruction.java URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/InvokeInstruction.java?rev=1691855&r1=1691854&r2=1691855&view=diff ============================================================================== --- commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/InvokeInstruction.java (original) +++ commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/InvokeInstruction.java Sun Jul 19 21:10:46 2015 @@ -70,7 +70,7 @@ public abstract class InvokeInstruction @Override public int consumeStack( ConstantPoolGen cpg ) { int sum; - if (opcode == Constants.INVOKESTATIC) { + if ((opcode == Constants.INVOKESTATIC) || (opcode == Constants.INVOKEDYNAMIC)) { sum = 0; } else { sum = 1; // this reference Modified: commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/PUTFIELD.java URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/PUTFIELD.java?rev=1691855&r1=1691854&r2=1691855&view=diff ============================================================================== --- commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/PUTFIELD.java (original) +++ commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/PUTFIELD.java Sun Jul 19 21:10:46 2015 @@ -79,7 +79,6 @@ public class PUTFIELD extends FieldInstr v.visitTypedInstruction(this); v.visitLoadClass(this); v.visitCPInstruction(this); - v.visitNameSignatureInstruction(this); v.visitFieldOrMethod(this); v.visitFieldInstruction(this); v.visitPUTFIELD(this); Modified: commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/PUTSTATIC.java URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/PUTSTATIC.java?rev=1691855&r1=1691854&r2=1691855&view=diff ============================================================================== --- commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/PUTSTATIC.java (original) +++ commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/PUTSTATIC.java Sun Jul 19 21:10:46 2015 @@ -78,7 +78,6 @@ public class PUTSTATIC extends FieldInst v.visitTypedInstruction(this); v.visitLoadClass(this); v.visitCPInstruction(this); - v.visitNameSignatureInstruction(this); v.visitFieldOrMethod(this); v.visitFieldInstruction(this); v.visitPUTSTATIC(this); Modified: commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/Visitor.java URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/Visitor.java?rev=1691855&r1=1691854&r2=1691855&view=diff ============================================================================== --- commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/Visitor.java (original) +++ commons/proper/bcel/trunk/src/main/java/org/apache/bcel/generic/Visitor.java Sun Jul 19 21:10:46 2015 @@ -448,6 +448,9 @@ public interface Visitor { void visitINVOKEVIRTUAL( INVOKEVIRTUAL obj ); + void visitINVOKEDYNAMIC( INVOKEDYNAMIC obj ); + + void visitFASTORE( FASTORE obj ); @@ -566,10 +569,4 @@ public interface Visitor { void visitBREAKPOINT( BREAKPOINT obj ); - - - void visitNameSignatureInstruction( NameSignatureInstruction obj ); - - - void visitINVOKEDYNAMIC( INVOKEDYNAMIC obj ); } Modified: commons/proper/bcel/trunk/src/main/java/org/apache/bcel/util/CodeHTML.java URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/main/java/org/apache/bcel/util/CodeHTML.java?rev=1691855&r1=1691854&r2=1691855&view=diff ============================================================================== --- commons/proper/bcel/trunk/src/main/java/org/apache/bcel/util/CodeHTML.java (original) +++ commons/proper/bcel/trunk/src/main/java/org/apache/bcel/util/CodeHTML.java Sun Jul 19 21:10:46 2015 @@ -26,6 +26,7 @@ import org.apache.bcel.classfile.Code; import org.apache.bcel.classfile.CodeException; import org.apache.bcel.classfile.ConstantFieldref; import org.apache.bcel.classfile.ConstantInterfaceMethodref; +import org.apache.bcel.classfile.ConstantInvokeDynamic; import org.apache.bcel.classfile.ConstantMethodref; import org.apache.bcel.classfile.ConstantNameAndType; import org.apache.bcel.classfile.ConstantPool; @@ -250,6 +251,7 @@ final class CodeHTML implements org.apac case INVOKESTATIC: case INVOKEVIRTUAL: case INVOKEINTERFACE: + case INVOKEDYNAMIC: int m_index = bytes.readShort(); String str; if (opcode == INVOKEINTERFACE) { // Special treatment needed @@ -260,16 +262,25 @@ final class CodeHTML implements org.apac ConstantInterfaceMethodref c = (ConstantInterfaceMethodref) constant_pool .getConstant(m_index, CONSTANT_InterfaceMethodref); class_index = c.getClassIndex(); - str = constant_pool.constantToString(c); index = c.getNameAndTypeIndex(); + name = Class2HTML.referenceClass(class_index); + } else if (opcode == INVOKEDYNAMIC) { // Special treatment needed + bytes.readUnsignedByte(); // Reserved + bytes.readUnsignedByte(); // Reserved + ConstantInvokeDynamic c = (ConstantInvokeDynamic) constant_pool + .getConstant(m_index, CONSTANT_InvokeDynamic); + index = c.getNameAndTypeIndex(); + name = "#" + c.getBootstrapMethodAttrIndex(); } else { + // UNDONE: Java8 now allows INVOKESPECIAL and INVOKESTATIC to + // reference EITHER a Methodref OR an InterfaceMethodref. + // Not sure if that affects this code or not. (markro) ConstantMethodref c = (ConstantMethodref) constant_pool.getConstant(m_index, CONSTANT_Methodref); class_index = c.getClassIndex(); - str = constant_pool.constantToString(c); index = c.getNameAndTypeIndex(); - } name = Class2HTML.referenceClass(class_index); + } str = Class2HTML.toHTML(constant_pool.constantToString(constant_pool.getConstant( index, CONSTANT_NameAndType))); // Get signature, i.e., types Modified: commons/proper/bcel/trunk/src/main/java/org/apache/bcel/util/InstructionFinder.java URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/main/java/org/apache/bcel/util/InstructionFinder.java?rev=1691855&r1=1691854&r2=1691855&view=diff ============================================================================== --- commons/proper/bcel/trunk/src/main/java/org/apache/bcel/util/InstructionFinder.java (original) +++ commons/proper/bcel/trunk/src/main/java/org/apache/bcel/util/InstructionFinder.java Sun Jul 19 21:10:46 2015 @@ -317,14 +317,14 @@ public class InstructionFinder { // Initialize pattern map static { map.put("arithmeticinstruction","(irem|lrem|iand|ior|ineg|isub|lneg|fneg|fmul|ldiv|fadd|lxor|frem|idiv|land|ixor|ishr|fsub|lshl|fdiv|iadd|lor|dmul|lsub|ishl|imul|lmul|lushr|dneg|iushr|lshr|ddiv|drem|dadd|ladd|dsub)"); - map.put("invokeinstruction", "(invokevirtual|invokeinterface|invokestatic|invokespecial)"); + map.put("invokeinstruction", "(invokevirtual|invokeinterface|invokestatic|invokespecial|invokedynamic)"); map.put("arrayinstruction", "(baload|aastore|saload|caload|fastore|lastore|iaload|castore|iastore|aaload|bastore|sastore|faload|laload|daload|dastore)"); map.put("gotoinstruction", "(goto|goto_w)"); map.put("conversioninstruction", "(d2l|l2d|i2s|d2i|l2i|i2b|l2f|d2f|f2i|i2d|i2l|f2d|i2c|f2l|i2f)"); map.put("localvariableinstruction","(fstore|iinc|lload|dstore|dload|iload|aload|astore|istore|fload|lstore)"); map.put("loadinstruction", "(fload|dload|lload|iload|aload)"); map.put("fieldinstruction", "(getfield|putstatic|getstatic|putfield)"); - map.put("cpinstruction", "(ldc2_w|invokeinterface|multianewarray|putstatic|instanceof|getstatic|checkcast|getfield|invokespecial|ldc_w|invokestatic|invokevirtual|putfield|ldc|new|anewarray)"); + map.put("cpinstruction", "(ldc2_w|invokeinterface|invokedynamic|multianewarray|putstatic|instanceof|getstatic|checkcast|getfield|invokespecial|ldc_w|invokestatic|invokevirtual|putfield|ldc|new|anewarray)"); map.put("stackinstruction", "(dup2|swap|dup2_x2|pop|pop2|dup|dup2_x1|dup_x2|dup_x1)"); map.put("branchinstruction", "(ifle|if_acmpne|if_icmpeq|if_acmpeq|ifnonnull|goto_w|iflt|ifnull|if_icmpne|tableswitch|if_icmple|ifeq|if_icmplt|jsr_w|if_icmpgt|ifgt|jsr|goto|ifne|ifge|lookupswitch|if_icmpge)"); map.put("returninstruction", "(lreturn|ireturn|freturn|dreturn|areturn|return)"); @@ -335,15 +335,15 @@ public class InstructionFinder { map.put("variablelengthinstruction", "(tableswitch|jsr|goto|lookupswitch)"); map.put("unconditionalbranch", "(goto|jsr|jsr_w|athrow|goto_w)"); map.put("constantpushinstruction", "(dconst|bipush|sipush|fconst|iconst|lconst)"); - map.put("typedinstruction", "(imul|lsub|aload|fload|lor|new|aaload|fcmpg|iand|iaload|lrem|idiv|d2l|isub|dcmpg|dastore|ret|f2d|f2i|drem|iinc|i2c|checkcast|frem|lreturn|astore|lushr|daload|dneg|fastore|istore|lshl|ldiv|lstore|areturn|ishr|ldc_w|invokeinterface|aastore|lxor|ishl|l2d|i2f|return|faload|sipush|iushr|caload|instanceof|invokespecial|putfield|fmul|ireturn|laload|d2f|lneg|ixor|i2l|fdiv|lastore|multianewarray|i2b|getstatic|i2d|putstatic|fcmpl|saload|ladd|irem|dload|jsr_w|dconst|dcmpl|fsub|freturn|ldc|aconst_null|castore|lmul|ldc2_w|dadd|iconst|f2l|ddiv|dstore|land|jsr|anewarray|dmul|bipush|dsub|sastore|d2i|i2s|lshr|iadd|l2i|lload|bastore|fstore|fneg|iload|fadd|baload|fconst|ior|ineg|dreturn|l2f|lconst|getfield|invokevirtual|invokestatic|iastore)"); + map.put("typedinstruction", "(imul|lsub|aload|fload|lor|new|aaload|fcmpg|iand|iaload|lrem|idiv|d2l|isub|dcmpg|dastore|ret|f2d|f2i|drem|iinc|i2c|checkcast|frem|lreturn|astore|lushr|daload|dneg|fastore|istore|lshl|ldiv|lstore|areturn|ishr|ldc_w|invokeinterface|invokedynamic|aastore|lxor|ishl|l2d|i2f|return|faload|sipush|iushr|caload|instanceof|invokespecial|putfield|fmul|ireturn|laload|d2f|lneg|ixor|i2l|fdiv|lastore|multianewarray|i2b|getstatic|i2d|putstatic|fcmpl|saload|ladd|irem|dload|jsr_w|dconst|dcmpl|fsub|freturn|ldc|aconst_null|castore|lmul|ldc2_w|dadd|iconst|f2l|ddiv|dstore|land|jsr|anewarray|dmul|bipush|dsub|sastore|d2i|i2s|lshr|iadd|l2i|lload|bastore|fstore|fneg|iload|fadd|baload|fconst|ior|ineg|dreturn|l2f|lconst|getfield|invokevirtual|invokestatic|iastore)"); map.put("popinstruction", "(fstore|dstore|pop|pop2|astore|putstatic|istore|lstore)"); map.put("allocationinstruction", "(multianewarray|new|anewarray|newarray)"); - map.put("indexedinstruction", "(lload|lstore|fload|ldc2_w|invokeinterface|multianewarray|astore|dload|putstatic|instanceof|getstatic|checkcast|getfield|invokespecial|dstore|istore|iinc|ldc_w|ret|fstore|invokestatic|iload|putfield|invokevirtual|ldc|new|aload|anewarray)"); + map.put("indexedinstruction", "(lload|lstore|fload|ldc2_w|invokeinterface|invokedynamic|multianewarray|astore|dload|putstatic|instanceof|getstatic|checkcast|getfield|invokespecial|dstore|istore|iinc|ldc_w|ret|fstore|invokestatic|iload|putfield|invokevirtual|ldc|new|aload|anewarray)"); map.put("pushinstruction", "(dup|lload|dup2|bipush|fload|ldc2_w|sipush|lconst|fconst|dload|getstatic|ldc_w|aconst_null|dconst|iload|ldc|iconst|aload)"); - map.put("stackproducer", "(imul|lsub|aload|fload|lor|new|aaload|fcmpg|iand|iaload|lrem|idiv|d2l|isub|dcmpg|dup|f2d|f2i|drem|i2c|checkcast|frem|lushr|daload|dneg|lshl|ldiv|ishr|ldc_w|invokeinterface|lxor|ishl|l2d|i2f|faload|sipush|iushr|caload|instanceof|invokespecial|fmul|laload|d2f|lneg|ixor|i2l|fdiv|getstatic|i2b|swap|i2d|dup2|fcmpl|saload|ladd|irem|dload|jsr_w|dconst|dcmpl|fsub|ldc|arraylength|aconst_null|tableswitch|lmul|ldc2_w|iconst|dadd|f2l|ddiv|land|jsr|anewarray|dmul|bipush|dsub|d2i|newarray|i2s|lshr|iadd|lload|l2i|fneg|iload|fadd|baload|fconst|lookupswitch|ior|ineg|lconst|l2f|getfield|invokevirtual|invokestatic)"); - map.put("stackconsumer", "(imul|lsub|lor|iflt|fcmpg|if_icmpgt|iand|ifeq|if_icmplt|lrem|ifnonnull|idiv|d2l|isub|dcmpg|dastore|if_icmpeq|f2d|f2i|drem|i2c|checkcast|frem|lreturn|astore|lushr|pop2|monitorexit|dneg|fastore|istore|lshl|ldiv|lstore|areturn|if_icmpge|ishr|monitorenter|invokeinterface|aastore|lxor|ishl|l2d|i2f|return|iushr|instanceof|invokespecial|fmul|ireturn|d2f|lneg|ixor|pop|i2l|ifnull|fdiv|lastore|i2b|if_acmpeq|ifge|swap|i2d|putstatic|fcmpl|ladd|irem|dcmpl|fsub|freturn|ifgt|castore|lmul|dadd|f2l|ddiv|dstore|land|if_icmpne|if_acmpne|dmul|dsub|sastore|ifle|d2i|i2s|lshr|iadd|l2i|bastore|fstore|fneg|fadd|ior|ineg|ifne|dreturn|l2f|if_icmple|getfield|invokevirtual|invokestatic|iastore)"); - map.put("exceptionthrower","(irem|lrem|laload|putstatic|baload|dastore|areturn|getstatic|ldiv|anewarray|iastore|castore|idiv|saload|lastore|fastore|putfield|lreturn|caload|getfield|return|aastore|freturn|newarray|instanceof|multianewarray|athrow|faload|iaload|aaload|dreturn|monitorenter|checkcast|bastore|arraylength|new|invokevirtual|sastore|ldc_w|ireturn|invokespecial|monitorexit|invokeinterface|ldc|invokestatic|daload)"); - map.put("loadclass", "(multianewarray|invokeinterface|instanceof|invokespecial|putfield|checkcast|putstatic|invokevirtual|new|getstatic|invokestatic|getfield|anewarray)"); + map.put("stackproducer", "(imul|lsub|aload|fload|lor|new|aaload|fcmpg|iand|iaload|lrem|idiv|d2l|isub|dcmpg|dup|f2d|f2i|drem|i2c|checkcast|frem|lushr|daload|dneg|lshl|ldiv|ishr|ldc_w|invokeinterface|invokedynamic|lxor|ishl|l2d|i2f|faload|sipush|iushr|caload|instanceof|invokespecial|fmul|laload|d2f|lneg|ixor|i2l|fdiv|getstatic|i2b|swap|i2d|dup2|fcmpl|saload|ladd|irem|dload|jsr_w|dconst|dcmpl|fsub|ldc|arraylength|aconst_null|tableswitch|lmul|ldc2_w|iconst|dadd|f2l|ddiv|land|jsr|anewarray|dmul|bipush|dsub|d2i|newarray|i2s|lshr|iadd|lload|l2i|fneg|iload|fadd|baload|fconst|lookupswitch|ior|ineg|lconst|l2f|getfield|invokevirtual|invokestatic)"); + map.put("stackconsumer", "(imul|lsub|lor|iflt|fcmpg|if_icmpgt|iand|ifeq|if_icmplt|lrem|ifnonnull|idiv|d2l|isub|dcmpg|dastore|if_icmpeq|f2d|f2i|drem|i2c|checkcast|frem|lreturn|astore|lushr|pop2|monitorexit|dneg|fastore|istore|lshl|ldiv|lstore|areturn|if_icmpge|ishr|monitorenter|invokeinterface|invokedynamic|aastore|lxor|ishl|l2d|i2f|return|iushr|instanceof|invokespecial|fmul|ireturn|d2f|lneg|ixor|pop|i2l|ifnull|fdiv|lastore|i2b|if_acmpeq|ifge|swap|i2d|putstatic|fcmpl|ladd|irem|dcmpl|fsub|freturn|ifgt|castore|lmul|dadd|f2l|ddiv|dstore|land|if_icmpne|if_acmpne|dmul|dsub|sastore|ifle|d2i|i2s|lshr|iadd|l2i|bastore|fstore|fneg|fadd|ior|ineg|ifne|dreturn|l2f|if_icmple|getfield|invokevirtual|invokestatic|iastore)"); + map.put("exceptionthrower","(irem|lrem|laload|putstatic|baload|dastore|areturn|getstatic|ldiv|anewarray|iastore|castore|idiv|saload|lastore|fastore|putfield|lreturn|caload|getfield|return|aastore|freturn|newarray|instanceof|multianewarray|athrow|faload|iaload|aaload|dreturn|monitorenter|checkcast|bastore|arraylength|new|invokevirtual|sastore|ldc_w|ireturn|invokespecial|monitorexit|invokeinterface|invokedynamic|ldc|invokestatic|daload)"); + map.put("loadclass", "(multianewarray|invokeinterface|invokedynamic|instanceof|invokespecial|putfield|checkcast|putstatic|invokevirtual|new|getstatic|invokestatic|getfield|anewarray)"); map.put("instructiontargeter", "(ifle|if_acmpne|if_icmpeq|if_acmpeq|ifnonnull|goto_w|iflt|ifnull|if_icmpne|tableswitch|if_icmple|ifeq|if_icmplt|jsr_w|if_icmpgt|ifgt|jsr|goto|ifne|ifge|lookupswitch|if_icmpge)"); // Some aliases map.put("if_icmp", "(if_icmpne|if_icmpeq|if_icmple|if_icmpge|if_icmplt|if_icmpgt)"); Modified: commons/proper/bcel/trunk/src/main/java/org/apache/bcel/verifier/statics/Pass3aVerifier.java URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/main/java/org/apache/bcel/verifier/statics/Pass3aVerifier.java?rev=1691855&r1=1691854&r2=1691855&view=diff ============================================================================== --- commons/proper/bcel/trunk/src/main/java/org/apache/bcel/verifier/statics/Pass3aVerifier.java (original) +++ commons/proper/bcel/trunk/src/main/java/org/apache/bcel/verifier/statics/Pass3aVerifier.java Sun Jul 19 21:10:46 2015 @@ -62,6 +62,7 @@ import org.apache.bcel.generic.ILOAD; import org.apache.bcel.generic.IMPDEP1; import org.apache.bcel.generic.IMPDEP2; import org.apache.bcel.generic.INSTANCEOF; +import org.apache.bcel.generic.INVOKEDYNAMIC; import org.apache.bcel.generic.INVOKEINTERFACE; import org.apache.bcel.generic.INVOKESPECIAL; import org.apache.bcel.generic.INVOKESTATIC; @@ -1071,6 +1072,12 @@ public final class Pass3aVerifier extend /** Checks if the constraints of operands of the said instruction(s) are satisfied. */ @Override + public void visitINVOKEDYNAMIC(INVOKEDYNAMIC o){ + throw new RuntimeException("INVOKEDYNAMIC instruction is not supported at this time"); + } + + /** Checks if the constraints of operands of the said instruction(s) are satisfied. */ + @Override public void visitINVOKEINTERFACE(INVOKEINTERFACE o){ try { // INVOKEINTERFACE is a LoadClass; the Class where the referenced method is declared in, Modified: commons/proper/bcel/trunk/src/main/java/org/apache/bcel/verifier/structurals/ExecutionVisitor.java URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/main/java/org/apache/bcel/verifier/structurals/ExecutionVisitor.java?rev=1691855&r1=1691854&r2=1691855&view=diff ============================================================================== --- commons/proper/bcel/trunk/src/main/java/org/apache/bcel/verifier/structurals/ExecutionVisitor.java (original) +++ commons/proper/bcel/trunk/src/main/java/org/apache/bcel/verifier/structurals/ExecutionVisitor.java Sun Jul 19 21:10:46 2015 @@ -788,6 +788,27 @@ public class ExecutionVisitor extends Em } /** Symbolically executes the corresponding Java Virtual Machine instruction. */ @Override + public void visitINVOKEDYNAMIC(INVOKEDYNAMIC o){ + for (int i=0; i<o.getArgumentTypes(cpg).length; i++){ + stack().pop(); + } + // We are sure the invoked method will xRETURN eventually + // We simulate xRETURNs functionality here because we + // don't really "jump into" and simulate the invoked + // method. + if (o.getReturnType(cpg) != Type.VOID){ + Type t = o.getReturnType(cpg); + if ( t.equals(Type.BOOLEAN) || + t.equals(Type.CHAR) || + t.equals(Type.BYTE) || + t.equals(Type.SHORT) ) { + t = Type.INT; + } + stack().push(t); + } + } + /** Symbolically executes the corresponding Java Virtual Machine instruction. */ + @Override public void visitINVOKEINTERFACE(INVOKEINTERFACE o){ stack().pop(); //objectref for (int i=0; i<o.getArgumentTypes(cpg).length; i++){ Modified: commons/proper/bcel/trunk/src/main/java/org/apache/bcel/verifier/structurals/InstConstraintVisitor.java URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/main/java/org/apache/bcel/verifier/structurals/InstConstraintVisitor.java?rev=1691855&r1=1691854&r2=1691855&view=diff ============================================================================== --- commons/proper/bcel/trunk/src/main/java/org/apache/bcel/verifier/structurals/InstConstraintVisitor.java (original) +++ commons/proper/bcel/trunk/src/main/java/org/apache/bcel/verifier/structurals/InstConstraintVisitor.java Sun Jul 19 21:10:46 2015 @@ -1746,6 +1746,14 @@ public class InstConstraintVisitor exten * Ensures the specific preconditions of the said instruction. */ @Override + public void visitINVOKEDYNAMIC(INVOKEDYNAMIC o){ + throw new RuntimeException("INVOKEDYNAMIC instruction is not supported at this time"); + } + + /** + * Ensures the specific preconditions of the said instruction. + */ + @Override public void visitINVOKEINTERFACE(INVOKEINTERFACE o){ // Method is not native, otherwise pass 3 would not happen. Modified: commons/proper/bcel/trunk/src/test/java/org/apache/bcel/visitors/CounterVisitor.java URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/test/java/org/apache/bcel/visitors/CounterVisitor.java?rev=1691855&r1=1691854&r2=1691855&view=diff ============================================================================== --- commons/proper/bcel/trunk/src/test/java/org/apache/bcel/visitors/CounterVisitor.java (original) +++ commons/proper/bcel/trunk/src/test/java/org/apache/bcel/visitors/CounterVisitor.java Sun Jul 19 21:10:46 2015 @@ -30,6 +30,7 @@ import org.apache.bcel.classfile.Constan import org.apache.bcel.classfile.ConstantFloat; import org.apache.bcel.classfile.ConstantInteger; import org.apache.bcel.classfile.ConstantInterfaceMethodref; +import org.apache.bcel.classfile.ConstantInvokeDynamic; import org.apache.bcel.classfile.ConstantLong; import org.apache.bcel.classfile.ConstantMethodref; import org.apache.bcel.classfile.ConstantNameAndType; @@ -358,4 +359,8 @@ public class CounterVisitor implements V { methodParametersCount++; } + + public void visitConstantInvokeDynamic(ConstantInvokeDynamic obj) + { + } }