From 855bf772ca3ee8aaeca1e897c94fae6e75839862 Mon Sep 17 00:00:00 2001 From: Michael Bogdanov Date: Thu, 6 Nov 2014 16:42:17 +0300 Subject: [PATCH] Prefix inc refactoring --- .../jet/codegen/ExpressionCodegen.java | 25 ++------ .../org/jetbrains/jet/codegen/StackValue.java | 60 +++++++++++++++++-- .../jet/codegen/inline/InlineCodegen.java | 2 +- .../jet/codegen/intrinsics/Increment.java | 10 +--- .../boxWithStdlib/lazyCodegen/increment.kt | 31 ++++++++++ ...lackBoxWithStdlibCodegenTestGenerated.java | 6 ++ 6 files changed, 101 insertions(+), 33 deletions(-) create mode 100644 compiler/testData/codegen/boxWithStdlib/lazyCodegen/increment.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 4e8a9b17f35..8f3205f1fb9 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -3141,7 +3141,7 @@ public class ExpressionCodegen extends JetVisitor implem if (callable instanceof IntrinsicMethod) { StackValue value = gen(lhs); // receiver value = StackValue.complexReceiver(value, StackValue.RECEIVER_WRITE, StackValue.RECEIVER_READ); - //value.putWriteReadReceiver(v); // receiver receiver + value.put(lhsType, v); // receiver lhs Type returnType = typeMapper.mapType(descriptor); StackValue rightSide = ((IntrinsicMethod) callable).generate(this, v, returnType, expression, @@ -3222,7 +3222,7 @@ public class ExpressionCodegen extends JetVisitor implem @Override public StackValue visitPrefixExpression(@NotNull JetPrefixExpression expression, StackValue receiver) { DeclarationDescriptor originalOperation = bindingContext.get(REFERENCE_TARGET, expression.getOperationReference()); - final ResolvedCall resolvedCall = getResolvedCallWithAssert(expression, bindingContext); + ResolvedCall resolvedCall = getResolvedCallWithAssert(expression, bindingContext); CallableDescriptor op = resolvedCall.getResultingDescriptor(); assert op instanceof FunctionDescriptor || originalOperation == null : String.valueOf(op); @@ -3239,24 +3239,10 @@ public class ExpressionCodegen extends JetVisitor implem return invokeFunction(resolvedCall, receiver); } - final Type type = expressionType(expression.getBaseExpression()); - final StackValue value = genLazy(expression.getBaseExpression(), type); + Type type = expressionType(expression.getBaseExpression()); + StackValue value = genLazy(expression.getBaseExpression(), type); - return new OperationStackValue(type, new Function1() { - @Override - public Unit invoke(InstructionAdapter v) { - StackValue valueWithReceiversOnStack = StackValue.complexReceiver(value, StackValue.RECEIVER_WRITE, StackValue.RECEIVER_READ); - //valueWithReceiversOnStack.putWriteReadReceiver(v); - valueWithReceiversOnStack.put(type, v); - - StackValue result = invokeFunction(resolvedCall, StackValue.onStack(type)); - result.put(type, v); - - valueWithReceiversOnStack.store(result.type, v); - StackValue.putNoReceiver(valueWithReceiversOnStack, type, v); - return null; - } - }); + return StackValue.preIncrement(type, value, -1, callable, resolvedCall, this); } @Override @@ -3322,7 +3308,6 @@ public class ExpressionCodegen extends JetVisitor implem public Unit invoke(InstructionAdapter adapter) { StackValue value = gen(expression.getBaseExpression()); value = StackValue.complexReceiver(value, StackValue.RECEIVER_WRITE, StackValue.RECEIVER_READ); - //value.putWriteReadReceiver(v); Type type = expressionType(expression.getBaseExpression()); value.put(type, v); // old value diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java b/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java index b8fd31c4705..4cd6a61a318 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java @@ -390,8 +390,19 @@ public abstract class StackValue implements StackValueI { return new PostIncrement(index, increment); } - public static StackValue preIncrement(int index, int increment) { - return new PreIncrement(index, increment); + public static StackValue preIncrementForLocalVar(int index, int increment) { + return new PreIncrementForLocalVar(index, increment); + } + + public static StackValue preIncrement( + @NotNull Type type, + @NotNull StackValue stackValue, + int delta, + @NotNull Callable method, + ResolvedCall resolvedCall, + @NotNull ExpressionCodegen codegen + ) { + return new PrefixIncrement(type, stackValue, delta, method, resolvedCall, codegen); } public static StackValue receiver( @@ -1245,11 +1256,11 @@ public abstract class StackValue implements StackValueI { } } - private static class PreIncrement extends StackValueWithoutReceiver { + private static class PreIncrementForLocalVar extends StackValueWithoutReceiver { private final int index; private final int increment; - public PreIncrement(int index, int increment) { + public PreIncrementForLocalVar(int index, int increment) { super(Type.INT_TYPE); this.index = index; this.increment = increment; @@ -1265,6 +1276,47 @@ public abstract class StackValue implements StackValueI { } } + private static class PrefixIncrement extends StackValueWithoutReceiver { + private final int delta; + private Callable callable; + private ResolvedCall resolvedCall; + private ExpressionCodegen codegen; + private StackValue value; + + public PrefixIncrement( + @NotNull Type type, + @NotNull StackValue value, + int delta, + @NotNull Callable callable, + ResolvedCall resolvedCall, + @NotNull ExpressionCodegen codegen + ) { + super(type); + this.value = value; + this.delta = delta; + this.callable = callable; + this.resolvedCall = resolvedCall; + this.codegen = codegen; + } + + @Override + public void put(@NotNull Type type, @NotNull InstructionAdapter v) { + value = StackValue.complexReceiver(value, RECEIVER_READ, RECEIVER_WRITE, RECEIVER_READ); + value.put(this.type, v); + + if (callable instanceof CallableMethod) { + value.store(codegen.invokeFunction(resolvedCall, StackValue.onStack(this.type)), v, true); + } + else { + genIncrement(this.type, delta, v); + value.store(this.type, v); + } + + StackValue.putNoReceiver(value, this.type, v); + coerceTo(type, v); + } + } + public static class CallReceiver extends StackValueWithoutReceiver { private final ResolvedCall resolvedCall; private final StackValue receiver; diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/inline/InlineCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/inline/InlineCodegen.java index 0863e94dc71..e1da804ed53 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/inline/InlineCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/inline/InlineCodegen.java @@ -367,7 +367,7 @@ public class InlineCodegen implements CallGenerator { ParameterInfo info = infos[i]; if (!info.isSkippedOrRemapped()) { Type type = info.type; - StackValue.local(index[i], type).store(StackValue.onStack(type), codegen.v, true); + StackValue.local(index[i], type).store(StackValue.onStack(type), codegen.v); } } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Increment.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Increment.java index 0a07e42b340..742b87f8122 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Increment.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Increment.java @@ -60,19 +60,13 @@ public class Increment extends IntrinsicMethod { if (index >= 0) { JetType operandType = codegen.getBindingContext().get(EXPRESSION_TYPE, operand); if (operandType != null && KotlinBuiltIns.getInstance().isPrimitiveType(operandType)) { - StackValue.preIncrement(index, myDelta).put(returnType, v); + StackValue.preIncrementForLocalVar(index, myDelta).put(returnType, v); return returnType; } } } - StackValue value = codegen.genQualified(receiver, operand); - value = StackValue.complexReceiver(value, StackValue.RECEIVER_READ, StackValue.RECEIVER_WRITE, StackValue.RECEIVER_READ); - //value.putReadWriteReadReceiver(v); - + StackValue value = StackValue.preIncrement(returnType, codegen.genQualified(receiver, operand), myDelta, this, null, codegen); value.put(returnType, v); - genIncrement(returnType, myDelta, v); - value.store(returnType, v); - StackValue.putNoReceiver(value, returnType, v); } else { receiver.put(returnType, v); diff --git a/compiler/testData/codegen/boxWithStdlib/lazyCodegen/increment.kt b/compiler/testData/codegen/boxWithStdlib/lazyCodegen/increment.kt new file mode 100644 index 00000000000..cb92ba0a306 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/lazyCodegen/increment.kt @@ -0,0 +1,31 @@ +var holder = "" +var globalA: A = A(-1) + get(): A { + holder += "getA" + return $globalA + } + + +class A(val p: Int) { + + var prop = this + + fun inc(): A { + return A(p+1) + } + + +} + +fun box(): String { + var a = A(1) + ++a + if (a.p != 2) return "fail 1: ${a.p} $holder" + + globalA = A(1) + ++(globalA.prop) + val holderValue = holder; + if (globalA.p != 1 || globalA.prop.p != 2 || holderValue != "getA") return "fail 2: ${a.p} ${a.prop.p} ${holderValue}" + + return "OK" +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java index 1fb2446464e..18c2fb39946 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java @@ -1484,6 +1484,12 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode doTestWithStdlib(fileName); } + @TestMetadata("increment.kt") + public void testIncrement() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/lazyCodegen/increment.kt"); + doTestWithStdlib(fileName); + } + @TestMetadata("safeAssign.kt") public void testSafeAssign() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/lazyCodegen/safeAssign.kt");