diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/CallableMethod.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/CallableMethod.java index 0a4a8eab4c6..cc4768b900d 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/CallableMethod.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/CallableMethod.java @@ -16,6 +16,8 @@ package org.jetbrains.kotlin.codegen; +import kotlin.Function1; +import kotlin.Unit; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.codegen.state.GenerationState; @@ -186,4 +188,19 @@ public class CallableMethod implements ExtendedCallable { public void beforeParameterGeneration(@NotNull InstructionAdapter v, @Nullable StackValue value) { } + + @NotNull + @Override + public StackValue invokeMethodWithArguments( + @NotNull final ResolvedCall resolvedCall, @NotNull final StackValue receiver, @NotNull final Type returnType, + @NotNull final ExpressionCodegen codegen + ) { + return StackValue.functionCall(returnType, new Function1() { + @Override + public Unit invoke(InstructionAdapter v) { + codegen.invokeMethodWithArguments(CallableMethod.this, resolvedCall, receiver, returnType); + return Unit.INSTANCE$; + } + }); + } } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index 18af05c942f..13bb894ac1a 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -36,10 +36,7 @@ import org.jetbrains.kotlin.codegen.binding.CalculatedClosure; import org.jetbrains.kotlin.codegen.context.*; import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension; import org.jetbrains.kotlin.codegen.inline.*; -import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethod; -import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods; -import org.jetbrains.kotlin.codegen.intrinsics.JavaClassProperty; -import org.jetbrains.kotlin.codegen.intrinsics.Not; +import org.jetbrains.kotlin.codegen.intrinsics.*; import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter; import org.jetbrains.kotlin.codegen.stackvalue.BranchedValue; import org.jetbrains.kotlin.codegen.state.GenerationState; @@ -2255,20 +2252,11 @@ public class ExpressionCodegen extends JetVisitor implem } FunctionDescriptor accessibleFunctionDescriptor = accessibleFunctionDescriptor(fd); - final Callable callable = resolveToCallable(accessibleFunctionDescriptor, superCall, resolvedCall); - final Type returnType = typeMapper.mapReturnType(accessibleFunctionDescriptor); + Callable callable = resolveToCallable(accessibleFunctionDescriptor, superCall, resolvedCall); + Type returnType = typeMapper.mapReturnType(accessibleFunctionDescriptor); if (callable instanceof ExtendedCallable) { - return StackValue.functionCall(returnType, new Function1() { - @Override - public Unit invoke(InstructionAdapter v) { - ExtendedCallable callableMethod = (ExtendedCallable) callable; - invokeMethodWithArguments(callableMethod, resolvedCall, receiver); - - StackValue.coerce(callableMethod.getReturnType(), returnType, v); - return Unit.INSTANCE$; - } - }); + return ((ExtendedCallable) callable).invokeMethodWithArguments(resolvedCall, receiver, returnType, this); } else { StackValue newReceiver = StackValue.receiver(resolvedCall, receiver, this, null); @@ -2282,6 +2270,16 @@ public class ExpressionCodegen extends JetVisitor implem } } + public void invokeMethodWithArguments( + @NotNull ExtendedCallable callable, + @NotNull ResolvedCall resolvedCall, + @NotNull StackValue receiver, + @NotNull Type returnType + ) { + invokeMethodWithArguments(callable, resolvedCall, receiver); + StackValue.coerce(callable.getReturnType(), returnType, v); + } + @Nullable private static JetSuperExpression getSuperCallExpression(@NotNull Call call) { ReceiverValue explicitReceiver = call.getExplicitReceiver(); @@ -3390,15 +3388,7 @@ public class ExpressionCodegen extends JetVisitor implem CallableDescriptor op = resolvedCall.getResultingDescriptor(); assert op instanceof FunctionDescriptor || originalOperation == null : String.valueOf(op); - Callable callable = resolveToCallable((FunctionDescriptor) op, false, resolvedCall); String operationName = originalOperation == null ? "" : originalOperation.getName().asString(); - if (callable instanceof Not) { - Type returnType = typeMapper.mapType(op); - return ((Not) callable).generate(this, returnType, expression, - Collections.singletonList(expression.getBaseExpression()), receiver); - } - - if (!(operationName.equals("inc") || operationName.equals("dec"))) { return invokeFunction(resolvedCall, receiver); } @@ -3406,6 +3396,7 @@ public class ExpressionCodegen extends JetVisitor implem int increment = operationName.equals("inc") ? 1 : -1; Type type = expressionType(expression.getBaseExpression()); StackValue value = gen(expression.getBaseExpression()); + Callable callable = resolveToCallable((FunctionDescriptor) op, false, resolvedCall); return StackValue.preIncrement(type, value, increment, callable, resolvedCall, this); } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExtendedCallable.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExtendedCallable.java index 73bd8f63508..46efb63b4a5 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExtendedCallable.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExtendedCallable.java @@ -59,4 +59,12 @@ public interface ExtendedCallable extends Callable { void beforeParameterGeneration(@NotNull InstructionAdapter v, @Nullable StackValue value); + @NotNull + StackValue invokeMethodWithArguments( + @NotNull ResolvedCall resolvedCall, + @NotNull StackValue receiver, + @NotNull Type returnType, + @NotNull ExpressionCodegen codegen + ); + } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/IntrinsicCallable.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/IntrinsicCallable.kt index f708bf57536..723b4636aec 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/IntrinsicCallable.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/IntrinsicCallable.kt @@ -16,10 +16,7 @@ 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.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.CallableDescriptor @@ -117,6 +114,12 @@ public abstract class IntrinsicCallable(val returnType1: Type, override fun beforeParameterGeneration(v: InstructionAdapter, value: StackValue?) { } + + override fun invokeMethodWithArguments(resolvedCall: ResolvedCall<*>, receiver: StackValue, returnType: Type, codegen: ExpressionCodegen): StackValue { + return StackValue.functionCall(returnType) { + codegen.invokeMethodWithArguments(this, resolvedCall, receiver, returnType) + } + } } 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 8fe1b2a9eb6..e80a2e354cc 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/Not.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/intrinsics/Not.kt @@ -21,7 +21,11 @@ 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.psi.JetCallExpression import org.jetbrains.kotlin.psi.JetExpression +import org.jetbrains.kotlin.psi.JetPrefixExpression +import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.org.objectweb.asm.Type public class Not : LazyIntrinsicMethod() { @@ -37,6 +41,23 @@ public class Not : LazyIntrinsicMethod() { } override fun supportCallable(): Boolean { - return false + return true + } + + override fun toCallable(fd: FunctionDescriptor, isSuper: Boolean, resolvedCall: ResolvedCall<*>, codegen: ExpressionCodegen): ExtendedCallable { + val callable = codegen.getState().getTypeMapper().mapToCallableMethod(fd, false, codegen.getContext()) + return object : MappedCallable(callable, {}) { + override fun invokeMethodWithArguments(resolvedCall: ResolvedCall<*>, receiver: StackValue, returnType: Type, codegen: ExpressionCodegen): StackValue { + val element = resolvedCall.getCall().getCallElement() + val stackValue = + if (element is JetPrefixExpression) { + codegen.gen(element.getBaseExpression()) + } + else { + StackValue.receiver(resolvedCall, receiver, codegen, this) + } + return StackValue.not(StackValue.coercion(stackValue, Type.BOOLEAN_TYPE)) + } + } } }