From 80b78f0f6dadc572c32494afef75010fac9b2323 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Mon, 15 Apr 2013 19:18:59 +0400 Subject: [PATCH] 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 --- .../org/jetbrains/jet/codegen/ExpressionCodegen.java | 2 +- .../org/jetbrains/jet/codegen/FunctionTypesUtil.java | 11 +++++++++++ .../jetbrains/jet/codegen/state/JetTypeMapper.java | 9 +++++---- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 12e2860b087..eb11ff6d1c6 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -1975,7 +1975,7 @@ public class ExpressionCodegen extends JetVisitor 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); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionTypesUtil.java b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionTypesUtil.java index 5db420519b1..26d056a92f9 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionTypesUtil.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionTypesUtil.java @@ -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(); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/state/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/state/JetTypeMapper.java index c31054863bb..847eef08375 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/state/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/state/JetTypeMapper.java @@ -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()); } }