Temporary generate old default method

This commit is contained in:
Michael Bogdanov
2016-01-21 17:23:23 +03:00
parent 829978a37d
commit a76d16931c
5 changed files with 46 additions and 8 deletions
@@ -57,10 +57,7 @@ import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature; import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
import org.jetbrains.kotlin.types.KotlinType; import org.jetbrains.kotlin.types.KotlinType;
import org.jetbrains.kotlin.types.TypeUtils; import org.jetbrains.kotlin.types.TypeUtils;
import org.jetbrains.org.objectweb.asm.AnnotationVisitor; import org.jetbrains.org.objectweb.asm.*;
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.commons.InstructionAdapter; import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
import org.jetbrains.org.objectweb.asm.commons.Method; import org.jetbrains.org.objectweb.asm.commons.Method;
import org.jetbrains.org.objectweb.asm.util.TraceMethodVisitor; import org.jetbrains.org.objectweb.asm.util.TraceMethodVisitor;
@@ -678,6 +675,15 @@ public class FunctionCodegen {
generateDefaultImplBody(owner, functionDescriptor, mv, loadStrategy, function, memberCodegen); generateDefaultImplBody(owner, functionDescriptor, mv, loadStrategy, function, memberCodegen);
endVisit(mv, "default method", getSourceFromDescriptor(functionDescriptor)); 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()); iv.areturn(signature.getReturnType());
} }
private void generateOldDefaultForFun(
Method newDefaultMethod,
JvmDeclarationOrigin origin,
int flags,
String[] exceptions,
String owner
) {
if ("<init>".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 @NotNull
private static FrameMap createFrameMap( private static FrameMap createFrameMap(
@NotNull GenerationState state, @NotNull GenerationState state,
@@ -9,5 +9,5 @@ class A {
} }
} }
// Test argument reordering when call site argument order differs from declaration one // Test argument reordering when call site argument order differs from declaration one
// 12 LOAD // 18 LOAD
// 5 STORE // 5 STORE
@@ -8,5 +8,5 @@ class A {
} }
} }
// Test there is no argument reordering when call site argument order same as declaration one // Test there is no argument reordering when call site argument order same as declaration one
// 9 LOAD // 15 LOAD
// 2 STORE // 2 STORE
@@ -14,4 +14,4 @@ interface A {
// 1 foo\( // 1 foo\(
// 1 getProp // 1 getProp
// 1 defaultFun\$ // 3 defaultFun\$
@@ -1,4 +1,4 @@
fun foo(a: Int = 1) {} fun foo(a: Int = 1) {}
// 0 _DefaultPackage.foo // 0 _DefaultPackage.foo
// 1 INVOKESTATIC TopLevelFunWithDefaultArgsKt\.foo // 2 INVOKESTATIC TopLevelFunWithDefaultArgsKt\.foo