Generation of ++ and += fixed for platform types

This commit is contained in:
Andrey Breslav
2014-10-21 18:38:08 +04:00
parent d28c96837e
commit 7ed7f020d3
24 changed files with 354 additions and 18 deletions
@@ -3005,9 +3005,10 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
StackValue value = gen(lhs); // receiver
value.dupReceiver(v); // receiver receiver
value.put(lhsType, v); // receiver lhs
((IntrinsicMethod) callable).generate(this, v, typeMapper.mapType(descriptor), expression,
Type returnType = typeMapper.mapType(descriptor);
((IntrinsicMethod) callable).generate(this, v, returnType, expression,
Collections.singletonList(expression.getRight()), StackValue.onStack(lhsType));
value.store(lhsType, v);
value.store(returnType, v);
return StackValue.none();
}
else {
@@ -3137,7 +3138,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
throw new UnsupportedOperationException("Don't know how to generate this postfix expression: " + originalOperationName + " " + op);
}
Type asmType = expressionType(expression);
Type asmResultType = expressionType(expression);
Type asmBaseType = expressionType(expression.getBaseExpression());
DeclarationDescriptor cls = op.getContainingDeclaration();
int increment;
@@ -3152,9 +3154,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
}
boolean isPrimitiveNumberClassDescriptor = isPrimitiveNumberClassDescriptor(cls);
if (isPrimitiveNumberClassDescriptor) {
if (isPrimitiveNumberClassDescriptor && AsmUtil.isPrimitive(asmBaseType)) {
JetExpression operand = expression.getBaseExpression();
if (operand instanceof JetReferenceExpression && asmType == Type.INT_TYPE) {
if (operand instanceof JetReferenceExpression && asmResultType == Type.INT_TYPE) {
int index = indexOfLocal((JetReferenceExpression) operand);
if (index >= 0) {
return StackValue.postIncrement(index, increment);
@@ -3171,8 +3173,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
pushReceiverAndValueViaDup(value, type); // receiver and new value
Type storeType;
if (isPrimitiveNumberClassDescriptor) {
genIncrement(asmType, increment, v);
if (isPrimitiveNumberClassDescriptor && AsmUtil.isPrimitive(asmBaseType)) {
genIncrement(asmResultType, increment, v);
storeType = type;
}
else {
@@ -3181,7 +3183,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
}
value.store(storeType, v);
return StackValue.onStack(asmType); // old value
return StackValue.onStack(asmResultType); // old value
}
private void pushReceiverAndValueViaDup(StackValue value, Type type) {
@@ -18,18 +18,21 @@ package org.jetbrains.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.psi.JetParenthesizedExpression;
import org.jetbrains.jet.lang.psi.JetPsiUtil;
import org.jetbrains.jet.lang.psi.JetReferenceExpression;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
import java.util.List;
import static org.jetbrains.jet.codegen.AsmUtil.genIncrement;
import static org.jetbrains.jet.codegen.AsmUtil.isPrimitive;
import static org.jetbrains.jet.lang.resolve.BindingContext.EXPRESSION_TYPE;
public class Increment extends IntrinsicMethod {
private final int myDelta;
@@ -51,15 +54,15 @@ public class Increment extends IntrinsicMethod {
assert isPrimitive(returnType) : "Return type of Increment intrinsic should be of primitive type : " + returnType;
if (arguments.size() > 0) {
JetExpression operand = arguments.get(0);
while (operand instanceof JetParenthesizedExpression) {
operand = ((JetParenthesizedExpression) operand).getExpression();
}
JetExpression operand = JetPsiUtil.deparenthesize(arguments.get(0));
if (operand instanceof JetReferenceExpression && returnType == Type.INT_TYPE) {
int index = codegen.indexOfLocal((JetReferenceExpression) operand);
if (index >= 0) {
StackValue.preIncrement(index, myDelta).put(returnType, v);
return returnType;
JetType operandType = codegen.getBindingContext().get(EXPRESSION_TYPE, operand);
if (operandType != null && KotlinBuiltIns.getInstance().isPrimitiveType(operandType)) {
StackValue.preIncrement(index, myDelta).put(returnType, v);
return returnType;
}
}
}
StackValue value = codegen.genQualified(receiver, operand);
@@ -0,0 +1,10 @@
fun box(): String {
var x = 1
(@foo x)++
++(@foo x)
(x: Int)++
++(x: Int)
if (x != 5) return "Fail: $x"
return "OK"
}
@@ -0,0 +1,8 @@
fun box(): String {
val l = java.util.ArrayList<Int>()
l.add(1)
var x = l[0]
x = 2
if (x != 2) return "Fail: $x}"
return "OK"
}
@@ -0,0 +1,9 @@
fun box(): String {
val l = java.util.ArrayList<Int>()
l.add(1)
val x = l[0] < 2
if (x != true) return "Fail: $x}"
val y = l[0] compareTo 2
if (y != -1) return "Fail (y): $y}"
return "OK"
}
@@ -0,0 +1,14 @@
fun box(): String {
val l = java.util.ArrayList<Int>()
l.add(1)
var x = l[0]
var y = l[0]
l[0]--
--l[0]
x--
--y
if (l[0] != -1) return "Fail: ${l[0]}"
if (x != 0) return "Fail x: $x"
if (y != 0) return "Fail y: $y"
return "OK"
}
@@ -0,0 +1,7 @@
fun box(): String {
val l = java.util.ArrayList<Int>()
l.add(2)
val x = l[0] / 2
if (x != 1) return "Fail: $x}"
return "OK"
}
@@ -0,0 +1,7 @@
fun box(): String {
val l = java.util.ArrayList<Int>()
l.add(1)
val x = l[0] == 2
if (x != false) return "Fail: $x}"
return "OK"
}
@@ -0,0 +1,7 @@
fun box(): String {
val l = java.util.ArrayList<Int>()
l.add(1)
val x = l[0].hashCode()
if (x != 1) return "Fail: $x}"
return "OK"
}
@@ -0,0 +1,14 @@
fun box(): String {
val l = java.util.ArrayList<Int>()
l.add(1)
var x = l[0]
var y = l[0]
l[0]++
++l[0]
x++
++y
if (l[0] != 3) return "Fail: ${l[0]}"
if (x != 2) return "Fail x: $x"
if (y != 2) return "Fail y: $y"
return "OK"
}
@@ -0,0 +1,7 @@
fun box(): String {
val l = java.util.ArrayList<Int>()
l.add(1)
val x = l[0] - 1
if (x != 0) return "Fail: $x}"
return "OK"
}
@@ -0,0 +1,7 @@
fun box(): String {
val l = java.util.ArrayList<Int>()
l.add(2)
val x = l[0] % 2
if (x != 0) return "Fail: $x}"
return "OK"
}
@@ -0,0 +1,7 @@
fun box(): String {
val l = java.util.ArrayList<Boolean>()
l.add(true)
val x = !l[0]
if (x) return "Fail: $x}"
return "OK"
}
@@ -0,0 +1,7 @@
fun box(): String {
val l = java.util.ArrayList<Int>()
l.add(1)
val x = l[0] != 1
if (x != false) return "Fail: $x}"
return "OK"
}
@@ -0,0 +1,7 @@
fun box(): String {
val l = java.util.ArrayList<Int>()
l.add(1)
val x = l[0] + 1
if (x != 2) return "Fail: $x}"
return "OK"
}
@@ -0,0 +1,10 @@
fun box(): String {
val l = java.util.ArrayList<Int>()
l.add(1)
var x = l[0]
x += 1
l[0] += 1
if (l[0] != 2) return "Fail: ${l[0]}"
if (x != 2) return "Fail: $x}"
return "OK"
}
@@ -0,0 +1,10 @@
fun box(): String {
val l = java.util.ArrayList<Int>()
l.add(2)
val sb = StringBuilder()
for (i in l[0]..3) {
sb.append(i)
}
if (sb.toString() != "23") return "Fail: $sb}"
return "OK"
}
@@ -0,0 +1,7 @@
fun box(): String {
val l = java.util.ArrayList<Int>()
l.add(1)
val x = l[0] * 2
if (x != 2) return "Fail: $x}"
return "OK"
}
@@ -0,0 +1,7 @@
fun box(): String {
val l = java.util.ArrayList<Int>()
l.add(1)
val x = l[0].toShort()
if (x != 1.toShort()) return "Fail: $x}"
return "OK"
}
@@ -0,0 +1,7 @@
fun box(): String {
val l = java.util.ArrayList<Int>()
l.add(1)
val x = "${l[0]}"
if (x != "1") return "Fail: $x}"
return "OK"
}
@@ -0,0 +1,20 @@
fun box(): String {
val l = java.util.ArrayList<Int>()
l.add(1000)
val x = l[0] === 1000
if (x) return "Fail: $x"
val x1 = l[0] === 1
if (x1) return "Fail 1: $x"
val x2 = l[0] === l[0]
if (!x2) return "Fail 2: $x"
val y = l[0] identityEquals 1000
if (y) return "Fail (y): $y"
val y1 = l[0] identityEquals 1
if (y1) return "Fail (y1): $y"
val y2 = l[0] identityEquals l[0]
if (!y2) return "Fail (y2): $y"
return "OK"
}
@@ -0,0 +1,7 @@
fun box(): String {
val l = java.util.ArrayList<Int>()
l.add(1)
val x = -l[0]
if (x != -1) return "Fail: $x"
return "OK"
}
@@ -0,0 +1,7 @@
fun box(): String {
val l = java.util.ArrayList<Int>()
l.add(1)
val x = +l[0]
if (x != 1) return "Fail: $x}"
return "OK"
}
@@ -30,7 +30,7 @@ import java.util.regex.Pattern;
@SuppressWarnings("all")
@TestMetadata("compiler/testData/codegen/box")
@TestDataPath("$PROJECT_ROOT")
@InnerTestClasses({BlackBoxCodegenTestGenerated.Arrays.class, BlackBoxCodegenTestGenerated.BinaryOp.class, BlackBoxCodegenTestGenerated.Bridges.class, BlackBoxCodegenTestGenerated.BuiltinStubMethods.class, BlackBoxCodegenTestGenerated.Casts.class, BlackBoxCodegenTestGenerated.Classes.class, BlackBoxCodegenTestGenerated.Closures.class, BlackBoxCodegenTestGenerated.Constants.class, BlackBoxCodegenTestGenerated.ControlStructures.class, BlackBoxCodegenTestGenerated.DefaultArguments.class, BlackBoxCodegenTestGenerated.DelegatedProperty.class, BlackBoxCodegenTestGenerated.Elvis.class, BlackBoxCodegenTestGenerated.Enum.class, BlackBoxCodegenTestGenerated.ExclExcl.class, BlackBoxCodegenTestGenerated.ExtensionFunctions.class, BlackBoxCodegenTestGenerated.ExtensionProperties.class, BlackBoxCodegenTestGenerated.FakeOverride.class, BlackBoxCodegenTestGenerated.FieldRename.class, BlackBoxCodegenTestGenerated.Finally.class, BlackBoxCodegenTestGenerated.Functions.class, BlackBoxCodegenTestGenerated.InnerNested.class, BlackBoxCodegenTestGenerated.Instructions.class, BlackBoxCodegenTestGenerated.Intrinsics.class, BlackBoxCodegenTestGenerated.JavaInterop.class, BlackBoxCodegenTestGenerated.Labels.class, BlackBoxCodegenTestGenerated.LocalClasses.class, BlackBoxCodegenTestGenerated.MultiDecl.class, BlackBoxCodegenTestGenerated.Objects.class, BlackBoxCodegenTestGenerated.OperatorConventions.class, BlackBoxCodegenTestGenerated.Package.class, BlackBoxCodegenTestGenerated.PrimitiveTypes.class, BlackBoxCodegenTestGenerated.Properties.class, BlackBoxCodegenTestGenerated.Reflection.class, BlackBoxCodegenTestGenerated.Regressions.class, BlackBoxCodegenTestGenerated.SafeCall.class, BlackBoxCodegenTestGenerated.SamConstructors.class, BlackBoxCodegenTestGenerated.Strings.class, BlackBoxCodegenTestGenerated.Super.class, BlackBoxCodegenTestGenerated.SuperConstructorCall.class, BlackBoxCodegenTestGenerated.ToArray.class, BlackBoxCodegenTestGenerated.Traits.class, BlackBoxCodegenTestGenerated.TypeInfo.class, BlackBoxCodegenTestGenerated.TypeMapping.class, BlackBoxCodegenTestGenerated.UnaryOp.class, BlackBoxCodegenTestGenerated.Unit.class, BlackBoxCodegenTestGenerated.Vararg.class, BlackBoxCodegenTestGenerated.When.class})
@InnerTestClasses({BlackBoxCodegenTestGenerated.Arrays.class, BlackBoxCodegenTestGenerated.BinaryOp.class, BlackBoxCodegenTestGenerated.Bridges.class, BlackBoxCodegenTestGenerated.BuiltinStubMethods.class, BlackBoxCodegenTestGenerated.Casts.class, BlackBoxCodegenTestGenerated.Classes.class, BlackBoxCodegenTestGenerated.Closures.class, BlackBoxCodegenTestGenerated.Constants.class, BlackBoxCodegenTestGenerated.ControlStructures.class, BlackBoxCodegenTestGenerated.DefaultArguments.class, BlackBoxCodegenTestGenerated.DelegatedProperty.class, BlackBoxCodegenTestGenerated.Elvis.class, BlackBoxCodegenTestGenerated.Enum.class, BlackBoxCodegenTestGenerated.ExclExcl.class, BlackBoxCodegenTestGenerated.ExtensionFunctions.class, BlackBoxCodegenTestGenerated.ExtensionProperties.class, BlackBoxCodegenTestGenerated.FakeOverride.class, BlackBoxCodegenTestGenerated.FieldRename.class, BlackBoxCodegenTestGenerated.Finally.class, BlackBoxCodegenTestGenerated.Functions.class, BlackBoxCodegenTestGenerated.InnerNested.class, BlackBoxCodegenTestGenerated.Instructions.class, BlackBoxCodegenTestGenerated.Intrinsics.class, BlackBoxCodegenTestGenerated.JavaInterop.class, BlackBoxCodegenTestGenerated.Labels.class, BlackBoxCodegenTestGenerated.LocalClasses.class, BlackBoxCodegenTestGenerated.MultiDecl.class, BlackBoxCodegenTestGenerated.Objects.class, BlackBoxCodegenTestGenerated.OperatorConventions.class, BlackBoxCodegenTestGenerated.Package.class, BlackBoxCodegenTestGenerated.PlatformTypes.class, BlackBoxCodegenTestGenerated.PrimitiveTypes.class, BlackBoxCodegenTestGenerated.Properties.class, BlackBoxCodegenTestGenerated.Reflection.class, BlackBoxCodegenTestGenerated.Regressions.class, BlackBoxCodegenTestGenerated.SafeCall.class, BlackBoxCodegenTestGenerated.SamConstructors.class, BlackBoxCodegenTestGenerated.Strings.class, BlackBoxCodegenTestGenerated.Super.class, BlackBoxCodegenTestGenerated.SuperConstructorCall.class, BlackBoxCodegenTestGenerated.ToArray.class, BlackBoxCodegenTestGenerated.Traits.class, BlackBoxCodegenTestGenerated.TypeInfo.class, BlackBoxCodegenTestGenerated.TypeMapping.class, BlackBoxCodegenTestGenerated.UnaryOp.class, BlackBoxCodegenTestGenerated.Unit.class, BlackBoxCodegenTestGenerated.Vararg.class, BlackBoxCodegenTestGenerated.When.class})
@RunWith(JUnit3RunnerWithInners.class)
public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
public void testAllFilesPresentInBox() throws Exception {
@@ -3955,6 +3955,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
doTest(fileName);
}
@TestMetadata("incWithLabel.kt")
public void testIncWithLabel() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/intrinsics/incWithLabel.kt");
doTest(fileName);
}
@TestMetadata("longRangeWithExplicitDot.kt")
public void testLongRangeWithExplicitDot() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/intrinsics/longRangeWithExplicitDot.kt");
@@ -5218,6 +5224,145 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
}
}
@TestMetadata("compiler/testData/codegen/box/platformTypes")
@TestDataPath("$PROJECT_ROOT")
@InnerTestClasses({PlatformTypes.Primitives.class})
@RunWith(JUnit3RunnerWithInners.class)
public static class PlatformTypes extends AbstractBlackBoxCodegenTest {
public void testAllFilesPresentInPlatformTypes() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/platformTypes"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("compiler/testData/codegen/box/platformTypes/primitives")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Primitives extends AbstractBlackBoxCodegenTest {
public void testAllFilesPresentInPrimitives() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/platformTypes/primitives"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("assign.kt")
public void testAssign() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/platformTypes/primitives/assign.kt");
doTest(fileName);
}
@TestMetadata("compareTo.kt")
public void testCompareTo() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/platformTypes/primitives/compareTo.kt");
doTest(fileName);
}
@TestMetadata("dec.kt")
public void testDec() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/platformTypes/primitives/dec.kt");
doTest(fileName);
}
@TestMetadata("div.kt")
public void testDiv() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/platformTypes/primitives/div.kt");
doTest(fileName);
}
@TestMetadata("equals.kt")
public void testEquals() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/platformTypes/primitives/equals.kt");
doTest(fileName);
}
@TestMetadata("hashCode.kt")
public void testHashCode() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/platformTypes/primitives/hashCode.kt");
doTest(fileName);
}
@TestMetadata("inc.kt")
public void testInc() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/platformTypes/primitives/inc.kt");
doTest(fileName);
}
@TestMetadata("minus.kt")
public void testMinus() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/platformTypes/primitives/minus.kt");
doTest(fileName);
}
@TestMetadata("mod.kt")
public void testMod() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/platformTypes/primitives/mod.kt");
doTest(fileName);
}
@TestMetadata("not.kt")
public void testNot() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/platformTypes/primitives/not.kt");
doTest(fileName);
}
@TestMetadata("notEquals.kt")
public void testNotEquals() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/platformTypes/primitives/notEquals.kt");
doTest(fileName);
}
@TestMetadata("plus.kt")
public void testPlus() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/platformTypes/primitives/plus.kt");
doTest(fileName);
}
@TestMetadata("plusAssign.kt")
public void testPlusAssign() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/platformTypes/primitives/plusAssign.kt");
doTest(fileName);
}
@TestMetadata("rangeTo.kt")
public void testRangeTo() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/platformTypes/primitives/rangeTo.kt");
doTest(fileName);
}
@TestMetadata("times.kt")
public void testTimes() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/platformTypes/primitives/times.kt");
doTest(fileName);
}
@TestMetadata("toShort.kt")
public void testToShort() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/platformTypes/primitives/toShort.kt");
doTest(fileName);
}
@TestMetadata("toString.kt")
public void testToString() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/platformTypes/primitives/toString.kt");
doTest(fileName);
}
@TestMetadata("udentityEquals.kt")
public void testUdentityEquals() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/platformTypes/primitives/udentityEquals.kt");
doTest(fileName);
}
@TestMetadata("unaryMinus.kt")
public void testUnaryMinus() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/platformTypes/primitives/unaryMinus.kt");
doTest(fileName);
}
@TestMetadata("unaryPlus.kt")
public void testUnaryPlus() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/platformTypes/primitives/unaryPlus.kt");
doTest(fileName);
}
}
}
@TestMetadata("compiler/testData/codegen/box/primitiveTypes")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)