IntrinsicCallable clean

This commit is contained in:
Michael Bogdanov
2015-04-06 19:23:56 +03:00
parent 31c4aaac4d
commit 86e12f1f42
7 changed files with 36 additions and 43 deletions
@@ -44,7 +44,7 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
public class ArrayIterator : IntrinsicMethod() {
override fun toCallable(method: CallableMethod): Callable {
return createUnaryIntrinsicCallable(method, needPrimitiveCheck = false) {
return createUnaryIntrinsicCallable(method) {
val methodSignature = "(${method.owner.getDescriptor()})${returnType.getDescriptor()}"
it.invokestatic("kotlin/jvm/internal/InternalPackage", "iterator", methodSignature, false)
}
@@ -24,7 +24,7 @@ import org.jetbrains.org.objectweb.asm.Opcodes
public class Clone : IntrinsicMethod() {
override fun toCallable(method: CallableMethod, isSuperCall: Boolean): Callable {
return createUnaryIntrinsicCallable(method, OBJECT_TYPE, needPrimitiveCheck = false) {
return createUnaryIntrinsicCallable(method, OBJECT_TYPE) {
val opcodes: Int = if (isSuperCall) Opcodes.INVOKESPECIAL else Opcodes.INVOKEVIRTUAL
it.visitMethodInsn(opcodes, "java/lang/Object", "clone", "()Ljava/lang/Object;", false)
}
@@ -57,7 +57,7 @@ public class Concat : IntrinsicMethod() {
override fun toCallable(method: CallableMethod): Callable {
return object : MappedCallable(method) {
return object : IntrinsicCallable(method) {
override fun invokeMethodWithArguments(resolvedCall: ResolvedCall<*>, receiver: StackValue, returnType: Type, codegen: ExpressionCodegen): StackValue {
return StackValue.operation(returnType) {
val arguments = resolvedCall.getCall().getValueArguments().map { it.getArgumentExpression() }
@@ -32,7 +32,7 @@ public class IdentityEquals : IntrinsicMethod() {
override fun toCallable(method: CallableMethod): Callable {
return object : MappedCallable(method) {
return object : IntrinsicCallable(method) {
override fun invokeMethodWithArguments(resolvedCall: ResolvedCall<*>, receiver: StackValue, returnType: Type, codegen: ExpressionCodegen): StackValue {
val element = resolvedCall.getCall().getCallElement()
val left: StackValue
@@ -25,10 +25,16 @@ import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
public abstract class IntrinsicCallable(override val returnType: Type,
override val valueParameterTypes: List<Type>,
override val dispatchReceiverType: Type?,
override val extensionReceiverType: Type?) : Callable {
public open class IntrinsicCallable(override val returnType: Type,
override val valueParameterTypes: List<Type>,
override val dispatchReceiverType: Type?,
override val extensionReceiverType: Type?,
private val invoke: IntrinsicCallable.(v: InstructionAdapter) -> Unit = { throw UnsupportedOperationException() }) : Callable {
constructor(callable: CallableMethod, invoke: IntrinsicCallable.(v: InstructionAdapter) -> Unit = {}) :
this(callable.returnType, callable.valueParameterTypes, callable.dispatchReceiverType, callable.extensionReceiverType, invoke) {
}
override fun invokeWithoutAssertions(v: InstructionAdapter) {
invokeIntrinsic(v)
@@ -38,7 +44,9 @@ public abstract class IntrinsicCallable(override val returnType: Type,
invokeWithoutAssertions(v)
}
public abstract fun invokeIntrinsic(v: InstructionAdapter);
public open fun invokeIntrinsic(v: InstructionAdapter) {
invoke(v)
}
override val parameterTypes: Array<Type>
get() {
@@ -74,44 +82,29 @@ fun createBinaryIntrinsicCallable(returnType: Type, valueParameterType: Type, th
}
}
public class UnaryIntrinsic(
callable: CallableMethod,
newReturnType: Type? = null,
needPrimitiveCheck: Boolean = true,
newThisType: Type? = null,
private val invoke: UnaryIntrinsic.(v: InstructionAdapter) -> Unit
) : IntrinsicCallable(newReturnType ?: callable.returnType, callable.valueParameterTypes, newThisType ?: callable.dispatchReceiverType, callable.extensionReceiverType) {
init {
if (needPrimitiveCheck) {
assert(AsmUtil.isPrimitive(returnType)) { "Return type of UnaryPlus intrinsic should be of primitive type: $returnType" }
}
assert(valueParameterTypes.isEmpty()) { "Unary operation should not have any parameters" }
}
override fun invokeIntrinsic(v: InstructionAdapter) {
invoke(v)
}
}
public fun createUnaryIntrinsicCallable(
callable: CallableMethod,
newReturnType: Type? = null,
needPrimitiveCheck: Boolean = true,
needPrimitiveCheck: Boolean = false,
newThisType: Type? = null,
invoke: IntrinsicCallable.(v: InstructionAdapter) -> Unit
) : IntrinsicCallable {
return UnaryIntrinsic(callable, newReturnType, needPrimitiveCheck, newThisType, invoke = invoke)
}
public open class MappedCallable(val callable: CallableMethod, val invoke: IntrinsicCallable.(v: InstructionAdapter) -> Unit = {}) :
IntrinsicCallable(callable.returnType, callable.valueParameterTypes, callable.dispatchReceiverType, callable.extensionReceiverType) {
override fun invokeIntrinsic(v: InstructionAdapter) {
invoke(v)
): IntrinsicCallable {
val intrinsic = IntrinsicCallable(
newReturnType ?: callable.returnType,
callable.valueParameterTypes,
newThisType ?: callable.dispatchReceiverType,
callable.extensionReceiverType,
invoke
)
assert(intrinsic.valueParameterTypes.isEmpty()) { "Unary operation should not have any parameters" }
if (needPrimitiveCheck) {
assert(AsmUtil.isPrimitive(intrinsic.returnType)) {
"Return type of UnaryPlus intrinsic should be of primitive type: ${intrinsic.returnType}"
}
}
return intrinsic
}
public fun createIntrinsicCallable(callable: CallableMethod, invoke: IntrinsicCallable.(v: InstructionAdapter) -> Unit) : IntrinsicCallable {
return MappedCallable(callable, invoke)
public fun createIntrinsicCallable(callable: CallableMethod, invoke: IntrinsicCallable.(v: InstructionAdapter) -> Unit): IntrinsicCallable {
return IntrinsicCallable(callable, invoke)
}
@@ -40,7 +40,7 @@ public class Not : IntrinsicMethod() {
}
override fun toCallable(method: CallableMethod): Callable {
return object : MappedCallable(method) {
return object : IntrinsicCallable(method) {
override fun invokeMethodWithArguments(resolvedCall: ResolvedCall<*>, receiver: StackValue, returnType: Type, codegen: ExpressionCodegen): StackValue {
val element = resolvedCall.getCall().getCallElement()
val stackValue =
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.codegen.CallableMethod
public class UnaryPlus : IntrinsicMethod() {
override fun toCallable(method: CallableMethod): Callable {
return createUnaryIntrinsicCallable(method, needPrimitiveCheck = true) {
return createUnaryIntrinsicCallable(method) {
//nothing
}
}