invokeinterface FunctionN.invoke()

Instead of invokevirtual on FunctionImpl class, do invokeinterface on a
Function trait. This will allow to invoke functions on classes which don't
inherit from FunctionImpl classes.

Also rename the method to the more sensible name
This commit is contained in:
Alexander Udalov
2013-04-15 19:18:59 +04:00
parent 141b996709
commit 80b78f0f6d
3 changed files with 17 additions and 5 deletions
@@ -1975,7 +1975,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
@NotNull
private CallableMethod resolveToCallableMethod(@NotNull FunctionDescriptor fd, boolean superCall, @NotNull CodegenContext context) {
if (isCallAsFunctionObject(fd)) {
return typeMapper.asCallableMethod(createInvoke(fd));
return typeMapper.mapToFunctionInvokeCallableMethod(createInvoke(fd));
}
else {
SimpleFunctionDescriptor originalOfSamAdapter = getOriginalIfSamAdapter(fd);
@@ -80,6 +80,17 @@ public class FunctionTypesUtil {
return functionImpl;
}
@NotNull
public static JvmClassName getFunctionTraitClassName(@NotNull FunctionDescriptor descriptor) {
int paramCount = descriptor.getValueParameters().size();
if (descriptor.getReceiverParameter() != null) {
return JvmClassName.byInternalName("jet/ExtensionFunction" + paramCount);
}
else {
return JvmClassName.byInternalName("jet/Function" + paramCount);
}
}
@NotNull
public static JvmClassName getFunctionImplClassName(@NotNull FunctionDescriptor descriptor) {
int paramCount = descriptor.getValueParameters().size();
@@ -47,7 +47,7 @@ import static org.jetbrains.asm4.Opcodes.*;
import static org.jetbrains.jet.codegen.AsmUtil.boxType;
import static org.jetbrains.jet.codegen.AsmUtil.getTraitImplThisParameterType;
import static org.jetbrains.jet.codegen.CodegenUtil.*;
import static org.jetbrains.jet.codegen.FunctionTypesUtil.getFunctionImplClassName;
import static org.jetbrains.jet.codegen.FunctionTypesUtil.getFunctionTraitClassName;
import static org.jetbrains.jet.codegen.binding.CodegenBinding.*;
public class JetTypeMapper extends BindingTraceAware {
@@ -936,9 +936,10 @@ public class JetTypeMapper extends BindingTraceAware {
return null;
}
public CallableMethod asCallableMethod(FunctionDescriptor fd) {
@NotNull
public CallableMethod mapToFunctionInvokeCallableMethod(@NotNull FunctionDescriptor fd) {
JvmMethodSignature descriptor = erasedInvokeSignature(fd);
JvmClassName owner = getFunctionImplClassName(fd);
JvmClassName owner = getFunctionTraitClassName(fd);
Type receiverParameterType;
ReceiverParameterDescriptor receiverParameter = fd.getOriginal().getReceiverParameter();
if (receiverParameter != null) {
@@ -947,6 +948,6 @@ public class JetTypeMapper extends BindingTraceAware {
else {
receiverParameterType = null;
}
return new CallableMethod(owner, null, null, descriptor, INVOKEVIRTUAL, owner, receiverParameterType, owner.getAsmType());
return new CallableMethod(owner, null, null, descriptor, INVOKEINTERFACE, owner, receiverParameterType, owner.getAsmType());
}
}