Prefix inc refactoring

This commit is contained in:
Michael Bogdanov
2014-11-06 16:42:17 +03:00
parent c7b1c0fe52
commit 855bf772ca
6 changed files with 101 additions and 33 deletions
@@ -3141,7 +3141,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> 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<StackValue, StackValue> 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<StackValue, StackValue> 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<InstructionAdapter, Unit>() {
@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<StackValue, StackValue> 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
@@ -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;
@@ -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);
}
}
}
@@ -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);
@@ -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"
}
@@ -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");