diff --git a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index b6644d44924..8809b85b14e 100644 --- a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -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; } diff --git a/idea/src/org/jetbrains/jet/codegen/StackValue.java b/idea/src/org/jetbrains/jet/codegen/StackValue.java index 1c1e2a0988e..29fe0156015 100644 --- a/idea/src/org/jetbrains/jet/codegen/StackValue.java +++ b/idea/src/org/jetbrains/jet/codegen/StackValue.java @@ -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()); } } diff --git a/idea/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java b/idea/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java index 7804e64cf64..16698be6a7a 100644 --- a/idea/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java +++ b/idea/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java @@ -338,10 +338,18 @@ public class NamespaceGenTest extends CodegenTestCase { public void testArrayWrite() throws Exception { loadText("fun foo(c: Array) { 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) { 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]); + } }