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) {
for (FunctionDescriptor overriddenFunction : overriddenFunctions) {
// 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());
}
@@ -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) {
Type type1 = state.getTypeMapper().mapType(overriddenFunction.getOriginal().getReturnType());
Type type2 = state.getTypeMapper().mapType(functionDescriptor.getReturnType());
if(!type1.equals(type2)) {
Method overriden = state.getTypeMapper().mapSignature(overriddenFunction.getName(), overriddenFunction.getOriginal()).getAsmMethod();
Method method = state.getTypeMapper().mapSignature(functionDescriptor.getName(), functionDescriptor).getAsmMethod();
Method overriden = state.getTypeMapper().mapSignature(overriddenFunction.getName(), overriddenFunction.getOriginal()).getAsmMethod();
if(differentMethods(method, overriden)) {
int flags = ACC_PUBLIC; // TODO.
final MethodVisitor mv = v.newMethod(null, flags, jvmSignature.getName(), overriden.getDescriptor(), null, null);
if (v.generateCode()) {
mv.visitCode();
Type[] argTypes = jvmSignature.getArgumentTypes();
Type[] argTypes = overriden.getArgumentTypes();
InstructionAdapter iv = new InstructionAdapter(mv);
iv.load(0, JetTypeMapper.TYPE_OBJECT);
for (int i = 0, reg = 1; i < argTypes.length; i++) {
Type argType = argTypes[i];
iv.load(reg, argType);
if(argType.getSort() == Type.OBJECT) {
iv.checkcast(argType);
StackValue.onStack(JetTypeMapper.TYPE_OBJECT).put(method.getArgumentTypes()[i], iv);
}
//noinspection AssignmentToForLoopParameter
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 {
blackBoxFile("regressions/kt903.jet");
}
public void testKt940 () throws Exception {
blackBoxFile("regressions/kt940.kt");
}
}