Intrinsic conversion

This commit is contained in:
Michael Bogdanov
2015-04-04 10:41:24 +03:00
parent a5612ec4c0
commit b99ff5c7ae
17 changed files with 613 additions and 528 deletions
@@ -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<JetExpression> 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<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
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<Iterator<Any>>())
}
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<Iterator<Any>>())
} 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;
}
}
}
}
}
}
@@ -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<JetExpression>, 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<JetExpression> 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)
}
}
}
}
@@ -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<JetExpression> 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<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);
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)
}
}
}
@@ -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<JetExpression> arguments,
@NotNull StackValue receiver
) {
JetExpression argument;
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);
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)
}
}
}
@@ -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();
@@ -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<JetExpression>, 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<JetExpression> 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<Array<Any>>())
}
}
override fun supportCallable(): Boolean {
return true
}
override fun toCallable(fd: FunctionDescriptor, isSuper: Boolean, resolvedCall: ResolvedCall<*>, codegen: ExpressionCodegen): ExtendedCallable {
return object : IntrinsicCallable(getType(javaClass<Array<Any>>()), listOf(), null, Type.getType(javaClass<Collection<*>>())) {
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;")
}
}
}
}
@@ -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<JetExpression> 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<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 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)
}
}
}
@@ -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<JetExpression>, 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<JetExpression> 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;
}
}
@@ -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<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
}
public class IteratorNext extends IntrinsicMethod {
@NotNull
@Override
public Type generateImpl(
@NotNull ExpressionCodegen codegen,
@NotNull InstructionAdapter v,
@NotNull Type returnType,
PsiElement element,
@NotNull List<JetExpression> 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;
}
}
@@ -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<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
}
public class JavaClassArray extends IntrinsicMethod {
@NotNull
@Override
public Type generateImpl(
@NotNull ExpressionCodegen codegen,
@NotNull InstructionAdapter v,
@NotNull Type returnType,
@Nullable PsiElement element,
@NotNull List<JetExpression> arguments,
@NotNull StackValue receiver
) {
assert element != null : "Element should not be null";
ResolvedCall<?> resolvedCall = getResolvedCallWithAssert((JetElement) element, codegen.getBindingContext());
Map.Entry<ValueParameterDescriptor, ResolvedValueArgument> 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
}
}
}
@@ -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<JetExpression>, 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<JetExpression> 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<Class<Any>>())
}
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<Class<Any>>()), listOf(), null, null) {
override fun invokeIntrinsic(v: InstructionAdapter) {
codegen.putReifierMarkerIfTypeIsReifiedParameter(javaClass, ReifiedTypeInliner.JAVA_CLASS_MARKER_METHOD_NAME)
putJavaLangClassInstance(v, codegen.getState().getTypeMapper().mapType(javaClass))
}
}
return getType(Class.class);
}
}
@@ -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<JetExpression> 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<JetExpression>, 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<Class<Any>>())
}
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<Class<Any>>()), 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)
}
}
}
}
@@ -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<JetExpression> 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<JetExpression>, 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<ResolvedValueArgument> 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)
}
}
}
}
@@ -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<JetExpression> arguments,
@NotNull StackValue receiver
) {
return codegen.generateNewArray((JetCallExpression) element);
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)
}
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)
}
}
}
}
@@ -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<JetExpression> arguments,
@NotNull StackValue receiver
) {
StackValue stackValue;
public class Not : LazyIntrinsicMethod() {
override 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));
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
}
}
@@ -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<JetExpression> arguments,
@NotNull StackValue receiver
) {
return StackValue.coercion(receiver, returnType);
override fun generateImpl(codegen: ExpressionCodegen, returnType: Type, element: PsiElement?, arguments: List<JetExpression>, receiver: StackValue): StackValue {
return StackValue.coercion(receiver, returnType)
}
override fun toCallable(method: CallableMethod): ExtendedCallable {
return UnaryIntrinsic(method) {
StackValue.coerce(calcReceiverType()!!, getReturnType(), it)
}
}
}
@@ -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<JetExpression> 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<JetExpression>, 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
}
}
}