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) {
//TODO: intrinsic properties (see intermediateValueForProperty)
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;
import com.intellij.psi.PsiElement;
import kotlin.ExtensionFunction1;
import kotlin.Unit;
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.StackValue;
import org.jetbrains.kotlin.psi.JetExpression;
import org.jetbrains.kotlin.codegen.CallableMethod;
import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
import java.util.List;
import static org.jetbrains.kotlin.codegen.AsmUtil.correctElementType;
public class ArrayGet extends LazyIntrinsicMethod {
@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));
}
public class ArrayGet extends IntrinsicMethod {
@NotNull
@Override
@@ -18,9 +18,13 @@ package org.jetbrains.kotlin.codegen.intrinsics
import com.intellij.psi.PsiElement
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.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
@@ -28,20 +32,13 @@ 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.jvm.AsmTypes.getType
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
import org.jetbrains.org.objectweb.asm.Type
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() {
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)
val call = element as JetCallExpression
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())
}
override fun supportCallable(): Boolean {
return true
}
//TODO refactor
override fun toCallable(state: GenerationState, fd: FunctionDescriptor, context: CodegenContext<*>, isSuper: Boolean): Callable {
val callableMethod = state.getTypeMapper().mapToCallableMethod(fd, false, context)
@@ -16,32 +16,13 @@
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.AsmUtil.correctElementType
import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.StackValue
import org.jetbrains.kotlin.psi.JetExpression
import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
import org.jetbrains.kotlin.codegen.AsmUtil.correctElementType
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 {
val type = correctElementType(method.getThisType())
@@ -16,27 +16,10 @@
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.StackValue
import org.jetbrains.kotlin.psi.JetExpression
import org.jetbrains.kotlin.codegen.CallableMethod
public class ArraySize : LazyIntrinsicMethod() {
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 class ArraySize : IntrinsicMethod() {
public override fun toCallable(method: CallableMethod): Callable {
return UnaryIntrinsic(method, null, false) { adapter ->
@@ -16,52 +16,20 @@
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.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.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.org.objectweb.asm.Opcodes.ISHL
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() {
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 {
return opcode == ISHL || opcode == ISHR || opcode == IUSHR
}
public override fun supportCallable(): Boolean {
return true
}
override fun toCallable(method: CallableMethod): Callable {
val returnType = method.getReturnType()
assert(method.getValueParameters().size() == 1)
@@ -16,45 +16,12 @@
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.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.codegen.CallableMethod
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE
import org.jetbrains.org.objectweb.asm.Opcodes
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 {
return UnaryIntrinsic(method, OBJECT_TYPE) {
@@ -16,40 +16,13 @@
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.kotlin.codegen.AsmUtil.comparisonOperandType
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
import org.jetbrains.kotlin.codegen.AsmUtil.comparisonOperandType
import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.kotlin.codegen.Callable
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) {
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 {
val argumentType = comparisonOperandType(method.getThisType() ?: method.getReceiverClass(), method.getArgumentTypes().first())
return IntrinsicCallable.binaryIntrinsic(method.getReturnType(), argumentType, argumentType, null) {
@@ -16,29 +16,24 @@
package org.jetbrains.kotlin.codegen.intrinsics
import com.intellij.openapi.util.Key
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.genStringBuilderConstructor
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.lexer.JetTokens
import org.jetbrains.kotlin.psi.JetBinaryExpression
import org.jetbrains.kotlin.psi.JetFile
import org.jetbrains.kotlin.psi.UserDataProperty
import org.jetbrains.kotlin.psi.JetExpression
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 kotlin.properties.Delegates
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
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) {
// LHS + RHS
@@ -59,10 +54,6 @@ public class Concat : IntrinsicMethod() {
return JAVA_STRING_TYPE
}
override fun supportCallable(): Boolean {
return true
}
override fun toCallable(fd: FunctionDescriptor, isSuper: Boolean, resolvedCall: ResolvedCall<*>, codegen: ExpressionCodegen): Callable {
val callable = codegen.getState().getTypeMapper().mapToCallableMethod(fd, false, codegen.getContext())
return object : MappedCallable(callable, {}) {
@@ -16,41 +16,15 @@
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.codegen.context.CodegenContext
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.codegen.ExpressionCodegen
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.psi.JetExpression
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.commons.InstructionAdapter
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.getType
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 {
return object : IntrinsicCallable(getType(javaClass<Array<Any>>()), listOf(), null, Type.getType(javaClass<Collection<*>>())) {
@@ -16,37 +16,12 @@
package org.jetbrains.kotlin.codegen.intrinsics
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.codegen.*
import org.jetbrains.org.objectweb.asm.Type
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.codegen.AsmUtil
import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE
public class Equals : LazyIntrinsicMethod() {
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))
}
public class Equals : IntrinsicMethod() {
override fun toCallable(method: CallableMethod): Callable {
return IntrinsicCallable.binaryIntrinsic(method.getReturnType(), OBJECT_TYPE, nullOrObject(method.getThisType()), nullOrObject(method.getReceiverClass())) {
@@ -16,30 +16,13 @@
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.org.objectweb.asm.Opcodes
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
public class HashCode : LazyIntrinsicMethod() {
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)
}
}
public class HashCode : IntrinsicMethod() {
override fun toCallable(method: CallableMethod): Callable {
return object: IntrinsicCallable(Type.INT_TYPE, emptyList(), nullOrObject(method.getThisType()), nullOrObject(method.getReceiverClass())) {
@@ -16,39 +16,18 @@
package org.jetbrains.kotlin.codegen.intrinsics
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.codegen.*
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.lexer.JetTokens
import org.jetbrains.kotlin.psi.JetBinaryExpression
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.jvm.AsmTypes.OBJECT_TYPE
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE
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
}
public class IdentityEquals : IntrinsicMethod() {
override fun toCallable(fd: FunctionDescriptor, isSuper: Boolean, resolvedCall: ResolvedCall<*>, codegen: ExpressionCodegen): Callable {
val callable = codegen.getState().getTypeMapper().mapToCallableMethod(fd, false, codegen.getContext())
@@ -16,46 +16,14 @@
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.isPrimitive
import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.kotlin.codegen.Callable
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) : LazyIntrinsicMethod() {
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
}
public class Increment(private val myDelta: Int) : IntrinsicMethod() {
override fun toCallable(fd: FunctionDescriptor, isSuper: Boolean, resolvedCall: ResolvedCall<*>, codegen: ExpressionCodegen): Callable {
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.collect.Lists;
import com.intellij.psi.PsiElement;
import kotlin.Function1;
import kotlin.Unit;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.codegen.*;
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.psi.JetExpression;
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;
import java.util.List;
import static org.jetbrains.kotlin.codegen.AsmUtil.numberFunctionOperandType;
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
public Callable toCallable(@NotNull FunctionDescriptor fd, boolean isSuper, @NotNull ResolvedCall resolvedCall, @NotNull ExpressionCodegen codegen) {
@@ -16,36 +16,12 @@
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.Callable
import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.org.objectweb.asm.Type
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 {
val type = numberFunctionOperandType(method.getReturnType())
@@ -16,28 +16,16 @@
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.builtins.KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME
import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.StackValue
import org.jetbrains.kotlin.psi.JetExpression
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.jvm.AsmTypes
import org.jetbrains.org.objectweb.asm.Type
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() {
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 {
val name: String
@@ -71,11 +59,6 @@ public class IteratorNext : IntrinsicMethod() {
return name
}
override fun supportCallable(): Boolean {
return true
}
override fun toCallable(state: GenerationState, fd: FunctionDescriptor, context: CodegenContext<*>, isSuper: Boolean): Callable {
val type = state.getTypeMapper().mapReturnType(fd)
return object: IntrinsicCallable(type, listOf(), AsmTypes.OBJECT_TYPE, null) {
@@ -16,36 +16,10 @@
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.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
import org.jetbrains.kotlin.codegen.CallableMethod
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 {
return MappedCallable(method) {
//do nothing all generated as vararg
@@ -16,41 +16,16 @@
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.Callable
import org.jetbrains.kotlin.codegen.ExpressionCodegen
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner
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.org.objectweb.asm.commons.InstructionAdapter
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 {
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 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.isPrimitive
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() {
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
if (isPrimitive(type)) {
if (!StackValue.couldSkipReceiverOnStaticCall(receiver)) {
@@ -49,10 +55,6 @@ public class JavaClassProperty : IntrinsicMethod() {
return getType(javaClass<Class<Any>>())
}
override fun supportCallable(): Boolean {
return true
}
override fun toCallable(fd: FunctionDescriptor, isSuper: Boolean, resolvedCall: ResolvedCall<*>, codegen: ExpressionCodegen): Callable {
val classType = codegen.getState().getTypeMapper().mapType(resolvedCall.getCall().getDispatchReceiver().getType())
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
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.codegen.ExpressionCodegen
import org.jetbrains.kotlin.codegen.Callable
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.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.ResolvedValueArgument
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
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() {
companion object {
public val MONITOR_ENTER: MonitorInstruction = MonitorInstruction(Opcodes.MONITORENTER)
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 {
return object : IntrinsicCallable(Type.VOID_TYPE, listOf(OBJECT_TYPE), null, null) {
override fun invokeIntrinsic(v: InstructionAdapter) {
@@ -16,22 +16,14 @@
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.StackValue
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.codegen.ExpressionCodegen
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.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
public class NewArray : LazyIntrinsicMethod() {
override fun generateImpl(codegen: ExpressionCodegen, returnType: Type, element: PsiElement?, arguments: List<JetExpression>, receiver: StackValue): StackValue {
return codegen.generateNewArray(element as JetCallExpression)
}
public class NewArray : IntrinsicMethod() {
override fun toCallable(fd: FunctionDescriptor, isSuper: Boolean, resolvedCall: ResolvedCall<*>, codegen: ExpressionCodegen): Callable {
val jetType = resolvedCall.getResultingDescriptor().getReturnType()!!
@@ -17,19 +17,17 @@
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.ExpressionCodegen
import org.jetbrains.kotlin.codegen.StackValue
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.psi.JetCallExpression
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 : LazyIntrinsicMethod() {
override fun generateImpl(codegen: ExpressionCodegen, returnType: Type, element: PsiElement?, arguments: List<JetExpression>, receiver: StackValue): StackValue {
public class Not : IntrinsicMethod() {
fun generateImpl(codegen: ExpressionCodegen, returnType: Type, element: PsiElement?, arguments: List<JetExpression>, receiver: StackValue): StackValue {
val stackValue: StackValue
if (arguments.size() == 1) {
stackValue = codegen.gen(arguments.get(0))
@@ -40,9 +38,6 @@ public class Not : LazyIntrinsicMethod() {
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 {
val callable = codegen.getState().getTypeMapper().mapToCallableMethod(fd, false, codegen.getContext())
@@ -16,19 +16,11 @@
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.CallableMethod
import org.jetbrains.kotlin.codegen.StackValue
import org.jetbrains.kotlin.psi.JetExpression
import org.jetbrains.org.objectweb.asm.Type
public class NumberCast : LazyIntrinsicMethod() {
override fun generateImpl(codegen: ExpressionCodegen, returnType: Type, element: PsiElement?, arguments: List<JetExpression>, receiver: StackValue): StackValue {
return StackValue.coercion(receiver, returnType)
}
public class NumberCast : IntrinsicMethod() {
override fun toCallable(method: CallableMethod): Callable {
return UnaryIntrinsic(method) {
@@ -16,42 +16,16 @@
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.ExpressionCodegen
import org.jetbrains.kotlin.codegen.StackValue
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.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.Type.*
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 {
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 {
val method = codegen.getState().getTypeMapper().mapToCallableMethod(fd, false, codegen.getContext())
val argType = nameToPrimitive(method.getReturnType().getInternalName().substringAfter("kotlin/").substringBefore("Range"))
@@ -16,35 +16,10 @@
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.StackValue
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
import org.jetbrains.kotlin.codegen.CallableMethod
public class StringGetChar : LazyIntrinsicMethod() {
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)
}
}
public class StringGetChar : IntrinsicMethod() {
override fun toCallable(method: CallableMethod): Callable {
return IntrinsicCallable.create(method) {
@@ -16,36 +16,10 @@
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.kotlin.resolve.jvm.AsmTypes.JAVA_STRING_TYPE
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE
import org.jetbrains.kotlin.codegen.CallableMethod
public class StringPlus : LazyIntrinsicMethod() {
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)
}
}
public class StringPlus : IntrinsicMethod() {
override fun toCallable(method: CallableMethod): Callable {
return IntrinsicCallable.create(method) {
@@ -16,25 +16,11 @@
package org.jetbrains.kotlin.codegen.intrinsics
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.codegen.*
import org.jetbrains.org.objectweb.asm.Type
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
import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.codegen.CallableMethod
public class ToString : LazyIntrinsicMethod() {
override fun generateImpl(
codegen: ExpressionCodegen,
returnType: Type,
element: PsiElement?,
arguments: List<JetExpression>,
receiver: StackValue
): StackValue {
return genToString(receiver, receiver.type)
}
public class ToString : IntrinsicMethod() {
override fun toCallable(method: CallableMethod): Callable {
val type = AsmUtil.stringValueOfType(method.getThisType() ?: method.getReceiverClass())
@@ -16,35 +16,11 @@
package org.jetbrains.kotlin.codegen.intrinsics
import com.intellij.psi.PsiElement
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.AsmUtil.numberFunctionOperandType
import org.jetbrains.kotlin.codegen.Callable
import org.jetbrains.kotlin.psi.JetExpression
import org.jetbrains.kotlin.codegen.CallableMethod
public class UnaryMinus : LazyIntrinsicMethod() {
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)
}
}
public class UnaryMinus : IntrinsicMethod() {
override fun toCallable(method: CallableMethod): Callable {
return UnaryIntrinsic(method, numberFunctionOperandType(method.getReturnType()), needPrimitiveCheck = true) {
@@ -16,28 +16,10 @@
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.CallableMethod
public class UnaryPlus : LazyIntrinsicMethod() {
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))
}
}
public class UnaryPlus : IntrinsicMethod() {
override fun toCallable(method: CallableMethod): Callable {
return UnaryIntrinsic(method, needPrimitiveCheck = true) {