diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java b/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java index 9116696fa30..5a0d5d17f80 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java @@ -433,25 +433,23 @@ public class AsmUtil { } } - public static Type genIncrement(Type expectedType, int myDelta, InstructionAdapter v) { + public static void genIncrement(Type expectedType, int myDelta, InstructionAdapter v) { if (expectedType == Type.LONG_TYPE) { - //noinspection UnnecessaryBoxing v.lconst(myDelta); } else if (expectedType == Type.FLOAT_TYPE) { - //noinspection UnnecessaryBoxing v.fconst(myDelta); } else if (expectedType == Type.DOUBLE_TYPE) { - //noinspection UnnecessaryBoxing v.dconst(myDelta); } else { v.iconst(myDelta); - expectedType = Type.INT_TYPE; + v.add(Type.INT_TYPE); + StackValue.coerce(Type.INT_TYPE, expectedType, v); + return; } v.add(expectedType); - return expectedType; } public static Type genNegate(Type expectedType, InstructionAdapter v) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 66971d59270..e0026290b71 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -3057,89 +3057,92 @@ public class ExpressionCodegen extends JetVisitor implem v.mark(ok); return StackValue.onStack(base.type); } + DeclarationDescriptor op = bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getOperationReference()); - if (op instanceof FunctionDescriptor) { - Type asmType = expressionType(expression); - DeclarationDescriptor cls = op.getContainingDeclaration(); - if (op.getName().asString().equals("inc") || op.getName().asString().equals("dec")) { - if (isPrimitiveNumberClassDescriptor(cls)) { - receiver.put(receiver.type, v); - JetExpression operand = expression.getBaseExpression(); - if (operand instanceof JetReferenceExpression) { - int index = indexOfLocal((JetReferenceExpression) operand); - if (index >= 0 && isIntPrimitive(asmType)) { - int increment = op.getName().asString().equals("inc") ? 1 : -1; - return StackValue.postIncrement(index, increment); - } - } - gen(operand, asmType); // old value - generateIncrement(op, asmType, operand, receiver); // increment in-place - return StackValue.onStack(asmType); // old value - } - else { - ResolvedCall resolvedCall = - bindingContext.get(BindingContext.RESOLVED_CALL, expression.getOperationReference()); - assert resolvedCall != null; + if (!(op instanceof FunctionDescriptor)) { + throw new UnsupportedOperationException("Don't know how to generate this postfix expression: " + op); + } - Callable callable = resolveToCallable((FunctionDescriptor) op, false); + Type asmType = expressionType(expression); + DeclarationDescriptor cls = op.getContainingDeclaration(); - StackValue value = gen(expression.getBaseExpression()); - value.dupReceiver(v); + int increment; + if (op.getName().asString().equals("inc")) { + increment = 1; + } + else if (op.getName().asString().equals("dec")) { + increment = -1; + } + else { + throw new UnsupportedOperationException("Unsupported postfix operation: " + op); + } - Type type = expressionType(expression.getBaseExpression()); - value.put(type, v); - - switch (value.receiverSize()) { - case 0: - dup(v, type); - break; - - case 1: - if (type.getSize() == 2) { - v.dup2X1(); - } - else { - v.dupX1(); - } - break; - - case 2: - if (type.getSize() == 2) { - v.dup2X2(); - } - else { - v.dupX2(); - } - break; - - case -1: - throw new UnsupportedOperationException(); - } - - CallableMethod callableMethod = (CallableMethod) callable; - callableMethod.invokeWithNotNullAssertion(v, state, resolvedCall); - - value.store(callableMethod.getReturnType(), v); - return StackValue.onStack(type); + if (isPrimitiveNumberClassDescriptor(cls)) { + receiver.put(receiver.type, v); + JetExpression operand = expression.getBaseExpression(); + if (operand instanceof JetReferenceExpression && asmType == Type.INT_TYPE) { + int index = indexOfLocal((JetReferenceExpression) operand); + if (index >= 0) { + return StackValue.postIncrement(index, increment); } } + gen(operand, asmType); // old value + generateIncrement(increment, asmType, operand, receiver); // increment in-place + return StackValue.onStack(asmType); // old value + } + else { + ResolvedCall resolvedCall = + bindingContext.get(BindingContext.RESOLVED_CALL, expression.getOperationReference()); + assert resolvedCall != null; + + Callable callable = resolveToCallable((FunctionDescriptor) op, false); + + StackValue value = gen(expression.getBaseExpression()); + value.dupReceiver(v); + + Type type = expressionType(expression.getBaseExpression()); + value.put(type, v); + + switch (value.receiverSize()) { + case 0: + dup(v, type); + break; + + case 1: + if (type.getSize() == 2) { + v.dup2X1(); + } + else { + v.dupX1(); + } + break; + + case 2: + if (type.getSize() == 2) { + v.dup2X2(); + } + else { + v.dupX2(); + } + break; + + case -1: + throw new UnsupportedOperationException(); + } + + CallableMethod callableMethod = (CallableMethod) callable; + callableMethod.invokeWithNotNullAssertion(v, state, resolvedCall); + + value.store(callableMethod.getReturnType(), v); + return StackValue.onStack(type); } - throw new UnsupportedOperationException("Don't know how to generate this postfix expression"); } - private void generateIncrement(DeclarationDescriptor op, Type asmType, JetExpression operand, StackValue receiver) { - int increment = op.getName().asString().equals("inc") ? 1 : -1; - if (operand instanceof JetReferenceExpression) { - int index = indexOfLocal((JetReferenceExpression) operand); - if (index >= 0 && isIntPrimitive(asmType)) { - v.iinc(index, increment); - return; - } - } + private void generateIncrement(int increment, Type asmType, JetExpression operand, StackValue receiver) { StackValue value = genQualified(receiver, operand); value.dupReceiver(v); value.put(asmType, v); - asmType = genIncrement(asmType, increment, v); + genIncrement(asmType, increment, v); value.store(asmType, 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 89ecc7e31c5..f358295e8ef 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Increment.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Increment.java @@ -29,7 +29,8 @@ import org.jetbrains.jet.lang.psi.JetReferenceExpression; import java.util.List; -import static org.jetbrains.jet.codegen.AsmUtil.*; +import static org.jetbrains.jet.codegen.AsmUtil.genIncrement; +import static org.jetbrains.jet.codegen.AsmUtil.unboxType; public class Increment implements IntrinsicMethod { private final int myDelta; @@ -57,9 +58,9 @@ public class Increment implements IntrinsicMethod { while (operand instanceof JetParenthesizedExpression) { operand = ((JetParenthesizedExpression) operand).getExpression(); } - if (operand instanceof JetReferenceExpression) { + if (operand instanceof JetReferenceExpression && expectedType == Type.INT_TYPE) { int index = codegen.indexOfLocal((JetReferenceExpression) operand); - if (index >= 0 && isIntPrimitive(expectedType)) { + if (index >= 0) { return StackValue.preIncrement(index, myDelta); } } @@ -68,12 +69,13 @@ public class Increment implements IntrinsicMethod { value.dupReceiver(v); value.put(expectedType, v); - value.store(genIncrement(expectedType, myDelta, v), v); + genIncrement(expectedType, myDelta, v); + value.store(expectedType, v); value.put(expectedType, v); } else { receiver.put(expectedType, v); - StackValue.coerce(genIncrement(expectedType, myDelta, v), expectedType, v); + genIncrement(expectedType, myDelta, v); } return StackValue.onStack(expectedType); } diff --git a/compiler/testData/codegen/box/primitiveTypes/incrementByteCharShort.kt b/compiler/testData/codegen/box/primitiveTypes/incrementByteCharShort.kt new file mode 100644 index 00000000000..59b3f12b2ef --- /dev/null +++ b/compiler/testData/codegen/box/primitiveTypes/incrementByteCharShort.kt @@ -0,0 +1,22 @@ +fun byteArg(b: Byte) {} +fun charArg(c: Char) {} +fun shortArg(s: Short) {} + +fun box(): String { + var b = 42.toByte() + b++ + ++b + byteArg(b) + + var c = 'x' + c++ + ++c + charArg(c) + + var s = 239.toShort() + s++ + ++s + shortArg(s) + + return "OK" +} diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java index bc16ba9d43e..784f1355c8f 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java @@ -3339,6 +3339,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest("compiler/testData/codegen/box/primitiveTypes/ea35963.kt"); } + @TestMetadata("incrementByteCharShort.kt") + public void testIncrementByteCharShort() throws Exception { + doTest("compiler/testData/codegen/box/primitiveTypes/incrementByteCharShort.kt"); + } + @TestMetadata("intLiteralIsNotNull.kt") public void testIntLiteralIsNotNull() throws Exception { doTest("compiler/testData/codegen/box/primitiveTypes/intLiteralIsNotNull.kt");