Callable Convertion

This commit is contained in:
Michael Bogdanov
2015-04-04 11:10:18 +03:00
parent 1d31b93c33
commit 8e0003c1a5
2 changed files with 57 additions and 120 deletions
@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.codegen;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.org.objectweb.asm.Type; import org.jetbrains.org.objectweb.asm.Type;
public interface Callable { public trait Callable {
} }
@@ -16,142 +16,96 @@
package org.jetbrains.kotlin.codegen; package org.jetbrains.kotlin.codegen;
import com.sun.org.apache.bcel.internal.generic.INVOKESPECIAL
import com.sun.org.apache.bcel.internal.generic.INVOKESTATIC
import kotlin.Function1; import kotlin.Function1;
import kotlin.Unit; import kotlin.Unit;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.codegen.state.GenerationState; import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.codegen.state.JetTypeMapper; import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall; import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
import org.jetbrains.kotlin.load.java.JvmAbi; import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind; import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind;
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature; import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature;
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature; import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
import org.jetbrains.org.objectweb.asm.Opcodes; import org.jetbrains.org.objectweb.asm.Opcodes.*;
import org.jetbrains.org.objectweb.asm.Type; import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter; import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
import org.jetbrains.org.objectweb.asm.commons.Method; import org.jetbrains.org.objectweb.asm.commons.Method;
import org.jetbrains.org.objectweb.asm.util.Printer; import org.jetbrains.org.objectweb.asm.util.Printer;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List;
import static org.jetbrains.org.objectweb.asm.Opcodes.INVOKESPECIAL; public class CallableMethod(private val owner: Type, private val defaultImplOwner: Type?, private val defaultImplParam: Type?, private val signature: JvmMethodSignature, private val invokeOpcode: Int, private val thisClass: Type?, private val receiverParameterType: Type?, private val generateCalleeType: Type?) : ExtendedCallable {
import static org.jetbrains.org.objectweb.asm.Opcodes.INVOKESTATIC;
public class CallableMethod implements ExtendedCallable { override fun getOwner(): Type {
private final Type owner; return owner
private final Type defaultImplOwner;
private final Type defaultImplParam;
private final JvmMethodSignature signature;
private final int invokeOpcode;
private final Type thisClass;
private final Type receiverParameterType;
private final Type generateCalleeType;
public CallableMethod(
@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;
this.defaultImplParam = defaultImplParam;
this.signature = signature;
this.invokeOpcode = invokeOpcode;
this.thisClass = thisClass;
this.receiverParameterType = receiverParameterType;
this.generateCalleeType = generateCalleeType;
} }
@Override public fun getValueParameters(): List<JvmMethodParameterSignature> {
@NotNull return signature.getValueParameters()
public Type getOwner() {
return owner;
} }
@NotNull override fun getValueParameterTypes(): List<Type> {
public List<JvmMethodParameterSignature> getValueParameters() { val valueParameters = signature.getValueParameters()
return signature.getValueParameters(); val result = ArrayList<Type>(valueParameters.size())
} for (parameter in valueParameters) {
@Override
@NotNull
public List<Type> getValueParameterTypes() {
List<JvmMethodParameterSignature> valueParameters = signature.getValueParameters();
List<Type> result = new ArrayList<Type>(valueParameters.size());
for (JvmMethodParameterSignature parameter : valueParameters) {
if (parameter.getKind() == JvmMethodParameterKind.VALUE) { if (parameter.getKind() == JvmMethodParameterKind.VALUE) {
result.add(parameter.getAsmType()); result.add(parameter.getAsmType())
} }
} }
return result; return result
} }
@NotNull public fun getAsmMethod(): Method {
public Method getAsmMethod() { return signature.getAsmMethod()
return signature.getAsmMethod();
} }
@Override override fun getArgumentTypes(): Array<Type> {
public Type[] getArgumentTypes() { return signature.getAsmMethod().getArgumentTypes()
return signature.getAsmMethod().getArgumentTypes();
} }
@Override override fun getThisType(): Type? {
@Nullable return thisClass
public Type getThisType() {
return thisClass;
} }
@Override override fun getReceiverClass(): Type? {
@Nullable return receiverParameterType
public Type getReceiverClass() {
return receiverParameterType;
} }
private void invoke(InstructionAdapter v) { private fun invoke(v: InstructionAdapter) {
v.visitMethodInsn(invokeOpcode, owner.getInternalName(), getAsmMethod().getName(), getAsmMethod().getDescriptor()); v.visitMethodInsn(invokeOpcode, owner.getInternalName(), getAsmMethod().getName(), getAsmMethod().getDescriptor())
} }
@Override
public void invokeWithNotNullAssertion( public override fun invokeWithNotNullAssertion(v: InstructionAdapter, state: GenerationState, resolvedCall: ResolvedCall<*>) {
@NotNull InstructionAdapter v, invokeWithoutAssertions(v)
@NotNull GenerationState state, AsmUtil.genNotNullAssertionForMethod(v, state, resolvedCall)
@NotNull ResolvedCall resolvedCall
) {
invokeWithoutAssertions(v);
AsmUtil.genNotNullAssertionForMethod(v, state, resolvedCall);
} }
@Override public override fun invokeWithoutAssertions(v: InstructionAdapter) {
public void invokeWithoutAssertions(@NotNull InstructionAdapter v) { invoke(v)
invoke(v);
} }
@Override override fun getGenerateCalleeType(): Type? {
@Nullable return generateCalleeType
public Type getGenerateCalleeType() {
return generateCalleeType;
} }
private void invokeDefault(InstructionAdapter v) { private fun invokeDefault(v: InstructionAdapter) {
if (defaultImplOwner == null || defaultImplParam == null) { if (defaultImplOwner == null || defaultImplParam == null) {
throw new IllegalStateException(); throw IllegalStateException()
} }
Method method = getAsmMethod(); val method = getAsmMethod();
String desc = JetTypeMapper.getDefaultDescriptor(method, val desc = JetTypeMapper.getDefaultDescriptor(method,
invokeOpcode == INVOKESTATIC ? null : defaultImplParam.getDescriptor(), if (invokeOpcode == INVOKESTATIC) null else defaultImplParam.getDescriptor(),
receiverParameterType != null); receiverParameterType != null);
if ("<init>".equals(method.getName())) { if ("<init>".equals(method.getName())) {
v.aconst(null); v.aconst(null)
v.visitMethodInsn(INVOKESPECIAL, defaultImplOwner.getInternalName(), "<init>", desc, false); v.visitMethodInsn(INVOKESPECIAL, defaultImplOwner!!.getInternalName(), "<init>", desc, false)
} }
else { else {
v.visitMethodInsn(INVOKESTATIC, defaultImplOwner.getInternalName(), v.visitMethodInsn(INVOKESTATIC, defaultImplOwner.getInternalName(),
@@ -159,48 +113,31 @@ public class CallableMethod implements ExtendedCallable {
} }
} }
public void invokeDefaultWithNotNullAssertion( public fun invokeDefaultWithNotNullAssertion(v: InstructionAdapter, state: GenerationState, resolvedCall: ResolvedCall<*>) {
@NotNull InstructionAdapter v, invokeDefault(v)
@NotNull GenerationState state, AsmUtil.genNotNullAssertionForMethod(v, state, resolvedCall)
@NotNull ResolvedCall resolvedCall
) {
invokeDefault(v);
AsmUtil.genNotNullAssertionForMethod(v, state, resolvedCall);
} }
@Override override fun getReturnType(): Type {
@NotNull return signature.getReturnType()
public Type getReturnType() {
return signature.getReturnType();
} }
@Override override fun toString(): String {
public String toString() { return Printer.OPCODES[invokeOpcode] + " " + owner.getInternalName() + "." + signature
return Printer.OPCODES[invokeOpcode] + " " + owner.getInternalName() + "." + signature;
} }
@Override override fun isStaticCall(): Boolean {
public boolean isStaticCall() { return invokeOpcode == INVOKESTATIC
return invokeOpcode == Opcodes.INVOKESTATIC;
} }
@Override
public void beforeParameterGeneration(@NotNull InstructionAdapter v, @Nullable StackValue value) { public override fun beforeParameterGeneration(v: InstructionAdapter, value: StackValue?) {
} }
@NotNull override fun invokeMethodWithArguments(resolvedCall: ResolvedCall<*>, receiver: StackValue, returnType: Type, codegen: ExpressionCodegen): StackValue {
@Override return StackValue.functionCall(returnType) {
public StackValue invokeMethodWithArguments( codegen.invokeMethodWithArguments(this@CallableMethod, resolvedCall, receiver, returnType)
@NotNull final ResolvedCall resolvedCall, @NotNull final StackValue receiver, @NotNull final Type returnType, }
@NotNull final ExpressionCodegen codegen
) {
return StackValue.functionCall(returnType, new Function1<InstructionAdapter, Unit>() {
@Override
public Unit invoke(InstructionAdapter v) {
codegen.invokeMethodWithArguments(CallableMethod.this, resolvedCall, receiver, returnType);
return Unit.INSTANCE$;
}
});
} }
} }