KT-998: wrong codegen for labeled continue/break
This commit is contained in:
@@ -65,10 +65,12 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
static class LoopBlockStackElement extends BlockStackElement {
|
static class LoopBlockStackElement extends BlockStackElement {
|
||||||
final Label continueLabel;
|
final Label continueLabel;
|
||||||
final Label breakLabel;
|
final Label breakLabel;
|
||||||
|
public JetSimpleNameExpression targetLabel;
|
||||||
|
|
||||||
LoopBlockStackElement(Label breakLabel, Label continueLabel) {
|
LoopBlockStackElement(Label breakLabel, Label continueLabel, JetSimpleNameExpression targetLabel) {
|
||||||
this.breakLabel = breakLabel;
|
this.breakLabel = breakLabel;
|
||||||
this.continueLabel = continueLabel;
|
this.continueLabel = continueLabel;
|
||||||
|
this.targetLabel = targetLabel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -258,7 +260,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
v.mark(condition);
|
v.mark(condition);
|
||||||
|
|
||||||
Label end = continueLabel != null ? continueLabel : new Label();
|
Label end = continueLabel != null ? continueLabel : new Label();
|
||||||
blockStackElements.push(new LoopBlockStackElement(end, condition));
|
blockStackElements.push(new LoopBlockStackElement(end, condition, targetLabel(expression)));
|
||||||
|
|
||||||
Label savedContinueLabel = continueLabel;
|
Label savedContinueLabel = continueLabel;
|
||||||
continueLabel = condition;
|
continueLabel = condition;
|
||||||
@@ -278,14 +280,15 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
return StackValue.onStack(Type.VOID_TYPE);
|
return StackValue.onStack(Type.VOID_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StackValue visitDoWhileExpression(JetDoWhileExpression expression, StackValue receiver) {
|
public StackValue visitDoWhileExpression(JetDoWhileExpression expression, StackValue receiver) {
|
||||||
Label condition = new Label();
|
Label condition = new Label();
|
||||||
v.mark(condition);
|
v.mark(condition);
|
||||||
|
|
||||||
Label end = new Label();
|
Label end = new Label();
|
||||||
|
|
||||||
blockStackElements.push(new LoopBlockStackElement(end, condition));
|
blockStackElements.push(new LoopBlockStackElement(end, condition, targetLabel(expression)));
|
||||||
|
|
||||||
gen(expression.getBody(), Type.VOID_TYPE);
|
gen(expression.getBody(), Type.VOID_TYPE);
|
||||||
|
|
||||||
@@ -356,7 +359,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Label begin = new Label();
|
Label begin = new Label();
|
||||||
blockStackElements.push(new LoopBlockStackElement(end, begin));
|
blockStackElements.push(new LoopBlockStackElement(end, begin, targetLabel(expression)));
|
||||||
|
|
||||||
v.mark(begin);
|
v.mark(begin);
|
||||||
v.load(iteratorVar, asmIterType);
|
v.load(iteratorVar, asmIterType);
|
||||||
@@ -426,7 +429,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
Label increment = new Label();
|
Label increment = new Label();
|
||||||
v.mark(condition);
|
v.mark(condition);
|
||||||
|
|
||||||
blockStackElements.push(new LoopBlockStackElement(end, increment));
|
blockStackElements.push(new LoopBlockStackElement(end, increment, targetLabel(expression)));
|
||||||
|
|
||||||
generateCondition(asmParamType, end);
|
generateCondition(asmParamType, end);
|
||||||
|
|
||||||
@@ -607,9 +610,10 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
}
|
}
|
||||||
else if(stackElement instanceof LoopBlockStackElement) {
|
else if(stackElement instanceof LoopBlockStackElement) {
|
||||||
LoopBlockStackElement loopBlockStackElement = (LoopBlockStackElement) stackElement;
|
LoopBlockStackElement loopBlockStackElement = (LoopBlockStackElement) stackElement;
|
||||||
Label label = labelElement == null ? loopBlockStackElement.breakLabel : null; // TODO:
|
if (labelElement == null || loopBlockStackElement.targetLabel != null && labelElement.getReferencedName().equals(loopBlockStackElement.targetLabel.getReferencedName())) {
|
||||||
v.goTo(label);
|
v.goTo(loopBlockStackElement.breakLabel);
|
||||||
return StackValue.none();
|
return StackValue.none();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
@@ -632,9 +636,10 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
}
|
}
|
||||||
else if(stackElement instanceof LoopBlockStackElement) {
|
else if(stackElement instanceof LoopBlockStackElement) {
|
||||||
LoopBlockStackElement loopBlockStackElement = (LoopBlockStackElement) stackElement;
|
LoopBlockStackElement loopBlockStackElement = (LoopBlockStackElement) stackElement;
|
||||||
Label label = labelElement == null ? loopBlockStackElement.continueLabel : null; // TODO:
|
if (labelElement == null || loopBlockStackElement.targetLabel != null && labelElement.getReferencedName().equals(loopBlockStackElement.targetLabel.getReferencedName())) {
|
||||||
v.goTo(label);
|
v.goTo(loopBlockStackElement.continueLabel);
|
||||||
return StackValue.none();
|
return StackValue.none();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
@@ -1960,8 +1965,24 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
v.invokevirtual("java/lang/StringBuilder", "append", appendDescriptor.getDescriptor());
|
v.invokevirtual("java/lang/StringBuilder", "append", appendDescriptor.getDescriptor());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private JetSimpleNameExpression targetLabel(JetExpression expression) {
|
||||||
|
if(expression.getParent() instanceof JetPrefixExpression) {
|
||||||
|
JetPrefixExpression parent = (JetPrefixExpression) expression.getParent();
|
||||||
|
JetSimpleNameExpression operationSign = parent.getOperationReference();
|
||||||
|
if (JetTokens.LABELS.contains(operationSign.getReferencedNameElementType())) {
|
||||||
|
return operationSign;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StackValue visitPrefixExpression(JetPrefixExpression expression, StackValue receiver) {
|
public StackValue visitPrefixExpression(JetPrefixExpression expression, StackValue receiver) {
|
||||||
|
JetSimpleNameExpression operationSign = expression.getOperationReference();
|
||||||
|
if (JetTokens.LABELS.contains(operationSign.getReferencedNameElementType())) {
|
||||||
|
return genQualified(receiver, expression.getBaseExpression());
|
||||||
|
}
|
||||||
|
|
||||||
DeclarationDescriptor op = bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getOperationReference());
|
DeclarationDescriptor op = bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getOperationReference());
|
||||||
final Callable callable = resolveToCallable(op, false);
|
final Callable callable = resolveToCallable(op, false);
|
||||||
if (callable instanceof IntrinsicMethod) {
|
if (callable instanceof IntrinsicMethod) {
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
fun findPairless(a : IntArray) : Int {
|
||||||
|
@loop for (i in a.indices) {
|
||||||
|
for (j in a.indices) {
|
||||||
|
if (i != j && a[i] == a[j]) continue@loop
|
||||||
|
}
|
||||||
|
return a[i]
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
fun hasDuplicates(a : IntArray) : Boolean {
|
||||||
|
var duplicate = false
|
||||||
|
@loop for (i in a.indices) {
|
||||||
|
for (j in a.indices) {
|
||||||
|
if (i != j && a[i] == a[j]) {
|
||||||
|
duplicate = true
|
||||||
|
break@loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return a[i]
|
||||||
|
}
|
||||||
|
return duplicate
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box() : String {
|
||||||
|
val a = IntArray(5)
|
||||||
|
a[0] = 0
|
||||||
|
a[1] = 0
|
||||||
|
a[2] = 1
|
||||||
|
a[3] = 1
|
||||||
|
a[4] = 5
|
||||||
|
if(findPairless(a) != 5) return "fail"
|
||||||
|
return if(hasDuplicates(a)) "OK" else "fail"
|
||||||
|
|
||||||
|
}
|
||||||
@@ -266,4 +266,8 @@ public class ControlStructuresTest extends CodegenTestCase {
|
|||||||
public void testKt1076() throws Exception {
|
public void testKt1076() throws Exception {
|
||||||
blackBoxFile("regressions/kt1076.kt");
|
blackBoxFile("regressions/kt1076.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testKt998() throws Exception {
|
||||||
|
blackBoxFile("regressions/kt998.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user