diff -r e6bc0dca294b src/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java --- a/src/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java Tue Oct 15 12:53:54 2013 +0200 +++ b/src/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java Thu Oct 24 11:22:56 2013 +0200 @@ -49,7 +49,7 @@ /* package */ final class InnerClassLambdaMetafactory extends AbstractValidatingLambdaMetafactory { private static final Unsafe UNSAFE = Unsafe.getUnsafe(); - private static final int CLASSFILE_VERSION = 51; + private static final int CLASSFILE_VERSION = 52; private static final String METHOD_DESCRIPTOR_VOID = Type.getMethodDescriptor(Type.VOID_TYPE); private static final String JAVA_LANG_OBJECT = "java/lang/Object"; private static final String NAME_CTOR = ""; @@ -392,7 +392,8 @@ convertArgumentTypes(Type.getArgumentTypes(methodDescriptor)); // Invoke the method we want to forward to - visitMethodInsn(invocationOpcode(), implMethodClassName, implMethodName, implMethodDesc); + visitMethodInsn(invocationOpcode(), implMethodClassName, implMethodName, implMethodDesc, + implDefiningClass.isInterface()); // Convert the return value (if any) and return it // Note: if adapting from non-void to void, the 'return' diff -r e6bc0dca294b src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java --- a/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java Tue Oct 15 12:53:54 2013 +0200 +++ b/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java Thu Oct 24 11:22:56 2013 +0200 @@ -275,7 +275,7 @@ */ private void classFilePrologue() { cw = new ClassWriter(ClassWriter.COMPUTE_MAXS + ClassWriter.COMPUTE_FRAMES); - cw.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL + Opcodes.ACC_SUPER, className, null, superName, null); + cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL + Opcodes.ACC_SUPER, className, null, superName, null); cw.visitSource(sourceFile, null); String invokerDesc = invokerType.toMethodDescriptorString(); @@ -646,7 +646,8 @@ // invocation if (member.isMethod()) { mtype = member.getMethodType().toMethodDescriptorString(); - mv.visitMethodInsn(refKindOpcode(refKind), cname, mname, mtype); + mv.visitMethodInsn(refKindOpcode(refKind), cname, mname, mtype, + member.getDeclaringClass().isInterface()); } else { mtype = MethodType.toFieldDescriptorString(member.getFieldType()); mv.visitFieldInsn(refKindOpcode(refKind), cname, mname, mtype); diff -r e6bc0dca294b src/share/classes/jdk/internal/org/objectweb/asm/ClassReader.java --- a/src/share/classes/jdk/internal/org/objectweb/asm/ClassReader.java Tue Oct 15 12:53:54 2013 +0200 +++ b/src/share/classes/jdk/internal/org/objectweb/asm/ClassReader.java Thu Oct 24 11:22:56 2013 +0200 @@ -1434,12 +1434,15 @@ case ClassWriter.FIELDORMETH_INSN: case ClassWriter.ITFMETH_INSN: { int cpIndex = items[readUnsignedShort(u + 1)]; + final boolean itf = (b[cpIndex - 1] == ClassWriter.IMETH); String iowner = readClass(cpIndex, c); cpIndex = items[readUnsignedShort(cpIndex + 2)]; String iname = readUTF8(cpIndex, c); String idesc = readUTF8(cpIndex + 2, c); if (opcode < Opcodes.INVOKEVIRTUAL) { mv.visitFieldInsn(opcode, iowner, iname, idesc); + } else if (itf && opcode != Opcodes.INVOKEINTERFACE) { + mv.visitMethodInsn(opcode, iowner, iname, idesc, itf); // use new API only if necessary } else { mv.visitMethodInsn(opcode, iowner, iname, idesc); } diff -r e6bc0dca294b src/share/classes/jdk/internal/org/objectweb/asm/MethodVisitor.java --- a/src/share/classes/jdk/internal/org/objectweb/asm/MethodVisitor.java Tue Oct 15 12:53:54 2013 +0200 +++ b/src/share/classes/jdk/internal/org/objectweb/asm/MethodVisitor.java Thu Oct 24 11:22:56 2013 +0200 @@ -474,6 +474,31 @@ } /** + * Visits a method instruction. A method instruction is an instruction that + * invokes a method; in addition, if itf is true, the owner is assumed to be an interface. + * + * @param opcode + * the opcode of the type instruction to be visited. This opcode + * is either INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or + * INVOKEINTERFACE. + * @param owner + * the internal name of the method's owner class (see + * {@link Type#getInternalName() getInternalName}). + * @param name + * the method's name. + * @param desc + * the method's descriptor (see {@link Type Type}). + * @param itf + * whether to the owner of the method is assumed to be an interface + */ + public void visitMethodInsn(int opcode, String owner, String name, + String desc, boolean itf) { + if (mv != null) { + mv.visitMethodInsn(opcode, owner, name, desc, itf); + } + } + + /** * Visits an invokedynamic instruction. * * @param name diff -r e6bc0dca294b src/share/classes/jdk/internal/org/objectweb/asm/MethodWriter.java --- a/src/share/classes/jdk/internal/org/objectweb/asm/MethodWriter.java Tue Oct 15 12:53:54 2013 +0200 +++ b/src/share/classes/jdk/internal/org/objectweb/asm/MethodWriter.java Thu Oct 24 11:22:56 2013 +0200 @@ -914,9 +914,8 @@ @Override public void visitMethodInsn(final int opcode, final String owner, - final String name, final String desc) { + final String name, final String desc, final boolean itf) { lastCodeOffset = code.length; - boolean itf = opcode == Opcodes.INVOKEINTERFACE; Item i = cw.newMethodItem(owner, name, desc, itf); int argSize = i.intVal; // Label currentBlock = this.currentBlock; @@ -954,7 +953,7 @@ } } // adds the instruction to the bytecode of the method - if (itf) { + if (opcode == Opcodes.INVOKEINTERFACE) { if (argSize == 0) { argSize = Type.getArgumentsAndReturnSizes(desc); i.intVal = argSize; @@ -966,6 +965,13 @@ } @Override + public void visitMethodInsn(final int opcode, final String owner, + final String name, final String desc) { + final boolean itf = opcode == Opcodes.INVOKEINTERFACE; + visitMethodInsn(opcode, owner, name, desc, itf); + } + + @Override public void visitInvokeDynamicInsn(final String name, final String desc, final Handle bsm, final Object... bsmArgs) { lastCodeOffset = code.length;