Fix recusrive calls in infix and prefix form
The infamous invokeOperation() method removed
This commit is contained in:
@@ -2638,7 +2638,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
|
||||
@Override
|
||||
public StackValue visitBinaryExpression(@NotNull JetBinaryExpression expression, StackValue receiver) {
|
||||
IElementType opToken = expression.getOperationReference().getReferencedNameElementType();
|
||||
JetSimpleNameExpression reference = expression.getOperationReference();
|
||||
IElementType opToken = reference.getReferencedNameElementType();
|
||||
if (opToken == JetTokens.EQ) {
|
||||
return generateAssignmentExpression(expression);
|
||||
}
|
||||
@@ -2657,7 +2658,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
}
|
||||
else if (opToken == JetTokens.LT || opToken == JetTokens.LTEQ ||
|
||||
opToken == JetTokens.GT || opToken == JetTokens.GTEQ) {
|
||||
return generateComparison(expression);
|
||||
return generateComparison(expression, receiver);
|
||||
}
|
||||
else if (opToken == JetTokens.ELVIS) {
|
||||
return generateElvis(expression);
|
||||
@@ -2666,7 +2667,10 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
return generateIn(expression);
|
||||
}
|
||||
else {
|
||||
DeclarationDescriptor op = bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getOperationReference());
|
||||
ResolvedCall<? extends CallableDescriptor> resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, reference);
|
||||
Call call = bindingContext.get(BindingContext.CALL, reference);
|
||||
|
||||
DeclarationDescriptor op = bindingContext.get(BindingContext.REFERENCE_TARGET, reference);
|
||||
assert op instanceof FunctionDescriptor : String.valueOf(op);
|
||||
Callable callable = resolveToCallable((FunctionDescriptor) op, false);
|
||||
if (callable instanceof IntrinsicMethod) {
|
||||
@@ -2675,7 +2679,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
Arrays.asList(expression.getLeft(), expression.getRight()), receiver, state);
|
||||
}
|
||||
else {
|
||||
return invokeOperation(expression, (FunctionDescriptor) op, (CallableMethod) callable);
|
||||
return invokeFunction(call, receiver, resolvedCall);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2856,7 +2860,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
return StackValue.onStack(exprType);
|
||||
}
|
||||
|
||||
private StackValue generateComparison(JetBinaryExpression expression) {
|
||||
private StackValue generateComparison(JetBinaryExpression expression, StackValue receiver) {
|
||||
DeclarationDescriptor target = bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getOperationReference());
|
||||
assert target instanceof FunctionDescriptor : "compareTo target should be a function: " + target;
|
||||
FunctionDescriptor descriptor = (FunctionDescriptor) target;
|
||||
@@ -2869,13 +2873,16 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
if (callable instanceof IntrinsicMethod) {
|
||||
// Compare two primitive values
|
||||
type = comparisonOperandType(expressionType(left), expressionType(right));
|
||||
StackValue receiver = gen(left);
|
||||
receiver.put(type, v);
|
||||
StackValue recv = gen(left);
|
||||
recv.put(type, v);
|
||||
gen(right, type);
|
||||
}
|
||||
else {
|
||||
ResolvedCall<? extends CallableDescriptor> resolvedCall =
|
||||
bindingContext.get(BindingContext.RESOLVED_CALL, expression.getOperationReference());
|
||||
Call call = bindingContext.get(BindingContext.CALL, expression.getOperationReference());
|
||||
StackValue result = invokeFunction(call, receiver, resolvedCall);
|
||||
type = Type.INT_TYPE;
|
||||
StackValue result = invokeOperation(expression, descriptor, (CallableMethod) callable);
|
||||
result.put(type, v);
|
||||
v.iconst(0);
|
||||
}
|
||||
@@ -3009,14 +3016,16 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
}
|
||||
else {
|
||||
DeclarationDescriptor cls = op.getContainingDeclaration();
|
||||
CallableMethod callableMethod = (CallableMethod) callable;
|
||||
ResolvedCall<? extends CallableDescriptor> resolvedCall =
|
||||
bindingContext.get(BindingContext.RESOLVED_CALL, expression.getOperationReference());
|
||||
assert resolvedCall != null;
|
||||
|
||||
if (isPrimitiveNumberClassDescriptor(cls) || !(op.getName().asString().equals("inc") || op.getName().asString().equals("dec"))) {
|
||||
return invokeOperation(expression, (FunctionDescriptor) op, callableMethod);
|
||||
Call call = bindingContext.get(BindingContext.CALL, expression.getOperationReference());
|
||||
return invokeFunction(call, receiver, resolvedCall);
|
||||
}
|
||||
else {
|
||||
ResolvedCall<? extends CallableDescriptor> resolvedCall =
|
||||
bindingContext.get(BindingContext.RESOLVED_CALL, expression.getOperationReference());
|
||||
assert resolvedCall != null;
|
||||
CallableMethod callableMethod = (CallableMethod) callable;
|
||||
|
||||
StackValue value = gen(expression.getBaseExpression());
|
||||
value.dupReceiver(v);
|
||||
@@ -3033,27 +3042,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
}
|
||||
}
|
||||
|
||||
private StackValue invokeOperation(JetOperationExpression expression, FunctionDescriptor op, CallableMethod callable) {
|
||||
//TODO: similar logic exists in visitSimpleNameExpression - extract common logic
|
||||
int functionLocalIndex = lookupLocalIndex(op);
|
||||
if (functionLocalIndex >= 0) {
|
||||
stackValueForLocal(op, functionLocalIndex).put(callable.getOwner(), v);
|
||||
} else {
|
||||
StackValue stackValue = context.lookupInContext(op, StackValue.local(0, OBJECT_TYPE), state, true);
|
||||
if (stackValue != null) {
|
||||
stackValue.put(callable.getOwner(), v);
|
||||
}
|
||||
}
|
||||
|
||||
ResolvedCall<? extends CallableDescriptor> resolvedCall =
|
||||
bindingContext.get(BindingContext.RESOLVED_CALL, expression.getOperationReference());
|
||||
assert resolvedCall != null;
|
||||
genThisAndReceiverFromResolvedCall(StackValue.none(), resolvedCall, callable);
|
||||
pushArgumentsAndInvoke(resolvedCall, callable);
|
||||
|
||||
return returnValueAsStackValue(op, callable.getSignature().getAsmMethod().getReturnType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public StackValue visitPostfixExpression(@NotNull JetPostfixExpression expression, StackValue receiver) {
|
||||
if (expression.getOperationReference().getReferencedNameElementType() == JetTokens.EXCLEXCL) {
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
fun Int.test(x : Int) : Int {
|
||||
if (this > 1) {
|
||||
return (this - 1) test x
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
fun box() : String = if (10.test(10) == 1) "OK" else "FAIL"
|
||||
@@ -0,0 +1,8 @@
|
||||
fun String.plus() : String {
|
||||
if (this == "") {
|
||||
return "done"
|
||||
}
|
||||
return +""
|
||||
}
|
||||
|
||||
fun box() : String = if (+"11" == "done") "OK" else "FAIL"
|
||||
@@ -0,0 +1,11 @@
|
||||
class C
|
||||
|
||||
fun C.compareTo(o: C) : Int {
|
||||
if (this == o) return 0
|
||||
if (o >= o) {
|
||||
return 1
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
fun box() : String = if (C() > C()) "OK" else "FAIL"
|
||||
@@ -0,0 +1,12 @@
|
||||
fun String.inc() : String {
|
||||
if (this == "") {
|
||||
return "done"
|
||||
}
|
||||
var s = ""
|
||||
return ++s
|
||||
}
|
||||
|
||||
fun box() : String {
|
||||
var s = "11test"
|
||||
return if (++s == "done") "OK" else "FAIL"
|
||||
}
|
||||
@@ -2407,6 +2407,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
doTest("compiler/testData/codegen/box/functions/functionNtoString.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("infixRecursiveCall.kt")
|
||||
public void testInfixRecursiveCall() throws Exception {
|
||||
doTest("compiler/testData/codegen/box/functions/infixRecursiveCall.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt1038.kt")
|
||||
public void testKt1038() throws Exception {
|
||||
doTest("compiler/testData/codegen/box/functions/kt1038.kt");
|
||||
@@ -2512,6 +2517,21 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
doTest("compiler/testData/codegen/box/functions/nothisnoclosure.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("prefixRecursiveCall.kt")
|
||||
public void testPrefixRecursiveCall() throws Exception {
|
||||
doTest("compiler/testData/codegen/box/functions/prefixRecursiveCall.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("recursiveCompareTo.kt")
|
||||
public void testRecursiveCompareTo() throws Exception {
|
||||
doTest("compiler/testData/codegen/box/functions/recursiveCompareTo.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("recursiveIncrementCall.kt")
|
||||
public void testRecursiveIncrementCall() throws Exception {
|
||||
doTest("compiler/testData/codegen/box/functions/recursiveIncrementCall.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/functions/invoke")
|
||||
public static class Invoke extends AbstractBlackBoxCodegenTest {
|
||||
public void testAllFilesPresentInInvoke() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user