closure as callable method

This commit is contained in:
Dmitry Jemerov
2011-07-06 12:15:05 +02:00
parent 5eb2f913b3
commit 8317fbc290
2 changed files with 12 additions and 5 deletions
@@ -211,4 +211,10 @@ public class ClosureCodegen {
signatureWriter.visitClassType(rawRetType.getInternalName()); signatureWriter.visitClassType(rawRetType.getInternalName());
signatureWriter.visitEnd(); signatureWriter.visitEnd();
} }
public static CallableMethod asCallableMethod(FunctionDescriptor fd) {
Method descriptor = erasedInvokeSignature(fd);
String owner = getInternalClassName(fd);
return new CallableMethod(owner, descriptor, Opcodes.INVOKEVIRTUAL, Arrays.asList(descriptor.getArgumentTypes()));
}
} }
@@ -780,6 +780,8 @@ public class ExpressionCodegen extends JetVisitor {
if (declarationPsiElement == null) { if (declarationPsiElement == null) {
throw new UnsupportedOperationException("couldn't find declaration for " + funDescriptor); throw new UnsupportedOperationException("couldn't find declaration for " + funDescriptor);
} }
Method methodDescriptor; Method methodDescriptor;
if (declarationPsiElement instanceof PsiMethod) { if (declarationPsiElement instanceof PsiMethod) {
final PsiMethod psiMethod = (PsiMethod) declarationPsiElement; final PsiMethod psiMethod = (PsiMethod) declarationPsiElement;
@@ -814,15 +816,14 @@ public class ExpressionCodegen extends JetVisitor {
gen(callee, Type.getObjectType(ClosureCodegen.getInternalClassName(fd))); gen(callee, Type.getObjectType(ClosureCodegen.getInternalClassName(fd)));
boolean isExtensionFunction = fd.getReceiverType() != null; boolean isExtensionFunction = fd.getReceiverType() != null;
int paramCount = fd.getValueParameters().size();
if (isExtensionFunction) { if (isExtensionFunction) {
ensureReceiverOnStack(expression, null); ensureReceiverOnStack(expression, null);
paramCount++;
} }
methodDescriptor = ClosureCodegen.erasedInvokeSignature(fd); CallableMethod callableMethod = ClosureCodegen.asCallableMethod(fd);
pushMethodArguments(expression, methodDescriptor); pushMethodArguments(expression, callableMethod.getValueParameterTypes());
v.invokevirtual(ClosureCodegen.getInternalClassName(fd), "invoke", methodDescriptor.getDescriptor()); callableMethod.invoke(v);
methodDescriptor = callableMethod.getSignature();
} }
if (methodDescriptor.getReturnType() != Type.VOID_TYPE) { if (methodDescriptor.getReturnType() != Type.VOID_TYPE) {