diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/ArrayIterator.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/ArrayIterator.kt index ee90225087a..89fd3ea08c8 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/ArrayIterator.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/ArrayIterator.kt @@ -14,66 +14,106 @@ * limitations under the License. */ -package org.jetbrains.kotlin.codegen.intrinsics; +package org.jetbrains.kotlin.codegen.intrinsics -import com.intellij.psi.PsiElement; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.kotlin.builtins.KotlinBuiltIns; -import org.jetbrains.kotlin.builtins.PrimitiveType; -import org.jetbrains.kotlin.codegen.ExpressionCodegen; -import org.jetbrains.kotlin.codegen.StackValue; -import org.jetbrains.kotlin.descriptors.ClassDescriptor; -import org.jetbrains.kotlin.descriptors.FunctionDescriptor; -import org.jetbrains.kotlin.name.FqName; -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.JvmPrimitiveType; -import org.jetbrains.org.objectweb.asm.Type; -import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter; +import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.builtins.KotlinBuiltIns +import org.jetbrains.kotlin.builtins.PrimitiveType +import org.jetbrains.kotlin.codegen.ExpressionCodegen +import org.jetbrains.kotlin.codegen.StackValue +import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.descriptors.FunctionDescriptor +import org.jetbrains.kotlin.name.FqName +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.JvmPrimitiveType +import org.jetbrains.org.objectweb.asm.Type +import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter -import java.util.Iterator; -import java.util.List; +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.ExtendedCallable +import org.jetbrains.kotlin.codegen.context.CodegenContext +import org.jetbrains.kotlin.codegen.state.GenerationState +import org.jetbrains.kotlin.resolve.jvm.AsmTypes.getType -import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME; -import static org.jetbrains.kotlin.codegen.AsmUtil.asmDescByFqNameWithoutInnerClasses; -import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.getType; - -public class ArrayIterator extends IntrinsicMethod { - @NotNull - @Override - public Type generateImpl( - @NotNull ExpressionCodegen codegen, - @NotNull InstructionAdapter v, - @NotNull Type returnType, - PsiElement element, - @NotNull List arguments, - @NotNull StackValue receiver - ) { - receiver.put(receiver.type, v); - JetCallExpression call = (JetCallExpression) element; - FunctionDescriptor funDescriptor = (FunctionDescriptor) codegen.getBindingContext() - .get(BindingContext.REFERENCE_TARGET, (JetSimpleNameExpression) call.getCalleeExpression()); - assert funDescriptor != null; - ClassDescriptor containingDeclaration = (ClassDescriptor) funDescriptor.getContainingDeclaration().getOriginal(); - if (containingDeclaration.equals(KotlinBuiltIns.getInstance().getArray())) { - v.invokestatic("kotlin/jvm/internal/InternalPackage", "iterator", "([Ljava/lang/Object;)Ljava/util/Iterator;", false); - return getType(Iterator.class); +public class ArrayIterator : IntrinsicMethod() { + override fun generateImpl(codegen: ExpressionCodegen, v: InstructionAdapter, returnType: Type, element: PsiElement?, arguments: List, 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 + val containingDeclaration = funDescriptor.getContainingDeclaration().getOriginal() as ClassDescriptor + if (containingDeclaration == KotlinBuiltIns.getInstance().getArray()) { + v.invokestatic("kotlin/jvm/internal/InternalPackage", "iterator", "([Ljava/lang/Object;)Ljava/util/Iterator;", false) + return getType(javaClass>()) } - for (JvmPrimitiveType jvmPrimitiveType : JvmPrimitiveType.values()) { - PrimitiveType primitiveType = jvmPrimitiveType.getPrimitiveType(); - ClassDescriptor arrayClass = KotlinBuiltIns.getInstance().getPrimitiveArrayClassDescriptor(primitiveType); - if (containingDeclaration.equals(arrayClass)) { - FqName fqName = new FqName(BUILT_INS_PACKAGE_FQ_NAME + "." + primitiveType.getTypeName() + "Iterator"); - String iteratorDesc = asmDescByFqNameWithoutInnerClasses(fqName); - String methodSignature = "([" + jvmPrimitiveType.getDesc() + ")" + iteratorDesc; - v.invokestatic("kotlin/jvm/internal/InternalPackage", "iterator", methodSignature, false); - return Type.getType(iteratorDesc); + for (jvmPrimitiveType in JvmPrimitiveType.values()) { + val primitiveType = jvmPrimitiveType.getPrimitiveType() + val arrayClass = KotlinBuiltIns.getInstance().getPrimitiveArrayClassDescriptor(primitiveType) + if (containingDeclaration == arrayClass) { + val fqName = FqName(BUILT_INS_PACKAGE_FQ_NAME.toString() + "." + primitiveType.getTypeName() + "Iterator") + val iteratorDesc = asmDescByFqNameWithoutInnerClasses(fqName) + val methodSignature = "([" + jvmPrimitiveType.getDesc() + ")" + iteratorDesc + v.invokestatic("kotlin/jvm/internal/InternalPackage", "iterator", methodSignature, false) + return Type.getType(iteratorDesc) } } - throw new UnsupportedOperationException(containingDeclaration.toString()); + throw UnsupportedOperationException(containingDeclaration.toString()) + } + + override fun supportCallable(): Boolean { + return true + } + + //TODO refactor + override fun toCallable(state: GenerationState, fd: FunctionDescriptor, context: CodegenContext<*>, isSuper: Boolean): ExtendedCallable { + val callableMethod = state.getTypeMapper().mapToCallableMethod(fd, false, context) + + val containingDeclaration = fd.getContainingDeclaration().getOriginal() as ClassDescriptor + var type: Type? = null; + if (containingDeclaration == KotlinBuiltIns.getInstance().getArray()) { + type = getType(javaClass>()) + } else { + + for (jvmPrimitiveType in JvmPrimitiveType.values()) { + val primitiveType = jvmPrimitiveType.getPrimitiveType() + val arrayClass = KotlinBuiltIns.getInstance().getPrimitiveArrayClassDescriptor(primitiveType) + if (containingDeclaration == arrayClass) { + val fqName = FqName(BUILT_INS_PACKAGE_FQ_NAME.toString() + "." + primitiveType.getTypeName() + "Iterator") + val iteratorDesc = asmDescByFqNameWithoutInnerClasses(fqName) + type = Type.getType(iteratorDesc) + break + } + } + } + + if (type == null) { + throw UnsupportedOperationException(containingDeclaration.toString()) + } + + + return UnaryIntrinsic(callableMethod, type) { + val containingDeclaration = fd.getContainingDeclaration().getOriginal() as ClassDescriptor + if (containingDeclaration == KotlinBuiltIns.getInstance().getArray()) { + it.invokestatic("kotlin/jvm/internal/InternalPackage", "iterator", "([Ljava/lang/Object;)Ljava/util/Iterator;", false) + } else { + for (jvmPrimitiveType in JvmPrimitiveType.values()) { + val primitiveType = jvmPrimitiveType.getPrimitiveType() + val arrayClass = KotlinBuiltIns.getInstance().getPrimitiveArrayClassDescriptor(primitiveType) + if (containingDeclaration == arrayClass) { + val fqName = FqName(BUILT_INS_PACKAGE_FQ_NAME.toString() + "." + primitiveType.getTypeName() + "Iterator") + val iteratorDesc = asmDescByFqNameWithoutInnerClasses(fqName) + val methodSignature = "([" + jvmPrimitiveType.getDesc() + ")" + iteratorDesc + it.invokestatic("kotlin/jvm/internal/InternalPackage", "iterator", methodSignature, false) + break; + } + } + } + } } } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/ArraySet.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/ArraySet.kt index 4fd104bac7b..505d6f50116 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/ArraySet.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/ArraySet.kt @@ -14,38 +14,42 @@ * limitations under the License. */ -package org.jetbrains.kotlin.codegen.intrinsics; +package org.jetbrains.kotlin.codegen.intrinsics -import com.intellij.psi.PsiElement; -import org.jetbrains.annotations.NotNull; -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 com.intellij.psi.PsiElement +import org.jetbrains.kotlin.codegen.CallableMethod +import org.jetbrains.kotlin.codegen.ExpressionCodegen +import org.jetbrains.kotlin.codegen.ExtendedCallable +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; +import org.jetbrains.kotlin.codegen.AsmUtil.correctElementType -import static org.jetbrains.kotlin.codegen.AsmUtil.correctElementType; +public class ArraySet : IntrinsicMethod() { + override fun generateImpl(codegen: ExpressionCodegen, v: InstructionAdapter, returnType: Type, element: PsiElement?, arguments: List, receiver: StackValue): Type { + receiver.put(receiver.type, v) + val type = correctElementType(receiver.type) -public class ArraySet extends IntrinsicMethod { - @NotNull - @Override - public Type generateImpl( - @NotNull ExpressionCodegen codegen, - @NotNull InstructionAdapter v, - @NotNull Type returnType, - PsiElement element, - @NotNull List arguments, - @NotNull StackValue receiver - ) { - receiver.put(receiver.type, v); - Type type = correctElementType(receiver.type); + codegen.gen(arguments.get(0), Type.INT_TYPE) + codegen.gen(arguments.get(1), type) - codegen.gen(arguments.get(0), Type.INT_TYPE); - codegen.gen(arguments.get(1), type); + v.astore(type) + return Type.VOID_TYPE + } - v.astore(type); - return Type.VOID_TYPE; + override fun supportCallable(): Boolean { + return true + } + + override fun toCallable(method: CallableMethod): ExtendedCallable { + val type = correctElementType(method.getThisType()) + return object: IntrinsicCallable(Type.VOID_TYPE, listOf(Type.INT_TYPE, type), method.getThisType(), method.getReceiverClass()) { + override fun invokeIntrinsic(v: InstructionAdapter) { + v.astore(type) + } + + } } } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/Clone.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/Clone.kt index 19afcb4d3b3..70c03e37335 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/Clone.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/Clone.kt @@ -14,52 +14,52 @@ * limitations under the License. */ -package org.jetbrains.kotlin.codegen.intrinsics; +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.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 com.intellij.psi.PsiElement +import org.jetbrains.kotlin.codegen.CallableMethod +import org.jetbrains.kotlin.codegen.ExpressionCodegen +import org.jetbrains.kotlin.codegen.ExtendedCallable +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 java.util.List; +import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCallWithAssert +import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE +import org.jetbrains.org.objectweb.asm.Opcodes -import static org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilPackage.getResolvedCallWithAssert; -import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE; - -public class Clone extends IntrinsicMethod { - @NotNull - @Override - protected Type generateImpl( - @NotNull ExpressionCodegen codegen, - @NotNull InstructionAdapter v, - @NotNull Type returnType, - @Nullable PsiElement element, - @NotNull List arguments, - @NotNull StackValue receiver - ) { - ResolvedCall resolvedCall = getResolvedCallWithAssert(((JetElement) element), codegen.getBindingContext()); - StackValue.receiver(resolvedCall, receiver, codegen, null).put(OBJECT_TYPE, v); +public class Clone : IntrinsicMethod() { + override fun generateImpl(codegen: ExpressionCodegen, v: InstructionAdapter, returnType: Type, element: PsiElement?, arguments: List, 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); + v.invokespecial("java/lang/Object", "clone", "()Ljava/lang/Object;", false) } else { - v.invokevirtual("java/lang/Object", "clone", "()Ljava/lang/Object;", false); + v.invokevirtual("java/lang/Object", "clone", "()Ljava/lang/Object;", false) } - return OBJECT_TYPE; + return OBJECT_TYPE } - private static boolean isSuperCall(@NotNull ResolvedCall resolvedCall) { - ReceiverValue dispatchReceiver = resolvedCall.getDispatchReceiver(); - return dispatchReceiver instanceof ExpressionReceiver && - ((ExpressionReceiver) dispatchReceiver).getExpression() instanceof JetSuperExpression; + 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): ExtendedCallable { + return UnaryIntrinsic(method, OBJECT_TYPE) { + val opcodes: Int = if (isSuperCall) Opcodes.INVOKESPECIAL else Opcodes.INVOKEVIRTUAL + it.visitMethodInsn(opcodes, "java/lang/Object", "clone", "()Ljava/lang/Object;", false) + } } } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/CompareTo.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/CompareTo.kt index cea92a969fd..a465b46395f 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/CompareTo.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/CompareTo.kt @@ -14,64 +14,70 @@ * limitations under the License. */ -package org.jetbrains.kotlin.codegen.intrinsics; +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 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.org.objectweb.asm.commons.InstructionAdapter -import java.util.List; +import org.jetbrains.kotlin.codegen.AsmUtil.comparisonOperandType +import org.jetbrains.kotlin.codegen.CallableMethod +import org.jetbrains.kotlin.codegen.ExtendedCallable -import static org.jetbrains.kotlin.codegen.AsmUtil.comparisonOperandType; - -public class CompareTo extends IntrinsicMethod { - @NotNull - @Override - public Type generateImpl( - @NotNull ExpressionCodegen codegen, - @NotNull InstructionAdapter v, - @NotNull Type returnType, - @Nullable PsiElement element, - @NotNull List arguments, - @NotNull StackValue receiver - ) { - JetExpression argument; +public class CompareTo : IntrinsicMethod() { + override fun generateImpl(codegen: ExpressionCodegen, v: InstructionAdapter, returnType: Type, element: PsiElement?, arguments: List, receiver: StackValue): Type { + var receiver = receiver + val argument: JetExpression if (arguments.size() == 1) { - argument = arguments.get(0); + argument = arguments.get(0) } else if (arguments.size() == 2) { - receiver = codegen.gen(arguments.get(0)); - argument = arguments.get(1); + receiver = codegen.gen(arguments.get(0)) + argument = arguments.get(1) } else { - throw new IllegalStateException("Invalid arguments to compareTo: " + arguments); + throw IllegalStateException("Invalid arguments to compareTo: " + arguments) } - Type type = comparisonOperandType(receiver.type, codegen.expressionType(argument)); + val type = comparisonOperandType(receiver.type, codegen.expressionType(argument)) - receiver.put(type, v); - codegen.gen(argument, type); + 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) { - v.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, "compare", "(II)I", false); + v.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, "compare", "(II)I", false) } else if (type == Type.LONG_TYPE) { - v.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, "compare", "(JJ)I", false); + v.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, "compare", "(JJ)I", false) } else if (type == Type.FLOAT_TYPE) { - v.invokestatic("java/lang/Float", "compare", "(FF)I", false); + v.invokestatic("java/lang/Float", "compare", "(FF)I", false) } else if (type == Type.DOUBLE_TYPE) { - v.invokestatic("java/lang/Double", "compare", "(DD)I", false); + v.invokestatic("java/lang/Double", "compare", "(DD)I", false) } else { - throw new UnsupportedOperationException(); + throw UnsupportedOperationException() } + } - return Type.INT_TYPE; + //TODO seems we need to different CompareTo + override fun supportCallable(): Boolean { + return false + } + + override fun toCallable(method: CallableMethod): ExtendedCallable { + val argumentType = comparisonOperandType(method.getThisType() ?: method.getReceiverClass(), method.getArgumentTypes().first()) + return IntrinsicCallable.binaryIntrinsic(method.getReturnType(), argumentType, argumentType, null) { + genInvoke(argumentType, it) + } } } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/Concat.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/Concat.java index 4e5aa83efd2..26d0d0f5bec 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/Concat.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/Concat.java @@ -49,7 +49,7 @@ public class Concat extends IntrinsicMethod { codegen.invokeAppend(arguments.get(1)); } else { - // LHS.plus(RHS) + // LHS?.plus(RHS) receiver.put(AsmTypes.OBJECT_TYPE, v); genStringBuilderConstructor(v); v.swap(); diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/CopyToArray.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/CopyToArray.kt index b3701b7c458..1c97122d3c0 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/CopyToArray.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/CopyToArray.kt @@ -14,44 +14,52 @@ * limitations under the License. */ -package org.jetbrains.kotlin.codegen.intrinsics; +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.kotlin.types.JetType; -import org.jetbrains.org.objectweb.asm.Type; -import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter; +import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.codegen.CallableMethod +import org.jetbrains.kotlin.codegen.ExpressionCodegen +import org.jetbrains.kotlin.codegen.ExtendedCallable +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.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 java.util.List; +import org.jetbrains.kotlin.resolve.jvm.AsmTypes.getType -import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.getType; +public class CopyToArray : IntrinsicMethod() { + override fun generateImpl(codegen: ExpressionCodegen, v: InstructionAdapter, returnType: Type, element: PsiElement?, arguments: List, receiver: StackValue): Type { + receiver.put(receiver.type, v) + v.dup() + v.invokeinterface("java/util/Collection", "size", "()I") -public class CopyToArray extends IntrinsicMethod { - @NotNull - @Override - public Type generateImpl( - @NotNull ExpressionCodegen codegen, - @NotNull InstructionAdapter v, - @NotNull Type returnType, - @Nullable PsiElement element, - @NotNull List arguments, - @NotNull StackValue receiver - ) { - 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) - assert element instanceof JetExpression; - JetType arrayType = codegen.expressionJetType((JetExpression) element); - assert arrayType != null; + codegen.newArrayInstruction(arrayType) + v.invokeinterface("java/util/Collection", "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;") - codegen.newArrayInstruction(arrayType); - v.invokeinterface("java/util/Collection", "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;"); - - return getType(Object[].class); + return getType(javaClass>()) } -} + + override fun supportCallable(): Boolean { + return true + } + + override fun toCallable(fd: FunctionDescriptor, isSuper: Boolean, resolvedCall: ResolvedCall<*>, codegen: ExpressionCodegen): ExtendedCallable { + return object : IntrinsicCallable(getType(javaClass>()), listOf(), null, Type.getType(javaClass>())) { + override fun invokeIntrinsic(v: InstructionAdapter) { + v.dup() + v.invokeinterface("java/util/Collection", "size", "()I") + codegen.newArrayInstruction(resolvedCall.getResultingDescriptor().getReturnType()!!) + v.invokeinterface("java/util/Collection", "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;") + } + } + } +} \ No newline at end of file diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/IdentityEquals.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/IdentityEquals.kt index b9d0f51bbf1..a7d62245912 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/IdentityEquals.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/IdentityEquals.kt @@ -14,44 +14,45 @@ * limitations under the License. */ -package org.jetbrains.kotlin.codegen.intrinsics; +package org.jetbrains.kotlin.codegen.intrinsics -import com.intellij.psi.PsiElement; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.kotlin.codegen.ExpressionCodegen; -import org.jetbrains.kotlin.codegen.StackValue; -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.org.objectweb.asm.Type; +import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.codegen.* +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.org.objectweb.asm.Type -import java.util.List; +import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE -import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE; - -public class IdentityEquals extends LazyIntrinsicMethod { - @NotNull - @Override - public StackValue generateImpl( - @NotNull ExpressionCodegen codegen, - @NotNull Type returnType, - PsiElement element, - @NotNull List arguments, - @NotNull StackValue receiver - ) { - StackValue left; - StackValue right; - if (element instanceof JetCallExpression) { - left = receiver; - right = codegen.gen(arguments.get(0)); +public class IdentityEquals : LazyIntrinsicMethod() { + override fun generateImpl(codegen: ExpressionCodegen, returnType: Type, element: PsiElement?, arguments: List, receiver: StackValue): StackValue { + val left: StackValue + val right: StackValue + if (element is JetCallExpression) { + left = receiver + right = codegen.gen(arguments.get(0)) } else { - assert element instanceof JetBinaryExpression; - JetBinaryExpression e = (JetBinaryExpression) element; - left = codegen.gen(e.getLeft()); - right = codegen.gen(e.getRight()); + 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); + return StackValue.cmp(JetTokens.EQEQEQ, OBJECT_TYPE, left, right) } + + + override fun supportCallable(): Boolean { + return false + } + + override fun toCallable(method: CallableMethod): ExtendedCallable { + return IntrinsicCallable.binaryIntrinsic(method.getReturnType(), OBJECT_TYPE, nullOrObject(method.getThisType()), nullOrObject(method.getReceiverClass())) { + v -> v.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, "areEqual", "(Ljava/lang/Object;Ljava/lang/Object;)Z", false) + AsmUtil.genAreEqualCall(v) + } + } + } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/Inv.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/Inv.kt index bd6325bca35..d9e7f05d12f 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/Inv.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/Inv.kt @@ -14,42 +14,49 @@ * limitations under the License. */ -package org.jetbrains.kotlin.codegen.intrinsics; +package org.jetbrains.kotlin.codegen.intrinsics -import com.intellij.psi.PsiElement; -import org.jetbrains.annotations.NotNull; -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 com.intellij.psi.PsiElement +import org.jetbrains.kotlin.codegen.CallableMethod +import org.jetbrains.kotlin.codegen.ExpressionCodegen +import org.jetbrains.kotlin.codegen.ExtendedCallable +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; +import org.jetbrains.kotlin.codegen.AsmUtil.isPrimitive +import org.jetbrains.kotlin.codegen.AsmUtil.numberFunctionOperandType -import static org.jetbrains.kotlin.codegen.AsmUtil.isPrimitive; -import static org.jetbrains.kotlin.codegen.AsmUtil.numberFunctionOperandType; +public class Inv : IntrinsicMethod() { + override fun generateImpl(codegen: ExpressionCodegen, v: InstructionAdapter, returnType: Type, element: PsiElement?, arguments: List, receiver: StackValue): Type { + assert(isPrimitive(returnType)) { "Return type of Inv intrinsic should be of primitive type : " + returnType } -public class Inv extends IntrinsicMethod { - @NotNull - @Override - public Type generateImpl( - @NotNull ExpressionCodegen codegen, - @NotNull InstructionAdapter v, - @NotNull Type returnType, - PsiElement element, - @NotNull List arguments, - @NotNull StackValue receiver - ) { - assert isPrimitive(returnType) : "Return type of Inv intrinsic should be of primitive type : " + returnType; - - receiver.put(numberFunctionOperandType(returnType), v); + receiver.put(numberFunctionOperandType(returnType), v) if (returnType == Type.LONG_TYPE) { - v.lconst(-1L); + v.lconst(-1) } else { - v.iconst(-1); + v.iconst(-1) + } + v.xor(returnType) + return returnType + } + + override fun supportCallable(): Boolean { + return true + } + + override fun toCallable(method: CallableMethod): ExtendedCallable { + val type = numberFunctionOperandType(method.getReturnType()) + return UnaryIntrinsic(method, method.getReturnType(), newThisType = type) { + if (getReturnType() == Type.LONG_TYPE) { + it.lconst(-1) + } + else { + it.iconst(-1) + } + it.xor(getReturnType()) } - v.xor(returnType); - return returnType; } } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/IteratorNext.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/IteratorNext.kt index 5c69c38a33a..4173ddf512e 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/IteratorNext.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/IteratorNext.kt @@ -14,62 +14,76 @@ * limitations under the License. */ -package org.jetbrains.kotlin.codegen.intrinsics; +package org.jetbrains.kotlin.codegen.intrinsics -import com.intellij.psi.PsiElement; -import org.jetbrains.annotations.NotNull; -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 com.intellij.psi.PsiElement +import org.jetbrains.kotlin.codegen.CallableMethod +import org.jetbrains.kotlin.codegen.ExpressionCodegen +import org.jetbrains.kotlin.codegen.ExtendedCallable +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 java.util.List; +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 -import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME; +public class IteratorNext : IntrinsicMethod() { + override fun generateImpl(codegen: ExpressionCodegen, v: InstructionAdapter, returnType: Type, element: PsiElement?, arguments: List, 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 + } -public class IteratorNext extends IntrinsicMethod { - @NotNull - @Override - public Type generateImpl( - @NotNull ExpressionCodegen codegen, - @NotNull InstructionAdapter v, - @NotNull Type returnType, - PsiElement element, - @NotNull List arguments, - @NotNull StackValue receiver - ) { - String name; + protected fun getIteratorName(returnType: Type): String { + val name: String if (returnType == Type.CHAR_TYPE) { - name = "Char"; + name = "Char" } else if (returnType == Type.BOOLEAN_TYPE) { - name = "Boolean"; + name = "Boolean" } else if (returnType == Type.BYTE_TYPE) { - name = "Byte"; + name = "Byte" } else if (returnType == Type.SHORT_TYPE) { - name = "Short"; + name = "Short" } else if (returnType == Type.INT_TYPE) { - name = "Int"; + name = "Int" } else if (returnType == Type.LONG_TYPE) { - name = "Long"; + name = "Long" } else if (returnType == Type.FLOAT_TYPE) { - name = "Float"; + name = "Float" } else if (returnType == Type.DOUBLE_TYPE) { - name = "Double"; + name = "Double" } else { - throw new UnsupportedOperationException(); + throw UnsupportedOperationException("Can't get correct name for iterator from type: " + returnType) + } + return name + } + + override fun supportCallable(): Boolean { + return true + } + + + override fun toCallable(state: GenerationState, fd: FunctionDescriptor, context: CodegenContext<*>, isSuper: Boolean): ExtendedCallable { + val type = state.getTypeMapper().mapReturnType(fd) + return object: IntrinsicCallable(type, listOf(), AsmTypes.OBJECT_TYPE, null) { + override fun invokeIntrinsic(v: InstructionAdapter) { + val returnType = getReturnType() + val name = getIteratorName(returnType) + v.invokevirtual(BUILT_INS_PACKAGE_FQ_NAME.toString() + "/" + name + "Iterator", "next" + name, "()" + returnType.getDescriptor(), false) + } } - receiver.put(AsmTypes.OBJECT_TYPE, v); - v.invokevirtual(BUILT_INS_PACKAGE_FQ_NAME + "/" + name + "Iterator", "next" + name, "()" + returnType.getDescriptor(), false); - return returnType; } } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/JavaClassArray.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/JavaClassArray.kt index 3a4281c9267..97c2b5c8e06 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/JavaClassArray.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/JavaClassArray.kt @@ -14,42 +14,41 @@ * limitations under the License. */ -package org.jetbrains.kotlin.codegen.intrinsics; +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.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 com.intellij.psi.PsiElement +import org.jetbrains.kotlin.codegen.CallableMethod +import org.jetbrains.kotlin.codegen.ExpressionCodegen +import org.jetbrains.kotlin.codegen.ExtendedCallable +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 java.util.List; -import java.util.Map; +import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCallWithAssert -import static org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilPackage.getResolvedCallWithAssert; +public class JavaClassArray : IntrinsicMethod() { + override fun generateImpl(codegen: ExpressionCodegen, v: InstructionAdapter, returnType: Type, element: PsiElement?, arguments: List, 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 + } -public class JavaClassArray extends IntrinsicMethod { - @NotNull - @Override - public Type generateImpl( - @NotNull ExpressionCodegen codegen, - @NotNull InstructionAdapter v, - @NotNull Type returnType, - @Nullable PsiElement element, - @NotNull List arguments, - @NotNull StackValue receiver - ) { - assert element != null : "Element should not be null"; - ResolvedCall resolvedCall = getResolvedCallWithAssert((JetElement) element, codegen.getBindingContext()); - Map.Entry argument = resolvedCall.getValueArguments().entrySet().iterator().next(); - codegen.genVarargs((VarargValueArgument) argument.getValue(), argument.getKey().getType()); - return returnType; + override fun supportCallable(): Boolean { + return true + } + + override fun toCallable(method: CallableMethod): ExtendedCallable { + return MappedCallable(method) { + //do nothing all generated as vararg + } } } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/JavaClassFunction.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/JavaClassFunction.kt index d9e7e296086..64aa9bed5ae 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/JavaClassFunction.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/JavaClassFunction.kt @@ -14,49 +14,52 @@ * limitations under the License. */ -package org.jetbrains.kotlin.codegen.intrinsics; +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.codegen.inline.ReifiedTypeInliner; -import org.jetbrains.kotlin.psi.JetElement; -import org.jetbrains.kotlin.psi.JetExpression; -import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilPackage; -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 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 java.util.List; +import org.jetbrains.kotlin.codegen.AsmUtil.putJavaLangClassInstance +import org.jetbrains.kotlin.codegen.ExtendedCallable +import org.jetbrains.kotlin.descriptors.FunctionDescriptor +import org.jetbrains.kotlin.resolve.jvm.AsmTypes.getType -import static org.jetbrains.kotlin.codegen.AsmUtil.putJavaLangClassInstance; -import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.getType; +public class JavaClassFunction : IntrinsicMethod() { + override fun generateImpl(codegen: ExpressionCodegen, v: InstructionAdapter, expectedType: Type, element: PsiElement?, arguments: List, receiver: StackValue): Type { + val resolvedCall = (element as JetElement).getResolvedCallWithAssert(codegen.getBindingContext()) + val returnType = resolvedCall.getResultingDescriptor().getReturnType() + assert(returnType != null) -public class JavaClassFunction extends IntrinsicMethod { - @NotNull - @Override - public Type generateImpl( - @NotNull ExpressionCodegen codegen, - @NotNull InstructionAdapter v, - @NotNull Type expectedType, - @Nullable PsiElement element, - @NotNull List arguments, - @NotNull StackValue receiver - ) { - ResolvedCall resolvedCall = CallUtilPackage.getResolvedCallWithAssert( - (JetElement) element, codegen.getBindingContext()); - JetType returnType = resolvedCall.getResultingDescriptor().getReturnType(); - assert returnType != null; + val type = returnType!!.getArguments().get(0).getType() - JetType type = returnType.getArguments().get(0).getType(); + codegen.putReifierMarkerIfTypeIsReifiedParameter(type, ReifiedTypeInliner.JAVA_CLASS_MARKER_METHOD_NAME) - codegen.putReifierMarkerIfTypeIsReifiedParameter(type, ReifiedTypeInliner.JAVA_CLASS_MARKER_METHOD_NAME); + putJavaLangClassInstance(v, codegen.getState().getTypeMapper().mapType(type)) - putJavaLangClassInstance(v, codegen.getState().getTypeMapper().mapType(type)); + return getType(javaClass>()) + } + + override fun supportCallable(): Boolean { + return true + } + + override fun toCallable(fd: FunctionDescriptor, isSuper: Boolean, resolvedCall: ResolvedCall<*>, codegen: ExpressionCodegen): ExtendedCallable { + val javaClass = resolvedCall.getResultingDescriptor().getReturnType()!!.getArguments().get(0).getType() + return object: IntrinsicCallable(getType(javaClass>()), listOf(), null, null) { + override fun invokeIntrinsic(v: InstructionAdapter) { + codegen.putReifierMarkerIfTypeIsReifiedParameter(javaClass, ReifiedTypeInliner.JAVA_CLASS_MARKER_METHOD_NAME) + putJavaLangClassInstance(v, codegen.getState().getTypeMapper().mapType(javaClass)) + } + } - return getType(Class.class); } } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/JavaClassProperty.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/JavaClassProperty.kt index aa15b21f944..b0362caa0fe 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/JavaClassProperty.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/JavaClassProperty.kt @@ -14,48 +14,60 @@ * limitations under the License. */ -package org.jetbrains.kotlin.codegen.intrinsics; +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.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 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 java.util.List; +import org.jetbrains.kotlin.codegen.AsmUtil.boxType +import org.jetbrains.kotlin.codegen.AsmUtil.isPrimitive +import org.jetbrains.kotlin.codegen.ExtendedCallable +import org.jetbrains.kotlin.descriptors.FunctionDescriptor +import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall +import org.jetbrains.kotlin.resolve.jvm.AsmTypes.getType -import static org.jetbrains.kotlin.codegen.AsmUtil.boxType; -import static org.jetbrains.kotlin.codegen.AsmUtil.isPrimitive; -import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.getType; - -public class JavaClassProperty extends IntrinsicMethod { - @NotNull - @Override - public Type generateImpl( - @NotNull ExpressionCodegen codegen, - @NotNull InstructionAdapter v, - @NotNull Type returnType, - @Nullable PsiElement element, - @NotNull List arguments, - @NotNull StackValue receiver - ) { - Type type = receiver.type; +public class JavaClassProperty : IntrinsicMethod() { + override fun generateImpl(codegen: ExpressionCodegen, v: InstructionAdapter, returnType: Type, element: PsiElement?, arguments: List, receiver: StackValue): Type { + val type = receiver.type if (isPrimitive(type)) { if (!StackValue.couldSkipReceiverOnStaticCall(receiver)) { - receiver.put(type, v); - AsmUtil.pop(v, type); + receiver.put(type, v) + AsmUtil.pop(v, type) } - v.getstatic(boxType(type).getInternalName(), "TYPE", "Ljava/lang/Class;"); + v.getstatic(boxType(type).getInternalName(), "TYPE", "Ljava/lang/Class;") } else { - receiver.put(type, v); - v.invokevirtual("java/lang/Object", "getClass", "()Ljava/lang/Class;", false); + receiver.put(type, v) + v.invokevirtual("java/lang/Object", "getClass", "()Ljava/lang/Class;", false) } - return getType(Class.class); + return getType(javaClass>()) + } + + override fun supportCallable(): Boolean { + return true + } + + override fun toCallable(fd: FunctionDescriptor, isSuper: Boolean, resolvedCall: ResolvedCall<*>, codegen: ExpressionCodegen): ExtendedCallable { + val classType = codegen.getState().getTypeMapper().mapType(resolvedCall.getCall().getDispatchReceiver().getType()) + return object : IntrinsicCallable(getType(javaClass>()), listOf(), classType, null) { + override fun invokeIntrinsic(v: InstructionAdapter) { + if (isPrimitive(classType)) { + v.getstatic(boxType(classType).getInternalName(), "TYPE", "Ljava/lang/Class;") + } + else { + v.invokevirtual("java/lang/Object", "getClass", "()Ljava/lang/Class;", false) + } + } + + override fun isStaticCall(): Boolean { + return isPrimitive(classType) + } + } } } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/MonitorInstruction.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/MonitorInstruction.kt index 2adffc21dd6..6ff14f48a7e 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/MonitorInstruction.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/MonitorInstruction.kt @@ -14,66 +14,62 @@ * limitations under the License. */ -package org.jetbrains.kotlin.codegen.intrinsics; +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.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.org.objectweb.asm.Opcodes; -import org.jetbrains.org.objectweb.asm.Type; -import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter; +import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.codegen.ExpressionCodegen +import org.jetbrains.kotlin.codegen.ExtendedCallable +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.org.objectweb.asm.Opcodes +import org.jetbrains.org.objectweb.asm.Type +import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter -import java.util.List; +import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCallWithAssert +import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE -import static org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilPackage.getResolvedCallWithAssert; -import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE; - -public class MonitorInstruction extends IntrinsicMethod { - - public static final MonitorInstruction MONITOR_ENTER = new MonitorInstruction(Opcodes.MONITORENTER); - public static final MonitorInstruction MONITOR_EXIT = new MonitorInstruction(Opcodes.MONITOREXIT); - - private final int opcode; - - private MonitorInstruction(int opcode) { - this.opcode = opcode; +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) } - @NotNull - @Override - protected Type generateImpl( - @NotNull ExpressionCodegen codegen, - @NotNull InstructionAdapter v, - @NotNull Type returnType, - @Nullable PsiElement element, - @NotNull List arguments, - @NotNull StackValue receiver - ) { - assert element != null : "Element should not be null"; + override fun generateImpl(codegen: ExpressionCodegen, v: InstructionAdapter, returnType: Type, element: PsiElement?, arguments: List, receiver: StackValue): Type { + assert(element != null, "Element should not be null") - ResolvedCall resolvedCall = getResolvedCallWithAssert((JetElement) element, codegen.getBindingContext()); + val resolvedCall = (element as JetElement).getResolvedCallWithAssert(codegen.getBindingContext()) - List resolvedArguments = resolvedCall.getValueArgumentsByIndex(); - assert resolvedArguments != null && resolvedArguments.size() == 1 : - "Monitor instruction (" + opcode + ") should have exactly 1 argument: " + resolvedArguments; + val resolvedArguments = resolvedCall.getValueArgumentsByIndex() + assert(resolvedArguments != null && resolvedArguments.size() == 1) { "Monitor instruction (" + opcode + ") should have exactly 1 argument: " + resolvedArguments } - ResolvedValueArgument argument = resolvedArguments.get(0); - assert argument instanceof ExpressionValueArgument : - "Monitor instruction (" + opcode + ") should have expression value argument: " + argument; + val argument = resolvedArguments!!.get(0) + assert(argument is ExpressionValueArgument) { "Monitor instruction (" + opcode + ") should have expression value argument: " + argument } - ValueArgument valueArgument = ((ExpressionValueArgument) argument).getValueArgument(); - assert valueArgument != null : "Unresolved value argument: " + argument; - codegen.gen(valueArgument.getArgumentExpression(), OBJECT_TYPE); + 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; + 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<*>): ExtendedCallable { + return object : IntrinsicCallable(Type.VOID_TYPE, listOf(OBJECT_TYPE), null, null) { + override fun invokeIntrinsic(v: InstructionAdapter) { + v.visitInsn(opcode) + } + } } } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/NewArray.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/NewArray.kt index a873467dd5b..29671d966ea 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/NewArray.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/NewArray.kt @@ -14,28 +14,34 @@ * limitations under the License. */ -package org.jetbrains.kotlin.codegen.intrinsics; +package org.jetbrains.kotlin.codegen.intrinsics -import com.intellij.psi.PsiElement; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.kotlin.codegen.ExpressionCodegen; -import org.jetbrains.kotlin.codegen.StackValue; -import org.jetbrains.kotlin.psi.JetCallExpression; -import org.jetbrains.kotlin.psi.JetExpression; -import org.jetbrains.org.objectweb.asm.Type; +import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.codegen.ExpressionCodegen +import org.jetbrains.kotlin.codegen.ExtendedCallable +import org.jetbrains.kotlin.codegen.StackValue +import org.jetbrains.kotlin.codegen.state.GenerationState +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 -import java.util.List; - -public class NewArray extends LazyIntrinsicMethod { - @NotNull - @Override - public StackValue generateImpl( - @NotNull ExpressionCodegen codegen, - @NotNull Type returnType, - PsiElement element, - @NotNull List arguments, - @NotNull StackValue receiver - ) { - return codegen.generateNewArray((JetCallExpression) element); +public class NewArray : LazyIntrinsicMethod() { + override fun generateImpl(codegen: ExpressionCodegen, returnType: Type, element: PsiElement?, arguments: List, receiver: StackValue): StackValue { + return codegen.generateNewArray(element as JetCallExpression) } + + override fun toCallable(fd: FunctionDescriptor, isSuper: Boolean, resolvedCall: ResolvedCall<*>, codegen: ExpressionCodegen): ExtendedCallable { + val jetType = resolvedCall.getResultingDescriptor().getReturnType()!! + val type = codegen.getState().getTypeMapper().mapType(jetType) + return object : IntrinsicCallable(type, listOf(Type.INT_TYPE), null, null) { + override fun invokeIntrinsic(v: InstructionAdapter) { + codegen.newArrayInstruction(jetType) + } + } + } + } + diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/Not.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/Not.kt index 7e261a73be6..8fe1b2a9eb6 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/Not.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/Not.kt @@ -14,34 +14,29 @@ * limitations under the License. */ -package org.jetbrains.kotlin.codegen.intrinsics; +package org.jetbrains.kotlin.codegen.intrinsics -import com.intellij.psi.PsiElement; -import org.jetbrains.annotations.NotNull; -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 com.intellij.psi.PsiElement +import org.jetbrains.kotlin.codegen.CallableMethod +import org.jetbrains.kotlin.codegen.ExpressionCodegen +import org.jetbrains.kotlin.codegen.ExtendedCallable +import org.jetbrains.kotlin.codegen.StackValue +import org.jetbrains.kotlin.psi.JetExpression +import org.jetbrains.org.objectweb.asm.Type -import java.util.List; - -public class Not extends LazyIntrinsicMethod { - @NotNull - @Override - public StackValue generateImpl( - @NotNull ExpressionCodegen codegen, - @NotNull Type returnType, - PsiElement element, - @NotNull List arguments, - @NotNull StackValue receiver - ) { - StackValue stackValue; +public class Not : LazyIntrinsicMethod() { + override fun generateImpl(codegen: ExpressionCodegen, returnType: Type, element: PsiElement?, arguments: List, receiver: StackValue): StackValue { + val stackValue: StackValue if (arguments.size() == 1) { - stackValue = codegen.gen(arguments.get(0)); + stackValue = codegen.gen(arguments.get(0)) } else { - stackValue = receiver; + stackValue = receiver } - return StackValue.not(StackValue.coercion(stackValue, Type.BOOLEAN_TYPE)); + return StackValue.not(StackValue.coercion(stackValue, Type.BOOLEAN_TYPE)) + } + + override fun supportCallable(): Boolean { + return false } } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/NumberCast.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/NumberCast.kt index 4eaa7a0d8ca..16ac12b9071 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/NumberCast.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/NumberCast.kt @@ -14,27 +14,25 @@ * limitations under the License. */ -package org.jetbrains.kotlin.codegen.intrinsics; +package org.jetbrains.kotlin.codegen.intrinsics -import com.intellij.psi.PsiElement; -import org.jetbrains.annotations.NotNull; -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 com.intellij.psi.PsiElement +import org.jetbrains.kotlin.codegen.CallableMethod +import org.jetbrains.kotlin.codegen.ExpressionCodegen +import org.jetbrains.kotlin.codegen.ExtendedCallable +import org.jetbrains.kotlin.codegen.StackValue +import org.jetbrains.kotlin.psi.JetExpression +import org.jetbrains.org.objectweb.asm.Type -import java.util.List; +public class NumberCast : LazyIntrinsicMethod() { -public class NumberCast extends LazyIntrinsicMethod { - @NotNull - @Override - public StackValue generateImpl( - @NotNull ExpressionCodegen codegen, - @NotNull Type returnType, - PsiElement element, - @NotNull List arguments, - @NotNull StackValue receiver - ) { - return StackValue.coercion(receiver, returnType); + override fun generateImpl(codegen: ExpressionCodegen, returnType: Type, element: PsiElement?, arguments: List, receiver: StackValue): StackValue { + return StackValue.coercion(receiver, returnType) + } + + override fun toCallable(method: CallableMethod): ExtendedCallable { + return UnaryIntrinsic(method) { + StackValue.coerce(calcReceiverType()!!, getReturnType(), it) + } } } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/UnaryPlus.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/UnaryPlus.kt index e067ec75c28..30205079cfd 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/UnaryPlus.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/UnaryPlus.kt @@ -14,38 +14,34 @@ * limitations under the License. */ -package org.jetbrains.kotlin.codegen.intrinsics; +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 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 java.util.List; +import org.jetbrains.kotlin.codegen.AsmUtil.isPrimitive +import org.jetbrains.kotlin.codegen.CallableMethod +import org.jetbrains.kotlin.codegen.ExtendedCallable -import static org.jetbrains.kotlin.codegen.AsmUtil.isPrimitive; - -public class UnaryPlus extends LazyIntrinsicMethod { - @NotNull - @Override - public StackValue generateImpl( - @NotNull ExpressionCodegen codegen, - @NotNull Type returnType, - @Nullable PsiElement element, - @NotNull List arguments, - @NotNull StackValue receiver - ) { - assert isPrimitive(returnType) : "Return type of UnaryPlus intrinsic should be of primitive type : " + returnType; +public class UnaryPlus : LazyIntrinsicMethod() { + override fun generateImpl(codegen: ExpressionCodegen, returnType: Type, element: PsiElement?, arguments: List, receiver: StackValue): StackValue { + assert(isPrimitive(returnType)) { "Return type of UnaryPlus intrinsic should be of primitive type : " + returnType } if (receiver != StackValue.none()) { - return receiver; + return receiver } else { - assert !arguments.isEmpty(); - return codegen.gen(arguments.get(0)); + assert(!arguments.isEmpty()) + return codegen.gen(arguments.get(0)) + } + } + + override fun toCallable(method: CallableMethod): ExtendedCallable { + return UnaryIntrinsic(method, needPrimitiveCheck = true) { + //nothing } } }