Prefix inc refactoring
This commit is contained in:
@@ -3141,7 +3141,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
|||||||
if (callable instanceof IntrinsicMethod) {
|
if (callable instanceof IntrinsicMethod) {
|
||||||
StackValue value = gen(lhs); // receiver
|
StackValue value = gen(lhs); // receiver
|
||||||
value = StackValue.complexReceiver(value, StackValue.RECEIVER_WRITE, StackValue.RECEIVER_READ);
|
value = StackValue.complexReceiver(value, StackValue.RECEIVER_WRITE, StackValue.RECEIVER_READ);
|
||||||
//value.putWriteReadReceiver(v); // receiver receiver
|
|
||||||
value.put(lhsType, v); // receiver lhs
|
value.put(lhsType, v); // receiver lhs
|
||||||
Type returnType = typeMapper.mapType(descriptor);
|
Type returnType = typeMapper.mapType(descriptor);
|
||||||
StackValue rightSide = ((IntrinsicMethod) callable).generate(this, v, returnType, expression,
|
StackValue rightSide = ((IntrinsicMethod) callable).generate(this, v, returnType, expression,
|
||||||
@@ -3222,7 +3222,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
|||||||
@Override
|
@Override
|
||||||
public StackValue visitPrefixExpression(@NotNull JetPrefixExpression expression, StackValue receiver) {
|
public StackValue visitPrefixExpression(@NotNull JetPrefixExpression expression, StackValue receiver) {
|
||||||
DeclarationDescriptor originalOperation = bindingContext.get(REFERENCE_TARGET, expression.getOperationReference());
|
DeclarationDescriptor originalOperation = bindingContext.get(REFERENCE_TARGET, expression.getOperationReference());
|
||||||
final ResolvedCall<?> resolvedCall = getResolvedCallWithAssert(expression, bindingContext);
|
ResolvedCall<?> resolvedCall = getResolvedCallWithAssert(expression, bindingContext);
|
||||||
CallableDescriptor op = resolvedCall.getResultingDescriptor();
|
CallableDescriptor op = resolvedCall.getResultingDescriptor();
|
||||||
|
|
||||||
assert op instanceof FunctionDescriptor || originalOperation == null : String.valueOf(op);
|
assert op instanceof FunctionDescriptor || originalOperation == null : String.valueOf(op);
|
||||||
@@ -3239,24 +3239,10 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
|||||||
return invokeFunction(resolvedCall, receiver);
|
return invokeFunction(resolvedCall, receiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
final Type type = expressionType(expression.getBaseExpression());
|
Type type = expressionType(expression.getBaseExpression());
|
||||||
final StackValue value = genLazy(expression.getBaseExpression(), type);
|
StackValue value = genLazy(expression.getBaseExpression(), type);
|
||||||
|
|
||||||
return new OperationStackValue(type, new Function1<InstructionAdapter, Unit>() {
|
return StackValue.preIncrement(type, value, -1, callable, resolvedCall, this);
|
||||||
@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;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -3322,7 +3308,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
|||||||
public Unit invoke(InstructionAdapter adapter) {
|
public Unit invoke(InstructionAdapter adapter) {
|
||||||
StackValue value = gen(expression.getBaseExpression());
|
StackValue value = gen(expression.getBaseExpression());
|
||||||
value = StackValue.complexReceiver(value, StackValue.RECEIVER_WRITE, StackValue.RECEIVER_READ);
|
value = StackValue.complexReceiver(value, StackValue.RECEIVER_WRITE, StackValue.RECEIVER_READ);
|
||||||
//value.putWriteReadReceiver(v);
|
|
||||||
|
|
||||||
Type type = expressionType(expression.getBaseExpression());
|
Type type = expressionType(expression.getBaseExpression());
|
||||||
value.put(type, v); // old value
|
value.put(type, v); // old value
|
||||||
|
|||||||
@@ -390,8 +390,19 @@ public abstract class StackValue implements StackValueI {
|
|||||||
return new PostIncrement(index, increment);
|
return new PostIncrement(index, increment);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static StackValue preIncrement(int index, int increment) {
|
public static StackValue preIncrementForLocalVar(int index, int increment) {
|
||||||
return new PreIncrement(index, 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(
|
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 index;
|
||||||
private final int increment;
|
private final int increment;
|
||||||
|
|
||||||
public PreIncrement(int index, int increment) {
|
public PreIncrementForLocalVar(int index, int increment) {
|
||||||
super(Type.INT_TYPE);
|
super(Type.INT_TYPE);
|
||||||
this.index = index;
|
this.index = index;
|
||||||
this.increment = increment;
|
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 {
|
public static class CallReceiver extends StackValueWithoutReceiver {
|
||||||
private final ResolvedCall<?> resolvedCall;
|
private final ResolvedCall<?> resolvedCall;
|
||||||
private final StackValue receiver;
|
private final StackValue receiver;
|
||||||
|
|||||||
@@ -367,7 +367,7 @@ public class InlineCodegen implements CallGenerator {
|
|||||||
ParameterInfo info = infos[i];
|
ParameterInfo info = infos[i];
|
||||||
if (!info.isSkippedOrRemapped()) {
|
if (!info.isSkippedOrRemapped()) {
|
||||||
Type type = info.type;
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,19 +60,13 @@ public class Increment extends IntrinsicMethod {
|
|||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
JetType operandType = codegen.getBindingContext().get(EXPRESSION_TYPE, operand);
|
JetType operandType = codegen.getBindingContext().get(EXPRESSION_TYPE, operand);
|
||||||
if (operandType != null && KotlinBuiltIns.getInstance().isPrimitiveType(operandType)) {
|
if (operandType != null && KotlinBuiltIns.getInstance().isPrimitiveType(operandType)) {
|
||||||
StackValue.preIncrement(index, myDelta).put(returnType, v);
|
StackValue.preIncrementForLocalVar(index, myDelta).put(returnType, v);
|
||||||
return returnType;
|
return returnType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
StackValue value = codegen.genQualified(receiver, operand);
|
StackValue value = StackValue.preIncrement(returnType, codegen.genQualified(receiver, operand), myDelta, this, null, codegen);
|
||||||
value = StackValue.complexReceiver(value, StackValue.RECEIVER_READ, StackValue.RECEIVER_WRITE, StackValue.RECEIVER_READ);
|
|
||||||
//value.putReadWriteReadReceiver(v);
|
|
||||||
|
|
||||||
value.put(returnType, v);
|
value.put(returnType, v);
|
||||||
genIncrement(returnType, myDelta, v);
|
|
||||||
value.store(returnType, v);
|
|
||||||
StackValue.putNoReceiver(value, returnType, v);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
receiver.put(returnType, v);
|
receiver.put(returnType, v);
|
||||||
|
|||||||
@@ -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"
|
||||||
|
}
|
||||||
+6
@@ -1484,6 +1484,12 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
|
|||||||
doTestWithStdlib(fileName);
|
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")
|
@TestMetadata("safeAssign.kt")
|
||||||
public void testSafeAssign() throws Exception {
|
public void testSafeAssign() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/lazyCodegen/safeAssign.kt");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/lazyCodegen/safeAssign.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user