Clean Intrinsics

This commit is contained in:
Michael Bogdanov
2015-04-04 11:29:17 +03:00
parent 32d4845606
commit 45d5a86468
31 changed files with 96 additions and 804 deletions
@@ -1903,7 +1903,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 intrinsic.generate(this, returnType, expression, Collections.<JetExpression>emptyList(), receiver); return ((JavaClassProperty)intrinsic).generate(this, returnType, expression, Collections.<JetExpression>emptyList(), receiver);
} }
} }
@@ -16,43 +16,17 @@
package org.jetbrains.kotlin.codegen.intrinsics; package org.jetbrains.kotlin.codegen.intrinsics;
import com.intellij.psi.PsiElement;
import kotlin.ExtensionFunction1; import kotlin.ExtensionFunction1;
import kotlin.Unit; import kotlin.Unit;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.codegen.CallableMethod;
import org.jetbrains.kotlin.codegen.ExpressionCodegen;
import org.jetbrains.kotlin.codegen.Callable; import org.jetbrains.kotlin.codegen.Callable;
import org.jetbrains.kotlin.codegen.StackValue; import org.jetbrains.kotlin.codegen.CallableMethod;
import org.jetbrains.kotlin.psi.JetExpression;
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;
import java.util.List;
import static org.jetbrains.kotlin.codegen.AsmUtil.correctElementType; import static org.jetbrains.kotlin.codegen.AsmUtil.correctElementType;
public class ArrayGet extends LazyIntrinsicMethod { public class ArrayGet extends IntrinsicMethod {
@NotNull
@Override
public StackValue generateImpl(
@NotNull ExpressionCodegen codegen,
@NotNull Type returnType,
PsiElement element,
@NotNull List<JetExpression> arguments,
@NotNull StackValue receiver
) {
int argumentIndex;
if (receiver == StackValue.none()) {
receiver = codegen.gen(arguments.get(0));
argumentIndex = 1;
} else {
argumentIndex = 0;
}
Type type = correctElementType(receiver.type);
return StackValue.arrayElement(type, receiver, StackValue.coercion(codegen.gen(arguments.get(argumentIndex)), Type.INT_TYPE));
}
@NotNull @NotNull
@Override @Override
@@ -18,9 +18,13 @@ package org.jetbrains.kotlin.codegen.intrinsics
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.PrimitiveType 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.ExpressionCodegen import org.jetbrains.kotlin.codegen.ExpressionCodegen
import org.jetbrains.kotlin.codegen.StackValue import org.jetbrains.kotlin.codegen.StackValue
import org.jetbrains.kotlin.codegen.context.CodegenContext
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
@@ -28,20 +32,13 @@ import org.jetbrains.kotlin.psi.JetCallExpression
import org.jetbrains.kotlin.psi.JetExpression import org.jetbrains.kotlin.psi.JetExpression
import org.jetbrains.kotlin.psi.JetSimpleNameExpression import org.jetbrains.kotlin.psi.JetSimpleNameExpression
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.getType
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
import org.jetbrains.kotlin.builtins.KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME
import org.jetbrains.kotlin.codegen.AsmUtil.asmDescByFqNameWithoutInnerClasses
import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.context.CodegenContext
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.getType
public class ArrayIterator : IntrinsicMethod() { public class ArrayIterator : IntrinsicMethod() {
override 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 {
receiver.put(receiver.type, v) receiver.put(receiver.type, v)
val call = element as JetCallExpression val call = element as JetCallExpression
val funDescriptor = codegen.getBindingContext().get(BindingContext.REFERENCE_TARGET, call.getCalleeExpression() as JetSimpleNameExpression) as FunctionDescriptor val funDescriptor = codegen.getBindingContext().get(BindingContext.REFERENCE_TARGET, call.getCalleeExpression() as JetSimpleNameExpression) as FunctionDescriptor
@@ -66,10 +63,6 @@ public class ArrayIterator : IntrinsicMethod() {
throw UnsupportedOperationException(containingDeclaration.toString()) throw UnsupportedOperationException(containingDeclaration.toString())
} }
override fun supportCallable(): Boolean {
return true
}
//TODO refactor //TODO refactor
override fun toCallable(state: GenerationState, fd: FunctionDescriptor, context: CodegenContext<*>, isSuper: Boolean): Callable { override fun toCallable(state: GenerationState, fd: FunctionDescriptor, context: CodegenContext<*>, isSuper: Boolean): Callable {
val callableMethod = state.getTypeMapper().mapToCallableMethod(fd, false, context) val callableMethod = state.getTypeMapper().mapToCallableMethod(fd, false, context)
@@ -16,32 +16,13 @@
package org.jetbrains.kotlin.codegen.intrinsics package org.jetbrains.kotlin.codegen.intrinsics
import com.intellij.psi.PsiElement import org.jetbrains.kotlin.codegen.AsmUtil.correctElementType
import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.kotlin.codegen.ExpressionCodegen
import org.jetbrains.kotlin.codegen.Callable import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.StackValue import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.kotlin.psi.JetExpression
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
import org.jetbrains.kotlin.codegen.AsmUtil.correctElementType
public class ArraySet : IntrinsicMethod() { public class ArraySet : IntrinsicMethod() {
override fun generateImpl(codegen: ExpressionCodegen, v: InstructionAdapter, returnType: Type, element: PsiElement?, arguments: List<JetExpression>, receiver: StackValue): Type {
receiver.put(receiver.type, v)
val type = correctElementType(receiver.type)
codegen.gen(arguments.get(0), Type.INT_TYPE)
codegen.gen(arguments.get(1), type)
v.astore(type)
return Type.VOID_TYPE
}
override fun supportCallable(): Boolean {
return true
}
override fun toCallable(method: CallableMethod): Callable { override fun toCallable(method: CallableMethod): Callable {
val type = correctElementType(method.getThisType()) val type = correctElementType(method.getThisType())
@@ -16,27 +16,10 @@
package org.jetbrains.kotlin.codegen.intrinsics package org.jetbrains.kotlin.codegen.intrinsics
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.kotlin.codegen.ExpressionCodegen
import org.jetbrains.kotlin.codegen.Callable import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.StackValue import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.kotlin.psi.JetExpression
public class ArraySize : LazyIntrinsicMethod() { public class ArraySize : IntrinsicMethod() {
override fun generateImpl(
codegen: ExpressionCodegen,
returnType: Type,
element: PsiElement?,
arguments: List<JetExpression>,
receiver: StackValue
): StackValue {
return StackValue.operation(Type.INT_TYPE) {
receiver.put(receiver.type, it)
it.arraylength()
}
}
public override fun toCallable(method: CallableMethod): Callable { public override fun toCallable(method: CallableMethod): Callable {
return UnaryIntrinsic(method, null, false) { adapter -> return UnaryIntrinsic(method, null, false) { adapter ->
@@ -16,52 +16,20 @@
package org.jetbrains.kotlin.codegen.intrinsics package org.jetbrains.kotlin.codegen.intrinsics
import com.google.common.collect.Lists
import com.intellij.psi.PsiElement
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
import org.jetbrains.kotlin.codegen.ExpressionCodegen
import org.jetbrains.kotlin.codegen.StackValue
import org.jetbrains.kotlin.psi.JetExpression
import org.jetbrains.org.objectweb.asm.Opcodes.*
import org.jetbrains.kotlin.codegen.AsmUtil.isPrimitive
import org.jetbrains.kotlin.codegen.AsmUtil.numberFunctionOperandType import org.jetbrains.kotlin.codegen.AsmUtil.numberFunctionOperandType
import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.kotlin.codegen.Callable import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.context.CodegenContext import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.org.objectweb.asm.Opcodes.ISHL
import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.org.objectweb.asm.Opcodes.ISHR
import org.jetbrains.org.objectweb.asm.Opcodes.IUSHR
import org.jetbrains.org.objectweb.asm.Type
public class BinaryOp(private val opcode: Int) : IntrinsicMethod() { public class BinaryOp(private val opcode: Int) : IntrinsicMethod() {
override fun generateImpl(codegen: ExpressionCodegen, v: InstructionAdapter, returnType: Type, element: PsiElement?, arguments: List<JetExpression>, receiver: StackValue): Type {
assert(isPrimitive(returnType)) { "Return type of BinaryOp intrinsic should be of primitive type : " + returnType }
val operandType = numberFunctionOperandType(returnType)
if (arguments.size() == 1) {
// Intrinsic is called as an ordinary function
if (receiver != StackValue.none()) {
receiver.put(operandType, v)
}
codegen.gen(arguments.get(0), if (shift()) Type.INT_TYPE else operandType)
}
else {
codegen.gen(arguments.get(0), operandType)
codegen.gen(arguments.get(1), if (shift()) Type.INT_TYPE else operandType)
}
v.visitInsn(returnType.getOpcode(opcode))
return returnType
}
private fun shift(): Boolean { private fun shift(): Boolean {
return opcode == ISHL || opcode == ISHR || opcode == IUSHR return opcode == ISHL || opcode == ISHR || opcode == IUSHR
} }
public override fun supportCallable(): Boolean {
return true
}
override fun toCallable(method: CallableMethod): Callable { override fun toCallable(method: CallableMethod): Callable {
val returnType = method.getReturnType() val returnType = method.getReturnType()
assert(method.getValueParameters().size() == 1) assert(method.getValueParameters().size() == 1)
@@ -16,45 +16,12 @@
package org.jetbrains.kotlin.codegen.intrinsics package org.jetbrains.kotlin.codegen.intrinsics
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.kotlin.codegen.ExpressionCodegen
import org.jetbrains.kotlin.codegen.Callable import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.StackValue import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.kotlin.psi.JetElement
import org.jetbrains.kotlin.psi.JetExpression
import org.jetbrains.kotlin.psi.JetSuperExpression
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCallWithAssert
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
public class Clone : IntrinsicMethod() { public class Clone : IntrinsicMethod() {
override fun generateImpl(codegen: ExpressionCodegen, v: InstructionAdapter, returnType: Type, element: PsiElement?, arguments: List<JetExpression>, receiver: StackValue): Type {
val resolvedCall = (element as JetElement).getResolvedCallWithAssert(codegen.getBindingContext())
StackValue.receiver(resolvedCall, receiver, codegen, null).put(OBJECT_TYPE, v)
if (isSuperCall(resolvedCall)) {
v.invokespecial("java/lang/Object", "clone", "()Ljava/lang/Object;", false)
}
else {
v.invokevirtual("java/lang/Object", "clone", "()Ljava/lang/Object;", false)
}
return OBJECT_TYPE
}
private fun isSuperCall(resolvedCall: ResolvedCall<*>): Boolean {
val dispatchReceiver = resolvedCall.getDispatchReceiver()
return dispatchReceiver is ExpressionReceiver && (dispatchReceiver as ExpressionReceiver).getExpression() is JetSuperExpression
}
override fun supportCallable(): Boolean {
return true
}
override fun toCallable(method: CallableMethod, isSuperCall: Boolean): Callable { override fun toCallable(method: CallableMethod, isSuperCall: Boolean): Callable {
return UnaryIntrinsic(method, OBJECT_TYPE) { return UnaryIntrinsic(method, OBJECT_TYPE) {
@@ -16,40 +16,13 @@
package org.jetbrains.kotlin.codegen.intrinsics package org.jetbrains.kotlin.codegen.intrinsics
import com.intellij.psi.PsiElement import org.jetbrains.kotlin.codegen.AsmUtil.comparisonOperandType
import org.jetbrains.kotlin.codegen.ExpressionCodegen import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.StackValue import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.kotlin.psi.JetExpression
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
import org.jetbrains.kotlin.codegen.AsmUtil.comparisonOperandType
import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.kotlin.codegen.Callable
public class CompareTo : IntrinsicMethod() { public class CompareTo : IntrinsicMethod() {
override fun generateImpl(codegen: ExpressionCodegen, v: InstructionAdapter, returnType: Type, element: PsiElement?, arguments: List<JetExpression>, receiver: StackValue): Type {
var receiver = receiver
val argument: JetExpression
if (arguments.size() == 1) {
argument = arguments.get(0)
}
else if (arguments.size() == 2) {
receiver = codegen.gen(arguments.get(0))
argument = arguments.get(1)
}
else {
throw IllegalStateException("Invalid arguments to compareTo: " + arguments)
}
val type = comparisonOperandType(receiver.type, codegen.expressionType(argument))
receiver.put(type, v)
codegen.gen(argument, type)
genInvoke(type, v)
return Type.INT_TYPE
}
private fun genInvoke(type: Type?, v: InstructionAdapter) { private fun genInvoke(type: Type?, v: InstructionAdapter) {
if (type == Type.INT_TYPE) { if (type == Type.INT_TYPE) {
@@ -69,11 +42,6 @@ public class CompareTo : IntrinsicMethod() {
} }
} }
//TODO seems we need to different CompareTo
override fun supportCallable(): Boolean {
return true
}
override fun toCallable(method: CallableMethod): Callable { override fun toCallable(method: CallableMethod): Callable {
val argumentType = comparisonOperandType(method.getThisType() ?: method.getReceiverClass(), method.getArgumentTypes().first()) val argumentType = comparisonOperandType(method.getThisType() ?: method.getReceiverClass(), method.getArgumentTypes().first())
return IntrinsicCallable.binaryIntrinsic(method.getReturnType(), argumentType, argumentType, null) { return IntrinsicCallable.binaryIntrinsic(method.getReturnType(), argumentType, argumentType, null) {
@@ -16,29 +16,24 @@
package org.jetbrains.kotlin.codegen.intrinsics package org.jetbrains.kotlin.codegen.intrinsics
import com.intellij.openapi.util.Key
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.codegen.ExpressionCodegen
import org.jetbrains.kotlin.codegen.StackValue
import org.jetbrains.kotlin.psi.JetExpression
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
import org.jetbrains.kotlin.codegen.AsmUtil.genInvokeAppendMethod import org.jetbrains.kotlin.codegen.AsmUtil.genInvokeAppendMethod
import org.jetbrains.kotlin.codegen.AsmUtil.genStringBuilderConstructor import org.jetbrains.kotlin.codegen.AsmUtil.genStringBuilderConstructor
import org.jetbrains.kotlin.codegen.Callable import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.ExpressionCodegen
import org.jetbrains.kotlin.codegen.StackValue
import org.jetbrains.kotlin.descriptors.FunctionDescriptor 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.JetFile import org.jetbrains.kotlin.psi.JetExpression
import org.jetbrains.kotlin.psi.UserDataProperty
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.JAVA_STRING_TYPE import org.jetbrains.kotlin.resolve.jvm.AsmTypes.JAVA_STRING_TYPE
import kotlin.properties.Delegates import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
public class Concat : IntrinsicMethod() { public class Concat : IntrinsicMethod() {
override 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
@@ -59,10 +54,6 @@ public class Concat : IntrinsicMethod() {
return JAVA_STRING_TYPE return JAVA_STRING_TYPE
} }
override fun supportCallable(): Boolean {
return true
}
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 callable = codegen.getState().getTypeMapper().mapToCallableMethod(fd, false, codegen.getContext()) val callable = codegen.getState().getTypeMapper().mapToCallableMethod(fd, false, codegen.getContext())
return object : MappedCallable(callable, {}) { return object : MappedCallable(callable, {}) {
@@ -16,41 +16,15 @@
package org.jetbrains.kotlin.codegen.intrinsics package org.jetbrains.kotlin.codegen.intrinsics
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.kotlin.codegen.ExpressionCodegen
import org.jetbrains.kotlin.codegen.Callable import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.StackValue 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.psi.JetExpression
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.types.JetType 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
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.getType
public class CopyToArray : IntrinsicMethod() { public class CopyToArray : IntrinsicMethod() {
override fun generateImpl(codegen: ExpressionCodegen, v: InstructionAdapter, returnType: Type, element: PsiElement?, arguments: List<JetExpression>, receiver: StackValue): Type {
receiver.put(receiver.type, v)
v.dup()
v.invokeinterface("java/util/Collection", "size", "()I")
assert(element is JetExpression)
val arrayType = codegen.expressionJetType(element as JetExpression)
assert(arrayType != null)
codegen.newArrayInstruction(arrayType)
v.invokeinterface("java/util/Collection", "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;")
return getType(javaClass<Array<Any>>())
}
override fun supportCallable(): Boolean {
return true
}
override fun toCallable(fd: FunctionDescriptor, isSuper: Boolean, resolvedCall: ResolvedCall<*>, codegen: ExpressionCodegen): Callable { override fun toCallable(fd: FunctionDescriptor, isSuper: Boolean, resolvedCall: ResolvedCall<*>, codegen: ExpressionCodegen): Callable {
return object : IntrinsicCallable(getType(javaClass<Array<Any>>()), listOf(), null, Type.getType(javaClass<Collection<*>>())) { return object : IntrinsicCallable(getType(javaClass<Array<Any>>()), listOf(), null, Type.getType(javaClass<Collection<*>>())) {
@@ -16,37 +16,12 @@
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.* import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.kotlin.psi.JetCallExpression
import org.jetbrains.kotlin.psi.JetExpression
import org.jetbrains.kotlin.lexer.JetTokens
import org.jetbrains.kotlin.codegen.AsmUtil.genEqualsForExpressionsOnStack
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE
public class Equals : LazyIntrinsicMethod() { public class Equals : IntrinsicMethod() {
override fun generateImpl(
codegen: ExpressionCodegen,
returnType: Type,
element: PsiElement?,
arguments: List<JetExpression>,
receiver: StackValue
): StackValue {
val leftExpr: StackValue
val rightExpr: JetExpression
if (element is JetCallExpression) {
leftExpr = StackValue.coercion(receiver, OBJECT_TYPE)
rightExpr = arguments.get(0)
}
else {
leftExpr = codegen.genLazy(arguments.get(0), OBJECT_TYPE)
rightExpr = arguments.get(1)
}
return genEqualsForExpressionsOnStack(JetTokens.EQEQ, leftExpr, codegen.genLazy(rightExpr, OBJECT_TYPE))
}
override fun toCallable(method: CallableMethod): Callable { override fun toCallable(method: CallableMethod): Callable {
return IntrinsicCallable.binaryIntrinsic(method.getReturnType(), OBJECT_TYPE, nullOrObject(method.getThisType()), nullOrObject(method.getReceiverClass())) { return IntrinsicCallable.binaryIntrinsic(method.getReturnType(), OBJECT_TYPE, nullOrObject(method.getThisType()), nullOrObject(method.getReceiverClass())) {
@@ -16,30 +16,13 @@
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.CallableMethod import org.jetbrains.kotlin.codegen.CallableMethod
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.kotlin.codegen.ExpressionCodegen
import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.StackValue
import org.jetbrains.kotlin.psi.JetExpression
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
public class HashCode : LazyIntrinsicMethod() { public class HashCode : IntrinsicMethod() {
override fun generateImpl(
codegen: ExpressionCodegen,
returnType: Type,
element: PsiElement?,
arguments: List<JetExpression>,
receiver: StackValue
): StackValue {
return StackValue.operation(Type.INT_TYPE) {
receiver.put(AsmTypes.OBJECT_TYPE, it)
it.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "hashCode", "()I", false)
}
}
override fun toCallable(method: CallableMethod): Callable { override fun toCallable(method: CallableMethod): Callable {
return object: IntrinsicCallable(Type.INT_TYPE, emptyList(), nullOrObject(method.getThisType()), nullOrObject(method.getReceiverClass())) { return object: IntrinsicCallable(Type.INT_TYPE, emptyList(), nullOrObject(method.getThisType()), nullOrObject(method.getReceiverClass())) {
@@ -16,39 +16,18 @@
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.* import org.jetbrains.kotlin.codegen.ExpressionCodegen
import org.jetbrains.kotlin.codegen.StackValue
import org.jetbrains.kotlin.descriptors.FunctionDescriptor 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.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.OBJECT_TYPE
import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE public class IdentityEquals : IntrinsicMethod() {
public class IdentityEquals : LazyIntrinsicMethod() {
override fun generateImpl(codegen: ExpressionCodegen, returnType: Type, element: PsiElement?, arguments: List<JetExpression>, receiver: StackValue): StackValue {
val left: StackValue
val right: StackValue
if (element is JetCallExpression) {
left = receiver
right = codegen.gen(arguments.get(0))
}
else {
assert(element is JetBinaryExpression)
val e = element as JetBinaryExpression
left = codegen.gen(e.getLeft())
right = codegen.gen(e.getRight())
}
return StackValue.cmp(JetTokens.EQEQEQ, OBJECT_TYPE, left, right)
}
override fun supportCallable(): Boolean {
return true
}
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 callable = codegen.getState().getTypeMapper().mapToCallableMethod(fd, false, codegen.getContext()) val callable = codegen.getState().getTypeMapper().mapToCallableMethod(fd, false, codegen.getContext())
@@ -16,46 +16,14 @@
package org.jetbrains.kotlin.codegen.intrinsics package org.jetbrains.kotlin.codegen.intrinsics
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.codegen.ExpressionCodegen
import org.jetbrains.kotlin.codegen.StackValue
import org.jetbrains.kotlin.psi.JetExpression
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.kotlin.codegen.AsmUtil.genIncrement import org.jetbrains.kotlin.codegen.AsmUtil.genIncrement
import org.jetbrains.kotlin.codegen.AsmUtil.isPrimitive
import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.kotlin.codegen.Callable import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.ExpressionCodegen
import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.psi.JetPrefixExpression import org.jetbrains.kotlin.psi.JetPrefixExpression
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
public class Increment(private val myDelta: Int) : LazyIntrinsicMethod() { public class Increment(private val myDelta: Int) : IntrinsicMethod() {
override fun generateImpl(codegen: ExpressionCodegen, returnType: Type, element: PsiElement?, arguments: List<JetExpression>, receiver: StackValue): StackValue {
assert(isPrimitive(returnType)) { "Return type of Increment intrinsic should be of primitive type : " + returnType }
if (arguments.size() > 0) {
throw UnsupportedOperationException("fail");
// val operand = arguments.get(0)
// val stackValue = codegen.genQualified(receiver, operand)
// if (stackValue is StackValue.Local && Type.INT_TYPE == stackValue.type) {
// return StackValue.preIncrementForLocalVar(stackValue.index, myDelta)
// }
// else {
// return StackValue.preIncrement(returnType, stackValue, myDelta, this, null, codegen)
// }
}
else {
return StackValue.operation(returnType) {
receiver.put(returnType, it)
genIncrement(returnType, myDelta, it)
}
}
}
override fun supportCallable(): Boolean {
return true
}
override fun toCallable(fd: FunctionDescriptor, isSuper: Boolean, resolvedCall: ResolvedCall<*>, codegen: ExpressionCodegen): Callable { override fun toCallable(fd: FunctionDescriptor, isSuper: Boolean, resolvedCall: ResolvedCall<*>, codegen: ExpressionCodegen): Callable {
val method = codegen.getState().getTypeMapper().mapToCallableMethod(fd, false, codegen.getContext()) val method = codegen.getState().getTypeMapper().mapToCallableMethod(fd, false, codegen.getContext())
@@ -18,56 +18,22 @@ package org.jetbrains.kotlin.codegen.intrinsics;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.intellij.psi.PsiElement;
import kotlin.Function1;
import kotlin.Unit;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.codegen.Callable;
import org.jetbrains.kotlin.codegen.*; import org.jetbrains.kotlin.codegen.CallableMethod;
import org.jetbrains.kotlin.codegen.ExpressionCodegen;
import org.jetbrains.kotlin.codegen.context.CodegenContext; import org.jetbrains.kotlin.codegen.context.CodegenContext;
import org.jetbrains.kotlin.codegen.state.GenerationState; import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.descriptors.FunctionDescriptor; import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
import org.jetbrains.kotlin.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; 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 java.util.List; import java.util.List;
import static org.jetbrains.kotlin.codegen.AsmUtil.numberFunctionOperandType; import static org.jetbrains.kotlin.codegen.AsmUtil.numberFunctionOperandType;
public abstract class IntrinsicMethod { public abstract class IntrinsicMethod {
public StackValue generate(
@NotNull final ExpressionCodegen codegen,
@NotNull final Type returnType,
@Nullable final PsiElement element,
@NotNull final List<JetExpression> arguments,
@NotNull final StackValue receiver
) {
return StackValue.operation(returnType, new Function1<InstructionAdapter, Unit>() {
@Override
public Unit invoke(InstructionAdapter v) {
Type actualType = generateImpl(codegen, v, returnType, element, arguments, receiver);
StackValue.coerce(actualType, returnType, v);
return Unit.INSTANCE$;
}
});
}
@NotNull
protected abstract Type generateImpl(
@NotNull ExpressionCodegen codegen,
@NotNull InstructionAdapter v,
@NotNull Type returnType,
@Nullable PsiElement element,
@NotNull List<JetExpression> arguments,
@NotNull StackValue receiver
);
public boolean supportCallable() {
return false;
}
@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) {
@@ -16,36 +16,12 @@
package org.jetbrains.kotlin.codegen.intrinsics package org.jetbrains.kotlin.codegen.intrinsics
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.kotlin.codegen.ExpressionCodegen
import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.StackValue
import org.jetbrains.kotlin.psi.JetExpression
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
import org.jetbrains.kotlin.codegen.AsmUtil.isPrimitive
import org.jetbrains.kotlin.codegen.AsmUtil.numberFunctionOperandType import org.jetbrains.kotlin.codegen.AsmUtil.numberFunctionOperandType
import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.org.objectweb.asm.Type
public class Inv : IntrinsicMethod() { public class Inv : IntrinsicMethod() {
override fun generateImpl(codegen: ExpressionCodegen, v: InstructionAdapter, returnType: Type, element: PsiElement?, arguments: List<JetExpression>, receiver: StackValue): Type {
assert(isPrimitive(returnType)) { "Return type of Inv intrinsic should be of primitive type : " + returnType }
receiver.put(numberFunctionOperandType(returnType), v)
if (returnType == Type.LONG_TYPE) {
v.lconst(-1)
}
else {
v.iconst(-1)
}
v.xor(returnType)
return returnType
}
override fun supportCallable(): Boolean {
return true
}
override fun toCallable(method: CallableMethod): Callable { override fun toCallable(method: CallableMethod): Callable {
val type = numberFunctionOperandType(method.getReturnType()) val type = numberFunctionOperandType(method.getReturnType())
@@ -16,28 +16,16 @@
package org.jetbrains.kotlin.codegen.intrinsics package org.jetbrains.kotlin.codegen.intrinsics
import com.intellij.psi.PsiElement import org.jetbrains.kotlin.builtins.KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME
import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.kotlin.codegen.ExpressionCodegen
import org.jetbrains.kotlin.codegen.Callable import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.StackValue import org.jetbrains.kotlin.codegen.context.CodegenContext
import org.jetbrains.kotlin.psi.JetExpression import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
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
import org.jetbrains.kotlin.builtins.KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME
import org.jetbrains.kotlin.codegen.context.CodegenContext
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
public class IteratorNext : IntrinsicMethod() { public class IteratorNext : IntrinsicMethod() {
override fun generateImpl(codegen: ExpressionCodegen, v: InstructionAdapter, returnType: Type, element: PsiElement?, arguments: List<JetExpression>, receiver: StackValue): Type {
val name = getIteratorName(returnType)
receiver.put(AsmTypes.OBJECT_TYPE, v)
v.invokevirtual(BUILT_INS_PACKAGE_FQ_NAME.toString() + "/" + name + "Iterator", "next" + name, "()" + returnType.getDescriptor(), false)
return returnType
}
protected fun getIteratorName(returnType: Type): String { protected fun getIteratorName(returnType: Type): String {
val name: String val name: String
@@ -71,11 +59,6 @@ public class IteratorNext : IntrinsicMethod() {
return name return name
} }
override fun supportCallable(): Boolean {
return true
}
override fun toCallable(state: GenerationState, fd: FunctionDescriptor, context: CodegenContext<*>, isSuper: Boolean): Callable { override fun toCallable(state: GenerationState, fd: FunctionDescriptor, context: CodegenContext<*>, isSuper: Boolean): Callable {
val type = state.getTypeMapper().mapReturnType(fd) val type = state.getTypeMapper().mapReturnType(fd)
return object: IntrinsicCallable(type, listOf(), AsmTypes.OBJECT_TYPE, null) { return object: IntrinsicCallable(type, listOf(), AsmTypes.OBJECT_TYPE, null) {
@@ -16,36 +16,10 @@
package org.jetbrains.kotlin.codegen.intrinsics package org.jetbrains.kotlin.codegen.intrinsics
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.kotlin.codegen.ExpressionCodegen
import org.jetbrains.kotlin.codegen.Callable import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.StackValue import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.psi.JetElement
import org.jetbrains.kotlin.psi.JetExpression
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument
import org.jetbrains.kotlin.resolve.calls.model.VarargValueArgument
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCallWithAssert
public class JavaClassArray : IntrinsicMethod() { public class JavaClassArray : IntrinsicMethod() {
override fun generateImpl(codegen: ExpressionCodegen, v: InstructionAdapter, returnType: Type, element: PsiElement?, arguments: List<JetExpression>, receiver: StackValue): Type {
assert(element != null, "Element should not be null")
val resolvedCall = (element as JetElement).getResolvedCallWithAssert(codegen.getBindingContext())
val argument = resolvedCall.getValueArguments().entrySet().iterator().next()
codegen.genVarargs(argument.getValue() as VarargValueArgument, argument.getKey().getType())
return returnType
}
override fun supportCallable(): Boolean {
return true
}
override fun toCallable(method: CallableMethod): Callable { override fun toCallable(method: CallableMethod): Callable {
return MappedCallable(method) { return MappedCallable(method) {
//do nothing all generated as vararg //do nothing all generated as vararg
@@ -16,41 +16,16 @@
package org.jetbrains.kotlin.codegen.intrinsics package org.jetbrains.kotlin.codegen.intrinsics
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.codegen.ExpressionCodegen
import org.jetbrains.kotlin.codegen.StackValue
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner
import org.jetbrains.kotlin.psi.JetElement
import org.jetbrains.kotlin.psi.JetExpression
import org.jetbrains.kotlin.resolve.calls.callUtil.*
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.types.JetType
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
import org.jetbrains.kotlin.codegen.AsmUtil.putJavaLangClassInstance import org.jetbrains.kotlin.codegen.AsmUtil.putJavaLangClassInstance
import org.jetbrains.kotlin.codegen.Callable import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.ExpressionCodegen
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner
import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.getType import org.jetbrains.kotlin.resolve.jvm.AsmTypes.getType
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
public class JavaClassFunction : IntrinsicMethod() { public class JavaClassFunction : IntrinsicMethod() {
override fun generateImpl(codegen: ExpressionCodegen, v: InstructionAdapter, expectedType: Type, element: PsiElement?, arguments: List<JetExpression>, receiver: StackValue): Type {
val resolvedCall = (element as JetElement).getResolvedCallWithAssert(codegen.getBindingContext())
val returnType = resolvedCall.getResultingDescriptor().getReturnType()
assert(returnType != null)
val type = returnType!!.getArguments().get(0).getType()
codegen.putReifierMarkerIfTypeIsReifiedParameter(type, ReifiedTypeInliner.JAVA_CLASS_MARKER_METHOD_NAME)
putJavaLangClassInstance(v, codegen.getState().getTypeMapper().mapType(type))
return getType(javaClass<Class<Any>>())
}
override fun supportCallable(): Boolean {
return true
}
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().get(0).getType()
@@ -18,21 +18,27 @@ package org.jetbrains.kotlin.codegen.intrinsics
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.codegen.AsmUtil import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.codegen.ExpressionCodegen
import org.jetbrains.kotlin.codegen.StackValue
import org.jetbrains.kotlin.psi.JetExpression
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
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
import org.jetbrains.kotlin.codegen.Callable 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.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.commons.InstructionAdapter
public class JavaClassProperty : IntrinsicMethod() { public class JavaClassProperty : IntrinsicMethod() {
override fun generateImpl(codegen: ExpressionCodegen, v: InstructionAdapter, returnType: Type, element: PsiElement?, arguments: List<JetExpression>, receiver: StackValue): Type { 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)
}
}
fun generateImpl(v: InstructionAdapter, receiver: StackValue): Type {
val type = receiver.type val type = receiver.type
if (isPrimitive(type)) { if (isPrimitive(type)) {
if (!StackValue.couldSkipReceiverOnStaticCall(receiver)) { if (!StackValue.couldSkipReceiverOnStaticCall(receiver)) {
@@ -49,10 +55,6 @@ public class JavaClassProperty : IntrinsicMethod() {
return getType(javaClass<Class<Any>>()) return getType(javaClass<Class<Any>>())
} }
override fun supportCallable(): Boolean {
return true
}
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 classType = codegen.getState().getTypeMapper().mapType(resolvedCall.getCall().getDispatchReceiver().getType()) val classType = codegen.getState().getTypeMapper().mapType(resolvedCall.getCall().getDispatchReceiver().getType())
return object : IntrinsicCallable(getType(javaClass<Class<Any>>()), listOf(), classType, null) { return object : IntrinsicCallable(getType(javaClass<Class<Any>>()), listOf(), classType, null) {
@@ -1,68 +0,0 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.codegen.intrinsics;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.codegen.ExpressionCodegen;
import org.jetbrains.kotlin.codegen.StackValue;
import org.jetbrains.kotlin.psi.JetExpression;
import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
import java.util.List;
public abstract class LazyIntrinsicMethod extends IntrinsicMethod {
@Override
public final StackValue generate(
@NotNull ExpressionCodegen codegen,
@NotNull Type returnType,
@Nullable PsiElement element,
@NotNull List<JetExpression> arguments,
@NotNull StackValue receiver
) {
return StackValue.coercion(generateImpl(codegen, returnType, element, arguments, receiver), returnType);
}
@NotNull
@Override
protected Type generateImpl(
@NotNull ExpressionCodegen codegen,
@NotNull InstructionAdapter v,
@NotNull Type returnType,
@Nullable PsiElement element,
@NotNull List<JetExpression> arguments,
@NotNull StackValue receiver
) {
throw new UnsupportedOperationException();
}
public abstract StackValue generateImpl(
@NotNull ExpressionCodegen codegen,
@NotNull Type returnType,
@Nullable PsiElement element,
@NotNull List<JetExpression> arguments,
@NotNull StackValue receiver
);
@Override
public boolean supportCallable() {
return true;
}
}
@@ -16,55 +16,22 @@
package org.jetbrains.kotlin.codegen.intrinsics package org.jetbrains.kotlin.codegen.intrinsics
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.codegen.ExpressionCodegen
import org.jetbrains.kotlin.codegen.Callable import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.StackValue
import org.jetbrains.kotlin.codegen.context.CodegenContext import org.jetbrains.kotlin.codegen.context.CodegenContext
import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.psi.JetElement
import org.jetbrains.kotlin.psi.JetExpression
import org.jetbrains.kotlin.psi.ValueArgument
import org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument 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
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCallWithAssert
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE
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)
} }
override fun generateImpl(codegen: ExpressionCodegen, v: InstructionAdapter, returnType: Type, element: PsiElement?, arguments: List<JetExpression>, receiver: StackValue): Type {
assert(element != null, "Element should not be null")
val resolvedCall = (element as JetElement).getResolvedCallWithAssert(codegen.getBindingContext())
val resolvedArguments = resolvedCall.getValueArgumentsByIndex()
assert(resolvedArguments != null && resolvedArguments.size() == 1) { "Monitor instruction (" + opcode + ") should have exactly 1 argument: " + resolvedArguments }
val argument = resolvedArguments!!.get(0)
assert(argument is ExpressionValueArgument) { "Monitor instruction (" + opcode + ") should have expression value argument: " + argument }
val valueArgument = (argument as ExpressionValueArgument).getValueArgument()
assert(valueArgument != null) { "Unresolved value argument: " + argument }
codegen.gen(valueArgument!!.getArgumentExpression(), OBJECT_TYPE)
v.visitInsn(opcode)
return Type.VOID_TYPE
}
override fun supportCallable(): Boolean {
return true
}
override fun toCallable(state: GenerationState, fd: FunctionDescriptor, context: CodegenContext<*>, isSuper: Boolean, resolvedCall: ResolvedCall<*>): Callable { override fun toCallable(state: GenerationState, fd: FunctionDescriptor, context: CodegenContext<*>, isSuper: Boolean, resolvedCall: ResolvedCall<*>): Callable {
return object : IntrinsicCallable(Type.VOID_TYPE, listOf(OBJECT_TYPE), null, null) { return object : IntrinsicCallable(Type.VOID_TYPE, listOf(OBJECT_TYPE), null, null) {
override fun invokeIntrinsic(v: InstructionAdapter) { override fun invokeIntrinsic(v: InstructionAdapter) {
@@ -16,22 +16,14 @@
package org.jetbrains.kotlin.codegen.intrinsics package org.jetbrains.kotlin.codegen.intrinsics
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.codegen.ExpressionCodegen
import org.jetbrains.kotlin.codegen.Callable import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.StackValue import org.jetbrains.kotlin.codegen.ExpressionCodegen
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.psi.JetCallExpression
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.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 NewArray : LazyIntrinsicMethod() { public class NewArray : IntrinsicMethod() {
override fun generateImpl(codegen: ExpressionCodegen, returnType: Type, element: PsiElement?, arguments: List<JetExpression>, receiver: StackValue): StackValue {
return codegen.generateNewArray(element as JetCallExpression)
}
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()!!
@@ -17,19 +17,17 @@
package org.jetbrains.kotlin.codegen.intrinsics package org.jetbrains.kotlin.codegen.intrinsics
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.kotlin.codegen.ExpressionCodegen
import org.jetbrains.kotlin.codegen.Callable import org.jetbrains.kotlin.codegen.Callable
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.JetCallExpression
import org.jetbrains.kotlin.psi.JetExpression 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 import org.jetbrains.org.objectweb.asm.Type
public class Not : LazyIntrinsicMethod() { public class Not : IntrinsicMethod() {
override fun generateImpl(codegen: ExpressionCodegen, returnType: Type, element: PsiElement?, arguments: List<JetExpression>, receiver: StackValue): StackValue { fun generateImpl(codegen: ExpressionCodegen, returnType: Type, element: PsiElement?, arguments: List<JetExpression>, receiver: StackValue): StackValue {
val stackValue: StackValue val stackValue: StackValue
if (arguments.size() == 1) { if (arguments.size() == 1) {
stackValue = codegen.gen(arguments.get(0)) stackValue = codegen.gen(arguments.get(0))
@@ -40,9 +38,6 @@ public class Not : LazyIntrinsicMethod() {
return StackValue.not(StackValue.coercion(stackValue, Type.BOOLEAN_TYPE)) return StackValue.not(StackValue.coercion(stackValue, Type.BOOLEAN_TYPE))
} }
override fun supportCallable(): Boolean {
return true
}
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 callable = codegen.getState().getTypeMapper().mapToCallableMethod(fd, false, codegen.getContext()) val callable = codegen.getState().getTypeMapper().mapToCallableMethod(fd, false, codegen.getContext())
@@ -16,19 +16,11 @@
package org.jetbrains.kotlin.codegen.intrinsics package org.jetbrains.kotlin.codegen.intrinsics
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.kotlin.codegen.ExpressionCodegen
import org.jetbrains.kotlin.codegen.Callable import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.kotlin.codegen.StackValue import org.jetbrains.kotlin.codegen.StackValue
import org.jetbrains.kotlin.psi.JetExpression
import org.jetbrains.org.objectweb.asm.Type
public class NumberCast : LazyIntrinsicMethod() { public class NumberCast : IntrinsicMethod() {
override fun generateImpl(codegen: ExpressionCodegen, returnType: Type, element: PsiElement?, arguments: List<JetExpression>, receiver: StackValue): StackValue {
return StackValue.coercion(receiver, returnType)
}
override fun toCallable(method: CallableMethod): Callable { override fun toCallable(method: CallableMethod): Callable {
return UnaryIntrinsic(method) { return UnaryIntrinsic(method) {
@@ -16,42 +16,16 @@
package org.jetbrains.kotlin.codegen.intrinsics package org.jetbrains.kotlin.codegen.intrinsics
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.codegen.ExpressionCodegen
import org.jetbrains.kotlin.codegen.Callable import org.jetbrains.kotlin.codegen.Callable
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.JetBinaryExpression
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.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
import org.jetbrains.org.objectweb.asm.Type.*
public class RangeTo : IntrinsicMethod() { public class RangeTo : IntrinsicMethod() {
override fun generateImpl(codegen: ExpressionCodegen, v: InstructionAdapter, returnType: Type, element: PsiElement?, arguments: List<JetExpression>, receiver: StackValue): Type {
v.anew(returnType)
v.dup()
val type: Type
if (arguments.size() == 1) {
assert(receiver is StackValue.CallReceiver) { "Receiver in an intrinsic qualified expression should be CallReceiver: " + receiver + " on " + element!!.getText() }
type = parameterType(receiver.type, codegen.expressionType(arguments.get(0)))
receiver.put(type, v)
codegen.gen(arguments.get(0), type)
}
else {
val expression = element as JetBinaryExpression
type = parameterType(codegen.expressionType(expression.getLeft()), codegen.expressionType(expression.getRight()))
codegen.gen(expression.getLeft(), type)
codegen.gen(expression.getRight(), type)
}
v.invokespecial(returnType.getInternalName(), "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, type, type), false)
return returnType
}
private fun nameToPrimitive(name: String) : Type { private fun nameToPrimitive(name: String) : Type {
return when (name) { return when (name) {
@@ -66,39 +40,6 @@ public class RangeTo : IntrinsicMethod() {
} }
} }
private fun parameterType(leftType: Type, rightType: Type): Type {
val left = leftType.getSort()
val right = rightType.getSort()
if (left == DOUBLE || right == DOUBLE) {
return DOUBLE_TYPE
}
else if (left == FLOAT || right == FLOAT) {
return FLOAT_TYPE
}
else if (left == LONG || right == LONG) {
return LONG_TYPE
}
else if (left == INT || right == INT) {
return INT_TYPE
}
else if (left == SHORT || right == SHORT) {
return SHORT_TYPE
}
else if (left == CHAR || right == CHAR) {
return CHAR_TYPE
}
else if (left == BYTE || right == BYTE) {
return BYTE_TYPE
}
else {
throw IllegalStateException("RangeTo intrinsic can only work for primitive types: " + leftType + ", " + rightType)
}
}
override fun supportCallable(): Boolean {
return true
}
override fun toCallable(fd: FunctionDescriptor, isSuper: Boolean, resolvedCall: ResolvedCall<*>, codegen: ExpressionCodegen): Callable { override fun toCallable(fd: FunctionDescriptor, isSuper: Boolean, resolvedCall: ResolvedCall<*>, codegen: ExpressionCodegen): Callable {
val method = codegen.getState().getTypeMapper().mapToCallableMethod(fd, false, codegen.getContext()) val method = codegen.getState().getTypeMapper().mapToCallableMethod(fd, false, codegen.getContext())
val argType = nameToPrimitive(method.getReturnType().getInternalName().substringAfter("kotlin/").substringBefore("Range")) val argType = nameToPrimitive(method.getReturnType().getInternalName().substringAfter("kotlin/").substringBefore("Range"))
@@ -16,35 +16,10 @@
package org.jetbrains.kotlin.codegen.intrinsics package org.jetbrains.kotlin.codegen.intrinsics
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.kotlin.codegen.ExpressionCodegen
import org.jetbrains.kotlin.codegen.Callable import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.StackValue 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.psi.JetExpression
public class StringGetChar : LazyIntrinsicMethod() { public class StringGetChar : IntrinsicMethod() {
override fun generateImpl(
codegen: ExpressionCodegen,
returnType: Type,
element: PsiElement?,
arguments: List<JetExpression>,
receiver: StackValue
): StackValue {
return StackValue.operation(Type.CHAR_TYPE) {
if (receiver != StackValue.none()) {
receiver.put(receiver.type, it)
}
if (!arguments.isEmpty()) {
codegen.gen(arguments.first()).put(Type.INT_TYPE, it)
}
it.invokevirtual("java/lang/String", "charAt", "(I)C", false)
}
}
override fun toCallable(method: CallableMethod): Callable { override fun toCallable(method: CallableMethod): Callable {
return IntrinsicCallable.create(method) { return IntrinsicCallable.create(method) {
@@ -16,36 +16,10 @@
package org.jetbrains.kotlin.codegen.intrinsics package org.jetbrains.kotlin.codegen.intrinsics
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.kotlin.codegen.ExpressionCodegen
import org.jetbrains.kotlin.codegen.Callable import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.StackValue import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.kotlin.psi.JetExpression
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.JAVA_STRING_TYPE
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE
public class StringPlus : LazyIntrinsicMethod() { public class StringPlus : IntrinsicMethod() {
override fun generateImpl(
codegen: ExpressionCodegen,
returnType: Type,
element: PsiElement?,
arguments: List<JetExpression>,
receiver: StackValue
): StackValue {
return StackValue.operation(JAVA_STRING_TYPE) {
if (receiver == StackValue.none()) {
codegen.gen(arguments.get(0)).put(JAVA_STRING_TYPE, it)
codegen.gen(arguments.get(1)).put(OBJECT_TYPE, it)
}
else {
receiver.put(JAVA_STRING_TYPE, it)
codegen.gen(arguments.get(0)).put(OBJECT_TYPE, it)
}
it.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, "stringPlus", "(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/String;", false)
}
}
override fun toCallable(method: CallableMethod): Callable { override fun toCallable(method: CallableMethod): Callable {
return IntrinsicCallable.create(method) { return IntrinsicCallable.create(method) {
@@ -16,25 +16,11 @@
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.* import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.kotlin.codegen.AsmUtil.genToString
import org.jetbrains.kotlin.codegen.context.CodegenContext
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.psi.JetExpression
public class ToString : LazyIntrinsicMethod() { public class ToString : IntrinsicMethod() {
override fun generateImpl(
codegen: ExpressionCodegen,
returnType: Type,
element: PsiElement?,
arguments: List<JetExpression>,
receiver: StackValue
): StackValue {
return genToString(receiver, receiver.type)
}
override fun toCallable(method: CallableMethod): Callable { override fun toCallable(method: CallableMethod): Callable {
val type = AsmUtil.stringValueOfType(method.getThisType() ?: method.getReceiverClass()) val type = AsmUtil.stringValueOfType(method.getThisType() ?: method.getReceiverClass())
@@ -16,35 +16,11 @@
package org.jetbrains.kotlin.codegen.intrinsics package org.jetbrains.kotlin.codegen.intrinsics
import com.intellij.psi.PsiElement import org.jetbrains.kotlin.codegen.AsmUtil.numberFunctionOperandType
import org.jetbrains.kotlin.codegen
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.kotlin.codegen.ExpressionCodegen
import org.jetbrains.kotlin.codegen.StackValue
import org.jetbrains.kotlin.codegen.AsmUtil.*
import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.kotlin.codegen.Callable import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.psi.JetExpression import org.jetbrains.kotlin.codegen.CallableMethod
public class UnaryMinus : LazyIntrinsicMethod() { public class UnaryMinus : IntrinsicMethod() {
override fun generateImpl(
codegen: ExpressionCodegen,
returnType: Type,
element: PsiElement?,
arguments: List<JetExpression>,
receiver: StackValue
): StackValue {
assert(isPrimitive(returnType)) { "Return type of UnaryMinus intrinsic should be of primitive type: " + returnType }
val operandType = numberFunctionOperandType(returnType)
val newReceiver = if (arguments.size() == 1) codegen.gen(arguments.get(0)) else receiver
return StackValue.operation(operandType) {
newReceiver.put(operandType, it)
it.neg(operandType)
}
}
override fun toCallable(method: CallableMethod): Callable { override fun toCallable(method: CallableMethod): Callable {
return UnaryIntrinsic(method, numberFunctionOperandType(method.getReturnType()), needPrimitiveCheck = true) { return UnaryIntrinsic(method, numberFunctionOperandType(method.getReturnType()), needPrimitiveCheck = true) {
@@ -16,28 +16,10 @@
package org.jetbrains.kotlin.codegen.intrinsics package org.jetbrains.kotlin.codegen.intrinsics
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.codegen.ExpressionCodegen
import org.jetbrains.kotlin.codegen.StackValue
import org.jetbrains.kotlin.psi.JetExpression
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.kotlin.codegen.AsmUtil.isPrimitive
import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.kotlin.codegen.Callable import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.CallableMethod
public class UnaryPlus : LazyIntrinsicMethod() { public class UnaryPlus : IntrinsicMethod() {
override fun generateImpl(codegen: ExpressionCodegen, returnType: Type, element: PsiElement?, arguments: List<JetExpression>, receiver: StackValue): StackValue {
assert(isPrimitive(returnType)) { "Return type of UnaryPlus intrinsic should be of primitive type : " + returnType }
if (receiver != StackValue.none()) {
return receiver
}
else {
assert(!arguments.isEmpty())
return codegen.gen(arguments.get(0))
}
}
override fun toCallable(method: CallableMethod): Callable { override fun toCallable(method: CallableMethod): Callable {
return UnaryIntrinsic(method, needPrimitiveCheck = true) { return UnaryIntrinsic(method, needPrimitiveCheck = true) {