Merge "[CF] Various instruction used in barray.BArray example."
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfArrayLoad.java b/src/main/java/com/android/tools/r8/cf/code/CfArrayLoad.java
new file mode 100644
index 0000000..9043ab6
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/cf/code/CfArrayLoad.java
@@ -0,0 +1,47 @@
+// Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package com.android.tools.r8.cf.code;
+
+import com.android.tools.r8.errors.Unreachable;
+import com.android.tools.r8.ir.code.MemberType;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+
+public class CfArrayLoad extends CfInstruction {
+
+  private final MemberType type;
+
+  public CfArrayLoad(MemberType type) {
+    this.type = type;
+  }
+
+  private int getLoadType() {
+    switch (type) {
+      case OBJECT:
+        return Opcodes.AALOAD;
+      case BYTE:
+      case BOOLEAN:
+        return Opcodes.BALOAD;
+      case CHAR:
+        return Opcodes.CALOAD;
+      case SHORT:
+        return Opcodes.SALOAD;
+      case INT:
+        return Opcodes.IALOAD;
+      case FLOAT:
+        return Opcodes.FALOAD;
+      case LONG:
+        return Opcodes.LALOAD;
+      case DOUBLE:
+        return Opcodes.DALOAD;
+      default:
+        throw new Unreachable("Unexpected type " + type);
+    }
+  }
+
+  @Override
+  public void write(MethodVisitor visitor) {
+    visitor.visitInsn(getLoadType());
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfConstNull.java b/src/main/java/com/android/tools/r8/cf/code/CfConstNull.java
new file mode 100644
index 0000000..f022f78
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/cf/code/CfConstNull.java
@@ -0,0 +1,15 @@
+// Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package com.android.tools.r8.cf.code;
+
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+
+public class CfConstNull extends CfInstruction {
+
+  @Override
+  public void write(MethodVisitor visitor) {
+    visitor.visitInsn(Opcodes.ACONST_NULL);
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfNew.java b/src/main/java/com/android/tools/r8/cf/code/CfNew.java
new file mode 100644
index 0000000..b528ea5
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/cf/code/CfNew.java
@@ -0,0 +1,23 @@
+// Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package com.android.tools.r8.cf.code;
+
+import com.android.tools.r8.graph.DexType;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+
+public class CfNew extends CfInstruction {
+
+  private final DexType type;
+
+  public CfNew(DexType type) {
+    this.type = type;
+  }
+
+  @Override
+  public void write(MethodVisitor visitor) {
+    visitor.visitTypeInsn(Opcodes.NEW, Type.getType(type.toDescriptorString()).getInternalName());
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfPop.java b/src/main/java/com/android/tools/r8/cf/code/CfPop.java
new file mode 100644
index 0000000..e058df6
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/cf/code/CfPop.java
@@ -0,0 +1,22 @@
+// Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package com.android.tools.r8.cf.code;
+
+import com.android.tools.r8.ir.code.ValueType;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+
+public class CfPop extends CfInstruction {
+
+  private final ValueType type;
+
+  public CfPop(ValueType type) {
+    this.type = type;
+  }
+
+  @Override
+  public void write(MethodVisitor visitor) {
+    visitor.visitInsn(type.isWide() ? Opcodes.POP2 : Opcodes.POP);
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/ir/code/ArrayGet.java b/src/main/java/com/android/tools/r8/ir/code/ArrayGet.java
index e0aa965..be0e6db 100644
--- a/src/main/java/com/android/tools/r8/ir/code/ArrayGet.java
+++ b/src/main/java/com/android/tools/r8/ir/code/ArrayGet.java
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.ir.code;
 
+import com.android.tools.r8.cf.code.CfArrayLoad;
 import com.android.tools.r8.code.Aget;
 import com.android.tools.r8.code.AgetBoolean;
 import com.android.tools.r8.code.AgetByte;
@@ -14,6 +15,8 @@
 import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.graph.AppInfoWithSubtyping;
 import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.ir.conversion.CfBuilder;
+import com.android.tools.r8.ir.conversion.CfBuilder.StackHelper;
 import com.android.tools.r8.ir.conversion.DexBuilder;
 import com.android.tools.r8.ir.optimize.Inliner.Constraint;
 import com.android.tools.r8.ir.regalloc.RegisterAllocator;
@@ -126,4 +129,15 @@
   public Constraint inliningConstraint(AppInfoWithSubtyping info, DexType holder) {
     return Constraint.ALWAYS;
   }
+
+  @Override
+  public void insertLoadAndStores(InstructionListIterator it, StackHelper stack) {
+    stack.loadInValues(this, it);
+    stack.storeOutValue(this, it);
+  }
+
+  @Override
+  public void buildCf(CfBuilder builder) {
+    builder.add(new CfArrayLoad(type));
+  }
 }
diff --git a/src/main/java/com/android/tools/r8/ir/code/ConstNumber.java b/src/main/java/com/android/tools/r8/ir/code/ConstNumber.java
index b887e97..c78f9ad 100644
--- a/src/main/java/com/android/tools/r8/ir/code/ConstNumber.java
+++ b/src/main/java/com/android/tools/r8/ir/code/ConstNumber.java
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.ir.code;
 
+import com.android.tools.r8.cf.code.CfConstNull;
 import com.android.tools.r8.cf.code.CfConstNumber;
 import com.android.tools.r8.code.Const;
 import com.android.tools.r8.code.Const16;
@@ -139,7 +140,11 @@
 
   @Override
   public void buildCf(CfBuilder builder) {
-    builder.add(new CfConstNumber(value, outType()));
+    if (outType().isObject()) {
+      builder.add(new CfConstNull());
+    } else {
+      builder.add(new CfConstNumber(value, outType()));
+    }
   }
 
   // Estimated size of the resulting dex instruction in code units.
diff --git a/src/main/java/com/android/tools/r8/ir/code/InvokeMethod.java b/src/main/java/com/android/tools/r8/ir/code/InvokeMethod.java
index 0fd4804..fef03c3 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InvokeMethod.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InvokeMethod.java
@@ -90,7 +90,7 @@
       return;
     }
     if (outValue == null) {
-      stack.popOutValue(this, it);
+      stack.popOutValue(ValueType.fromDexType(method.proto.returnType), this, it);
     } else {
       stack.storeOutValue(this, it);
     }
diff --git a/src/main/java/com/android/tools/r8/ir/code/NewInstance.java b/src/main/java/com/android/tools/r8/ir/code/NewInstance.java
index 434b415..979b491 100644
--- a/src/main/java/com/android/tools/r8/ir/code/NewInstance.java
+++ b/src/main/java/com/android/tools/r8/ir/code/NewInstance.java
@@ -3,9 +3,12 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.ir.code;
 
+import com.android.tools.r8.cf.code.CfNew;
 import com.android.tools.r8.dex.Constants;
 import com.android.tools.r8.graph.AppInfoWithSubtyping;
 import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.ir.conversion.CfBuilder;
+import com.android.tools.r8.ir.conversion.CfBuilder.StackHelper;
 import com.android.tools.r8.ir.conversion.DexBuilder;
 import com.android.tools.r8.ir.optimize.Inliner.Constraint;
 
@@ -76,4 +79,14 @@
   public Constraint inliningConstraint(AppInfoWithSubtyping info, DexType holder) {
     return Constraint.classIsVisible(holder, clazz, info);
   }
+
+  @Override
+  public void insertLoadAndStores(InstructionListIterator it, StackHelper stack) {
+    stack.storeOutValue(this, it);
+  }
+
+  @Override
+  public void buildCf(CfBuilder builder) {
+    builder.add(new CfNew(clazz));
+  }
 }
diff --git a/src/main/java/com/android/tools/r8/ir/code/Pop.java b/src/main/java/com/android/tools/r8/ir/code/Pop.java
index 61ab130..33d5557 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Pop.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Pop.java
@@ -3,9 +3,11 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.ir.code;
 
+import com.android.tools.r8.cf.code.CfPop;
 import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.graph.AppInfoWithSubtyping;
 import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.ir.conversion.CfBuilder;
 import com.android.tools.r8.ir.optimize.Inliner.Constraint;
 
 public class Pop extends Instruction {
@@ -38,4 +40,9 @@
   public Constraint inliningConstraint(AppInfoWithSubtyping info, DexType holder) {
     throw new Unreachable();
   }
+
+  @Override
+  public void buildCf(CfBuilder builder) {
+    builder.add(new CfPop(inValues.get(0).type));
+  }
 }
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java b/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java
index bc5df81..cb5b445 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java
@@ -20,6 +20,7 @@
 import com.android.tools.r8.ir.code.StackValue;
 import com.android.tools.r8.ir.code.Store;
 import com.android.tools.r8.ir.code.Value;
+import com.android.tools.r8.ir.code.ValueType;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
@@ -55,8 +56,8 @@
       add(new Store(oldOutValue, newOutValue), instruction, it);
     }
 
-    public void popOutValue(Instruction instruction, InstructionListIterator it) {
-      StackValue newOutValue = new StackValue(instruction.outType());
+    public void popOutValue(ValueType type, Instruction instruction, InstructionListIterator it) {
+      StackValue newOutValue = new StackValue(type);
       instruction.swapOutValue(newOutValue);
       add(new Pop(newOutValue), instruction, it);
     }