if a shared variable is a result of the block, release it only after it has been put

#KT-2151 Fixed
This commit is contained in:
Dmitry Jemerov
2012-06-08 17:58:09 +02:00
parent 56310599a5
commit 8baae95531
4 changed files with 37 additions and 4 deletions
@@ -917,8 +917,13 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
final Type sharedVarType = typeMapper.getSharedVarType(variableDescriptor);
final Type type = sharedVarType != null ? sharedVarType : asmType(variableDescriptor.getType());
if(sharedVarType != null) {
v.aconst(null);
v.store(index, TYPE_OBJECT);
if (answer instanceof StackValue.Shared && index == ((StackValue.Shared) answer).getIndex()) {
((StackValue.Shared) answer).releaseOnPut();
}
else {
v.aconst(null);
v.store(index, TYPE_OBJECT);
}
}
v.visitLocalVariable(var.getName(), type.getDescriptor(), null, blockStart, blockEnd, index);
@@ -924,20 +924,33 @@ public abstract class StackValue {
public static class Shared extends StackValue {
private final int index;
private boolean isReleaseOnPut = false;
public Shared(int index, Type type) {
super(type);
this.index = index;
}
public void releaseOnPut() {
isReleaseOnPut = true;
}
public int getIndex() {
return index;
}
@Override
public void put(Type type, InstructionAdapter v) {
v.load(index, JetTypeMapper.TYPE_OBJECT);
Type refType = refType(this.type);
Type sharedType = sharedTypeForType(this.type);
v.visitFieldInsn(Opcodes.GETFIELD, sharedType.getInternalName(), "ref", refType.getDescriptor());
StackValue.onStack(refType).coerce(this.type, v);
StackValue.onStack(this.type).coerce(type, v);
coerce(refType, this.type, v);
coerce(this.type, type, v);
if (isReleaseOnPut) {
v.aconst(null);
v.store(index, JetTypeMapper.TYPE_OBJECT);
}
}
@Override
@@ -0,0 +1,11 @@
fun foo(): String {
return if (true) {
var x = "OK"
fun foo() { x += "fail" }
x
} else "fail"
}
fun box(): String {
return foo()
}
@@ -62,4 +62,8 @@ public class ClosuresGenTest extends CodegenTestCase {
public void testEnclosingThis() throws Exception {
blackBoxFile("classes/enclosingThis.jet");
}
public void testKt2151() {
blackBoxFile("regressions/kt2151.kt");
}
}