Reformat some code, optimize imports, remove unused

Mostly in JVM codegen intrinsics
This commit is contained in:
Alexander Udalov
2015-04-28 00:35:53 +03:00
parent 7831e75955
commit 94eac98500
34 changed files with 291 additions and 331 deletions
@@ -17,18 +17,20 @@
package org.jetbrains.kotlin.codegen package org.jetbrains.kotlin.codegen
import com.intellij.psi.tree.IElementType import com.intellij.psi.tree.IElementType
import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.codegen.StackValue
import org.jetbrains.kotlin.lexer.JetTokens import org.jetbrains.kotlin.lexer.JetTokens
import org.jetbrains.org.objectweb.asm.Label import org.jetbrains.org.objectweb.asm.Label
import org.jetbrains.org.objectweb.asm.Type
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.commons.InstructionAdapter import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
open class BranchedValue(val arg1: StackValue, val arg2: StackValue? = null, val operandType: Type, val opcode: Int) : StackValue(Type.BOOLEAN_TYPE) { open class BranchedValue(
val arg1: StackValue,
val arg2: StackValue? = null,
val operandType: Type,
val opcode: Int
) : StackValue(Type.BOOLEAN_TYPE) {
constructor(or: BranchedValue, opcode: Int) : this(or.arg1, or.arg2, or.operandType, opcode) { constructor(or: BranchedValue, opcode: Int) : this(or.arg1, or.arg2, or.operandType, opcode)
}
override fun putSelector(type: Type, v: InstructionAdapter) { override fun putSelector(type: Type, v: InstructionAdapter) {
val branchJumpLabel = Label() val branchJumpLabel = Label()
@@ -65,7 +67,7 @@ open class BranchedValue(val arg1: StackValue, val arg2: StackValue? = null, val
override fun putSelector(type: Type, v: InstructionAdapter) { override fun putSelector(type: Type, v: InstructionAdapter) {
v.iconst(1) v.iconst(1)
coerceTo(type, v); coerceTo(type, v)
} }
} }
@@ -78,7 +80,7 @@ open class BranchedValue(val arg1: StackValue, val arg2: StackValue? = null, val
override fun putSelector(type: Type, v: InstructionAdapter) { override fun putSelector(type: Type, v: InstructionAdapter) {
v.iconst(0) v.iconst(0)
coerceTo(type, v); coerceTo(type, v)
} }
} }
@@ -127,8 +129,10 @@ open class BranchedValue(val arg1: StackValue, val arg2: StackValue? = null, val
} }
} }
class And(arg1: StackValue, arg2: StackValue) : class And(
BranchedValue(BranchedValue.condJump(arg1), BranchedValue.condJump(arg2), Type.BOOLEAN_TYPE, IFEQ) { arg1: StackValue,
arg2: StackValue
) : BranchedValue(BranchedValue.condJump(arg1), BranchedValue.condJump(arg2), Type.BOOLEAN_TYPE, IFEQ) {
override fun condJump(jumpLabel: Label, v: InstructionAdapter, jumpIfFalse: Boolean) { override fun condJump(jumpLabel: Label, v: InstructionAdapter, jumpIfFalse: Boolean) {
val stayLabel = Label() val stayLabel = Label()
@@ -138,8 +142,10 @@ class And(arg1: StackValue, arg2: StackValue) :
} }
} }
class Or(arg1: StackValue, arg2: StackValue) : class Or(
BranchedValue(BranchedValue.condJump(arg1), BranchedValue.condJump(arg2), Type.BOOLEAN_TYPE, IFEQ) { arg1: StackValue,
arg2: StackValue
) : BranchedValue(BranchedValue.condJump(arg1), BranchedValue.condJump(arg2), Type.BOOLEAN_TYPE, IFEQ) {
override fun condJump(jumpLabel: Label, v: InstructionAdapter, jumpIfFalse: Boolean) { override fun condJump(jumpLabel: Label, v: InstructionAdapter, jumpIfFalse: Boolean) {
val stayLabel = Label() val stayLabel = Label()
@@ -167,8 +173,12 @@ class CondJump(val condition: BranchedValue, op: Int) : BranchedValue(condition,
} }
} }
class NumberCompare(val opToken: IElementType, operandType: Type, left: StackValue, right: StackValue) : class NumberCompare(
BranchedValue(left, right, operandType, NumberCompare.getNumberCompareOpcode(opToken)) { val opToken: IElementType,
operandType: Type,
left: StackValue,
right: StackValue
) : BranchedValue(left, right, operandType, NumberCompare.getNumberCompareOpcode(opToken)) {
override fun patchOpcode(opcode: Int, v: InstructionAdapter): Int { override fun patchOpcode(opcode: Int, v: InstructionAdapter): Int {
when (operandType) { when (operandType) {
@@ -207,8 +217,12 @@ class NumberCompare(val opToken: IElementType, operandType: Type, left: StackVal
} }
} }
class ObjectCompare(val opToken: IElementType, operandType: Type, left: StackValue, right: StackValue) : class ObjectCompare(
BranchedValue(left, right, operandType, ObjectCompare.getObjectCompareOpcode(opToken)) { val opToken: IElementType,
operandType: Type,
left: StackValue,
right: StackValue
) : BranchedValue(left, right, operandType, ObjectCompare.getObjectCompareOpcode(opToken)) {
companion object { companion object {
fun getObjectCompareOpcode(opToken: IElementType): Int { fun getObjectCompareOpcode(opToken: IElementType): Int {
@@ -16,14 +16,9 @@
package org.jetbrains.kotlin.codegen; package org.jetbrains.kotlin.codegen;
import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.annotations.Nullable; import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.kotlin.codegen.state.GenerationState; import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument;
import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
public trait Callable { public trait Callable {
public val owner: Type public val owner: Type
@@ -16,40 +16,36 @@
package org.jetbrains.kotlin.codegen; package org.jetbrains.kotlin.codegen;
import com.sun.org.apache.bcel.internal.generic.INVOKESPECIAL import org.jetbrains.kotlin.codegen.state.JetTypeMapper
import com.sun.org.apache.bcel.internal.generic.INVOKESTATIC import org.jetbrains.kotlin.load.java.JvmAbi
import kotlin.Function1; import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind
import kotlin.Unit; import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature
import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
import org.jetbrains.annotations.Nullable; import org.jetbrains.org.objectweb.asm.Opcodes.INVOKESPECIAL
import org.jetbrains.kotlin.codegen.state.GenerationState; import org.jetbrains.org.objectweb.asm.Opcodes.INVOKESTATIC
import org.jetbrains.kotlin.codegen.state.JetTypeMapper; import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall; import org.jetbrains.org.objectweb.asm.commons.Method
import org.jetbrains.kotlin.load.java.JvmAbi; import org.jetbrains.org.objectweb.asm.util.Printer
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind;
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature;
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
import org.jetbrains.org.objectweb.asm.Opcodes.*;
import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
import org.jetbrains.org.objectweb.asm.commons.Method;
import org.jetbrains.org.objectweb.asm.util.Printer;
import java.util.ArrayList; public class CallableMethod(
override val owner: Type,
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 dispatchReceiverType: Type?, override val extensionReceiverType: Type?, override val generateCalleeType: Type?) : Callable { private val defaultImplOwner: Type?,
private val defaultImplParam: Type?,
public fun getValueParameters(): List<JvmMethodParameterSignature> { private val signature: JvmMethodSignature,
return signature.getValueParameters() private val invokeOpcode: Int,
} override val dispatchReceiverType: Type?,
override val extensionReceiverType: Type?,
override val generateCalleeType: Type?
) : Callable {
public fun getValueParameters(): List<JvmMethodParameterSignature> =
signature.getValueParameters()
override val valueParameterTypes: List<Type> override val valueParameterTypes: List<Type>
get() = signature.getValueParameters().filter { it.getKind() == JvmMethodParameterKind.VALUE }.map { it.getAsmType() } get() = signature.getValueParameters().filter { it.getKind() == JvmMethodParameterKind.VALUE }.map { it.getAsmType() }
public fun getAsmMethod(): Method { public fun getAsmMethod(): Method =
return signature.getAsmMethod() signature.getAsmMethod()
}
override val parameterTypes: Array<Type> override val parameterTypes: Array<Type>
get() = getAsmMethod().getArgumentTypes() get() = getAsmMethod().getArgumentTypes()
@@ -64,29 +60,29 @@ public class CallableMethod(override val owner: Type, private val defaultImplOwn
throw IllegalStateException() throw IllegalStateException()
} }
val method = getAsmMethod(); val method = getAsmMethod()
val desc = JetTypeMapper.getDefaultDescriptor(method, val desc = JetTypeMapper.getDefaultDescriptor(
if (invokeOpcode == INVOKESTATIC) null else defaultImplParam.getDescriptor(), method,
extensionReceiverType != null); if (invokeOpcode == INVOKESTATIC) null else defaultImplParam.getDescriptor(),
extensionReceiverType != 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(),
method.getName() + JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX, desc, false); method.getName() + JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX, desc, false)
} }
} }
override val returnType: Type override val returnType: Type
get() = signature.getReturnType() get() = signature.getReturnType()
override fun isStaticCall(): Boolean { override fun isStaticCall(): Boolean =
return invokeOpcode == INVOKESTATIC invokeOpcode == INVOKESTATIC
}
override fun toString(): String { override fun toString(): String =
return "${Printer.OPCODES[invokeOpcode]} ${owner.getInternalName()}.$signature" "${Printer.OPCODES[invokeOpcode]} ${owner.getInternalName()}.$signature"
}
} }
@@ -1922,7 +1922,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
if (intrinsic instanceof JavaClassProperty) { if (intrinsic instanceof JavaClassProperty) {
//TODO: intrinsic properties (see intermediateValueForProperty) //TODO: intrinsic properties (see intermediateValueForProperty)
Type returnType = typeMapper.mapType(memberDescriptor); Type returnType = typeMapper.mapType(memberDescriptor);
return ((JavaClassProperty)intrinsic).generate(this, returnType, expression, Collections.<JetExpression>emptyList(), receiver); return ((JavaClassProperty) intrinsic).generate(returnType, receiver);
} }
} }
@@ -19,10 +19,8 @@ package org.jetbrains.kotlin.codegen.intrinsics;
import org.jetbrains.kotlin.codegen.AsmUtil.correctElementType import org.jetbrains.kotlin.codegen.AsmUtil.correctElementType
import org.jetbrains.kotlin.codegen.Callable import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.CallableMethod import org.jetbrains.kotlin.codegen.CallableMethod
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 =
createIntrinsicCallable(method) { createIntrinsicCallable(method) {
val type = correctElementType(calcReceiverType()) val type = correctElementType(calcReceiverType())
@@ -16,37 +16,13 @@
package org.jetbrains.kotlin.codegen.intrinsics package org.jetbrains.kotlin.codegen.intrinsics
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME
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.CallableMethod
import org.jetbrains.kotlin.codegen.ExpressionCodegen
import org.jetbrains.kotlin.codegen.StackValue
import org.jetbrains.kotlin.codegen.context.CodegenContext
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.JetCallExpression
import org.jetbrains.kotlin.psi.JetExpression
import org.jetbrains.kotlin.psi.JetSimpleNameExpression
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.getType
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
import org.jetbrains.kotlin.utils.join
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
public class ArrayIterator : IntrinsicMethod() { public class ArrayIterator : IntrinsicMethod() {
override fun toCallable(method: CallableMethod): Callable { override fun toCallable(method: CallableMethod): Callable =
return createUnaryIntrinsicCallable(method) { createUnaryIntrinsicCallable(method) {
val methodSignature = "(${method.owner.getDescriptor()})${returnType.getDescriptor()}" val methodSignature = "(${method.owner.getDescriptor()})${returnType.getDescriptor()}"
it.invokestatic("kotlin/jvm/internal/InternalPackage", "iterator", methodSignature, false) it.invokestatic("kotlin/jvm/internal/InternalPackage", "iterator", methodSignature, false)
} }
}
} }
@@ -23,14 +23,17 @@ import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter 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.dispatchReceiverType) val type = correctElementType(method.dispatchReceiverType)
return object: IntrinsicCallable(Type.VOID_TYPE, listOf(Type.INT_TYPE, type), method.dispatchReceiverType, method.extensionReceiverType) { return object : IntrinsicCallable(
Type.VOID_TYPE,
listOf(Type.INT_TYPE, type),
method.dispatchReceiverType,
method.extensionReceiverType
) {
override fun invokeIntrinsic(v: InstructionAdapter) { override fun invokeIntrinsic(v: InstructionAdapter) {
v.astore(type) v.astore(type)
} }
} }
} }
} }
@@ -20,10 +20,8 @@ import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.CallableMethod import org.jetbrains.kotlin.codegen.CallableMethod
public class ArraySize : IntrinsicMethod() { public class ArraySize : IntrinsicMethod() {
override fun toCallable(method: CallableMethod): Callable =
public override fun toCallable(method: CallableMethod): Callable { createUnaryIntrinsicCallable(method) { adapter ->
return createUnaryIntrinsicCallable(method) { adapter -> adapter.arraylength()
adapter.arraylength() }
}
}
} }
@@ -25,10 +25,8 @@ import org.jetbrains.org.objectweb.asm.Opcodes.IUSHR
import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.Type
public class BinaryOp(private val opcode: Int) : IntrinsicMethod() { public class BinaryOp(private val opcode: Int) : IntrinsicMethod() {
private fun shift(): Boolean =
private fun shift(): Boolean { opcode == ISHL || opcode == ISHR || opcode == IUSHR
return opcode == ISHL || opcode == ISHR || opcode == IUSHR
}
override fun toCallable(method: CallableMethod): Callable { override fun toCallable(method: CallableMethod): Callable {
val returnType = method.returnType val returnType = method.returnType
@@ -22,11 +22,9 @@ import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE
import org.jetbrains.org.objectweb.asm.Opcodes 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 { createUnaryIntrinsicCallable(method, OBJECT_TYPE) {
return createUnaryIntrinsicCallable(method, OBJECT_TYPE) { val opcode = if (isSuperCall) Opcodes.INVOKESPECIAL else Opcodes.INVOKEVIRTUAL
val opcodes: Int = if (isSuperCall) Opcodes.INVOKESPECIAL else Opcodes.INVOKEVIRTUAL it.visitMethodInsn(opcode, "java/lang/Object", "clone", "()Ljava/lang/Object;", false)
it.visitMethodInsn(opcodes, "java/lang/Object", "clone", "()Ljava/lang/Object;", false) }
}
}
} }
@@ -23,7 +23,6 @@ import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
public class CompareTo : IntrinsicMethod() { public class CompareTo : IntrinsicMethod() {
private fun genInvoke(type: Type?, v: InstructionAdapter) { private fun genInvoke(type: Type?, v: InstructionAdapter) {
when (type) { when (type) {
Type.INT_TYPE -> v.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, "compare", "(II)I", false) Type.INT_TYPE -> v.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, "compare", "(II)I", false)
@@ -35,7 +34,10 @@ public class CompareTo : IntrinsicMethod() {
} }
override fun toCallable(method: CallableMethod): Callable { override fun toCallable(method: CallableMethod): Callable {
val parameterType = comparisonOperandType(method.dispatchReceiverType ?: method.extensionReceiverType, method.parameterTypes.single()) val parameterType = comparisonOperandType(
method.dispatchReceiverType ?: method.extensionReceiverType,
method.parameterTypes.single()
)
return createBinaryIntrinsicCallable(method.returnType, parameterType, parameterType, null) { return createBinaryIntrinsicCallable(method.returnType, parameterType, parameterType, null) {
genInvoke(parameterType, it) genInvoke(parameterType, it)
} }
@@ -23,7 +23,6 @@ import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.CallableMethod 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.lexer.JetTokens import org.jetbrains.kotlin.lexer.JetTokens
import org.jetbrains.kotlin.psi.JetBinaryExpression import org.jetbrains.kotlin.psi.JetBinaryExpression
import org.jetbrains.kotlin.psi.JetExpression import org.jetbrains.kotlin.psi.JetExpression
@@ -34,8 +33,14 @@ import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
public class Concat : IntrinsicMethod() { public class Concat : IntrinsicMethod() {
fun generateImpl(codegen: ExpressionCodegen, v: InstructionAdapter, returnType: Type, element: PsiElement?, arguments: List<JetExpression>, receiver: StackValue): Type { fun generateImpl(
codegen: ExpressionCodegen,
v: InstructionAdapter,
returnType: Type,
element: PsiElement?,
arguments: List<JetExpression>,
receiver: StackValue
): Type {
if (element is JetBinaryExpression && element.getOperationReference().getReferencedNameElementType() == JetTokens.PLUS) { if (element is JetBinaryExpression && element.getOperationReference().getReferencedNameElementType() == JetTokens.PLUS) {
// LHS + RHS // LHS + RHS
genStringBuilderConstructor(v) genStringBuilderConstructor(v)
@@ -56,20 +61,23 @@ public class Concat : IntrinsicMethod() {
} }
override fun toCallable(method: CallableMethod): Callable { override fun toCallable(method: CallableMethod): Callable =
return object : IntrinsicCallable(method) { object : IntrinsicCallable(method) {
override fun invokeMethodWithArguments(resolvedCall: ResolvedCall<*>, receiver: StackValue, codegen: ExpressionCodegen): StackValue { override fun invokeMethodWithArguments(
return StackValue.operation(returnType) { resolvedCall: ResolvedCall<*>,
val arguments = resolvedCall.getCall().getValueArguments().map { it.getArgumentExpression() } receiver: StackValue,
val actualType = generateImpl( codegen: ExpressionCodegen
codegen, it, returnType, ): StackValue {
resolvedCall.getCall().getCallElement(), return StackValue.operation(returnType) {
arguments, val arguments = resolvedCall.getCall().getValueArguments().map { it.getArgumentExpression() }
StackValue.receiver(resolvedCall, receiver, codegen, this) val actualType = generateImpl(
) codegen, it, returnType,
StackValue.coerce(actualType, returnType, it) resolvedCall.getCall().getCallElement(),
arguments,
StackValue.receiver(resolvedCall, receiver, codegen, this)
)
StackValue.coerce(actualType, returnType, it)
}
} }
} }
}
}
} }
@@ -22,11 +22,13 @@ import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE 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 { createBinaryIntrinsicCallable(
return createBinaryIntrinsicCallable(method.returnType, OBJECT_TYPE, nullOrObject(method.dispatchReceiverType), nullOrObject(method.extensionReceiverType)) { method.returnType,
AsmUtil.genAreEqualCall(it) OBJECT_TYPE,
} nullOrObject(method.dispatchReceiverType),
} nullOrObject(method.extensionReceiverType)
) {
AsmUtil.genAreEqualCall(it)
}
} }
@@ -23,12 +23,15 @@ import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter 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 { object : IntrinsicCallable(
return object: IntrinsicCallable(Type.INT_TYPE, emptyList(), nullOrObject(method.dispatchReceiverType), nullOrObject(method.extensionReceiverType)) { Type.INT_TYPE,
override fun invokeIntrinsic(v: InstructionAdapter) { emptyList(),
v.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "hashCode", "()I", false) nullOrObject(method.dispatchReceiverType),
nullOrObject(method.extensionReceiverType)
) {
override fun invokeIntrinsic(v: InstructionAdapter) {
v.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "hashCode", "()I", false)
}
} }
}
}
} }
@@ -20,34 +20,33 @@ import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.CallableMethod 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.lexer.JetTokens import org.jetbrains.kotlin.lexer.JetTokens
import org.jetbrains.kotlin.psi.JetBinaryExpression import org.jetbrains.kotlin.psi.JetBinaryExpression
import org.jetbrains.kotlin.psi.JetCallExpression import org.jetbrains.kotlin.psi.JetCallExpression
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE
import org.jetbrains.org.objectweb.asm.Type
public class IdentityEquals : IntrinsicMethod() { public class IdentityEquals : IntrinsicMethod() {
override fun toCallable(method: CallableMethod): Callable =
object : IntrinsicCallable(method) {
override fun toCallable(method: CallableMethod): Callable { override fun invokeMethodWithArguments(
return object : IntrinsicCallable(method) { resolvedCall: ResolvedCall<*>,
override fun invokeMethodWithArguments(resolvedCall: ResolvedCall<*>, receiver: StackValue, codegen: ExpressionCodegen): StackValue { receiver: StackValue,
val element = resolvedCall.getCall().getCallElement() codegen: ExpressionCodegen
val left: StackValue ): StackValue {
val right: StackValue val element = resolvedCall.getCall().getCallElement()
if (element is JetCallExpression) { val left: StackValue
left = StackValue.receiver(resolvedCall, receiver, codegen, this) val right: StackValue
right = codegen.gen(resolvedCall.getValueArgumentsByIndex()!!.single().getArguments().single().getArgumentExpression()) if (element is JetCallExpression) {
left = StackValue.receiver(resolvedCall, receiver, codegen, this)
right = codegen.gen(resolvedCall.getValueArgumentsByIndex()!!.single().getArguments().single().getArgumentExpression())
}
else {
element as JetBinaryExpression
left = codegen.gen(element.getLeft())
right = codegen.gen(element.getRight())
}
return StackValue.cmp(JetTokens.EQEQEQ, OBJECT_TYPE, left, right)
} }
else {
val e = element as JetBinaryExpression
left = codegen.gen(e.getLeft())
right = codegen.gen(e.getRight())
}
return StackValue.cmp(JetTokens.EQEQEQ, OBJECT_TYPE, left, right)
} }
}
}
} }
@@ -19,18 +19,14 @@ 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.CallableMethod
import org.jetbrains.kotlin.codegen.ExpressionCodegen
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.psi.JetPrefixExpression import org.jetbrains.kotlin.psi.JetPrefixExpression
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall 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(method: CallableMethod, isSuper: Boolean, resolvedCall: ResolvedCall<*>): Callable =
override fun toCallable(method: CallableMethod, isSuper: Boolean, resolvedCall: ResolvedCall<*>): Callable { createIntrinsicCallable(method) {
return createIntrinsicCallable(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) }
}
}
} }
@@ -16,25 +16,30 @@
package org.jetbrains.kotlin.codegen.intrinsics package org.jetbrains.kotlin.codegen.intrinsics
import org.jetbrains.kotlin.codegen.* import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.codegen.context.CodegenContext import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
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 open class IntrinsicCallable(override val returnType: Type, public open class IntrinsicCallable(
override val valueParameterTypes: List<Type>, override val returnType: Type,
override val dispatchReceiverType: Type?, override val valueParameterTypes: List<Type>,
override val extensionReceiverType: Type?, override val dispatchReceiverType: Type?,
private val invoke: IntrinsicCallable.(v: InstructionAdapter) -> Unit = { throw UnsupportedOperationException() }) : Callable { override val extensionReceiverType: Type?,
private val invoke: IntrinsicCallable.(v: InstructionAdapter) -> Unit = { throw UnsupportedOperationException() }
) : Callable {
constructor(callable: CallableMethod, invoke: IntrinsicCallable.(v: InstructionAdapter) -> Unit = {}) : constructor(
this(callable.returnType, callable.valueParameterTypes, callable.dispatchReceiverType, callable.extensionReceiverType, invoke) { callable: CallableMethod,
invoke: IntrinsicCallable.(v: InstructionAdapter) -> Unit = {}
} ) : this(
callable.returnType,
callable.valueParameterTypes,
callable.dispatchReceiverType,
callable.extensionReceiverType,
invoke
)
override fun genInvokeInstruction(v: InstructionAdapter) { override fun genInvokeInstruction(v: InstructionAdapter) {
invokeIntrinsic(v) invokeIntrinsic(v)
@@ -45,31 +50,28 @@ public open class IntrinsicCallable(override val returnType: Type,
} }
override val parameterTypes: Array<Type> override val parameterTypes: Array<Type>
get() { get() = throw UnsupportedOperationException()
throw UnsupportedOperationException()
}
override fun isStaticCall(): Boolean { override fun isStaticCall() = false
return false
}
override val generateCalleeType: Type? override val generateCalleeType: Type?
get() { get() = null
return null
}
override val owner: Type override val owner: Type
get() { get() = throw UnsupportedOperationException()
throw UnsupportedOperationException()
}
public fun calcReceiverType(): Type? { public fun calcReceiverType(): Type =
return extensionReceiverType ?: dispatchReceiverType extensionReceiverType ?: dispatchReceiverType!!
}
} }
fun createBinaryIntrinsicCallable(returnType: Type, valueParameterType: Type, thisType: Type? = null, receiverType: Type? = null, lambda: IntrinsicCallable.(i: InstructionAdapter) -> Unit): IntrinsicCallable { fun createBinaryIntrinsicCallable(
assert(AsmUtil.isPrimitive(returnType)) { "Return type of BinaryOp intrinsic should be of primitive type : " + returnType } returnType: Type,
valueParameterType: Type,
thisType: Type? = null,
receiverType: Type? = null,
lambda: IntrinsicCallable.(v: 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) { return object : IntrinsicCallable(returnType, listOf(valueParameterType), thisType, receiverType) {
override fun invokeIntrinsic(v: InstructionAdapter) { override fun invokeIntrinsic(v: InstructionAdapter) {
@@ -101,6 +103,9 @@ public fun createUnaryIntrinsicCallable(
return intrinsic return intrinsic
} }
public fun createIntrinsicCallable(callable: CallableMethod, invoke: IntrinsicCallable.(v: InstructionAdapter) -> Unit): IntrinsicCallable { public fun createIntrinsicCallable(
callable: CallableMethod,
invoke: IntrinsicCallable.(v: InstructionAdapter) -> Unit
): IntrinsicCallable {
return IntrinsicCallable(callable, invoke) return IntrinsicCallable(callable, invoke)
} }
@@ -20,17 +20,19 @@ 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;
import org.jetbrains.kotlin.codegen.ExpressionCodegen; import org.jetbrains.kotlin.codegen.ExpressionCodegen;
import org.jetbrains.kotlin.codegen.context.CodegenContext;
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.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;
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().getTypeMapper().mapToCallableMethod(fd, false, codegen.getContext()), isSuper, resolvedCall); return toCallable(codegen.getState().getTypeMapper().mapToCallableMethod(fd, false, codegen.getContext()), isSuper, resolvedCall);
} }
@@ -56,5 +58,4 @@ public abstract class IntrinsicMethod {
public Type nullOr(Type type, Type newType) { public Type nullOr(Type type, Type newType) {
return type == null ? null : newType; return type == null ? null : newType;
} }
} }
@@ -22,7 +22,6 @@ import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.org.objectweb.asm.Type 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.returnType) val type = numberFunctionOperandType(method.returnType)
return createUnaryIntrinsicCallable(method, newThisType = type) { return createUnaryIntrinsicCallable(method, newThisType = type) {
@@ -20,17 +20,11 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME
import org.jetbrains.kotlin.codegen.AsmUtil import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.codegen.Callable import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.CallableMethod import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.kotlin.codegen.ExpressionCodegen
import org.jetbrains.kotlin.codegen.context.CodegenContext
import org.jetbrains.kotlin.codegen.state.GenerationState
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
public class IteratorNext : IntrinsicMethod() { public class IteratorNext : IntrinsicMethod() {
private fun getIteratorName(returnType: Type): String { private fun getIteratorName(returnType: Type): String {
return when (returnType) { return when (returnType) {
Type.CHAR_TYPE -> "Char" Type.CHAR_TYPE -> "Char"
@@ -45,13 +39,17 @@ public class IteratorNext : IntrinsicMethod() {
} }
} }
override fun toCallable(method: CallableMethod): Callable { override fun toCallable(method: CallableMethod): Callable {
val type = AsmUtil.unboxType(method.returnType) val type = AsmUtil.unboxType(method.returnType)
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 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.asString() + "/" + name + "Iterator",
"next$name",
"()" + returnType.getDescriptor(),
false
)
} }
} }
} }
@@ -20,9 +20,8 @@ import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.CallableMethod 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 createIntrinsicCallable(method) { createIntrinsicCallable(method) {
//do nothing all generated as vararg //do nothing all generated as vararg
} }
}
} }
@@ -26,15 +26,13 @@ import org.jetbrains.kotlin.resolve.jvm.AsmTypes.getType
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
public class JavaClassFunction : IntrinsicMethod() { public class JavaClassFunction : 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 javaClass = resolvedCall.getResultingDescriptor().getReturnType()!!.getArguments().get(0).getType() val javaClass = resolvedCall.getResultingDescriptor().getReturnType()!!.getArguments().first().getType()
return object: IntrinsicCallable(getType(javaClass<Class<Any>>()), listOf(), null, null) { return object : IntrinsicCallable(getType(javaClass<Class<Any>>()), listOf(), null, null) {
override fun invokeIntrinsic(v: InstructionAdapter) { override fun invokeIntrinsic(v: InstructionAdapter) {
codegen.putReifierMarkerIfTypeIsReifiedParameter(javaClass, ReifiedTypeInliner.JAVA_CLASS_MARKER_METHOD_NAME) codegen.putReifierMarkerIfTypeIsReifiedParameter(javaClass, ReifiedTypeInliner.JAVA_CLASS_MARKER_METHOD_NAME)
putJavaLangClassInstance(v, codegen.getState().getTypeMapper().mapType(javaClass)) putJavaLangClassInstance(v, codegen.getState().getTypeMapper().mapType(javaClass))
} }
} }
} }
} }
@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.codegen.intrinsics package org.jetbrains.kotlin.codegen.intrinsics
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.codegen.AsmUtil import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.codegen.AsmUtil.boxType import org.jetbrains.kotlin.codegen.AsmUtil.boxType
import org.jetbrains.kotlin.codegen.AsmUtil.isPrimitive import org.jetbrains.kotlin.codegen.AsmUtil.isPrimitive
@@ -24,19 +23,17 @@ import org.jetbrains.kotlin.codegen.Callable
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
import org.jetbrains.kotlin.psi.JetExpression
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall 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.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 class JavaClassProperty : IntrinsicMethod() { public class JavaClassProperty : IntrinsicMethod() {
public fun generate(codegen: ExpressionCodegen, returnType: Type, element: PsiElement?, arguments: List<JetExpression>, receiver: StackValue): StackValue { public fun generate(returnType: Type, receiver: StackValue): StackValue =
return StackValue.operation(returnType) { StackValue.operation(returnType) {
val actualType = generateImpl(it, receiver) val actualType = generateImpl(it, receiver)
StackValue.coerce(actualType, returnType, it) StackValue.coerce(actualType, returnType, it)
} }
}
fun generateImpl(v: InstructionAdapter, receiver: StackValue): Type { fun generateImpl(v: InstructionAdapter, receiver: StackValue): Type {
val type = receiver.type val type = receiver.type
@@ -67,9 +64,7 @@ public class JavaClassProperty : IntrinsicMethod() {
} }
} }
override fun isStaticCall(): Boolean { override fun isStaticCall() = isPrimitive(classType)
return isPrimitive(classType)
}
} }
} }
} }
@@ -18,16 +18,12 @@ 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.CallableMethod
import org.jetbrains.kotlin.codegen.context.CodegenContext
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE
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
public class MonitorInstruction private(private val opcode: Int) : IntrinsicMethod() { public class MonitorInstruction private (private val opcode: Int) : IntrinsicMethod() {
companion object { companion object {
public val MONITOR_ENTER: MonitorInstruction = MonitorInstruction(Opcodes.MONITORENTER) public val MONITOR_ENTER: MonitorInstruction = MonitorInstruction(Opcodes.MONITORENTER)
public val MONITOR_EXIT: MonitorInstruction = MonitorInstruction(Opcodes.MONITOREXIT) public val MONITOR_EXIT: MonitorInstruction = MonitorInstruction(Opcodes.MONITOREXIT)
@@ -24,7 +24,6 @@ import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
public class NewArray : IntrinsicMethod() { public class NewArray : 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 jetType = resolvedCall.getResultingDescriptor().getReturnType()!! val jetType = resolvedCall.getResultingDescriptor().getReturnType()!!
val type = codegen.getState().getTypeMapper().mapType(jetType) val type = codegen.getState().getTypeMapper().mapType(jetType)
@@ -34,6 +33,4 @@ public class NewArray : IntrinsicMethod() {
} }
} }
} }
} }
@@ -16,31 +16,30 @@
package org.jetbrains.kotlin.codegen.intrinsics package org.jetbrains.kotlin.codegen.intrinsics
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.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.psi.JetExpression
import org.jetbrains.kotlin.psi.JetPrefixExpression import org.jetbrains.kotlin.psi.JetPrefixExpression
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.org.objectweb.asm.Type
public class Not : IntrinsicMethod() { public class Not : IntrinsicMethod() {
override fun toCallable(method: CallableMethod): Callable { override fun toCallable(method: CallableMethod): Callable =
return object : IntrinsicCallable(method) { object : IntrinsicCallable(method) {
override fun invokeMethodWithArguments(resolvedCall: ResolvedCall<*>, receiver: StackValue, codegen: ExpressionCodegen): StackValue { override fun invokeMethodWithArguments(
val element = resolvedCall.getCall().getCallElement() resolvedCall: ResolvedCall<*>,
val stackValue = receiver: StackValue,
if (element is JetPrefixExpression) { codegen: ExpressionCodegen
codegen.gen(element.getBaseExpression()) ): StackValue {
} val element = resolvedCall.getCall().getCallElement()
else { val stackValue =
StackValue.receiver(resolvedCall, receiver, codegen, this) if (element is JetPrefixExpression) {
} codegen.gen(element.getBaseExpression())
return StackValue.not(stackValue) }
else {
StackValue.receiver(resolvedCall, receiver, codegen, this)
}
return StackValue.not(stackValue)
}
} }
}
}
} }
@@ -21,10 +21,8 @@ import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.kotlin.codegen.StackValue 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 { createUnaryIntrinsicCallable(method) {
return createUnaryIntrinsicCallable(method) { StackValue.coerce(calcReceiverType(), returnType, it)
StackValue.coerce(calcReceiverType()!!, returnType, it) }
}
}
} }
@@ -18,36 +18,36 @@ 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.CallableMethod
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.resolve.calls.model.ResolvedCall
import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.Type
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 class RangeTo : IntrinsicMethod() { public class RangeTo : IntrinsicMethod() {
private fun nameToPrimitive(name: String): Type =
private fun nameToPrimitive(name: String) : Type { when (name) {
return when (name) { "Double" -> DOUBLE_TYPE
"Double" -> DOUBLE_TYPE; "Float" -> FLOAT_TYPE
"Float" -> FLOAT_TYPE "Long" -> LONG_TYPE
"Long" -> LONG_TYPE "Int" -> INT_TYPE
"Int" -> INT_TYPE "Short" -> SHORT_TYPE
"Short" -> SHORT_TYPE "Char" -> CHAR_TYPE
"Char" -> CHAR_TYPE "Byte" -> BYTE_TYPE
"Byte" -> BYTE_TYPE else -> throw IllegalStateException("RangeTo intrinsic can only work for primitive types: $name")
else -> throw IllegalStateException("RangeTo intrinsic can only work for primitive types: " + name) }
}
}
override fun toCallable(method: CallableMethod): Callable { override fun toCallable(method: CallableMethod): Callable {
val argType = nameToPrimitive(method.returnType.getInternalName().substringAfter("kotlin/").substringBefore("Range")) val argType = nameToPrimitive(method.returnType.getInternalName().substringAfter("kotlin/").substringBefore("Range"))
return object : IntrinsicCallable(method.returnType, method.valueParameterTypes.map { argType }, nullOr(method.dispatchReceiverType, argType), nullOr(method.extensionReceiverType, argType)) { return object : IntrinsicCallable(
method.returnType,
method.valueParameterTypes.map { argType },
nullOr(method.dispatchReceiverType, argType),
nullOr(method.extensionReceiverType, argType)
) {
override fun beforeParameterGeneration(v: InstructionAdapter, value: StackValue?) { override fun beforeParameterGeneration(v: InstructionAdapter, value: StackValue?) {
v.anew(returnType) 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) {
@@ -20,10 +20,8 @@ import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.CallableMethod 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 { createIntrinsicCallable(method) {
return createIntrinsicCallable(method) { it.invokevirtual("java/lang/String", "charAt", "(I)C", false)
it.invokevirtual("java/lang/String", "charAt", "(I)C", false) }
}
}
} }
@@ -20,11 +20,9 @@ import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.CallableMethod 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 { createIntrinsicCallable(method) {
return createIntrinsicCallable(method) { it.invokestatic("kotlin/jvm/internal/Intrinsics", "stringPlus",
it.invokestatic("kotlin/jvm/internal/Intrinsics", "stringPlus", "(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/String;", false) "(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/String;", false)
} }
}
} }
@@ -21,11 +21,10 @@ import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.CallableMethod 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.dispatchReceiverType ?: method.extensionReceiverType) val type = AsmUtil.stringValueOfType(method.dispatchReceiverType ?: method.extensionReceiverType)
return createUnaryIntrinsicCallable(method, newThisType = type) { return createUnaryIntrinsicCallable(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)
} }
} }
} }
@@ -21,10 +21,8 @@ import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.CallableMethod 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 { createUnaryIntrinsicCallable(method, numberFunctionOperandType(method.returnType), needPrimitiveCheck = true) {
return createUnaryIntrinsicCallable(method, numberFunctionOperandType(method.returnType), needPrimitiveCheck = true) { it.neg(returnType)
it.neg(returnType) }
}
}
} }
@@ -20,10 +20,8 @@ import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.CallableMethod 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 { createUnaryIntrinsicCallable(method) {
return createUnaryIntrinsicCallable(method) { //nothing
//nothing }
}
}
} }
@@ -18,11 +18,9 @@ package org.jetbrains.kotlin.idea.completion.test
import com.intellij.codeInsight.lookup.LookupElement import com.intellij.codeInsight.lookup.LookupElement
import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.util.io.FileUtil
import kotlin.Function1
import org.jetbrains.kotlin.idea.test.JetLightCodeInsightFixtureTestCase
import org.jetbrains.kotlin.idea.caches.resolve.LibraryModificationTracker import org.jetbrains.kotlin.idea.caches.resolve.LibraryModificationTracker
import org.jetbrains.kotlin.idea.project.TargetPlatform import org.jetbrains.kotlin.idea.project.TargetPlatform
import org.jetbrains.kotlin.idea.test.JetLightCodeInsightFixtureTestCase
import java.io.File import java.io.File
public abstract class JetFixtureCompletionBaseTestCase : JetLightCodeInsightFixtureTestCase() { public abstract class JetFixtureCompletionBaseTestCase : JetLightCodeInsightFixtureTestCase() {