intrinsics java->kt file renaming

This commit is contained in:
Michael Bogdanov
2015-04-04 10:36:55 +03:00
parent c1ab7f06f7
commit a5612ec4c0
38 changed files with 388 additions and 58 deletions
@@ -359,7 +359,7 @@ public class AsmUtil {
return null;
}
private static Type stringValueOfType(Type type) {
public static Type stringValueOfType(Type type) {
int sort = type.getSort();
return sort == Type.OBJECT || sort == Type.ARRAY
? OBJECT_TYPE
@@ -525,7 +525,7 @@ public class AsmUtil {
public Unit invoke(InstructionAdapter v) {
left.put(leftType, v);
right.put(rightType, v);
v.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, "areEqual", "(Ljava/lang/Object;Ljava/lang/Object;)Z", false);
genAreEqualCall(v);
if (opToken == JetTokens.EXCLEQ || opToken == JetTokens.EXCLEQEQEQ) {
genInvertBoolean(v);
@@ -535,6 +535,10 @@ public class AsmUtil {
});
}
public static void genAreEqualCall(InstructionAdapter v) {
v.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, "areEqual", "(Ljava/lang/Object;Ljava/lang/Object;)Z");
}
public static void genIncrement(Type expectedType, int myDelta, InstructionAdapter v) {
if (expectedType == Type.LONG_TYPE) {
v.lconst(myDelta);
@@ -35,7 +35,7 @@ public abstract class CallGenerator {
@Override
public void genCallInner(
@NotNull CallableMethod callableMethod,
@NotNull ExtendedCallable callableMethod,
ResolvedCall<?> resolvedCall,
boolean callDefault,
@NotNull ExpressionCodegen codegen
@@ -44,7 +44,7 @@ public abstract class CallGenerator {
callableMethod.invokeWithNotNullAssertion(codegen.v, codegen.getState(), resolvedCall);
}
else {
callableMethod.invokeDefaultWithNotNullAssertion(codegen.v, codegen.getState(), resolvedCall);
((CallableMethod)callableMethod).invokeDefaultWithNotNullAssertion(codegen.v, codegen.getState(), resolvedCall);
}
}
@@ -90,7 +90,7 @@ public abstract class CallGenerator {
}
}
public void genCall(@NotNull CallableMethod callableMethod, @Nullable ResolvedCall<?> resolvedCall, boolean callDefault, @NotNull ExpressionCodegen codegen) {
public void genCall(@NotNull ExtendedCallable callableMethod, @Nullable ResolvedCall<?> resolvedCall, boolean callDefault, @NotNull ExpressionCodegen codegen) {
if (resolvedCall != null) {
JetExpression calleeExpression = resolvedCall.getCall().getCalleeExpression();
if (calleeExpression != null) {
@@ -101,7 +101,7 @@ public abstract class CallGenerator {
genCallInner(callableMethod, resolvedCall, callDefault, codegen);
}
public abstract void genCallInner(@NotNull CallableMethod callableMethod, @Nullable ResolvedCall<?> resolvedCall, boolean callDefault, @NotNull ExpressionCodegen codegen);
public abstract void genCallInner(@NotNull ExtendedCallable callableMethod, @Nullable ResolvedCall<?> resolvedCall, boolean callDefault, @NotNull ExpressionCodegen codegen);
public abstract void genCallWithoutAssertions(@NotNull CallableMethod callableMethod, @NotNull ExpressionCodegen codegen);
@@ -16,5 +16,10 @@
package org.jetbrains.kotlin.codegen;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.org.objectweb.asm.Type;
public interface Callable {
}
@@ -78,6 +78,7 @@ public class CallableMethod implements ExtendedCallable {
return signature.getValueParameters();
}
@Override
@NotNull
public List<Type> getValueParameterTypes() {
List<JvmMethodParameterSignature> valueParameters = signature.getValueParameters();
@@ -95,15 +96,18 @@ public class CallableMethod implements ExtendedCallable {
return signature.getAsmMethod();
}
@Override
public Type[] getArgumentTypes() {
return signature.getAsmMethod().getArgumentTypes();
}
@Override
@Nullable
public Type getThisType() {
return thisClass;
}
@Override
@Nullable
public Type getReceiverClass() {
return receiverParameterType;
@@ -2252,14 +2252,14 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
}
FunctionDescriptor accessibleFunctionDescriptor = accessibleFunctionDescriptor(fd);
final Callable callable = resolveToCallable(accessibleFunctionDescriptor, superCall);
final Callable callable = resolveToCallable(accessibleFunctionDescriptor, superCall, resolvedCall);
final Type returnType = typeMapper.mapReturnType(accessibleFunctionDescriptor);
if (callable instanceof CallableMethod) {
if (callable instanceof ExtendedCallable) {
return StackValue.functionCall(returnType, new Function1<InstructionAdapter, Unit>() {
@Override
public Unit invoke(InstructionAdapter v) {
CallableMethod callableMethod = (CallableMethod) callable;
ExtendedCallable callableMethod = (ExtendedCallable) callable;
invokeMethodWithArguments(callableMethod, resolvedCall, receiver);
StackValue.coerce(callableMethod.getReturnType(), returnType, v);
@@ -2305,10 +2305,10 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
}
@NotNull
Callable resolveToCallable(@NotNull FunctionDescriptor fd, boolean superCall) {
Callable resolveToCallable(@NotNull FunctionDescriptor fd, boolean superCall, @NotNull ResolvedCall resolvedCall) {
IntrinsicMethod intrinsic = state.getIntrinsics().getIntrinsic(fd);
if (intrinsic != null) {
return intrinsic;
return !intrinsic.supportCallable() ? intrinsic : intrinsic.toCallable(fd, superCall, resolvedCall, this);
}
return resolveToCallableMethod(fd, superCall, context);
@@ -2320,7 +2320,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
}
public void invokeMethodWithArguments(
@NotNull CallableMethod callableMethod,
@NotNull ExtendedCallable callableMethod,
@NotNull ResolvedCall<?> resolvedCall,
@NotNull StackValue receiver
) {
@@ -2341,7 +2341,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
}
public void invokeMethodWithArguments(
@NotNull CallableMethod callableMethod,
@NotNull ExtendedCallable callableMethod,
@NotNull ResolvedCall<?> resolvedCall,
@NotNull StackValue receiver,
@NotNull CallGenerator callGenerator,
@@ -3010,7 +3010,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
return generateConstructorCall(resolvedCall, expressionType(expression));
}
Callable callable = resolveToCallable(descriptor, false);
Callable callable = resolveToCallable(descriptor, false, resolvedCall);
if (callable instanceof IntrinsicMethod) {
Type returnType = typeMapper.mapType(descriptor);
return ((IntrinsicMethod) callable).generate(this, returnType, expression,
@@ -3255,7 +3255,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
JetExpression left = expression.getLeft();
JetExpression right = expression.getRight();
Callable callable = resolveToCallable(descriptor, false);
Callable callable = resolveToCallable(descriptor, false, resolvedCall);
Type type;
StackValue leftValue;
@@ -3285,7 +3285,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
private StackValue generateAugmentedAssignment(JetBinaryExpression expression) {
ResolvedCall<?> resolvedCall = getResolvedCallWithAssert(expression, bindingContext);
FunctionDescriptor descriptor = (FunctionDescriptor) resolvedCall.getResultingDescriptor();
Callable callable = resolveToCallable(descriptor, false);
Callable callable = resolveToCallable(descriptor, false, resolvedCall);
JetExpression lhs = expression.getLeft();
Type lhsType = expressionType(lhs);
@@ -3310,7 +3310,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
keepReturnValue = !KotlinBuiltIns.getInstance().getUnitType().equals(descriptor.getReturnType());
}
callAugAssignMethod(expression, resolvedCall, (CallableMethod) callable, lhsType, keepReturnValue);
callAugAssignMethod(expression, resolvedCall, (ExtendedCallable) callable, lhsType, keepReturnValue);
return StackValue.none();
}
@@ -3318,7 +3318,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
private void callAugAssignMethod(
@NotNull JetBinaryExpression expression,
@NotNull ResolvedCall<?> resolvedCall,
@NotNull CallableMethod callable,
@NotNull ExtendedCallable callable,
@NotNull Type lhsType,
boolean keepReturnValue
) {
@@ -3379,7 +3379,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
CallableDescriptor op = resolvedCall.getResultingDescriptor();
assert op instanceof FunctionDescriptor || originalOperation == null : String.valueOf(op);
Callable callable = resolveToCallable((FunctionDescriptor) op, false);
Callable callable = resolveToCallable((FunctionDescriptor) op, false, resolvedCall);
if (callable instanceof IntrinsicMethod) {
Type returnType = typeMapper.mapType(op);
return ((IntrinsicMethod) callable).generate(this, returnType, expression,
@@ -3674,8 +3674,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
boolean isGetter = "get".equals(operationDescriptor.getName().asString());
Callable callable = resolveToCallable(operationDescriptor, false);
CallableMethod callableMethod = resolveToCallableMethod(operationDescriptor, false, context);
Callable callable = resolveToCallable(operationDescriptor, false, isGetter ? resolvedGetCall : resolvedSetCall );
ExtendedCallable callableMethod = resolveToCallableMethod(operationDescriptor, false, context);
Type[] argumentTypes = callableMethod.getArgumentTypes();
StackValue collectionElementReceiver =
@@ -3689,23 +3689,23 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
}
private StackValue createCollectionElementReceiver(
JetArrayAccessExpression expression,
StackValue receiver,
JetExpression array,
Type arrayType,
FunctionDescriptor operationDescriptor,
@NotNull JetArrayAccessExpression expression,
@NotNull StackValue receiver,
@NotNull JetExpression array,
@NotNull Type arrayType,
@NotNull FunctionDescriptor operationDescriptor,
boolean isGetter,
ResolvedCall<FunctionDescriptor> resolvedGetCall,
ResolvedCall<FunctionDescriptor> resolvedGetCall,
ResolvedCall<FunctionDescriptor> resolvedSetCall,
Callable callable,
Type[] argumentTypes
@NotNull Callable callable,
@NotNull Type[] argumentTypes
) {
ResolvedCall<FunctionDescriptor> resolvedCall = isGetter ? resolvedGetCall : resolvedSetCall;
assert resolvedCall != null : "couldn't find resolved call: " + expression.getText();
if (callable instanceof CallableMethod) {
CallableMethod callableMethod = (CallableMethod) callable;
if (callable instanceof ExtendedCallable) {
ExtendedCallable callableMethod = (ExtendedCallable) callable;
ArgumentGenerator argumentGenerator =
new CallBasedArgumentGenerator(this, defaultCallGenerator,
resolvedCall.getResultingDescriptor().getValueParameters(),
@@ -23,6 +23,8 @@ 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 interface ExtendedCallable extends Callable {
@NotNull
Type getOwner();
@@ -38,9 +40,19 @@ public interface ExtendedCallable extends Callable {
@Nullable
Type getGenerateCalleeType();
@NotNull
List<Type> getValueParameterTypes();
Type[] getArgumentTypes();
@NotNull
Type getReturnType();
boolean isStaticCall();
@Nullable
Type getThisType();
@Nullable
Type getReceiverClass();
}
@@ -28,7 +28,6 @@ import org.jetbrains.kotlin.codegen.stackvalue.BranchedValue;
import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.lexer.JetTokens;
import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.psi.JetArrayAccessExpression;
import org.jetbrains.kotlin.psi.JetExpression;
@@ -41,7 +40,6 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.org.objectweb.asm.Label;
import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
import org.jetbrains.org.objectweb.asm.commons.Method;
import java.util.Collections;
import java.util.List;
@@ -429,7 +427,7 @@ public abstract class StackValue {
ResolvedCall<?> resolvedCall,
StackValue receiver,
ExpressionCodegen codegen,
@Nullable CallableMethod callableMethod
@Nullable ExtendedCallable callableMethod
) {
if (resolvedCall.getDispatchReceiver().exists() || resolvedCall.getExtensionReceiver().exists() || isLocalFunCall(callableMethod)) {
boolean hasExtensionReceiver = resolvedCall.getExtensionReceiver().exists();
@@ -448,7 +446,7 @@ public abstract class StackValue {
@NotNull StackValue receiver,
@NotNull ExpressionCodegen codegen,
@NotNull ResolvedCall resolvedCall,
@Nullable CallableMethod callableMethod,
@Nullable ExtendedCallable callableMethod,
boolean isExtension
) {
ReceiverValue receiverValue = isExtension ? resolvedCall.getExtensionReceiver() : resolvedCall.getDispatchReceiver();
@@ -482,7 +480,7 @@ public abstract class StackValue {
}
@Contract("null -> false")
private static boolean isLocalFunCall(@Nullable CallableMethod callableMethod) {
private static boolean isLocalFunCall(@Nullable ExtendedCallable callableMethod) {
return callableMethod != null && callableMethod.getGenerateCalleeType() != null;
}
@@ -662,12 +660,12 @@ public abstract class StackValue {
private final ResolvedCall<FunctionDescriptor> resolvedSetCall;
public CollectionElementReceiver(
Callable callable,
StackValue receiver,
@NotNull Callable callable,
@NotNull StackValue receiver,
ResolvedCall<FunctionDescriptor> resolvedGetCall,
ResolvedCall<FunctionDescriptor> resolvedSetCall,
boolean isGetter,
ExpressionCodegen codegen,
@NotNull ExpressionCodegen codegen,
ArgumentGenerator argumentGenerator,
List<ResolvedValueArgument> valueArguments,
JetExpression array,
@@ -697,8 +695,8 @@ public abstract class StackValue {
@NotNull Type type, @NotNull InstructionAdapter v
) {
ResolvedCall<?> call = isGetter ? resolvedGetCall : resolvedSetCall;
if (callable instanceof CallableMethod) {
StackValue newReceiver = StackValue.receiver(call, receiver, codegen, (CallableMethod) callable);
if (callable instanceof ExtendedCallable) {
StackValue newReceiver = StackValue.receiver(call, receiver, codegen, (ExtendedCallable) callable);
newReceiver.put(newReceiver.type, v);
argumentGenerator.generate(valueArguments);
}
@@ -864,8 +862,8 @@ public abstract class StackValue {
this.state = state;
this.setterDescriptor = resolvedSetCall == null ? null : resolvedSetCall.getResultingDescriptor();
this.getterDescriptor = resolvedGetCall == null ? null : resolvedGetCall.getResultingDescriptor();
this.setter = resolvedSetCall == null ? null : codegen.resolveToCallable(setterDescriptor, false);
this.getter = resolvedGetCall == null ? null : codegen.resolveToCallable(getterDescriptor, false);
this.setter = resolvedSetCall == null ? null : codegen.resolveToCallable(setterDescriptor, false, resolvedSetCall);
this.getter = resolvedGetCall == null ? null : codegen.resolveToCallable(getterDescriptor, false, resolvedGetCall);
this.codegen = codegen;
}
@@ -874,8 +872,8 @@ public abstract class StackValue {
if (getter == null) {
throw new UnsupportedOperationException("no getter specified");
}
if (getter instanceof CallableMethod) {
((CallableMethod) getter).invokeWithNotNullAssertion(v, state, resolvedGetCall);
if (getter instanceof ExtendedCallable) {
((ExtendedCallable) getter).invokeWithNotNullAssertion(v, state, resolvedGetCall);
}
else {
StackValue result = ((IntrinsicMethod) getter).generate(codegen, this.type, null, Collections.<JetExpression>emptyList(), StackValue.none());
@@ -930,8 +928,8 @@ public abstract class StackValue {
if (setter == null) {
throw new UnsupportedOperationException("no setter specified");
}
if (setter instanceof CallableMethod) {
CallableMethod method = (CallableMethod) setter;
if (setter instanceof ExtendedCallable) {
ExtendedCallable method = (ExtendedCallable) setter;
Type[] argumentTypes = method.getArgumentTypes();
coerce(topOfStackType, argumentTypes[argumentTypes.length - 1], v);
method.invokeWithNotNullAssertion(v, state, resolvedSetCall);
@@ -1230,7 +1228,7 @@ public abstract class StackValue {
value = StackValue.complexReceiver(value, true, false, true);
value.put(this.type, v);
if (callable instanceof CallableMethod) {
if (callable instanceof ExtendedCallable) {
value.store(codegen.invokeFunction(resolvedCall, StackValue.onStack(this.type)), v, true);
}
else {
@@ -1260,7 +1258,7 @@ public abstract class StackValue {
public static Type calcType(
@NotNull ResolvedCall<?> resolvedCall,
@NotNull JetTypeMapper typeMapper,
@Nullable CallableMethod callableMethod
@Nullable ExtendedCallable callableMethod
) {
CallableDescriptor descriptor = resolvedCall.getResultingDescriptor();
@@ -67,7 +67,7 @@ public class TailRecursionCodegen {
public void generateTailRecursion(ResolvedCall<?> resolvedCall) {
CallableDescriptor fd = resolvedCall.getResultingDescriptor();
assert fd instanceof FunctionDescriptor : "Resolved call doesn't refer to the function descriptor: " + fd;
CallableMethod callable = (CallableMethod) codegen.resolveToCallable((FunctionDescriptor) fd, false);
CallableMethod callable = (CallableMethod) codegen.resolveToCallable((FunctionDescriptor) fd, false, resolvedCall);
List<ResolvedValueArgument> arguments = resolvedCall.getValueArgumentsByIndex();
if (arguments == null) {
@@ -125,7 +125,7 @@ public class InlineCodegen extends CallGenerator {
}
@Override
public void genCallInner(@NotNull CallableMethod callableMethod, @Nullable ResolvedCall<?> resolvedCall, boolean callDefault, @NotNull ExpressionCodegen codegen) {
public void genCallInner(@NotNull ExtendedCallable callableMethod, @Nullable ResolvedCall<?> resolvedCall, boolean callDefault, @NotNull ExpressionCodegen codegen) {
SMAPAndMethodNode nodeAndSmap = null;
try {
@@ -17,11 +17,16 @@
package org.jetbrains.kotlin.codegen.intrinsics;
import com.intellij.psi.PsiElement;
import kotlin.ExtensionFunction1;
import kotlin.Unit;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.codegen.CallableMethod;
import org.jetbrains.kotlin.codegen.ExpressionCodegen;
import org.jetbrains.kotlin.codegen.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;
@@ -48,4 +53,20 @@ public class ArrayGet extends LazyIntrinsicMethod {
Type type = correctElementType(receiver.type);
return StackValue.arrayElement(type, receiver, StackValue.coercion(codegen.gen(arguments.get(argumentIndex)), Type.INT_TYPE));
}
@NotNull
@Override
public ExtendedCallable toCallable(@NotNull CallableMethod method) {
return new MappedCallable(method, new ExtensionFunction1<MappedCallable, InstructionAdapter, Unit>() {
@Override
public Unit invoke(
MappedCallable callable,
InstructionAdapter adapter
) {
Type type = correctElementType(callable.calcReceiverType());
adapter.aload(type);
return Unit.INSTANCE$;
}
});
}
}
@@ -17,8 +17,10 @@
package org.jetbrains.kotlin.codegen.intrinsics
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.kotlin.codegen.ExpressionCodegen
import org.jetbrains.kotlin.codegen.ExtendedCallable
import org.jetbrains.kotlin.codegen.StackValue
import org.jetbrains.kotlin.psi.JetExpression
@@ -35,4 +37,10 @@ public class ArraySize : LazyIntrinsicMethod() {
it.arraylength()
}
}
public override fun toCallable(method: CallableMethod): ExtendedCallable {
return UnaryIntrinsic(method, null, false) { adapter ->
adapter.arraylength()
}
}
}
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.codegen.intrinsics
import com.google.common.collect.Lists
import com.intellij.psi.PsiElement
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
@@ -25,6 +26,11 @@ import org.jetbrains.kotlin.psi.JetExpression
import org.jetbrains.org.objectweb.asm.Opcodes.*
import org.jetbrains.kotlin.codegen.AsmUtil.isPrimitive
import org.jetbrains.kotlin.codegen.AsmUtil.numberFunctionOperandType
import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.kotlin.codegen.ExtendedCallable
import org.jetbrains.kotlin.codegen.context.CodegenContext
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
public class BinaryOp(private val opcode: Int) : IntrinsicMethod() {
@@ -51,4 +57,19 @@ public class BinaryOp(private val opcode: Int) : IntrinsicMethod() {
private fun shift(): Boolean {
return opcode == ISHL || opcode == ISHR || opcode == IUSHR
}
public override fun supportCallable(): Boolean {
return true
}
override fun toCallable(method: CallableMethod): ExtendedCallable {
val returnType = method.getReturnType()
assert(method.getValueParameters().size() == 1)
val operandType = numberFunctionOperandType(returnType)
val paramType = if (shift()) Type.INT_TYPE else operandType
return IntrinsicCallable.binaryIntrinsic(operandType, paramType, operandType) {
v -> v.visitInsn(getReturnType().getOpcode(opcode))
}
}
}
@@ -17,9 +17,8 @@
package org.jetbrains.kotlin.codegen.intrinsics
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.codegen.*
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.kotlin.codegen.ExpressionCodegen
import org.jetbrains.kotlin.codegen.StackValue
import org.jetbrains.kotlin.psi.JetCallExpression
import org.jetbrains.kotlin.psi.JetExpression
import org.jetbrains.kotlin.lexer.JetTokens
@@ -48,4 +47,11 @@ public class Equals : LazyIntrinsicMethod() {
return genEqualsForExpressionsOnStack(JetTokens.EQEQ, leftExpr, codegen.genLazy(rightExpr, OBJECT_TYPE))
}
override fun toCallable(method: CallableMethod): ExtendedCallable {
return IntrinsicCallable.binaryIntrinsic(method.getReturnType(), OBJECT_TYPE, nullOrObject(method.getThisType()), nullOrObject(method.getReceiverClass())) {
AsmUtil.genAreEqualCall(it)
}
}
}
@@ -17,12 +17,15 @@
package org.jetbrains.kotlin.codegen.intrinsics
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.kotlin.codegen.ExpressionCodegen
import org.jetbrains.kotlin.codegen.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.commons.InstructionAdapter
public class HashCode : LazyIntrinsicMethod() {
override fun generateImpl(
@@ -37,4 +40,12 @@ public class HashCode : LazyIntrinsicMethod() {
it.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "hashCode", "()I", false)
}
}
override fun toCallable(method: CallableMethod): ExtendedCallable {
return object: IntrinsicCallable(Type.INT_TYPE, emptyList(), nullOrObject(method.getThisType()), nullOrObject(method.getReceiverClass())) {
override fun invokeIntrinsic(v: InstructionAdapter) {
v.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "hashCode", "()I", false)
}
}
}
}
@@ -23,6 +23,8 @@ import org.jetbrains.kotlin.psi.JetExpression
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.kotlin.codegen.AsmUtil.genIncrement
import org.jetbrains.kotlin.codegen.AsmUtil.isPrimitive
import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.kotlin.codegen.ExtendedCallable
public class Increment(private val myDelta: Int) : LazyIntrinsicMethod() {
@@ -46,4 +48,8 @@ public class Increment(private val myDelta: Int) : LazyIntrinsicMethod() {
}
}
}
override fun supportCallable(): Boolean {
return false
}
}
@@ -0,0 +1,141 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.codegen.intrinsics
import org.jetbrains.kotlin.codegen.AsmUtil
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.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
public abstract class IntrinsicCallable(val returnType1: Type,
val valueParametersTypes: List<Type>,
val thisType1: Type?,
val receiverType1: Type?) : ExtendedCallable {
companion object {
fun create(descriptor: FunctionDescriptor, context: CodegenContext<*>, state: GenerationState, lambda: IntrinsicCallable.(i: InstructionAdapter) -> Unit): IntrinsicCallable {
return create(state.getTypeMapper().mapToCallableMethod(descriptor, false, context), lambda)
}
fun create(callableMethod: CallableMethod, lambda: IntrinsicCallable.(i: InstructionAdapter) -> Unit): IntrinsicCallable {
return object : IntrinsicCallable(callableMethod.getReturnType(), callableMethod.getValueParameterTypes(), callableMethod.getThisType(), callableMethod.getReceiverClass()) {
override fun invokeIntrinsic(v: InstructionAdapter) {
lambda(v)
}
}
}
fun binaryIntrinsic(returnType: Type, valueParameterType: Type, thisType: Type? = null, receiverType: Type? = null, lambda: IntrinsicCallable.(i: InstructionAdapter) -> Unit): IntrinsicCallable {
assert(AsmUtil.isPrimitive(returnType)) { "Return type of BinaryOp intrinsic should be of primitive type : " + returnType }
return object : IntrinsicCallable(returnType, listOf(valueParameterType), thisType, receiverType) {
override fun invokeIntrinsic(v: InstructionAdapter) {
lambda(v)
}
}
}
fun create(descriptor: FunctionDescriptor, context: CodegenContext<*>, state: GenerationState, receiverTransformer: Type.() -> Type, lambda: IntrinsicCallable.(i: InstructionAdapter) -> Unit): IntrinsicCallable {
val callableMethod = state.getTypeMapper().mapToCallableMethod(descriptor, false, context)
return object : IntrinsicCallable(callableMethod.getReturnType(), callableMethod.getValueParameterTypes(), callableMethod.getThisType()?.receiverTransformer(), callableMethod.getReceiverClass()?.receiverTransformer()) {
override fun invokeIntrinsic(v: InstructionAdapter) {
lambda(v)
}
}
}
}
override fun getValueParameterTypes(): List<Type> {
return valueParametersTypes
}
override fun invokeWithoutAssertions(v: InstructionAdapter) {
invokeIntrinsic(v)
}
override fun invokeWithNotNullAssertion(v: InstructionAdapter, state: GenerationState, resolvedCall: ResolvedCall<out CallableDescriptor>) {
invokeWithoutAssertions(v)
}
public abstract fun invokeIntrinsic(v: InstructionAdapter);
override fun getArgumentTypes(): Array<out Type>? {
throw UnsupportedOperationException()
}
override fun isStaticCall(): Boolean {
return false
}
override fun getGenerateCalleeType(): Type? {
return null
}
override fun getReturnType(): Type {
return returnType1
}
override fun getThisType(): Type? {
return thisType1
}
override fun getReceiverClass(): Type? {
return receiverType1
}
override fun getOwner(): Type {
throw UnsupportedOperationException()
}
public fun calcReceiverType(): Type? {
return getReceiverClass() ?: getThisType()
}
}
public class UnaryIntrinsic(val callable: CallableMethod, val newReturnType: Type? = null, needPrimitiveCheck: Boolean = false, val newThisType: Type? = null, val invoke: UnaryIntrinsic.(v: InstructionAdapter) -> Unit) :
IntrinsicCallable(newReturnType ?: callable.getReturnType(), callable.getValueParameterTypes(), newThisType ?: callable.getThisType(), callable.getReceiverClass()) {
{
if (needPrimitiveCheck) {
assert(AsmUtil.isPrimitive(getReturnType())) { "Return type of UnaryPlus intrinsic should be of primitive type : " + getReturnType() }
}
assert(getValueParameterTypes().size == 0, "Unary operation should not have any parameters")
}
override fun invokeIntrinsic(v: InstructionAdapter) {
invoke(v)
}
}
public open class MappedCallable(val callable: CallableMethod, val invoke: MappedCallable.(v: InstructionAdapter) -> Unit = {}) :
IntrinsicCallable(callable.getReturnType(), callable.getValueParameterTypes(), callable.getThisType(), callable.getReceiverClass()) {
override fun invokeIntrinsic(v: InstructionAdapter) {
invoke(v)
}
}
@@ -16,20 +16,27 @@
package org.jetbrains.kotlin.codegen.intrinsics;
import com.google.common.base.Function;
import com.google.common.collect.Lists;
import com.intellij.psi.PsiElement;
import kotlin.Function1;
import kotlin.Unit;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.codegen.Callable;
import org.jetbrains.kotlin.codegen.ExpressionCodegen;
import org.jetbrains.kotlin.codegen.StackValue;
import org.jetbrains.kotlin.codegen.*;
import org.jetbrains.kotlin.codegen.context.CodegenContext;
import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
import org.jetbrains.kotlin.psi.JetExpression;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
import org.jetbrains.kotlin.resolve.jvm.AsmTypes;
import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
import java.util.List;
import static org.jetbrains.kotlin.codegen.AsmUtil.numberFunctionOperandType;
public abstract class IntrinsicMethod implements Callable {
public StackValue generate(
@NotNull final ExpressionCodegen codegen,
@@ -57,4 +64,47 @@ public abstract class IntrinsicMethod implements Callable {
@NotNull List<JetExpression> arguments,
@NotNull StackValue receiver
);
public boolean supportCallable() {
return false;
}
@NotNull
public ExtendedCallable toCallable(@NotNull FunctionDescriptor fd, boolean isSuper, @NotNull ResolvedCall resolvedCall, @NotNull ExpressionCodegen codegen) {
return toCallable(codegen.getState(), fd, codegen.getContext(), isSuper, resolvedCall);
}
@NotNull
public ExtendedCallable toCallable(@NotNull GenerationState state, @NotNull FunctionDescriptor fd, @NotNull CodegenContext<?> context, boolean isSuper, @NotNull
ResolvedCall resolvedCall) {
return toCallable(state, fd, context, isSuper);
}
@NotNull
public ExtendedCallable toCallable(@NotNull GenerationState state, @NotNull FunctionDescriptor fd, @NotNull CodegenContext<?> context, boolean isSuper) {
return toCallable(state.getTypeMapper().mapToCallableMethod(fd, false, context), isSuper);
}
@NotNull
public ExtendedCallable toCallable(@NotNull CallableMethod method, boolean isSuperCall) {
//assert !isSuper;
return toCallable(method);
}
@NotNull
public ExtendedCallable toCallable(@NotNull CallableMethod method) {
throw new UnsupportedOperationException("Not implemented");
}
public List<Type> transformTypes(List<Type> types) {
return Lists.transform(types, new Function<Type, Type>() {
@Override
public Type apply(Type input) {
return numberFunctionOperandType(input);
}
});
}
public Type nullOrObject(Type type) {
return type == null ? null : AsmTypes.OBJECT_TYPE;
}
}
@@ -60,4 +60,9 @@ public abstract class LazyIntrinsicMethod extends IntrinsicMethod {
@NotNull List<JetExpression> arguments,
@NotNull StackValue receiver
);
@Override
public boolean supportCallable() {
return true;
}
}
@@ -17,9 +17,14 @@
package org.jetbrains.kotlin.codegen.intrinsics
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.kotlin.codegen.ExpressionCodegen
import org.jetbrains.kotlin.codegen.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
public class StringGetChar : LazyIntrinsicMethod() {
@@ -40,4 +45,10 @@ public class StringGetChar : LazyIntrinsicMethod() {
it.invokevirtual("java/lang/String", "charAt", "(I)C", false)
}
}
override fun toCallable(method: CallableMethod): ExtendedCallable {
return IntrinsicCallable.create(method) {
it.invokevirtual("java/lang/String", "charAt", "(I)C", false)
}
}
}
@@ -17,7 +17,9 @@
package org.jetbrains.kotlin.codegen.intrinsics
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.kotlin.codegen.ExpressionCodegen
import org.jetbrains.kotlin.codegen.ExtendedCallable
import org.jetbrains.kotlin.codegen.StackValue
import org.jetbrains.kotlin.psi.JetExpression
import org.jetbrains.org.objectweb.asm.Type
@@ -44,4 +46,11 @@ public class StringPlus : LazyIntrinsicMethod() {
it.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, "stringPlus", "(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/String;", false)
}
}
override fun toCallable(method: CallableMethod): ExtendedCallable {
return IntrinsicCallable.create(method) {
it.invokestatic("kotlin/jvm/internal/Intrinsics", "stringPlus", "(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/String;", false)
}
}
}
@@ -17,10 +17,12 @@
package org.jetbrains.kotlin.codegen.intrinsics
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.codegen.*
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.kotlin.codegen.ExpressionCodegen
import org.jetbrains.kotlin.codegen.StackValue
import org.jetbrains.kotlin.codegen.AsmUtil.genToString
import org.jetbrains.kotlin.codegen.context.CodegenContext
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.psi.JetExpression
public class ToString : LazyIntrinsicMethod() {
@@ -33,4 +35,11 @@ public class ToString : LazyIntrinsicMethod() {
): StackValue {
return genToString(receiver, receiver.type)
}
override fun toCallable(method: CallableMethod): ExtendedCallable {
val type = AsmUtil.stringValueOfType(method.getThisType() ?: method.getReceiverClass())
return UnaryIntrinsic(method, newThisType = type) {
it.invokestatic("java/lang/String", "valueOf", "(" + type.getDescriptor() + ")Ljava/lang/String;", false)
}
}
}
@@ -17,10 +17,13 @@
package org.jetbrains.kotlin.codegen.intrinsics
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.codegen
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.kotlin.codegen.ExpressionCodegen
import org.jetbrains.kotlin.codegen.StackValue
import org.jetbrains.kotlin.codegen.AsmUtil.*
import org.jetbrains.kotlin.codegen.CallableMethod
import org.jetbrains.kotlin.codegen.ExtendedCallable
import org.jetbrains.kotlin.psi.JetExpression
public class UnaryMinus : LazyIntrinsicMethod() {
@@ -42,4 +45,10 @@ public class UnaryMinus : LazyIntrinsicMethod() {
it.neg(operandType)
}
}
override fun toCallable(method: CallableMethod): ExtendedCallable {
return UnaryIntrinsic(method, numberFunctionOperandType(method.getReturnType()), needPrimitiveCheck = true) {
it.neg(getReturnType())
}
}
}