Intrinsic.toCallable clean
This commit is contained in:
@@ -23,10 +23,9 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
|||||||
|
|
||||||
public class ArrayGet : IntrinsicMethod() {
|
public class ArrayGet : IntrinsicMethod() {
|
||||||
|
|
||||||
override fun toCallable(method: CallableMethod): Callable {
|
override fun toCallable(method: CallableMethod): Callable =
|
||||||
return MappedCallable(method) {
|
createMappedCallable(method) {
|
||||||
val type = correctElementType(calcReceiverType())
|
val type = correctElementType(calcReceiverType())
|
||||||
it.aload(type)
|
it.aload(type)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
|||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME
|
||||||
import org.jetbrains.kotlin.codegen.AsmUtil.asmDescByFqNameWithoutInnerClasses
|
import org.jetbrains.kotlin.codegen.AsmUtil.asmDescByFqNameWithoutInnerClasses
|
||||||
import org.jetbrains.kotlin.codegen.Callable
|
import org.jetbrains.kotlin.codegen.Callable
|
||||||
|
import org.jetbrains.kotlin.codegen.CallableMethod
|
||||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
||||||
import org.jetbrains.kotlin.codegen.StackValue
|
import org.jetbrains.kotlin.codegen.StackValue
|
||||||
import org.jetbrains.kotlin.codegen.context.CodegenContext
|
import org.jetbrains.kotlin.codegen.context.CodegenContext
|
||||||
@@ -32,6 +33,7 @@ import org.jetbrains.kotlin.psi.JetCallExpression
|
|||||||
import org.jetbrains.kotlin.psi.JetExpression
|
import org.jetbrains.kotlin.psi.JetExpression
|
||||||
import org.jetbrains.kotlin.psi.JetSimpleNameExpression
|
import org.jetbrains.kotlin.psi.JetSimpleNameExpression
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.getType
|
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.getType
|
||||||
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
|
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
|
||||||
import org.jetbrains.org.objectweb.asm.Type
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
@@ -63,9 +65,8 @@ public class ArrayIterator : IntrinsicMethod() {
|
|||||||
throw UnsupportedOperationException(containingDeclaration.toString())
|
throw UnsupportedOperationException(containingDeclaration.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO refactor
|
override fun toCallable(fd: FunctionDescriptor, isSuper: Boolean, resolvedCall: ResolvedCall<*>, codegen: ExpressionCodegen): Callable {
|
||||||
override fun toCallable(state: GenerationState, fd: FunctionDescriptor, context: CodegenContext<*>, isSuper: Boolean): Callable {
|
val method = codegen.getState().getTypeMapper().mapToCallableMethod(fd, false, codegen.getContext())
|
||||||
val callableMethod = state.getTypeMapper().mapToCallableMethod(fd, false, context)
|
|
||||||
|
|
||||||
val containingDeclaration = fd.getContainingDeclaration().getOriginal() as ClassDescriptor
|
val containingDeclaration = fd.getContainingDeclaration().getOriginal() as ClassDescriptor
|
||||||
var type: Type? = null;
|
var type: Type? = null;
|
||||||
@@ -89,8 +90,7 @@ public class ArrayIterator : IntrinsicMethod() {
|
|||||||
throw UnsupportedOperationException(containingDeclaration.toString())
|
throw UnsupportedOperationException(containingDeclaration.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return createUnaryCallable(method, type) {
|
||||||
return UnaryIntrinsic(callableMethod, type) {
|
|
||||||
val containingDeclaration = fd.getContainingDeclaration().getOriginal() as ClassDescriptor
|
val containingDeclaration = fd.getContainingDeclaration().getOriginal() as ClassDescriptor
|
||||||
if (containingDeclaration == KotlinBuiltIns.getInstance().getArray()) {
|
if (containingDeclaration == KotlinBuiltIns.getInstance().getArray()) {
|
||||||
it.invokestatic("kotlin/jvm/internal/InternalPackage", "iterator", "([Ljava/lang/Object;)Ljava/util/Iterator;", false)
|
it.invokestatic("kotlin/jvm/internal/InternalPackage", "iterator", "([Ljava/lang/Object;)Ljava/util/Iterator;", false)
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.codegen.CallableMethod
|
|||||||
public class ArraySize : IntrinsicMethod() {
|
public class ArraySize : IntrinsicMethod() {
|
||||||
|
|
||||||
public override fun toCallable(method: CallableMethod): Callable {
|
public override fun toCallable(method: CallableMethod): Callable {
|
||||||
return UnaryIntrinsic(method, null, false) { adapter ->
|
return createUnaryCallable(method) { adapter ->
|
||||||
adapter.arraylength()
|
adapter.arraylength()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ public class BinaryOp(private val opcode: Int) : IntrinsicMethod() {
|
|||||||
val operandType = numberFunctionOperandType(returnType)
|
val operandType = numberFunctionOperandType(returnType)
|
||||||
val paramType = if (shift()) Type.INT_TYPE else operandType
|
val paramType = if (shift()) Type.INT_TYPE else operandType
|
||||||
|
|
||||||
return IntrinsicCallable.binaryIntrinsic(operandType, paramType, operandType) {
|
return binaryIntrinsic(operandType, paramType, operandType) {
|
||||||
v -> v.visitInsn(returnType.getOpcode(opcode))
|
v -> v.visitInsn(returnType.getOpcode(opcode))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import org.jetbrains.org.objectweb.asm.Opcodes
|
|||||||
public class Clone : IntrinsicMethod() {
|
public class Clone : IntrinsicMethod() {
|
||||||
|
|
||||||
override fun toCallable(method: CallableMethod, isSuperCall: Boolean): Callable {
|
override fun toCallable(method: CallableMethod, isSuperCall: Boolean): Callable {
|
||||||
return UnaryIntrinsic(method, OBJECT_TYPE) {
|
return createUnaryCallable(method, OBJECT_TYPE) {
|
||||||
val opcodes: Int = if (isSuperCall) Opcodes.INVOKESPECIAL else Opcodes.INVOKEVIRTUAL
|
val opcodes: Int = if (isSuperCall) Opcodes.INVOKESPECIAL else Opcodes.INVOKEVIRTUAL
|
||||||
it.visitMethodInsn(opcodes, "java/lang/Object", "clone", "()Ljava/lang/Object;", false)
|
it.visitMethodInsn(opcodes, "java/lang/Object", "clone", "()Ljava/lang/Object;", false)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ public class CompareTo : IntrinsicMethod() {
|
|||||||
|
|
||||||
override fun toCallable(method: CallableMethod): Callable {
|
override fun toCallable(method: CallableMethod): Callable {
|
||||||
val argumentType = comparisonOperandType(method.thisType ?: method.receiverType, method.argumentTypes.first())
|
val argumentType = comparisonOperandType(method.thisType ?: method.receiverType, method.argumentTypes.first())
|
||||||
return IntrinsicCallable.binaryIntrinsic(method.returnType, argumentType, argumentType, null) {
|
return binaryIntrinsic(method.returnType, argumentType, argumentType, null) {
|
||||||
genInvoke(argumentType, it)
|
genInvoke(argumentType, it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import com.intellij.psi.PsiElement
|
|||||||
import org.jetbrains.kotlin.codegen.AsmUtil.genInvokeAppendMethod
|
import org.jetbrains.kotlin.codegen.AsmUtil.genInvokeAppendMethod
|
||||||
import org.jetbrains.kotlin.codegen.AsmUtil.genStringBuilderConstructor
|
import org.jetbrains.kotlin.codegen.AsmUtil.genStringBuilderConstructor
|
||||||
import org.jetbrains.kotlin.codegen.Callable
|
import org.jetbrains.kotlin.codegen.Callable
|
||||||
|
import org.jetbrains.kotlin.codegen.CallableMethod
|
||||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
||||||
import org.jetbrains.kotlin.codegen.StackValue
|
import org.jetbrains.kotlin.codegen.StackValue
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
@@ -54,9 +55,9 @@ public class Concat : IntrinsicMethod() {
|
|||||||
return JAVA_STRING_TYPE
|
return JAVA_STRING_TYPE
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toCallable(fd: FunctionDescriptor, isSuper: Boolean, resolvedCall: ResolvedCall<*>, codegen: ExpressionCodegen): Callable {
|
|
||||||
val callable = codegen.getState().getTypeMapper().mapToCallableMethod(fd, false, codegen.getContext())
|
override fun toCallable(method: CallableMethod): Callable {
|
||||||
return object : MappedCallable(callable, {}) {
|
return object : MappedCallable(method) {
|
||||||
override fun invokeMethodWithArguments(resolvedCall: ResolvedCall<*>, receiver: StackValue, returnType: Type, codegen: ExpressionCodegen): StackValue {
|
override fun invokeMethodWithArguments(resolvedCall: ResolvedCall<*>, receiver: StackValue, returnType: Type, codegen: ExpressionCodegen): StackValue {
|
||||||
return StackValue.operation(returnType) {
|
return StackValue.operation(returnType) {
|
||||||
val arguments = resolvedCall.getCall().getValueArguments().map { it.getArgumentExpression() }
|
val arguments = resolvedCall.getCall().getValueArguments().map { it.getArgumentExpression() }
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE
|
|||||||
public class Equals : IntrinsicMethod() {
|
public class Equals : IntrinsicMethod() {
|
||||||
|
|
||||||
override fun toCallable(method: CallableMethod): Callable {
|
override fun toCallable(method: CallableMethod): Callable {
|
||||||
return IntrinsicCallable.binaryIntrinsic(method.returnType, OBJECT_TYPE, nullOrObject(method.thisType), nullOrObject(method.receiverType)) {
|
return binaryIntrinsic(method.returnType, OBJECT_TYPE, nullOrObject(method.thisType), nullOrObject(method.receiverType)) {
|
||||||
AsmUtil.genAreEqualCall(it)
|
AsmUtil.genAreEqualCall(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
package org.jetbrains.kotlin.codegen.intrinsics
|
package org.jetbrains.kotlin.codegen.intrinsics
|
||||||
|
|
||||||
import org.jetbrains.kotlin.codegen.Callable
|
import org.jetbrains.kotlin.codegen.Callable
|
||||||
|
import org.jetbrains.kotlin.codegen.CallableMethod
|
||||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
||||||
import org.jetbrains.kotlin.codegen.StackValue
|
import org.jetbrains.kotlin.codegen.StackValue
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
@@ -29,9 +30,9 @@ import org.jetbrains.org.objectweb.asm.Type
|
|||||||
|
|
||||||
public class IdentityEquals : IntrinsicMethod() {
|
public class IdentityEquals : IntrinsicMethod() {
|
||||||
|
|
||||||
override fun toCallable(fd: FunctionDescriptor, isSuper: Boolean, resolvedCall: ResolvedCall<*>, codegen: ExpressionCodegen): Callable {
|
|
||||||
val callable = codegen.getState().getTypeMapper().mapToCallableMethod(fd, false, codegen.getContext())
|
override fun toCallable(method: CallableMethod): Callable {
|
||||||
return object : MappedCallable(callable) {
|
return object : MappedCallable(method) {
|
||||||
override fun invokeMethodWithArguments(resolvedCall: ResolvedCall<*>, receiver: StackValue, returnType: Type, codegen: ExpressionCodegen): StackValue {
|
override fun invokeMethodWithArguments(resolvedCall: ResolvedCall<*>, receiver: StackValue, returnType: Type, codegen: ExpressionCodegen): StackValue {
|
||||||
val element = resolvedCall.getCall().getCallElement()
|
val element = resolvedCall.getCall().getCallElement()
|
||||||
val left: StackValue
|
val left: StackValue
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.codegen.intrinsics
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.codegen.AsmUtil.genIncrement
|
import org.jetbrains.kotlin.codegen.AsmUtil.genIncrement
|
||||||
import org.jetbrains.kotlin.codegen.Callable
|
import org.jetbrains.kotlin.codegen.Callable
|
||||||
|
import org.jetbrains.kotlin.codegen.CallableMethod
|
||||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
import org.jetbrains.kotlin.psi.JetPrefixExpression
|
import org.jetbrains.kotlin.psi.JetPrefixExpression
|
||||||
@@ -25,9 +26,8 @@ import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
|||||||
|
|
||||||
public class Increment(private val myDelta: Int) : IntrinsicMethod() {
|
public class Increment(private val myDelta: Int) : IntrinsicMethod() {
|
||||||
|
|
||||||
override fun toCallable(fd: FunctionDescriptor, isSuper: Boolean, resolvedCall: ResolvedCall<*>, codegen: ExpressionCodegen): Callable {
|
override fun toCallable(method: CallableMethod, isSuper: Boolean, resolvedCall: ResolvedCall<*>): Callable {
|
||||||
val method = codegen.getState().getTypeMapper().mapToCallableMethod(fd, false, codegen.getContext())
|
return createMappedCallable(method) {
|
||||||
return MappedCallable(method) {
|
|
||||||
val jetExpression = resolvedCall.getCall().getCalleeExpression()
|
val jetExpression = resolvedCall.getCall().getCalleeExpression()
|
||||||
assert(jetExpression !is JetPrefixExpression) { "There should be postfix increment ${jetExpression!!.getText()}" }
|
assert(jetExpression !is JetPrefixExpression) { "There should be postfix increment ${jetExpression!!.getText()}" }
|
||||||
genIncrement(returnType, myDelta, it)
|
genIncrement(returnType, myDelta, it)
|
||||||
|
|||||||
@@ -30,40 +30,6 @@ public abstract class IntrinsicCallable(override val returnType: Type,
|
|||||||
override val thisType: Type?,
|
override val thisType: Type?,
|
||||||
override val receiverType: Type?) : Callable {
|
override val receiverType: Type?) : Callable {
|
||||||
|
|
||||||
companion object {
|
|
||||||
fun create(descriptor: FunctionDescriptor, context: CodegenContext<*>, state: GenerationState, lambda: IntrinsicCallable.(i: InstructionAdapter) -> Unit): IntrinsicCallable {
|
|
||||||
return create(state.getTypeMapper().mapToCallableMethod(descriptor, false, context), lambda)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun create(callableMethod: CallableMethod, lambda: IntrinsicCallable.(i: InstructionAdapter) -> Unit): IntrinsicCallable {
|
|
||||||
return object : IntrinsicCallable(callableMethod.returnType, callableMethod.valueParameterTypes, callableMethod.thisType, callableMethod.receiverType) {
|
|
||||||
override fun invokeIntrinsic(v: InstructionAdapter) {
|
|
||||||
lambda(v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun binaryIntrinsic(returnType: Type, valueParameterType: Type, thisType: Type? = null, receiverType: Type? = null, lambda: IntrinsicCallable.(i: InstructionAdapter) -> Unit): IntrinsicCallable {
|
|
||||||
assert(AsmUtil.isPrimitive(returnType)) { "Return type of BinaryOp intrinsic should be of primitive type : " + returnType }
|
|
||||||
|
|
||||||
return object : IntrinsicCallable(returnType, listOf(valueParameterType), thisType, receiverType) {
|
|
||||||
override fun invokeIntrinsic(v: InstructionAdapter) {
|
|
||||||
lambda(v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun create(descriptor: FunctionDescriptor, context: CodegenContext<*>, state: GenerationState, receiverTransformer: Type.() -> Type, lambda: IntrinsicCallable.(i: InstructionAdapter) -> Unit): IntrinsicCallable {
|
|
||||||
val callableMethod = state.getTypeMapper().mapToCallableMethod(descriptor, false, context)
|
|
||||||
|
|
||||||
return object : IntrinsicCallable(callableMethod.returnType, callableMethod.valueParameterTypes, callableMethod.thisType?.receiverTransformer(), callableMethod.receiverType?.receiverTransformer()) {
|
|
||||||
override fun invokeIntrinsic(v: InstructionAdapter) {
|
|
||||||
lambda(v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun invokeWithoutAssertions(v: InstructionAdapter) {
|
override fun invokeWithoutAssertions(v: InstructionAdapter) {
|
||||||
invokeIntrinsic(v)
|
invokeIntrinsic(v)
|
||||||
}
|
}
|
||||||
@@ -96,9 +62,17 @@ public abstract class IntrinsicCallable(override val returnType: Type,
|
|||||||
public fun calcReceiverType(): Type? {
|
public fun calcReceiverType(): Type? {
|
||||||
return receiverType ?: thisType
|
return receiverType ?: thisType
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun binaryIntrinsic(returnType: Type, valueParameterType: Type, thisType: Type? = null, receiverType: Type? = null, lambda: IntrinsicCallable.(i: InstructionAdapter) -> Unit): IntrinsicCallable {
|
||||||
|
assert(AsmUtil.isPrimitive(returnType)) { "Return type of BinaryOp intrinsic should be of primitive type : " + returnType }
|
||||||
|
|
||||||
|
return object : IntrinsicCallable(returnType, listOf(valueParameterType), thisType, receiverType) {
|
||||||
|
override fun invokeIntrinsic(v: InstructionAdapter) {
|
||||||
|
lambda(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class UnaryIntrinsic(val callable: CallableMethod, val newReturnType: Type? = null, needPrimitiveCheck: Boolean = false, val newThisType: Type? = null, val invoke: UnaryIntrinsic.(v: InstructionAdapter) -> Unit) :
|
public class UnaryIntrinsic(val callable: CallableMethod, val newReturnType: Type? = null, needPrimitiveCheck: Boolean = false, val newThisType: Type? = null, val invoke: UnaryIntrinsic.(v: InstructionAdapter) -> Unit) :
|
||||||
IntrinsicCallable(newReturnType ?: callable.returnType, callable.valueParameterTypes, newThisType ?: callable.thisType, callable.receiverType) {
|
IntrinsicCallable(newReturnType ?: callable.returnType, callable.valueParameterTypes, newThisType ?: callable.thisType, callable.receiverType) {
|
||||||
@@ -113,14 +87,20 @@ public class UnaryIntrinsic(val callable: CallableMethod, val newReturnType: Typ
|
|||||||
override fun invokeIntrinsic(v: InstructionAdapter) {
|
override fun invokeIntrinsic(v: InstructionAdapter) {
|
||||||
invoke(v)
|
invoke(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public open class MappedCallable(val callable: CallableMethod, val invoke: MappedCallable.(v: InstructionAdapter) -> Unit = {}) :
|
public fun createUnaryCallable(callable: CallableMethod, newReturnType: Type? = null, needPrimitiveCheck: Boolean = false, invoke: IntrinsicCallable.(v: InstructionAdapter) -> Unit) : IntrinsicCallable {
|
||||||
IntrinsicCallable(callable.returnType, callable.valueParameterTypes, callable.thisType, callable.receiverType) {
|
return UnaryIntrinsic(callable, newReturnType, needPrimitiveCheck, invoke = invoke)
|
||||||
|
}
|
||||||
|
|
||||||
|
public open class MappedCallable(val callable: CallableMethod, val invoke: IntrinsicCallable.(v: InstructionAdapter) -> Unit = {}) :
|
||||||
|
IntrinsicCallable(callable.returnType, callable.valueParameterTypes, callable.thisType, callable.receiverType) {
|
||||||
|
|
||||||
override fun invokeIntrinsic(v: InstructionAdapter) {
|
override fun invokeIntrinsic(v: InstructionAdapter) {
|
||||||
invoke(v)
|
invoke(v)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun createMappedCallable(callable: CallableMethod, invoke: IntrinsicCallable.(v: InstructionAdapter) -> Unit) : IntrinsicCallable {
|
||||||
|
return MappedCallable(callable, invoke)
|
||||||
}
|
}
|
||||||
@@ -16,8 +16,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.codegen.intrinsics;
|
package org.jetbrains.kotlin.codegen.intrinsics;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.kotlin.codegen.Callable;
|
import org.jetbrains.kotlin.codegen.Callable;
|
||||||
import org.jetbrains.kotlin.codegen.CallableMethod;
|
import org.jetbrains.kotlin.codegen.CallableMethod;
|
||||||
@@ -29,31 +27,20 @@ import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
|||||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes;
|
import org.jetbrains.kotlin.resolve.jvm.AsmTypes;
|
||||||
import org.jetbrains.org.objectweb.asm.Type;
|
import org.jetbrains.org.objectweb.asm.Type;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static org.jetbrains.kotlin.codegen.AsmUtil.numberFunctionOperandType;
|
|
||||||
|
|
||||||
public abstract class IntrinsicMethod {
|
public abstract class IntrinsicMethod {
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public Callable toCallable(@NotNull FunctionDescriptor fd, boolean isSuper, @NotNull ResolvedCall resolvedCall, @NotNull ExpressionCodegen codegen) {
|
public Callable toCallable(@NotNull FunctionDescriptor fd, boolean isSuper, @NotNull ResolvedCall resolvedCall, @NotNull ExpressionCodegen codegen) {
|
||||||
return toCallable(codegen.getState(), fd, codegen.getContext(), isSuper, resolvedCall);
|
return toCallable(codegen.getState().getTypeMapper().mapToCallableMethod(fd, false, codegen.getContext()), isSuper, resolvedCall);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public Callable toCallable(@NotNull GenerationState state, @NotNull FunctionDescriptor fd, @NotNull CodegenContext<?> context, boolean isSuper, @NotNull
|
public Callable toCallable(@NotNull CallableMethod method, boolean isSuper, @NotNull ResolvedCall resolvedCall) {
|
||||||
ResolvedCall resolvedCall) {
|
return toCallable(method, isSuper);
|
||||||
return toCallable(state, fd, context, isSuper);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public Callable toCallable(@NotNull GenerationState state, @NotNull FunctionDescriptor fd, @NotNull CodegenContext<?> context, boolean isSuper) {
|
|
||||||
return toCallable(state.getTypeMapper().mapToCallableMethod(fd, false, context), isSuper);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public Callable toCallable(@NotNull CallableMethod method, boolean isSuperCall) {
|
public Callable toCallable(@NotNull CallableMethod method, boolean isSuperCall) {
|
||||||
//assert !isSuper;
|
|
||||||
return toCallable(method);
|
return toCallable(method);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,15 +49,6 @@ public abstract class IntrinsicMethod {
|
|||||||
throw new UnsupportedOperationException("Not implemented");
|
throw new UnsupportedOperationException("Not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Type> transformTypes(List<Type> types) {
|
|
||||||
return Lists.transform(types, new Function<Type, Type>() {
|
|
||||||
@Override
|
|
||||||
public Type apply(Type input) {
|
|
||||||
return numberFunctionOperandType(input);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public Type nullOrObject(Type type) {
|
public Type nullOrObject(Type type) {
|
||||||
return nullOr(type, AsmTypes.OBJECT_TYPE);
|
return nullOr(type, AsmTypes.OBJECT_TYPE);
|
||||||
}
|
}
|
||||||
@@ -79,4 +57,4 @@ public abstract class IntrinsicMethod {
|
|||||||
return type == null ? null : newType;
|
return type == null ? null : newType;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -25,7 +25,7 @@ public class Inv : IntrinsicMethod() {
|
|||||||
|
|
||||||
override fun toCallable(method: CallableMethod): Callable {
|
override fun toCallable(method: CallableMethod): Callable {
|
||||||
val type = numberFunctionOperandType(method.returnType)
|
val type = numberFunctionOperandType(method.returnType)
|
||||||
return UnaryIntrinsic(method, method.returnType, newThisType = type) {
|
return UnaryIntrinsic(method, newThisType = type) {
|
||||||
if (returnType == Type.LONG_TYPE) {
|
if (returnType == Type.LONG_TYPE) {
|
||||||
it.lconst(-1)
|
it.lconst(-1)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,9 +18,12 @@ package org.jetbrains.kotlin.codegen.intrinsics
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME
|
||||||
import org.jetbrains.kotlin.codegen.Callable
|
import org.jetbrains.kotlin.codegen.Callable
|
||||||
|
import org.jetbrains.kotlin.codegen.CallableMethod
|
||||||
|
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
||||||
import org.jetbrains.kotlin.codegen.context.CodegenContext
|
import org.jetbrains.kotlin.codegen.context.CodegenContext
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||||
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
|
||||||
@@ -59,11 +62,11 @@ public class IteratorNext : IntrinsicMethod() {
|
|||||||
return name
|
return name
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toCallable(state: GenerationState, fd: FunctionDescriptor, context: CodegenContext<*>, isSuper: Boolean): Callable {
|
|
||||||
val type = state.getTypeMapper().mapReturnType(fd)
|
override fun toCallable(fd: FunctionDescriptor, isSuper: Boolean, resolvedCall: ResolvedCall<*>, codegen: ExpressionCodegen): Callable {
|
||||||
|
val type = codegen.getState().getTypeMapper().mapReturnType(fd)
|
||||||
return object: IntrinsicCallable(type, listOf(), AsmTypes.OBJECT_TYPE, null) {
|
return object: IntrinsicCallable(type, listOf(), AsmTypes.OBJECT_TYPE, null) {
|
||||||
override fun invokeIntrinsic(v: InstructionAdapter) {
|
override fun invokeIntrinsic(v: InstructionAdapter) {
|
||||||
val returnType = returnType
|
|
||||||
val name = getIteratorName(returnType)
|
val name = getIteratorName(returnType)
|
||||||
v.invokevirtual(BUILT_INS_PACKAGE_FQ_NAME.toString() + "/" + name + "Iterator", "next" + name, "()" + returnType.getDescriptor(), false)
|
v.invokevirtual(BUILT_INS_PACKAGE_FQ_NAME.toString() + "/" + name + "Iterator", "next" + name, "()" + returnType.getDescriptor(), false)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.codegen.CallableMethod
|
|||||||
|
|
||||||
public class JavaClassArray : IntrinsicMethod() {
|
public class JavaClassArray : IntrinsicMethod() {
|
||||||
override fun toCallable(method: CallableMethod): Callable {
|
override fun toCallable(method: CallableMethod): Callable {
|
||||||
return MappedCallable(method) {
|
return createMappedCallable(method) {
|
||||||
//do nothing all generated as vararg
|
//do nothing all generated as vararg
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
package org.jetbrains.kotlin.codegen.intrinsics
|
package org.jetbrains.kotlin.codegen.intrinsics
|
||||||
|
|
||||||
import org.jetbrains.kotlin.codegen.Callable
|
import org.jetbrains.kotlin.codegen.Callable
|
||||||
|
import org.jetbrains.kotlin.codegen.CallableMethod
|
||||||
import org.jetbrains.kotlin.codegen.context.CodegenContext
|
import org.jetbrains.kotlin.codegen.context.CodegenContext
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
@@ -32,7 +33,7 @@ public class MonitorInstruction private(private val opcode: Int) : IntrinsicMeth
|
|||||||
public val MONITOR_EXIT: MonitorInstruction = MonitorInstruction(Opcodes.MONITOREXIT)
|
public val MONITOR_EXIT: MonitorInstruction = MonitorInstruction(Opcodes.MONITOREXIT)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toCallable(state: GenerationState, fd: FunctionDescriptor, context: CodegenContext<*>, isSuper: Boolean, resolvedCall: ResolvedCall<*>): Callable {
|
override fun toCallable(method: CallableMethod): Callable {
|
||||||
return object : IntrinsicCallable(Type.VOID_TYPE, listOf(OBJECT_TYPE), null, null) {
|
return object : IntrinsicCallable(Type.VOID_TYPE, listOf(OBJECT_TYPE), null, null) {
|
||||||
override fun invokeIntrinsic(v: InstructionAdapter) {
|
override fun invokeIntrinsic(v: InstructionAdapter) {
|
||||||
v.visitInsn(opcode)
|
v.visitInsn(opcode)
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.codegen.intrinsics
|
|||||||
|
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import org.jetbrains.kotlin.codegen.Callable
|
import org.jetbrains.kotlin.codegen.Callable
|
||||||
|
import org.jetbrains.kotlin.codegen.CallableMethod
|
||||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
||||||
import org.jetbrains.kotlin.codegen.StackValue
|
import org.jetbrains.kotlin.codegen.StackValue
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
@@ -38,10 +39,8 @@ public class Not : IntrinsicMethod() {
|
|||||||
return StackValue.not(StackValue.coercion(stackValue, Type.BOOLEAN_TYPE))
|
return StackValue.not(StackValue.coercion(stackValue, Type.BOOLEAN_TYPE))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun toCallable(method: CallableMethod): Callable {
|
||||||
override fun toCallable(fd: FunctionDescriptor, isSuper: Boolean, resolvedCall: ResolvedCall<*>, codegen: ExpressionCodegen): Callable {
|
return object : MappedCallable(method) {
|
||||||
val callable = codegen.getState().getTypeMapper().mapToCallableMethod(fd, false, codegen.getContext())
|
|
||||||
return object : MappedCallable(callable, {}) {
|
|
||||||
override fun invokeMethodWithArguments(resolvedCall: ResolvedCall<*>, receiver: StackValue, returnType: Type, codegen: ExpressionCodegen): StackValue {
|
override fun invokeMethodWithArguments(resolvedCall: ResolvedCall<*>, receiver: StackValue, returnType: Type, codegen: ExpressionCodegen): StackValue {
|
||||||
val element = resolvedCall.getCall().getCallElement()
|
val element = resolvedCall.getCall().getCallElement()
|
||||||
val stackValue =
|
val stackValue =
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.codegen.StackValue
|
|||||||
public class NumberCast : IntrinsicMethod() {
|
public class NumberCast : IntrinsicMethod() {
|
||||||
|
|
||||||
override fun toCallable(method: CallableMethod): Callable {
|
override fun toCallable(method: CallableMethod): Callable {
|
||||||
return UnaryIntrinsic(method) {
|
return createUnaryCallable(method) {
|
||||||
StackValue.coerce(calcReceiverType()!!, returnType, it)
|
StackValue.coerce(calcReceiverType()!!, returnType, it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.codegen.CallableMethod
|
|||||||
public class StringGetChar : IntrinsicMethod() {
|
public class StringGetChar : IntrinsicMethod() {
|
||||||
|
|
||||||
override fun toCallable(method: CallableMethod): Callable {
|
override fun toCallable(method: CallableMethod): Callable {
|
||||||
return IntrinsicCallable.create(method) {
|
return createMappedCallable(method) {
|
||||||
it.invokevirtual("java/lang/String", "charAt", "(I)C", false)
|
it.invokevirtual("java/lang/String", "charAt", "(I)C", false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.codegen.CallableMethod
|
|||||||
public class StringPlus : IntrinsicMethod() {
|
public class StringPlus : IntrinsicMethod() {
|
||||||
|
|
||||||
override fun toCallable(method: CallableMethod): Callable {
|
override fun toCallable(method: CallableMethod): Callable {
|
||||||
return IntrinsicCallable.create(method) {
|
return createMappedCallable(method) {
|
||||||
it.invokestatic("kotlin/jvm/internal/Intrinsics", "stringPlus", "(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/String;", false)
|
it.invokestatic("kotlin/jvm/internal/Intrinsics", "stringPlus", "(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/String;", false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.codegen.CallableMethod
|
|||||||
public class UnaryMinus : IntrinsicMethod() {
|
public class UnaryMinus : IntrinsicMethod() {
|
||||||
|
|
||||||
override fun toCallable(method: CallableMethod): Callable {
|
override fun toCallable(method: CallableMethod): Callable {
|
||||||
return UnaryIntrinsic(method, numberFunctionOperandType(method.returnType), needPrimitiveCheck = true) {
|
return createUnaryCallable(method, numberFunctionOperandType(method.returnType), needPrimitiveCheck = true) {
|
||||||
it.neg(returnType)
|
it.neg(returnType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.codegen.CallableMethod
|
|||||||
public class UnaryPlus : IntrinsicMethod() {
|
public class UnaryPlus : IntrinsicMethod() {
|
||||||
|
|
||||||
override fun toCallable(method: CallableMethod): Callable {
|
override fun toCallable(method: CallableMethod): Callable {
|
||||||
return UnaryIntrinsic(method, needPrimitiveCheck = true) {
|
return createUnaryCallable(method, needPrimitiveCheck = true) {
|
||||||
//nothing
|
//nothing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user