attempt to fix KT-2251
This commit is contained in:
@@ -2697,6 +2697,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
v.iconst(increment);
|
v.iconst(increment);
|
||||||
|
asmType = Type.INT_TYPE;
|
||||||
}
|
}
|
||||||
v.add(asmType);
|
v.add(asmType);
|
||||||
value.store(asmType, v);
|
value.store(asmType, v);
|
||||||
@@ -3202,7 +3203,7 @@ The "returned" value of try expression with no finally is either the last expres
|
|||||||
condType = asmType(condJetType);
|
condType = asmType(condJetType);
|
||||||
if (!(CodegenUtil.isNumberPrimitive(condType) || condType.getSort() == Type.BOOLEAN)) {
|
if (!(CodegenUtil.isNumberPrimitive(condType) || condType.getSort() == Type.BOOLEAN)) {
|
||||||
subjectType = boxType(subjectType);
|
subjectType = boxType(subjectType);
|
||||||
expressionToMatch.coerce(subjectType, v);
|
expressionToMatch.coerceTo(subjectType, v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ public abstract class StackValue {
|
|||||||
|
|
||||||
public void condJump(Label label, boolean jumpIfFalse, InstructionAdapter v) {
|
public void condJump(Label label, boolean jumpIfFalse, InstructionAdapter v) {
|
||||||
put(this.type, v);
|
put(this.type, v);
|
||||||
coerce(Type.BOOLEAN_TYPE, v);
|
coerceTo(Type.BOOLEAN_TYPE, v);
|
||||||
if (jumpIfFalse) {
|
if (jumpIfFalse) {
|
||||||
v.ifeq(label);
|
v.ifeq(label);
|
||||||
}
|
}
|
||||||
@@ -231,7 +231,7 @@ public abstract class StackValue {
|
|||||||
v.checkcast(type);
|
v.checkcast(type);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
coerce(type, v);
|
coerceTo(type, v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -244,10 +244,14 @@ public abstract class StackValue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void coerce(Type toType, InstructionAdapter v) {
|
protected void coerceTo(Type toType, InstructionAdapter v) {
|
||||||
coerce(this.type, toType, v);
|
coerce(this.type, toType, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void coerceFrom(Type topOfStackType, InstructionAdapter v) {
|
||||||
|
coerce(topOfStackType, this.type, v);
|
||||||
|
}
|
||||||
|
|
||||||
protected static void coerce(Type fromType, Type toType, InstructionAdapter v) {
|
protected static void coerce(Type fromType, Type toType, InstructionAdapter v) {
|
||||||
if (toType.equals(fromType)) return;
|
if (toType.equals(fromType)) return;
|
||||||
|
|
||||||
@@ -382,7 +386,7 @@ public abstract class StackValue {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void put(Type type, InstructionAdapter v) {
|
public void put(Type type, InstructionAdapter v) {
|
||||||
coerce(type, v);
|
coerceTo(type, v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -401,13 +405,13 @@ public abstract class StackValue {
|
|||||||
@Override
|
@Override
|
||||||
public void put(Type type, InstructionAdapter v) {
|
public void put(Type type, InstructionAdapter v) {
|
||||||
v.load(index, this.type);
|
v.load(index, this.type);
|
||||||
coerce(type, v);
|
coerceTo(type, v);
|
||||||
// TODO unbox
|
// TODO unbox
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void store(Type topOfStackType, InstructionAdapter v) {
|
public void store(Type topOfStackType, InstructionAdapter v) {
|
||||||
coerce(topOfStackType, this.type, v);
|
coerceFrom(topOfStackType, v);
|
||||||
v.store(index, this.type);
|
v.store(index, this.type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -419,7 +423,7 @@ public abstract class StackValue {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void put(Type type, InstructionAdapter v) {
|
public void put(Type type, InstructionAdapter v) {
|
||||||
coerce(type, v);
|
coerceTo(type, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -465,7 +469,7 @@ public abstract class StackValue {
|
|||||||
else {
|
else {
|
||||||
v.aconst(value);
|
v.aconst(value);
|
||||||
}
|
}
|
||||||
coerce(type, v);
|
coerceTo(type, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -616,12 +620,12 @@ public abstract class StackValue {
|
|||||||
@Override
|
@Override
|
||||||
public void put(Type type, InstructionAdapter v) {
|
public void put(Type type, InstructionAdapter v) {
|
||||||
v.aload(boxed); // assumes array and index are on the stack
|
v.aload(boxed); // assumes array and index are on the stack
|
||||||
onStack(boxed).coerce(type, v);
|
coerce(boxed, type, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void store(Type topOfStackType, InstructionAdapter v) {
|
public void store(Type topOfStackType, InstructionAdapter v) {
|
||||||
onStack(type).coerce(boxed, v);
|
coerce(topOfStackType, boxed, v);
|
||||||
v.astore(boxed);
|
v.astore(boxed);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -677,7 +681,7 @@ public abstract class StackValue {
|
|||||||
else {
|
else {
|
||||||
((IntrinsicMethod) getter).generate(codegen, v, type, null, null, null, state);
|
((IntrinsicMethod) getter).generate(codegen, v, type, null, null, null, state);
|
||||||
}
|
}
|
||||||
coerce(type, v);
|
coerceTo(type, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -901,7 +905,7 @@ public abstract class StackValue {
|
|||||||
@Override
|
@Override
|
||||||
public void put(Type type, InstructionAdapter v) {
|
public void put(Type type, InstructionAdapter v) {
|
||||||
v.visitFieldInsn(isStatic ? GETSTATIC : GETFIELD, owner.getInternalName(), name, this.type.getDescriptor());
|
v.visitFieldInsn(isStatic ? GETSTATIC : GETFIELD, owner.getInternalName(), name, this.type.getDescriptor());
|
||||||
coerce(type, v);
|
coerceTo(type, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -918,7 +922,7 @@ public abstract class StackValue {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void store(Type topOfStackType, InstructionAdapter v) {
|
public void store(Type topOfStackType, InstructionAdapter v) {
|
||||||
coerce(topOfStackType, this.type, v);
|
coerceFrom(topOfStackType, v);
|
||||||
v.visitFieldInsn(isStatic ? PUTSTATIC : PUTFIELD, owner.getInternalName(), name, this.type.getDescriptor());
|
v.visitFieldInsn(isStatic ? PUTSTATIC : PUTFIELD, owner.getInternalName(), name, this.type.getDescriptor());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -976,11 +980,12 @@ public abstract class StackValue {
|
|||||||
v.visitMethodInsn(invokeOpcode, methodOwner.getInternalName(), getter.getName(), getter.getDescriptor());
|
v.visitMethodInsn(invokeOpcode, methodOwner.getInternalName(), getter.getName(), getter.getDescriptor());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
coerce(type, v);
|
coerceTo(type, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void store(Type topOfStackType, InstructionAdapter v) {
|
public void store(Type topOfStackType, InstructionAdapter v) {
|
||||||
|
coerceFrom(topOfStackType, v);
|
||||||
if (isSuper && isInterface) {
|
if (isSuper && isInterface) {
|
||||||
assert setter != null;
|
assert setter != null;
|
||||||
v.visitMethodInsn(INVOKESTATIC, methodOwner.getInternalName(), setter.getName(),
|
v.visitMethodInsn(INVOKESTATIC, methodOwner.getInternalName(), setter.getName(),
|
||||||
@@ -1047,8 +1052,8 @@ public abstract class StackValue {
|
|||||||
Type refType = refType(this.type);
|
Type refType = refType(this.type);
|
||||||
Type sharedType = sharedTypeForType(this.type);
|
Type sharedType = sharedTypeForType(this.type);
|
||||||
v.visitFieldInsn(GETFIELD, sharedType.getInternalName(), "ref", refType.getDescriptor());
|
v.visitFieldInsn(GETFIELD, sharedType.getInternalName(), "ref", refType.getDescriptor());
|
||||||
coerce(refType, this.type, v);
|
coerceFrom(refType, v);
|
||||||
coerce(this.type, type, v);
|
coerceTo(type, v);
|
||||||
if (isReleaseOnPut) {
|
if (isReleaseOnPut) {
|
||||||
v.aconst(null);
|
v.aconst(null);
|
||||||
v.store(index, OBJECT_TYPE);
|
v.store(index, OBJECT_TYPE);
|
||||||
@@ -1057,6 +1062,7 @@ public abstract class StackValue {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void store(Type topOfStackType, InstructionAdapter v) {
|
public void store(Type topOfStackType, InstructionAdapter v) {
|
||||||
|
coerceFrom(topOfStackType, v);
|
||||||
v.load(index, OBJECT_TYPE);
|
v.load(index, OBJECT_TYPE);
|
||||||
v.swap();
|
v.swap();
|
||||||
Type refType = refType(this.type);
|
Type refType = refType(this.type);
|
||||||
@@ -1133,13 +1139,13 @@ public abstract class StackValue {
|
|||||||
Type sharedType = sharedTypeForType(this.type);
|
Type sharedType = sharedTypeForType(this.type);
|
||||||
Type refType = refType(this.type);
|
Type refType = refType(this.type);
|
||||||
v.visitFieldInsn(GETFIELD, sharedType.getInternalName(), "ref", refType.getDescriptor());
|
v.visitFieldInsn(GETFIELD, sharedType.getInternalName(), "ref", refType.getDescriptor());
|
||||||
StackValue.onStack(refType).coerce(this.type, v);
|
coerceFrom(refType, v);
|
||||||
StackValue.onStack(this.type).coerce(type, v);
|
coerceTo(type, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void store(Type topOfStackType, InstructionAdapter v) {
|
public void store(Type topOfStackType, InstructionAdapter v) {
|
||||||
coerce(topOfStackType, v);
|
coerceFrom(topOfStackType, v);
|
||||||
v.visitFieldInsn(PUTFIELD, sharedTypeForType(type).getInternalName(), "ref", refType(type).getDescriptor());
|
v.visitFieldInsn(PUTFIELD, sharedTypeForType(type).getInternalName(), "ref", refType(type).getDescriptor());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1200,7 +1206,7 @@ public abstract class StackValue {
|
|||||||
public void put(Type type, InstructionAdapter v) {
|
public void put(Type type, InstructionAdapter v) {
|
||||||
if (!type.equals(Type.VOID_TYPE)) {
|
if (!type.equals(Type.VOID_TYPE)) {
|
||||||
v.load(index, Type.INT_TYPE);
|
v.load(index, Type.INT_TYPE);
|
||||||
coerce(type, v);
|
coerceTo(type, v);
|
||||||
}
|
}
|
||||||
v.iinc(index, increment);
|
v.iinc(index, increment);
|
||||||
}
|
}
|
||||||
@@ -1221,7 +1227,7 @@ public abstract class StackValue {
|
|||||||
v.iinc(index, increment);
|
v.iinc(index, increment);
|
||||||
if (!type.equals(Type.VOID_TYPE)) {
|
if (!type.equals(Type.VOID_TYPE)) {
|
||||||
v.load(index, Type.INT_TYPE);
|
v.load(index, Type.INT_TYPE);
|
||||||
coerce(type, v);
|
coerceTo(type, v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
fun box() : String {
|
||||||
|
var x = 20.toByte()
|
||||||
|
var y = 20.toByte()
|
||||||
|
val foo = {
|
||||||
|
x++
|
||||||
|
++x
|
||||||
|
}
|
||||||
|
|
||||||
|
if(++x != 21.toByte() || x++ != 21.toByte() || foo() != 24.toByte() || x != 24.toByte()) return "shared byte fail"
|
||||||
|
if(++y != 21.toByte() || y++ != 21.toByte() || y != 22.toByte()) return "byte fail"
|
||||||
|
|
||||||
|
var xs = 20.toShort()
|
||||||
|
var ys = 20.toShort()
|
||||||
|
val foos = {
|
||||||
|
xs++
|
||||||
|
++xs
|
||||||
|
}
|
||||||
|
|
||||||
|
if(++xs != 21.toShort() || xs++ != 21.toShort() || foos() != 24.toShort() || xs != 24.toShort()) return "shared short fail"
|
||||||
|
if(++ys != 21.toShort() || ys++ != 21.toShort() || ys != 22.toShort()) return "short fail"
|
||||||
|
|
||||||
|
var xc = 20.toChar()
|
||||||
|
var yc = 20.toChar()
|
||||||
|
val fooc = {
|
||||||
|
xc++
|
||||||
|
++xc
|
||||||
|
}
|
||||||
|
|
||||||
|
if(++xc != 21.toChar() || xc++ != 21.toChar() || fooc() != 24.toChar() || xc != 24.toChar()) return "shared char fail"
|
||||||
|
if(++yc != 21.toChar() || yc++ != 21.toChar() || yc != 22.toChar()) return "char fail"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
@@ -448,4 +448,9 @@ public class PrimitiveTypesTest extends CodegenTestCase {
|
|||||||
public void testEmptyRanges() throws Exception {
|
public void testEmptyRanges() throws Exception {
|
||||||
blackBoxFile("emptyRanges.kt");
|
blackBoxFile("emptyRanges.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void test2251() throws Exception {
|
||||||
|
blackBoxFile("regressions/kt2251.kt");
|
||||||
|
System.out.println(generateToText());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user