don't generate direct increment and similar bytecodes for variables which are captured in closure (KT-1980)
This commit is contained in:
@@ -1635,6 +1635,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
|
|
||||||
public int indexOfLocal(JetReferenceExpression lhs) {
|
public int indexOfLocal(JetReferenceExpression lhs) {
|
||||||
final DeclarationDescriptor declarationDescriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, lhs);
|
final DeclarationDescriptor declarationDescriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, lhs);
|
||||||
|
if (typeMapper.isVarCapturedInClosure(declarationDescriptor)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
return lookupLocal(declarationDescriptor);
|
return lookupLocal(declarationDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1033,17 +1033,17 @@ public class JetTypeMapper {
|
|||||||
else if (descriptor instanceof FunctionDescriptor) {
|
else if (descriptor instanceof FunctionDescriptor) {
|
||||||
return StackValue.sharedTypeForType(mapType(((FunctionDescriptor) descriptor).getReceiverParameter().getType(), MapTypeMode.VALUE));
|
return StackValue.sharedTypeForType(mapType(((FunctionDescriptor) descriptor).getReceiverParameter().getType(), MapTypeMode.VALUE));
|
||||||
}
|
}
|
||||||
else if (descriptor instanceof VariableDescriptor) {
|
else if (descriptor instanceof VariableDescriptor && isVarCapturedInClosure(descriptor)) {
|
||||||
VariableDescriptor variableDescriptor = (VariableDescriptor) descriptor;
|
JetType outType = ((VariableDescriptor) descriptor).getType();
|
||||||
Boolean aBoolean = bindingContext.get(BindingContext.CAPTURED_IN_CLOSURE, variableDescriptor);
|
return StackValue.sharedTypeForType(mapType(outType, MapTypeMode.VALUE));
|
||||||
if (aBoolean != null && aBoolean && variableDescriptor.isVar()) {
|
|
||||||
JetType outType = variableDescriptor.getType();
|
|
||||||
return StackValue.sharedTypeForType(mapType(outType, MapTypeMode.VALUE));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isVarCapturedInClosure(DeclarationDescriptor descriptor) {
|
||||||
|
if (!(descriptor instanceof VariableDescriptor) || descriptor instanceof PropertyDescriptor) return false;
|
||||||
|
VariableDescriptor variableDescriptor = (VariableDescriptor) descriptor;
|
||||||
|
Boolean aBoolean = bindingContext.get(BindingContext.CAPTURED_IN_CLOSURE, variableDescriptor);
|
||||||
|
return aBoolean != null && aBoolean && variableDescriptor.isVar();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
import java.util.*
|
||||||
|
|
||||||
|
public inline fun Int.times(body : () -> Unit) {
|
||||||
|
var count = this;
|
||||||
|
while (count > 0) {
|
||||||
|
body()
|
||||||
|
count--
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun calc() : Int {
|
||||||
|
val a = ArrayList<()->Int>()
|
||||||
|
2.times {
|
||||||
|
var j = 1
|
||||||
|
a.add({ j })
|
||||||
|
++j
|
||||||
|
}
|
||||||
|
var sum = 0
|
||||||
|
for (f in a) {
|
||||||
|
val g = f as () -> Int
|
||||||
|
sum += g()
|
||||||
|
}
|
||||||
|
return sum
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box() : String {
|
||||||
|
val x = calc()
|
||||||
|
return if (x == 4) "OK" else x.toString()
|
||||||
|
}
|
||||||
@@ -391,4 +391,9 @@ public class ClassGenTest extends CodegenTestCase {
|
|||||||
createEnvironmentWithMockJdkAndIdeaAnnotations(CompilerSpecialMode.JDK_HEADERS);
|
createEnvironmentWithMockJdkAndIdeaAnnotations(CompilerSpecialMode.JDK_HEADERS);
|
||||||
blackBoxFile("regressions/kt1918.kt");
|
blackBoxFile("regressions/kt1918.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testKt1980() throws Exception {
|
||||||
|
createEnvironmentWithMockJdkAndIdeaAnnotations(CompilerSpecialMode.JDK_HEADERS);
|
||||||
|
blackBoxFile("regressions/kt1980.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user