diff -r 38c1b3ec92c5 src/share/classes/jdk/internal/org/objectweb/asm/MethodWriter.java --- a/src/share/classes/jdk/internal/org/objectweb/asm/MethodWriter.java Thu Oct 24 10:49:22 2013 +0200 +++ b/src/share/classes/jdk/internal/org/objectweb/asm/MethodWriter.java Thu Oct 24 11:26:50 2013 +0200 @@ -916,6 +916,8 @@ public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc, final boolean itf) { lastCodeOffset = code.length; + // If opcode == Opcodes.INVOKEVIRTUAL && itf == true ? + // Error or should ignore itf? Item i = cw.newMethodItem(owner, name, desc, itf); int argSize = i.intVal; // Label currentBlock = this.currentBlock; diff -r 38c1b3ec92c5 src/share/classes/jdk/internal/org/objectweb/asm/commons/AnalyzerAdapter.java --- a/src/share/classes/jdk/internal/org/objectweb/asm/commons/AnalyzerAdapter.java Thu Oct 24 10:49:22 2013 +0200 +++ b/src/share/classes/jdk/internal/org/objectweb/asm/commons/AnalyzerAdapter.java Thu Oct 24 11:26:50 2013 +0200 @@ -368,6 +368,42 @@ } @Override + public void visitMethodInsn(final int opcode, final String owner, + final String name, final String desc, final boolean ift) { + if (mv != null) { + mv.visitMethodInsn(opcode, owner, name, desc, ift); + } + if (this.locals == null) { + labels = null; + return; + } + pop(desc); + if (opcode != Opcodes.INVOKESTATIC) { + Object t = pop(); + if (opcode == Opcodes.INVOKESPECIAL && name.charAt(0) == '<') { + Object u; + if (t == Opcodes.UNINITIALIZED_THIS) { + u = this.owner; + } else { + u = uninitializedTypes.get(t); + } + for (int i = 0; i < locals.size(); ++i) { + if (locals.get(i) == t) { + locals.set(i, u); + } + } + for (int i = 0; i < stack.size(); ++i) { + if (stack.get(i) == t) { + stack.set(i, u); + } + } + } + } + pushDesc(desc); + labels = null; + } + + @Override public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) { if (mv != null) { diff -r 38c1b3ec92c5 src/share/classes/jdk/internal/org/objectweb/asm/commons/CodeSizeEvaluator.java --- a/src/share/classes/jdk/internal/org/objectweb/asm/commons/CodeSizeEvaluator.java Thu Oct 24 10:49:22 2013 +0200 +++ b/src/share/classes/jdk/internal/org/objectweb/asm/commons/CodeSizeEvaluator.java Thu Oct 24 11:26:50 2013 +0200 @@ -165,6 +165,21 @@ } @Override + public void visitMethodInsn(final int opcode, final String owner, + final String name, final String desc, final boolean itf) { + if (opcode == INVOKEINTERFACE) { + minSize += 5; + maxSize += 5; + } else { + minSize += 3; + maxSize += 3; + } + if (mv != null) { + mv.visitMethodInsn(opcode, owner, name, desc, itf); + } + } + + @Override public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) { minSize += 5; diff -r 38c1b3ec92c5 src/share/classes/jdk/internal/org/objectweb/asm/commons/InstructionAdapter.java --- a/src/share/classes/jdk/internal/org/objectweb/asm/commons/InstructionAdapter.java Thu Oct 24 10:49:22 2013 +0200 +++ b/src/share/classes/jdk/internal/org/objectweb/asm/commons/InstructionAdapter.java Thu Oct 24 11:26:50 2013 +0200 @@ -558,6 +558,35 @@ } @Override + public void visitMethodInsn(final int opcode, final String owner, + final String name, final String desc, final boolean ift) { + switch (opcode) { + case Opcodes.INVOKESPECIAL: + // Pass ift along + invokespecial(owner, name, desc); + break; + case Opcodes.INVOKEVIRTUAL: + if (ift != true) { + invokevirtual(owner, name, desc); + break; + } else { + // Ignore or barf? + // Document opcodes for which ift is valid as a parameter? + throw new IllegalArgumentException(); + } + case Opcodes.INVOKESTATIC: + // Pass ift along + invokestatic(owner, name, desc); + break; + case Opcodes.INVOKEINTERFACE: + invokeinterface(owner, name, desc); + break; + default: + throw new IllegalArgumentException(); + } + } + + @Override public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) { invokedynamic(name, desc, bsm, bsmArgs); diff -r 38c1b3ec92c5 src/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingMethodAdapter.java --- a/src/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingMethodAdapter.java Thu Oct 24 10:49:22 2013 +0200 +++ b/src/share/classes/jdk/internal/org/objectweb/asm/commons/RemappingMethodAdapter.java Thu Oct 24 11:26:50 2013 +0200 @@ -157,6 +157,14 @@ } @Override + public void visitMethodInsn(int opcode, String owner, String name, + String desc, boolean itf) { + super.visitMethodInsn(opcode, remapper.mapType(owner), + remapper.mapMethodName(owner, name, desc), + remapper.mapMethodDesc(desc), itf); + } + + @Override public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) { for (int i = 0; i < bsmArgs.length; i++) { diff -r 38c1b3ec92c5 src/share/classes/jdk/internal/org/objectweb/asm/tree/MethodInsnNode.java --- a/src/share/classes/jdk/internal/org/objectweb/asm/tree/MethodInsnNode.java Thu Oct 24 10:49:22 2013 +0200 +++ b/src/share/classes/jdk/internal/org/objectweb/asm/tree/MethodInsnNode.java Thu Oct 24 11:26:50 2013 +0200 @@ -61,6 +61,7 @@ import java.util.Map; import jdk.internal.org.objectweb.asm.MethodVisitor; +import jdk.internal.org.objectweb.asm.Opcodes; /** * A node that represents a method instruction. A method instruction is an @@ -87,6 +88,13 @@ public String desc; /** + * Whether to the owner of the method is assumed to be an interface + */ + public boolean itf; + + private boolean itfSet; + + /** * Constructs a new {@link MethodInsnNode}. * * @param opcode @@ -108,6 +116,36 @@ this.owner = owner; this.name = name; this.desc = desc; + this.itf = opcode == Opcodes.INVOKEINTERFACE; + this.itfSet = false; + } + + /** + * Constructs a new {@link MethodInsnNode}. + * + * @param opcode + * the opcode of the type instruction to be constructed. This + * opcode must be INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or + * INVOKEINTERFACE. + * @param owner + * the internal name of the method's owner class (see + * {@link jdk.internal.org.objectweb.asm.Type#getInternalName() + * getInternalName}). + * @param name + * the method's name. + * @param desc + * the method's descriptor (see {@link jdk.internal.org.objectweb.asm.Type}). + * @param itf + * whether to the owner of the method is assumed to be an interface + */ + public MethodInsnNode(final int opcode, final String owner, + final String name, final String desc, final boolean itf) { + super(opcode); + this.owner = owner; + this.name = name; + this.desc = desc; + this.itf = itf; + this.itfSet = true; } /** @@ -128,11 +166,17 @@ @Override public void accept(final MethodVisitor mv) { - mv.visitMethodInsn(opcode, owner, name, desc); + if (itfSet) + mv.visitMethodInsn(opcode, owner, name, desc, itf); + else + mv.visitMethodInsn(opcode, owner, name, desc); } @Override public AbstractInsnNode clone(final Map labels) { - return new MethodInsnNode(opcode, owner, name, desc); + if (itfSet) + return new MethodInsnNode(opcode, owner, name, desc, itf); + else + return new MethodInsnNode(opcode, owner, name, desc); } } diff -r 38c1b3ec92c5 src/share/classes/jdk/internal/org/objectweb/asm/tree/MethodNode.java --- a/src/share/classes/jdk/internal/org/objectweb/asm/tree/MethodNode.java Thu Oct 24 10:49:22 2013 +0200 +++ b/src/share/classes/jdk/internal/org/objectweb/asm/tree/MethodNode.java Thu Oct 24 11:26:50 2013 +0200 @@ -468,6 +468,12 @@ } @Override + public void visitMethodInsn(final int opcode, final String owner, + final String name, final String desc, final boolean ift) { + instructions.add(new MethodInsnNode(opcode, owner, name, desc, ift)); + } + + @Override public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) { instructions.add(new InvokeDynamicInsnNode(name, desc, bsm, bsmArgs)); diff -r 38c1b3ec92c5 src/share/classes/jdk/internal/org/objectweb/asm/util/ASMifier.java --- a/src/share/classes/jdk/internal/org/objectweb/asm/util/ASMifier.java Thu Oct 24 10:49:22 2013 +0200 +++ b/src/share/classes/jdk/internal/org/objectweb/asm/util/ASMifier.java Thu Oct 24 11:26:50 2013 +0200 @@ -655,6 +655,23 @@ } @Override + public void visitMethodInsn(final int opcode, final String owner, + final String name, final String desc, final boolean itf) { + buf.setLength(0); + buf.append(this.name).append(".visitMethodInsn(") + .append(OPCODES[opcode]).append(", "); + appendConstant(owner); + buf.append(", "); + appendConstant(name); + buf.append(", "); + appendConstant(desc); + buf.append(", "); + appendConstant(itf); + buf.append(");\n"); + text.add(buf.toString()); + } + + @Override public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) { buf.setLength(0); diff -r 38c1b3ec92c5 src/share/classes/jdk/internal/org/objectweb/asm/util/CheckMethodAdapter.java --- a/src/share/classes/jdk/internal/org/objectweb/asm/util/CheckMethodAdapter.java Thu Oct 24 10:49:22 2013 +0200 +++ b/src/share/classes/jdk/internal/org/objectweb/asm/util/CheckMethodAdapter.java Thu Oct 24 11:26:50 2013 +0200 @@ -725,6 +725,25 @@ } @Override + public void visitMethodInsn(final int opcode, final String owner, + final String name, final String desc, boolean itf) { + checkStartCode(); + checkEndCode(); + checkOpcode(opcode, 5); + // If itf == true are there any different constraints? +// if (opcode == Opcodes.INVOKEVIRTUAL && itf == true) { +// throw new IllegalStateException(); +// } + if (opcode != Opcodes.INVOKESPECIAL || !"".equals(name)) { + checkMethodIdentifier(version, name, "name"); + } + checkInternalName(owner, "owner"); + checkMethodDesc(desc); + super.visitMethodInsn(opcode, owner, name, desc, itf); + ++insnCount; + } + + @Override public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) { checkStartCode(); diff -r 38c1b3ec92c5 src/share/classes/jdk/internal/org/objectweb/asm/util/Printer.java --- a/src/share/classes/jdk/internal/org/objectweb/asm/util/Printer.java Thu Oct 24 10:49:22 2013 +0200 +++ b/src/share/classes/jdk/internal/org/objectweb/asm/util/Printer.java Thu Oct 24 11:26:50 2013 +0200 @@ -399,13 +399,22 @@ /** * Method instruction. See - * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitMethodInsn}. + * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitMethodInsn(int, String, String, String)}. */ public abstract void visitMethodInsn(final int opcode, final String owner, final String name, final String desc); /** * Method instruction. See + * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitMethodInsn(int, String, String, String, boolean)}. + */ + public void visitMethodInsn(final int opcode, final String owner, + final String name, final String desc, final boolean itf) { + throw new RuntimeException("Must be overriden"); + } + + /** + * Method instruction. See * {@link jdk.internal.org.objectweb.asm.MethodVisitor#visitInvokeDynamicInsn}. */ public abstract void visitInvokeDynamicInsn(String name, String desc, diff -r 38c1b3ec92c5 src/share/classes/jdk/internal/org/objectweb/asm/util/Textifier.java --- a/src/share/classes/jdk/internal/org/objectweb/asm/util/Textifier.java Thu Oct 24 10:49:22 2013 +0200 +++ b/src/share/classes/jdk/internal/org/objectweb/asm/util/Textifier.java Thu Oct 24 11:26:50 2013 +0200 @@ -834,6 +834,12 @@ } @Override + public void visitMethodInsn(final int opcode, final String owner, + final String name, final String desc, final boolean ift) { + visitMethodInsn(opcode, owner, name, desc); + } + + @Override public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) { buf.setLength(0); diff -r 38c1b3ec92c5 src/share/classes/jdk/internal/org/objectweb/asm/util/TraceMethodVisitor.java --- a/src/share/classes/jdk/internal/org/objectweb/asm/util/TraceMethodVisitor.java Thu Oct 24 10:49:22 2013 +0200 +++ b/src/share/classes/jdk/internal/org/objectweb/asm/util/TraceMethodVisitor.java Thu Oct 24 11:26:50 2013 +0200 @@ -184,6 +184,13 @@ } @Override + public void visitMethodInsn(final int opcode, final String owner, + final String name, final String desc, final boolean itf) { + p.visitMethodInsn(opcode, owner, name, desc, itf); + super.visitMethodInsn(opcode, owner, name, desc, itf); + } + + @Override public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) { p.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);