Refactor CallableMethod, add convenient methods
It no longer exposes its JvmMethodSignature
This commit is contained in:
@@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user