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 @NotNull
private CallableMethod resolveToCallableMethod(@NotNull FunctionDescriptor fd, boolean superCall, @NotNull CodegenContext context) { private CallableMethod resolveToCallableMethod(@NotNull FunctionDescriptor fd, boolean superCall, @NotNull CodegenContext context) {
if (isCallAsFunctionObject(fd)) { if (isCallAsFunctionObject(fd)) {
return typeMapper.asCallableMethod(createInvoke(fd)); return typeMapper.mapToFunctionInvokeCallableMethod(createInvoke(fd));
} }
else { else {
SimpleFunctionDescriptor originalOfSamAdapter = getOriginalIfSamAdapter(fd); SimpleFunctionDescriptor originalOfSamAdapter = getOriginalIfSamAdapter(fd);
@@ -80,6 +80,17 @@ public class FunctionTypesUtil {
return functionImpl; 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 @NotNull
public static JvmClassName getFunctionImplClassName(@NotNull FunctionDescriptor descriptor) { public static JvmClassName getFunctionImplClassName(@NotNull FunctionDescriptor descriptor) {
int paramCount = descriptor.getValueParameters().size(); 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.boxType;
import static org.jetbrains.jet.codegen.AsmUtil.getTraitImplThisParameterType; import static org.jetbrains.jet.codegen.AsmUtil.getTraitImplThisParameterType;
import static org.jetbrains.jet.codegen.CodegenUtil.*; 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.*; import static org.jetbrains.jet.codegen.binding.CodegenBinding.*;
public class JetTypeMapper extends BindingTraceAware { public class JetTypeMapper extends BindingTraceAware {
@@ -936,9 +936,10 @@ public class JetTypeMapper extends BindingTraceAware {
return null; return null;
} }
public CallableMethod asCallableMethod(FunctionDescriptor fd) { @NotNull
public CallableMethod mapToFunctionInvokeCallableMethod(@NotNull FunctionDescriptor fd) {
JvmMethodSignature descriptor = erasedInvokeSignature(fd); JvmMethodSignature descriptor = erasedInvokeSignature(fd);
JvmClassName owner = getFunctionImplClassName(fd); JvmClassName owner = getFunctionTraitClassName(fd);
Type receiverParameterType; Type receiverParameterType;
ReceiverParameterDescriptor receiverParameter = fd.getOriginal().getReceiverParameter(); ReceiverParameterDescriptor receiverParameter = fd.getOriginal().getReceiverParameter();
if (receiverParameter != null) { if (receiverParameter != null) {
@@ -947,6 +948,6 @@ public class JetTypeMapper extends BindingTraceAware {
else { else {
receiverParameterType = null; 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());
} }
} }