Do not use 'dup' for postfix increment/decrement: can't do it with collection element in general.

KT-11190, KT-11191, KT-11192, KT-11200, KT-11206
This commit is contained in:
Dmitry Petrov
2016-03-01 18:06:46 +03:00
parent 3ca4097bcc
commit 9244ef9b81
13 changed files with 557 additions and 19 deletions
@@ -557,22 +557,31 @@ public class AsmUtil {
}
public static void genIncrement(Type expectedType, int myDelta, InstructionAdapter v) {
if (expectedType == Type.LONG_TYPE) {
v.lconst(myDelta);
numConst(myDelta, expectedType, v);
v.add(expectedType);
}
public static void numConst(int value, Type type, InstructionAdapter v) {
if (type == Type.FLOAT_TYPE) {
v.fconst(value);
}
else if (expectedType == Type.FLOAT_TYPE) {
v.fconst(myDelta);
else if (type == Type.DOUBLE_TYPE) {
v.dconst(value);
}
else if (expectedType == Type.DOUBLE_TYPE) {
v.dconst(myDelta);
else if (type == Type.LONG_TYPE) {
v.lconst(value);
}
else if (type == Type.CHAR_TYPE || type == Type.BYTE_TYPE || type == Type.SHORT_TYPE || type == Type.INT_TYPE) {
v.iconst(value);
}
else {
v.iconst(myDelta);
v.add(Type.INT_TYPE);
StackValue.coerce(Type.INT_TYPE, expectedType, v);
return;
throw new IllegalArgumentException("Primitive numeric type expected, got: " + type);
}
v.add(expectedType);
}
public static void genIncrement(Type expectedType, Type baseType, int myDelta, InstructionAdapter v) {
genIncrement(baseType, myDelta, v);
StackValue.coerce(baseType, expectedType, v);
}
public static void swap(InstructionAdapter v, Type stackTop, Type afterTop) {
@@ -3319,26 +3319,31 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
return StackValue.operation(asmBaseType, new Function1<InstructionAdapter, Unit>() {
@Override
public Unit invoke(InstructionAdapter v) {
StackValue value = gen(expression.getBaseExpression());
value = StackValue.complexWriteReadReceiver(value);
StackValue value = StackValue.complexWriteReadReceiver(gen(expression.getBaseExpression()));
Type type = expressionType(expression.getBaseExpression());
value.put(type, v); // old value
value.put(asmBaseType, v);
AsmUtil.dup(v, asmBaseType);
value.dup(v, true);
StackValue previousValue = StackValue.local(myFrameMap.enterTemp(asmBaseType), asmBaseType);
previousValue.store(StackValue.onStack(asmBaseType), v);
Type storeType;
if (isPrimitiveNumberClassDescriptor && AsmUtil.isPrimitive(asmBaseType)) {
genIncrement(asmResultType, increment, v);
storeType = type;
genIncrement(asmResultType, asmBaseType, increment, v);
storeType = asmBaseType;
}
else {
StackValue result = invokeFunction(resolvedCall, StackValue.onStack(type));
StackValue result = invokeFunction(resolvedCall, StackValue.onStack(asmBaseType));
result.put(result.type, v);
storeType = result.type;
}
value.store(StackValue.onStack(storeType), v, true);
previousValue.put(asmBaseType, v);
myFrameMap.leaveTemp(asmBaseType);
return Unit.INSTANCE;
}
});