diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java index 76f48b07f6d..a575f123661 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java @@ -57,10 +57,7 @@ import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature; import org.jetbrains.kotlin.types.KotlinType; import org.jetbrains.kotlin.types.TypeUtils; -import org.jetbrains.org.objectweb.asm.AnnotationVisitor; -import org.jetbrains.org.objectweb.asm.Label; -import org.jetbrains.org.objectweb.asm.MethodVisitor; -import org.jetbrains.org.objectweb.asm.Type; +import org.jetbrains.org.objectweb.asm.*; import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter; import org.jetbrains.org.objectweb.asm.commons.Method; import org.jetbrains.org.objectweb.asm.util.TraceMethodVisitor; @@ -678,6 +675,15 @@ public class FunctionCodegen { generateDefaultImplBody(owner, functionDescriptor, mv, loadStrategy, function, memberCodegen); endVisit(mv, "default method", getSourceFromDescriptor(functionDescriptor)); } + + generateOldDefaultForFun(defaultMethod, + JvmDeclarationOriginKt.Synthetic(function, functionDescriptor), + flags, + getThrownExceptions(functionDescriptor, typeMapper), + (owner.getContextKind() == OwnerKind.DEFAULT_IMPLS ? + typeMapper.mapDefaultImpls((ClassDescriptor) functionDescriptor.getContainingDeclaration()) : + typeMapper.mapImplementationOwner(functionDescriptor)).getInternalName() + ); } } @@ -742,6 +748,38 @@ public class FunctionCodegen { iv.areturn(signature.getReturnType()); } + private void generateOldDefaultForFun( + Method newDefaultMethod, + JvmDeclarationOrigin origin, + int flags, + String[] exceptions, + String owner + ) { + if ("".equals(newDefaultMethod.getName())) { + return; + } + String oldSignature = newDefaultMethod.getDescriptor().replaceFirst("Ljava/lang/Object;\\)", ")"); + MethodVisitor mv = v.newMethod( + origin, + flags, + newDefaultMethod.getName(), + oldSignature, + null, + exceptions + ); + mv.visitCode(); + int index = 0; + InstructionAdapter iv = new InstructionAdapter(mv); + for (Type type: Type.getArgumentTypes(oldSignature)) { + iv.load(index, type); + index += type.getSize(); + } + iv.aconst(null); + iv.visitMethodInsn(Opcodes.INVOKESTATIC, owner, newDefaultMethod.getName(), newDefaultMethod.getDescriptor(), false); + iv.areturn(newDefaultMethod.getReturnType()); + mv.visitEnd(); + } + @NotNull private static FrameMap createFrameMap( @NotNull GenerationState state, diff --git a/compiler/testData/codegen/bytecodeText/argumentOrder/argumentReorderWithDefault.kt b/compiler/testData/codegen/bytecodeText/argumentOrder/argumentReorderWithDefault.kt index f372d21eca1..3f473f2eabb 100644 --- a/compiler/testData/codegen/bytecodeText/argumentOrder/argumentReorderWithDefault.kt +++ b/compiler/testData/codegen/bytecodeText/argumentOrder/argumentReorderWithDefault.kt @@ -9,5 +9,5 @@ class A { } } // Test argument reordering when call site argument order differs from declaration one -// 12 LOAD +// 18 LOAD // 5 STORE \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/argumentOrder/sameOrderWithDefault.kt b/compiler/testData/codegen/bytecodeText/argumentOrder/sameOrderWithDefault.kt index 9eb56ffefa0..16cf9b37519 100644 --- a/compiler/testData/codegen/bytecodeText/argumentOrder/sameOrderWithDefault.kt +++ b/compiler/testData/codegen/bytecodeText/argumentOrder/sameOrderWithDefault.kt @@ -8,5 +8,5 @@ class A { } } // Test there is no argument reordering when call site argument order same as declaration one -// 9 LOAD +// 15 LOAD // 2 STORE \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/interfaces/noPrivateMemberInJavaInterface.kt b/compiler/testData/codegen/bytecodeText/interfaces/noPrivateMemberInJavaInterface.kt index 416089932f6..52062a70825 100644 --- a/compiler/testData/codegen/bytecodeText/interfaces/noPrivateMemberInJavaInterface.kt +++ b/compiler/testData/codegen/bytecodeText/interfaces/noPrivateMemberInJavaInterface.kt @@ -14,4 +14,4 @@ interface A { // 1 foo\( // 1 getProp -// 1 defaultFun\$ +// 3 defaultFun\$ diff --git a/compiler/testData/codegen/bytecodeText/topLevelFunWithDefaultArgs.kt b/compiler/testData/codegen/bytecodeText/topLevelFunWithDefaultArgs.kt index ff8facf98dc..1a1cff3ff6a 100644 --- a/compiler/testData/codegen/bytecodeText/topLevelFunWithDefaultArgs.kt +++ b/compiler/testData/codegen/bytecodeText/topLevelFunWithDefaultArgs.kt @@ -1,4 +1,4 @@ fun foo(a: Int = 1) {} // 0 _DefaultPackage.foo -// 1 INVOKESTATIC TopLevelFunWithDefaultArgsKt\.foo +// 2 INVOKESTATIC TopLevelFunWithDefaultArgsKt\.foo