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
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.org.objectweb.asm.Label
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.Opcodes.*
import org.jetbrains.org.objectweb.asm.Type
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) {
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) {
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) {
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) :
BranchedValue(BranchedValue.condJump(arg1), BranchedValue.condJump(arg2), Type.BOOLEAN_TYPE, IFEQ) {
class And(
arg1: StackValue,
arg2: StackValue
) : BranchedValue(BranchedValue.condJump(arg1), BranchedValue.condJump(arg2), Type.BOOLEAN_TYPE, IFEQ) {
override fun condJump(jumpLabel: Label, v: InstructionAdapter, jumpIfFalse: Boolean) {
val stayLabel = Label()
@@ -138,8 +142,10 @@ class And(arg1: StackValue, arg2: StackValue) :
}
}
class Or(arg1: StackValue, arg2: StackValue) :
BranchedValue(BranchedValue.condJump(arg1), BranchedValue.condJump(arg2), Type.BOOLEAN_TYPE, IFEQ) {
class Or(
arg1: StackValue,
arg2: StackValue
) : BranchedValue(BranchedValue.condJump(arg1), BranchedValue.condJump(arg2), Type.BOOLEAN_TYPE, IFEQ) {
override fun condJump(jumpLabel: Label, v: InstructionAdapter, jumpIfFalse: Boolean) {
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) :
BranchedValue(left, right, operandType, NumberCompare.getNumberCompareOpcode(opToken)) {
class NumberCompare(
val opToken: IElementType,
operandType: Type,
left: StackValue,
right: StackValue
) : BranchedValue(left, right, operandType, NumberCompare.getNumberCompareOpcode(opToken)) {
override fun patchOpcode(opcode: Int, v: InstructionAdapter): Int {
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) :
BranchedValue(left, right, operandType, ObjectCompare.getObjectCompareOpcode(opToken)) {
class ObjectCompare(
val opToken: IElementType,
operandType: Type,
left: StackValue,
right: StackValue
) : BranchedValue(left, right, operandType, ObjectCompare.getObjectCompareOpcode(opToken)) {
companion object {
fun getObjectCompareOpcode(opToken: IElementType): Int {
@@ -16,14 +16,9 @@
package org.jetbrains.kotlin.codegen;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.codegen.state.GenerationState;
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;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
public trait Callable {
public val owner: Type
@@ -16,40 +16,36 @@
package org.jetbrains.kotlin.codegen;
import com.sun.org.apache.bcel.internal.generic.INVOKESPECIAL
import com.sun.org.apache.bcel.internal.generic.INVOKESTATIC
import kotlin.Function1;
import kotlin.Unit;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
import org.jetbrains.kotlin.load.java.JvmAbi;
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 org.jetbrains.kotlin.codegen.state.JetTypeMapper
import org.jetbrains.kotlin.load.java.JvmAbi
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.INVOKESPECIAL
import org.jetbrains.org.objectweb.asm.Opcodes.INVOKESTATIC
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, 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 {
public fun getValueParameters(): List<JvmMethodParameterSignature> {
return signature.getValueParameters()
}
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 {
public fun getValueParameters(): List<JvmMethodParameterSignature> =
signature.getValueParameters()
override val valueParameterTypes: List<Type>
get() = signature.getValueParameters().filter { it.getKind() == JvmMethodParameterKind.VALUE }.map { it.getAsmType() }
public fun getAsmMethod(): Method {
return signature.getAsmMethod()
}
public fun getAsmMethod(): Method =
signature.getAsmMethod()
override val parameterTypes: Array<Type>
get() = getAsmMethod().getArgumentTypes()
@@ -64,29 +60,29 @@ public class CallableMethod(override val owner: Type, private val defaultImplOwn
throw IllegalStateException()
}
val method = getAsmMethod();
val desc = JetTypeMapper.getDefaultDescriptor(method,
if (invokeOpcode == INVOKESTATIC) null else defaultImplParam.getDescriptor(),
extensionReceiverType != null);
val method = getAsmMethod()
val desc = JetTypeMapper.getDefaultDescriptor(
method,
if (invokeOpcode == INVOKESTATIC) null else defaultImplParam.getDescriptor(),
extensionReceiverType != null
)
if ("<init>".equals(method.getName())) {
v.aconst(null)
v.visitMethodInsn(INVOKESPECIAL, defaultImplOwner!!.getInternalName(), "<init>", desc, false)
v.visitMethodInsn(INVOKESPECIAL, defaultImplOwner.getInternalName(), "<init>", desc, false)
}
else {
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
get() = signature.getReturnType()
override fun isStaticCall(): Boolean {
return invokeOpcode == INVOKESTATIC
}
override fun isStaticCall(): Boolean =
invokeOpcode == INVOKESTATIC
override fun toString(): String {
return "${Printer.OPCODES[invokeOpcode]} ${owner.getInternalName()}.$signature"
}
override fun toString(): String =
"${Printer.OPCODES[invokeOpcode]} ${owner.getInternalName()}.$signature"
}
@@ -1922,7 +1922,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
if (intrinsic instanceof JavaClassProperty) {
//TODO: intrinsic properties (see intermediateValueForProperty)
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.Callable
import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
public class ArrayGet : IntrinsicMethod() {
override fun toCallable(method: CallableMethod): Callable =
createIntrinsicCallable(method) {
val type = correctElementType(calcReceiverType())
@@ -16,37 +16,13 @@
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.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() {
override fun toCallable(method: CallableMethod): Callable {
return createUnaryIntrinsicCallable(method) {
val methodSignature = "(${method.owner.getDescriptor()})${returnType.getDescriptor()}"
it.invokestatic("kotlin/jvm/internal/InternalPackage", "iterator", methodSignature, false)
}
}
override fun toCallable(method: CallableMethod): Callable =
createUnaryIntrinsicCallable(method) {
val methodSignature = "(${method.owner.getDescriptor()})${returnType.getDescriptor()}"
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
public class ArraySet : IntrinsicMethod() {
override fun toCallable(method: CallableMethod): Callable {
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) {
v.astore(type)
}
}
}
}
@@ -20,10 +20,8 @@ import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.CallableMethod
public class ArraySize : IntrinsicMethod() {
public override fun toCallable(method: CallableMethod): Callable {
return createUnaryIntrinsicCallable(method) { adapter ->
adapter.arraylength()
}
}
override fun toCallable(method: CallableMethod): Callable =
createUnaryIntrinsicCallable(method) { adapter ->
adapter.arraylength()
}
}
@@ -25,10 +25,8 @@ import org.jetbrains.org.objectweb.asm.Opcodes.IUSHR
import org.jetbrains.org.objectweb.asm.Type
public class BinaryOp(private val opcode: Int) : IntrinsicMethod() {
private fun shift(): Boolean {
return opcode == ISHL || opcode == ISHR || opcode == IUSHR
}
private fun shift(): Boolean =
opcode == ISHL || opcode == ISHR || opcode == IUSHR
override fun toCallable(method: CallableMethod): Callable {
val returnType = method.returnType
@@ -22,11 +22,9 @@ import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE
import org.jetbrains.org.objectweb.asm.Opcodes
public class Clone : IntrinsicMethod() {
override fun toCallable(method: CallableMethod, isSuperCall: Boolean): Callable {
return createUnaryIntrinsicCallable(method, OBJECT_TYPE) {
val opcodes: Int = if (isSuperCall) Opcodes.INVOKESPECIAL else Opcodes.INVOKEVIRTUAL
it.visitMethodInsn(opcodes, "java/lang/Object", "clone", "()Ljava/lang/Object;", false)
}
}
override fun toCallable(method: CallableMethod, isSuperCall: Boolean): Callable =
createUnaryIntrinsicCallable(method, OBJECT_TYPE) {
val opcode = if (isSuperCall) Opcodes.INVOKESPECIAL else Opcodes.INVOKEVIRTUAL
it.visitMethodInsn(opcode, "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
public class CompareTo : IntrinsicMethod() {
private fun genInvoke(type: Type?, v: InstructionAdapter) {
when (type) {
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 {
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) {
genInvoke(parameterType, it)
}
@@ -23,7 +23,6 @@ import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.kotlin.codegen.ExpressionCodegen
import org.jetbrains.kotlin.codegen.StackValue
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.lexer.JetTokens
import org.jetbrains.kotlin.psi.JetBinaryExpression
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
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) {
// LHS + RHS
genStringBuilderConstructor(v)
@@ -56,20 +61,23 @@ public class Concat : IntrinsicMethod() {
}
override fun toCallable(method: CallableMethod): Callable {
return object : IntrinsicCallable(method) {
override fun invokeMethodWithArguments(resolvedCall: ResolvedCall<*>, receiver: StackValue, codegen: ExpressionCodegen): StackValue {
return StackValue.operation(returnType) {
val arguments = resolvedCall.getCall().getValueArguments().map { it.getArgumentExpression() }
val actualType = generateImpl(
codegen, it, returnType,
resolvedCall.getCall().getCallElement(),
arguments,
StackValue.receiver(resolvedCall, receiver, codegen, this)
)
StackValue.coerce(actualType, returnType, it)
override fun toCallable(method: CallableMethod): Callable =
object : IntrinsicCallable(method) {
override fun invokeMethodWithArguments(
resolvedCall: ResolvedCall<*>,
receiver: StackValue,
codegen: ExpressionCodegen
): StackValue {
return StackValue.operation(returnType) {
val arguments = resolvedCall.getCall().getValueArguments().map { it.getArgumentExpression() }
val actualType = generateImpl(
codegen, it, returnType,
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
public class Equals : IntrinsicMethod() {
override fun toCallable(method: CallableMethod): Callable {
return createBinaryIntrinsicCallable(method.returnType, OBJECT_TYPE, nullOrObject(method.dispatchReceiverType), nullOrObject(method.extensionReceiverType)) {
AsmUtil.genAreEqualCall(it)
}
}
override fun toCallable(method: CallableMethod): Callable =
createBinaryIntrinsicCallable(
method.returnType,
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
public class HashCode : IntrinsicMethod() {
override fun toCallable(method: CallableMethod): Callable {
return object: IntrinsicCallable(Type.INT_TYPE, emptyList(), nullOrObject(method.dispatchReceiverType), nullOrObject(method.extensionReceiverType)) {
override fun invokeIntrinsic(v: InstructionAdapter) {
v.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "hashCode", "()I", false)
override fun toCallable(method: CallableMethod): Callable =
object : IntrinsicCallable(
Type.INT_TYPE,
emptyList(),
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.ExpressionCodegen
import org.jetbrains.kotlin.codegen.StackValue
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.lexer.JetTokens
import org.jetbrains.kotlin.psi.JetBinaryExpression
import org.jetbrains.kotlin.psi.JetCallExpression
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE
import org.jetbrains.org.objectweb.asm.Type
public class IdentityEquals : IntrinsicMethod() {
override fun toCallable(method: CallableMethod): Callable {
return object : IntrinsicCallable(method) {
override fun invokeMethodWithArguments(resolvedCall: ResolvedCall<*>, receiver: StackValue, codegen: ExpressionCodegen): StackValue {
val element = resolvedCall.getCall().getCallElement()
val left: StackValue
val right: StackValue
if (element is JetCallExpression) {
left = StackValue.receiver(resolvedCall, receiver, codegen, this)
right = codegen.gen(resolvedCall.getValueArgumentsByIndex()!!.single().getArguments().single().getArgumentExpression())
override fun toCallable(method: CallableMethod): Callable =
object : IntrinsicCallable(method) {
override fun invokeMethodWithArguments(
resolvedCall: ResolvedCall<*>,
receiver: StackValue,
codegen: ExpressionCodegen
): StackValue {
val element = resolvedCall.getCall().getCallElement()
val left: StackValue
val right: StackValue
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.Callable
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.resolve.calls.model.ResolvedCall
public class Increment(private val myDelta: Int) : IntrinsicMethod() {
override fun toCallable(method: CallableMethod, isSuper: Boolean, resolvedCall: ResolvedCall<*>): Callable {
return createIntrinsicCallable(method) {
val jetExpression = resolvedCall.getCall().getCalleeExpression()
assert(jetExpression !is JetPrefixExpression) { "There should be postfix increment ${jetExpression!!.getText()}" }
genIncrement(returnType, myDelta, it)
}
}
override fun toCallable(method: CallableMethod, isSuper: Boolean, resolvedCall: ResolvedCall<*>): Callable =
createIntrinsicCallable(method) {
val jetExpression = resolvedCall.getCall().getCalleeExpression()
assert(jetExpression !is JetPrefixExpression) { "There should be postfix increment ${jetExpression!!.getText()}" }
genIncrement(returnType, myDelta, it)
}
}
@@ -16,25 +16,30 @@
package org.jetbrains.kotlin.codegen.intrinsics
import org.jetbrains.kotlin.codegen.*
import org.jetbrains.kotlin.codegen.context.CodegenContext
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
public open class IntrinsicCallable(override val returnType: Type,
override val valueParameterTypes: List<Type>,
override val dispatchReceiverType: Type?,
override val extensionReceiverType: Type?,
private val invoke: IntrinsicCallable.(v: InstructionAdapter) -> Unit = { throw UnsupportedOperationException() }) : Callable {
public open class IntrinsicCallable(
override val returnType: Type,
override val valueParameterTypes: List<Type>,
override val dispatchReceiverType: Type?,
override val extensionReceiverType: Type?,
private val invoke: IntrinsicCallable.(v: InstructionAdapter) -> Unit = { throw UnsupportedOperationException() }
) : Callable {
constructor(callable: CallableMethod, invoke: IntrinsicCallable.(v: InstructionAdapter) -> Unit = {}) :
this(callable.returnType, callable.valueParameterTypes, callable.dispatchReceiverType, callable.extensionReceiverType, invoke) {
}
constructor(
callable: CallableMethod,
invoke: IntrinsicCallable.(v: InstructionAdapter) -> Unit = {}
) : this(
callable.returnType,
callable.valueParameterTypes,
callable.dispatchReceiverType,
callable.extensionReceiverType,
invoke
)
override fun genInvokeInstruction(v: InstructionAdapter) {
invokeIntrinsic(v)
@@ -45,31 +50,28 @@ public open class IntrinsicCallable(override val returnType: Type,
}
override val parameterTypes: Array<Type>
get() {
throw UnsupportedOperationException()
}
get() = throw UnsupportedOperationException()
override fun isStaticCall(): Boolean {
return false
}
override fun isStaticCall() = false
override val generateCalleeType: Type?
get() {
return null
}
get() = null
override val owner: Type
get() {
throw UnsupportedOperationException()
}
get() = throw UnsupportedOperationException()
public fun calcReceiverType(): Type? {
return extensionReceiverType ?: dispatchReceiverType
}
public fun calcReceiverType(): Type =
extensionReceiverType ?: dispatchReceiverType!!
}
fun createBinaryIntrinsicCallable(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 }
fun createBinaryIntrinsicCallable(
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) {
override fun invokeIntrinsic(v: InstructionAdapter) {
@@ -101,6 +103,9 @@ public fun createUnaryIntrinsicCallable(
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)
}
}
@@ -20,17 +20,19 @@ import org.jetbrains.annotations.NotNull;
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.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.org.objectweb.asm.Type;
public abstract class IntrinsicMethod {
@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);
}
@@ -56,5 +58,4 @@ public abstract class IntrinsicMethod {
public Type nullOr(Type type, Type newType) {
return type == null ? null : newType;
}
}
@@ -22,7 +22,6 @@ import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.org.objectweb.asm.Type
public class Inv : IntrinsicMethod() {
override fun toCallable(method: CallableMethod): Callable {
val type = numberFunctionOperandType(method.returnType)
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.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.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.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
public class IteratorNext : IntrinsicMethod() {
private fun getIteratorName(returnType: Type): String {
return when (returnType) {
Type.CHAR_TYPE -> "Char"
@@ -45,13 +39,17 @@ public class IteratorNext : IntrinsicMethod() {
}
}
override fun toCallable(method: CallableMethod): Callable {
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) {
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
public class JavaClassArray : IntrinsicMethod() {
override fun toCallable(method: CallableMethod): Callable {
return createIntrinsicCallable(method) {
//do nothing all generated as vararg
}
}
override fun toCallable(method: CallableMethod): Callable =
createIntrinsicCallable(method) {
//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
public class JavaClassFunction : IntrinsicMethod() {
override fun toCallable(fd: FunctionDescriptor, isSuper: Boolean, resolvedCall: ResolvedCall<*>, codegen: ExpressionCodegen): Callable {
val javaClass = resolvedCall.getResultingDescriptor().getReturnType()!!.getArguments().get(0).getType()
return object: IntrinsicCallable(getType(javaClass<Class<Any>>()), listOf(), null, null) {
val javaClass = resolvedCall.getResultingDescriptor().getReturnType()!!.getArguments().first().getType()
return object : IntrinsicCallable(getType(javaClass<Class<Any>>()), listOf(), null, null) {
override fun invokeIntrinsic(v: InstructionAdapter) {
codegen.putReifierMarkerIfTypeIsReifiedParameter(javaClass, ReifiedTypeInliner.JAVA_CLASS_MARKER_METHOD_NAME)
putJavaLangClassInstance(v, codegen.getState().getTypeMapper().mapType(javaClass))
}
}
}
}
@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.codegen.intrinsics
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.codegen.AsmUtil.boxType
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.StackValue
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.jvm.AsmTypes.getType
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
public class JavaClassProperty : IntrinsicMethod() {
public fun generate(codegen: ExpressionCodegen, returnType: Type, element: PsiElement?, arguments: List<JetExpression>, receiver: StackValue): StackValue {
return StackValue.operation(returnType) {
val actualType = generateImpl(it, receiver)
StackValue.coerce(actualType, returnType, it)
}
}
public fun generate(returnType: Type, receiver: StackValue): StackValue =
StackValue.operation(returnType) {
val actualType = generateImpl(it, receiver)
StackValue.coerce(actualType, returnType, it)
}
fun generateImpl(v: InstructionAdapter, receiver: StackValue): Type {
val type = receiver.type
@@ -67,9 +64,7 @@ public class JavaClassProperty : IntrinsicMethod() {
}
}
override fun isStaticCall(): Boolean {
return isPrimitive(classType)
}
override fun isStaticCall() = isPrimitive(classType)
}
}
}
@@ -18,16 +18,12 @@ package org.jetbrains.kotlin.codegen.intrinsics
import org.jetbrains.kotlin.codegen.Callable
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.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.Type
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 {
public val MONITOR_ENTER: MonitorInstruction = MonitorInstruction(Opcodes.MONITORENTER)
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
public class NewArray : IntrinsicMethod() {
override fun toCallable(fd: FunctionDescriptor, isSuper: Boolean, resolvedCall: ResolvedCall<*>, codegen: ExpressionCodegen): Callable {
val jetType = resolvedCall.getResultingDescriptor().getReturnType()!!
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
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.kotlin.codegen.ExpressionCodegen
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.resolve.calls.model.ResolvedCall
import org.jetbrains.org.objectweb.asm.Type
public class Not : IntrinsicMethod() {
override fun toCallable(method: CallableMethod): Callable {
return object : IntrinsicCallable(method) {
override fun invokeMethodWithArguments(resolvedCall: ResolvedCall<*>, receiver: StackValue, codegen: ExpressionCodegen): StackValue {
val element = resolvedCall.getCall().getCallElement()
val stackValue =
if (element is JetPrefixExpression) {
codegen.gen(element.getBaseExpression())
}
else {
StackValue.receiver(resolvedCall, receiver, codegen, this)
}
return StackValue.not(stackValue)
override fun toCallable(method: CallableMethod): Callable =
object : IntrinsicCallable(method) {
override fun invokeMethodWithArguments(
resolvedCall: ResolvedCall<*>,
receiver: StackValue,
codegen: ExpressionCodegen
): StackValue {
val element = resolvedCall.getCall().getCallElement()
val stackValue =
if (element is JetPrefixExpression) {
codegen.gen(element.getBaseExpression())
}
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
public class NumberCast : IntrinsicMethod() {
override fun toCallable(method: CallableMethod): Callable {
return createUnaryIntrinsicCallable(method) {
StackValue.coerce(calcReceiverType()!!, returnType, it)
}
}
override fun toCallable(method: CallableMethod): Callable =
createUnaryIntrinsicCallable(method) {
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.CallableMethod
import org.jetbrains.kotlin.codegen.ExpressionCodegen
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.commons.InstructionAdapter
public class RangeTo : IntrinsicMethod() {
private fun nameToPrimitive(name: String) : Type {
return when (name) {
"Double" -> DOUBLE_TYPE;
"Float" -> FLOAT_TYPE
"Long" -> LONG_TYPE
"Int" -> INT_TYPE
"Short" -> SHORT_TYPE
"Char" -> CHAR_TYPE
"Byte" -> BYTE_TYPE
else -> throw IllegalStateException("RangeTo intrinsic can only work for primitive types: " + name)
}
}
private fun nameToPrimitive(name: String): Type =
when (name) {
"Double" -> DOUBLE_TYPE
"Float" -> FLOAT_TYPE
"Long" -> LONG_TYPE
"Int" -> INT_TYPE
"Short" -> SHORT_TYPE
"Char" -> CHAR_TYPE
"Byte" -> BYTE_TYPE
else -> throw IllegalStateException("RangeTo intrinsic can only work for primitive types: $name")
}
override fun toCallable(method: CallableMethod): Callable {
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?) {
v.anew(returnType)
v.dup()
value?.moveToTopOfStack(value!!.type, v, 2)
value?.moveToTopOfStack(value.type, v, 2)
}
override fun invokeIntrinsic(v: InstructionAdapter) {
@@ -55,4 +55,4 @@ public class RangeTo : IntrinsicMethod() {
}
}
}
}
}
@@ -20,10 +20,8 @@ import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.CallableMethod
public class StringGetChar : IntrinsicMethod() {
override fun toCallable(method: CallableMethod): Callable {
return createIntrinsicCallable(method) {
it.invokevirtual("java/lang/String", "charAt", "(I)C", false)
}
}
override fun toCallable(method: CallableMethod): Callable =
createIntrinsicCallable(method) {
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
public class StringPlus : IntrinsicMethod() {
override fun toCallable(method: CallableMethod): Callable {
return createIntrinsicCallable(method) {
it.invokestatic("kotlin/jvm/internal/Intrinsics", "stringPlus", "(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/String;", false)
}
}
override fun toCallable(method: CallableMethod): Callable =
createIntrinsicCallable(method) {
it.invokestatic("kotlin/jvm/internal/Intrinsics", "stringPlus",
"(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
public class ToString : IntrinsicMethod() {
override fun toCallable(method: CallableMethod): Callable {
val type = AsmUtil.stringValueOfType(method.dispatchReceiverType ?: method.extensionReceiverType)
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
public class UnaryMinus : IntrinsicMethod() {
override fun toCallable(method: CallableMethod): Callable {
return createUnaryIntrinsicCallable(method, numberFunctionOperandType(method.returnType), needPrimitiveCheck = true) {
it.neg(returnType)
}
}
override fun toCallable(method: CallableMethod): Callable =
createUnaryIntrinsicCallable(method, numberFunctionOperandType(method.returnType), needPrimitiveCheck = true) {
it.neg(returnType)
}
}
@@ -20,10 +20,8 @@ import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.CallableMethod
public class UnaryPlus : IntrinsicMethod() {
override fun toCallable(method: CallableMethod): Callable {
return createUnaryIntrinsicCallable(method) {
//nothing
}
}
override fun toCallable(method: CallableMethod): Callable =
createUnaryIntrinsicCallable(method) {
//nothing
}
}
@@ -18,11 +18,9 @@ package org.jetbrains.kotlin.idea.completion.test
import com.intellij.codeInsight.lookup.LookupElement
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.project.TargetPlatform
import org.jetbrains.kotlin.idea.test.JetLightCodeInsightFixtureTestCase
import java.io.File
public abstract class JetFixtureCompletionBaseTestCase : JetLightCodeInsightFixtureTestCase() {