Refactor CallableMethod, add convenient methods

It no longer exposes its JvmMethodSignature
This commit is contained in:
Alexander Udalov
2013-12-29 20:42:13 +04:00
parent 28d2306aa1
commit d73b2057e3
5 changed files with 45 additions and 40 deletions
@@ -20,7 +20,9 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.asm4.Type; import org.jetbrains.asm4.Type;
import org.jetbrains.asm4.commons.InstructionAdapter; import org.jetbrains.asm4.commons.InstructionAdapter;
import org.jetbrains.asm4.commons.Method;
import org.jetbrains.asm4.util.Printer; import org.jetbrains.asm4.util.Printer;
import org.jetbrains.jet.codegen.signature.JvmMethodParameterSignature;
import org.jetbrains.jet.codegen.signature.JvmMethodSignature; import org.jetbrains.jet.codegen.signature.JvmMethodSignature;
import org.jetbrains.jet.codegen.state.GenerationState; import org.jetbrains.jet.codegen.state.GenerationState;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
@@ -32,25 +34,24 @@ import static org.jetbrains.asm4.Opcodes.INVOKESPECIAL;
import static org.jetbrains.asm4.Opcodes.INVOKESTATIC; import static org.jetbrains.asm4.Opcodes.INVOKESTATIC;
public class CallableMethod implements Callable { public class CallableMethod implements Callable {
@NotNull
private final Type owner; private final Type owner;
@Nullable
private final Type defaultImplOwner; private final Type defaultImplOwner;
@Nullable
private final Type defaultImplParam; private final Type defaultImplParam;
private final JvmMethodSignature signature; private final JvmMethodSignature signature;
private final int invokeOpcode; private final int invokeOpcode;
@Nullable
private final Type thisClass; private final Type thisClass;
@Nullable
private final Type receiverParameterType; private final Type receiverParameterType;
@Nullable
private final Type generateCalleeType; private final Type generateCalleeType;
public CallableMethod( public CallableMethod(
@NotNull Type owner, @Nullable Type defaultImplOwner, @Nullable Type defaultImplParam, @NotNull Type owner,
JvmMethodSignature signature, int invokeOpcode, @Nullable Type defaultImplOwner,
@Nullable Type thisClass, @Nullable Type receiverParameterType, @Nullable Type generateCalleeType @Nullable Type defaultImplParam,
@NotNull JvmMethodSignature signature,
int invokeOpcode,
@Nullable Type thisClass,
@Nullable Type receiverParameterType,
@Nullable Type generateCalleeType
) { ) {
this.owner = owner; this.owner = owner;
this.defaultImplOwner = defaultImplOwner; this.defaultImplOwner = defaultImplOwner;
@@ -67,18 +68,25 @@ public class CallableMethod implements Callable {
return owner; return owner;
} }
public JvmMethodSignature getSignature() { @NotNull
return signature; public List<JvmMethodParameterSignature> getValueParameters() {
return signature.getKotlinParameterTypes();
}
@NotNull
public List<Type> getValueParameterTypes() {
return signature.getValueParameterTypes();
}
@NotNull
public Method getAsmMethod() {
return signature.getAsmMethod();
} }
public int getInvokeOpcode() { public int getInvokeOpcode() {
return invokeOpcode; return invokeOpcode;
} }
public List<Type> getValueParameterTypes() {
return signature.getValueParameterTypes();
}
@Nullable @Nullable
public Type getThisType() { public Type getThisType() {
return thisClass; return thisClass;
@@ -90,8 +98,7 @@ public class CallableMethod implements Callable {
} }
private void invoke(InstructionAdapter v) { private void invoke(InstructionAdapter v) {
v.visitMethodInsn(getInvokeOpcode(), owner.getInternalName(), getSignature().getAsmMethod().getName(), v.visitMethodInsn(getInvokeOpcode(), owner.getInternalName(), getAsmMethod().getName(), getAsmMethod().getDescriptor());
getSignature().getAsmMethod().getDescriptor());
} }
public void invokeWithNotNullAssertion( public void invokeWithNotNullAssertion(
@@ -117,17 +124,18 @@ public class CallableMethod implements Callable {
throw new IllegalStateException(); throw new IllegalStateException();
} }
Method method = getAsmMethod();
v.iconst(mask); v.iconst(mask);
String desc = getSignature().getAsmMethod().getDescriptor().replace(")", "I)"); String desc = method.getDescriptor().replace(")", "I)");
if ("<init>".equals(getSignature().getAsmMethod().getName())) { if ("<init>".equals(method.getName())) {
v.visitMethodInsn(INVOKESPECIAL, defaultImplOwner.getInternalName(), "<init>", desc); v.visitMethodInsn(INVOKESPECIAL, defaultImplOwner.getInternalName(), "<init>", desc);
} }
else { else {
if (getInvokeOpcode() != INVOKESTATIC) { if (getInvokeOpcode() != INVOKESTATIC) {
desc = desc.replace("(", "(" + defaultImplParam.getDescriptor()); desc = desc.replace("(", "(" + defaultImplParam.getDescriptor());
} }
v.visitMethodInsn(INVOKESTATIC, defaultImplOwner.getInternalName(), v.visitMethodInsn(INVOKESTATIC, defaultImplOwner.getInternalName(), method.getName() + JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX, desc);
getSignature().getAsmMethod().getName() + JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX, desc);
} }
} }
@@ -145,6 +153,7 @@ public class CallableMethod implements Callable {
return thisClass != null && generateCalleeType == null; return thisClass != null && generateCalleeType == null;
} }
@NotNull
public Type getReturnType() { public Type getReturnType() {
return signature.getReturnType(); return signature.getReturnType();
} }
@@ -1335,7 +1335,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
v.anew(type); v.anew(type);
v.dup(); v.dup();
Method cons = constructor.getSignature().getAsmMethod();
pushClosureOnStack(closure, false); pushClosureOnStack(closure, false);
@@ -1348,13 +1347,13 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
assert superConstructor != null; assert superConstructor != null;
//noinspection SuspiciousMethodCalls //noinspection SuspiciousMethodCalls
CallableMethod superCallable = typeMapper.mapToCallableMethod(superConstructor); CallableMethod superCallable = typeMapper.mapToCallableMethod(superConstructor);
Type[] argumentTypes = superCallable.getSignature().getAsmMethod().getArgumentTypes(); Type[] argumentTypes = superCallable.getAsmMethod().getArgumentTypes();
ResolvedCall resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, superCall.getCalleeExpression()); ResolvedCall resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, superCall.getCalleeExpression());
assert resolvedCall != null; assert resolvedCall != null;
pushMethodArguments(resolvedCall, Arrays.asList(argumentTypes)); pushMethodArguments(resolvedCall, Arrays.asList(argumentTypes));
} }
v.invokespecial(type.getInternalName(), "<init>", cons.getDescriptor()); v.invokespecial(type.getInternalName(), "<init>", constructor.getAsmMethod().getDescriptor());
return StackValue.onStack(type); return StackValue.onStack(type);
} }
@@ -2007,7 +2006,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
CallableMethod callableMethod = (CallableMethod) callable; CallableMethod callableMethod = (CallableMethod) callable;
invokeMethodWithArguments(callableMethod, resolvedCall, receiver); invokeMethodWithArguments(callableMethod, resolvedCall, receiver);
Type returnType = typeMapper.mapReturnType(resolvedCall.getResultingDescriptor()); Type returnType = typeMapper.mapReturnType(resolvedCall.getResultingDescriptor());
StackValue.coerce(callableMethod.getSignature().getReturnType(), returnType, v); StackValue.coerce(callableMethod.getReturnType(), returnType, v);
return StackValue.onStack(returnType); return StackValue.onStack(returnType);
} }
else { else {
@@ -3382,7 +3381,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
assert resolvedCall != null : "couldn't find resolved call: " + expression.getText(); assert resolvedCall != null : "couldn't find resolved call: " + expression.getText();
Callable callable = resolveToCallable(operationDescriptor, false); Callable callable = resolveToCallable(operationDescriptor, false);
Method asmMethod = resolveToCallableMethod(operationDescriptor, false, context).getSignature().getAsmMethod(); Method asmMethod = resolveToCallableMethod(operationDescriptor, false, context).getAsmMethod();
Type[] argumentTypes = asmMethod.getArgumentTypes(); Type[] argumentTypes = asmMethod.getArgumentTypes();
if (callable instanceof CallableMethod) { if (callable instanceof CallableMethod) {
@@ -479,7 +479,7 @@ public class FunctionCodegen extends ParentCodegenAwareImpl {
mask |= (1 << parameterDescriptor.getIndex()); mask |= (1 << parameterDescriptor.getIndex());
} }
v.iconst(mask); v.iconst(mask);
String desc = method.getSignature().getAsmMethod().getDescriptor().replace(")", "I)"); String desc = method.getAsmMethod().getDescriptor().replace(")", "I)");
v.invokespecial(methodOwner.getInternalName(), "<init>", desc); v.invokespecial(methodOwner.getInternalName(), "<init>", desc);
v.areturn(Type.VOID_TYPE); v.areturn(Type.VOID_TYPE);
endVisit(mv, "default constructor for " + methodOwner.getInternalName(), null); endVisit(mv, "default constructor for " + methodOwner.getInternalName(), null);
@@ -608,8 +608,8 @@ public class FunctionCodegen extends ParentCodegenAwareImpl {
method = typeMapper.mapToCallableMethod(functionDescriptor, false, methodContext); method = typeMapper.mapToCallableMethod(functionDescriptor, false, methodContext);
} }
iv.visitMethodInsn(method.getInvokeOpcode(), method.getOwner().getInternalName(), method.getSignature().getAsmMethod().getName(), iv.visitMethodInsn(method.getInvokeOpcode(), method.getOwner().getInternalName(), method.getAsmMethod().getName(),
method.getSignature().getAsmMethod().getDescriptor()); method.getAsmMethod().getDescriptor());
iv.areturn(signature.getReturnType()); iv.areturn(signature.getReturnType());
@@ -846,7 +846,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
parameterIndex += type.getSize(); parameterIndex += type.getSize();
} }
String constructorJvmDescriptor = typeMapper.mapToCallableMethod(constructor).getSignature().getAsmMethod().getDescriptor(); String constructorJvmDescriptor = typeMapper.mapToCallableMethod(constructor).getAsmMethod().getDescriptor();
iv.invokespecial(thisDescriptorType.getInternalName(), "<init>", constructorJvmDescriptor); iv.invokespecial(thisDescriptorType.getInternalName(), "<init>", constructorJvmDescriptor);
iv.areturn(thisDescriptorType); iv.areturn(thisDescriptorType);
@@ -995,8 +995,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
typeMapper.mapToCallableMethod((ConstructorDescriptor) functionDescriptor) : typeMapper.mapToCallableMethod((ConstructorDescriptor) functionDescriptor) :
typeMapper.mapToCallableMethod(functionDescriptor, callFromAccessor, context); typeMapper.mapToCallableMethod(functionDescriptor, callFromAccessor, context);
Type[] argTypes = callableMethod.getSignature().getAsmMethod().getArgumentTypes();
int reg = 1; int reg = 1;
if (isConstructor) { if (isConstructor) {
iv.anew(callableMethod.getOwner()); iv.anew(callableMethod.getOwner());
@@ -1007,7 +1005,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
iv.load(0, OBJECT_TYPE); iv.load(0, OBJECT_TYPE);
} }
for (Type argType : argTypes) { for (Type argType : callableMethod.getAsmMethod().getArgumentTypes()) {
iv.load(reg, argType); iv.load(reg, argType);
reg += argType.getSize(); reg += argType.getSize();
} }
@@ -1492,7 +1490,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
if (isAnonymousObject(descriptor) && superCall instanceof JetDelegatorToSuperCall) { if (isAnonymousObject(descriptor) && superCall instanceof JetDelegatorToSuperCall) {
int nextVar = findFirstSuperArgument(method); int nextVar = findFirstSuperArgument(method);
for (Type t : superCallable.getSignature().getAsmMethod().getArgumentTypes()) { for (Type t : superCallable.getAsmMethod().getArgumentTypes()) {
iv.load(nextVar, t); iv.load(nextVar, t);
nextVar += t.getSize(); nextVar += t.getSize();
} }
@@ -1503,10 +1501,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
} }
} }
private static int findFirstSuperArgument(CallableMethod method) { private static int findFirstSuperArgument(@NotNull CallableMethod method) {
List<JvmMethodParameterSignature> types = method.getSignature().getKotlinParameterTypes();
int i = 0; int i = 0;
for (JvmMethodParameterSignature type : types) { for (JvmMethodParameterSignature type : method.getValueParameters()) {
if (type.getKind() == JvmMethodParameterKind.SUPER_CALL_PARAM) { if (type.getKind() == JvmMethodParameterKind.SUPER_CALL_PARAM) {
return i + 1; // because of this return i + 1; // because of this
} }
@@ -644,7 +644,7 @@ public abstract class StackValue {
} }
if (setter instanceof CallableMethod) { if (setter instanceof CallableMethod) {
CallableMethod method = (CallableMethod) setter; CallableMethod method = (CallableMethod) setter;
Method asmMethod = method.getSignature().getAsmMethod(); Method asmMethod = method.getAsmMethod();
Type[] argumentTypes = asmMethod.getArgumentTypes(); Type[] argumentTypes = asmMethod.getArgumentTypes();
coerce(topOfStackType, argumentTypes[argumentTypes.length - 1], v); coerce(topOfStackType, argumentTypes[argumentTypes.length - 1], v);
method.invokeWithNotNullAssertion(v, state, resolvedSetCall); method.invokeWithNotNullAssertion(v, state, resolvedSetCall);
@@ -867,7 +867,7 @@ public abstract class StackValue {
genNotNullAssertionForField(v, state, descriptor); genNotNullAssertionForField(v, state, descriptor);
} }
else { else {
Method method = getter.getSignature().getAsmMethod(); Method method = getter.getAsmMethod();
v.visitMethodInsn(getter.getInvokeOpcode(), getter.getOwner().getInternalName(), method.getName(), method.getDescriptor()); v.visitMethodInsn(getter.getInvokeOpcode(), getter.getOwner().getInternalName(), method.getName(), method.getDescriptor());
} }
coerceTo(type, v); coerceTo(type, v);
@@ -880,7 +880,7 @@ public abstract class StackValue {
v.visitFieldInsn(isStatic ? PUTSTATIC : PUTFIELD, methodOwner.getInternalName(), getPropertyName(), v.visitFieldInsn(isStatic ? PUTSTATIC : PUTFIELD, methodOwner.getInternalName(), getPropertyName(),
this.type.getDescriptor()); } this.type.getDescriptor()); }
else { else {
Method method = setter.getSignature().getAsmMethod(); Method method = setter.getAsmMethod();
v.visitMethodInsn(setter.getInvokeOpcode(), setter.getOwner().getInternalName(), method.getName(), method.getDescriptor()); v.visitMethodInsn(setter.getInvokeOpcode(), setter.getOwner().getInternalName(), method.getName(), method.getDescriptor());
} }
} }