KT-940 proper calculation of bridge methods

This commit is contained in:
Alex Tkachman
2012-01-10 19:50:13 +02:00
parent 0af995d79b
commit 2e0b1863cd
3 changed files with 39 additions and 7 deletions
@@ -254,7 +254,7 @@ public class FunctionCodegen {
if(kind != OwnerKind.TRAIT_IMPL) { if(kind != OwnerKind.TRAIT_IMPL) {
for (FunctionDescriptor overriddenFunction : overriddenFunctions) { for (FunctionDescriptor overriddenFunction : overriddenFunctions) {
// TODO should we check params here as well? // TODO should we check params here as well?
checkOverride(owner, state, v, jvmSignature, functionDescriptor, overriddenFunction); checkOverride(owner, state, v, jvmSignature, functionDescriptor, overriddenFunction.getOriginal());
} }
checkOverride(owner, state, v, jvmSignature, functionDescriptor, functionDescriptor.getOriginal()); checkOverride(owner, state, v, jvmSignature, functionDescriptor, functionDescriptor.getOriginal());
} }
@@ -412,26 +412,39 @@ public class FunctionCodegen {
} }
} }
private static boolean differentMethods(Method method, Method overriden) {
if(!method.getReturnType().equals(overriden.getReturnType()))
return true;
Type[] methodArgumentTypes = method.getArgumentTypes();
Type[] overridenArgumentTypes = overriden.getArgumentTypes();
if(methodArgumentTypes.length != overridenArgumentTypes.length)
return true;
for(int i = 0; i != methodArgumentTypes.length; ++i)
if(!methodArgumentTypes[i].equals(overridenArgumentTypes[i]))
return true;
return false;
}
private static void checkOverride(CodegenContext owner, GenerationState state, ClassBuilder v, Method jvmSignature, FunctionDescriptor functionDescriptor, FunctionDescriptor overriddenFunction) { private static void checkOverride(CodegenContext owner, GenerationState state, ClassBuilder v, Method jvmSignature, FunctionDescriptor functionDescriptor, FunctionDescriptor overriddenFunction) {
Type type1 = state.getTypeMapper().mapType(overriddenFunction.getOriginal().getReturnType()); Method method = state.getTypeMapper().mapSignature(functionDescriptor.getName(), functionDescriptor).getAsmMethod();
Type type2 = state.getTypeMapper().mapType(functionDescriptor.getReturnType()); Method overriden = state.getTypeMapper().mapSignature(overriddenFunction.getName(), overriddenFunction.getOriginal()).getAsmMethod();
if(!type1.equals(type2)) { if(differentMethods(method, overriden)) {
Method overriden = state.getTypeMapper().mapSignature(overriddenFunction.getName(), overriddenFunction.getOriginal()).getAsmMethod();
int flags = ACC_PUBLIC; // TODO. int flags = ACC_PUBLIC; // TODO.
final MethodVisitor mv = v.newMethod(null, flags, jvmSignature.getName(), overriden.getDescriptor(), null, null); final MethodVisitor mv = v.newMethod(null, flags, jvmSignature.getName(), overriden.getDescriptor(), null, null);
if (v.generateCode()) { if (v.generateCode()) {
mv.visitCode(); mv.visitCode();
Type[] argTypes = jvmSignature.getArgumentTypes(); Type[] argTypes = overriden.getArgumentTypes();
InstructionAdapter iv = new InstructionAdapter(mv); InstructionAdapter iv = new InstructionAdapter(mv);
iv.load(0, JetTypeMapper.TYPE_OBJECT); iv.load(0, JetTypeMapper.TYPE_OBJECT);
for (int i = 0, reg = 1; i < argTypes.length; i++) { for (int i = 0, reg = 1; i < argTypes.length; i++) {
Type argType = argTypes[i]; Type argType = argTypes[i];
iv.load(reg, argType); iv.load(reg, argType);
if(argType.getSort() == Type.OBJECT) { if(argType.getSort() == Type.OBJECT) {
iv.checkcast(argType); StackValue.onStack(JetTypeMapper.TYPE_OBJECT).put(method.getArgumentTypes()[i], iv);
} }
//noinspection AssignmentToForLoopParameter //noinspection AssignmentToForLoopParameter
reg += argType.getSize(); reg += argType.getSize();
} }
@@ -0,0 +1,15 @@
import java.util.*
fun box() : String {
val w = object : Comparator<String?> {
override fun compare(o1 : String?, o2 : String?) : Int {
val l1 : Int = o1?.length ?: 0
val l2 = o2?.length ?: 0
return l1 - l2
}
}
w.compare("aaa", "bbb")
return "OK"
}
@@ -241,4 +241,8 @@ public class ClassGenTest extends CodegenTestCase {
public void testKt903 () throws Exception { public void testKt903 () throws Exception {
blackBoxFile("regressions/kt903.jet"); blackBoxFile("regressions/kt903.jet");
} }
public void testKt940 () throws Exception {
blackBoxFile("regressions/kt940.kt");
}
} }