refactoring: introduce CallableMethod abstraction (owner, signature and invoke opcode)
This commit is contained in:
@@ -0,0 +1,30 @@
|
|||||||
|
package org.jetbrains.jet.codegen;
|
||||||
|
|
||||||
|
import org.objectweb.asm.commons.Method;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author yole
|
||||||
|
*/
|
||||||
|
public class CallableMethod {
|
||||||
|
private final String owner;
|
||||||
|
private final Method descriptor;
|
||||||
|
private final int invokeOpcode;
|
||||||
|
|
||||||
|
public CallableMethod(String owner, Method descriptor, int invokeOpcode) {
|
||||||
|
this.owner = owner;
|
||||||
|
this.descriptor = descriptor;
|
||||||
|
this.invokeOpcode = invokeOpcode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOwner() {
|
||||||
|
return owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Method getDescriptor() {
|
||||||
|
return descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getInvokeOpcode() {
|
||||||
|
return invokeOpcode;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,7 +17,6 @@ import org.jetbrains.jet.lang.types.JetType;
|
|||||||
import org.jetbrains.jet.lang.types.TypeProjection;
|
import org.jetbrains.jet.lang.types.TypeProjection;
|
||||||
import org.jetbrains.jet.lang.types.TypeUtils;
|
import org.jetbrains.jet.lang.types.TypeUtils;
|
||||||
import org.jetbrains.jet.lexer.JetTokens;
|
import org.jetbrains.jet.lexer.JetTokens;
|
||||||
import org.jetbrains.jet.resolve.DescriptorRenderer;
|
|
||||||
import org.objectweb.asm.Label;
|
import org.objectweb.asm.Label;
|
||||||
import org.objectweb.asm.MethodVisitor;
|
import org.objectweb.asm.MethodVisitor;
|
||||||
import org.objectweb.asm.Opcodes;
|
import org.objectweb.asm.Opcodes;
|
||||||
@@ -785,30 +784,21 @@ public class ExpressionCodegen extends JetVisitor {
|
|||||||
}
|
}
|
||||||
else if (declarationPsiElement instanceof JetNamedFunction) {
|
else if (declarationPsiElement instanceof JetNamedFunction) {
|
||||||
final JetNamedFunction jetFunction = (JetNamedFunction) declarationPsiElement;
|
final JetNamedFunction jetFunction = (JetNamedFunction) declarationPsiElement;
|
||||||
methodDescriptor = typeMapper.mapSignature(jetFunction);
|
CallableMethod callableMethod = typeMapper.mapToCallableMethod(jetFunction);
|
||||||
|
|
||||||
if (functionParent instanceof NamespaceDescriptorImpl) {
|
if (functionParent instanceof NamespaceDescriptorImpl) {
|
||||||
if (jetFunction.getReceiverTypeRef() != null) {
|
if (jetFunction.getReceiverTypeRef() != null) {
|
||||||
ensureReceiverOnStack(expression, null);
|
ensureReceiverOnStack(expression, null);
|
||||||
}
|
}
|
||||||
pushMethodArguments(expression, methodDescriptor);
|
|
||||||
pushTypeArguments(expression);
|
|
||||||
final String owner = NamespaceCodegen.getJVMClassName(DescriptorRenderer.getFQName(functionParent));
|
|
||||||
v.invokestatic(owner, methodDescriptor.getName(), methodDescriptor.getDescriptor());
|
|
||||||
}
|
}
|
||||||
else if (functionParent instanceof ClassDescriptor) {
|
else if (functionParent instanceof ClassDescriptor) {
|
||||||
ClassDescriptor containingClass = (ClassDescriptor) functionParent;
|
ensureReceiverOnStack(expression, (ClassDescriptor) functionParent);
|
||||||
ensureReceiverOnStack(expression, containingClass);
|
|
||||||
pushMethodArguments(expression, methodDescriptor);
|
|
||||||
pushTypeArguments(expression);
|
|
||||||
final String owner = typeMapper.jvmName(containingClass, OwnerKind.INTERFACE);
|
|
||||||
int opcode = typeMapper.isInterface(containingClass, OwnerKind.INTERFACE)
|
|
||||||
? Opcodes.INVOKEINTERFACE
|
|
||||||
: Opcodes.INVOKEVIRTUAL;
|
|
||||||
v.visitMethodInsn(opcode,owner, methodDescriptor.getName(), methodDescriptor.getDescriptor());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new UnsupportedOperationException("don't know how to generate call to " + declarationPsiElement);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pushMethodArguments(expression, callableMethod.getDescriptor());
|
||||||
|
pushTypeArguments(expression);
|
||||||
|
invokeCallableMethod(callableMethod);
|
||||||
|
methodDescriptor = callableMethod.getDescriptor();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
gen(callee, Type.getObjectType(ClosureCodegen.getInternalClassName(fd)));
|
gen(callee, Type.getObjectType(ClosureCodegen.getInternalClassName(fd)));
|
||||||
@@ -840,6 +830,11 @@ public class ExpressionCodegen extends JetVisitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void invokeCallableMethod(CallableMethod callableMethod) {
|
||||||
|
v.visitMethodInsn(callableMethod.getInvokeOpcode(), callableMethod.getOwner(),
|
||||||
|
callableMethod.getDescriptor().getName(), callableMethod.getDescriptor().getDescriptor());
|
||||||
|
}
|
||||||
|
|
||||||
private Method generateJavaMethodCall(JetCallExpression expression, PsiMethod psiMethod) {
|
private Method generateJavaMethodCall(JetCallExpression expression, PsiMethod psiMethod) {
|
||||||
final PsiClass containingClass = psiMethod.getContainingClass();
|
final PsiClass containingClass = psiMethod.getContainingClass();
|
||||||
String owner = JetTypeMapper.jvmName(containingClass);
|
String owner = JetTypeMapper.jvmName(containingClass);
|
||||||
|
|||||||
@@ -298,6 +298,30 @@ public class JetTypeMapper {
|
|||||||
return new Method(f.getName(), returnType, parameterTypes.toArray(new Type[parameterTypes.size()]));
|
return new Method(f.getName(), returnType, parameterTypes.toArray(new Type[parameterTypes.size()]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CallableMethod mapToCallableMethod(JetNamedFunction f) {
|
||||||
|
final FunctionDescriptor functionDescriptor = bindingContext.getFunctionDescriptor(f);
|
||||||
|
final DeclarationDescriptor functionParent = functionDescriptor.getContainingDeclaration();
|
||||||
|
Method descriptor = mapSignature(f);
|
||||||
|
String owner;
|
||||||
|
int invokeOpcode;
|
||||||
|
if (functionParent instanceof NamespaceDescriptor) {
|
||||||
|
owner = NamespaceCodegen.getJVMClassName(DescriptorRenderer.getFQName(functionParent));
|
||||||
|
invokeOpcode = Opcodes.INVOKESTATIC;
|
||||||
|
}
|
||||||
|
else if (functionParent instanceof ClassDescriptor) {
|
||||||
|
ClassDescriptor containingClass = (ClassDescriptor) functionParent;
|
||||||
|
owner = jvmName(containingClass, OwnerKind.INTERFACE);
|
||||||
|
invokeOpcode = isInterface(containingClass, OwnerKind.INTERFACE)
|
||||||
|
? Opcodes.INVOKEINTERFACE
|
||||||
|
: Opcodes.INVOKEVIRTUAL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new UnsupportedOperationException("unknown function parent");
|
||||||
|
}
|
||||||
|
|
||||||
|
return new CallableMethod(owner, descriptor, invokeOpcode);
|
||||||
|
}
|
||||||
|
|
||||||
public Method mapSignature(String name, FunctionDescriptor f) {
|
public Method mapSignature(String name, FunctionDescriptor f) {
|
||||||
final JetType receiverType = f.getReceiverType();
|
final JetType receiverType = f.getReceiverType();
|
||||||
final List<ValueParameterDescriptor> parameters = f.getValueParameters();
|
final List<ValueParameterDescriptor> parameters = f.getValueParameters();
|
||||||
|
|||||||
Reference in New Issue
Block a user