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:
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user