augmented assignments for arrays; replace the hack of "value before receiver" with a lesser hack of dupReceiver()
This commit is contained in:
@@ -781,7 +781,7 @@ public class ExpressionCodegen extends JetVisitor {
|
||||
private void generateAssignmentExpression(JetBinaryExpression expression) {
|
||||
StackValue stackValue = generateIntermediateValue(expression.getLeft());
|
||||
genToJVMStack(expression.getRight());
|
||||
stackValue.store(v, false);
|
||||
stackValue.store(v);
|
||||
}
|
||||
|
||||
private void generateAugmentedAssignment(JetBinaryExpression expression) {
|
||||
@@ -789,11 +789,11 @@ public class ExpressionCodegen extends JetVisitor {
|
||||
final JetExpression lhs = expression.getLeft();
|
||||
Type asmType = expressionType(lhs);
|
||||
StackValue value = generateIntermediateValue(lhs);
|
||||
value.dupReceiver(v);
|
||||
value.put(asmType, v);
|
||||
genToJVMStack(expression.getRight());
|
||||
v.visitInsn(asmType.getOpcode(opcodeForMethod(op.getName())));
|
||||
value = generateIntermediateValue(lhs);
|
||||
value.store(v, true);
|
||||
value.store(v);
|
||||
}
|
||||
|
||||
private void generateConcatenation(JetBinaryExpression expression) {
|
||||
@@ -896,6 +896,7 @@ public class ExpressionCodegen extends JetVisitor {
|
||||
}
|
||||
}
|
||||
StackValue value = generateIntermediateValue(operand);
|
||||
value.dupReceiver(v);
|
||||
value.put(asmType, v);
|
||||
if (asmType == Type.LONG_TYPE) {
|
||||
v.aconst(Long.valueOf(increment));
|
||||
@@ -910,8 +911,7 @@ public class ExpressionCodegen extends JetVisitor {
|
||||
v.aconst(increment);
|
||||
}
|
||||
v.add(asmType);
|
||||
value = generateIntermediateValue(operand);
|
||||
value.store(v, true);
|
||||
value.store(v);
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,10 +19,13 @@ public abstract class StackValue {
|
||||
|
||||
public abstract void put(Type type, InstructionAdapter v);
|
||||
|
||||
public void store(InstructionAdapter v, boolean valueBeforeReceiver) {
|
||||
public void store(InstructionAdapter v) {
|
||||
throw new UnsupportedOperationException("cannot store to value " + this);
|
||||
}
|
||||
|
||||
public void dupReceiver(InstructionAdapter v) {
|
||||
}
|
||||
|
||||
public void condJump(Label label, boolean jumpIfFalse, InstructionAdapter v) {
|
||||
if (this.type == Type.BOOLEAN_TYPE) {
|
||||
put(Type.BOOLEAN_TYPE, v);
|
||||
@@ -160,7 +163,7 @@ public abstract class StackValue {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void store(InstructionAdapter v, boolean valueBeforeReceiver) {
|
||||
public void store(InstructionAdapter v) {
|
||||
v.store(index, this.type);
|
||||
}
|
||||
}
|
||||
@@ -328,9 +331,14 @@ public abstract class StackValue {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void store(InstructionAdapter v, boolean valueBeforeReceiver) {
|
||||
public void store(InstructionAdapter v) {
|
||||
v.astore(type); // assumes array and index are on the stack
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dupReceiver(InstructionAdapter v) {
|
||||
v.dup2(); // array and index
|
||||
}
|
||||
}
|
||||
|
||||
private static class Field extends StackValue {
|
||||
@@ -351,11 +359,12 @@ public abstract class StackValue {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void store(InstructionAdapter v, boolean valueBeforeReceiver) {
|
||||
// HACK should find some way to avoid this swap
|
||||
if (valueBeforeReceiver && !isStatic) {
|
||||
v.swap();
|
||||
}
|
||||
public void dupReceiver(InstructionAdapter v) {
|
||||
if (!isStatic) v.dup();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void store(InstructionAdapter v) {
|
||||
v.visitFieldInsn(isStatic ? Opcodes.PUTSTATIC : Opcodes.PUTFIELD, owner, name, this.type.getDescriptor());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -338,10 +338,18 @@ public class NamespaceGenTest extends CodegenTestCase {
|
||||
|
||||
public void testArrayWrite() throws Exception {
|
||||
loadText("fun foo(c: Array<String>) { c[0] = \"jet\"; }");
|
||||
System.out.println(generateToText());
|
||||
final Method main = generateFunction();
|
||||
String[] array = new String[] { null };
|
||||
main.invoke(null, new Object[] { array });
|
||||
assertEquals("jet", array[0]);
|
||||
}
|
||||
|
||||
public void testArrayAugAssign() throws Exception {
|
||||
loadText("fun foo(c: Array<Int>) { c[0] *= 2 }");
|
||||
System.out.println(generateToText());
|
||||
final Method main = generateFunction();
|
||||
int[] data = new int[] { 5 };
|
||||
main.invoke(null, new Object[] { data });
|
||||
assertEquals(10, data[0]);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user