Callable methods to properties
This commit is contained in:
@@ -26,26 +26,26 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
|||||||
|
|
||||||
|
|
||||||
public trait Callable {
|
public trait Callable {
|
||||||
public fun getOwner(): Type
|
public val owner: Type
|
||||||
|
|
||||||
|
public val thisType: Type?
|
||||||
|
|
||||||
|
public val receiverType: Type?
|
||||||
|
|
||||||
|
public val generateCalleeType: Type?
|
||||||
|
|
||||||
|
public val valueParameterTypes: List<Type>
|
||||||
|
|
||||||
|
public val argumentTypes: Array<Type>
|
||||||
|
|
||||||
|
public val returnType: Type
|
||||||
|
|
||||||
public fun invokeWithNotNullAssertion(v: InstructionAdapter, state: GenerationState, resolvedCall: ResolvedCall<*>)
|
public fun invokeWithNotNullAssertion(v: InstructionAdapter, state: GenerationState, resolvedCall: ResolvedCall<*>)
|
||||||
|
|
||||||
public fun invokeWithoutAssertions(v: InstructionAdapter)
|
public fun invokeWithoutAssertions(v: InstructionAdapter)
|
||||||
|
|
||||||
public fun getGenerateCalleeType(): Type?
|
|
||||||
|
|
||||||
public fun getValueParameterTypes(): List<Type>
|
|
||||||
|
|
||||||
public fun getArgumentTypes(): Array<Type>
|
|
||||||
|
|
||||||
public fun getReturnType(): Type
|
|
||||||
|
|
||||||
public fun isStaticCall(): Boolean
|
public fun isStaticCall(): Boolean
|
||||||
|
|
||||||
public fun getThisType(): Type?
|
|
||||||
|
|
||||||
public fun getReceiverClass(): Type?
|
|
||||||
|
|
||||||
public fun beforeParameterGeneration(v: InstructionAdapter, value: StackValue?)
|
public fun beforeParameterGeneration(v: InstructionAdapter, value: StackValue?)
|
||||||
|
|
||||||
public fun invokeMethodWithArguments(resolvedCall: ResolvedCall<*>, receiver: StackValue, returnType: Type, codegen: ExpressionCodegen): StackValue
|
public fun invokeMethodWithArguments(resolvedCall: ResolvedCall<*>, receiver: StackValue, returnType: Type, codegen: ExpressionCodegen): StackValue
|
||||||
|
|||||||
@@ -38,42 +38,31 @@ import org.jetbrains.org.objectweb.asm.util.Printer;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
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?) : Callable {
|
public class CallableMethod(override val owner: Type, private val defaultImplOwner: Type?, private val defaultImplParam: Type?, private val signature: JvmMethodSignature, private val invokeOpcode: Int, override val thisType: Type?, override val receiverType: Type?, override val generateCalleeType: Type?) : Callable {
|
||||||
|
|
||||||
override fun getOwner(): Type {
|
|
||||||
return owner
|
|
||||||
}
|
|
||||||
|
|
||||||
public fun getValueParameters(): List<JvmMethodParameterSignature> {
|
public fun getValueParameters(): List<JvmMethodParameterSignature> {
|
||||||
return signature.getValueParameters()
|
return signature.getValueParameters()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getValueParameterTypes(): List<Type> {
|
override val valueParameterTypes: List<Type>
|
||||||
val valueParameters = signature.getValueParameters()
|
get() {
|
||||||
val result = ArrayList<Type>(valueParameters.size())
|
val valueParameters = signature.getValueParameters()
|
||||||
for (parameter in valueParameters) {
|
val result = ArrayList<Type>(valueParameters.size())
|
||||||
if (parameter.getKind() == JvmMethodParameterKind.VALUE) {
|
for (parameter in valueParameters) {
|
||||||
result.add(parameter.getAsmType())
|
if (parameter.getKind() == JvmMethodParameterKind.VALUE) {
|
||||||
|
result.add(parameter.getAsmType())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
public fun getAsmMethod(): Method {
|
public fun getAsmMethod(): Method {
|
||||||
return signature.getAsmMethod()
|
return signature.getAsmMethod()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getArgumentTypes(): Array<Type> {
|
override val argumentTypes: Array<Type>
|
||||||
return signature.getAsmMethod().getArgumentTypes()
|
get() =signature.getAsmMethod().getArgumentTypes()
|
||||||
}
|
|
||||||
|
|
||||||
override fun getThisType(): Type? {
|
|
||||||
return thisClass
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getReceiverClass(): Type? {
|
|
||||||
return receiverParameterType
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun invoke(v: InstructionAdapter) {
|
private fun invoke(v: InstructionAdapter) {
|
||||||
v.visitMethodInsn(invokeOpcode, owner.getInternalName(), getAsmMethod().getName(), getAsmMethod().getDescriptor())
|
v.visitMethodInsn(invokeOpcode, owner.getInternalName(), getAsmMethod().getName(), getAsmMethod().getDescriptor())
|
||||||
@@ -89,10 +78,6 @@ public class CallableMethod(private val owner: Type, private val defaultImplOwne
|
|||||||
invoke(v)
|
invoke(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getGenerateCalleeType(): Type? {
|
|
||||||
return generateCalleeType
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun invokeDefault(v: InstructionAdapter) {
|
private fun invokeDefault(v: InstructionAdapter) {
|
||||||
if (defaultImplOwner == null || defaultImplParam == null) {
|
if (defaultImplOwner == null || defaultImplParam == null) {
|
||||||
throw IllegalStateException()
|
throw IllegalStateException()
|
||||||
@@ -100,8 +85,8 @@ public class CallableMethod(private val owner: Type, private val defaultImplOwne
|
|||||||
|
|
||||||
val method = getAsmMethod();
|
val method = getAsmMethod();
|
||||||
val desc = JetTypeMapper.getDefaultDescriptor(method,
|
val desc = JetTypeMapper.getDefaultDescriptor(method,
|
||||||
if (invokeOpcode == INVOKESTATIC) null else defaultImplParam.getDescriptor(),
|
if (invokeOpcode == INVOKESTATIC) null else defaultImplParam.getDescriptor(),
|
||||||
receiverParameterType != null);
|
receiverType != null);
|
||||||
|
|
||||||
if ("<init>".equals(method.getName())) {
|
if ("<init>".equals(method.getName())) {
|
||||||
v.aconst(null)
|
v.aconst(null)
|
||||||
@@ -118,9 +103,10 @@ public class CallableMethod(private val owner: Type, private val defaultImplOwne
|
|||||||
AsmUtil.genNotNullAssertionForMethod(v, state, resolvedCall)
|
AsmUtil.genNotNullAssertionForMethod(v, state, resolvedCall)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getReturnType(): Type {
|
override val returnType: Type
|
||||||
return signature.getReturnType()
|
get() {
|
||||||
}
|
return signature.getReturnType()
|
||||||
|
}
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
return Printer.OPCODES[invokeOpcode] + " " + owner.getInternalName() + "." + signature
|
return Printer.OPCODES[invokeOpcode] + " " + owner.getInternalName() + "." + signature
|
||||||
@@ -130,7 +116,6 @@ public class CallableMethod(private val owner: Type, private val defaultImplOwne
|
|||||||
return invokeOpcode == INVOKESTATIC
|
return invokeOpcode == INVOKESTATIC
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override fun beforeParameterGeneration(v: InstructionAdapter, value: StackValue?) {
|
public override fun beforeParameterGeneration(v: InstructionAdapter, value: StackValue?) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -136,7 +136,7 @@ public class DefaultParameterValueSubstitutor(val state: GenerationState) {
|
|||||||
val v = InstructionAdapter(mv)
|
val v = InstructionAdapter(mv)
|
||||||
mv.visitCode()
|
mv.visitCode()
|
||||||
|
|
||||||
val methodOwner = typeMapper.mapToCallableMethod(delegateFunctionDescriptor, false, context).getOwner()
|
val methodOwner = typeMapper.mapToCallableMethod(delegateFunctionDescriptor, false, context).owner
|
||||||
if (!isStatic) {
|
if (!isStatic) {
|
||||||
val thisIndex = frameMap.enterTemp(AsmTypes.OBJECT_TYPE)
|
val thisIndex = frameMap.enterTemp(AsmTypes.OBJECT_TYPE)
|
||||||
v.load(thisIndex, methodOwner) // Load this on stack
|
v.load(thisIndex, methodOwner) // Load this on stack
|
||||||
|
|||||||
@@ -1275,7 +1275,7 @@ public abstract class StackValue {
|
|||||||
ReceiverParameterDescriptor extensionReceiver = descriptor.getExtensionReceiverParameter();
|
ReceiverParameterDescriptor extensionReceiver = descriptor.getExtensionReceiverParameter();
|
||||||
|
|
||||||
if (extensionReceiver != null) {
|
if (extensionReceiver != null) {
|
||||||
return callableMethod != null ? callableMethod.getReceiverClass() : typeMapper.mapType(extensionReceiver.getType());
|
return callableMethod != null ? callableMethod.getReceiverType() : typeMapper.mapType(extensionReceiver.getType());
|
||||||
}
|
}
|
||||||
else if (dispatchReceiver != null) {
|
else if (dispatchReceiver != null) {
|
||||||
if (AnnotationsPackage.isPlatformStaticInObjectOrClass(descriptor)) {
|
if (AnnotationsPackage.isPlatformStaticInObjectOrClass(descriptor)) {
|
||||||
|
|||||||
@@ -74,13 +74,13 @@ public class TailRecursionCodegen {
|
|||||||
throw new IllegalStateException("Failed to arrange value arguments by index: " + fd);
|
throw new IllegalStateException("Failed to arrange value arguments by index: " + fd);
|
||||||
}
|
}
|
||||||
assignParameterValues(fd, callable, arguments);
|
assignParameterValues(fd, callable, arguments);
|
||||||
if (callable.getReceiverClass() != null) {
|
if (callable.getReceiverType() != null) {
|
||||||
if (resolvedCall.getExtensionReceiver() != fd.getExtensionReceiverParameter().getValue()) {
|
if (resolvedCall.getExtensionReceiver() != fd.getExtensionReceiverParameter().getValue()) {
|
||||||
StackValue expression = context.getReceiverExpression(codegen.typeMapper);
|
StackValue expression = context.getReceiverExpression(codegen.typeMapper);
|
||||||
expression.store(StackValue.onStack(callable.getReceiverClass()), v, true);
|
expression.store(StackValue.onStack(callable.getReceiverType()), v, true);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
AsmUtil.pop(v, callable.getReceiverClass());
|
AsmUtil.pop(v, callable.getReceiverType());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
|||||||
public class ArraySet : IntrinsicMethod() {
|
public class ArraySet : IntrinsicMethod() {
|
||||||
|
|
||||||
override fun toCallable(method: CallableMethod): Callable {
|
override fun toCallable(method: CallableMethod): Callable {
|
||||||
val type = correctElementType(method.getThisType())
|
val type = correctElementType(method.thisType)
|
||||||
return object: IntrinsicCallable(Type.VOID_TYPE, listOf(Type.INT_TYPE, type), method.getThisType(), method.getReceiverClass()) {
|
return object: IntrinsicCallable(Type.VOID_TYPE, listOf(Type.INT_TYPE, type), method.thisType, method.receiverType) {
|
||||||
override fun invokeIntrinsic(v: InstructionAdapter) {
|
override fun invokeIntrinsic(v: InstructionAdapter) {
|
||||||
v.astore(type)
|
v.astore(type)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,13 +31,13 @@ public class BinaryOp(private val opcode: Int) : IntrinsicMethod() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun toCallable(method: CallableMethod): Callable {
|
override fun toCallable(method: CallableMethod): Callable {
|
||||||
val returnType = method.getReturnType()
|
val returnType = method.returnType
|
||||||
assert(method.getValueParameters().size() == 1)
|
assert(method.getValueParameters().size() == 1)
|
||||||
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 IntrinsicCallable.binaryIntrinsic(operandType, paramType, operandType) {
|
||||||
v -> v.visitInsn(getReturnType().getOpcode(opcode))
|
v -> v.visitInsn(returnType.getOpcode(opcode))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,8 +43,8 @@ public class CompareTo : IntrinsicMethod() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun toCallable(method: CallableMethod): Callable {
|
override fun toCallable(method: CallableMethod): Callable {
|
||||||
val argumentType = comparisonOperandType(method.getThisType() ?: method.getReceiverClass(), method.getArgumentTypes().first())
|
val argumentType = comparisonOperandType(method.thisType ?: method.receiverType, method.argumentTypes.first())
|
||||||
return IntrinsicCallable.binaryIntrinsic(method.getReturnType(), argumentType, argumentType, null) {
|
return IntrinsicCallable.binaryIntrinsic(method.returnType, argumentType, argumentType, null) {
|
||||||
genInvoke(argumentType, it)
|
genInvoke(argumentType, it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.getReturnType(), OBJECT_TYPE, nullOrObject(method.getThisType()), nullOrObject(method.getReceiverClass())) {
|
return IntrinsicCallable.binaryIntrinsic(method.returnType, OBJECT_TYPE, nullOrObject(method.thisType), nullOrObject(method.receiverType)) {
|
||||||
AsmUtil.genAreEqualCall(it)
|
AsmUtil.genAreEqualCall(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
|||||||
public class HashCode : IntrinsicMethod() {
|
public class HashCode : IntrinsicMethod() {
|
||||||
|
|
||||||
override fun toCallable(method: CallableMethod): Callable {
|
override fun toCallable(method: CallableMethod): Callable {
|
||||||
return object: IntrinsicCallable(Type.INT_TYPE, emptyList(), nullOrObject(method.getThisType()), nullOrObject(method.getReceiverClass())) {
|
return object: IntrinsicCallable(Type.INT_TYPE, emptyList(), nullOrObject(method.thisType), nullOrObject(method.receiverType)) {
|
||||||
override fun invokeIntrinsic(v: InstructionAdapter) {
|
override fun invokeIntrinsic(v: InstructionAdapter) {
|
||||||
v.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "hashCode", "()I", false)
|
v.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "hashCode", "()I", false)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ public class Increment(private val myDelta: Int) : IntrinsicMethod() {
|
|||||||
return MappedCallable(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(getReturnType(), myDelta, it)
|
genIncrement(returnType, myDelta, it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,10 +25,10 @@ import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
|||||||
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
|
||||||
|
|
||||||
public abstract class IntrinsicCallable(val returnType1: Type,
|
public abstract class IntrinsicCallable(override val returnType: Type,
|
||||||
val valueParametersTypes: List<Type>,
|
override val valueParameterTypes: List<Type>,
|
||||||
val thisType1: Type?,
|
override val thisType: Type?,
|
||||||
val receiverType1: Type?) : Callable {
|
override val receiverType: Type?) : Callable {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun create(descriptor: FunctionDescriptor, context: CodegenContext<*>, state: GenerationState, lambda: IntrinsicCallable.(i: InstructionAdapter) -> Unit): IntrinsicCallable {
|
fun create(descriptor: FunctionDescriptor, context: CodegenContext<*>, state: GenerationState, lambda: IntrinsicCallable.(i: InstructionAdapter) -> Unit): IntrinsicCallable {
|
||||||
@@ -36,7 +36,7 @@ public abstract class IntrinsicCallable(val returnType1: Type,
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun create(callableMethod: CallableMethod, lambda: IntrinsicCallable.(i: InstructionAdapter) -> Unit): IntrinsicCallable {
|
fun create(callableMethod: CallableMethod, lambda: IntrinsicCallable.(i: InstructionAdapter) -> Unit): IntrinsicCallable {
|
||||||
return object : IntrinsicCallable(callableMethod.getReturnType(), callableMethod.getValueParameterTypes(), callableMethod.getThisType(), callableMethod.getReceiverClass()) {
|
return object : IntrinsicCallable(callableMethod.returnType, callableMethod.valueParameterTypes, callableMethod.thisType, callableMethod.receiverType) {
|
||||||
override fun invokeIntrinsic(v: InstructionAdapter) {
|
override fun invokeIntrinsic(v: InstructionAdapter) {
|
||||||
lambda(v)
|
lambda(v)
|
||||||
}
|
}
|
||||||
@@ -56,7 +56,7 @@ public abstract class IntrinsicCallable(val returnType1: Type,
|
|||||||
fun create(descriptor: FunctionDescriptor, context: CodegenContext<*>, state: GenerationState, receiverTransformer: Type.() -> Type, lambda: IntrinsicCallable.(i: InstructionAdapter) -> Unit): IntrinsicCallable {
|
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)
|
val callableMethod = state.getTypeMapper().mapToCallableMethod(descriptor, false, context)
|
||||||
|
|
||||||
return object : IntrinsicCallable(callableMethod.getReturnType(), callableMethod.getValueParameterTypes(), callableMethod.getThisType()?.receiverTransformer(), callableMethod.getReceiverClass()?.receiverTransformer()) {
|
return object : IntrinsicCallable(callableMethod.returnType, callableMethod.valueParameterTypes, callableMethod.thisType?.receiverTransformer(), callableMethod.receiverType?.receiverTransformer()) {
|
||||||
override fun invokeIntrinsic(v: InstructionAdapter) {
|
override fun invokeIntrinsic(v: InstructionAdapter) {
|
||||||
lambda(v)
|
lambda(v)
|
||||||
}
|
}
|
||||||
@@ -64,11 +64,6 @@ public abstract class IntrinsicCallable(val returnType1: Type,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getValueParameterTypes(): List<Type> {
|
|
||||||
return valueParametersTypes
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
override fun invokeWithoutAssertions(v: InstructionAdapter) {
|
override fun invokeWithoutAssertions(v: InstructionAdapter) {
|
||||||
invokeIntrinsic(v)
|
invokeIntrinsic(v)
|
||||||
}
|
}
|
||||||
@@ -79,36 +74,27 @@ public abstract class IntrinsicCallable(val returnType1: Type,
|
|||||||
|
|
||||||
public abstract fun invokeIntrinsic(v: InstructionAdapter);
|
public abstract fun invokeIntrinsic(v: InstructionAdapter);
|
||||||
|
|
||||||
override fun getArgumentTypes(): Array<Type> {
|
override val argumentTypes: Array<Type>
|
||||||
throw UnsupportedOperationException()
|
get() {
|
||||||
}
|
throw UnsupportedOperationException()
|
||||||
|
}
|
||||||
|
|
||||||
override fun isStaticCall(): Boolean {
|
override fun isStaticCall(): Boolean {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getGenerateCalleeType(): Type? {
|
override val generateCalleeType: Type?
|
||||||
return null
|
get() {
|
||||||
}
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
override fun getReturnType(): Type {
|
override val owner: Type
|
||||||
return returnType1
|
get() {
|
||||||
}
|
throw UnsupportedOperationException()
|
||||||
|
}
|
||||||
override fun getThisType(): Type? {
|
|
||||||
return thisType1
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getReceiverClass(): Type? {
|
|
||||||
return receiverType1
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getOwner(): Type {
|
|
||||||
throw UnsupportedOperationException()
|
|
||||||
}
|
|
||||||
|
|
||||||
public fun calcReceiverType(): Type? {
|
public fun calcReceiverType(): Type? {
|
||||||
return getReceiverClass() ?: getThisType()
|
return receiverType ?: thisType
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun beforeParameterGeneration(v: InstructionAdapter, value: StackValue?) {
|
override fun beforeParameterGeneration(v: InstructionAdapter, value: StackValue?) {
|
||||||
@@ -124,13 +110,13 @@ public abstract class IntrinsicCallable(val returnType1: Type,
|
|||||||
|
|
||||||
|
|
||||||
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.getReturnType(), callable.getValueParameterTypes(), newThisType ?: callable.getThisType(), callable.getReceiverClass()) {
|
IntrinsicCallable(newReturnType ?: callable.returnType, callable.valueParameterTypes, newThisType ?: callable.thisType, callable.receiverType) {
|
||||||
|
|
||||||
{
|
{
|
||||||
if (needPrimitiveCheck) {
|
if (needPrimitiveCheck) {
|
||||||
assert(AsmUtil.isPrimitive(getReturnType())) { "Return type of UnaryPlus intrinsic should be of primitive type : " + getReturnType() }
|
assert(AsmUtil.isPrimitive(returnType)) { "Return type of UnaryPlus intrinsic should be of primitive type : " + returnType }
|
||||||
}
|
}
|
||||||
assert(getValueParameterTypes().size == 0, "Unary operation should not have any parameters")
|
assert(valueParameterTypes.size == 0, "Unary operation should not have any parameters")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun invokeIntrinsic(v: InstructionAdapter) {
|
override fun invokeIntrinsic(v: InstructionAdapter) {
|
||||||
@@ -140,7 +126,7 @@ public class UnaryIntrinsic(val callable: CallableMethod, val newReturnType: Typ
|
|||||||
}
|
}
|
||||||
|
|
||||||
public open class MappedCallable(val callable: CallableMethod, val invoke: MappedCallable.(v: InstructionAdapter) -> Unit = {}) :
|
public open class MappedCallable(val callable: CallableMethod, val invoke: MappedCallable.(v: InstructionAdapter) -> Unit = {}) :
|
||||||
IntrinsicCallable(callable.getReturnType(), callable.getValueParameterTypes(), callable.getThisType(), callable.getReceiverClass()) {
|
IntrinsicCallable(callable.returnType, callable.valueParameterTypes, callable.thisType, callable.receiverType) {
|
||||||
|
|
||||||
|
|
||||||
override fun invokeIntrinsic(v: InstructionAdapter) {
|
override fun invokeIntrinsic(v: InstructionAdapter) {
|
||||||
|
|||||||
@@ -24,15 +24,15 @@ import org.jetbrains.org.objectweb.asm.Type
|
|||||||
public class Inv : IntrinsicMethod() {
|
public class Inv : IntrinsicMethod() {
|
||||||
|
|
||||||
override fun toCallable(method: CallableMethod): Callable {
|
override fun toCallable(method: CallableMethod): Callable {
|
||||||
val type = numberFunctionOperandType(method.getReturnType())
|
val type = numberFunctionOperandType(method.returnType)
|
||||||
return UnaryIntrinsic(method, method.getReturnType(), newThisType = type) {
|
return UnaryIntrinsic(method, method.returnType, newThisType = type) {
|
||||||
if (getReturnType() == Type.LONG_TYPE) {
|
if (returnType == Type.LONG_TYPE) {
|
||||||
it.lconst(-1)
|
it.lconst(-1)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
it.iconst(-1)
|
it.iconst(-1)
|
||||||
}
|
}
|
||||||
it.xor(getReturnType())
|
it.xor(returnType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ public class IteratorNext : IntrinsicMethod() {
|
|||||||
val type = state.getTypeMapper().mapReturnType(fd)
|
val type = state.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 = getReturnType()
|
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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ public class NumberCast : IntrinsicMethod() {
|
|||||||
|
|
||||||
override fun toCallable(method: CallableMethod): Callable {
|
override fun toCallable(method: CallableMethod): Callable {
|
||||||
return UnaryIntrinsic(method) {
|
return UnaryIntrinsic(method) {
|
||||||
StackValue.coerce(calcReceiverType()!!, getReturnType(), it)
|
StackValue.coerce(calcReceiverType()!!, returnType, it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,16 +42,16 @@ public class RangeTo : IntrinsicMethod() {
|
|||||||
|
|
||||||
override fun toCallable(fd: FunctionDescriptor, isSuper: Boolean, resolvedCall: ResolvedCall<*>, codegen: ExpressionCodegen): Callable {
|
override fun toCallable(fd: FunctionDescriptor, isSuper: Boolean, resolvedCall: ResolvedCall<*>, codegen: ExpressionCodegen): Callable {
|
||||||
val method = codegen.getState().getTypeMapper().mapToCallableMethod(fd, false, codegen.getContext())
|
val method = codegen.getState().getTypeMapper().mapToCallableMethod(fd, false, codegen.getContext())
|
||||||
val argType = nameToPrimitive(method.getReturnType().getInternalName().substringAfter("kotlin/").substringBefore("Range"))
|
val argType = nameToPrimitive(method.returnType.getInternalName().substringAfter("kotlin/").substringBefore("Range"))
|
||||||
return object : IntrinsicCallable(method.getReturnType(), method.getValueParameterTypes().map { argType }, nullOr(method.getThisType(), argType), nullOr(method.getReceiverClass(), argType)) {
|
return object : IntrinsicCallable(method.returnType, method.valueParameterTypes.map { argType }, nullOr(method.thisType, argType), nullOr(method.receiverType, argType)) {
|
||||||
override fun beforeParameterGeneration(v: InstructionAdapter, value: StackValue?) {
|
override fun beforeParameterGeneration(v: InstructionAdapter, value: StackValue?) {
|
||||||
v.anew(getReturnType())
|
v.anew(returnType)
|
||||||
v.dup()
|
v.dup()
|
||||||
value?.moveToTopOfStack(value!!.type, v, 2)
|
value?.moveToTopOfStack(value!!.type, v, 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun invokeIntrinsic(v: InstructionAdapter) {
|
override fun invokeIntrinsic(v: InstructionAdapter) {
|
||||||
v.invokespecial(getReturnType().getInternalName(), "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, argType, argType), false)
|
v.invokespecial(returnType.getInternalName(), "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, argType, argType), false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.codegen.CallableMethod
|
|||||||
public class ToString : IntrinsicMethod() {
|
public class ToString : IntrinsicMethod() {
|
||||||
|
|
||||||
override fun toCallable(method: CallableMethod): Callable {
|
override fun toCallable(method: CallableMethod): Callable {
|
||||||
val type = AsmUtil.stringValueOfType(method.getThisType() ?: method.getReceiverClass())
|
val type = AsmUtil.stringValueOfType(method.thisType ?: method.receiverType)
|
||||||
return UnaryIntrinsic(method, newThisType = type) {
|
return UnaryIntrinsic(method, newThisType = type) {
|
||||||
it.invokestatic("java/lang/String", "valueOf", "(" + type.getDescriptor() + ")Ljava/lang/String;", false)
|
it.invokestatic("java/lang/String", "valueOf", "(" + type.getDescriptor() + ")Ljava/lang/String;", false)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,8 +23,8 @@ 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.getReturnType()), needPrimitiveCheck = true) {
|
return UnaryIntrinsic(method, numberFunctionOperandType(method.returnType), needPrimitiveCheck = true) {
|
||||||
it.neg(getReturnType())
|
it.neg(returnType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user