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